diff --git a/package-lock.json b/package-lock.json index d642a2f7..5948cbd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,27 @@ { "name": "@diamondlightsource/cs-web-lib", - "version": "0.10.17", + "version": "0.10.18", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@diamondlightsource/cs-web-lib", - "version": "0.10.17", + "version": "0.10.18", "license": "ISC", "dependencies": { - "@mui/icons-material": "^7.3.7", - "@reduxjs/toolkit": "^2.11.2", "apollo-link-retry": "^2.2.16", "bufferutil": "^4.0.8", "loglevel": "^1.9.2", - "react-grid-layout": "^2.2.3", - "react-toastify": "^11.0.5", "safe-stable-stringify": "^2.5.0", "utf-8-validate": "^5.0.10" }, "devDependencies": { "@apollo/client": "^3.11.8", "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^7.3.7", "@mui/material": "^7.3.2", "@mui/x-charts": "^9.3.0", + "@reduxjs/toolkit": "^2.11.2", "@rollup/plugin-commonjs": "^28", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-typescript": "^12.3.0", @@ -48,11 +46,13 @@ "graphql-ws": "^5.16.0", "jsdom": "^25.0.1", "prettier": "^3.3.3", - "react-gauge-component": "^2.0.26", + "react-gauge-component": "^2.0.29", + "react-grid-layout": "^2.2.3", "react-id-generator": "^3.0.2", "react-router": "^7.13.0", "react-test-renderer": "^18.3.1", "react-tiny-popover": "^8.1.2", + "react-toastify": "^11.0.5", "rollup": "^4", "rollup-plugin-dts": "^6.1.1", "rollup-plugin-peer-deps-external": "^2.2.4", @@ -62,22 +62,25 @@ "typescript": "^5.6.3", "vite": "^8.0.16", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-node-polyfills": "^0.26.0", "vitest": "^4.0.8", "vitest-canvas-mock": "^0.3.3", "vitest-websocket-mock": "^0.4.0", "xml-js": "^1.6.11" }, "peerDependencies": { + "@mui/icons-material": "^7.3.7", "@mui/material": "^7.3.2", "@mui/x-charts": "^9.3.0", + "@reduxjs/toolkit": "^2.11.2", "@types/react": "^18.3.1", "d3": "^7.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-gauge-component": "^2.0.26", + "react-gauge-component": "^2.0.29", + "react-grid-layout": "^2.2.3", "react-redux": "^7.2.9", - "react-router": "^7.13.0" + "react-router": "^7.13.0", + "react-toastify": "^11.0.5" } }, "node_modules/@adobe/css-tools": { @@ -155,7 +158,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", @@ -267,7 +270,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.7", @@ -401,7 +404,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -425,7 +428,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.29.7", @@ -530,7 +533,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -540,7 +543,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -589,7 +592,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.7" @@ -2184,7 +2187,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", @@ -2199,7 +2202,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", @@ -2218,7 +2221,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.29.7", @@ -2381,7 +2384,7 @@ "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", @@ -2401,6 +2404,7 @@ "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "dev": true, "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0", @@ -2414,13 +2418,14 @@ "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0" @@ -2430,13 +2435,14 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/react": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", - "devOptional": true, + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -2462,6 +2468,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "dev": true, "license": "MIT", "dependencies": { "@emotion/hash": "^0.9.2", @@ -2475,13 +2482,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/styled": { "version": "11.14.1", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -2498,504 +2506,39 @@ "peerDependenciesMeta": { "@types/react": { "optional": true - } - } - }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", - "license": "MIT" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", - "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", - "devOptional": true, - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "license": "MIT" - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "peer": true, - "engines": { - "node": ">=18" + } } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" + "peerDependencies": { + "react": ">=16.8.0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", @@ -3198,7 +2741,7 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -3220,7 +2763,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==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3230,14 +2773,14 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3248,6 +2791,7 @@ "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.11.tgz", "integrity": "sha512-a7I/b/nBTdXYz2cOSlEmkQ9WWE1x8FHpqMhFPp+Y1VPFxcOw91G5ELOHARQAGSPy5V+UCgJua6K/1x70bAtQPw==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -3258,6 +2802,7 @@ "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.11.tgz", "integrity": "sha512-+hz5ilwHZ3djd5es3sCErLioqe/NhZcYTsV/TNXZAMdJdb23F4xzJjqnnZdnurc3S1+ietcssRNqieOhPQLZ7Q==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6" @@ -3284,6 +2829,7 @@ "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.11.tgz", "integrity": "sha512-yq8bPc3LxOwKRWpcjRgDkYFmpM6aKlARfESTmOQcvLYFeJwtHte2tw6hJDrb8sk8wcvpDprHEHVaoUU0MslIkw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", @@ -3333,6 +2879,7 @@ "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.11.tgz", "integrity": "sha512-9B+YKms0fRHbNrqp9tOT/DNbNnU5gyvJ1o3qAGXfq8GmZcbJnE3At9x07Zr/o0pkhzg4aDdwXVqe4+AcgtOCPA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", @@ -3360,6 +2907,7 @@ "version": "7.3.10", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.10.tgz", "integrity": "sha512-WxE9SiF8xskAQqGjsp0poXCkCqsoXFEsSr0HBXfApmGHR+DBnXRp+z46Vsltg4gpPM4Z96DeAQRpeAOnhNg7Ng==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", @@ -3394,6 +2942,7 @@ "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.11.tgz", "integrity": "sha512-7izwGWdNawAKpBKcRlx7f2gFnAAjmASBWvMcyX4YYEeLOFsbfGRbUYGInvnAcUeql3rPxI7F9Ft4oY2OLRz44g==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", @@ -3643,6 +3192,7 @@ "version": "7.4.12", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.12.tgz", "integrity": "sha512-iKNAF2u9PzSIj40CjvKJWxFXJo122jXVdrmdh0hMYd+FR+NuJMkr/L88XwWLCRiJ5P1j+uyac25+Kp6YC4hu6w==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6" @@ -3660,6 +3210,7 @@ "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.11.tgz", "integrity": "sha512-XTjGnifwteg71/ij+0e7Y7d+hwyntMYP5wPoA/g2drdGH+Flkvjwy0OfrVpKBbaOvofq4zU/LIyUZyKgmWu18g==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", @@ -4005,6 +3556,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -4015,6 +3567,7 @@ "version": "2.12.0", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", + "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -4328,29 +3881,6 @@ } } }, - "node_modules/@rollup/plugin-inject": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", - "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", @@ -4794,12 +4324,14 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, "license": "MIT" }, "node_modules/@standard-schema/utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "dev": true, "license": "MIT" }, "node_modules/@testing-library/dom": { @@ -5279,7 +4811,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@types/plotly.js": { @@ -5353,6 +4885,7 @@ "version": "4.4.12", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "*" @@ -6517,39 +6050,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -6624,7 +6124,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", @@ -6772,13 +6272,6 @@ "dev": true, "license": "MIT" }, - "node_modules/bn.js": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz", - "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==", - "dev": true, - "license": "MIT" - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -6812,109 +6305,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.17.0" - } - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", - "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^5.2.1", - "randombytes": "^2.1.0", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.6.tgz", - "integrity": "sha512-sd+Q65fjlWCYWtZKXiKfrUc8d+4jtp/8f0W2NkwzLtoW4bI6UDnWusLWIurHnmurW0XShIRxpwiOX4EoPtXUAg==", - "dev": true, - "license": "ISC", - "dependencies": { - "bn.js": "^5.2.3", - "browserify-rsa": "^4.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.6.1", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.9", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "~1.0.5" - } - }, "node_modules/browserslist": { "version": "4.28.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", @@ -6949,38 +6339,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true, - "license": "MIT" - }, "node_modules/bufferutil": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.1.0.tgz", @@ -7007,13 +6365,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true, - "license": "MIT" - }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -7068,7 +6419,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -7148,21 +6499,6 @@ "node": ">=8" } }, - "node_modules/cipher-base": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", - "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/clean-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", @@ -7211,6 +6547,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -7307,24 +6644,11 @@ "dev": true, "license": "MIT" }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true, - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/cookie": { @@ -7355,93 +6679,32 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "devOptional": true, - "license": "MIT", - "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/cosmiconfig/node_modules/yaml": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", - "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", - "devOptional": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "license": "MIT", "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "@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/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", "dev": true, - "license": "MIT" + "license": "ISC", + "engines": { + "node": ">= 6" + } }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -7459,33 +6722,6 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", - "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-cipher": "^1.0.1", - "browserify-sign": "^4.2.3", - "create-ecdh": "^4.0.4", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "diffie-hellman": "^5.0.3", - "hash-base": "~3.0.4", - "inherits": "^2.0.4", - "pbkdf2": "^3.1.2", - "public-encrypt": "^4.0.3", - "randombytes": "^2.1.0", - "randomfill": "^1.0.4" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/css-declaration-sorter": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", @@ -8220,7 +7456,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8325,17 +7561,6 @@ "node": ">=6" } }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -8356,25 +7581,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "dev": true, - "license": "MIT" - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8413,6 +7619,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.7", @@ -8444,19 +7651,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/domain-browser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -8523,29 +7717,6 @@ "dev": true, "license": "ISC" }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "dev": true, - "license": "MIT" - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -8570,7 +7741,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -8659,7 +7830,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8760,50 +7931,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -8818,7 +7945,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -9623,27 +8750,6 @@ "dev": true, "license": "MIT" }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -9673,6 +8779,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz", "integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==", + "dev": true, "license": "MIT" }, "node_modules/fast-glob": { @@ -9778,7 +8885,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/find-up": { @@ -9787,6 +8894,7 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -9889,7 +8997,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "devOptional": true, + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10279,36 +9387,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", - "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "node_modules/hasown": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -10317,18 +9400,6 @@ "node": ">= 0.4" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "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", @@ -10378,13 +9449,6 @@ "node": ">= 14" } }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true, - "license": "MIT" - }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -10432,27 +9496,6 @@ "postcss": "^8.1.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -10467,6 +9510,7 @@ "version": "11.1.8", "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.8.tgz", "integrity": "sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -10490,7 +9534,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -10565,7 +9609,8 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/internal-slot": { "version": "1.1.0", @@ -10592,23 +9637,6 @@ "node": ">=12" } }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -10631,7 +9659,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/is-async-function": { @@ -10720,7 +9748,7 @@ "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.3" @@ -10846,23 +9874,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -11091,16 +10102,6 @@ "license": "ISC", "peer": true }, - "node_modules/isomorphic-timers-promises": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-timers-promises/-/isomorphic-timers-promises-1.0.1.tgz", - "integrity": "sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/iterator.prototype": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", @@ -11281,7 +10282,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "devOptional": true, + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -11302,7 +10303,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -11671,7 +10672,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/loader-utils": { @@ -11690,6 +10691,7 @@ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -11816,18 +10818,6 @@ "node": ">= 0.4" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -11872,27 +10862,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "dev": true, - "license": "MIT" - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -11926,20 +10895,6 @@ "node": ">=4" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true, - "license": "MIT" - }, "node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", @@ -11990,7 +10945,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -12077,67 +11032,6 @@ "node": ">=18" } }, - "node_modules/node-stdlib-browser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-stdlib-browser/-/node-stdlib-browser-1.3.1.tgz", - "integrity": "sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert": "^2.0.0", - "browser-resolve": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^5.7.1", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "create-require": "^1.1.1", - "crypto-browserify": "^3.12.1", - "domain-browser": "4.22.0", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "isomorphic-timers-promises": "^1.0.1", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "pkg-dir": "^5.0.0", - "process": "^0.11.10", - "punycode": "^1.4.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.1", - "url": "^0.11.4", - "util": "^0.12.4", - "vm-browserify": "^1.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-stdlib-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-stdlib-browser/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -12216,23 +11110,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -12387,13 +11264,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true, - "license": "MIT" - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -12428,6 +11298,7 @@ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -12444,6 +11315,7 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -12494,18 +11366,11 @@ "node": ">=6" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true, - "license": "(MIT AND Zlib)" - }, "node_modules/parent-module": { "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==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -12514,28 +11379,11 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz", - "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "pbkdf2": "^3.1.5", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -12561,14 +11409,7 @@ }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "license": "MIT" + } }, "node_modules/path-exists": { "version": "4.0.0", @@ -12606,14 +11447,14 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12626,29 +11467,11 @@ "dev": true, "license": "MIT" }, - "node_modules/pbkdf2": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", - "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "ripemd160": "^2.0.3", - "safe-buffer": "^5.2.1", - "sha.js": "^2.4.12", - "to-buffer": "^1.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "devOptional": true, + "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -12677,19 +11500,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -13418,23 +12228,6 @@ "dev": true, "license": "MIT" }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, "node_modules/promise.series": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/promise.series/-/promise.series-0.2.0.tgz", @@ -13462,28 +12255,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "dev": true, - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -13494,31 +12265,6 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.15.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", - "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -13540,27 +12286,6 @@ ], "license": "MIT" }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -13592,6 +12317,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.5.0.tgz", "integrity": "sha512-VC+HBLEZ0XJxnOxVAZsdRi8rD04Iz3SiiKOoYzamjylUcju/hP9np/aZdLHf/7WOD268WMoNJMvYfB5yAK45cw==", + "dev": true, "license": "MIT", "dependencies": { "clsx": "^2.1.1", @@ -13620,6 +12346,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-2.2.3.tgz", "integrity": "sha512-OAEJHBxmfuxQfVtZwRzmsokijGlBgzYIJ7MUlLk/VSa43SaGzu15w5D0P2RDrfX5EvP9POMbL6bFrai/huDzbQ==", + "dev": true, "license": "MIT", "dependencies": { "clsx": "^2.1.1", @@ -13648,6 +12375,7 @@ "version": "19.2.6", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", + "dev": true, "license": "MIT" }, "node_modules/react-redux": { @@ -13687,6 +12415,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.2.0.tgz", "integrity": "sha512-3NKQ0SLZV7rs3LQHeXlOzDSRQfFrkX6TVet77/Qk03zqiZyee37b7N8/gwDJAA8UUjRz7PdWCCy49hcso45SMQ==", + "dev": true, "license": "MIT", "dependencies": { "prop-types": "15.x", @@ -13778,6 +12507,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.1.0.tgz", "integrity": "sha512-e9h23x3phN0wbFeB6yovmWp7lobzV4CaCH0LO8nVP6H7Y+3GbcLpIzMm9dJhcp1RXbpyfvjgpfXqO80QAmn7sg==", + "dev": true, "license": "MIT", "dependencies": { "clsx": "^2.1.1" @@ -13791,6 +12521,7 @@ "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", @@ -13913,36 +12644,6 @@ "node": ">=8" } }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -13961,12 +12662,14 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "dev": true, "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "dev": true, "license": "MIT", "peerDependencies": { "redux": "^5.0.0" @@ -14129,19 +12832,21 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.2.0.tgz", "integrity": "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==", + "dev": true, "license": "MIT" }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true, "license": "MIT" }, "node_modules/resolve": { "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -14163,7 +12868,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -14198,36 +12903,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", - "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.1.2", - "inherits": "^2.0.4" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ripemd160/node_modules/hash-base": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", - "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/robust-predicates": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", @@ -14497,27 +13172,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-identifier": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", @@ -14677,34 +13331,6 @@ "node": ">= 0.4" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true, - "license": "MIT" - }, - "node_modules/sha.js": { - "version": "2.4.12", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", - "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", - "dev": true, - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.0" - }, - "bin": { - "sha.js": "bin.js" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -14827,7 +13453,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "devOptional": true, + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -14915,77 +13541,6 @@ "node": ">= 0.4" } }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "license": "MIT", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, "node_modules/string-hash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", @@ -15192,6 +13747,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "dev": true, "license": "MIT" }, "node_modules/supports-color": { @@ -15211,7 +13767,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==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -15283,19 +13839,6 @@ "license": "MIT", "peer": true }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -15360,21 +13903,6 @@ "dev": true, "license": "MIT" }, - "node_modules/to-buffer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "^2.0.5", - "safe-buffer": "^5.2.1", - "typed-array-buffer": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -15496,13 +14024,6 @@ "dev": true, "license": "0BSD" }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true, - "license": "MIT" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -15735,27 +14256,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true, - "license": "MIT" - }, "node_modules/use-sync-external-store": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", @@ -15779,20 +14279,6 @@ "node": ">=6.14.2" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -15948,23 +14434,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/vite-plugin-node-polyfills": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.26.0.tgz", - "integrity": "sha512-BAe5YzJf368XGev02hDvioidx4uVH8dqEJlG73bjQSxM26/AQnGcKFomq9n3vGq5yqpSHKN4h1XQNxx9l98mBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/plugin-inject": "^5.0.5", - "node-stdlib-browser": "^1.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/davidmyersdev" - }, - "peerDependencies": { - "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, "node_modules/vitest": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.7.tgz", @@ -16120,13 +14589,6 @@ "node": ">=14.0.0" } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true, - "license": "MIT" - }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", @@ -16382,16 +14844,6 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -16399,30 +14851,13 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 4d4c9b7f..1b088d75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "@diamondlightsource/cs-web-lib", - "version": "0.10.17", + "type": "module", + "version": "0.10.18", "description": "Control system web library", "main": "./dist/index.cjs", "scripts": { @@ -20,17 +21,17 @@ "url": "https://github.com/DiamondLightSource/cs-web-lib.git" }, "dependencies": { - "@mui/icons-material": "^7.3.7", - "@reduxjs/toolkit": "^2.11.2", "apollo-link-retry": "^2.2.16", "bufferutil": "^4.0.8", "loglevel": "^1.9.2", - "react-grid-layout": "^2.2.3", - "react-toastify": "^11.0.5", "safe-stable-stringify": "^2.5.0", "utf-8-validate": "^5.0.10" }, "devDependencies": { + "react-grid-layout": "^2.2.3", + "react-toastify": "^11.0.5", + "@mui/icons-material": "^7.3.7", + "@reduxjs/toolkit": "^2.11.2", "@apollo/client": "^3.11.8", "@emotion/styled": "^11.13.0", "@mui/material": "^7.3.2", @@ -59,7 +60,7 @@ "graphql-ws": "^5.16.0", "jsdom": "^25.0.1", "prettier": "^3.3.3", - "react-gauge-component": "^2.0.26", + "react-gauge-component": "^2.0.29", "react-id-generator": "^3.0.2", "react-router": "^7.13.0", "react-test-renderer": "^18.3.1", @@ -73,22 +74,25 @@ "typescript": "^5.6.3", "vite": "^8.0.16", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-node-polyfills": "^0.26.0", "vitest": "^4.0.8", "vitest-canvas-mock": "^0.3.3", "vitest-websocket-mock": "^0.4.0", "xml-js": "^1.6.11" }, "peerDependencies": { + "@mui/icons-material": "^7.3.7", + "@reduxjs/toolkit": "^2.11.2", + "react-grid-layout": "^2.2.3", + "react-toastify": "^11.0.5", + "@mui/material": "^7.3.2", + "@mui/x-charts": "^9.3.0", "@types/react": "^18.3.1", + "d3": "^7.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-gauge-component": "^2.0.26", + "react-gauge-component": "^2.0.29", "react-redux": "^7.2.9", - "react-router": "^7.13.0", - "d3": "^7.9.0", - "@mui/material": "^7.3.2", - "@mui/x-charts": "^9.3.0" + "react-router": "^7.13.0" }, "module": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/rollup.config.mjs b/rollup.config.mjs index 0f342eb6..195e5cc7 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -7,10 +7,21 @@ import postcss from "rollup-plugin-postcss"; import peerDepsExternal from "rollup-plugin-peer-deps-external"; import preserveDirectives from 'rollup-preserve-directives'; +const external = [ + 'react', + 'react-dom', + 'react-gauge-component', + 'react-redux', + '@reduxjs/toolkit', + '@mui/material', + '@mui/system', + '@mui/icons-material' +]; + const config = [ { input: "src/index.ts", - + external, output: [ { dir: "dist", @@ -38,7 +49,8 @@ const config = [ peerDepsExternal(), resolve({ - preferBuiltins: true + preferBuiltins: true, + dedupe: ['react', 'react-dom'] }), commonjs({ include: [ @@ -58,7 +70,7 @@ const config = [ input: "dist/index.d.ts", output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], - external: [/\.css$/, '@reduxjs/toolkit'] + external: [/\.css$/, ...external] } ]; diff --git a/src/misc/urlUtils.test.ts b/src/misc/urlUtils.test.ts index 6972f2a6..0559649b 100644 --- a/src/misc/urlUtils.test.ts +++ b/src/misc/urlUtils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { buildUrl, isFullyQualifiedUrl } from "./urlUtils"; +import { buildUrl, isFullyQualifiedUrl, normalisePath } from "./urlUtils"; describe("urlUtils", () => { describe("isFullyQualifiedUrl", () => { @@ -135,3 +135,76 @@ describe("urlUtils", () => { }); }); }); + +describe("normalisePath", (): void => { + it("returns path when no other arguments are specified", async (): Promise => { + const result = normalisePath("/a/path"); + expect(result).toBe("/a/path"); + }); + + it("returns path without .. when no other arguments are specified and path starts with ../", async (): Promise => { + const result = normalisePath("../../a/path"); + expect(result).toBe("a/path"); + }); + + it("Joins path and parent when parent is a valid url", async (): Promise => { + const result = normalisePath("/a/path", "http://test.diamond.ac.uk/"); + expect(result).toBe("http://test.diamond.ac.uk/a/path"); + }); + + it("Joins path and parent when parent is a path", async (): Promise => { + const result = normalisePath("/a/path", "/parent/path"); + expect(result).toBe("/parent/path/a/path"); + }); + + it("Joins path when path contains .. and removes trailing folders from paren path", async (): Promise => { + const result = normalisePath("../a/path", "/parent/path"); + expect(result).toBe("/parent/a/path"); + }); + + it("Returns path if path is a valid url", async (): Promise => { + const result = normalisePath( + "https://anothertest.diamond.ac.uk/a/path", + "http://test.diamond.ac.uk/" + ); + expect(result).toBe("https://anothertest.diamond.ac.uk/a/path"); + }); + + it("Does not substitute macros if macros undefined", async (): Promise => { + const result = normalisePath( + "$(some_macro)/$(another_macro)/path", + "$(another_macro)/parent" + ); + expect(result).toBe( + "$(another_macro)/parent/$(some_macro)/$(another_macro)/path" + ); + }); + + it("Substitutes macros into path if macros defined", async (): Promise => { + const result = normalisePath( + "$(some_macro)/$(another_macro)/path", + "$(another_macro)/parent", + { + some_macro: "macroPath", + another_macro: "anotherMacroPath", + absent_macro: "no_match" + } + ); + expect(result).toBe( + "$(another_macro)/parent/macroPath/anotherMacroPath/path" + ); + }); + + it("Substitutes macros into path, returns path if path becomes a fully qualified url", async (): Promise => { + const result = normalisePath( + "$(some_macro)/$(another_macro)/path", + "$(another_macro)/parent", + { + some_macro: "http://test.diamond.ac.uk", + another_macro: "anotherMacroPath", + absent_macro: "no_match" + } + ); + expect(result).toBe("http://test.diamond.ac.uk/anotherMacroPath/path"); + }); +}); diff --git a/src/misc/urlUtils.ts b/src/misc/urlUtils.ts index 0de74626..3c08c453 100644 --- a/src/misc/urlUtils.ts +++ b/src/misc/urlUtils.ts @@ -1,3 +1,6 @@ +import { resolveMacros } from "../types"; +import { MacroMap } from "../types/macros"; + export const isFullyQualifiedUrl = (url: string): boolean => { try { const parsed = new URL(url); @@ -46,3 +49,20 @@ export const buildUrl = ( return `${baseHost}${path}`; } }; + +export const normalisePath = ( + path: string, + parentDir?: string, + macros?: MacroMap +): string => { + let prefix = parentDir ?? ""; + while (path.startsWith("../")) { + path = path.slice(3); + prefix = prefix.slice(0, prefix.lastIndexOf("/")); + } + + // If path contains macros, we need to apply these before building the url + const resolvedPath = macros ? resolveMacros(path, macros) : path; + + return buildUrl(prefix, resolvedPath); +}; diff --git a/src/redux/slices/fileCacheSlice.ts b/src/redux/slices/fileCacheSlice.ts index 4c82c2c0..0f017332 100644 --- a/src/redux/slices/fileCacheSlice.ts +++ b/src/redux/slices/fileCacheSlice.ts @@ -14,6 +14,7 @@ import { Position } from "../../types"; import { MacroMap } from "../../types/macros"; import stringify from "safe-stable-stringify"; import { Breakpoints, Layout, ResponsiveLayouts } from "react-grid-layout"; +import { resolveWidgetPathsAndMacros } from "./fileCacheSliceUtils"; export interface FileCache { [fileId: string]: WidgetDescription; @@ -252,8 +253,14 @@ const fileCacheSlice = createSlice({ }); if (state.displayInstanceCache) { + const parentDir = file.slice(0, file.lastIndexOf("/")); + state.displayInstanceCache[uuid] = { - description: description, + description: resolveWidgetPathsAndMacros( + description, + parentDir, + macros + ), fileId: file, macros: macros, uuid, diff --git a/src/redux/slices/fileCacheSliceUtils.test.ts b/src/redux/slices/fileCacheSliceUtils.test.ts new file mode 100644 index 00000000..9ec69d3d --- /dev/null +++ b/src/redux/slices/fileCacheSliceUtils.test.ts @@ -0,0 +1,164 @@ +import { describe, it, expect, vi } from "vitest"; +import { resolveWidgetPathsAndMacros } from "./fileCacheSliceUtils"; +import { resolveAndNormaliseWidgetPaths } from "../../ui/widgets/EmbeddedDisplay/parserPatcherUtils"; +import { WidgetDescription } from "../../ui/widgets/createComponent"; + +vi.mock("../../ui/widgets/EmbeddedDisplay/parserPatcherUtils", () => ({ + resolveAndNormaliseWidgetPaths: vi.fn((widget, filepath, macros) => { + widget._resolved = { + filepath, + macros + }; + + return widget; + }) +})); + +describe("resolveWidgetPathsAndMacros", () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + it("applies resolveAndNormaliseWidgetPaths to root", () => { + const widget = { type: "root" } as Partial; + + const result = resolveWidgetPathsAndMacros( + widget as WidgetDescription, + "/file", + { + A: "1" + } + ); + + expect(resolveAndNormaliseWidgetPaths).toHaveBeenCalledWith( + widget, + "/file", + { A: "1" } + ); + + expect(result._resolved).toEqual({ + filepath: "/file", + macros: { A: "1" } + }); + }); + + it("merges widget macros with parent macros (child overrides parent)", () => { + const widget = { + type: "root", + macros: { B: "2" } + } as Partial; + + resolveWidgetPathsAndMacros(widget as WidgetDescription, "/file", { + A: "1", + B: "parent" + }); + + expect(resolveAndNormaliseWidgetPaths).toHaveBeenCalledWith( + widget, + "/file", + { + A: "1", + B: "2" + } + ); + }); + + it("recursively processes children", () => { + const child = { type: "child" } as Partial; + const widget = { + type: "root", + children: [child] + } as Partial; + + const result = resolveWidgetPathsAndMacros( + widget as WidgetDescription, + "/file", + {} + ); + + expect(resolveAndNormaliseWidgetPaths).toHaveBeenCalledTimes(2); + + expect(result?.children?.[0]?._resolved).toBeDefined(); + }); + + it("recursively processes tabs", () => { + const tabChild = { type: "tab-child" } as Partial; + const widget = { + type: "root", + tab: [tabChild] + } as Partial; + + const result = resolveWidgetPathsAndMacros( + widget as WidgetDescription, + "/file", + {} + ); + + expect(resolveAndNormaliseWidgetPaths).toHaveBeenCalledTimes(2); + + expect(result.tab[0]._resolved).toBeDefined(); + }); + + it("propagates merged macros to children", () => { + const child = { type: "child" } as Partial; + const widget = { + type: "root", + macros: { B: "2" }, + children: [child] + } as Partial; + + resolveWidgetPathsAndMacros(widget as WidgetDescription, "/file", { + A: "1" + }); + + expect(resolveAndNormaliseWidgetPaths).toHaveBeenNthCalledWith( + 2, + child, + "/file", + { + A: "1", + B: "2" + } + ); + }); + + it("handles both children and tabs together", () => { + const child = { type: "child" } as Partial; + const tabChild = { type: "tab-child" } as Partial; + + const widget = { + type: "root", + children: [child], + tab: [tabChild] + } as Partial; + + resolveWidgetPathsAndMacros(widget as WidgetDescription, "/file", {}); + + // root + child + tabChild + expect(resolveAndNormaliseWidgetPaths).toHaveBeenCalledTimes(3); + }); + + it("works when no macros are provided", () => { + const widget = { type: "root" } as Partial; + + resolveWidgetPathsAndMacros(widget as WidgetDescription, "/file"); + + expect(resolveAndNormaliseWidgetPaths).toHaveBeenCalledWith( + widget, + "/file", + {} + ); + }); + + it("mutates and returns the same object reference", () => { + const widget: any = { type: "root" } as Partial; + + const result = resolveWidgetPathsAndMacros( + widget as WidgetDescription, + "/file", + {} + ); + + expect(result).toBe(widget); + }); +}); diff --git a/src/redux/slices/fileCacheSliceUtils.ts b/src/redux/slices/fileCacheSliceUtils.ts new file mode 100644 index 00000000..c4f899a5 --- /dev/null +++ b/src/redux/slices/fileCacheSliceUtils.ts @@ -0,0 +1,57 @@ +import { MacroMap } from "../../types/macros"; +import { WidgetDescription } from "../../ui/widgets/createComponent"; +import { resolveAndNormaliseWidgetPaths } from "../../ui/widgets/EmbeddedDisplay/parserPatcherUtils"; + +/** + * Recursively resolves and normalizes all path-related attributes within a widget tree. + * + * This function: + * - Merges macros defined on the widget with those inherited from the parent context + * - Applies macro substitution to all path values + * - Resolves relative paths against the provided file path and converts them to absolute paths + * - Traverses and updates all nested child widgets and tab children + * + * Note: This function mutates the provided widget description and its descendants. + * It should be called after parsing, as macro values may influence the appearance of + * the display, as well as the resolved paths and macros of any nested sub-displays. + * + * @param widgetDescription - The widget to process and mutate. + * @param filepath - The absolute file path used as the base for resolving relative paths. + * @param macros - Optional macros inherited from the parent context. + * @returns The same widget description instance with all paths resolved and normalized. + */ +export const resolveWidgetPathsAndMacros = ( + widgetDescription: WidgetDescription, + filepath?: string, + macros?: MacroMap +): WidgetDescription => { + const combinedMacros = { + ...(macros ?? {}), + ...(widgetDescription?.macros ?? {}) + }; + + // Patch the paths in this widget + widgetDescription = resolveAndNormaliseWidgetPaths( + widgetDescription, + filepath, + combinedMacros + ); + + // Recursively patch the child widgets + if (widgetDescription.children) { + widgetDescription.children = widgetDescription.children.map( + (child: any) => { + return resolveWidgetPathsAndMacros(child, filepath, combinedMacros); + } + ); + } + + // Recursively patch the child tabs + if (widgetDescription.tab) { + widgetDescription.tab = widgetDescription.tab.map((child: any) => { + return resolveWidgetPathsAndMacros(child, filepath, combinedMacros); + }); + } + + return widgetDescription; +}; diff --git a/src/ui/hooks/useClassFile.tsx b/src/ui/hooks/useClassFile.tsx index 7aede89b..7ff2ecf6 100644 --- a/src/ui/hooks/useClassFile.tsx +++ b/src/ui/hooks/useClassFile.tsx @@ -58,8 +58,7 @@ export function useClassFile(userTheme?: Theme): Theme { const fetchData = async (): Promise => { const widgetDescription = await fetchAndConvert( classFile as string, - "ca", - {} + "ca" ); const [classTheme, classStyle] = createClassTheme(widgetDescription); setTheme(classTheme); diff --git a/src/ui/hooks/useFile.tsx b/src/ui/hooks/useFile.tsx index 6ed2e4ab..c831e8fd 100644 --- a/src/ui/hooks/useFile.tsx +++ b/src/ui/hooks/useFile.tsx @@ -35,46 +35,34 @@ export interface File { export async function fetchAndConvert( filepath: string, - protocol: string, - macros?: MacroMap + protocol: string ): Promise { try { const parentDir = filepath.slice(0, filepath.lastIndexOf("/")); const fileResponse = await httpRequest(filepath); const fileExt = filepath.split(".").pop() || "json"; - const contents = await fileResponse.text(); + const contents = (await fileResponse?.text()) ?? ""; let description = EMPTY_WIDGET; // Hack! - if (contents.startsWith("")) { + if (contents?.startsWith("")) { throw new Error("File not found"); } if (contents !== "") { // Convert the contents to widget description style object switch (fileExt) { case "bob": - description = await parseBob( - contents, - protocol, - parentDir, - macros, - filepath - ); + description = await parseBob(contents, protocol, parentDir, filepath); break; case "bcf": - description = await parseBcf(contents, protocol, parentDir, filepath); + description = await parseBcf(contents, protocol, filepath); break; case "json": - description = await parseJson( - contents, - protocol, - parentDir, - filepath - ); + description = await parseJson(contents, protocol, filepath); break; case "opi": - description = await parseOpi(contents, protocol, parentDir, filepath); + description = await parseOpi(contents, protocol, filepath); break; } } @@ -106,8 +94,7 @@ export function useFile( const fetchData = async (): Promise => { const widgetDescription = await fetchAndConvert( file.path, - file.defaultProtocol, - macros + file.defaultProtocol ); // Populate the file cache. diff --git a/src/ui/widgets/Device/device.tsx b/src/ui/widgets/Device/device.tsx index e307929b..6e5701ed 100644 --- a/src/ui/widgets/Device/device.tsx +++ b/src/ui/widgets/Device/device.tsx @@ -57,7 +57,6 @@ export const DeviceComponent = ( componentDescription = await parseObject( jsonObject, "ca", - undefined, replacedDeviceName ); } else { diff --git a/src/ui/widgets/EmbeddedDisplay/bcfParser.ts b/src/ui/widgets/EmbeddedDisplay/bcfParser.ts index 85b9a0fb..c8f587e7 100644 --- a/src/ui/widgets/EmbeddedDisplay/bcfParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bcfParser.ts @@ -15,7 +15,6 @@ import { ParserDict, parseChildProps, parseWidget } from "./parser"; export async function parseBcf( xmlString: string, defaultProtocol: string, - filepath: string, fileId?: string ): Promise { // Convert it to a "compact format" @@ -59,14 +58,7 @@ export async function parseBcf( colors: (props: ElementCompact) => parseChildProps(props["colors"], BOB_SIMPLE_PARSERS), tabs: async (props: ElementCompact) => - bobParseTabs( - props["tabs"], - simpleParsers, - complexParsers, - filepath, - {}, - fileId - ) + bobParseTabs(props["tabs"], simpleParsers, complexParsers, fileId) }; const classFile = await parseWidget( @@ -77,8 +69,6 @@ export async function parseBcf( complexParsers, false, OPI_PATCHERS(BOB_SIMPLE_PARSERS, BOB_COMPLEX_PARSERS), - filepath, - {}, fileId, true ); diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 4b33d43a..9ebfd8a5 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -48,7 +48,6 @@ import { Axis, newAxis } from "../../../types/axis"; import { newTrace, Trace } from "../../../types/trace"; import { parsePlt } from "./pltParser"; import { scriptParser } from "./scripts/scriptParser"; -import { MacroMap } from "../../../types/macros"; import { bobParseNumber } from "./BobParsers/baseBobParsers"; import { bobParseResponsiveBreakpoints, @@ -444,8 +443,6 @@ export async function bobParseTabs( props: any, simpleParsers: ParserDict, complexParsers: ComplexParserDict, - filepath?: string, - macros?: MacroMap, fileId?: string ): Promise { const tabs = await Promise.all( @@ -467,8 +464,6 @@ export async function bobParseTabs( complexParsers, false, OPI_PATCHERS(BOB_SIMPLE_PARSERS, BOB_COMPLEX_PARSERS), - filepath, - macros, fileId ); }) @@ -700,7 +695,6 @@ export async function parseBob( xmlString: string, defaultProtocol: string, filepath: string, - macros?: MacroMap, fileId?: string ): Promise { // Convert it to a "compact format" @@ -755,14 +749,7 @@ export async function parseBob( colors: (props: ElementCompact) => parseChildProps(props["colors"], BOB_SIMPLE_PARSERS), tabs: async (props: ElementCompact) => - bobParseTabs( - props["tabs"], - simpleParsers, - complexParsers, - filepath, - macros, - fileId - ) + bobParseTabs(props["tabs"], simpleParsers, complexParsers, fileId) }; const displayWidget = await parseWidget( @@ -773,8 +760,6 @@ export async function parseBob( complexParsers, false, OPI_PATCHERS(BOB_SIMPLE_PARSERS, BOB_COMPLEX_PARSERS), - filepath, - macros, fileId ); diff --git a/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.test.tsx b/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.test.tsx index b5e26d99..ff2c3745 100644 --- a/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.test.tsx +++ b/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.test.tsx @@ -8,7 +8,6 @@ import { MacroContext } from "../../../types/macros"; import { useFile } from "../../hooks/useFile"; import { BorderStyle, newRelativePosition } from "../../../types"; import { newBorder } from "../../../types/border"; -import { newColor } from "../../../types/color"; vi.mock("../../hooks/useFile", () => ({ useFile: vi.fn(), @@ -52,11 +51,11 @@ vi.mock("../utils", () => ({ })); vi.mock("../../../types/color", () => ({ - newColor: () => "color" + newColor: () => ({ colorString: "color" }) })); vi.mock("../../../types/border", () => ({ - newBorder: (style: any) => ({ style }), + newBorder: (style: any, color: any) => ({ style, color, width: 1 }), BorderStyle: { Line: "line", GroupBox: "groupbox" } })); @@ -293,7 +292,7 @@ describe("EmbeddedDisplay (unit)", () => { const props = { ...baseProps, - border: newBorder(BorderStyle.GroupBox, newColor("white"), 1) as any + border: newBorder(BorderStyle.GroupBox, { colorString: "white" }, 1) }; const { getByTestId } = renderWithContext(); diff --git a/src/ui/widgets/EmbeddedDisplay/jsonParser.ts b/src/ui/widgets/EmbeddedDisplay/jsonParser.ts index 13dfd269..5570aa2b 100644 --- a/src/ui/widgets/EmbeddedDisplay/jsonParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/jsonParser.ts @@ -147,7 +147,6 @@ function jsonGetTargetWidget(props: any): { export async function parseObject( object: any, // eslint-disable-line @typescript-eslint/explicit-module-boundary-types defaultProtocol: string, - path?: string, fileId?: string ): Promise { const simpleParsers: ParserDict = { @@ -169,8 +168,6 @@ export async function parseObject( COMPLEX_PARSERS, true, [], - path, - undefined, fileId ); } @@ -183,13 +180,7 @@ export async function parseObject( export async function parseJson( jsonString: string, defaultProtocol: string, - path: string, fileId?: string ): Promise { - return await parseObject( - JSON.parse(jsonString), - defaultProtocol, - path, - fileId - ); + return await parseObject(JSON.parse(jsonString), defaultProtocol, fileId); } diff --git a/src/ui/widgets/EmbeddedDisplay/opiParser.test.ts b/src/ui/widgets/EmbeddedDisplay/opiParser.test.ts index 3732023a..af28bc3c 100644 --- a/src/ui/widgets/EmbeddedDisplay/opiParser.test.ts +++ b/src/ui/widgets/EmbeddedDisplay/opiParser.test.ts @@ -2,13 +2,7 @@ import log from "loglevel"; import { ColorUtils } from "../../../types/color"; import { borderNONE } from "../../../types/border"; import { Rule } from "../../../types/props"; -import { - normalisePath, - opiParseRules, - opiPatchPaths, - opiPatchRules, - parseOpi -} from "./opiParser"; +import { opiParseRules, opiPatchRules, parseOpi } from "./opiParser"; import { newAbsolutePosition, newRelativePosition @@ -18,6 +12,7 @@ import { WidgetDescription } from "../createComponent"; import { ElementCompact } from "xml-js"; import { ComplexParserDict, ParserDict } from "./parser"; import { pvQualifiedName } from "../../../types/pv"; +import { resolveAndNormaliseWidgetPaths } from "./parserPatcherUtils"; ensureWidgetsRegistered(); @@ -211,9 +206,9 @@ describe("opi widget parser", (): void => { expect(widget.actions.actions.length).toEqual(1); const action = widget.actions.actions[0]; expect(action.type).toEqual("OPEN_TAB"); - // Relative paths handled. + // Paths are resloved after file parsing as they may contain macros. expect(action.dynamicInfo.file.path).toEqual( - "prefix/dlsPLCApp_opi/vacValve_detail.opi" + "../dlsPLCApp_opi/vacValve_detail.opi" ); expect(action.dynamicInfo.description).toEqual("Open OPI"); }); @@ -432,79 +427,6 @@ $(trace_0_y_pv_value) }); }); -describe("normalisePath", (): void => { - it("returns path when no other arguments are specified", async (): Promise => { - const result = normalisePath("/a/path"); - expect(result).toBe("/a/path"); - }); - - it("returns path without .. when no other arguments are specified and path starts with ../", async (): Promise => { - const result = normalisePath("../../a/path"); - expect(result).toBe("a/path"); - }); - - it("Joins path and parent when parent is a valid url", async (): Promise => { - const result = normalisePath("/a/path", "http://test.diamond.ac.uk/"); - expect(result).toBe("http://test.diamond.ac.uk/a/path"); - }); - - it("Joins path and parent when parent is a path", async (): Promise => { - const result = normalisePath("/a/path", "/parent/path"); - expect(result).toBe("/parent/path/a/path"); - }); - - it("Joins path when path contains .. and removes trailing folders from paren path", async (): Promise => { - const result = normalisePath("../a/path", "/parent/path"); - expect(result).toBe("/parent/a/path"); - }); - - it("Returns path if path is a valid url", async (): Promise => { - const result = normalisePath( - "https://anothertest.diamond.ac.uk/a/path", - "http://test.diamond.ac.uk/" - ); - expect(result).toBe("https://anothertest.diamond.ac.uk/a/path"); - }); - - it("Does not substitute macros if macros undefined", async (): Promise => { - const result = normalisePath( - "$(some_macro)/$(another_macro)/path", - "$(another_macro)/parent" - ); - expect(result).toBe( - "$(another_macro)/parent/$(some_macro)/$(another_macro)/path" - ); - }); - - it("Substitutes macros into path if macros defined", async (): Promise => { - const result = normalisePath( - "$(some_macro)/$(another_macro)/path", - "$(another_macro)/parent", - { - some_macro: "macroPath", - another_macro: "anotherMacroPath", - absent_macro: "no_match" - } - ); - expect(result).toBe( - "$(another_macro)/parent/macroPath/anotherMacroPath/path" - ); - }); - - it("Substitutes macros into path, returns path if path becomes a fully qualified url", async (): Promise => { - const result = normalisePath( - "$(some_macro)/$(another_macro)/path", - "$(another_macro)/parent", - { - some_macro: "http://test.diamond.ac.uk", - another_macro: "anotherMacroPath", - absent_macro: "no_match" - } - ); - expect(result).toBe("http://test.diamond.ac.uk/anotherMacroPath/path"); - }); -}); - describe("opiParseRules", () => { const defaultProtocol = "ca"; @@ -816,12 +738,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, {})( - widget, - undefined, - undefined, - { "opi.number": 123 } - ); + const result = await opiPatchRules(parserDict, {})(widget, { + "opi.number": 123 + }); expect(result.rules?.[0].prop).toBe("opi.number"); @@ -844,12 +763,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, {})( - widget, - undefined, - undefined, - { "opi.flag": 123 } - ); + const result = await opiPatchRules(parserDict, {})(widget, { + "opi.flag": 123 + }); expect(result.rules?.[0].prop).toBe("flag[0]"); @@ -872,12 +788,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, {})( - widget, - undefined, - undefined, - { "opi.count": 123 } - ); + const result = await opiPatchRules(parserDict, {})(widget, { + "opi.count": 123 + }); expect(result.rules?.[0].prop).toBe("unknownProp"); expect(result.rules?.[0].expressions[0].convertedValue).toBeUndefined(); @@ -897,12 +810,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, {})( - widget, - undefined, - undefined, - { "opi.sum": 123 } - ); + const result = await opiPatchRules(parserDict, {})(widget, { + "opi.sum": 123 + }); expect(result.rules?.[0].prop).toBe("count"); expect(result.rules?.[0].expressions[0].convertedValue).toBeUndefined(); @@ -922,12 +832,10 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, {})( - widget, - undefined, - undefined, - { "opi.num": 123, "opi.text": 345 } - ); + const result = await opiPatchRules(parserDict, {})(widget, { + "opi.num": 123, + "opi.text": 345 + }); expect(result.rules?.[0].prop).toBe("opi.num"); expect(result.rules?.[0].expressions[0].convertedValue).toBe(5); @@ -985,12 +893,10 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, {})( - widget, - undefined, - undefined, - { "opi.alpha": 123, "opi.beta": 345 } - ); + const result = await opiPatchRules(parserDict, {})(widget, { + "opi.alpha": 123, + "opi.beta": 345 + }); expect(result.rules?.[0].prop).toBe("opi.alpha"); expect(result.rules?.[0].expressions[0].convertedValue).toBe("A:1"); @@ -1013,12 +919,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules({}, complexParserDict)( - widget, - undefined, - undefined, - { file: 123 } - ); + const result = await opiPatchRules({}, complexParserDict)(widget, { + file: 123 + }); expect(result.rules?.[0].prop).toBe("file"); @@ -1047,12 +950,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules({}, complexParserDict)( - widget, - undefined, - undefined, - { file345: 123 } - ); + const result = await opiPatchRules({}, complexParserDict)(widget, { + file345: 123 + }); expect(result.rules?.[0].prop).toBe("file"); @@ -1084,12 +984,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, complexParserDict)( - widget, - undefined, - undefined, - { file: 123 } - ); + const result = await opiPatchRules(parserDict, complexParserDict)(widget, { + file: 123 + }); expect(result.rules?.[0].prop).toBe("file"); @@ -1121,12 +1018,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, complexParserDict)( - widget, - undefined, - undefined, - { file: 123 } - ); + const result = await opiPatchRules(parserDict, complexParserDict)(widget, { + file: 123 + }); expect(result.rules?.[0].prop).toBe("file"); @@ -1158,12 +1052,9 @@ describe("opiPatchRules", () => { ] } as Partial as WidgetDescription; - const result = await opiPatchRules(parserDict, complexParserDict)( - widget, - undefined, - undefined, - { imageFile: 123 } - ); + const result = await opiPatchRules(parserDict, complexParserDict)(widget, { + imageFile: 123 + }); expect(result.rules?.[0].prop).toBe("imageFile"); @@ -1180,7 +1071,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1194,7 +1085,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1209,7 +1100,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1225,7 +1116,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1253,7 +1144,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1276,7 +1167,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1300,7 +1191,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1322,7 +1213,7 @@ describe("opiPatchPaths", () => { }; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); @@ -1338,7 +1229,9 @@ describe("opiPatchPaths", () => { imageFile: "img/icon.png" }; - const result = opiPatchPaths(widgetDescription as WidgetDescription); + const result = resolveAndNormaliseWidgetPaths( + widgetDescription as WidgetDescription + ); expect(result.file.path).toBe("relative/path.opi"); expect(result.imageFile).toBe("img/icon.png"); @@ -1351,7 +1244,7 @@ describe("opiPatchPaths", () => { const parentDir = "/parent/dir"; const macros = { MACRO: "expanded" }; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir, macros @@ -1367,7 +1260,7 @@ describe("opiPatchPaths", () => { const parentDir = "/parent/dir"; const macros = { MACRO: "http://example.com" }; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir, macros @@ -1380,7 +1273,7 @@ describe("opiPatchPaths", () => { const widgetDescription: Partial = {}; const parentDir = "/parent/dir"; - const result = opiPatchPaths( + const result = resolveAndNormaliseWidgetPaths( widgetDescription as WidgetDescription, parentDir ); diff --git a/src/ui/widgets/EmbeddedDisplay/opiParser.ts b/src/ui/widgets/EmbeddedDisplay/opiParser.ts index e7f2046f..114c3b13 100644 --- a/src/ui/widgets/EmbeddedDisplay/opiParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/opiParser.ts @@ -3,7 +3,7 @@ import log from "loglevel"; import { ElementCompact, xml2js } from "xml-js"; import { Rule, Expression, OpiFile } from "../../../types/props"; -import { MacroMap, resolveMacros } from "../../../types/macros"; +import { MacroMap } from "../../../types/macros"; import { Color, ColorUtils } from "../../../types/color"; import { FontStyle, Font, newFont } from "../../../types/font"; import { Border, BorderStyle, newBorder } from "../../../types/border"; @@ -33,7 +33,6 @@ import { } from "../widgetActions"; import { snakeCaseToCamelCase } from "../utils"; import { newPoint, newPoints, Point, Points } from "../../../types/points"; -import { buildUrl, isFullyQualifiedUrl } from "../../../misc/urlUtils"; import { parseArrayString } from "../../../misc/stringUtils"; export interface XmlDescription { @@ -763,11 +762,9 @@ export const OPI_COMPLEX_PARSERS: ComplexParserDict = { }; export const opiPatchRules = - (parserDict: ParserDict, complexParsers: ComplexParserDict) => + (parserDict: ParserDict, complexParsers: ComplexParserDict): PatchFunction => async ( widgetDescription: WidgetDescription, - path?: string, - macros?: MacroMap, allowedProps?: { [key: string]: unknown } ): Promise => { /* Re-index simple parsers so we can find the correct one @@ -817,127 +814,9 @@ export const opiPatchRules = return widgetDescription; }; -export function normalisePath( - path: string, - parentDir?: string, - macros?: MacroMap -): string { - let prefix = parentDir ?? ""; - while (path.startsWith("../")) { - path = path.slice(3); - prefix = prefix.slice(0, prefix.lastIndexOf("/")); - } - - // If path contains macros, we need to apply these before building the url - const resolvedPath = macros ? resolveMacros(path, macros) : path; - - return buildUrl(prefix, resolvedPath); -} - -export function opiPatchPaths( - widgetDescription: WidgetDescription, - parentDir?: string, - macros?: MacroMap -): WidgetDescription { - log.debug(`opiPatchPaths ${parentDir}`); - // file: OpiFile type - - if ( - widgetDescription["file"] && - parentDir && - !isFullyQualifiedUrl(widgetDescription["file"].path) - ) { - widgetDescription["file"].path = normalisePath( - widgetDescription["file"].path, - parentDir, - macros - ); - log.debug(`Corrected opi file to ${widgetDescription["file"].path}`); - } - // imageFile and image: just strings - for (const prop of ["imageFile", "image"]) { - // If image over http do not manipulate path. - if (isFullyQualifiedUrl(widgetDescription[prop])) { - continue; - } - if (widgetDescription[prop]) { - widgetDescription[prop] = normalisePath( - widgetDescription[prop], - parentDir, - macros - ); - log.debug(`Corrected image file to ${widgetDescription.imageFile}`); - } - } - // action.file: OpiFile type - if (widgetDescription.actions && parentDir) { - for (const action of widgetDescription.actions.actions) { - if (action.dynamicInfo) { - action.dynamicInfo.file.path = normalisePath( - action.dynamicInfo.file.path, - parentDir, - macros - ); - log.debug(`Corrected path to ${action.dynamicInfo.file.path}`); - } - } - } - - // symbols: list of string file paths - if (widgetDescription["symbols"] && parentDir) { - widgetDescription["symbols"] = widgetDescription["symbols"].map( - (symbol: string) => { - if (isFullyQualifiedUrl(symbol)) return symbol; - return normalisePath(symbol, parentDir, macros); - } - ); - // For the case where a symbol contains a rule that updates a symbol path - widgetDescription["rules"] - ?.filter((rule: any) => rule?.prop?.startsWith("symbols[")) - ?.forEach((rule: any) => { - rule?.expressions - ?.filter((expression: any) => expression.convertedValue) - ?.forEach((expression: any) => { - expression.convertedValue = normalisePath( - expression.convertedValue, - parentDir, - macros - ); - }); - }); - } - - // case where a rule contains a file - if (widgetDescription["rules"] && parentDir) { - widgetDescription["rules"] - ?.filter((rule: any) => rule?.prop?.startsWith("file")) - ?.forEach((rule: any) => { - rule?.expressions - ?.filter((expression: any) => expression?.convertedValue?.path) - ?.forEach((expression: any) => { - expression.convertedValue.path = normalisePath( - expression.convertedValue.path, - parentDir, - macros - ); - }); - }); - } - - // When a tab widget contains a file - if (widgetDescription["tabs"] && parentDir) { - widgetDescription["tabs"].forEach((tab: any) => { - if (isFullyQualifiedUrl(tab.file)) return; - tab.file = normalisePath(tab.file, parentDir, macros); - }); - } - - return widgetDescription; -} - -function opiPatchActions( +const opiPatchActions: PatchFunction = ( widgetDescription: WidgetDescription -): WidgetDescription { +): WidgetDescription => { if ( widgetDescription.type === "actionbutton" && widgetDescription.text && @@ -961,21 +840,19 @@ function opiPatchActions( } } return widgetDescription; -} +}; export const OPI_PATCHERS = ( parserDict: ParserDict, complexParsers: ComplexParserDict ): PatchFunction[] => [ opiPatchRules(parserDict, complexParsers), - opiPatchPaths, opiPatchActions ]; export async function parseOpi( xmlString: string, defaultProtocol: string, - filepath: string, fileId?: string ): Promise { // Convert it to a "compact format" @@ -1017,8 +894,6 @@ export async function parseOpi( complexParsers, false, OPI_PATCHERS(OPI_SIMPLE_PARSERS, OPI_COMPLEX_PARSERS), - filepath, - undefined, fileId ); diff --git a/src/ui/widgets/EmbeddedDisplay/parser.ts b/src/ui/widgets/EmbeddedDisplay/parser.ts index 20e89bf0..b82211ed 100644 --- a/src/ui/widgets/EmbeddedDisplay/parser.ts +++ b/src/ui/widgets/EmbeddedDisplay/parser.ts @@ -59,10 +59,14 @@ export type ComplexParserDict = { [key: string]: (value: any) => GenericProp | Promise; }; -export type PatchFunction = ( +export type MutatingPatchFunction = ( props: WidgetDescription, path?: string, - macros?: MacroMap, + macros?: MacroMap +) => WidgetDescription | Promise; + +export type PatchFunction = ( + props: WidgetDescription, allowedProps?: { [key: string]: unknown } ) => WidgetDescription | Promise; @@ -188,8 +192,6 @@ export async function parseWidget( complexParsers: ComplexParserDict, passThrough: boolean, patchFunctions: PatchFunction[], - filepath?: string, - macros?: MacroMap, fileId?: string, classFile?: boolean ): Promise { @@ -205,12 +207,7 @@ export async function parseWidget( ); // Execute patch functions. for (const patcher of patchFunctions) { - widgetDescription = await patcher( - widgetDescription, - filepath, - macros, - allowedProps - ); + widgetDescription = await patcher(widgetDescription, allowedProps); } /* Child widgets */ const childWidgets = toArray(props[childrenName]); @@ -224,8 +221,6 @@ export async function parseWidget( complexParsers, passThrough, patchFunctions, - filepath, - macros, fileId, classFile ); @@ -248,7 +243,7 @@ export async function parseWidget( widgetDescription.wrapWords = true; } - widgetDescription.fileId = fileId ?? filepath ?? ""; + widgetDescription.fileId = fileId ?? ""; return widgetDescription; } diff --git a/src/ui/widgets/EmbeddedDisplay/parserPatcherUtils.test.ts b/src/ui/widgets/EmbeddedDisplay/parserPatcherUtils.test.ts new file mode 100644 index 00000000..ca88dada --- /dev/null +++ b/src/ui/widgets/EmbeddedDisplay/parserPatcherUtils.test.ts @@ -0,0 +1,203 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { resolveAndNormaliseWidgetPaths } from "./parserPatcherUtils"; +import * as urlUtils from "../../../misc/urlUtils"; +import { normalisePath } from "../../../misc/urlUtils"; + +vi.mock("../../../misc/urlUtils", () => ({ + normalisePath: vi.fn(path => `resolved:${path}`), + isFullyQualifiedUrl: vi.fn( + path => typeof path === "string" && path.startsWith("http") + ) +})); + +const isFullyQualifiedUrl = + urlUtils.isFullyQualifiedUrl as unknown as ReturnType; + +describe("resolveAndNormaliseWidgetPaths", () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + + it("mutates and returns the same object", () => { + const widget: any = { type: "test" }; + + const result = resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(result).toBe(widget); + }); + + it("resolves file.path if not fully qualified", () => { + const widget: any = { + file: { path: "file.opi" } + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", { A: "1" }); + + expect(normalisePath).toHaveBeenCalledWith("file.opi", "/parent", { + A: "1" + }); + + expect(widget.file.path).toBe("resolved:file.opi"); + }); + + it("skips file.path if already fully qualified", () => { + isFullyQualifiedUrl.mockReturnValue(true); + + const widget: any = { + file: { path: "http://example.com/file.opi" } + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(normalisePath).not.toHaveBeenCalled(); + }); + + it("resolves imageFile and image", () => { + const widget: any = { + imageFile: "img.png", + image: "img2.png" + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.imageFile).toBe("resolved:img.png"); + expect(widget.image).toBe("resolved:img2.png"); + }); + + it("skips image if fully qualified URL", () => { + isFullyQualifiedUrl.mockImplementation( + path => path && path?.startsWith("http") + ); + + const widget: any = { + image: "http://example.com/img.png" + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(normalisePath).not.toHaveBeenCalled(); + }); + + it("resolves action dynamicInfo file paths", () => { + const widget: any = { + actions: { + actions: [ + { + dynamicInfo: { + file: { path: "action.opi" } + } + } + ] + } + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.actions.actions[0].dynamicInfo.file.path).toBe( + "resolved:action.opi" + ); + }); + + it("resolves symbols paths", () => { + const widget: any = { + symbols: ["a.sym", "b.sym"] + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.symbols).toEqual(["resolved:a.sym", "resolved:b.sym"]); + }); + + it("skips fully qualified symbols", () => { + isFullyQualifiedUrl.mockImplementation( + path => path && path?.startsWith("http") + ); + + const widget: any = { + symbols: ["http://example.com/a.sym"] + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.symbols[0]).toBe("http://example.com/a.sym"); + }); + + it("resolves symbol paths inside rules expressions", () => { + const widget: any = { + symbols: ["a.sym"], + rules: [ + { + prop: "symbols[0]", + expressions: [ + { + convertedValue: "rule.sym" + } + ] + } + ] + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.rules[0].expressions[0].convertedValue).toBe( + "resolved:rule.sym" + ); + }); + + it("resolves rule file paths", () => { + const widget: any = { + rules: [ + { + prop: "file", + expressions: [ + { + convertedValue: { + path: "rule.opi" + } + } + ] + } + ] + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.rules[0].expressions[0].convertedValue.path).toBe( + "resolved:rule.opi" + ); + }); + + it("resolves tab file paths", () => { + const widget: any = { + tabs: [{ file: "tab1.opi" }, { file: "tab2.opi" }] + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(widget.tabs[0].file).toBe("resolved:tab1.opi"); + expect(widget.tabs[1].file).toBe("resolved:tab2.opi"); + }); + + it("skips tab file if fully qualified", () => { + isFullyQualifiedUrl.mockReturnValue(true); + + const widget: any = { + tabs: [{ file: "http://example.com/tab.opi" }] + }; + + resolveAndNormaliseWidgetPaths(widget, "/parent", {}); + + expect(normalisePath).not.toHaveBeenCalled(); + }); + + it("only skips sections that require parentDir when missing", () => { + const widget: any = { + file: { path: "file.opi" }, + image: "img.png" + }; + + resolveAndNormaliseWidgetPaths(widget, undefined, {}); + + expect(normalisePath).toHaveBeenCalledWith("img.png", undefined, {}); + }); +}); diff --git a/src/ui/widgets/EmbeddedDisplay/parserPatcherUtils.ts b/src/ui/widgets/EmbeddedDisplay/parserPatcherUtils.ts new file mode 100644 index 00000000..18280046 --- /dev/null +++ b/src/ui/widgets/EmbeddedDisplay/parserPatcherUtils.ts @@ -0,0 +1,120 @@ +import log from "loglevel"; +import { normalisePath, isFullyQualifiedUrl } from "../../../misc/urlUtils"; +import { MacroMap } from "../../../types/macros"; +import { WidgetDescription } from "../createComponent"; + +/** + * Mutates the path-related attributes of a widget by resolving and applying + * the provided macros to any paths it contains. + * + * Since macro values may differ between files, this transformation must be + * performed after the widget has been fully parsed. + * + * In addition to macro substitution, any relative paths are resolved against + * the parent directory and converted to absolute paths. + * + * @param widgetDescription - The widget description object to update. + * @param parentDir - The absolute URL or file system path of the parent directory, + * used as the base for resolving relative paths. + * @param macros - A key-value map of macros to substitute into path values. + * @returns The updated widget description with macros resolved and all paths normalized to absolute. + */ +export const resolveAndNormaliseWidgetPaths = ( + widgetDescription: WidgetDescription, + parentDir?: string, + macros?: MacroMap +): WidgetDescription => { + log.debug(`resolveAndNormaliseWidgetPaths ${parentDir}`); + + if ( + widgetDescription["file"] && + parentDir && + !isFullyQualifiedUrl(widgetDescription["file"].path) + ) { + widgetDescription["file"].path = normalisePath( + widgetDescription["file"].path, + parentDir, + macros + ); + log.debug(`Corrected opi file to ${widgetDescription["file"].path}`); + } + // imageFile and image: just strings + for (const prop of ["imageFile", "image"]) { + // If image over http do not manipulate path. + if (isFullyQualifiedUrl(widgetDescription[prop])) { + continue; + } + if (widgetDescription[prop]) { + widgetDescription[prop] = normalisePath( + widgetDescription[prop], + parentDir, + macros + ); + log.debug(`Corrected image file to ${widgetDescription.imageFile}`); + } + } + // action.file: OpiFile type + if (widgetDescription.actions && parentDir) { + for (const action of widgetDescription.actions.actions) { + if (action.dynamicInfo) { + action.dynamicInfo.file.path = normalisePath( + action.dynamicInfo.file.path, + parentDir, + macros + ); + log.debug(`Corrected path to ${action.dynamicInfo.file.path}`); + } + } + } + + // symbols: list of string file paths + if (widgetDescription["symbols"] && parentDir) { + widgetDescription["symbols"] = widgetDescription["symbols"].map( + (symbol: string) => { + if (isFullyQualifiedUrl(symbol)) return symbol; + return normalisePath(symbol, parentDir, macros); + } + ); + // For the case where a symbol contains a rule that updates a symbol path + widgetDescription["rules"] + ?.filter((rule: any) => rule?.prop?.startsWith("symbols[")) + ?.forEach((rule: any) => { + rule?.expressions + ?.filter((expression: any) => expression.convertedValue) + ?.forEach((expression: any) => { + expression.convertedValue = normalisePath( + expression.convertedValue, + parentDir, + macros + ); + }); + }); + } + + // case where a rule contains a file + if (widgetDescription["rules"] && parentDir) { + widgetDescription["rules"] + ?.filter((rule: any) => rule?.prop?.startsWith("file")) + ?.forEach((rule: any) => { + rule?.expressions + ?.filter((expression: any) => expression?.convertedValue?.path) + ?.forEach((expression: any) => { + expression.convertedValue.path = normalisePath( + expression.convertedValue.path, + parentDir, + macros + ); + }); + }); + } + + // When a tab widget contains a file + if (widgetDescription["tabs"] && parentDir) { + widgetDescription["tabs"].forEach((tab: any) => { + if (isFullyQualifiedUrl(tab.file)) return; + tab.file = normalisePath(tab.file, parentDir, macros); + }); + } + + return widgetDescription; +}; diff --git a/src/ui/widgets/EmbeddedDisplay/pltParser.ts b/src/ui/widgets/EmbeddedDisplay/pltParser.ts index bed27f30..5470e5a4 100644 --- a/src/ui/widgets/EmbeddedDisplay/pltParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/pltParser.ts @@ -4,9 +4,9 @@ import { XmlDescription, opiParseBoolean, opiParseString, - opiParseNumber, - normalisePath + opiParseNumber } from "./opiParser"; +import { normalisePath } from "../../../misc/urlUtils"; import { parseChildProps, ParserDict } from "./parser"; import { Axis, newAxis } from "../../../types/axis"; import { Archiver, newTrace, Trace } from "../../../types/trace"; diff --git a/src/ui/widgets/Tabs/dynamicTabs.test.tsx b/src/ui/widgets/Tabs/dynamicTabs.test.tsx index 4fac22b2..9645dd2e 100644 --- a/src/ui/widgets/Tabs/dynamicTabs.test.tsx +++ b/src/ui/widgets/Tabs/dynamicTabs.test.tsx @@ -16,6 +16,10 @@ vi.spyOn(global, "fetch").mockImplementation( ) as Mock ); +vi.mock("../EmbeddedDisplay/embeddedDisplay", () => ({ + EmbeddedDisplay: () =>
+})); + const TAB_ONE: FileDescription = { path: "one.json", macros: {}, diff --git a/src/ui/widgets/Tabs/navigationTabs.tsx b/src/ui/widgets/Tabs/navigationTabs.tsx index 2796c917..7b92cf6f 100644 --- a/src/ui/widgets/Tabs/navigationTabs.tsx +++ b/src/ui/widgets/Tabs/navigationTabs.tsx @@ -52,7 +52,7 @@ export const NavigationTabsComponent = ( resize={0} file={{ path: tab.file, - macros: tab.macros, + macros: tab.macros ?? {}, defaultProtocol: tab.protocol ?? "ca" }} /> diff --git a/src/ui/widgets/Tabs/tabs.tsx b/src/ui/widgets/Tabs/tabs.tsx index 91b30eae..359e68f6 100644 --- a/src/ui/widgets/Tabs/tabs.tsx +++ b/src/ui/widgets/Tabs/tabs.tsx @@ -135,7 +135,7 @@ export const TabBar = (props: TabComponentProps): JSX.Element => { newProps?.onTabClosed?.(index)} > diff --git a/vite.config.ts b/vite.config.ts index 8daa99e0..cb523847 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,13 +1,14 @@ import { defineConfig, loadEnv } from 'vite'; -import { nodePolyfills } from "vite-plugin-node-polyfills"; import react from '@vitejs/plugin-react'; -import eslint from 'vite-plugin-eslint'; // https://vitejs.dev/config/ export default defineConfig(({ command, mode }) => { const env = loadEnv(mode, process.cwd(), ''); return { - plugins: [react(), eslint(), nodePolyfills()], + plugins: [react()], + resolve: { + dedupe: ['react', 'react-dom'] + }, test: { environment: 'jsdom', include: ['**/*.test.ts', '**/*.test.tsx'],