diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 00000000000..94f3f791b7e --- /dev/null +++ b/.mise.toml @@ -0,0 +1,2 @@ +[settings] +python.github_attestations = false diff --git a/.nvmrc b/.nvmrc index 9de2256827a..2bd5a0a98a3 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -lts/iron +22 diff --git a/mise.toml b/mise.toml new file mode 100644 index 00000000000..76517acf39e --- /dev/null +++ b/mise.toml @@ -0,0 +1,5 @@ +[settings] +python.github_attestations = false + +[tools] +node = "22" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4b99376ec2b..1f56dcda979 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,7 +62,7 @@ "date-fns-tz": "^2.0.1", "dayjs": "^1.11.13", "diff": "^5.2.2", - "dompurify": "^3.4.12", + "dompurify": "^3.4.16", "elliptic": "^6.6.1", "font-awesome": "^4.7.0", "fs-extra": "^11.3.0", @@ -71,7 +71,7 @@ "html-to-pdfmake": "^2.0.6", "html2canvas": "^1.4.1", "jest": "^30.2.0", - "joi": "^18.2.1", + "joi": "^18.2.5", "joi-browser": "^13.4.0", "jquery": "^3.7.1", "jspdf": "^4.2.1", @@ -84,7 +84,7 @@ "lodash": "^4.17.21", "lucide-react": "^0.484.0", "micromatch": "^4.0.8", - "moment": "^2.30.1", + "moment": "^2.31.0", "moment-timezone": "^0.5.33", "object-hash": "^3.0.0", "path-browserify": "^1.0.1", @@ -145,7 +145,7 @@ "xlsx": "^0.18.5" }, "devDependencies": { - "@babel/core": "^7.28.0", + "@babel/core": "^7.29.6", "@babel/eslint-parser": "^7.28.0", "@babel/helper-validator-identifier": "^7.12.11", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", @@ -192,7 +192,7 @@ "stylelint-config-css-modules": "^4.5.1", "stylelint-config-standard": "^39.0.1", "typescript": "^4.8.4", - "vite": "^6.3.5", + "vite": "^6.4.3", "vitest": "^3.2.4" }, "engines": { @@ -210,6 +210,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -248,12 +249,12 @@ } }, "node_modules/@ant-design/colors": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.2.1.tgz", - "integrity": "sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz", + "integrity": "sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==", "license": "MIT", "dependencies": { - "@ant-design/fast-color": "^2.0.6" + "@ant-design/fast-color": "^3.0.0" } }, "node_modules/@ant-design/cssinjs": { @@ -303,19 +304,16 @@ "license": "MIT" }, "node_modules/@ant-design/cssinjs/node_modules/stylis": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", - "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz", + "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", "license": "MIT" }, "node_modules/@ant-design/fast-color": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.6.tgz", - "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-3.0.1.tgz", + "integrity": "sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.24.7" - }, "engines": { "node": ">=8.x" } @@ -405,24 +403,6 @@ "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", "license": "MIT" }, - "node_modules/@ant-design/icons/node_modules/@ant-design/colors": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz", - "integrity": "sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==", - "license": "MIT", - "dependencies": { - "@ant-design/fast-color": "^3.0.0" - } - }, - "node_modules/@ant-design/icons/node_modules/@ant-design/fast-color": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-3.0.1.tgz", - "integrity": "sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==", - "license": "MIT", - "engines": { - "node": ">=8.x" - } - }, "node_modules/@ant-design/plots": { "version": "2.6.8", "resolved": "https://registry.npmjs.org/@ant-design/plots/-/plots-2.6.8.tgz", @@ -569,12 +549,12 @@ "license": "MIT" }, "node_modules/@antv/g": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@antv/g/-/g-6.3.1.tgz", - "integrity": "sha512-WYEKqy86LHB2PzTmrZXrIsIe+3Epeds2f68zceQ+BJtRoGki7Sy4IhlC8LrUMztgfT1t3d/0L745NWZwITroKA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@antv/g/-/g-6.3.3.tgz", + "integrity": "sha512-Fs07ACQ7LqIpGFhL1wrVhdNbpsezL+vZKzKnKQj3dFzmEHu3S0sSumJtx2iCjy5shQPDWFu8vqSRdYrZdTVlGg==", "license": "MIT", "dependencies": { - "@antv/g-lite": "2.7.0", + "@antv/g-lite": "2.7.2", "@antv/util": "^3.3.5", "@babel/runtime": "^7.25.6", "gl-matrix": "^3.4.3", @@ -595,7 +575,7 @@ "tslib": "^2.5.3" } }, - "node_modules/@antv/g-lite": { + "node_modules/@antv/g-canvas/node_modules/@antv/g-lite": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/@antv/g-lite/-/g-lite-2.7.0.tgz", "integrity": "sha512-uSzgHYa5bwR5L2Au7/5tsOhFmXKZKLPBH90+Q9bP9teVs5VT4kOAi0isPSpDI8uhdDC2/VrfTWu5K9HhWI6FWw==", @@ -610,11 +590,20 @@ "tslib": "^2.5.3" } }, - "node_modules/@antv/g-lite/node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "license": "MIT" + "node_modules/@antv/g-lite": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@antv/g-lite/-/g-lite-2.7.2.tgz", + "integrity": "sha512-hno43swzUX3jBSi26O0l9YJxRVTiZ5HcNb3K6YKf8DRyT/hDo1zvnyD3vm/AmNa9va+3W76VznKgJThn4zRhYw==", + "license": "MIT", + "dependencies": { + "@antv/g-math": "3.1.0", + "@antv/util": "^3.3.5", + "@antv/vendor": "^1.0.3", + "@babel/runtime": "^7.25.6", + "eventemitter3": "^5.0.1", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } }, "node_modules/@antv/g-math": { "version": "3.1.0", @@ -640,6 +629,21 @@ "tslib": "^2.5.3" } }, + "node_modules/@antv/g-plugin-dragndrop/node_modules/@antv/g-lite": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@antv/g-lite/-/g-lite-2.7.0.tgz", + "integrity": "sha512-uSzgHYa5bwR5L2Au7/5tsOhFmXKZKLPBH90+Q9bP9teVs5VT4kOAi0isPSpDI8uhdDC2/VrfTWu5K9HhWI6FWw==", + "license": "MIT", + "dependencies": { + "@antv/g-math": "3.1.0", + "@antv/util": "^3.3.5", + "@antv/vendor": "^1.0.3", + "@babel/runtime": "^7.25.6", + "eventemitter3": "^5.0.1", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } + }, "node_modules/@antv/g-svg": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@antv/g-svg/-/g-svg-2.1.1.tgz", @@ -653,6 +657,21 @@ "tslib": "^2.5.3" } }, + "node_modules/@antv/g-svg/node_modules/@antv/g-lite": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@antv/g-lite/-/g-lite-2.7.0.tgz", + "integrity": "sha512-uSzgHYa5bwR5L2Au7/5tsOhFmXKZKLPBH90+Q9bP9teVs5VT4kOAi0isPSpDI8uhdDC2/VrfTWu5K9HhWI6FWw==", + "license": "MIT", + "dependencies": { + "@antv/g-math": "3.1.0", + "@antv/util": "^3.3.5", + "@antv/vendor": "^1.0.3", + "@babel/runtime": "^7.25.6", + "eventemitter3": "^5.0.1", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } + }, "node_modules/@antv/g2": { "version": "5.4.8", "resolved": "https://registry.npmjs.org/@antv/g2/-/g2-5.4.8.tgz", @@ -858,12 +877,12 @@ "license": "ISC" }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -872,30 +891,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -949,13 +968,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -978,13 +997,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -1080,9 +1099,9 @@ } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1103,27 +1122,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "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==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1146,9 +1165,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1205,27 +1224,27 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "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==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "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==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1247,13 +1266,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", - "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz", + "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==", "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8" }, "engines": { "node": ">=6.9.0" @@ -1354,12 +1373,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", - "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -1706,12 +1725,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -2159,16 +2178,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", - "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.8.tgz", + "integrity": "sha512-6iSnEK0zlkLKU4heofK/AdmRD4e2SHVpJMtrwnTCzhnaM98ria4rTrOXBBi45BTTYnJtO8txnPsX4fChYXkmeA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.8" }, "engines": { "node": ">=6.9.0" @@ -2847,31 +2866,31 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", - "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz", + "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.3", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.9", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -2879,13 +2898,13 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -3150,9 +3169,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.8.tgz", - "integrity": "sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.9.tgz", + "integrity": "sha512-iGGw4OsAYsS6pD29MdJ2bX/nJx65a04ZZiw6x+VwWlP2DdXf6f++Zmuv/OzALpdyfVhjbduIIF2cXM7HWBIe9A==", "dev": true, "funding": [ { @@ -4064,9 +4083,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -4273,6 +4292,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.6.tgz", "integrity": "sha512-mtBFIi1UsYQo7rYonYFkjgYKGoL8T+fEH6NGUpvuqtY3ytMsAoDaPo5rk25KuMtKDipY4bGYM/CkmCHA1N3FUg==", + "deprecated": "v0.2.x is no longer supported. Unless you are still using FontAwesome 5, please update to v3.1.1 or greater.", "license": "MIT", "dependencies": { "prop-types": "^15.8.1" @@ -4478,22 +4498,6 @@ } } }, - "node_modules/@inquirer/core/node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@inquirer/core/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4526,19 +4530,6 @@ "node": ">=8" } }, - "node_modules/@inquirer/core/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@inquirer/core/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -4611,35 +4602,6 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", @@ -4655,23 +4617,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4698,9 +4643,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -4720,39 +4665,26 @@ } }, "node_modules/@jest/console": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", - "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.5.2.tgz", + "integrity": "sha512-e8sQC4pCMHPBrPX7Hk8TJr+DM5dkUnImSTNag8SEWFAFAF6xIz4AJvCKapnrdHnZxep4bxw4PhG+ZbimYBMyKw==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", + "jest-message-util": "30.5.1", + "jest-util": "30.5.1", "slash": "^3.0.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/console/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/console/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -4762,13 +4694,13 @@ } }, "node_modules/@jest/console/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -4780,9 +4712,9 @@ } }, "node_modules/@jest/console/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/@jest/console/node_modules/ansi-styles": { @@ -4797,35 +4729,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/console/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/console/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -4833,22 +4750,13 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/console/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/console/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -4860,9 +4768,9 @@ } }, "node_modules/@jest/console/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -4872,32 +4780,32 @@ } }, "node_modules/@jest/console/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/core": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", - "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.5.2.tgz", + "integrity": "sha512-/jqvFWoJF7LV1a6AUpYMbMm+2yIYsHJfR474H0SCzr9k8tnO/jl9wRg6zSG6lxgf6EozNlCG4amFzWsbZSvvZA==", "license": "MIT", "dependencies": { - "@jest/console": "30.4.1", - "@jest/pattern": "30.4.0", - "@jest/reporters": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", + "@jest/console": "30.5.2", + "@jest/pattern": "30.5.0", + "@jest/reporters": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", @@ -4905,20 +4813,20 @@ "exit-x": "^0.2.2", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.4.1", - "jest-config": "30.4.2", - "jest-haste-map": "30.4.1", - "jest-message-util": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-resolve-dependencies": "30.4.2", - "jest-runner": "30.4.2", - "jest-runtime": "30.4.2", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", - "jest-watcher": "30.4.1", - "pretty-format": "30.4.1", + "jest-changed-files": "30.5.1", + "jest-config": "30.5.2", + "jest-haste-map": "30.5.1", + "jest-message-util": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-resolve": "30.5.1", + "jest-resolve-dependencies": "30.5.2", + "jest-runner": "30.5.2", + "jest-runtime": "30.5.2", + "jest-snapshot": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", + "jest-watcher": "30.5.2", + "pretty-format": "30.5.1", "slash": "^3.0.0" }, "engines": { @@ -4933,87 +4841,53 @@ } } }, - "node_modules/@jest/core/node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", + "node_modules/@jest/core/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", + "node_modules/@jest/core/node_modules/@jest/transform": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0" + "@babel/core": "^7.27.4", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", "@types/yargs": "^17.0.33", "chalk": "^4.1.2" @@ -5023,26 +4897,11 @@ } }, "node_modules/@jest/core/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/@jest/core/node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -5056,9 +4915,9 @@ } }, "node_modules/@jest/core/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "license": "BSD-3-Clause", "workspaces": [ "test/babel-8" @@ -5068,42 +4927,27 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@jest/core/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/@jest/core/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" + "node": ">=12.0.0" }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/@jest/core/node_modules/istanbul-lib-instrument": { @@ -5122,74 +4966,42 @@ "node": ">=10" } }, - "node_modules/@jest/core/node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/core/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/@jest/core/node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -5197,68 +5009,22 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/core/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core/node_modules/jest-snapshot": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.4.1", - "graceful-fs": "^4.2.11", - "jest-diff": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "pretty-format": "30.4.1", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/core/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -5269,26 +5035,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/core/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -5298,47 +5048,20 @@ } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@jest/core/node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", @@ -5353,10 +5076,9 @@ } }, "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", - "dev": true, + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.5.0.tgz", + "integrity": "sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -5379,30 +5101,34 @@ } }, "node_modules/@jest/expect": { + "name": "@jest/fake-timers", "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.5.2.tgz", + "integrity": "sha512-d/HOLSrJUlBIl6n3LzOa7cjW3xdePm5H5gQw2lixZ/0h157l9sw3mLblzFqnPcTbhDzhRQdBOX3A3KcG73nm5Q==", "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3" + "@jest/get-type": "30.5.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/fake-timers": { @@ -5424,9 +5150,9 @@ } }, "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.5.0.tgz", + "integrity": "sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -5449,55 +5175,67 @@ } }, "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "dev": true, + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.5.0.tgz", + "integrity": "sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==", "license": "MIT", "dependencies": { "@types/node": "*", - "jest-regex-util": "30.0.1" + "jest-regex-util": "30.5.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/pattern/node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "dev": true, + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/@jest/react-is-18": { + "name": "react-is", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/@jest/react-is-19": { + "name": "react-is", + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.1.tgz", + "integrity": "sha512-RRieF6IyxQBkcK6pP8xOHprLTPW6QjRkbGdImtqNme+/hYVwCZkLQLdlZGOhUqXwkS9IEynaGvPJtv6XB/cz0Q==", + "license": "MIT" + }, "node_modules/@jest/reporters": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", - "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.5.2.tgz", + "integrity": "sha512-ev6E9iG73twQcfAfoTnviuYkr3yOrYbzAtMFCimv2fxHXPIp9PBt2u1wNMt0aYWgl8FPwIcS8oqRJg6alnht4Q==", "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", + "@jest/console": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", "@types/node": "*", "chalk": "^4.1.2", "collect-v8-coverage": "^1.0.2", "exit-x": "^0.2.2", - "glob": "^10.5.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", + "jest-message-util": "30.5.1", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -5520,23 +5258,10 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "license": "MIT" }, - "node_modules/@jest/reporters/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/reporters/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -5546,22 +5271,22 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -5571,13 +5296,13 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -5589,9 +5314,9 @@ } }, "node_modules/@jest/reporters/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/@jest/reporters/node_modules/ansi-styles": { @@ -5607,9 +5332,9 @@ } }, "node_modules/@jest/reporters/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "license": "BSD-3-Clause", "workspaces": [ "test/babel-8" @@ -5619,52 +5344,62 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@jest/reporters/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, - "node_modules/@jest/reporters/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/@jest/reporters/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5687,43 +5422,41 @@ } }, "node_modules/@jest/reporters/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" } }, "node_modules/@jest/reporters/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -5732,21 +5465,21 @@ } }, "node_modules/@jest/reporters/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -5757,41 +5490,50 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/reporters/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", + "node_modules/@jest/reporters/node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "license": "BlueOak-1.0.0", "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", + "node_modules/@jest/reporters/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@jest/reporters/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -5801,35 +5543,20 @@ } }, "node_modules/@jest/reporters/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@jest/reporters/node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", @@ -5857,12 +5584,12 @@ } }, "node_modules/@jest/snapshot-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", - "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.5.1.tgz", + "integrity": "sha512-V3wnxNtiVmw5PPVg433Cn3VdXnsOeu/ofLw3KC04Bn2y1wIlU5kozXQn48rhrgj/02LrCVtntTEF1yBha0XSUw==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -5871,23 +5598,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/snapshot-utils/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/snapshot-utils/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -5897,13 +5611,13 @@ } }, "node_modules/@jest/snapshot-utils/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -5915,28 +5629,20 @@ } }, "node_modules/@jest/snapshot-utils/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/@jest/snapshot-utils/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.5.2.tgz", + "integrity": "sha512-c5CehvkbfHX6yyNg7bMn2ylqlp9AHXuZ/3hPH/Lh5bxD/vefd/lV9HBjMqXef9yQNqkdwyZvkLSVSwB38hy8Qw==", "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", + "@jridgewell/trace-mapping": "^0.3.31", "callsites": "^3.1.0", + "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.11" }, "engines": { @@ -5944,13 +5650,13 @@ } }, "node_modules/@jest/test-result": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", - "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.5.2.tgz", + "integrity": "sha512-eO6YU5rsLfs60ne694e0IAmRgeBnoA8mu0nlxXDbl/1j5km0o2vO9/VbbUIKIH+WRKKEI+ELgwraRGn2Lhep8g==", "license": "MIT", "dependencies": { - "@jest/console": "30.4.1", - "@jest/types": "30.4.1", + "@jest/console": "30.5.2", + "@jest/types": "30.5.1", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" }, @@ -5958,23 +5664,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-result/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/test-result/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -5984,13 +5677,13 @@ } }, "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -6002,52 +5695,30 @@ } }, "node_modules/@jest/test-result/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/@jest/test-result/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/test-sequencer": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", - "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.5.2.tgz", + "integrity": "sha512-bmij8jZyYAC47ExT2GeP7PcrlwSNS+Bp3KeRuBH88gpcxqDv6fljN8PemS4J/lLZ79xb6mpaennQTTq0zUAVVg==", "license": "MIT", "dependencies": { - "@jest/test-result": "30.4.1", + "@jest/test-result": "30.5.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", + "jest-haste-map": "30.5.1", "slash": "^3.0.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/test-sequencer/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -6057,13 +5728,13 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -6075,66 +5746,66 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/@jest/test-sequencer/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/@jest/test-sequencer/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" } }, "node_modules/@jest/test-sequencer/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/test-sequencer/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -6145,26 +5816,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/test-sequencer/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -6173,21 +5828,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@jest/test-sequencer/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@jest/transform": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", @@ -6243,6 +5883,16 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -6517,13 +6167,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.1.tgz", - "integrity": "sha512-WU3YLkKXii/x8ZEKnrLKsPwplCVE11yZxUvlaaZSIzCcI3x2OdFC8eMlNy74hVeUsYQvzzX1Es/k4ARPlFvpPQ==", + "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==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.2", - "@mui/utils": "^7.3.1", + "@babel/runtime": "^7.28.6", + "@mui/utils": "^7.3.11", "prop-types": "^15.8.1" }, "engines": { @@ -6544,16 +6194,16 @@ } }, "node_modules/@mui/styled-engine": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.1.tgz", - "integrity": "sha512-Nqo6OHjvJpXJ1+9TekTE//+8RybgPQUKwns2Lh0sq+8rJOUSUKS3KALv4InSOdHhIM9Mdi8/L7LTF1/Ky6D6TQ==", + "version": "7.3.10", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.10.tgz", + "integrity": "sha512-WxE9SiF8xskAQqGjsp0poXCkCqsoXFEsSr0HBXfApmGHR+DBnXRp+z46Vsltg4gpPM4Z96DeAQRpeAOnhNg7Ng==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.2", + "@babel/runtime": "^7.28.6", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", - "csstype": "^3.1.3", + "csstype": "^3.2.3", "prop-types": "^15.8.1" }, "engines": { @@ -6578,18 +6228,18 @@ } }, "node_modules/@mui/system": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.1.tgz", - "integrity": "sha512-mIidecvcNVpNJMdPDmCeoSL5zshKBbYPcphjuh6ZMjhybhqhZ4mX6k9zmIWh6XOXcqRQMg5KrcjnO0QstrNj3w==", + "version": "7.3.11", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.11.tgz", + "integrity": "sha512-7izwGWdNawAKpBKcRlx7f2gFnAAjmASBWvMcyX4YYEeLOFsbfGRbUYGInvnAcUeql3rPxI7F9Ft4oY2OLRz44g==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.2", - "@mui/private-theming": "^7.3.1", - "@mui/styled-engine": "^7.3.1", - "@mui/types": "^7.4.5", - "@mui/utils": "^7.3.1", + "@babel/runtime": "^7.28.6", + "@mui/private-theming": "^7.3.11", + "@mui/styled-engine": "^7.3.10", + "@mui/types": "^7.4.12", + "@mui/utils": "^7.3.11", "clsx": "^2.1.1", - "csstype": "^3.1.3", + "csstype": "^3.2.3", "prop-types": "^15.8.1" }, "engines": { @@ -6618,12 +6268,12 @@ } }, "node_modules/@mui/types": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.5.tgz", - "integrity": "sha512-ZPwlAOE3e8C0piCKbaabwrqZbW4QvWz0uapVPWya7fYj6PeDkl5sSJmomT7wjOcZGPB48G/a6Ubidqreptxz4g==", + "version": "7.4.12", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.12.tgz", + "integrity": "sha512-iKNAF2u9PzSIj40CjvKJWxFXJo122jXVdrmdh0hMYd+FR+NuJMkr/L88XwWLCRiJ5P1j+uyac25+Kp6YC4hu6w==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.2" + "@babel/runtime": "^7.28.6" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -6635,17 +6285,17 @@ } }, "node_modules/@mui/utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.1.tgz", - "integrity": "sha512-/31y4wZqVWa0jzMnzo6JPjxwP6xXy4P3+iLbosFg/mJQowL1KIou0LC+lquWW60FKVbKz5ZUWBg2H3jausa0pw==", + "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==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.2", - "@mui/types": "^7.4.5", + "@babel/runtime": "^7.28.6", + "@mui/types": "^7.4.12", "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^19.1.1" + "react-is": "^19.2.3" }, "engines": { "node": ">=14.0.0" @@ -6664,6 +6314,12 @@ } } }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.1.tgz", + "integrity": "sha512-RRieF6IyxQBkcK6pP8xOHprLTPW6QjRkbGdImtqNme+/hYVwCZkLQLdlZGOhUqXwkS9IEynaGvPJtv6XB/cz0Q==", + "license": "MIT" + }, "node_modules/@mui/x-date-pickers": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-8.11.0.tgz", @@ -6752,22 +6408,42 @@ "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.6.tgz", + "integrity": "sha512-mRyDmEw9/fCDXCGfL1sbgIw/GUK0PVxRW4YwgPN61F3LQ+fSyoBFarJVzgGyhF6kRzEQZ0FejDqm4WLXSeqQmw==", "license": "MIT", "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "@emnapi/core": "^1.7.1 || 2.0.0-beta.2", + "@emnapi/runtime": "^1.7.1 || 2.0.0-beta.2" } }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { @@ -6844,18 +6520,16 @@ "license": "MIT" }, "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "dev": true, + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz", + "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==", "hasInstallScript": true, "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.3", "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.4" }, "engines": { "node": ">= 10.0.0" @@ -6865,29 +6539,27 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" + "@parcel/watcher-android-arm64": "2.6.0", + "@parcel/watcher-darwin-arm64": "2.6.0", + "@parcel/watcher-darwin-x64": "2.6.0", + "@parcel/watcher-freebsd-x64": "2.6.0", + "@parcel/watcher-linux-arm-glibc": "2.6.0", + "@parcel/watcher-linux-arm-musl": "2.6.0", + "@parcel/watcher-linux-arm64-glibc": "2.6.0", + "@parcel/watcher-linux-arm64-musl": "2.6.0", + "@parcel/watcher-linux-x64-glibc": "2.6.0", + "@parcel/watcher-linux-x64-musl": "2.6.0", + "@parcel/watcher-win32-arm64": "2.6.0", + "@parcel/watcher-win32-x64": "2.6.0" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz", + "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6902,13 +6574,12 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz", + "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6923,13 +6594,12 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz", + "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6944,13 +6614,12 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz", + "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6965,13 +6634,12 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz", + "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==", "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6986,13 +6654,12 @@ } }, "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz", + "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==", "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7007,13 +6674,12 @@ } }, "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz", + "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7028,13 +6694,12 @@ } }, "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz", + "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7049,13 +6714,12 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz", + "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7070,13 +6734,12 @@ } }, "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz", + "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7091,13 +6754,12 @@ } }, "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz", + "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7111,14 +6773,13 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz", + "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==", "cpu": [ - "ia32" + "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7132,25 +6793,16 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/@parcel/watcher/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">= 10.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@pkgjs/parseargs": { @@ -7250,6 +6902,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/@plotly/mapbox-gl/-/mapbox-gl-1.13.4.tgz", "integrity": "sha512-sR3/Pe5LqT/fhYgp4rT4aSFf1rTsxMbGiH6Hojc7PH36ny5Bn17iVFUjpzycafETURuFbLZUfjODO8LvSI+5zQ==", + "deprecated": "This package is deprecated as of August 2026. plotly.js v4 uses MapLibre for map traces — see https://github.com/maplibre/maplibre-gl-js.", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", @@ -7681,6 +7334,18 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@rc-component/color-picker/node_modules/@ant-design/fast-color": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.6.tgz", + "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.7" + }, + "engines": { + "node": ">=8.x" + } + }, "node_modules/@rc-component/context": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", @@ -7901,9 +7566,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.49.0.tgz", - "integrity": "sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.66.0.tgz", + "integrity": "sha512-7y4XeoUHPecjfUDRmap8U0q6bjfLAPn7uOGT8BKyqy8uNDOjsGS8rlBhOx6sZLVwwjN6hapvGl2mW9/IS6UNww==", "cpu": [ "arm" ], @@ -7915,9 +7580,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.49.0.tgz", - "integrity": "sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.66.0.tgz", + "integrity": "sha512-e8WugYZXpgqrlMXLCudYVRAxAcK7AIY36JxRDwFRD38L9q62G1VsEUW6ijXxzjxYjNB8i1zo3B/ycIQ/qjLC/Q==", "cpu": [ "arm64" ], @@ -7928,10 +7593,24 @@ "android" ] }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.66.0.tgz", + "integrity": "sha512-6vkDCfyDjNLokh+Rt1D2KtNgFFMEPdkWha/mbtP4cSjh9xiN8T/JBS/A7nDYKjmMAXHrvR9J3AzUk2LtFbIBLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.49.0.tgz", - "integrity": "sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.66.0.tgz", + "integrity": "sha512-/mzZAX0+Q6eXxvkR0HB0RZCCrsbmFD8DpsvCQoMYABDfq/DjqkbfytuJ7GvZ4AhR/Mgis2fXbZrGqfbcK2Z5fA==", "cpu": [ "x64" ], @@ -7943,9 +7622,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.49.0.tgz", - "integrity": "sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.66.0.tgz", + "integrity": "sha512-JQJx9E8tUjGqed1RevDmoHaS3V30ODdV8uyvGxlwd4K5se6bkPrMeltSybqAtpJ+ltDRfo7FORQaJG2Hd5nGog==", "cpu": [ "arm64" ], @@ -7957,9 +7636,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.49.0.tgz", - "integrity": "sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.66.0.tgz", + "integrity": "sha512-GEaUQQjMaG7X1304qMgqLjzCKv6CdDirzJSS+UqUs3xhJ9X2Kjzu0JDbLoUU42FWxwmZqz+SsgU1SlQv9GNRVA==", "cpu": [ "x64" ], @@ -7971,9 +7650,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.49.0.tgz", - "integrity": "sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.66.0.tgz", + "integrity": "sha512-DgmAU9N0NhDQDzHgFUocDio7zRO8jR/nY/obDGvCR8zbJ6J77Fg6X49yPuExJUpYPbC82EOaRhG969pWzUSnHQ==", "cpu": [ "arm" ], @@ -7985,9 +7664,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.49.0.tgz", - "integrity": "sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.66.0.tgz", + "integrity": "sha512-zG09YZ+sk/HoHq+P9gYB0EseQ3M20RbDuKGWey6fbiMDV1LxfXvhgSW9jDaCcvFPMgfLXpimzXY+UYvA8R2mLQ==", "cpu": [ "arm" ], @@ -7999,9 +7678,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.49.0.tgz", - "integrity": "sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.66.0.tgz", + "integrity": "sha512-vlArhgyXbcVc1D4WZPoiYuqJIaMiSHBj6etRXua0KlfjlZeuiQyVAPYi0/N49O4mSp3u1iGUBLEjNa8ec81XZg==", "cpu": [ "arm64" ], @@ -8013,9 +7692,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.49.0.tgz", - "integrity": "sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.66.0.tgz", + "integrity": "sha512-RxJZtk0G87YPotDaRDvRqStV8cbqLSC5TroHvQHHKsqBg0ok64RxKgtXeFsa7FBcy7mb4crBrG3xK8USWIqWNA==", "cpu": [ "arm64" ], @@ -8026,10 +7705,24 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.49.0.tgz", - "integrity": "sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.66.0.tgz", + "integrity": "sha512-qlGcw959PrLLkZhiBxF3OZ6SQvj+OKY85mCqGNgSRs4LZlDJ6ICqmz6UdxtINdhcXYwNIbZoapQVBAmZlD2hUQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.66.0.tgz", + "integrity": "sha512-TvTI/7Cy0WvRA1SXgwzu6bwXBnMpmeT/ln5q7WvSpqmXy1VbmEnY8HVIDQNBiaHJvoWqRr0M4FNo7qiqtyMaFw==", "cpu": [ "loong64" ], @@ -8041,9 +7734,23 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.49.0.tgz", - "integrity": "sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.66.0.tgz", + "integrity": "sha512-UZEDkSoDRZ50NyLj70nO6mpIK3dvs2cPTTvQb1bA/PBDmr9fvn5KiESuGfh6srd7Zi6Lt9Sv2sVrFr1QoHLvPQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.66.0.tgz", + "integrity": "sha512-VRbxTvagLh3HRcysx1CNq+HHcvJbSebNI6fCbk7jwmmWHkXjrSIV3igXBpRHUTFdg0pagWGu50xoSZXnrZHjVQ==", "cpu": [ "ppc64" ], @@ -8055,9 +7762,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.49.0.tgz", - "integrity": "sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.66.0.tgz", + "integrity": "sha512-uWdJpvYqh0LE/i+YBL3sMX0a2kUkICENjmrPmyBmMOFc3jMrs6MSQH/pMD+VIpGEoUcr3XkHGLLfymzIqPSRRg==", "cpu": [ "riscv64" ], @@ -8069,9 +7776,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.49.0.tgz", - "integrity": "sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.66.0.tgz", + "integrity": "sha512-3FUd88pxgWAjK60OgCrika1AcNG+u8zaCdWjg4TlcZTDkt5TGyci8ZU64l3OJ9ax0MEjw3P80B/3PoSQDCLwJQ==", "cpu": [ "riscv64" ], @@ -8083,9 +7790,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.49.0.tgz", - "integrity": "sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.66.0.tgz", + "integrity": "sha512-qT2rMmgyej62g5AdwktK+Bt2lBu497pzWZe12TTQ5JmZjOYPnEwcPEAOSLTBxBV+6gIES75rXm219v/QkT397A==", "cpu": [ "s390x" ], @@ -8097,9 +7804,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.49.0.tgz", - "integrity": "sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.66.0.tgz", + "integrity": "sha512-E46rnZgp7J84Qwe8RMlF+rgimnDo/9fuiGbUArGB0ZkMWf97O7yeSCfKls5x/YJOF0RcuSe9RctuKe1hlxICiA==", "cpu": [ "x64" ], @@ -8111,9 +7818,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.49.0.tgz", - "integrity": "sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.66.0.tgz", + "integrity": "sha512-Uz1HiZe+qBzqgdPsON+z0wRx3WdATuyzwvGT6cr2VZVrqqko0ZJVfkrQJtwDMuDcAfXYdo7XucaxJ7lTLjEcgg==", "cpu": [ "x64" ], @@ -8124,10 +7831,38 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.66.0.tgz", + "integrity": "sha512-Ph7TX3Ex5qdfcb7Tc6eEPugVkRfJ501eTovO4T5029YObfpZ7dzn3RiwpFvGp50nk2QUhvBMZ0PFGlEj6pOYTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.66.0.tgz", + "integrity": "sha512-nZYPEya7ZkeNxUEiF7qmNZbyLTyRN3MK5cO22KqsaoneUzXJuzBIQRw+7BEQy9LGj2O5vrCE9V3EpK06FYo1tQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.49.0.tgz", - "integrity": "sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.66.0.tgz", + "integrity": "sha512-u7aTfS3R6C4hRsqXSzaO6qLZYLVuMkHMvcWlux4IM8IJif1VCl2cgPBSo5gSNoFoStQypQP+qwq8W1IyFBf1QQ==", "cpu": [ "arm64" ], @@ -8139,9 +7874,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.49.0.tgz", - "integrity": "sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.66.0.tgz", + "integrity": "sha512-e+i9ueHrH1Bafb0cf0woAIVJbYcoC8vRaD+vz+Xi8w6jz9cYJSV3vyKO6ELGSZ6g4W4MJOm2WPLN4/nQf77h7w==", "cpu": [ "ia32" ], @@ -8152,10 +7887,24 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.66.0.tgz", + "integrity": "sha512-KfTCbrtr2zXTqH2E1F+uYlFTrYibxHKqPAHobpd8Kfg49cEHmuHebOidCTDRgqG1suaPFX7oejFQeGE71zWKfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.49.0.tgz", - "integrity": "sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.66.0.tgz", + "integrity": "sha512-xA+neBh1bqkqaS3b48T2UHZnDsTIpb9B0h+TdBzynjF/ymCpYndhfY10RqW0qSKB1HqqQA83mINVhAdwA+mETg==", "cpu": [ "x64" ], @@ -8443,9 +8192,9 @@ "license": "MIT" }, "node_modules/@testing-library/react/node_modules/@types/yargs": { - "version": "15.0.19", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", - "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", + "version": "15.0.20", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.20.tgz", + "integrity": "sha512-KIkX+/GgfFitlASYCGoSF+T4XRXhOubJLhkLVtSfsRTe9jWMmuM2g28zQ41BtPTG7TRBb2xHW+LCNVE9QR/vsg==", "dev": true, "license": "MIT", "dependencies": { @@ -8610,9 +8359,9 @@ } }, "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", + "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==", "license": "MIT", "optional": true, "dependencies": { @@ -8822,9 +8571,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "license": "MIT" }, "node_modules/@types/geojson": { @@ -8923,23 +8672,10 @@ "pretty-format": "^30.0.0" } }, - "node_modules/@types/jest/node_modules/@jest/expect-utils": { - "version": "30.1.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.1.1.tgz", - "integrity": "sha512-5YUHr27fpJ64dnvtu+tt11ewATynrHkGYD+uSFgRr8V2eFJis/vEXgToyLwccIwqBihVfz9jwio+Zr1ab1Zihw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@types/jest/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "dev": true, "license": "MIT", "dependencies": { @@ -8949,29 +8685,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@types/jest/node_modules/@jest/types": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", - "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@types/jest/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -8988,161 +8705,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/jest/node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/jest/node_modules/expect": { - "version": "30.1.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.1.1.tgz", - "integrity": "sha512-OKe7cdic4qbfWd/CcgwJvvCrNX2KWfuMZee9AfJHL1gTYmvqjBjZG1a2NwfhspBzxzlXwsN75WWpKTYfsJpBxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.1.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.1.1", - "jest-message-util": "30.1.0", - "jest-mock": "30.0.5", - "jest-util": "30.0.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-diff": { - "version": "30.1.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.1.1.tgz", - "integrity": "sha512-LUU2Gx8EhYxpdzTR6BmjL1ifgOAQJQELTHOiPv9KITaKjZvJ9Jmgigx01tuZ49id37LorpGc9dPBPlXTboXScw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.0.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-matcher-utils": { - "version": "30.1.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.1.1.tgz", - "integrity": "sha512-SuH2QVemK48BNTqReti6FtjsMPFsSOD/ZzRxU1TttR7RiRsRSe78d03bb4Cx6D4bQC/80Q8U4VnaaAH9FlbZ9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.1.1", - "pretty-format": "30.0.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-message-util": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.1.0.tgz", - "integrity": "sha512-HizKDGG98cYkWmaLUHChq4iN+oCENohQLb7Z5guBPumYs+/etonmNFlg1Ps6yN9LTPyZn+M+b/9BbnHx3WTMDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.0.5", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.0.5", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-mock": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", - "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.0.5", - "@types/node": "*", - "jest-util": "30.0.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-util": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.0.5.tgz", - "integrity": "sha512-pvyPWssDZR0FlfMxCBoc0tvM8iUEskaRFALUtGQYzVEAqisAztmy+R8LnU14KT4XA0H/a5HMVTXat1jLne010g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.0.5", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@types/jest/node_modules/pretty-format": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", - "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/jsdom": { "version": "21.1.7", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", @@ -9247,12 +8825,12 @@ "optional": true }, "node_modules/@types/react": { - "version": "19.1.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", - "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", "license": "MIT", "dependencies": { - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-datepicker": { @@ -9424,14 +9002,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.0.tgz", - "integrity": "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.1.tgz", + "integrity": "sha512-lC/t6eMCZZQAAKZEYGL6RDVSuFehpdmMT6h+nJIjIa6oylN/PwDgDVtEIbB7O9xFfZYtZAYLoLlDNWKJhtF+uQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.0", - "@typescript-eslint/visitor-keys": "8.60.0" + "@typescript-eslint/types": "8.72.1", + "@typescript-eslint/visitor-keys": "8.72.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9459,9 +9037,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.0.tgz", - "integrity": "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.1.tgz", + "integrity": "sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw==", "dev": true, "license": "MIT", "engines": { @@ -9500,6 +9078,38 @@ "typescript": ">=4.8.4 <6.1.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/types": { + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.0.tgz", + "integrity": "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.0.tgz", + "integrity": "sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.60.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -9511,16 +9121,29 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { @@ -9563,15 +9186,15 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.0.tgz", - "integrity": "sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.0.tgz", + "integrity": "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.60.0", - "eslint-visitor-keys": "^5.0.0" + "@typescript-eslint/visitor-keys": "8.60.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9581,8 +9204,71 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.0.tgz", + "integrity": "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.0.tgz", + "integrity": "sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.60.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.1.tgz", + "integrity": "sha512-SB8xqipSzZHUePCCLNeYxqnxq83X61/qzNhjQGbTfjxGZIeOEP7tBgWYX05Tcd6CgE02WdTJnh5b8kMZJ/+bnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.72.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, @@ -9598,6 +9284,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "deprecated": "Potential CWE-502 - Update to 1.3.1 or higher", "license": "ISC" }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { @@ -9913,9 +9600,9 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", - "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.7.tgz", + "integrity": "sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg==", "dev": true, "license": "MIT", "dependencies": { @@ -9937,8 +9624,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.2.4", - "vitest": "3.2.4" + "@vitest/browser": "3.2.7", + "vitest": "3.2.7" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -9946,125 +9633,16 @@ } } }, - "node_modules/@vitest/coverage-v8/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/glob/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vitest/coverage-v8/node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/glob/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/test-exclude": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", - "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^10.4.1", - "minimatch": "^10.2.2" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@vitest/expect": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", - "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -10073,13 +9651,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", - "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.4", + "@vitest/spy": "3.2.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -10100,9 +9678,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", - "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", "dev": true, "license": "MIT", "dependencies": { @@ -10113,13 +9691,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", - "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.4", + "@vitest/utils": "3.2.7", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -10128,13 +9706,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", - "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.4", + "@vitest/pretty-format": "3.2.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -10143,9 +9721,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", - "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10156,13 +9734,13 @@ } }, "node_modules/@vitest/ui": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.4.tgz", - "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.7.tgz", + "integrity": "sha512-eVtcpJXGhS0GjMuHROfbXLhlxooyUcuip8GNzzjDD5jzafZqzanJH4W3VGmUxHNx4fv6qQGUGJHRpGUdj+9D6Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.4", + "@vitest/utils": "3.2.7", "fflate": "^0.8.2", "flatted": "^3.3.3", "pathe": "^2.0.3", @@ -10174,17 +9752,17 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "3.2.4" + "vitest": "3.2.7" } }, "node_modules/@vitest/utils": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", - "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.4", + "@vitest/pretty-format": "3.2.7", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, @@ -10348,9 +9926,9 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", - "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.15.tgz", + "integrity": "sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -10375,9 +9953,9 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -10418,13 +9996,15 @@ } }, "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", + "dependencies": { + "debug": "4" + }, "engines": { - "node": ">= 14" + "node": ">= 6.0.0" } }, "node_modules/ajv": { @@ -10472,6 +10052,21 @@ "ajv": "^8.8.2" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -10567,6 +10162,27 @@ "react-dom": ">=16.9.0" } }, + "node_modules/antd/node_modules/@ant-design/colors": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.2.1.tgz", + "integrity": "sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==", + "license": "MIT", + "dependencies": { + "@ant-design/fast-color": "^2.0.6" + } + }, + "node_modules/antd/node_modules/@ant-design/fast-color": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.6.tgz", + "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.7" + }, + "engines": { + "node": ">=8.x" + } + }, "node_modules/antd/node_modules/@ant-design/icons": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.6.1.tgz", @@ -10829,9 +10445,9 @@ } }, "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/assert": { @@ -10947,9 +10563,9 @@ } }, "node_modules/axios": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", - "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.21.0.tgz", + "integrity": "sha512-YCzXMB53Q9PZBsh7yN7wtapit4WepwcHS2fP8QhGsBxSz5YtgYobV7GGlWlAJi+RxfU77GQTQi2DSLUma42EYA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", @@ -10971,31 +10587,6 @@ "axios": ">= 0.17.0" } }, - "node_modules/axios/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/axios/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -11045,17 +10636,54 @@ "node": ">=8" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "node_modules/babel-plugin-istanbul/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -11207,9 +10835,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.32", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.32.tgz", - "integrity": "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==", + "version": "2.11.34", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.34.tgz", + "integrity": "sha512-Aqr8mA1kIvyJ3UY5YAY7ib8LSo1DmDMbMnVqGPtsKW1LxaFQFwn9Eb3yvq2fUKJsRvaXjnAV7R5osqETapzNiA==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -11253,9 +10881,9 @@ "license": "MIT" }, "node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.5.tgz", + "integrity": "sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==", "license": "MIT" }, "node_modules/boolbase": { @@ -11268,6 +10896,7 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", + "deprecated": "This version of Bootstrap is no longer supported. Please upgrade to the latest version.", "funding": [ { "type": "github", @@ -11285,9 +10914,10 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -11373,30 +11003,29 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", - "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.6.tgz", + "integrity": "sha512-sd+Q65fjlWCYWtZKXiKfrUc8d+4jtp/8f0W2NkwzLtoW4bI6UDnWusLWIurHnmurW0XShIRxpwiOX4EoPtXUAg==", "license": "ISC", "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", + "bn.js": "^5.2.3", + "browserify-rsa": "^4.1.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", + "elliptic": "^6.6.1", "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", + "parse-asn1": "^5.1.9", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" }, "engines": { - "node": ">= 0.12" + "node": ">= 0.10" } }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.5.tgz", + "integrity": "sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ==", "funding": [ { "type": "opencollective", @@ -11413,11 +11042,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" + "baseline-browser-mapping": "^2.11.33", + "caniuse-lite": "^1.0.30001819", + "electron-to-chromium": "^1.5.464", + "node-releases": "^2.0.60", + "update-browserslist-db": "^1.3.4" }, "bin": { "browserslist": "cli.js" @@ -11598,9 +11227,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001793", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", - "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "version": "1.0.30001820", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001820.tgz", + "integrity": "sha512-gfWD6MxqVCqAOwmODfZf7DchWvlrA+SRdNX7ceLfg3xRqe5ssjjpF7EgslC/0tiLiNTajdaNN/q8c/5u/7Gz8w==", "funding": [ { "type": "opencollective", @@ -11801,10 +11430,9 @@ } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "funding": [ { "type": "github", @@ -11830,9 +11458,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.3.0.tgz", + "integrity": "sha512-lmNyBzi6iYiqyrExTctfmjd8tInx+dHu9PBomTfH5RXS53c27JMFJgzNv5TyAnm3PgGf+MLy0+Ws41/HlVxdKQ==", "license": "MIT" }, "node_modules/clamp": { @@ -11892,6 +11520,52 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -12125,9 +11799,9 @@ } }, "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.10.0.tgz", + "integrity": "sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==", "dev": true, "license": "MIT" }, @@ -12175,6 +11849,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -12277,9 +11952,9 @@ } }, "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", "license": "ISC", "engines": { "node": ">= 6" @@ -12314,9 +11989,9 @@ } }, "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/create-hash": { @@ -12480,6 +12155,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "deprecated": "Active development of CryptoJS has been discontinued. This library is no longer maintained.", "license": "MIT" }, "node_modules/css-box-model": { @@ -12918,9 +12594,9 @@ } }, "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", "license": "ISC", "engines": { "node": ">=12" @@ -13439,17 +13115,12 @@ "license": "MIT" }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", - "optional": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, "engines": { - "node": ">=0.10" + "node": ">=8" } }, "node_modules/detect-newline": { @@ -13476,16 +13147,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -13498,9 +13159,9 @@ } }, "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/dir-glob": { @@ -13588,9 +13249,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz", - "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.17.tgz", + "integrity": "sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -13683,9 +13344,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.364", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.364.tgz", - "integrity": "sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==", + "version": "1.5.468", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.468.tgz", + "integrity": "sha512-8XdEp3sIqO+PzmVPxhzqHq/3+yCxp44m27cm2WY1sRn3ZhwKyKmqSi2hx6gEhmnOXmh8NUuYE00z6Onzn5m6DA==", "license": "ISC" }, "node_modules/elementary-circuits-directed-graph": { @@ -13713,9 +13374,9 @@ } }, "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/emittery": { @@ -14656,9 +14317,9 @@ } }, "node_modules/eslint-plugin-vitest/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", "dev": true, "license": "MIT", "dependencies": { @@ -14679,13 +14340,13 @@ } }, "node_modules/eslint-plugin-vitest/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -14764,9 +14425,9 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -14884,22 +14545,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", @@ -15055,7 +14700,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, "license": "MIT" }, "node_modules/events": { @@ -15100,30 +14744,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/execa/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -15140,20 +14760,20 @@ } }, "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.5.2.tgz", + "integrity": "sha512-0LNuMvs8/5mRYhnCR4k+lGV7fqPMs6Bnksda4S3zsCUmdxBpAn4zU4NNzXdq1pMKe/H4W5t/zVIDSJ/H3e0vDA==", "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" + "@jest/expect-utils": "30.5.2", + "@jest/get-type": "30.5.0", + "jest-matcher-utils": "30.5.2", + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/expect-type": { @@ -15166,6 +14786,134 @@ "node": ">=12.0.0" } }, + "node_modules/expect/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "license": "MIT" + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expect/node_modules/jest-message-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.5.1", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-util": "30.5.1", + "picomatch": "^4.0.3", + "pretty-format": "30.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect/node_modules/jest-mock": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz", + "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==", + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.5.2", + "@jest/types": "30.5.1", + "@types/node": "*", + "jest-util": "30.5.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.5.1", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/expect/node_modules/pretty-format": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", + "license": "MIT", + "dependencies": { + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -15308,9 +15056,9 @@ } }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", "funding": [ { "type": "github", @@ -15359,9 +15107,9 @@ "license": "MIT" }, "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz", + "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", "license": "MIT" }, "node_modules/file-entry-cache": { @@ -15449,9 +15197,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.2.tgz", + "integrity": "sha512-/kVP2U8z596Ia0gwFrwyIeo74ta5aVmSeU1FfAUMAmcEP5EP7zydmag3SLiN64NaRKef3lxsq7i/g7ltJQDGow==", "funding": [ { "type": "individual", @@ -15579,12 +15327,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -15828,21 +15578,21 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -15867,6 +15617,30 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "license": "BSD-2-Clause" }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -15880,7 +15654,7 @@ "node": ">=6" } }, - "node_modules/global-prefix": { + "node_modules/global-modules/node_modules/global-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", @@ -15895,7 +15669,14 @@ "node": ">=6" } }, - "node_modules/global-prefix/node_modules/which": { + "node_modules/global-modules/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/global-modules/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", @@ -15908,6 +15689,44 @@ "which": "bin/which" } }, + "node_modules/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "license": "MIT", + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/global-prefix/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -16639,18 +16458,27 @@ "node": ">= 14" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6" } }, "node_modules/human-signals": { @@ -16731,9 +16559,9 @@ } }, "node_modules/immutable": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", - "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", + "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==", "dev": true, "license": "MIT" }, @@ -16805,6 +16633,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -16818,11 +16647,13 @@ "license": "ISC" }, "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/inline-style-parser": { "version": "0.1.1", @@ -17062,7 +16893,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17105,6 +16935,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", @@ -17136,7 +16982,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -17561,15 +17406,15 @@ } }, "node_modules/jest": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", - "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.5.2.tgz", + "integrity": "sha512-3gnpdBIza8ijCl3iMV9ChE3hSt1+46865qqod863gQtJr1DixOkAU5DoGbi3u+XlRcw++BhZQMu/y4xBdHBvSQ==", "license": "MIT", "dependencies": { - "@jest/core": "30.4.2", - "@jest/types": "30.4.1", + "@jest/core": "30.5.2", + "@jest/types": "30.5.1", "import-local": "^3.2.0", - "jest-cli": "30.4.2" + "jest-cli": "30.5.2" }, "bin": { "jest": "bin/jest.js" @@ -17587,36 +17432,23 @@ } }, "node_modules/jest-changed-files": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", - "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.5.1.tgz", + "integrity": "sha512-0+bvMM/ENhDI29Z8q1r4HxiDIi4G5tnBmSw4esfPQoj9q8Nik7KIyuxHkTVnnniJQf05SxpGaKDQ+4h28ynGPg==", "license": "MIT", "dependencies": { "execa": "^5.1.1", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "p-limit": "^3.1.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-changed-files/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-changed-files/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -17626,13 +17458,13 @@ } }, "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -17644,42 +17476,18 @@ } }, "node_modules/jest-changed-files/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest-changed-files/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-changed-files/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -17690,25 +17498,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-changed-files/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-changed-files/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -17718,28 +17511,28 @@ } }, "node_modules/jest-circus": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", - "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.5.2.tgz", + "integrity": "sha512-vffFgjs5JSJ9q4ds1vNW3klKYPJfYfIY61LT/zaZgvTeASJOWZUt8LBfHgIcV4rwxlPBLl/ePBGccHEclS4PlQ==", "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/expect": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", + "@jest/environment": "30.5.2", + "@jest/expect": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-runtime": "30.4.2", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", + "jest-each": "30.5.2", + "jest-matcher-utils": "30.5.2", + "jest-message-util": "30.5.1", + "jest-runtime": "30.5.2", + "jest-snapshot": "30.5.2", + "jest-util": "30.5.1", "p-limit": "^3.1.0", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -17748,89 +17541,55 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-circus/node_modules/@jest/environment": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz", + "integrity": "sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==", "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-mock": "30.4.1" + "jest-mock": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-circus/node_modules/@jest/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", - "license": "MIT", - "dependencies": { - "expect": "30.4.1", - "jest-snapshot": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.5.2.tgz", + "integrity": "sha512-2E+1Pg6jJxbRjLNLpciC71iri/3qsKJL222/aXJEFwC0VdUSvfS+JZQQLEVjUYYc8t8pQu2MGE3cF2+bNTYRsg==", "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0" + "expect": "30.5.2", + "jest-snapshot": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-circus/node_modules/@jest/fake-timers": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz", + "integrity": "sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-circus/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -17839,39 +17598,14 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-circus/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -17883,9 +17617,9 @@ } }, "node_modules/jest-circus/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/jest-circus/node_modules/@sinonjs/fake-timers": { @@ -17909,210 +17643,49 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", - "license": "BSD-3-Clause", - "workspaces": [ - "test/babel-8" - ], + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.5.1", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-util": "30.5.1", + "picomatch": "^4.0.3", + "pretty-format": "30.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" }, "engines": { - "node": ">=12" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-circus/node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", - "picomatch": "^4.0.3", - "pretty-format": "30.4.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "node_modules/jest-circus/node_modules/jest-mock": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz", + "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/expect-utils": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-snapshot": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.4.1", - "graceful-fs": "^4.2.11", - "jest-diff": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "pretty-format": "30.4.1", - "semver": "^7.7.2", - "synckit": "^0.11.8" + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-circus/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -18123,41 +17696,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-circus/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -18167,15 +17709,15 @@ } }, "node_modules/jest-circus/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -18197,49 +17739,21 @@ ], "license": "MIT" }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/jest-cli": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", - "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.5.2.tgz", + "integrity": "sha512-YYYxUUVjFgPvgEleKNKMaYGIFgR3l3832Cl0kRL/oCiDZ03v7wImUtquHl2OOBCCNgprjZgBN5bczS/JklPBDg==", "license": "MIT", "dependencies": { - "@jest/core": "30.4.2", - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", + "@jest/core": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/types": "30.5.1", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.4.2", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", + "jest-config": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", "yargs": "^17.7.2" }, "bin": { @@ -18257,23 +17771,10 @@ } } }, - "node_modules/jest-cli/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-cli/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -18283,13 +17784,13 @@ } }, "node_modules/jest-cli/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -18301,42 +17802,18 @@ } }, "node_modules/jest-cli/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest-cli/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-cli/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -18348,9 +17825,9 @@ } }, "node_modules/jest-cli/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -18360,32 +17837,32 @@ } }, "node_modules/jest-config": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", - "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.5.2.tgz", + "integrity": "sha512-U6221OZekabePvGcGPf4raIBKMvYQWFHvhobDJRojOYaFMj2HaGytAdknjDhYc6JTz2fdHW9+6k0wWUDaNeOFQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", - "@jest/pattern": "30.4.0", - "@jest/test-sequencer": "30.4.1", - "@jest/types": "30.4.1", - "babel-jest": "30.4.1", + "@jest/get-type": "30.5.0", + "@jest/pattern": "30.5.0", + "@jest/test-sequencer": "30.5.2", + "@jest/types": "30.5.1", + "babel-jest": "30.5.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", - "glob": "^10.5.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "jest-circus": "30.4.2", - "jest-docblock": "30.4.0", - "jest-environment-node": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-runner": "30.4.2", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", + "jest-circus": "30.5.2", + "jest-docblock": "30.5.0", + "jest-environment-node": "30.5.2", + "jest-regex-util": "30.5.0", + "jest-resolve": "30.5.1", + "jest-runner": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", "parse-json": "^5.2.0", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -18409,23 +17886,10 @@ } } }, - "node_modules/jest-config/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-config/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -18435,22 +17899,22 @@ } }, "node_modules/jest-config/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -18460,13 +17924,13 @@ } }, "node_modules/jest-config/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -18478,9 +17942,9 @@ } }, "node_modules/jest-config/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/jest-config/node_modules/ansi-styles": { @@ -18496,15 +17960,15 @@ } }, "node_modules/jest-config/node_modules/babel-jest": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", - "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.5.2.tgz", + "integrity": "sha512-ES8WeJ2fNWPEDunyAtUfJ12nHyaWUloCHdkfK2oW5uSoQSUmjNKdWiGaXJITJwvFEWoD/evHEg/QoCXAvLaQqQ==", "license": "MIT", "dependencies": { - "@jest/transform": "30.4.1", + "@jest/transform": "30.5.2", "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.4.0", + "babel-plugin-istanbul": "^8.0.0", + "babel-preset-jest": "30.5.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -18516,10 +17980,26 @@ "@babel/core": "^7.11.0 || ^8.0.0-0" } }, + "node_modules/jest-config/node_modules/babel-jest/node_modules/babel-preset-jest": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.5.0.tgz", + "integrity": "sha512-ZGPn5ClP4lBDpuOK8W1yQIOy359HmbnZv3suucAlIe+SEE9yDsxV4S2PjSbH2Vc97U+WmzYD7vw3kr8NsQ/i6w==", + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.5.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1 || ^8.0.0" + } + }, "node_modules/jest-config/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "license": "BSD-3-Clause", "workspaces": [ "test/babel-8" @@ -18529,16 +18009,16 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", - "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.5.0.tgz", + "integrity": "sha512-gtGo1B+u14jrZQv6TdSWIWkTqclboo7Qn+dFAGUOIuXLFuJKAdg3U5MIWzZnW4vfUb4dX9skmAMiby86e/SF4A==", "license": "MIT", "dependencies": { "@types/babel__core": "^7.20.5" @@ -18547,62 +18027,56 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-config/node_modules/babel-preset-jest": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", - "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", + "node_modules/jest-config/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "30.4.0", - "babel-preset-current-node-syntax": "^1.2.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + "node": "18 || 20 || >=22" } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, - "node_modules/jest-config/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/jest-config/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/jest-config/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -18625,45 +18099,43 @@ } }, "node_modules/jest-config/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" } }, "node_modules/jest-config/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-config/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -18674,41 +18146,50 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-config/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", + "node_modules/jest-config/node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/jest-config/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "license": "BlueOak-1.0.0", "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-config/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", + "node_modules/jest-config/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/jest-config/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -18718,35 +18199,20 @@ } }, "node_modules/jest-config/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/jest-config/node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", @@ -18761,26 +18227,42 @@ } }, "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.5.2.tgz", + "integrity": "sha512-rBtHnI6BWTiWj3lM7fOLVfChx7R9B0u9VV3PRHawKs79x6ZjW1QoSrKenaigNGWlvhtoi2BqvDbABDie+Os3xQ==", "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/diff-sequences": "30.5.0", + "@jest/get-type": "30.5.0", + "chalk": "^4.1.2", + "pretty-format": "30.5.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-diff/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "license": "MIT" + }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -18790,31 +18272,24 @@ } }, "node_modules/jest-diff/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-diff/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-docblock": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", - "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.5.0.tgz", + "integrity": "sha512-NwDqcxtoZi33RhuW+zJS/RVA3rmheQ8BnwpYZuc/Eruaz6seQb7+aoCeDZu/3X7W2XmD8DbSo9Pn72DbKsBFYw==", "license": "MIT", "dependencies": { "detect-newline": "^3.1.0" @@ -18824,38 +18299,26 @@ } }, "node_modules/jest-each": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", - "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.5.2.tgz", + "integrity": "sha512-GRrW+7fmmgmkvyfEBqc1QFdWnF1Ex5yG6Y6AWL4TTxnkWlKIT98dsKh3P3UuWm6v4XsQwVE6DEzXIPMzWJ3ZbA==", "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.4.1", + "@jest/get-type": "30.5.0", + "@jest/types": "30.5.1", "chalk": "^4.1.2", - "jest-util": "30.4.1", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-each/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -18865,13 +18328,13 @@ } }, "node_modules/jest-each/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -18883,9 +18346,9 @@ } }, "node_modules/jest-each/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/jest-each/node_modules/ansi-styles": { @@ -18900,37 +18363,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-each/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-each/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-each/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -18942,9 +18390,9 @@ } }, "node_modules/jest-each/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -18954,87 +18402,74 @@ } }, "node_modules/jest-each/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", - "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.5.2.tgz", + "integrity": "sha512-Ciz4KgTGIbojxSKpuFImgWJj5EyqfE8xMq9NxWmOXnQywHHS03H9Mv+vaCB29J5pr3JBrY27WbRV18rBdjh8Dg==", "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", + "@jest/environment": "30.5.2", + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-mock": "30.4.1", - "jest-util": "30.4.1", - "jest-validate": "30.4.1" + "jest-mock": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz", + "integrity": "sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==", "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-mock": "30.4.1" + "jest-mock": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz", + "integrity": "sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -19044,13 +18479,13 @@ } }, "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -19062,9 +18497,9 @@ } }, "node_modules/jest-environment-node/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": { @@ -19088,35 +18523,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-environment-node/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -19125,35 +18545,27 @@ } }, "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz", + "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/expect-utils": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-util": "30.4.1" + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-environment-node/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -19165,9 +18577,9 @@ } }, "node_modules/jest-environment-node/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -19177,30 +18589,20 @@ } }, "node_modules/jest-environment-node/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-haste-map": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", @@ -19227,23 +18629,55 @@ "fsevents": "^2.3.2" } }, + "node_modules/jest-haste-map/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/jest-leak-detector": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", - "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.5.1.tgz", + "integrity": "sha512-gt4GT2aWgEoCNTcBe4rqS74xTIUJxi+UD9SNSu9aOk5LmTEd6fS5KSTmAKAfitCCktQHNN+upUuL6EkBfFbMDQ==", "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "pretty-format": "30.4.1" + "@jest/get-type": "30.5.0", + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-leak-detector/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -19253,9 +18687,9 @@ } }, "node_modules/jest-leak-detector/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/jest-leak-detector/node_modules/ansi-styles": { @@ -19271,41 +18705,57 @@ } }, "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.5.2.tgz", + "integrity": "sha512-lFkB365PTIHOhPzwrb9T6gvlDnPpOZ7/c3ewOKKB7bzztqjVrtlyRL2MkyfJXpyY2u2SKw001JKrTx14fBUFcQ==", "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.5.0", + "chalk": "^4.1.2", + "jest-diff": "30.5.2", + "pretty-format": "30.5.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "license": "MIT" + }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -19315,27 +18765,20 @@ } }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-message-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", @@ -19407,23 +18850,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, "node_modules/jest-regex-util": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", @@ -19435,100 +18861,252 @@ } }, "node_modules/jest-resolve": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", - "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.5.1.tgz", + "integrity": "sha512-wprhLejRtwN6h8ZgaqC0eYjGJ1uMdGPT/+b3eFncbG4NWuuP9QL+vWwRinu9waw7hkOLcpMJGVJAMgBwsPssMQ==", "license": "MIT", "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" + "unrs-resolver": "^1.12.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", - "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.5.2.tgz", + "integrity": "sha512-GMI0DP5enX9Z2qW2zFy1bOkrCfWAOPRJQ7qHt0pdfrxBPsgWxglMPrRSK2TX/wRWYxcPRSLFg3Z88qPOzHx7FQ==", "license": "MIT", "dependencies": { - "jest-regex-util": "30.4.0", - "jest-snapshot": "30.4.1" + "jest-regex-util": "30.5.0", + "jest-snapshot": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", + "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", + "node_modules/jest-resolve/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0" + "@sinclair/typebox": "^0.34.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", - "jest-regex-util": "30.4.0" + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "node_modules/jest-resolve/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "license": "MIT" + }, + "node_modules/jest-resolve/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "node_modules/jest-resolve/node_modules/jest-haste-map": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve/node_modules/jest-regex-util": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.5.1", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-runner": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.5.2.tgz", + "integrity": "sha512-/B6px7hiiNhVSRwuv9AGn0nawYvwsHeQZ3ItTd5Gp2diFd0EOKaWVeWqcbw3L88vx1GfpCKjQkxWItZCTl11Rw==", + "license": "MIT", + "dependencies": { + "@jest/console": "30.5.2", + "@jest/environment": "30.5.2", + "@jest/source-map": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.5.0", + "jest-environment-node": "30.5.2", + "jest-haste-map": "30.5.1", + "jest-leak-detector": "30.5.1", + "jest-message-util": "30.5.1", + "jest-resolve": "30.5.1", + "jest-runtime": "30.5.2", + "jest-util": "30.5.1", + "jest-watcher": "30.5.2", + "jest-worker": "30.5.1", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/environment": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz", + "integrity": "sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==", + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", + "@types/node": "*", + "jest-mock": "30.5.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/fake-timers": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz", + "integrity": "sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.5.1", + "@sinonjs/fake-timers": "^15.4.0", + "@types/node": "*", + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/transform": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -19537,14 +19115,14 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -19555,13 +19133,22 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "node_modules/jest-runner/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest-resolve-dependencies/node_modules/ansi-styles": { + "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", @@ -19573,10 +19160,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-resolve-dependencies/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "node_modules/jest-runner/node_modules/babel-plugin-istanbul": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "license": "BSD-3-Clause", "workspaces": [ "test/babel-8" @@ -19586,45 +19173,30 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/jest-resolve-dependencies/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/jest-runner/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" + "node": ">=12.0.0" }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/jest-resolve-dependencies/node_modules/istanbul-lib-instrument": { + "node_modules/jest-runner/node_modules/istanbul-lib-instrument": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", @@ -19640,74 +19212,42 @@ "node": ">=10" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "node_modules/jest-runner/node_modules/jest-haste-map": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -19715,68 +19255,37 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "node_modules/jest-runner/node_modules/jest-mock": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz", + "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/expect-utils": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-util": "30.4.1" + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/jest-snapshot": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", + "node_modules/jest-runner/node_modules/jest-regex-util": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.4.1", - "graceful-fs": "^4.2.11", - "jest-diff": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "pretty-format": "30.4.1", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "node_modules/jest-runner/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -19787,26 +19296,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/jest-runner/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -19815,37 +19308,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-resolve-dependencies/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "node_modules/jest-runner/node_modules/pretty-format": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve-dependencies/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/write-file-atomic": { + "node_modules/jest-runner/node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", @@ -19858,245 +19336,104 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "node_modules/jest-runtime": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.5.2.tgz", + "integrity": "sha512-0paUAHBlheai10A3XSy9Xh+YBG0IROy+/qzcDPzQ/nbbXrznQzeWy5qniICWK6d3W3scaRQCVAbXdcK0ibBq4w==", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.5.2", + "@jest/fake-timers": "30.5.2", + "@jest/globals": "30.5.2", + "@jest/source-map": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.2.0", + "collect-v8-coverage": "^1.0.2", + "es-module-lexer": "^2.1.0", + "glob": "^13.0.6", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.5.1", + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-regex-util": "30.5.0", + "jest-resolve": "30.5.1", + "jest-snapshot": "30.5.2", + "jest-util": "30.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/environment": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz", + "integrity": "sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==", "license": "MIT", "dependencies": { + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-regex-util": "30.4.0" + "jest-mock": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "node_modules/jest-runtime/node_modules/@jest/expect": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.5.2.tgz", + "integrity": "sha512-2E+1Pg6jJxbRjLNLpciC71iri/3qsKJL222/aXJEFwC0VdUSvfS+JZQQLEVjUYYc8t8pQu2MGE3cF2+bNTYRsg==", "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "expect": "30.5.2", + "jest-snapshot": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "node_modules/jest-runtime/node_modules/@jest/fake-timers": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz", + "integrity": "sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", + "@jest/types": "30.5.1", + "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", - "license": "MIT" - }, - "node_modules/jest-resolve/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/jest-runtime/node_modules/@jest/globals": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.5.2.tgz", + "integrity": "sha512-62zfS+dL+M5aTNHXCNLyqD+j4oqxTIzDYrZbpqMP8Yn+gvlAGyzC6BSPNb1ZmFOakV1RtFYX/O3FCQXSWmQdgg==", "license": "MIT", + "dependencies": { + "@jest/environment": "30.5.2", + "@jest/expect": "30.5.2", + "@jest/types": "30.5.1", + "jest-mock": "30.5.2" + }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-resolve/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest-runner": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", - "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", - "license": "MIT", - "dependencies": { - "@jest/console": "30.4.1", - "@jest/environment": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-docblock": "30.4.0", - "jest-environment-node": "30.4.1", - "jest-haste-map": "30.4.1", - "jest-leak-detector": "30.4.1", - "jest-message-util": "30.4.1", - "jest-resolve": "30.4.1", - "jest-runtime": "30.4.2", - "jest-util": "30.4.1", - "jest-watcher": "30.4.1", - "jest-worker": "30.4.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-mock": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@sinonjs/fake-timers": "^15.4.0", - "@types/node": "*", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "node_modules/jest-runtime/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -20105,23 +19442,23 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "node_modules/jest-runtime/node_modules/@jest/transform": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -20130,14 +19467,14 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -20148,13 +19485,13 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "node_modules/jest-runtime/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": { + "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": { "version": "15.4.0", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", @@ -20163,7 +19500,7 @@ "@sinonjs/commons": "^3.0.1" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { + "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", @@ -20175,10 +19512,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runner/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "node_modules/jest-runtime/node_modules/babel-plugin-istanbul": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "license": "BSD-3-Clause", "workspaces": [ "test/babel-8" @@ -20188,28 +19525,74 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/jest-runner/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/jest-runtime/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" } }, - "node_modules/jest-runner/node_modules/istanbul-lib-instrument": { + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/jest-runtime/node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "license": "MIT" + }, + "node_modules/jest-runtime/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/istanbul-lib-instrument": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", @@ -20225,44 +19608,42 @@ "node": ">=10" } }, - "node_modules/jest-runner/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "node_modules/jest-runtime/node_modules/jest-haste-map": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" } }, - "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -20270,36 +19651,37 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz", + "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/expect-utils": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-util": "30.4.1" + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "node_modules/jest-runtime/node_modules/jest-regex-util": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -20310,41 +19692,50 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", + "node_modules/jest-runtime/node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "license": "BlueOak-1.0.0", "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-runner/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", + "node_modules/jest-runtime/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "yocto-queue": "^0.1.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-runner/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/jest-runtime/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -20353,199 +19744,70 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-runner/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "node_modules/jest-runtime/node_modules/pretty-format": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", + "node_modules/jest-runtime/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/jest-runner/node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "node_modules/jest-snapshot": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.5.2.tgz", + "integrity": "sha512-jKIdes25AnAH73dOCi2qE6J6vHJ6L2vyBS11M89kT50DVJcLTf2AOjvcc+2vVaN8lUbY5v2R83aqXo3Ro9fqYA==", "license": "MIT", "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", - "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.4.1", - "@jest/fake-timers": "30.4.1", - "@jest/globals": "30.4.1", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.5.2", + "@jest/get-type": "30.5.0", + "@jest/snapshot-utils": "30.5.1", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", + "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", - "collect-v8-coverage": "^1.0.2", - "glob": "^10.5.0", + "expect": "30.5.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-mock": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", - "license": "MIT", - "dependencies": { - "expect": "30.4.1", - "jest-snapshot": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@sinonjs/fake-timers": "^15.4.0", - "@types/node": "*", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/globals": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", - "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.4.1", - "@jest/expect": "30.4.1", - "@jest/types": "30.4.1", - "jest-mock": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" + "jest-diff": "30.5.2", + "jest-matcher-utils": "30.5.2", + "jest-message-util": "30.5.1", + "jest-util": "30.5.1", + "pretty-format": "30.5.1", + "semver": "^7.7.2", + "synckit": "^0.11.8" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "node_modules/jest-snapshot/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -20554,23 +19816,23 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "node_modules/jest-snapshot/node_modules/@jest/transform": { + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -20579,14 +19841,14 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -20597,22 +19859,13 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "node_modules/jest-snapshot/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", - "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/jest-runtime/node_modules/ansi-styles": { + "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", @@ -20624,10 +19877,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "node_modules/jest-snapshot/node_modules/babel-plugin-istanbul": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "license": "BSD-3-Clause", "workspaces": [ "test/babel-8" @@ -20637,75 +19890,30 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" - } - }, - "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/jest-runtime/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/jest-runtime/node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", + "node_modules/jest-snapshot/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "node": ">=12.0.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/jest-runtime/node_modules/istanbul-lib-instrument": { + "node_modules/jest-snapshot/node_modules/istanbul-lib-instrument": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", @@ -20721,74 +19929,42 @@ "node": ">=10" } }, - "node_modules/jest-runtime/node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "node_modules/jest-snapshot/node_modules/jest-haste-map": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-runtime/node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "node_modules/jest-snapshot/node_modules/jest-message-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -20796,68 +19972,22 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-snapshot": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", + "node_modules/jest-snapshot/node_modules/jest-regex-util": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.4.1", - "graceful-fs": "^4.2.11", - "jest-diff": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "pretty-format": "30.4.1", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "node_modules/jest-snapshot/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -20868,41 +19998,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-runtime/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/jest-snapshot/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -20911,46 +20010,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-runtime/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/write-file-atomic": { + "node_modules/jest-snapshot/node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", @@ -20963,125 +20038,61 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/jest-snapshot": { + "node_modules/jest-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", + "@types/node": "*", "chalk": "^4.0.0", - "expect": "^29.7.0", + "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "picomatch": "^2.2.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/jest-util/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, "node_modules/jest-validate": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", - "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.5.1.tgz", + "integrity": "sha512-i/buJ56wTpxihE93hQYNMfdOThS87+HGvLZzZJmU4xggPcdTYQq051iwALLCHp3q+SkCGH+EFejQZz5EbBSkkg==", "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.4.1", + "@jest/get-type": "30.5.0", + "@jest/types": "30.5.1", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-validate/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-validate/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -21091,13 +20102,13 @@ } }, "node_modules/jest-validate/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -21109,9 +20120,9 @@ } }, "node_modules/jest-validate/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, "node_modules/jest-validate/node_modules/ansi-styles": { @@ -21138,66 +20149,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-validate/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-validate/node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-watcher": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", - "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.5.2.tgz", + "integrity": "sha512-rqRgg4R11GA9m1UsEZwQeixHsgZReCn6TOHAHtIH33yXrIvoX0OGPA20Yzzjkz7X40fZvcRSxEpQppYPcWzmcQ==", "license": "MIT", "dependencies": { - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", + "@jest/test-result": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "string-length": "^4.0.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-watcher/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-watcher/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -21207,13 +20196,13 @@ } }, "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -21225,57 +20214,99 @@ } }, "node_modules/jest-watcher/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest-watcher/node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "@jest/types": "30.5.1", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-watcher/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-watcher/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/jest-worker": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.5.1.tgz", + "integrity": "sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA==", "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.5.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/@jest/schemas": { + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-watcher/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "node_modules/jest-worker/node_modules/@jest/types": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", + "dependencies": { + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-watcher/node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "node_modules/jest-worker/node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "license": "MIT" + }, + "node_modules/jest-worker/node_modules/jest-util": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -21286,10 +20317,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-watcher/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/jest-worker/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -21298,39 +20329,10 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-watcher/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -21342,23 +20344,10 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest/node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest/node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -21368,13 +20357,13 @@ } }, "node_modules/jest/node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -21386,24 +20375,15 @@ } }, "node_modules/jest/node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "license": "MIT" }, - "node_modules/jest/node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/joi": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.2.1.tgz", - "integrity": "sha512-2/OKlogiESf2Nh3TFCrRjrr9z1DRHeW0I+KReF67+4J0Ns+8hBtHRmoWAZ2OFU6I5+TWLEe6sVlSdXPjHm5UbQ==", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-18.3.0.tgz", + "integrity": "sha512-/RwAK4BAfzcdbdFg073tzq4/xhY6Q7lMd5AmjqTL6pu0QFJdEmtswgm8BvgwXvOKuPNYQ8XrdQrrW/gF65LiNw==", "license": "BSD-3-Clause", "dependencies": { "@hapi/address": "^5.1.1", @@ -21429,6 +20409,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/jpeg-exif/-/jpeg-exif-1.1.4.tgz", "integrity": "sha512-a+bKEcCjtuW5WTdgeXFzswSrdqi0jk4XlEtZlx5A94wCoBpFjfFTbo/Tra5SpNCl/YFZPvcV1dJc+TAYeg6ROQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "license": "MIT" }, "node_modules/jquery": { @@ -21444,10 +20425,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -21496,6 +20487,30 @@ } } }, + "node_modules/jsdom/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/jsdom/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -21783,8 +20798,93 @@ "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, - "engines": { - "node": ">=20.0.0" + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/loader-runner": { @@ -21813,9 +20913,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.debounce": { @@ -21883,7 +20983,9 @@ } }, "node_modules/log-update/node_modules/ansi-escapes": { - "version": "7.2.0", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", "dev": true, "license": "MIT", "dependencies": { @@ -21909,6 +21011,44 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/log-update/node_modules/strip-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", @@ -21925,6 +21065,24 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -22013,6 +21171,7 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" @@ -22147,38 +21306,6 @@ "integrity": "sha512-jR1MwkLaZGa8Zftct9ZFruyWFrdl9ZyD2OliXNy9Qq5bBPeg5wHVpBQF9p5GjnicSDQqvBVpysxTPKmWdsfWMA==", "license": "ISC" }, - "node_modules/maplibre-gl/node_modules/global-prefix": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", - "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", - "license": "MIT", - "dependencies": { - "ini": "^4.1.3", - "kind-of": "^6.0.3", - "which": "^4.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/maplibre-gl/node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/maplibre-gl/node_modules/isexe": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", - "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/maplibre-gl/node_modules/potpack": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz", @@ -22206,21 +21333,6 @@ "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", "license": "ISC" }, - "node_modules/maplibre-gl/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -22284,6 +21396,15 @@ "url": "https://github.com/sindresorhus/mem?sponsor=1" } }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/memoize-one": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", @@ -22346,9 +21467,9 @@ } }, "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/mime-db": { @@ -22373,12 +21494,12 @@ } }, "node_modules/mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6" } }, "node_modules/mimic-function": { @@ -22417,9 +21538,10 @@ "license": "MIT" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -22438,10 +21560,10 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -22486,9 +21608,9 @@ } }, "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.31.0.tgz", + "integrity": "sha512-0acOTfMiWOheYS4eoWb80yYMb/JLvVv9SHbs2PehaDzfUG0Bw855SKyk0IKTnPGa5+U2bmi3W68l1+sGLX/pvw==", "license": "MIT", "engines": { "node": "*" @@ -22573,6 +21695,19 @@ } } }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/murmurhash-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", @@ -22603,9 +21738,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", "dev": true, "funding": [ { @@ -22622,11 +21757,12 @@ } }, "node_modules/napi-postinstall": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.7.tgz", + "integrity": "sha512-jyU4cU4kVAmy/3qjP+DcoQTNXfINHc+dFw54gGqWC8nu0mpV0kOnk7kff+J+Q18SbX0k3Np8Rm7yFjd3phatNQ==", "license": "MIT", "bin": { + "napi-patch": "lib/patch.js", "napi-postinstall": "lib/cli.js" }, "engines": { @@ -22709,9 +21845,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/node-int64": { "version": "0.4.0", @@ -22720,9 +21854,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.46", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz", - "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==", + "version": "2.0.61", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.61.tgz", + "integrity": "sha512-5NUN6QCxNFrS9oEA9RPS+d0AP+ooGBzzovY2JhIpDRHacPvOhHjXjUsUMX9qp4nLHZ+5jVgXB2jj/P4arGOE/g==", "license": "MIT", "engines": { "node": ">=18" @@ -22941,16 +22075,15 @@ } }, "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { - "mimic-function": "^5.0.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=18" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -23009,15 +22142,15 @@ } }, "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -23035,6 +22168,21 @@ "node": ">=8" } }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -23075,16 +22223,15 @@ "license": "MIT" }, "node_modules/parse-asn1": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", - "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.10.tgz", + "integrity": "sha512-gBlTKLbYnAJN9WjmawVOMfaGvVoy4lX0LH18t7ccwtEG9RgAa4ETf2eu3d2J4e/5SoCjCms0A0UF4tTw/Eyn6Q==", "license": "ISC", "dependencies": { "asn1.js": "^4.10.1", "browserify-aes": "^1.2.0", "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", + "pbkdf2": "^3.1.7", "safe-buffer": "^5.2.1" }, "engines": { @@ -23198,6 +22345,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -23287,51 +22435,20 @@ } }, "node_modules/pbkdf2": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", - "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.7.tgz", + "integrity": "sha512-nS4mvFgVwUrecPTRdpdseM2fwpdfnX0/HibA8DgBRQtihUAzHQYJFU2l+OlEtiXtpqkrMvCPDwyXMUnASDt6Qw==", "license": "MIT", "dependencies": { - "create-hash": "~1.1.3", + "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "ripemd160": "=2.0.1", + "ripemd160": "^2.0.3", "safe-buffer": "^5.2.1", - "sha.js": "^2.4.11", - "to-buffer": "^1.2.0" + "sha.js": "^2.4.12", + "to-buffer": "^1.2.2" }, "engines": { - "node": ">=0.12" - } - }, - "node_modules/pbkdf2/node_modules/create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "sha.js": "^2.4.0" - } - }, - "node_modules/pbkdf2/node_modules/hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1" - } - }, - "node_modules/pbkdf2/node_modules/ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", - "license": "MIT", - "dependencies": { - "hash-base": "^2.0.0", - "inherits": "^2.0.1" + "node": ">= 0.10" } }, "node_modules/pdfast": { @@ -23374,9 +22491,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -23420,9 +22537,9 @@ } }, "node_modules/plotly.js": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-3.5.1.tgz", - "integrity": "sha512-rUzQ7Q46whi1aWT2JlvKE2dnryNORPrxyy66OGSMXgejK3XgD4ysD9SapMOI1RzzUJyX0KbfVDFcB9/DqOyH9Q==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-3.7.0.tgz", + "integrity": "sha512-r17/w3Ob/E+A1vqN382PV/6Dz+IAxAsxNCpWcnGfGFLqE0M6vPUa+ve7HPhivrl9LMicZg2Fy0U5GbpauHo32A==", "license": "MIT", "dependencies": { "@plotly/d3": "3.8.2", @@ -23614,9 +22731,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz", + "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==", "dev": true, "funding": [ { @@ -23634,9 +22751,9 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.20", "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -23685,9 +22802,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.5.tgz", - "integrity": "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.7.tgz", + "integrity": "sha512-wWBro/7hJ40ye6TPiXkUQoXKCw23xSsjriUvqd7Uls9Sso3oLiON1flc18cCdnjgCRXw4fBVqUJJeOdDTh3P3g==", "dev": true, "license": "MIT", "dependencies": { @@ -23782,9 +22899,9 @@ "license": "MIT" }, "node_modules/probe-image-size": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.3.0.tgz", - "integrity": "sha512-7CaDeBwiAbh6ohXsvLbAZhO7wzsZAmaevfxe39qvCwRh8LyaZfDlBGGLU1CCTgrTLtCOdwBBhjOrIHaIIimHfQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.5.0.tgz", + "integrity": "sha512-ietdx4XPgmnzHRZOq1/KtcnsBkL4bRsBe+Szj5Tuq1/KPqDG42OspG1IhJb7vz6Z9pSzhp0J6UPnw6hujJTWoQ==", "funding": [ { "type": "github", @@ -23798,8 +22915,7 @@ "license": "MIT", "dependencies": { "lodash.merge": "^4.6.2", - "needle": "^2.5.2", - "stream-parser": "~0.3.1" + "needle": "^2.5.2" } }, "node_modules/process-nextick-args": { @@ -23887,9 +23003,9 @@ } }, "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/punycode": { @@ -24801,20 +23917,6 @@ "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", "license": "MIT" }, - "node_modules/react-is-18": { - "name": "react-is", - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, - "node_modules/react-is-19": { - "name": "react-is", - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", - "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", - "license": "MIT" - }, "node_modules/react-leaflet": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", @@ -25299,9 +24401,9 @@ } }, "node_modules/react-to-pdf/node_modules/dompurify": { - "version": "2.5.8", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.8.tgz", - "integrity": "sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==", + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.9.tgz", + "integrity": "sha512-i6mvVmWN4xo9LrhCOZrDgSs9noW6nOahbrmzjRbPF36YPyj5Ue5lgok0MHDWkG7xzpWFO2OYttXdzM7rJxHvNA==", "license": "(MPL-2.0 OR Apache-2.0)", "optional": true }, @@ -25369,6 +24471,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -25508,9 +24611,9 @@ } }, "node_modules/read-excel-file/node_modules/fflate": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", - "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.5.tgz", + "integrity": "sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g==", "license": "MIT" }, "node_modules/readable-stream": { @@ -25552,6 +24655,7 @@ "version": "2.15.4", "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "deprecated": "1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide", "license": "MIT", "dependencies": { "clsx": "^2.0.0", @@ -25979,6 +25083,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -26017,21 +25137,61 @@ "dependencies": { "glob": "^7.1.3" }, - "bin": { - "rimraf": "bin.js" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", + "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", "license": "MIT", "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "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==", + "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": { @@ -26041,13 +25201,13 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz", - "integrity": "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==", + "version": "4.66.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.66.0.tgz", + "integrity": "sha512-Onq6/qO4ARhxIs+jYiHE0pYehadLyMECAiGEqQ+0/aWND3+2PmifJIIqBLYtuBODqHTlOUEQFtIVPyCy0Lck7A==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" + "@types/estree": "1.0.9" }, "bin": { "rollup": "dist/bin/rollup" @@ -26057,43 +25217,35 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.49.0", - "@rollup/rollup-android-arm64": "4.49.0", - "@rollup/rollup-darwin-arm64": "4.49.0", - "@rollup/rollup-darwin-x64": "4.49.0", - "@rollup/rollup-freebsd-arm64": "4.49.0", - "@rollup/rollup-freebsd-x64": "4.49.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", - "@rollup/rollup-linux-arm-musleabihf": "4.49.0", - "@rollup/rollup-linux-arm64-gnu": "4.49.0", - "@rollup/rollup-linux-arm64-musl": "4.49.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", - "@rollup/rollup-linux-ppc64-gnu": "4.49.0", - "@rollup/rollup-linux-riscv64-gnu": "4.49.0", - "@rollup/rollup-linux-riscv64-musl": "4.49.0", - "@rollup/rollup-linux-s390x-gnu": "4.49.0", - "@rollup/rollup-linux-x64-gnu": "4.49.0", - "@rollup/rollup-linux-x64-musl": "4.49.0", - "@rollup/rollup-win32-arm64-msvc": "4.49.0", - "@rollup/rollup-win32-ia32-msvc": "4.49.0", - "@rollup/rollup-win32-x64-msvc": "4.49.0", + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.66.0", + "@rollup/rollup-android-arm64": "4.66.0", + "@rollup/rollup-darwin-arm64": "4.66.0", + "@rollup/rollup-darwin-x64": "4.66.0", + "@rollup/rollup-freebsd-arm64": "4.66.0", + "@rollup/rollup-freebsd-x64": "4.66.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.66.0", + "@rollup/rollup-linux-arm-musleabihf": "4.66.0", + "@rollup/rollup-linux-arm64-gnu": "4.66.0", + "@rollup/rollup-linux-arm64-musl": "4.66.0", + "@rollup/rollup-linux-loong64-gnu": "4.66.0", + "@rollup/rollup-linux-loong64-musl": "4.66.0", + "@rollup/rollup-linux-ppc64-gnu": "4.66.0", + "@rollup/rollup-linux-ppc64-musl": "4.66.0", + "@rollup/rollup-linux-riscv64-gnu": "4.66.0", + "@rollup/rollup-linux-riscv64-musl": "4.66.0", + "@rollup/rollup-linux-s390x-gnu": "4.66.0", + "@rollup/rollup-linux-x64-gnu": "4.66.0", + "@rollup/rollup-linux-x64-musl": "4.66.0", + "@rollup/rollup-openbsd-x64": "4.66.0", + "@rollup/rollup-openharmony-arm64": "4.66.0", + "@rollup/rollup-win32-arm64-msvc": "4.66.0", + "@rollup/rollup-win32-ia32-msvc": "4.66.0", + "@rollup/rollup-win32-x64-gnu": "4.66.0", + "@rollup/rollup-win32-x64-msvc": "4.66.0", "fsevents": "~2.3.2" } }, - "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.49.0.tgz", - "integrity": "sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, "node_modules/rrweb-cssom": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", @@ -26643,22 +25795,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -26669,34 +25805,15 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -26825,30 +25942,6 @@ "node": ">= 6" } }, - "node_modules/stream-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", - "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", - "license": "MIT", - "dependencies": { - "debug": "2" - } - }, - "node_modules/stream-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/stream-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, "node_modules/stream-shift": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", @@ -26916,17 +26009,17 @@ } }, "node_modules/string-width": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", - "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", - "dev": true, + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=20" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -26966,7 +26059,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -26976,13 +26068,12 @@ } }, "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -27130,13 +26221,12 @@ } }, "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-final-newline": { @@ -27908,18 +26998,73 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, + "node_modules/terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", + "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "glob": "^10.4.1", + "minimatch": "^10.2.2" }, "engines": { - "node": ">=8" + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/text-segmentation": { @@ -28031,9 +27176,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -28076,9 +27221,9 @@ } }, "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.6.tgz", + "integrity": "sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==", "dev": true, "license": "MIT", "engines": { @@ -28109,12 +27254,13 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/to-buffer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", - "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", "license": "MIT", "dependencies": { "isarray": "^2.0.5", @@ -28283,6 +27429,16 @@ "json5": "lib/cli.js" } }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -28318,13 +27474,12 @@ } }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -28478,9 +27633,9 @@ } }, "node_modules/undici": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", - "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz", + "integrity": "sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==", "license": "MIT", "engines": { "node": ">=20.18.1" @@ -28628,9 +27783,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", "funding": [ { "type": "opencollective", @@ -28739,6 +27894,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -28800,9 +27956,9 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.5.tgz", + "integrity": "sha512-4enwjFfi4IwtEh0w+jPzpLVOFQiPHmmzPxcHXQOyEur47o6u0jE573DmGpjA+7irXoMLYRZD5ZaFUEneS3abPg==", "dev": true, "license": "MIT", "dependencies": { @@ -28916,9 +28072,9 @@ } }, "node_modules/vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -28929,20 +28085,20 @@ } }, "node_modules/vitest": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", - "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.4", - "@vitest/mocker": "3.2.4", - "@vitest/pretty-format": "^3.2.4", - "@vitest/runner": "3.2.4", - "@vitest/snapshot": "3.2.4", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -28972,8 +28128,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.4", - "@vitest/ui": "3.2.4", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", "happy-dom": "*", "jsdom": "*" }, @@ -29002,9 +28158,9 @@ } }, "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -29042,6 +28198,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" @@ -29168,6 +28325,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" @@ -29364,18 +28522,17 @@ } }, "node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dev": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -29432,7 +28589,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -29445,7 +28601,6 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -29454,39 +28609,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -29523,9 +28652,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz", + "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==", "dev": true, "license": "MIT", "engines": { @@ -29619,9 +28748,9 @@ "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==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", "dev": true, "license": "ISC", "bin": { diff --git a/src/actions/__tests__/userManagement.test.js b/src/actions/__tests__/userManagement.test.js index 6dbd17a20bc..99c9ba71493 100644 --- a/src/actions/__tests__/userManagement.test.js +++ b/src/actions/__tests__/userManagement.test.js @@ -87,21 +87,50 @@ describe('User Management Actions', () => { ]); }); - it('allows an empty reason and removes a previously saved reason', async () => { - const mockUser = { _id: '123', notRehireableReason: 'Previous reason' }; - axios.patch.mockResolvedValueOnce({ data: {} }); + it('stores the audit history returned by the backend', async () => { + const mockUser = { _id: '123' }; + const history = [ + { + action: 'submitted', + reason: 'Missed commitments', + changedAt: '2026-01-02T03:04:00.000Z', + changedBy: { username: 'admin@example.org', firstName: 'Alex', lastName: 'Admin' }, + }, + ]; + axios.patch.mockResolvedValueOnce({ + data: { + notRehireableReason: 'Missed commitments', + notRehireableReasonHistory: history, + }, + }); - await store.dispatch(actions.updateRehireableStatus(mockUser, false, '')); + await store.dispatch(actions.updateRehireableStatus(mockUser, false, 'Missed commitments')); - expect(axios.patch).toHaveBeenCalledWith(ENDPOINTS.UPDATE_REHIREABLE_STATUS(mockUser._id), { - isRehireable: false, - notRehireableReason: '', - }); expect(store.getActions()).toEqual([ - { type: 'USER_PROFILE_UPDATE', user: { _id: '123', isRehireable: false } }, + { + type: 'USER_PROFILE_UPDATE', + user: { + _id: '123', + isRehireable: false, + notRehireableReason: 'Missed commitments', + notRehireableReasonHistory: history, + }, + }, ]); }); + it('does not send an empty reason when changing to not rehireable', async () => { + const mockUser = { _id: '123', notRehireableReason: 'Previous reason' }; + axios.patch.mockResolvedValueOnce({ data: {} }); + + await expect( + store.dispatch(actions.updateRehireableStatus(mockUser, false, ' ')), + ).rejects.toThrow('A reason is required'); + + expect(axios.patch).not.toHaveBeenCalled(); + expect(store.getActions()).toEqual([]); + }); + it('clears a saved reason when changing back to rehireable', async () => { const mockUser = { _id: '123', notRehireableReason: 'Previous reason' }; axios.patch.mockResolvedValueOnce({ data: {} }); @@ -250,6 +279,37 @@ describe('User Management Actions', () => { await store.dispatch(actions.getUserProfileBasicInfo({ source: mockSource })); expect(store.getActions()).toEqual(expectedActions); }); + + it('fetches a single user basic info by userId using the query-param contract', async () => { + const mockUserId = 'user-123'; + const mockBasicInfo = { _id: mockUserId, firstName: 'John', lastName: 'Doe' }; + + axios.get.mockResolvedValueOnce({ data: mockBasicInfo }); + + const expectedActions = [ + { type: 'FETCH_USER_PROFILE_BASIC_INFO' }, + { type: 'RECEIVE_USER_PROFILE_BASIC_INFO', payload: mockBasicInfo } + ]; + + await store.dispatch(actions.getUserProfileBasicInfo({ userId: mockUserId })); + expect(store.getActions()).toEqual(expectedActions); + expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.USER_PROFILE_BASIC_INFO_BY_ID(mockUserId)); + }); + + it('does not leave the fetch pending when the userId lookup is rejected (400)', async () => { + const mockUserId = 'user-123'; + const badRequestError = { response: { status: 400, data: { error: 'Source parameter is required' } } }; + + axios.get.mockRejectedValueOnce(badRequestError); + + const expectedActions = [ + { type: 'FETCH_USER_PROFILE_BASIC_INFO' }, + { type: 'FETCH_USER_PROFILE_BASIC_INFO_ERROR' } + ]; + + await store.dispatch(actions.getUserProfileBasicInfo({ userId: mockUserId })); + expect(store.getActions()).toEqual(expectedActions); + }); }); describe('UI State Actions', () => { diff --git a/src/actions/__tests__/weeklyProjectSummaryActions.test.js b/src/actions/__tests__/weeklyProjectSummaryActions.test.js new file mode 100644 index 00000000000..7d5f47395af --- /dev/null +++ b/src/actions/__tests__/weeklyProjectSummaryActions.test.js @@ -0,0 +1,96 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import axios from 'axios'; +import { + fetchWeeklyProjectSummaryProjectStatus, +} from '../bmdashboard/weeklyProjectSummaryActions'; +import { + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, +} from '../../constants/bmdashboard/weeklyProjectSummaryConstants'; + +vi.mock('axios'); + +const mockStore = configureMockStore([thunk]); + +const createDeferred = () => { + let resolve; + let reject; + const promise = new Promise((promiseResolve, promiseReject) => { + resolve = promiseResolve; + reject = promiseReject; + }); + + return { promise, resolve, reject }; +}; + +describe('weeklyProjectSummaryActions Project Status requests', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('dispatches unique request metadata for rapid Project Status requests', async () => { + const firstRequest = createDeferred(); + const secondRequest = createDeferred(); + axios.get.mockReturnValueOnce(firstRequest.promise).mockReturnValueOnce(secondRequest.promise); + const store = mockStore({}); + + const firstDispatch = store.dispatch( + fetchWeeklyProjectSummaryProjectStatus({ + startDate: '2026-09-13', + endDate: '2026-09-19', + projectId: '', + comparisonStartDate: null, + comparisonEndDate: undefined, + }), + ); + const secondDispatch = store.dispatch( + fetchWeeklyProjectSummaryProjectStatus({ + startDate: '2026-09-20', + endDate: '2026-09-26', + }), + ); + + const [firstBegin, secondBegin] = store.getActions(); + expect(firstBegin.type).toBe(FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN); + expect(secondBegin.type).toBe(FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN); + expect(firstBegin.meta.requestId).not.toBe(secondBegin.meta.requestId); + expect(firstBegin.meta.requestKey).toBe('endDate=2026-09-19&startDate=2026-09-13'); + expect(secondBegin.meta.requestKey).toBe('endDate=2026-09-26&startDate=2026-09-20'); + + secondRequest.resolve({ data: { current: { metrics: { totalProjects: { value: 2 } } } } }); + await secondDispatch; + firstRequest.resolve({ data: { current: { metrics: { totalProjects: { value: 1 } } } } }); + await firstDispatch; + + const successActions = store + .getActions() + .filter(action => action.type === FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS); + expect(successActions).toHaveLength(2); + expect(successActions[0].meta.requestId).toBe(secondBegin.meta.requestId); + expect(successActions[1].meta.requestId).toBe(firstBegin.meta.requestId); + }); + + it('dispatches the active request metadata on Project Status failure', async () => { + const error = new Error('network failure'); + axios.get.mockRejectedValue(error); + const store = mockStore({}); + + const result = await store.dispatch( + fetchWeeklyProjectSummaryProjectStatus({ + startDate: '2026-09-13', + endDate: '2026-09-19', + }), + ); + + const [beginAction, errorAction] = store.getActions(); + expect(result).toBeNull(); + expect(errorAction).toMatchObject({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + payload: error, + meta: beginAction.meta, + }); + }); +}); diff --git a/src/actions/actionTypes.js b/src/actions/actionTypes.js new file mode 100644 index 00000000000..943ef0d67e2 --- /dev/null +++ b/src/actions/actionTypes.js @@ -0,0 +1,2 @@ +export const FETCH_ALL_BADGES = 'FETCH_ALL_BADGES'; +export const FETCH_BADGES_FAILURE = 'FETCH_BADGES_FAILURE'; \ No newline at end of file diff --git a/src/actions/bmdashboard/weeklyProjectSummaryActions.js b/src/actions/bmdashboard/weeklyProjectSummaryActions.js index 74836a9c8dd..07e9dfc2f65 100644 --- a/src/actions/bmdashboard/weeklyProjectSummaryActions.js +++ b/src/actions/bmdashboard/weeklyProjectSummaryActions.js @@ -1,7 +1,12 @@ +import axios from 'axios'; +import { ENDPOINTS } from '~/utils/URL'; import { SET_PROJECT_FILTER, SET_DATE_RANGE_FILTER, SET_COMPARISON_PERIOD_FILTER, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, } from '../../constants/bmdashboard/weeklyProjectSummaryConstants'; export const setProjectFilter = project => ({ @@ -18,3 +23,64 @@ export const setComparisonPeriodFilter = comparisonPeriod => ({ type: SET_COMPARISON_PERIOD_FILTER, payload: comparisonPeriod, }); + +let weeklyProjectSummaryProjectStatusRequestCounter = 0; + +const createWeeklyProjectSummaryProjectStatusRequestId = () => { + weeklyProjectSummaryProjectStatusRequestCounter += 1; + return `weekly-project-summary-project-status-${Date.now()}-${weeklyProjectSummaryProjectStatusRequestCounter}`; +}; + +export const getWeeklyProjectSummaryProjectStatusRequestKey = params => { + const queryParams = new URLSearchParams(); + Object.entries(params || {}) + .filter(([, value]) => value !== undefined && value !== null && value !== '') + .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) + .forEach(([key, value]) => { + queryParams.append(key, value); + }); + + return queryParams.toString(); +}; + +export const fetchWeeklyProjectSummaryProjectStatusBegin = meta => ({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN, + meta, +}); + +export const fetchWeeklyProjectSummaryProjectStatusSuccess = (payload, meta) => ({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + payload, + meta, +}); + +export const fetchWeeklyProjectSummaryProjectStatusError = (error, meta) => ({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + payload: error, + meta, +}); + +export const fetchWeeklyProjectSummaryProjectStatus = params => async dispatch => { + const requestId = createWeeklyProjectSummaryProjectStatusRequestId(); + const requestKey = getWeeklyProjectSummaryProjectStatusRequestKey(params); + const requestMeta = { requestId, requestKey }; + + dispatch(fetchWeeklyProjectSummaryProjectStatusBegin(requestMeta)); + + try { + const queryParams = new URLSearchParams(); + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined && value !== null && value !== '') { + queryParams.append(key, value); + } + }); + + const url = `${ENDPOINTS.BM_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS}?${queryParams.toString()}`; + const response = await axios.get(url); + dispatch(fetchWeeklyProjectSummaryProjectStatusSuccess(response.data, requestMeta)); + return response.data; + } catch (error) { + dispatch(fetchWeeklyProjectSummaryProjectStatusError(error, requestMeta)); + return null; + } +}; diff --git a/src/actions/communityPortal/eventActions.js b/src/actions/communityPortal/eventActions.js deleted file mode 100644 index 4ebd88af93a..00000000000 --- a/src/actions/communityPortal/eventActions.js +++ /dev/null @@ -1,26 +0,0 @@ -import axios from 'axios'; -import { ENDPOINTS } from '../../utils/URL'; -import { toast } from 'react-toastify'; - -export const createEvent = eventData => { - return async dispatch => { - try { - const res = await axios.post(ENDPOINTS.EVENTS, eventData); - if (res.status === 201) { - toast.success('Event created successfully!'); - return { success: true, event: res.data }; - } - return { success: false, error: 'Unexpected response status' }; - } catch (error) { - if (error.response?.status === 500) { - toast.error('Error creating event. Please try again.'); - } else if (error.response?.status === 404 || error.response?.status === 403 || error.response?.status === 400) { - toast.error('Permission or Validation Error. Please check your input or access rights'); - } else { - toast.error('Error creating event. Please try again.'); - } - return { success: false, error: error.response?.data || error.message }; - } - }; -}; - diff --git a/src/actions/promotionActions.js b/src/actions/promotionActions.js index f66a05d6124..06f8571e83c 100644 --- a/src/actions/promotionActions.js +++ b/src/actions/promotionActions.js @@ -6,6 +6,11 @@ export const getPromotionEligibility = async requestor => { return res.data; }; +export const getPromotionPending = async requestor => { + const res = await axios.post(ENDPOINTS.PROMOTION_PENDING, { requestor }); + return res.data; +}; + export const postPromotionEligibility = async (memberIds, requestor) => { const res = await axios.post(ENDPOINTS.PROMOTE_MEMBERS, { memberIds, diff --git a/src/actions/userManagement.js b/src/actions/userManagement.js index a2e0c9b7b61..f554fc18b33 100644 --- a/src/actions/userManagement.js +++ b/src/actions/userManagement.js @@ -305,16 +305,31 @@ export const updateRehireableStatus = (user, isRehireable, notRehireableReason = const reason = typeof notRehireableReason === 'string' ? notRehireableReason.trim() : ''; const requestData = { isRehireable }; - if (!isRehireable && reason) { + if (!isRehireable && !reason) { + throw new Error('A reason is required when a user is not rehireable.'); + } + + if (!isRehireable) { userProfile.notRehireableReason = reason; requestData.notRehireableReason = reason; } else { delete userProfile.notRehireableReason; - if (!isRehireable) requestData.notRehireableReason = ''; } - await axios.patch(ENDPOINTS.UPDATE_REHIREABLE_STATUS(user._id), requestData); + const response = await axios.patch(ENDPOINTS.UPDATE_REHIREABLE_STATUS(user._id), requestData); + const responseData = response?.data || {}; + if (Array.isArray(responseData.notRehireableReasonHistory)) { + userProfile.notRehireableReasonHistory = responseData.notRehireableReasonHistory; + } + if (typeof responseData.notRehireableReason === 'string') { + if (responseData.notRehireableReason) { + userProfile.notRehireableReason = responseData.notRehireableReason; + } else { + delete userProfile.notRehireableReason; + } + } dispatch(userProfileUpdateAction(userProfile)); + return userProfile; }; }; @@ -423,7 +438,7 @@ export const getUserProfileBasicInfo = ({ userId, source } = {}) => { // API request to fetch basic user profile information let userProfileBasicInfoPromise; if (userId) - userProfileBasicInfoPromise = axios.get(ENDPOINTS.USER_PROFILE(userId)); + userProfileBasicInfoPromise = axios.get(ENDPOINTS.USER_PROFILE_BASIC_INFO_BY_ID(userId)); else if (source) userProfileBasicInfoPromise = axios.get(ENDPOINTS.USER_PROFILE_BASIC_INFO(source)); else @@ -471,4 +486,4 @@ export const updateUserInfomation = value => dispatch => { */ export const finishUserInfoUpdate = () => dispatch => { dispatch({ type: FINISH_USER_INFO_UPDATE }); -}; \ No newline at end of file +}; diff --git a/src/components/BMDashboard/InteractiveMap/BaseInteractiveMap.jsx b/src/components/BMDashboard/InteractiveMap/BaseInteractiveMap.jsx index 4e15625aa15..6d7af7f0f56 100644 --- a/src/components/BMDashboard/InteractiveMap/BaseInteractiveMap.jsx +++ b/src/components/BMDashboard/InteractiveMap/BaseInteractiveMap.jsx @@ -1,6 +1,13 @@ import { MapContainer, TileLayer } from 'react-leaflet'; import MarkerClusterGroup from '@changey/react-leaflet-markercluster'; -import { MapThemeUpdater, ProjectMarkers, MapLegend, ProjectCounter } from './MapSharedComponents'; +import { + MapThemeUpdater, + ProjectMarkers, + MapLegend, + ProjectCounter, + MapConfig, +} from './MapSharedComponents'; +import styles from './InteractiveMap.module.css'; function BaseInteractiveMap({ orgs = [], @@ -38,6 +45,7 @@ function BaseInteractiveMap({ return (
diff --git a/src/components/BMDashboard/InteractiveMap/InteractiveMap.jsx b/src/components/BMDashboard/InteractiveMap/InteractiveMap.jsx index 6932911f619..6163c0f3d4e 100644 --- a/src/components/BMDashboard/InteractiveMap/InteractiveMap.jsx +++ b/src/components/BMDashboard/InteractiveMap/InteractiveMap.jsx @@ -14,6 +14,7 @@ import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; import styles from './InteractiveMap.module.css'; +import { MapConfig } from './MapSharedComponents'; const MapDateInput = forwardRef(({ darkMode, className, ...props }, ref) => ( @@ -511,11 +505,8 @@ export default function InteractiveMap() { [-85, -180], [85, 180], ]} - url={ - darkMode - ? 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png' - : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' - } + url={MapConfig.tileUrl} + attribution='© OpenStreetMap contributors' minZoom={2} maxZoom={15} /> diff --git a/src/components/BMDashboard/InteractiveMap/InteractiveMap.module.css b/src/components/BMDashboard/InteractiveMap/InteractiveMap.module.css index 92545378130..af3cb9d025b 100644 --- a/src/components/BMDashboard/InteractiveMap/InteractiveMap.module.css +++ b/src/components/BMDashboard/InteractiveMap/InteractiveMap.module.css @@ -343,7 +343,9 @@ .mapArea { position: relative; width: 100%; - height: 90vh; + + /* Fixed, responsive height so the whole map fits inside its dashboard card */ + height: clamp(320px, 55vh, 520px); border-radius: 12px; overflow: hidden; margin-top: 10px; @@ -368,9 +370,10 @@ outline: 1px solid transparent; } -/* Dark tiles already provide the dark-mode map look; avoid extra dimming. */ -.darkMap { - filter: none; +/* Dark mode: darken the standard OSM tiles (keyless). Only the tile layer is filtered, + so markers, clusters, legend and popups keep their real colors. */ +.darkMap :global(.leaflet-tile-pane) { + filter: invert(1) hue-rotate(180deg) brightness(0.95) contrast(0.9) saturate(0.6); } /* ---------------------------------- @@ -435,11 +438,6 @@ color: #6acfde !important; } -/* Hide zoom buttons */ -:global(.leaflet-control-zoom) { - display: none !important; -} - :global(.leaflet-control) { z-index: 2000 !important; } @@ -511,8 +509,8 @@ .legendBox { position: absolute; /* absolute inside the map container */ - width: 160px; /* fixed width */ - height: 180px; /* fixed height */ + width: max-content; /* size to content so it covers as little of the map as possible */ + height: max-content; cursor: move; user-select: none; padding: 10px 12px; @@ -531,6 +529,27 @@ justify-content: flex-start; } +.legendBox h4 { + margin: 0 0 6px; + font-size: 14px; + font-weight: 700; +} + +/* Zoom buttons: keep them readable in dark mode */ +.darkPage :global(.leaflet-bar a) { + background-color: #1c2541; + color: #f8fafc; + border-bottom-color: #465a74; +} + +.darkPage :global(.leaflet-bar a:hover) { + background-color: #2d4059; +} + +.darkPage :global(.leaflet-bar) { + border-color: #465a74; +} + .darkPage .legendBox { border: 1px solid rgb(255 255 255 / 15%); color: #fff; diff --git a/src/components/BMDashboard/InteractiveMap/MapSharedComponents.jsx b/src/components/BMDashboard/InteractiveMap/MapSharedComponents.jsx index d1a944d74ff..81cf799c27c 100644 --- a/src/components/BMDashboard/InteractiveMap/MapSharedComponents.jsx +++ b/src/components/BMDashboard/InteractiveMap/MapSharedComponents.jsx @@ -504,10 +504,9 @@ export const MapUtils = { MAP CONFIGURATION CONSTANTS ----------------------------------------------------- */ export const MapConfig = { - tileUrls: { - dark: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', - light: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', - }, + // One tile source for both themes. CARTO's dark_all tiles now require an API key + // (they render "API KEY REQUIRED"), so dark mode darkens these tiles with CSS instead. + tileUrl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', maxZoom: 15, minZoom: 1, clusterSettings: { diff --git a/src/components/BMDashboard/Issues/IssueCharts.module.css b/src/components/BMDashboard/Issues/IssueCharts.module.css index 465defd6fbf..c4188a76009 100644 --- a/src/components/BMDashboard/Issues/IssueCharts.module.css +++ b/src/components/BMDashboard/Issues/IssueCharts.module.css @@ -549,3 +549,93 @@ Issue Charts Module CSS :global(.darkCalendar) :global(.react-datepicker__triangle) { display: none !important; } + +/* ----- Issue Tracking card (Weekly Project Summary) ----- */ +.filtersRow { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.75rem; + padding: 1rem 1rem 0.5rem; +} + +.dateRangeGroup { + display: flex; + align-items: center; + gap: 0.5rem; + flex: 0 1 auto; + min-width: 0; +} + +.dateRangeGroup :global(.react-datepicker-wrapper) { + width: 9.5rem; +} + +.dateRangeGroup :global(.react-datepicker-wrapper) input { + width: 100%; +} + +.dateSeparator { + white-space: nowrap; +} + +.projectsFilter { + flex: 1 1 220px; + min-width: 0; +} + +.typeFilter { + flex: 0 0 auto; +} + +.filterControl { + height: 38px; + font-size: 0.875rem; + box-sizing: border-box; +} + +.issuesChartArea { + position: relative; + width: 100%; + max-width: 100%; + min-width: 0; + box-sizing: border-box; + padding: 0.5rem 1rem 1rem; +} + +.dark .noData { + color: #cfd7e3; +} + +@media (width <= 576px) { + .dateRangeGroup { + flex: 1 1 100%; + } + + .dateRangeGroup :global(.react-datepicker-wrapper) { + flex: 1 1 0; + width: auto; + min-width: 0; + } + + .projectsFilter, + .typeFilter { + flex: 1 1 100%; + } + + .typeFilter select { + width: 100%; + } +} + +/* Dark mode: readable date placeholders + match the type select to the other controls */ +.dark .dateDark::placeholder { + color: #cfd7e3 !important; + opacity: 1; +} + +.dark .selectDark { + background-color: #2b3e59 !important; + border-color: #4a5a72 !important; + color: #fff !important; +} diff --git a/src/components/BMDashboard/Issues/LongestOpenIssuesChart.jsx b/src/components/BMDashboard/Issues/LongestOpenIssuesChart.jsx index 9447cf91851..9507e4b8ce1 100644 --- a/src/components/BMDashboard/Issues/LongestOpenIssuesChart.jsx +++ b/src/components/BMDashboard/Issues/LongestOpenIssuesChart.jsx @@ -56,6 +56,9 @@ function IssuesCharts({ bmProjects = [] }) { borderColor: graphType === 'Longest Open' ? 'rgba(54, 162, 235, 1)' : 'rgba(255, 99, 132, 1)', borderWidth: 1, + barPercentage: 0.6, + categoryPercentage: 0.8, + maxBarThickness: 32, }, ], }; @@ -64,16 +67,32 @@ function IssuesCharts({ bmProjects = [] }) { const vals = chartData.map(d => (graphType === 'Longest Open' ? d.daysOpen : d.totalCost)); const dataMax = vals.length > 0 ? Math.max(...vals) : 600; const xMax = Math.ceil((dataMax + 50) / 250) * 250; + const gridColor = darkMode ? 'rgba(255, 255, 255, 0.12)' : 'rgba(0, 0, 0, 0.08)'; + const axisBorderColor = darkMode ? 'rgba(255, 255, 255, 0.35)' : 'rgba(0, 0, 0, 0.25)'; return { indexAxis: 'y', responsive: true, maintainAspectRatio: false, + resizeDelay: 100, layout: { - padding: { right: 80, left: 10 }, + padding: ({ chart }) => ({ right: chart.width < 420 ? 56 : 80, left: 4 }), }, plugins: { legend: { display: false }, + tooltip: { + backgroundColor: darkMode ? '#1e2d42' : '#ffffff', + titleColor: darkMode ? '#ffffff' : '#111111', + bodyColor: darkMode ? '#e0e6f0' : '#333333', + borderColor: darkMode ? '#4a5a72' : '#ced4da', + borderWidth: 1, + callbacks: { + title: items => { + const issue = chartData[items[0]?.dataIndex]; + return issue ? issue.title || String(issue.issueId) : ''; + }, + }, + }, datalabels: { anchor: 'end', align: 'right', @@ -102,10 +121,20 @@ function IssuesCharts({ bmProjects = [] }) { color: darkMode ? '#fff' : '#000', }, ticks: { stepSize: 250, color: darkMode ? '#ccc' : '#333' }, + grid: { color: gridColor }, + border: { color: axisBorderColor }, }, y: { afterFit: scale => { - scale.width = 200; + scale.width = Math.round(Math.min(200, Math.max(90, scale.chart.width * 0.32))); + }, + // Shorten y-axis labels to fit the label column (full title is in the tooltip). + afterTickToLabelConversion: scale => { + const maxChars = Math.max(10, Math.floor((scale.chart.width * 0.32) / 7.5)); + scale.ticks.forEach(tick => { + const label = String(tick.label ?? ''); + tick.label = label.length > maxChars ? `${label.slice(0, maxChars - 1)}…` : label; + }); }, title: { display: true, @@ -118,6 +147,8 @@ function IssuesCharts({ bmProjects = [] }) { maxRotation: 0, autoSkip: false, }, + grid: { color: gridColor }, + border: { color: axisBorderColor }, }, }, elements: { @@ -129,73 +160,77 @@ function IssuesCharts({ bmProjects = [] }) { const projectOptions = bmProjects.map(p => ({ value: p._id, label: p.name })); const selectedProjectOptions = projectOptions.filter(opt => selectedProjects.includes(opt.value)); - const darkSelectStyles = darkMode - ? { - control: base => ({ - ...base, - background: '#2b3e59', - borderColor: '#4a5a72', - color: '#fff', - }), - menu: base => ({ ...base, background: '#2b3e59' }), - option: (base, { isFocused }) => ({ - ...base, - background: isFocused ? '#4a5a72' : '#2b3e59', - color: '#fff', - }), - multiValue: base => ({ ...base, background: '#4a5a72' }), - multiValueLabel: base => ({ ...base, color: '#fff' }), - singleValue: base => ({ ...base, color: '#fff' }), - input: base => ({ ...base, color: '#fff' }), - placeholder: base => ({ ...base, color: '#aaa' }), - } - : {}; + const selectStyles = { + control: base => ({ + ...base, + minHeight: 38, + ...(darkMode && { background: '#2b3e59', borderColor: '#4a5a72', color: '#fff' }), + }), + menu: base => ({ ...base, zIndex: 5, ...(darkMode && { background: '#2b3e59' }) }), + option: (base, { isFocused }) => + darkMode ? { ...base, background: isFocused ? '#4a5a72' : '#2b3e59', color: '#fff' } : base, + multiValue: base => (darkMode ? { ...base, background: '#4a5a72' } : base), + multiValueLabel: base => (darkMode ? { ...base, color: '#fff' } : base), + singleValue: base => (darkMode ? { ...base, color: '#fff' } : base), + input: base => (darkMode ? { ...base, color: '#fff' } : base), + placeholder: base => ({ ...base, color: darkMode ? '#cfd7e3' : '#6c757d' }), + }; + + // Height grows with the number of bars; width always follows the card. + const chartHeight = Math.max(240, chartData.length * 56 + 110); return (
-
-
+
+
setDateRange(prev => ({ ...prev, start: value }))} placeholderText="Start date" + ariaLabelledBy="issues-start-date" calendarClassName={darkMode ? styles.darkCalendar : styles.lightCalendar} - className={darkMode ? styles.dateDark : styles.dateInput} + className={`${darkMode ? styles.dateDark : styles.dateInput} ${styles.filterControl}`} isClearable /> - to + to setDateRange(prev => ({ ...prev, end: value }))} placeholderText="End date" + ariaLabelledBy="issues-end-date" calendarClassName={darkMode ? styles.darkCalendar : styles.lightCalendar} - className={darkMode ? styles.dateDark : styles.dateInput} + className={`${darkMode ? styles.dateDark : styles.dateInput} ${styles.filterControl}`} isClearable />
-
+
setGraphType(e.target.value)} - className={darkMode ? styles.selectDark : styles.select} + className={`${darkMode ? styles.selectDark : styles.select} ${styles.filterControl}`} >
-
+
0 ? chartHeight : 'auto' }} + > {chartData.length > 0 ? ( YEAR_COLORS[idx % YEAR_COLORS.length]; + const stripNumericSuffix = value => { const str = String(value); let end = str.length; @@ -103,7 +117,36 @@ const issueChartCardTickRotationPlugin = { }, }; -const generateColor = idx => `hsl(${(idx * 60) % 360}, 70%, 50%)`; +// Draws the issue count above each bar (no extra dependency needed) +const barValueLabelsPlugin = { + id: 'issueChartBarValueLabels', + afterDatasetsDraw(chart, _args, pluginOptions = {}) { + if (!pluginOptions.enabled) return; + + const { ctx } = chart; + ctx.save(); + ctx.textAlign = 'center'; + ctx.textBaseline = 'bottom'; + ctx.fillStyle = pluginOptions.color || '#232323'; + + chart.data.datasets.forEach((dataset, datasetIndex) => { + if (!chart.isDatasetVisible(datasetIndex)) return; + const meta = chart.getDatasetMeta(datasetIndex); + + meta.data.forEach((bar, index) => { + const value = Number(dataset.data?.[index]) || 0; + if (value <= 0) return; + + // Scale text to the bar width so labels stay readable without overlapping neighbours + const fontSize = Math.max(8, Math.min(12, Math.floor((bar.width || 10) * 0.9))); + ctx.font = `600 ${fontSize}px sans-serif`; + ctx.fillText(String(value), bar.x, bar.y - 2); + }); + }); + + ctx.restore(); + }, +}; const handleLegendClick = (e, legendItem, legend) => { const index = legendItem.datasetIndex; @@ -147,11 +190,15 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { const { loading, issues, error } = useSelector(state => state.bmissuechart); const [filters, setFilters] = useState({ issueTypes: [], years: [] }); + // 'multi' compares several years side by side; 'single' focuses on one year + const [viewMode, setViewMode] = useState('multi'); + const [singleYear, setSingleYear] = useState(null); const [isMobile, setIsMobile] = useState( typeof window !== 'undefined' ? window.innerWidth <= 640 : false, ); const isCardVariant = variant === 'card'; + const isSingleYearView = viewMode === 'single'; useEffect(() => { dispatch(fetchIssues()); @@ -229,11 +276,14 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { const flatIssueTypeOptions = flattenOptions(issueTypes); const uniqueYears = years.map(y => y.value); + const latestYear = uniqueYears.at(-1) ?? null; + // Single-year view defaults to the most recent year until the user picks one + const selectedSingleYear = singleYear ?? latestYear; const yearColorMap = useMemo( () => uniqueYears.reduce((acc, year, idx) => { - acc[year] = generateColor(idx); + acc[year] = getYearColor(idx); return acc; }, {}), [uniqueYears], @@ -266,6 +316,7 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { issueTypes: [], years: [], }); + setSingleYear(null); }; const chartData = useMemo(() => { @@ -307,7 +358,10 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { return aLower.localeCompare(bLower, undefined, { numeric: true }); }); - const filteredYears = filters.years.length ? filters.years : uniqueYears; + let filteredYears = filters.years.length ? filters.years : uniqueYears; + if (isSingleYearView) { + filteredYears = selectedSingleYear == null ? [] : [selectedSingleYear]; + } const labels = selectedBases; const datasets = filteredYears.map(year => ({ @@ -324,7 +378,7 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { })); return { labels, datasets }; - }, [issues, filters, uniqueYears, yearColorMap, darkMode]); + }, [issues, filters, uniqueYears, yearColorMap, darkMode, isSingleYearView, selectedSingleYear]); const chartAnalysis = useMemo(() => { const labels = chartData?.labels ?? []; @@ -401,6 +455,8 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { maintainAspectRatio: false, layout: { padding: { + // Room above the tallest bar for its value label + top: 16, bottom: isCardVariant ? 8 : 56, }, }, @@ -436,6 +492,10 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { datalabels: { display: false, }, + issueChartBarValueLabels: { + enabled: true, + color: darkMode ? '#f3f4f6' : '#1f2937', + }, issueChartCardTickRotation: { enabled: isCardVariant, isMobile, @@ -499,7 +559,7 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { ); const chartPlugins = useMemo( - () => [xAxisBackgroundPlugin(darkMode), issueChartCardTickRotationPlugin], + () => [xAxisBackgroundPlugin(darkMode), issueChartCardTickRotationPlugin, barValueLabelsPlugin], [darkMode], ); @@ -651,12 +711,29 @@ function IssueChart({ variant = 'standalone', showTitle = true }) { const activeFilterSummary = useMemo(() => { const issueTypeCount = filters.issueTypes.length || getValidIssueTypes(issues).length; + + if (isSingleYearView) { + return `${issueTypeCount} Issue Types | ${selectedSingleYear ?? 'No year'}`; + } + const yearList = filters.years.length ? filters.years : uniqueYears; const range = yearList.length > 0 ? `${Math.min(...yearList)}–${Math.max(...yearList)}` : 'No years'; return `${issueTypeCount} Issue Types | ${range}`; - }, [filters.issueTypes, filters.years, issues, uniqueYears]); + }, [ + filters.issueTypes, + filters.years, + issues, + uniqueYears, + isSingleYearView, + selectedSingleYear, + ]); + + const viewToggleButtonClass = isActive => + `${styles.issueChartViewToggleButton} ${ + isActive ? styles.issueChartViewToggleButtonActive : '' + }`; const chartContent = (
)} + {/* Switch between comparing several years and focusing on one year */} +
+ + +
+
Year: - setSingleYear(selected?.value ?? null)} + value={years.find(option => option.value === selectedSingleYear) || null} + styles={selectStyles} + aria-label="Select a year" + placeholder="Select a year" + /> + ) : ( + - - - -
- -
- - -
- -
- - -
+
+

Rental Cost Over Time

+ +
+
+
+ +
-
-
- - -
- -
- - -
+
+ + +
+ +
+ +
-
{renderChartContent()}
+
+
+ + +
+ +
+ + +
+
+
+ +
+ {renderChartContent()}
); diff --git a/src/components/BMDashboard/RentalChart/RentalChart.module.css b/src/components/BMDashboard/RentalChart/RentalChart.module.css index 6dc8c03ccb8..8cc3d64a82d 100644 --- a/src/components/BMDashboard/RentalChart/RentalChart.module.css +++ b/src/components/BMDashboard/RentalChart/RentalChart.module.css @@ -3,18 +3,41 @@ /* ====================== Light Mode Base ====================== */ -.rentalContainer { +.rental-container { position: relative; width: 100%; margin: 0 auto; padding: 20px; + display: flex; + flex-direction: column; + justify-content: center; + background-color: #fff; + border-radius: 8px; + min-height: 15vh; } -/* General text */ -.textLight { +.rental-container.dark-mode { + background-color: #1b2a41 !important; color: #e0e0e0; } +.text-light { + color: #e0e0e0; +} + +/* Same title style as the Percent of Tools Returned Late card */ +.rental-container h1 { + margin-bottom: 20px; + text-align: left; + color: #333; + font-size: 24px; + font-weight: bold; +} + +.rental-container h1.text-light { + color: #fff; +} + /* Chart wrapper (applies in dark + light mode) */ .chartWrapper { height: 600px; @@ -27,8 +50,10 @@ box-shadow: 0 2px 10px rgb(0 0 0 / 5%); } -/* Chart controls + filters */ -.chartControls { +/* ========================================= + Filter Controls + ========================================= */ +.chart-controls { display: flex; flex-direction: column; gap: 15px; @@ -36,30 +61,38 @@ width: 100%; } -.filterRow { +.chart-filters { display: flex; flex-wrap: wrap; - gap: 20px; - margin-top: 40px; - align-items: flex-start; - justify-content: flex-end; + justify-content: center; + align-items: center; + gap: 12px 24px; + margin: 15px 0 20px; } -.topFilters { - width: 100%; - margin-bottom: 10px; +/* Let both filter rows flow into one centered row that wraps on small screens */ +.filter-row { + display: contents; } -.dateFilters { - width: 100%; +/* Label sits inline, to the left of its control */ +.filter-group { + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; } -.filterGroup { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 6px; - min-width: 150px; +.filter-group label { + margin: 0; + white-space: nowrap; +} + +/* Datepicker's inline wrapper adds a line-height gap under the input; its input is + forced to width: 100% by a dashboard-wide rule, so size the wrapper instead */ +.filter-group :global(.react-datepicker-wrapper) { + display: block; + width: 130px; } .filterGroup label { @@ -69,33 +102,74 @@ color: inherit; } -.filterText { - margin-right: 0; +.filter-text, +.date-label { + margin-right: 8px; white-space: nowrap; } -/* Date picker input */ -.datePicker { +/* ========================================= + Inputs & Dropdowns + ========================================= */ + +/* 38px matches the dashboard-wide datepicker input height */ +.rental-chart-select, +.date-picker { + box-sizing: border-box; + height: 38px; padding: 6px 10px; border: 1px solid #ccc; - border-radius: 6px; /* rounded */ + border-radius: 4px; font-size: 14px; +} + +.rental-chart-select { + min-width: 150px; +} + +.date-picker { width: 120px; } -select, -.rentalChartSelect { +.dark-select { + background-color: #1b2a41 !important; + color: #e0e0e0; + border: 1px solid #555 !important; +} + +/* Tool filter stays disabled until a project is picked */ +.rental-chart-select:disabled { + opacity: 0.55; + cursor: not-allowed; +} + +.date-picker.dark-date-picker { + background-color: #1b2a41 !important; + color: #e0e0e0 !important; + border: 1px solid #555 !important; +} + +/* ========================================= + Chart Area & Loading States + ========================================= */ + +/* Flat, like the Returned Late chart: the dashboard card already frames it */ +.chart-wrapper { + height: 500px; + width: 100%; + margin: 0 auto; + box-sizing: border-box; background-color: #fff; - color: #333; - border: 1px solid #ccc; - border-radius: 6px; - cursor: pointer; +} + +.dark-chart { + background-color: #1b2a41; } /* States */ .loading, .error, -.noData { +.no-data { display: flex; justify-content: center; align-items: center; @@ -108,128 +182,9 @@ select, color: #d32f2f; } -/* React DatePicker overrides (light mode base) */ -.reactDatepicker { - background-color: #fff; - color: #333; - border: 1px solid #ccc; - border-radius: 6px; -} - -.reactDatepicker__header { - background-color: #f5f5f5; - border-bottom: 1px solid #ccc; - border-radius: 6px 6px 0 0; -} - -.reactDatepicker__current-month, -.reactDatepicker__day-name, -.reactDatepicker__day, -.reactDatepicker__month-text, -.reactDatepicker__year-text { - color: #333; -} - -.reactDatepicker__day:hover, -.reactDatepicker__month-text:hover, -.reactDatepicker__year-text:hover { - background-color: #eee; -} - -.reactDatepicker__day--selected, -.reactDatepicker__day--in-selecting-range, -.reactDatepicker__day--in-range { - background-color: #0078d7; - color: white; - border-radius: 50%; -} - -.reactDatepickerPopper { +:global(.react-datepicker-popper) { z-index: 999 !important; max-width: 100vw; - border-radius: 6px; -} - -/* ====================== - Dark Mode Overrides - ====================== */ -.darkMode { - background-color: #1b2a41; - color: #e0e0e0; -} - -.darkMode .rentalContainer { - background-color: #1b2a41; - color: #e0e0e0; -} - -.darkMode select, -.darkMode .rentalChartSelect { - background-color: #333; - color: #e0e0e0; - border: 1px solid #555; -} - -/* DatePicker input & popper */ -.darkMode .DatePickerInput, -.darkMode .DatePicker, -.darkMode .DatePickerPopper, -.darkMode .DatePickerCalendar { - background-color: #333; - color: #e0e0e0; - border: 1px solid #555; - border-radius: 6px; - z-index: 9999; -} - -/* Calendar header */ -.darkMode .DatePickerCalendar .react-datepicker__header { - background-color: #333; - border-bottom: 1px solid #555; - color: #e0e0e0; - border-radius: 6px 6px 0 0; -} - -/* Days, months, years */ -.darkMode .DatePickerCalendar .react-datepicker__day, -.darkMode .DatePickerCalendar .react-datepicker__day-name, -.darkMode .DatePickerCalendar .react-datepicker__month-text, -.darkMode .DatePickerCalendar .react-datepicker__year-text { - color: #e0e0e0; - background-color: #333; - border-radius: 4px; -} - -/* Dark mode DatePicker root */ -.darkMode .react-datepicker { - background-color: #000 !important; /* match your select */ - color: #e0e0e0 !important; - border: 1px solid #444 !important; - border-radius: 6px; -} - -/* Header inside */ -.darkMode .react-datepicker__header { - background-color: #111 !important; - border-bottom: 1px solid #444 !important; - color: #e0e0e0 !important; -} - -/* Hover effect */ -.darkMode .DatePickerCalendar .react-datepicker__day:hover, -.darkMode .DatePickerCalendar .react-datepicker__month-text:hover, -.darkMode .DatePickerCalendar .react-datepicker__year-text:hover { - background-color: #444; - color: #fff; -} - -/* Selected and in-range */ -.darkMode .DatePickerCalendar .react-datepicker__day--selected, -.darkMode .DatePickerCalendar .react-datepicker__day--in-range, -.darkMode .DatePickerCalendar .react-datepicker__day--in-selecting-range { - background-color: #555; - color: #fff; - border-radius: 50%; } /* Chart wrapper */ @@ -238,3 +193,63 @@ select, border-radius: 8px; box-shadow: 0 2px 10px rgb(255 255 255 / 5%); } + +/* ========================================= + Small Screens + ========================================= */ + +/* Sized by the card's own width, not the viewport: the dashboard can make the card + narrow even on a wide screen */ +.rental-container { + container-type: inline-size; +} + +@container (width <= 640px) { + .rental-container h1 { + margin-bottom: 12px; + font-size: 20px; + } + + /* Stack filters in a two-column grid so labels and controls line up */ + .chart-filters { + display: grid; + grid-template-columns: max-content minmax(0, 1fr); + gap: 10px 12px; + width: 100%; + max-width: 420px; + margin: 10px auto 16px; + } + + .filter-group { + display: contents; + } + + .filter-group label { + text-align: left; + } + + .rental-chart-select, + .date-picker { + width: 100%; + min-width: 0; + } + + .filter-group :global(.react-datepicker-wrapper) { + width: 100%; + } + + .filter-text, + .date-label { + margin-right: 0; + } + + .chart-wrapper { + height: 380px; + } +} + +@media (width <= 576px) { + .rental-container { + padding: 12px; + } +} diff --git a/src/components/BMDashboard/RentalChart/RentalDatePicker.module.css b/src/components/BMDashboard/RentalChart/RentalDatePicker.module.css new file mode 100644 index 00000000000..fa9961c2620 --- /dev/null +++ b/src/components/BMDashboard/RentalChart/RentalDatePicker.module.css @@ -0,0 +1,158 @@ +/* Shared calendar popup theme for the Rental Tracking charts. + Applied through react-datepicker's calendarClassName so it only affects these pickers. + Colors follow the HGN design system (N = neutral, P = primary, H = highlight). */ + +.calendar { + --cal-bg: #fff; + --cal-border: #e5e5e6; /* N40 */ + --cal-text: #1c313b; /* P500 */ + --cal-muted: #63676c; /* N500 */ + --cal-outside: #b6b8ba; /* N70 */ + --cal-hover-bg: #efeff0; /* N30 */ + --cal-selected-bg: #595d62; /* N600 */ + --cal-selected-text: #fff; + --cal-range-bg: #e8f4f9; /* H50 */ + --cal-range-text: #1c313b; + --cal-arrow: #2e5061; /* P300 */ + --cal-select-bg: #fff; + + font-family: inherit; + background-color: var(--cal-bg); + color: var(--cal-text); + border: 1px solid var(--cal-border); + border-radius: 8px; + box-shadow: 0 6px 20px rgb(0 0 0 / 12%); + padding: 4px; +} + +.calendar.dark { + --cal-bg: #1b2a41; + --cal-border: #3f444a; /* N800 */ + --cal-text: #e0e0e0; + --cal-muted: #b6b8ba; /* N70 */ + --cal-outside: #707377; /* N400 */ + --cal-hover-bg: #2c3e50; + --cal-selected-bg: #3ea0cb; /* H200 */ + --cal-selected-text: #fff; + --cal-range-bg: #2e5061; /* P300 */ + --cal-range-text: #fff; + --cal-arrow: #e0e0e0; + --cal-select-bg: #2c3e50; + + box-shadow: 0 6px 20px rgb(0 0 0 / 45%); +} + +.calendar :global(.react-datepicker__triangle) { + display: none; +} + +.calendar :global(.react-datepicker__header) { + background-color: var(--cal-bg); + border-bottom: none; + padding-top: 10px; +} + +.calendar :global(.react-datepicker__current-month) { + color: var(--cal-text); + font-size: 15px; + font-weight: 700; + margin-bottom: 6px; +} + +.calendar :global(.react-datepicker__day-name) { + color: var(--cal-muted); + font-size: 11px; + font-weight: 600; + text-transform: uppercase; +} + +.calendar :global(.react-datepicker__navigation) { + top: 10px; +} + +.calendar :global(.react-datepicker__navigation-icon::before) { + border-color: var(--cal-arrow); + border-width: 2px 2px 0 0; +} + +.calendar :global(.react-datepicker__navigation:hover .react-datepicker__navigation-icon::before) { + border-color: var(--cal-text); +} + +.calendar :global(.react-datepicker__month-select), +.calendar :global(.react-datepicker__year-select) { + background-color: var(--cal-select-bg); + color: var(--cal-text); + border: 1px solid var(--cal-border); + border-radius: 4px; + padding: 2px 4px; + font-size: 13px; +} + +.calendar :global(.react-datepicker__month) { + margin: 6px; +} + +/* Every day: round, readable text. Three classes deep to beat the library's range rules. */ +.calendar :global(.react-datepicker__month .react-datepicker__day) { + color: var(--cal-text); + border-radius: 50%; + background-color: transparent; + font-weight: 400; +} + +.calendar :global(.react-datepicker__month .react-datepicker__day--outside-month) { + color: var(--cal-outside); +} + +.calendar :global(.react-datepicker__month .react-datepicker__day--in-range), +.calendar :global(.react-datepicker__month .react-datepicker__day--in-selecting-range) { + background-color: var(--cal-range-bg); + color: var(--cal-range-text); +} + +.calendar :global(.react-datepicker__month .react-datepicker__day:hover), +.calendar :global(.react-datepicker__month .react-datepicker__day--keyboard-selected) { + background-color: var(--cal-hover-bg); + color: var(--cal-text); +} + +.calendar :global(.react-datepicker__month .react-datepicker__day--selected), +.calendar :global(.react-datepicker__month .react-datepicker__day--range-start), +.calendar :global(.react-datepicker__month .react-datepicker__day--range-end), +.calendar :global(.react-datepicker__month .react-datepicker__day--selected:hover) { + background-color: var(--cal-selected-bg); + color: var(--cal-selected-text); + font-weight: 600; +} + +.calendar :global(.react-datepicker__month .react-datepicker__day--today) { + font-weight: 700; +} + +.calendar :global(.react-datepicker__month .react-datepicker__day--disabled) { + color: var(--cal-outside); + background-color: transparent; + cursor: default; + opacity: 0.6; +} + +/* Other dashboard cards ship `.darkMode .react-datepicker__tab-loop ...` rules with !important + that reach every calendar on the page; restate the values those rules override. */ +.calendar.dark :global(.react-datepicker__header) { + background-color: var(--cal-bg) !important; + border-bottom-color: transparent !important; +} + +.calendar.dark :global(.react-datepicker__header .react-datepicker__day-name) { + color: var(--cal-muted) !important; +} + +.calendar.dark :global(.react-datepicker__month .react-datepicker__day--outside-month) { + color: var(--cal-outside) !important; +} + +:global(.react-datepicker-popper) :global(.react-datepicker).calendar.dark { + background-color: var(--cal-bg) !important; + border-color: var(--cal-border) !important; +} diff --git a/src/components/BMDashboard/RentalChart/ReturnedLateChart.jsx b/src/components/BMDashboard/RentalChart/ReturnedLateChart.jsx index cfbced79ae5..2f42546ee67 100644 --- a/src/components/BMDashboard/RentalChart/ReturnedLateChart.jsx +++ b/src/components/BMDashboard/RentalChart/ReturnedLateChart.jsx @@ -6,6 +6,8 @@ import DatePicker from 'react-datepicker'; import { MultiSelect } from 'react-multi-select-component'; import 'react-datepicker/dist/react-datepicker.css'; import styles from './ReturnedLateChart.module.css'; +import datePickerStyles from './RentalDatePicker.module.css'; +import { Select } from 'antd'; import { Chart as ChartJS, CategoryScale, @@ -66,12 +68,17 @@ function getRequestErrorMessage(error, fallbackMessage) { ); } +// Below this width the chart switches to smaller fonts and shorter axis titles +const COMPACT_CHART_WIDTH = 576; + export default function ReturnedLateChart() { const chartRef = useRef(null); + const chartContainerRef = useRef(null); + const [chartWidth, setChartWidth] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [availableProjects, setAvailableProjects] = useState([]); - const [availableTools, setAvailableTools] = useState([]); + const [allToolsData, setAllToolsData] = useState([]); const [selectedProject, setSelectedProject] = useState('All'); const [selectedTools, setSelectedTools] = useState([]); const [dateRange, setDateRange] = useState({ @@ -87,6 +94,17 @@ export default function ReturnedLateChart() { const darkMode = useSelector(state => state.theme.darkMode); const [sortOption, setSortOption] = useState('DESC'); const isMultiProjectView = selectedProject === 'All'; + // Tools are picked per project, so the list only has the selected project's tools + const availableTools = useMemo(() => { + if (isMultiProjectView) return []; + const tools = allToolsData + .filter(item => item.projectId === selectedProject) + .map(item => item.toolName) + .filter(Boolean); + return [...new Set(tools)] + .sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' })) + .map(tool => ({ label: tool, value: tool })); + }, [allToolsData, isMultiProjectView, selectedProject]); const visibleDatasets = useMemo( () => chartData.datasets.map(dataset => ({ @@ -154,8 +172,7 @@ export default function ReturnedLateChart() { if (toolsResult.status === 'fulfilled') { const data = getArrayPayload(toolsResult.value.data); - const tools = Array.from(new Set(data.map(d => d.toolName))).filter(Boolean); - setAvailableTools(tools.map(t => ({ label: t, value: t }))); + setAllToolsData(data); didLoadAnyData = didLoadAnyData || data.length > 0; } @@ -178,7 +195,8 @@ export default function ReturnedLateChart() { } }; - fetchInitial(); + // Errors are handled inside fetchInitial + fetchInitial().catch(() => {}); }, []); const buildUrl = () => { @@ -300,7 +318,8 @@ export default function ReturnedLateChart() { setLoading(false); } }; - fetchData(); + // Errors are handled inside fetchData + fetchData().catch(() => {}); }, [availableProjects, darkMode, selectedProject, dateRange, selectedTools, sortOption]); useEffect(() => { @@ -333,9 +352,23 @@ export default function ReturnedLateChart() { [chartData.datasets, chartData.labels, rawToolsData], ); + // Track the chart area's width so fonts and labels can shrink on small screens + useEffect(() => { + const container = chartContainerRef.current; + if (!container || typeof ResizeObserver === 'undefined') return undefined; + const observer = new ResizeObserver(([entry]) => setChartWidth(entry.contentRect.width)); + observer.observe(container); + return () => observer.disconnect(); + }, []); + + const isCompact = chartWidth > 0 && chartWidth < COMPACT_CHART_WIDTH; + const options = useMemo(() => { const textColor = darkMode ? '#fff' : '#333'; - const datalabelCOlor = darkMode ? '#fff' : '#111'; + const datalabelColor = darkMode ? '#fff' : '#111'; + // Same grid/axis line colors as the Rental Cost chart; Chart.js' default is invisible on dark + const gridColor = darkMode ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)'; + const axisBorderColor = darkMode ? 'rgba(255,255,255,0.25)' : 'rgba(0,0,0,0.25)'; return { responsive: true, maintainAspectRatio: false, @@ -356,8 +389,11 @@ export default function ReturnedLateChart() { align: 'top', offset: 4, formatter: value => `${Number(value).toFixed(0)}%`, - color: datalabelCOlor, - font: { weight: 'bold' }, + // Skip empty bars so "0%" labels don't crowd the axis + display: ctx => ctx.dataset.data[ctx.dataIndex] > 0, + clamp: true, + color: datalabelColor, + font: { weight: 'bold', size: isCompact ? 10 : 12 }, }, tooltip: { callbacks: { @@ -367,7 +403,7 @@ export default function ReturnedLateChart() { label(context) { const v = context.parsed.y; const label = context.dataset.label; - return `${label}: ${v}%`; + return `${label}: ${Number(Number(v).toFixed(1))}%`; }, afterLabel(context) { const toolDetail = rawToolsData.find( @@ -388,30 +424,39 @@ export default function ReturnedLateChart() { title: { display: true, text: 'Tool Name', - font: { size: 16, weight: 'bold' }, + font: { size: isCompact ? 12 : 16, weight: 'bold' }, color: textColor, }, ticks: { color: textColor, + font: { size: isCompact ? 10 : 12 }, + maxRotation: isCompact ? 60 : 50, + autoSkip: true, }, + grid: { color: gridColor }, + border: { color: axisBorderColor }, }, y: { beginAtZero: true, title: { display: true, - text: 'Percent of tools returned late', - font: { size: 16, weight: 'bold' }, + text: isCompact ? '% returned late' : 'Percent of tools returned late', + font: { size: isCompact ? 12 : 16, weight: 'bold' }, color: textColor, }, ticks: { color: textColor, + font: { size: isCompact ? 10 : 12 }, callback: v => `${v}%`, }, - max: maxChartValue > 0 ? maxChartValue * 1.15 : 100, + grid: { color: gridColor }, + border: { color: axisBorderColor }, + // Round the top up to the next 10% (leaving room for labels) so the last tick is clean + max: maxChartValue > 0 ? Math.min(100, Math.ceil((maxChartValue * 1.15) / 10) * 10) : 100, }, }, }; - }, [darkMode, handleBarClick, maxChartValue, rawToolsData]); + }, [darkMode, handleBarClick, maxChartValue, rawToolsData, isCompact]); const toggleProjectVisibility = projectId => { if (!projectId || !isMultiProjectView) return; @@ -423,7 +468,6 @@ export default function ReturnedLateChart() { const multiProjectLegendVisible = isMultiProjectView && legendItems.length > 1; - const handleProjectChange = e => setSelectedProject(e.target.value); const handleStartDateChange = date => setDateRange(prev => ({ startDate: date, endDate: prev.endDate < date ? date : prev.endDate })); const handleEndDateChange = date => @@ -431,7 +475,13 @@ export default function ReturnedLateChart() { startDate: prev.startDate > date ? date : prev.startDate, endDate: date, })); - const isOxfordBlue = darkMode ? 'bg-oxford-blue' : ''; + + const isOxfordBlue = darkMode ? styles['bg-oxford-blue'] : ''; + + const getLegendItemClass = hidden => { + if (hidden) return styles['returned-late-legend-item-hidden']; + return darkMode ? 'dark-mode-legend' : ''; + }; return (
@@ -451,9 +501,9 @@ export default function ReturnedLateChart() {
-
+ {/* Added the darkMode text-white logic to the label! */} - + {/* MultiSelect has no title prop, so the wrapper shows the disabled hint */} +
+ +
+ {/* FIX: Added htmlFor to pacify the linter! */} - - + Highest % Late + Lowest % Late + Alphabetical (A–Z) +
-
+
-
-
+
{loading && (
s, so the app-wide label margin/bold leaked in as gaps between rows */ +.returned-late-tools-select :global(.select-item) { + margin: 0; + padding: 8px 10px; + font-weight: 400; +} + +.returned-late-tools-select :global(.select-item input) { + accent-color: #3ea0cb; +} + +.returned-late-tools-select :global(.search input) { + color: inherit; +} + +.returned-late-tools-select :global(.dropdown-content) { + z-index: 9999; } .returned-late-chart-container { height: 520px; position: relative; + z-index: 0; } .returned-late-loading { @@ -139,13 +239,18 @@ color: #666; } +.bg-oxford-blue .returned-late-loading { + color: #ffffff; +} + .returned-late-error { - color: #d32f2f; - padding: 16px; - background-color: #ffebee; - border: 1px solid #ffcdd2; - border-radius: 4px; + color: #ffffff !important; + background-color: #b3261e; + padding: 14px 16px; + border-radius: 6px; margin: 20px 0; + font-weight: 500; + text-align: center; } .returned-late-no-data { @@ -158,193 +263,139 @@ font-style: italic; } -.background-dark { - background-color: #2a3f5f; - border: 1px solid #555; +.bg-oxford-blue .returned-late-no-data { + color: #ffffff; } -.background-red { - background-color: #ff4d4f; -} - -:global(.dark.rmsc ) { - --rmsc-border: none; - --rmsc-bg: none; - border:transparent; +.bg-oxford-blue .returned-late-date-picker { + background-color: #1b2a41 !important; + color: #e0e0e0 !important; + border: 1px solid #555 !important; } -:global(.dark.rmsc .dropdown-heading) { - background-color: #2a3f5f; - color: #fff; - border: 1px solid #555; - border-radius: 4px; - overflow: hidden; +.bg-oxford-blue .returned-late-project-select { + background-color: #1b2a41 !important; + border: none !important; } -:global(.dark.rmsc .select-item:hover) { - background-color: #253246; +.bg-oxford-blue { + background-color: #1b2a41 !important; + color: #ffffff; } -:global(.dark.rmsc .select-item.selected) { - background-color: #253246; +.bg-oxford-blue .returned-late-chart-container { + background-color: #1b2a41 !important; } -:global(.rmsc.dark .options) { - background-color: #2a3f5f; - color: #fff; -} +/* ========================================================================== + Ant Design Dropdown Menu Overrides (Dark Mode) + ========================================================================== */ -/* Search box */ -:global(.rmsc.dark .search) { - background-color: #2a3f5f; - color: #fff; -} +.bg-oxford-blue :global(.ant-select:not(.ant-select-disabled) .ant-select-selector) { + background-color: #1b2a41 !important; + color: #e0e0e0 !important; + border: 1px solid #555555 !important; -:global(.rmsc.dark .search input:focus) { - background-color: #223653; } - -.returned-late-detail-backdrop { - position: fixed; - inset: 0; - background: rgb(0 0 0 / 25%); - z-index: 2147483646; +.bg-oxford-blue :global(.ant-select-selection-item) { + color: #e0e0e0 !important; } -.returned-late-detail-panel { - position: fixed; - top: 0; - right: 0; - width: 360px; - height: 100vh; - padding: 20px; - z-index: 2147483647; - box-shadow: -4px 0 10px rgb(0 0 0 / 40%); - background: #fff; - color: #111; -} - -.dark-panel { - background: #0b2545; - color: #fff; -} - -.returned-late-detail-close { - background: none; - border: none; - font-size: 20px; - float: right; - cursor: pointer; - color: inherit; -} - -:global(html.dark-mode) .returned-late-chart h1, -:global(body.dark-mode) .returned-late-chart h1 { - color: #fff; +.bg-oxford-blue :global(.ant-select-arrow) { + color: #e0e0e0 !important; } -:global(html.dark-mode) .returned-late-legend-hint, -:global(body.dark-mode) .returned-late-legend-hint { - color: #cbd5e1; +.dark-dropdown-menu { + background-color: #1b2a41 !important; } -:global(html.dark-mode) .returned-late-legend-item, -:global(body.dark-mode) .returned-late-legend-item { - background: #0f172a; - color: #f8fafc; - border-color: #475569; +.dark-dropdown-menu :global(.ant-select-item) { + color: #e0e0e0 !important; } -:global(html.dark-mode) .returned-late-legend-item:hover, -:global(body.dark-mode) .returned-late-legend-item:hover { - border-color: #94a3b8; - background: #172033; -} -:global(html.dark-mode) .returned-late-legend-item-hidden, -:global(body.dark-mode) .returned-late-legend-item-hidden { - background: #172033; - color: #cbd5e1; +.dark-dropdown-menu :global(.ant-select-item-option-active):not(:global(.ant-select-item-option-disabled)) { + background-color: #2c3e50 !important; } -:global(html.dark-mode) .returned-late-filter-label, -:global(body.dark-mode) .returned-late-filter-label { - color: #fff; -} -:global(html.dark-mode) .returned-late-project-select, -:global(body.dark-mode) .returned-late-project-select { - background-color: #1e293b; - color: #fff; - border: 1px solid #475569; +.dark-dropdown-menu :global(.ant-select-item-option-selected):not(:global(.ant-select-item-option-disabled)) { + background-color: #374151 !important; + color: #ffffff !important; + font-weight: 600; } -:global(html.dark-mode) .returned-late-project-select option, -:global(body.dark-mode) .returned-late-project-select option { - background-color: #1e293b; - color: #fff; -} -:global(html.dark-mode) .returned-late-date-picker, -:global(body.dark-mode) .returned-late-date-picker { - background-color: #1e293b; - color: #fff; - border: 1px solid #475569; +.dark-dropdown-menu :global(.ant-select-empty) { + color: #374151 !important; } -:global(html.dark-mode) .returned-late-tools-select :global(.dropdown-container), -:global(body.dark-mode) .returned-late-tools-select :global(.dropdown-container) { - background-color: #1e293b; - color: #fff; - border: 1px solid #475569; +.bg-oxford-blue .returned-late-legend-item { + background-color: #1b2a41 !important; + border-color: #555555 !important; + color: #ffffff !important; } -:global(html.dark-mode) .returned-late-tools-select :global(.dropdown-heading), -:global(body.dark-mode) .returned-late-tools-select :global(.dropdown-heading) { - color: #fff; +.bg-oxford-blue .returned-late-legend-item-hidden { + opacity: 0.45 !important; + background-color: #152234 !important; + border-color: #334155 !important; } -:global(html.dark-mode) .returned-late-tools-select :global(.select-panel), -:global(body.dark-mode) .returned-late-tools-select :global(.select-panel) { - background-color: #1e293b; - color: #fff; - border: 1px solid #475569; -} +/* ========================================================================== + Small Screens + ========================================================================== */ +@container (width <= 640px) { + .returned-late-chart h1 { + margin-bottom: 12px; + font-size: 20px; + } -:global(html.dark-mode) .returned-late-tools-select :global(.select-panel) :global(input), -:global(body.dark-mode) .returned-late-tools-select :global(.select-panel) :global(input) { - background-color: #0f172a; - color: #fff; - border: 1px solid #475569; -} + .returned-late-legend-block { + align-items: flex-start; + } -:global(html.dark-mode) .returned-late-tools-select :global(.select-item), -:global(body.dark-mode) .returned-late-tools-select :global(.select-item) { - color: #fff; -} + .returned-late-legend { + justify-content: flex-start; + } -:global(html.dark-mode) .returned-late-tools-select :global(.select-item:hover), -:global(body.dark-mode) .returned-late-tools-select :global(.select-item:hover) { - background-color: #243b64; -} + /* One filter per row, labels in a fixed column so the controls line up */ + .returned-late-filters { + flex-direction: column; + align-items: stretch; + gap: 10px; + width: 100%; + max-width: 420px; + margin: 10px auto 16px; + } -@media screen and (width <= 768px) { - .returned-late-chart h1 { - margin-bottom: 8px; + .returned-late-filter-group { + display: grid; + grid-template-columns: 72px minmax(0, 1fr); + gap: 12px; } - .returned-late-legend-hint { - margin-top: 0; + .returned-late-filter-label { + text-align: left; } - .returned-late-legend-block { - align-items: stretch; + .returned-late-filter-group > div, + .returned-late-project-select, + .returned-late-chart .returned-late-tools-select, + .returned-late-filter-group :global(.react-datepicker-wrapper) { width: 100%; + min-width: 0; } - .returned-late-legend { - justify-content: flex-start; + .returned-late-chart-container { + height: 380px; + } +} + +@media (width <= 576px) { + .returned-late-chart { + padding: 12px; } } diff --git a/src/components/BMDashboard/WeeklyProjectSummary/CardSelector.jsx b/src/components/BMDashboard/WeeklyProjectSummary/CardSelector.jsx new file mode 100644 index 00000000000..5207e535d7e --- /dev/null +++ b/src/components/BMDashboard/WeeklyProjectSummary/CardSelector.jsx @@ -0,0 +1,194 @@ +import { useEffect, useRef, useState } from 'react'; +import PropTypes from 'prop-types'; +import styles from './CardSelector.module.css'; + +export const CARD_LIMIT_OPTIONS = ['4', '6', '8', 'all']; + +// Preset card groups. Keys that are not on the page are ignored. +export const CARD_PRESETS = [ + { + id: 'finance', + label: 'Finance Focus', + keys: ['Financials', 'Financials Tracking', 'Loss Tracking', 'Material Consumption'], + }, + { + id: 'schedule', + label: 'Schedule Focus', + keys: [ + 'Project Status', + 'Risk profile for projects', + 'Issue Tracking', + 'Issues Breakdown', + 'Labor and Time Tracking', + ], + }, + { + id: 'operations', + label: 'Operations Focus', + keys: [ + 'Tools and Equipment Tracking', + 'Rental Tracking', + 'Material Consumption', + 'Injury Severity by Projects', + 'Lessons Learned', + 'Global Distribution and Project Status Overview', + ], + }, + { id: 'all', label: 'All Cards', keys: null }, +]; + +function CardSelector({ cards, visibleKeys, cardLimit, shownCount, onChange, darkMode }) { + const [open, setOpen] = useState(false); + const wrapperRef = useRef(null); + + useEffect(() => { + if (open === false) return undefined; + const handleClickOutside = event => { + if (wrapperRef.current && wrapperRef.current.contains(event.target) === false) { + setOpen(false); + } + }; + const handleEscape = event => { + if (event.key === 'Escape') setOpen(false); + }; + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('keydown', handleEscape); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('keydown', handleEscape); + }; + }, [open]); + + const allKeys = cards.map(card => card.key); + + const toggleKey = key => { + const next = new Set(visibleKeys); + if (next.has(key)) { + next.delete(key); + } else { + next.add(key); + } + onChange( + allKeys.filter(k => next.has(k)), + cardLimit, + ); + }; + + const applyPreset = preset => { + const keys = preset.keys ? allKeys.filter(k => preset.keys.includes(k)) : allKeys; + onChange(keys, 'all'); + }; + + return ( +
+ + + {open && ( +
+
+ Presets +
+ {CARD_PRESETS.map(preset => ( + + ))} +
+
+ +
+ + +
+ +
+
+ Cards +
+ + +
+
+
    + {cards.map((card, index) => { + const inputId = `card-option-${index}`; + return ( +
  • + +
  • + ); + })} +
+
+
+ )} +
+ ); +} + +CardSelector.propTypes = { + cards: PropTypes.arrayOf( + PropTypes.shape({ key: PropTypes.string.isRequired, title: PropTypes.string.isRequired }), + ).isRequired, + visibleKeys: PropTypes.arrayOf(PropTypes.string).isRequired, + cardLimit: PropTypes.oneOf(CARD_LIMIT_OPTIONS).isRequired, + shownCount: PropTypes.number.isRequired, + onChange: PropTypes.func.isRequired, + darkMode: PropTypes.bool, +}; + +CardSelector.defaultProps = { + darkMode: false, +}; + +export default CardSelector; diff --git a/src/components/BMDashboard/WeeklyProjectSummary/CardSelector.module.css b/src/components/BMDashboard/WeeklyProjectSummary/CardSelector.module.css new file mode 100644 index 00000000000..8412efafb6f --- /dev/null +++ b/src/components/BMDashboard/WeeklyProjectSummary/CardSelector.module.css @@ -0,0 +1,148 @@ +.cardSelector { + position: relative; + display: inline-block; +} + +.toggleButton { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + border: 1px solid #ced4da; + border-radius: 6px; + background: #fff; + color: #212529; + font-size: 0.875rem; + cursor: pointer; +} + +.toggleButton:hover { + background: #f1f3f5; +} + +.toggleButtonDark { + background: #2b3e59; + border-color: #4a5a72; + color: #fff; +} + +.toggleButtonDark:hover { + background: #36506f; +} + +.panel { + position: absolute; + top: calc(100% + 6px); + right: 0; + z-index: 20; + width: min(340px, 90vw); + max-height: 70vh; + overflow-y: auto; + padding: 12px; + border: 1px solid #dee2e6; + border-radius: 8px; + background: #fff; + color: #212529; + box-shadow: 0 6px 20px rgb(0 0 0 / 15%); + box-sizing: border-box; +} + +.panelDark { + background: #1e2d42; + border-color: #4a5a72; + color: #e0e6f0; +} + +.group { + margin-bottom: 12px; +} + +.group:last-child { + margin-bottom: 0; +} + +.groupLabel { + display: block; + margin-bottom: 6px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + opacity: 0.8; +} + +.presetRow { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.presetButton { + padding: 4px 10px; + border: 1px solid currentcolor; + border-radius: 999px; + background: transparent; + color: inherit; + font-size: 0.8rem; + cursor: pointer; +} + +.presetButton:hover { + opacity: 0.8; +} + +.limitSelect { + padding: 4px 8px; + border: 1px solid #ced4da; + border-radius: 4px; + background: #fff; + color: #212529; + font-size: 0.875rem; +} + +.panelDark .limitSelect { + background: #2b3e59; + border-color: #4a5a72; + color: #fff; +} + +.listHeader { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 6px; +} + +.listHeader .groupLabel { + margin-bottom: 0; +} + +.linkButton { + margin-left: 8px; + padding: 0; + border: 0; + background: none; + color: #0d6efd; + font-size: 0.8rem; + text-decoration: underline; + cursor: pointer; +} + +.panelDark .linkButton { + color: #8ab4ff; +} + +.cardList { + margin: 0; + padding: 0; + list-style: none; +} + +.cardOption { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 0; + font-size: 0.875rem; + cursor: pointer; +} diff --git a/src/components/BMDashboard/WeeklyProjectSummary/CostPredictionChart.jsx b/src/components/BMDashboard/WeeklyProjectSummary/CostPredictionChart.jsx index 27dad4dd9ac..4141289cca1 100644 --- a/src/components/BMDashboard/WeeklyProjectSummary/CostPredictionChart.jsx +++ b/src/components/BMDashboard/WeeklyProjectSummary/CostPredictionChart.jsx @@ -56,7 +56,55 @@ const PROJECTS = [ ]; const DEFAULT_WINDOW_MONTHS = 6; -const TODAY_STR = new Date().toISOString().slice(0, 10); +// Local calendar date as YYYY-MM-DD. toISOString() returns the UTC date, which is +// already "tomorrow" in the evening for timezones behind UTC (e.g. 6 p.m. Pacific), +// so it must not be used for the date-input limit or clamping. +export function getLocalDateString(date = new Date()) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +} + +const MONTH_NAMES = [ + 'january', + 'february', + 'march', + 'april', + 'may', + 'june', + 'july', + 'august', + 'september', + 'october', + 'november', + 'december', +]; + +// Parses a "Month YYYY" label (e.g. "March 2026") into a local Date set to +// the 1st of that month. Avoids relying on the native Date constructor's +// implementation-defined parsing of non-ISO strings, which behaves +// inconsistently across browsers/engines. +export function parseMonthLabel(label) { + const parts = String(label || '') + .trim() + .split(/\s+/); + if (parts.length !== 2) return new Date(NaN); + const monthIndex = MONTH_NAMES.indexOf(parts[0].toLowerCase()); + const year = Number(parts[1]); + if (monthIndex === -1 || Number.isNaN(year)) return new Date(NaN); + return new Date(year, monthIndex, 1); +} + +// Parses a "YYYY-MM-DD" date-input value into a local Date, avoiding the +// UTC-midnight interpretation the Date constructor applies to bare ISO +// date strings (which can shift the date by a day in non-UTC timezones). +export function parseIsoDateOnly(value) { + if (!value) return null; + const [y, m, d] = value.split('-').map(Number); + if (!y || !m || !d) return null; + return new Date(y, m - 1, d); +} const SAMPLE_DATA_BASE = { 'building-1': { plannedStart: 400, plannedGrowth: 5.6, actualStart: 380, actualGrowth: 5.4 }, @@ -285,6 +333,8 @@ function CostPredictionChart({ projectId }) { // filter state const [selectedProjectId, setSelectedProjectId] = useState(''); const [dateRange, setDateRange] = useState({ start: '', end: '' }); // 'YYYY-MM-DD' + // Computed each render so it stays correct if the page is left open past midnight. + const todayStr = getLocalDateString(); const legendItems = [ { label: 'Planned Cost', color: SERIES_COLORS.planned, type: 'circle' }, @@ -337,17 +387,17 @@ function CostPredictionChart({ projectId }) { return chartData.slice(-DEFAULT_WINDOW_MONTHS); } return chartData.filter(d => { - const pointDate = new Date(d.month); + const pointDate = parseMonthLabel(d.month); if (dateRange.start) { - const s = new Date(dateRange.start); - const startMonth = new Date(s.getFullYear(), s.getMonth(), 1); - if (pointDate < startMonth) return false; + const s = parseIsoDateOnly(dateRange.start); + const startMonth = s && new Date(s.getFullYear(), s.getMonth(), 1); + if (startMonth && pointDate < startMonth) return false; } if (dateRange.end) { - const e = new Date(dateRange.end); - const endMonth = new Date(e.getFullYear(), e.getMonth(), 1); - if (pointDate > endMonth) return false; + const e = parseIsoDateOnly(dateRange.end); + const endMonth = e && new Date(e.getFullYear(), e.getMonth(), 1); + if (endMonth && pointDate > endMonth) return false; } return true; }); @@ -450,7 +500,7 @@ function CostPredictionChart({ projectId }) { style={filterStyles.control} value={dateRange.start} min="2011-01-01" - max={dateRange.end || TODAY_STR} + max={dateRange.end || todayStr} onChange={e => setDateRange(prev => ({ ...prev, start: e.target.value }))} />
@@ -468,8 +518,11 @@ function CostPredictionChart({ projectId }) { style={filterStyles.control} value={dateRange.end} min={dateRange.start || undefined} - max={TODAY_STR} - onChange={e => setDateRange(prev => ({ ...prev, end: e.target.value }))} + max={todayStr} + onChange={e => { + const clamped = e.target.value > todayStr ? todayStr : e.target.value; + setDateRange(prev => ({ ...prev, end: clamped })); + }} />
diff --git a/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.jsx b/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.jsx index 15929b03294..a5fddea041a 100644 --- a/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.jsx +++ b/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.jsx @@ -1,22 +1,23 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import Select from 'react-select'; import { useSelector } from 'react-redux'; import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer } from 'recharts'; import styles from './DistributionLaborHours.module.css'; -const COLORS = ['#2a647c', '#2e8ea3', '#ffab91', '#ffccbb', '#bbbbbb', '#f9f3e3']; +const COLORS = ['#4f8fa8', '#3fa4b8', '#ffab91', '#ffccbb', '#c7c7c7', '#f9f3e3']; const CustomTooltip = ({ active, payload, total, darkMode }) => { if (active && payload && payload.length) { const { name, value } = payload[0]; - const percent = ((value / total) * 100).toFixed(1); + const percent = total > 0 ? ((value / total) * 100).toFixed(1) : '0.0'; + return (

{name}

@@ -25,6 +26,7 @@ const CustomTooltip = ({ active, payload, total, darkMode }) => {
); } + return null; }; @@ -33,37 +35,135 @@ export default function DistributionLaborHours() { const [originalData, setOriginalData] = useState([]); const [filteredData, setFilteredData] = useState([]); - const [dateRange, setDateRange] = useState({ from: '', to: '' }); + + const [dateRange, setDateRange] = useState({ + from: '', + to: '', + }); + const [projectFilter, setProjectFilter] = useState(''); const [memberFilter, setMemberFilter] = useState(''); + const [filtersApplied, setFiltersApplied] = useState(false); useEffect(() => { const fetchData = async () => { const mockData = [ - { name: 'Stud Wall Construction', value: 25.9 }, - { name: 'Foundation Concreting', value: 18.5 }, - { name: 'Task A', value: 22.2 }, - { name: 'Task B', value: 18.5 }, - { name: 'Task C', value: 14.8 }, - { name: 'Electrical', value: 12 }, - { name: 'Plumbing', value: 8 }, - { name: 'Welding', value: 6 }, + { + name: 'Stud Wall Construction', + value: 25.9, + project: 'Project A', + member: 'Member 1', + date: '2026-08-05', + }, + { + name: 'Foundation Concreting', + value: 18.5, + project: 'Project A', + member: 'Member 2', + date: '2026-08-09', + }, + { + name: 'Task A', + value: 22.2, + project: 'Project B', + member: 'Member 1', + date: '2026-08-12', + }, + { + name: 'Task B', + value: 18.5, + project: 'Project B', + member: 'Member 2', + date: '2026-08-16', + }, + { + name: 'Task C', + value: 14.8, + project: 'Project A', + member: 'Member 1', + date: '2026-08-20', + }, + { + name: 'Electrical', + value: 12, + project: 'Project A', + member: 'Member 2', + date: '2026-08-22', + }, + { + name: 'Plumbing', + value: 8, + project: 'Project B', + member: 'Member 1', + date: '2026-08-24', + }, + { + name: 'Welding', + value: 6, + project: 'Project B', + member: 'Member 2', + date: '2026-08-27', + }, ]; + setOriginalData(mockData); }; + fetchData(); }, []); - useEffect(() => { - const top5 = originalData.slice(0, 5); - const othersTotal = originalData.slice(5).reduce((sum, item) => sum + item.value, 0); + const formatChartData = data => { + const sortedData = [...data].sort((a, b) => b.value - a.value); + + const top5 = sortedData.slice(0, 5).map(({ name, value }) => ({ + name, + value, + })); + + const othersTotal = sortedData.slice(5).reduce((sum, item) => sum + item.value, 0); + if (othersTotal > 0) { - top5.push({ name: 'Others', value: othersTotal }); + top5.push({ + name: 'Others', + value: Number(othersTotal.toFixed(1)), + }); } - setFilteredData(top5); - }, [originalData, dateRange, projectFilter, memberFilter]); - const totalHours = filteredData.reduce((sum, item) => sum + item.value, 0); + return top5; + }; + + useEffect(() => { + if (originalData.length > 0) { + setFilteredData(formatChartData(originalData)); + } + }, [originalData]); + + const handleSubmit = () => { + let result = [...originalData]; + + if (dateRange.from) { + result = result.filter(item => item.date >= dateRange.from); + } + + if (dateRange.to) { + result = result.filter(item => item.date <= dateRange.to); + } + + if (projectFilter) { + result = result.filter(item => item.project === projectFilter); + } + + if (memberFilter) { + result = result.filter(item => item.member === memberFilter); + } + + setFilteredData(formatChartData(result)); + setFiltersApplied(true); + }; + + const totalHours = useMemo(() => filteredData.reduce((sum, item) => sum + item.value, 0), [ + filteredData, + ]); const projectOptions = [ { value: '', label: 'ALL' }, @@ -77,104 +177,191 @@ export default function DistributionLaborHours() { { value: 'Member 2', label: 'Member 2' }, ]; + const selectedProject = + projectOptions.find(option => option.value === projectFilter) || projectOptions[0]; + + const selectedMember = + memberOptions.find(option => option.value === memberFilter) || memberOptions[0]; + + const menuPortalTarget = typeof document !== 'undefined' ? document.body : null; + + const selectStyles = { + menuPortal: base => ({ + ...base, + zIndex: 9999, + }), + menu: base => ({ + ...base, + zIndex: 9999, + }), + }; + return (
-

Distribution of Labor Hours

- - {/* Filters */} -
- - - - -
- -
-
+
+

Distribution of Labor Hours

+ +
+
+
+ + { + const newFrom = e.target.value; + + setDateRange(previous => ({ + from: newFrom, + to: previous.to && newFrom && newFrom > previous.to ? '' : previous.to, + })); + + setFiltersApplied(false); + }} + /> +
+ +
+ + { + const newTo = e.target.value; + + setDateRange(previous => ({ + from: previous.from && newTo && newTo < previous.from ? '' : previous.from, + to: newTo, + })); - {/* Chart + Legend */} -
-
- {filteredData.map((entry, index) => ( -
- - - {entry.name}: {entry.value} hrs -
- ))} + +
+ + { + setMemberFilter(option?.value || ''); + setFiltersApplied(false); + }} + className={styles.selectContainer} + classNamePrefix="labor-hours-select" + menuPortalTarget={menuPortalTarget} + menuPosition="fixed" + styles={selectStyles} + isSearchable={false} + /> +
+
+ +
+ + + {filtersApplied && Filters applied} +
-
- - - ( - - {`${((value / totalHours) * 100).toFixed(1)}%`} - - )} - > +
+ {filteredData.length > 0 ? ( +
+
{filteredData.map((entry, index) => ( - +
+ + + + {entry.name}: {entry.value} hrs + +
))} - - } /> - - +
+ +
+ + + ( + + {totalHours > 0 ? `${((value / totalHours) * 100).toFixed(1)}%` : '0.0%'} + + )} + > + {filteredData.map((entry, index) => ( + + ))} + + + } /> + + +
+
+ ) : ( +
No labor-hour data found for the selected filters.
+ )}
diff --git a/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.module.css b/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.module.css index e59d56e8a95..f793516ffd3 100644 --- a/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.module.css +++ b/src/components/BMDashboard/WeeklyProjectSummary/DistributionLaborHours/DistributionLaborHours.module.css @@ -1,23 +1,55 @@ -/* stylelint-disable */ +/* stylelint-disable */ + .container { - border-radius: 8px; - padding: 12px; - box-shadow: 0 1px 3px rgb(0 0 0 / 15%); width: 100%; height: 100%; + min-height: 650px; + box-sizing: border-box; + container-type: inline-size; + display: flex; flex-direction: column; + align-items: stretch; + justify-content: flex-start; + + border-radius: 8px; + padding: 20px; + box-shadow: 0 1px 3px rgb(0 0 0 / 15%); + transition: background-color 0.3s ease, color 0.3s ease; } +/* + * Keep the title, filters, Submit button, and chart + * grouped together with consistent vertical spacing. + * The content starts near the top of the card. + */ +.content { + width: 100%; + max-width: 100%; + min-width: 0; + + display: flex; + flex-direction: column; + align-items: center; +} + +/* ========================= + TITLE + ========================= */ + .title { + width: 100%; + + margin: 0 0 20px; + + color: #111827; + font-size: large; font-weight: bold; - margin-bottom: 18px; - color: #111827; + text-align: center; } -/* Keep title blue in dark mode */ :global(.dark) .title, :global(.dark-mode) .title, :global(.bm-dashboard-dark) .title, @@ -25,234 +57,491 @@ color: #2563eb !important; } -.filters { +/* ========================= + FILTERS + ========================= */ + +.filtersSection { + width: 100%; + + display: flex; + flex-direction: column; + align-items: center; +} + +.filterRow { + width: 100%; + display: flex; flex-wrap: wrap; + justify-content: center; - gap: 12px; - margin-bottom: 16px; + align-items: flex-end; + + column-gap: 18px; + row-gap: 12px; } -.filters label { +.filterGroup { + min-width: 115px; + display: flex; flex-direction: column; + + gap: 6px; +} + +.filterGroup label { + margin: 0; + font-size: 0.9rem; + font-weight: 600; + text-align: center; } -/* Dark mode: make filter labels readable */ -:global(.dark) .filters label, -:global(.dark-mode) .filters label, -:global([data-theme='dark']) .filters label { +:global(.dark) .filterGroup label, +:global(.dark-mode) .filterGroup label, +:global(.bm-dashboard-dark) .filterGroup label, +:global([data-theme='dark']) .filterGroup label { color: #fff; } -/* Scope to date inputs only — react-select renders its own inside - .filters, and this box styling must not apply to it. */ -.filters input[type='date'] { - height: auto !important; - border-radius: 6px; +/* ========================= + DATE INPUTS + ========================= */ + +.filterGroup input[type='date'] { + min-height: 38px; + box-sizing: border-box; + + padding: 7px 9px; + + border: 1px solid #d1d5db; + border-radius: 6px; + font-size: 0.95rem; line-height: 1.2; } -/* Give the dropdowns enough width and keep option text on one line */ -:global(.react-select-container) { - min-width: 100px; +:global(.dark) .filterGroup input[type='date'], +:global(.dark-mode) .filterGroup input[type='date'], +:global(.bm-dashboard-dark) .filterGroup input[type='date'], +:global([data-theme='dark']) .filterGroup input[type='date'] { + background-color: #1f2937 !important; + color: #f9fafb !important; + border-color: #374151 !important; + + color-scheme: dark; +} + +/* ========================= + REACT SELECT + ========================= */ + +.selectContainer { + min-width: 115px; +} + +:global(.labor-hours-select__control) { + min-height: 38px !important; + cursor: pointer !important; } -:global(.react-select__option), -:global(.react-select__single-value) { +:global(.labor-hours-select__option), +:global(.labor-hours-select__single-value) { white-space: nowrap; font-weight: normal !important; } -:global(.dark) :global(.react-select__control), -:global(.dark-mode) :global(.react-select__control), -:global([data-theme='dark']) :global(.react-select__control) { +:global(.labor-hours-select__menu), +:global(.labor-hours-select__menu-portal) { + z-index: 9999 !important; +} + +:global(.labor-hours-select__indicator-separator) { + background-color: #ccc !important; +} + +:global(.labor-hours-select__dropdown-indicator) { + color: #ccc !important; +} + +/* ========================= + SELECT DARK MODE + ========================= */ + +:global(.dark) :global(.labor-hours-select__control), +:global(.dark-mode) :global(.labor-hours-select__control), +:global(.bm-dashboard-dark) :global(.labor-hours-select__control), +:global([data-theme='dark']) :global(.labor-hours-select__control) { background-color: #1f2937 !important; border-color: #374151 !important; } -:global(.dark) :global(.react-select__single-value), -:global(.dark-mode) :global(.react-select__single-value), -:global([data-theme='dark']) :global(.react-select__single-value), -:global(.dark) :global(.react-select__input), -:global(.dark-mode) :global(.react-select__input), -:global([data-theme='dark']) :global(.react-select__input) { +:global(.dark) :global(.labor-hours-select__single-value), +:global(.dark-mode) :global(.labor-hours-select__single-value), +:global(.bm-dashboard-dark) :global(.labor-hours-select__single-value), +:global([data-theme='dark']) :global(.labor-hours-select__single-value) { color: #f9fafb !important; } -:global(.dark) :global(.react-select__placeholder), -:global(.dark-mode) :global(.react-select__placeholder), -:global([data-theme='dark']) :global(.react-select__placeholder) { - color: #9ca3af !important; +:global(.dark) :global(.labor-hours-select__input), +:global(.dark-mode) :global(.labor-hours-select__input), +:global(.bm-dashboard-dark) :global(.labor-hours-select__input), +:global([data-theme='dark']) :global(.labor-hours-select__input) { + color: #f9fafb !important; } -/* Dim the vertical separator between the value and the dropdown arrow */ -:global(.react-select__indicator-separator) { - background-color: #ccc !important; +:global(.dark) :global(.labor-hours-select__placeholder), +:global(.dark-mode) :global(.labor-hours-select__placeholder), +:global(.bm-dashboard-dark) :global(.labor-hours-select__placeholder), +:global([data-theme='dark']) :global(.labor-hours-select__placeholder) { + color: #9ca3af !important; } -/* Dark mode: use the panel color for the separator */ -:global(.dark) :global(.react-select__indicator-separator), -:global(.dark-mode) :global(.react-select__indicator-separator), -:global([data-theme='dark']) :global(.react-select__indicator-separator) { - background-color: #2d4059 !important; +:global(.dark) :global(.labor-hours-select__indicator-separator), +:global(.dark-mode) :global(.labor-hours-select__indicator-separator), +:global(.bm-dashboard-dark) :global(.labor-hours-select__indicator-separator), +:global([data-theme='dark']) :global(.labor-hours-select__indicator-separator) { + background-color: #4b5563 !important; } -/* Make the dropdown arrow a light gray (not bright white) in both modes */ -:global(.react-select__dropdown-indicator) { - color: #ccc !important; -} - -:global(.dark) :global(.react-select__menu), -:global(.dark-mode) :global(.react-select__menu), -:global([data-theme='dark']) :global(.react-select__menu) { +:global(.dark) :global(.labor-hours-select__menu), +:global(.dark-mode) :global(.labor-hours-select__menu), +:global(.bm-dashboard-dark) :global(.labor-hours-select__menu), +:global([data-theme='dark']) :global(.labor-hours-select__menu) { background-color: #1f2937 !important; border: 1px solid #374151 !important; - z-index: 10; } -:global(.dark) :global(.react-select__option), -:global(.dark-mode) :global(.react-select__option), -:global([data-theme='dark']) :global(.react-select__option) { +:global(.dark) :global(.labor-hours-select__option), +:global(.dark-mode) :global(.labor-hours-select__option), +:global(.bm-dashboard-dark) :global(.labor-hours-select__option), +:global([data-theme='dark']) :global(.labor-hours-select__option) { background-color: #1f2937 !important; color: #f9fafb !important; + cursor: pointer; } -:global(.dark) :global(.react-select__option--is-focused), -:global(.dark-mode) :global(.react-select__option--is-focused), -:global([data-theme='dark']) :global(.react-select__option--is-focused) { +:global(.dark) :global(.labor-hours-select__option--is-focused), +:global(.dark-mode) :global(.labor-hours-select__option--is-focused), +:global(.bm-dashboard-dark) :global(.labor-hours-select__option--is-focused), +:global([data-theme='dark']) :global(.labor-hours-select__option--is-focused) { background-color: #374151 !important; - color: #ffffff !important; + color: #fff !important; } -/* Dark mode: style date inputs only (not react-select's internal input) */ -:global(.dark) .filters input[type='date'], -:global(.dark-mode) .filters input[type='date'], -:global([data-theme='dark']) .filters input[type='date'] { - background-color: #1f2937 !important; - color: #f9fafb !important; - border: 1px solid #374151 !important; + +:global(.dark) :global(.labor-hours-select__option--is-selected), +:global(.dark-mode) :global(.labor-hours-select__option--is-selected), +:global(.bm-dashboard-dark) :global(.labor-hours-select__option--is-selected), +:global([data-theme='dark']) :global(.labor-hours-select__option--is-selected) { + background-color: #2563eb !important; + color: #fff !important; } -:global(.dark) .filters input[type='date'], -:global(.dark-mode) .filters input[type='date'], -:global([data-theme='dark']) .filters input[type='date'] { - color-scheme: dark; +/* ========================= + SUBMIT + ========================= */ + +.submitSection { + position: relative; + + width: 100%; + height: 42px; + + margin-top: 12px; + + display: flex; + justify-content: center; + align-items: center; +} + +.button { + min-height: 38px; + + padding: 8px 18px; + + border: none; + border-radius: 6px; + + background-color: #2563eb; + color: #fff; + + cursor: pointer; + + transition: background-color 0.3s ease; +} + +.button:hover { + background-color: #1d4ed8; +} + +.button:focus-visible { + outline: 2px solid #93c5fd; + outline-offset: 2px; +} + +:global(.dark) .button, +:global(.dark-mode) .button, +:global(.bm-dashboard-dark) .button, +:global([data-theme='dark']) .button { + background-color: #2563eb; + color: #fff; } -.chartWrapper { +.appliedMessage { + position: absolute; + + left: calc(50% + 58px); + top: 50%; + + transform: translateY(-50%); + + white-space: nowrap; + + color: #166534; + + font-size: 0.8rem; + font-weight: 500; +} + +:global(.dark) .appliedMessage, +:global(.dark-mode) .appliedMessage, +:global(.bm-dashboard-dark) .appliedMessage, +:global([data-theme='dark']) .appliedMessage { + color: #86efac; +} + +/* ========================= + VISUALIZATION + ========================= */ + +/* + * Important: + * No flex-grow. + * No min-height. + * No huge padding. + * + * The chart simply follows the filters with a controlled gap. + */ +.visualizationSection { + width: 100%; + min-width: 0; + flex: 0 0 auto; + display: flex; - justify-content: space-between; align-items: center; - flex-wrap: wrap; - gap: 16px; + justify-content: center; + + margin-top: 28px; + padding: 0; +} + +.visualizationContent { + width: 100%; + max-width: 700px; + min-width: 0; + + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 340px); + + justify-content: center; + align-items: center; + column-gap: 24px; } +/* ========================= + LEGEND + ========================= */ + .legend { + width: 100%; + min-width: 0; + display: flex; flex-direction: column; - min-width: 150px; + justify-content: center; } .legendItem { display: flex; align-items: center; - margin-bottom: 8px; + + margin-bottom: 9px; + font-size: 0.85rem; } +.legendItem:last-child { + margin-bottom: 0; +} + +.legendText { + min-width: 0; + overflow-wrap: anywhere; + line-height: 1.3; +} + .colorBox { width: 12px; height: 12px; + margin-right: 8px; + border-radius: 2px; + + flex-shrink: 0; +} + +/* ========================= + PIE + ========================= */ + +.pieChartContainer { + width: 100%; + max-width: 340px; + height: 300px; + min-width: 0; + + display: flex; + align-items: center; + justify-content: center; } +/* ========================= + TOOLTIP + ========================= */ + .tooltip { - background-color: #f3f4f6; - color: #111827; /* darker percentage text in light mode */ - padding: 8px; + padding: 8px 10px; + border-radius: 6px; + + background-color: #f3f4f6; + color: #111827; + + box-shadow: 0 2px 6px rgb(0 0 0 / 15%); +} + +.tooltip p { + margin: 2px 0; } -/* Dark mode: ensure tooltip text is white on hover */ :global(.dark) .tooltip, :global(.dark-mode) .tooltip, +:global(.bm-dashboard-dark) .tooltip, :global([data-theme='dark']) .tooltip { color: #fff; } -:global(.dark) .tooltip:hover, -:global(.dark-mode) .tooltip:hover, -:global([data-theme='dark']) .tooltip:hover { - color: #fff; -} - -/* Dark mode: force ALL tooltip text to white */ :global(.dark) .tooltip *, :global(.dark-mode) .tooltip *, +:global(.bm-dashboard-dark) .tooltip *, :global([data-theme='dark']) .tooltip * { color: #fff !important; } -.buttonContainer { - width: 100%; +/* ========================= + NO DATA + ========================= */ + +.noData { + width: 100%; + min-height: 250px; + display: flex; + align-items: center; justify-content: center; - margin-top: 5px; -} -/* Submit button – light & dark mode safe */ -.button { - background-color: #2563eb; /* blue */ - color: #fff; /* white text */ - border: none; - border-radius: 6px; - padding: 8px 16px; - cursor: pointer; - transition: background-color 0.3s ease; + color: #4b5563; + + text-align: center; + font-size: 0.95rem; } -/* Hover */ -.button:hover { - background-color: #1d4ed8; +:global(.dark) .noData, +:global(.dark-mode) .noData, +:global(.bm-dashboard-dark) .noData, +:global([data-theme='dark']) .noData { + color: #d1d5db; } -/* Dark mode – keep same button color (no brightness jump) */ -:global(.dark) .button, -:global(.dark-mode) .button, -:global([data-theme='dark']) .button { - background-color: #2563eb; - color: #fff; +@container (max-width: 620px) { + .visualizationContent { + grid-template-columns: minmax(0, 1fr); + justify-items: center; + row-gap: 16px; + } + + .legend { + width: 100%; + max-width: 320px; + } + + .pieChartContainer { + width: 100%; + max-width: 300px; + height: 290px; + } + + .visualizationSection { + margin-top: 24px; + } } +/* ========================= + TABLET + ========================= */ -.pieChartContainer { - display: flex; - justify-content: center; - align-items: center; - width: 100%; +@media (width <= 900px) { + .container { + height: auto; + min-height: auto; + padding: 24px 18px; + } + + .content { + max-width: none; + } } +/* ========================= + MOBILE + ========================= */ + @media (width <= 768px) { - .chartWrapper { + .container { + padding: 20px 14px; + } + + .filterRow { flex-direction: column; align-items: center; + + gap: 10px; } - .legend { - margin-bottom: 16px; - align-items: center; + .filterGroup { + width: 100%; + max-width: 280px; + } + + .selectContainer { + width: 100%; } - .filters { + .submitSection { + height: auto; + + margin-top: 12px; + flex-direction: column; - align-items: center; - gap: 10px; + + gap: 6px; } - .filters label { - width: 100%; + .appliedMessage { + position: static; + transform: none; } -} \ No newline at end of file +} diff --git a/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.jsx b/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.jsx index 1ff6ef8a97c..0e038b0f58f 100644 --- a/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.jsx +++ b/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.jsx @@ -1,4 +1,3 @@ -// LossTrackingLineChart.jsx import { useEffect, useMemo, useRef, useState } from 'react'; import { useSelector } from 'react-redux'; import { @@ -24,6 +23,32 @@ const colors = { '2024-Glass': '#ff8c00', }; +// Custom tooltip: line colors shown as swatches, text in the theme's text color so every +// row is readable in light and dark mode; rows sorted from highest to lowest loss. +function LossTooltip({ active, payload, label }) { + if (!active || !payload?.length) return null; + const rows = payload + .filter(item => Number.isFinite(item.value)) + .sort((a, b) => b.value - a.value); + + return ( +
+
{label}
+ {rows.map(item => ( +
+
+ ))} +
+ ); +} + const rawData = [ { year: 2022, @@ -140,16 +165,13 @@ export default function LossTrackingLineChart() { const darkMode = useSelector(state => state.theme.darkMode); const hostRef = useRef(null); - // --- Promote parent wrapper (no parent code changes needed) --- useEffect(() => { const host = hostRef.current; if (!host) return; - // Find the wrapper the page uses around our component const wrapper = host.closest('.weekly-project-summary-card.financial-big'); if (!wrapper) return; - // Save previous inline styles to restore on unmount const prev = { gridColumn: wrapper.style.gridColumn, flex: wrapper.style.flex, @@ -158,7 +180,6 @@ export default function LossTrackingLineChart() { minWidth: wrapper.style.minWidth, }; - // Make the wrapper span the full grid row & fill flex rows wrapper.style.gridColumn = '1 / -1'; wrapper.style.flex = '1 1 100%'; wrapper.style.width = '100%'; @@ -192,26 +213,63 @@ export default function LossTrackingLineChart() { ); const filteredLines = useMemo(() => { + const filterStart = startDate ? startDate.substring(0, 7) : ''; + const filterEnd = endDate ? endDate.substring(0, 7) : ''; + return rawData.filter(line => { - const yearMatch = year === 'All' || String(line.year) === year; const materialMatch = material === 'All' || line.material === material; + let yearMatch = year === 'All' || String(line.year) === year; + + // Filter lines dynamically if they sit entirely outside the selected calendar period + if (filterStart && `${line.year}-12` < filterStart) yearMatch = false; // Checks through end of year + if (filterEnd && `${line.year}-01` > filterEnd) yearMatch = false; // Checks from start of year + return yearMatch && materialMatch; }); - }, [material, year]); + }, [material, year, startDate, endDate]); + + // Enforces valid boundary limitations on HTML pickers dynamically + const dateBounds = useMemo(() => { + if (year === 'All') return { min: '2022-01-01', max: '2024-12-31' }; + return { min: `${year}-01-01`, max: `${year}-12-31` }; + }, [year]); + + // Clears date pickers gracefully if they don't belong to the newly active year selection + const handleYearChange = newYear => { + setYear(newYear); + if (newYear !== 'All') { + if (startDate && !startDate.startsWith(newYear)) setStartDate(''); + if (endDate && !endDate.startsWith(newYear)) setEndDate(''); + } + }; + // Groups and explicitly sorts keys chronologically to handle continuous year-over-year transitions smoothly const chartData = useMemo(() => { const merged = {}; + const filterStart = startDate ? startDate.substring(0, 7) : ''; + const filterEnd = endDate ? endDate.substring(0, 7) : ''; + filteredLines.forEach(line => { line.data.forEach(({ date, month, value }) => { - const withinRange = (!startDate || date >= startDate) && (!endDate || date <= endDate); + const withinRange = + (!filterStart || date >= filterStart) && (!filterEnd || date <= filterEnd); + if (withinRange) { - if (!merged[month]) merged[month] = { month }; - merged[month][`${line.year}-${line.material}`] = value; + if (!merged[date]) { + merged[date] = { + date, + displayLabel: year === 'All' ? `${month} ${String(line.year).substring(2)}` : month, + }; + } + merged[date][`${line.year}-${line.material}`] = value; } }); }); - return Object.values(merged); - }, [filteredLines, startDate, endDate]); + + return Object.keys(merged) + .sort((a, b) => a.localeCompare(b)) + .map(key => merged[key]); + }, [filteredLines, startDate, endDate, year]); const isDefaultFilters = material === DEFAULTS.material && @@ -255,10 +313,9 @@ export default function LossTrackingLineChart() { ))} - - - - - {!isDateRangeValid && ( Start date must be before or equal to end date. @@ -317,54 +364,53 @@ export default function LossTrackingLineChart() {
No data available for the selected filters.
) : ( <> - - - - - - - {filteredLines.map(line => ( - + + + + - ))} - - + + } + cursor={{ stroke: gridColor, strokeWidth: 2 }} + /> + {filteredLines.map(line => ( + + ))} + + +
{legendItems.map(item => ( diff --git a/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.module.css b/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.module.css index f66d850d0a6..2a24026938e 100644 --- a/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.module.css +++ b/src/components/BMDashboard/WeeklyProjectSummary/Financials/LossTrackingLineCharts/LossTrackingLineChart.module.css @@ -1,4 +1,4 @@ -/* ---------- Theme tokens ---------- */ +/* stylelint-disable */ :root { --bg-color: #fff; --text-color: #1f1f1f; @@ -20,16 +20,16 @@ --radius-sm: 8px; --space: 1rem; --shadow: 0 2px 10px rgb(0 0 0 / 8%); + --error-color: #dc3545; } -/* Optional manual dark mode (toggle this class on our container) */ .darkMode { --bg-color: #0f1522; --text-color: #f1f3f7; --muted-text: #c9ced8; - --border-color: #2c3a52; - --tooltip-bg: #1a2336; - --surface: #182235; + --border-color: #555; + --tooltip-bg: #1b2a41; + --surface: #1b2a41; --surface-muted: #111a2b; --accent-color: #7aa2ff; --accent-hover: #9bb9ff; @@ -40,9 +40,9 @@ --reset-btn-bg: #ff6b5e; --reset-btn-hover: #ff4a3a; --reset-btn-text: #0f1522; + --error-color: #ff6b6b; } -/* ---------- Host & card container ---------- */ .host { width: 100%; max-width: 100%; @@ -74,14 +74,11 @@ letter-spacing: 0.1px; } -/* ---------- Filters (grid: one lane when space allows) ---------- */ .lossTrackingChartFilters { display: grid; - - /* Each item gets at least 220px; if space allows, they all sit on one row */ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.85rem var(--space); - align-items: end; /* align baselines for inputs and button */ + align-items: end; background-color: var(--surface-muted); border: 1px solid var(--border-color); border-radius: var(--radius-sm); @@ -95,12 +92,11 @@ font-size: 0.95rem; color: var(--text-color); gap: 0.35rem; - min-width: 0; /* allow shrinking to column width */ + min-width: 0; } -/* Inputs */ .lossTrackingChartFilters select, -.lossTrackingChartFilters input[type="month"] { +.lossTrackingChartFilters [type="date"] { padding: 0.55rem 0.7rem; border: 1px solid var(--border-color); border-radius: 8px; @@ -122,16 +118,21 @@ padding-right: 2.45rem !important; } -.lossTrackingChartFilters input[type="month"] { +.lossTrackingChartFilters [type="date"] { color-scheme: light; } -.darkMode .lossTrackingChartFilters input[type="month"] { +.darkMode .lossTrackingChartFilters [type="date"] { color-scheme: dark; } -.lossTrackingChartFilters input[type="month"]::-webkit-calendar-picker-indicator { +.lossTrackingChartFilters input[type="date"]::-webkit-calendar-picker-indicator { opacity: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; cursor: pointer; } @@ -156,13 +157,12 @@ } .lossTrackingChartFilters select:focus-visible, -.lossTrackingChartFilters input[type="month"]:focus-visible { +.lossTrackingChartFilters [type="date"]:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 2px var(--ring), 0 0 0 4px var(--ring-offset); } -/* Reset button — behaves like any grid item so it aligns in the same lane */ .resetBtn { padding: 0.6rem 1rem; font-size: 0.95rem; @@ -176,13 +176,16 @@ letter-spacing: 0.2px; transition: background-color 0.15s ease, transform 0.02s ease, box-shadow 0.15s ease, color 0.15s ease; box-shadow: 0 1px 0 rgb(0 0 0 / 4%), 0 2px 8px rgb(0 0 0 / 8%); + place-self: end start; +} - /* IMPORTANT: no margin-left/auto and no order hacks */ - place-self: end start; /* align start like labels */ /* baseline alignment with inputs */ +.resetBtn:hover { + background-color: var(--reset-btn-hover); } -.resetBtn:hover { background-color: var(--reset-btn-hover); } -.resetBtn:active { transform: translateY(1px); } +.resetBtn:active { + transform: translateY(1px); +} .resetBtn:focus-visible { outline: none; @@ -195,81 +198,54 @@ box-shadow: none; } -/* Date range validation error — spans full grid width */ -.dateRangeError { +div.lossTrackingChartContainer span.dateRangeError { grid-column: 1 / -1; - color: #e53935; - font-size: 0.82rem; - font-weight: 500; + color: var(--error-color) !important; + font-size: 0.85rem; + font-weight: 600; padding: 0.15rem 0.1rem; + display: block; + margin-top: 10px; } -/* Optional: on very narrow screens, make the button full width to match stacked inputs */ -@media (width <= 768px) { - .resetBtn { justify-self: stretch; } - - .customLegend { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } -} - -/* ---------- Chart area (responsive height) ---------- */ .chartWrapper { + display: flex; + flex-direction: column; width: 100%; - /* Responsive, predictable height for ResponsiveContainer (height="100%") */ + /* Height of the plot area only; the wrapper grows to fit the legend below it */ --chart-height: clamp(320px, 42vh, 680px); - height: var(--chart-height); background-color: var(--surface-muted); border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 1rem; - min-width: 0; /* let SVG measure correctly in flex/grid */ -} - -@media screen and (width >= 1440px) { - .chartWrapper { --chart-height: clamp(340px, 40vh, 720px); } -} - -/* Recharts tweaks */ -.recharts-cartesian-grid line { stroke: var(--grid-color); } - -.customLegend { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 0.55rem 1.1rem; - margin-top: 1rem; - color: var(--text-color); - font-size: 0.95rem; - align-items: start; + min-width: 0; } -.legendItem { - display: inline-flex; - align-items: center; - gap: 0.45rem; +/* Fixed-height box for ResponsiveContainer (height="100%") */ +.chartArea { + height: var(--chart-height); min-width: 0; - justify-self: start; + width: 100%; } -.legendSwatch { - width: 10px; - height: 10px; - border-radius: 999px; - flex: 0 0 auto; +@media (width >=1440px) { + .chartWrapper { + --chart-height: clamp(340px, 40vh, 720px); + } } -.legendItem > span:last-child { - white-space: nowrap; +.recharts-cartesian-grid line { + stroke: var(--grid-color); } -/* ---------- No data state ---------- */ .noDataMessage { display: flex; justify-content: center; align-items: center; - height: 100%; + height: var(--chart-height); + box-sizing: border-box; font-size: 1rem; font-weight: 600; color: var(--muted-text); @@ -281,30 +257,99 @@ transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease; } -/* --- Ultra-narrow phones: <= 400px --- */ -@media (width <= 400px) { +.customLegend { + display: flex; + flex-wrap: wrap !important; + justify-content: center; + align-items: center; + gap: 15px; + margin-top: 20px; + width: 100%; +} + +.legendItem { + display: flex; + align-items: center; + gap: 6px; + white-space: nowrap; + font-size: 14px; +} + +.legendSwatch { + width: 10px; + height: 10px; + border-radius: 999px; + flex: 0 0 auto; +} + +@media (width <=768px) { + .resetBtn { + justify-self: stretch; + } +} + +@media (width <=400px) { .lossTrackingChartFilters { - grid-template-columns: 1fr; /* force single column */ - gap: 0.6rem; /* slightly tighter spacing */ - padding: 0.75rem; /* reduce inner padding */ + grid-template-columns: 1fr; + gap: 0.6rem; + padding: 0.75rem; } .lossTrackingChartFilters label { - min-width: 0; /* allow shrink */ + min-width: 0; } .lossTrackingChartFilters select, - .lossTrackingChartFilters input[type="month"], + .lossTrackingChartFilters [type="date"], .resetBtn { - width: 100%; /* full width controls */ - box-sizing: border-box; /* respect padding/border */ + width: 100%; + box-sizing: border-box; } +} - .resetBtn { - justify-self: stretch; /* no overflow due to intrinsic width */ - } +/* ---------- Tooltip ---------- */ +.tooltip { + min-width: 190px; + padding: 0.6rem 0.75rem; + background-color: var(--tooltip-bg); + color: var(--text-color); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + box-shadow: 0 6px 18px rgb(0 0 0 / 18%); + font-size: 0.85rem; + line-height: 1.2; +} - .customLegend { - grid-template-columns: 1fr; - } +.tooltipTitle { + margin-bottom: 0.45rem; + padding-bottom: 0.35rem; + border-bottom: 1px solid var(--border-color); + font-weight: 700; +} + +.tooltipRow { + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 0.5rem; + padding: 0.15rem 0; +} + +.tooltipSwatch { + width: 10px; + height: 10px; + border-radius: 50%; + + /* Outline keeps pale colors (e.g. yellow) visible on light backgrounds */ + box-shadow: 0 0 0 1px rgb(0 0 0 / 15%); +} + +.tooltipLabel { + white-space: nowrap; +} + +.tooltipValue { + font-weight: 700; + font-variant-numeric: tabular-nums; + text-align: right; } diff --git a/src/components/BMDashboard/WeeklyProjectSummary/GroupedBarGraphInjurySeverity/InjuryCategoryBarChart.jsx b/src/components/BMDashboard/WeeklyProjectSummary/GroupedBarGraphInjurySeverity/InjuryCategoryBarChart.jsx index a18f90ce622..7e5dd5db482 100644 --- a/src/components/BMDashboard/WeeklyProjectSummary/GroupedBarGraphInjurySeverity/InjuryCategoryBarChart.jsx +++ b/src/components/BMDashboard/WeeklyProjectSummary/GroupedBarGraphInjurySeverity/InjuryCategoryBarChart.jsx @@ -162,13 +162,19 @@ function InjuryCategoryBarChart() { }, [data]); const allSeriesProjectIds = useMemo(() => { const set = new Set(projects.map(p => String(p._id))); + // Include projects that have bars but are missing from the project list, so the legend matches the chart + for (const pid of seriesProjectIds) set.add(pid); return Array.from(set); - }, [projects]); + }, [projects, seriesProjectIds]); const colorProjectIds = useMemo(() => { const source = unfilteredProjects.length ? unfilteredProjects : projects; const set = new Set(source.map(project => String(project._id))); + // Every project shown (current list or bars) needs a palette color; otherwise it renders black, + // which is invisible on the dark-mode chart background + for (const p of projects) set.add(String(p._id)); + for (const pid of seriesProjectIds) set.add(pid); return Array.from(set); - }, [unfilteredProjects, projects]); + }, [unfilteredProjects, projects, seriesProjectIds]); const showLabels = seriesProjectIds.length <= 4; @@ -215,44 +221,70 @@ function InjuryCategoryBarChart() { endDate, ]); - const selectStyles = darkMode && { - control: base => ({ - ...base, - backgroundColor: '#2b3e59', - color: 'white', - }), - menu: base => ({ - ...base, - backgroundColor: '#2b3e59', - color: 'white', - }), - option: (base, state) => ({ - ...base, - color: 'white', - backgroundColor: state.isSelected - ? 'rgba(255, 255, 255, 0.15)' - : state.isFocused - ? 'rgba(255, 255, 255, 0.1)' - : 'transparent', - '&:active': { - backgroundColor: 'rgba(255, 255, 255, 0.2)', + // Theme-aware react-select styles for both modes. Styling lives here instead of global + // CSS overrides so it cannot leak into other dropdowns in the app. + const selectStyles = useMemo(() => { + const textColor = darkMode ? '#ffffff' : '#111827'; + const mutedColor = darkMode ? '#cbd5e1' : '#6b7280'; + const surfaceColor = darkMode ? '#2b3e59' : '#ffffff'; + const borderColor = darkMode ? '#6b7280' : '#d1d5db'; + + return { + control: (base, state) => ({ + ...base, + backgroundColor: surfaceColor, + borderColor: state.isFocused ? '#3b82f6' : borderColor, + boxShadow: state.isFocused ? '0 0 0 1px #3b82f6' : 'none', + '&:hover': { borderColor: '#3b82f6' }, + }), + placeholder: base => ({ ...base, color: mutedColor }), + // Typed search text stays readable in dark mode (was black on dark before) + input: base => ({ ...base, color: textColor }), + singleValue: base => ({ ...base, color: textColor }), + multiValue: base => ({ ...base, backgroundColor: darkMode ? '#375071' : '#e5e7eb' }), + multiValueLabel: base => ({ ...base, color: textColor }), + multiValueRemove: base => ({ + ...base, + color: textColor, + ':hover': { backgroundColor: '#0d55b3', color: '#ffffff' }, + }), + indicatorSeparator: base => ({ ...base, backgroundColor: borderColor }), + dropdownIndicator: base => ({ ...base, color: mutedColor, ':hover': { color: textColor } }), + clearIndicator: base => ({ ...base, color: mutedColor, ':hover': { color: textColor } }), + menu: base => ({ ...base, backgroundColor: surfaceColor, zIndex: 5 }), + option: (base, state) => { + let backgroundColor = surfaceColor; + if (state.isFocused) backgroundColor = darkMode ? '#334155' : '#e2e8f0'; + if (state.isSelected) backgroundColor = darkMode ? '#1d4ed8' : '#dbeafe'; + return { + ...base, + backgroundColor, + color: textColor, + ':active': { backgroundColor: darkMode ? '#0d55b3' : '#bfdbfe' }, + }; }, - }), - singleValue: base => ({ - ...base, - color: 'white', - }), - }; - // : {}; + noOptionsMessage: base => ({ ...base, color: mutedColor }), + }; + }, [darkMode]); - return ( -
-
-

Injury Severity by Category of Worker Injured

+ const containerClassName = `${styles.injuryChartContainer} ${ + darkMode ? styles.injuryChartDark : '' + }`; + // Applied to the calendar popup itself so dark styles don't depend on global classes + const calendarClassName = darkMode ? styles.injuryDarkCalendar : undefined; -
-
-
)} + {emailMode === EMAIL_MODES.WEEKLY_UPDATE && } {/* Form */} {emailMode !== EMAIL_MODES.WEEKLY_UPDATE && ( diff --git a/src/components/EmailManagement/email-sender/WeeklyUpdateComposer.jsx b/src/components/EmailManagement/email-sender/WeeklyUpdateComposer.jsx index 5105b4b4348..31d9e5643ae 100644 --- a/src/components/EmailManagement/email-sender/WeeklyUpdateComposer.jsx +++ b/src/components/EmailManagement/email-sender/WeeklyUpdateComposer.jsx @@ -1,12 +1,13 @@ import axios from 'axios'; import PropTypes from 'prop-types'; -import { useCallback, useState } from 'react'; +import React, { useCallback, useRef, useState } from 'react'; import { FaExclamationTriangle, FaEye, FaImage, FaPaperPlane, FaTimes, + FaTrash, FaUpload, } from 'react-icons/fa'; import { useSelector } from 'react-redux'; @@ -144,11 +145,25 @@ const EMAIL_TEMPLATE_STYLES = ` margin: 5px 0; } `; +const getImageUploadPrompt = imageDragging => { + if (imageDragging) { + return 'Drop image here'; + } + + return 'Click to upload or drag and drop'; +}; + +const getVideoUploadPrompt = videoDragging => { + if (videoDragging) { + return 'Drop YouTube link here!'; + } + return 'Drag & drop YouTube link here'; +}; const WeeklyUpdateComposer = ({ onClose }) => { const darkMode = useSelector(state => state.theme.darkMode); const currentUser = useSelector(state => state.auth?.user); - + const imageInputRef = useRef(null); // Form state - only what changes each week const [headerImage, setHeaderImage] = useState(''); const [introParagraph, setIntroParagraph] = useState(''); @@ -193,31 +208,40 @@ const WeeklyUpdateComposer = ({ onClose }) => { }, []); // Handle image file drop - const handleImageDrop = useCallback(e => { - e.preventDefault(); - e.stopPropagation(); - setImageDragging(false); + // Process an image file from either the file picker or drag-and-drop + const handleImageFile = useCallback(file => { + if (!file) return; - const files = e.dataTransfer?.files; - if (files && files.length > 0) { - const file = files[0]; - - // Check if it's an image - if (file.type.startsWith('image/')) { - const reader = new FileReader(); - reader.onload = event => { - const base64Image = event.target.result; - setHeaderImage(base64Image); - setImagePreview(base64Image); - toast.success('Image loaded successfully!'); - }; - reader.readAsDataURL(file); - } else { - toast.error('Please drop an image file (jpg, png, gif, etc.)'); - } + if (!file.type.startsWith('image/')) { + toast.error('Please drop an image file (jpg, png, gif, etc.)'); + return; } + + const reader = new FileReader(); + + reader.onload = event => { + const base64Image = event.target.result; + setHeaderImage(base64Image); + setImagePreview(base64Image); + toast.success('Image loaded successfully!'); + }; + + reader.readAsDataURL(file); }, []); + // Handle image drag-and-drop events + const handleImageDrop = useCallback( + e => { + e.preventDefault(); + e.stopPropagation(); + setImageDragging(false); + + const file = e.dataTransfer?.files?.[0]; + handleImageFile(file); + }, + [handleImageFile], + ); + const handleImageDragOver = useCallback(e => { e.preventDefault(); e.stopPropagation(); @@ -502,9 +526,54 @@ const WeeklyUpdateComposer = ({ onClose }) => { setIsSending(false); } }, [emailDistribution, recipientList, generateEmailHTML, currentUser]); + let composerThemeClass = 'weekly-update-composer light-mode'; + + if (darkMode) { + composerThemeClass = 'weekly-update-composer dark-mode'; + } + + let imageDropZoneBackgroundColor = '#f9fafb'; + let imageDropZoneBorder = '2px dashed #d1d5db'; + let imageUploadIconColor = '#9ca3af'; + let imageUploadTextColor = '#6b7280'; + let imageUploadPrompt = getImageUploadPrompt(); + + if (darkMode) { + imageDropZoneBackgroundColor = '#2d2d2d'; + imageDropZoneBorder = '2px dashed #666'; + imageUploadIconColor = '#d1d5db'; + imageUploadTextColor = '#e5e7eb'; + } + + if (imageDragging) { + imageDropZoneBackgroundColor = darkMode ? '#26374a' : '#eff6ff'; + imageDropZoneBorder = '3px dashed #3b82f6'; + imageUploadIconColor = '#60a5fa'; + imageUploadTextColor = '#60a5fa'; + } + let videoUploadPrompt = getVideoUploadPrompt(); + + let videoDropZoneBackgroundColor = '#f9fafb'; + let videoDropZoneBorder = '2px dashed #d1d5db'; + let videoUploadIconColor = '#9ca3af'; + let videoUploadTextColor = '#6b7280'; + + if (darkMode) { + videoDropZoneBackgroundColor = '#2d2d2d'; + videoDropZoneBorder = '2px dashed #666'; + videoUploadIconColor = '#d1d5db'; + videoUploadTextColor = '#e5e7eb'; + } + + if (videoDragging) { + videoDropZoneBackgroundColor = darkMode ? '#452626' : '#fef2f2'; + videoDropZoneBorder = '3px dashed #ef4444'; + videoUploadIconColor = '#f87171'; + videoUploadTextColor = '#f87171'; + } return ( -
+

📰 Weekly Progress Update

Fill in the 4 fields below - everything else is automatic!

@@ -524,28 +593,58 @@ const WeeklyUpdateComposer = ({ onClose }) => { {/* Drag & Drop Zone */} -
imageInputRef.current?.click()} onDrop={handleImageDrop} onDragOver={handleImageDragOver} onDragLeave={handleImageDragLeave} style={{ - border: imageDragging ? '3px dashed #3b82f6' : '2px dashed #d1d5db', + display: 'block', + width: '100%', + border: imageDropZoneBorder, borderRadius: '8px', - padding: '20px', + padding: '30px', textAlign: 'center', - backgroundColor: imageDragging ? '#eff6ff' : '#f9fafb', - transition: 'all 0.2s ease', - marginBottom: '10px', + backgroundColor: imageDropZoneBackgroundColor, cursor: 'pointer', + transition: 'all 0.2s', + font: 'inherit', + color: 'inherit', }} > - -

- {imageDragging ? 'Drop image here!' : 'Drag & drop an image here'} + e.stopPropagation()} + onChange={e => { + const file = e.target.files?.[0]; + + if (file) { + handleImageFile(file); + } + + e.target.value = ''; + }} + /> + + + +

+ {imageUploadPrompt}

- or paste URL below -
+ JPG, PNG, GIF, etc. + { invalid={!!validationErrors.headerImage} placeholder="Or paste image URL here (e.g., https://example.com/image.jpg)" /> + {validationErrors.headerImage && (
{validationErrors.headerImage}
)} + Supports: Drag & drop image files, or paste image URLs @@ -564,7 +665,26 @@ const WeeklyUpdateComposer = ({ onClose }) => { {/* Image Preview */} {imagePreview && (
- +
+ + +
+ Header preview { onError={() => { toast.error('Invalid image URL'); setImagePreview(''); + setHeaderImage(''); }} />
@@ -610,21 +731,27 @@ const WeeklyUpdateComposer = ({ onClose }) => { onDragOver={handleVideoDragOver} onDragLeave={handleVideoDragLeave} style={{ - border: videoDragging ? '3px dashed #ef4444' : '2px dashed #d1d5db', + border: videoDropZoneBorder, borderRadius: '8px', - padding: '20px', + padding: '30px', textAlign: 'center', - backgroundColor: videoDragging ? '#fef2f2' : '#f9fafb', - transition: 'all 0.2s ease', - marginBottom: '10px', + backgroundColor: videoDropZoneBackgroundColor, cursor: 'pointer', + transition: 'all 0.2s', }} > - -

- {videoDragging ? 'Drop YouTube link here!' : 'Drag & drop YouTube link here'} + + +

+ {videoUploadPrompt}

- or paste URL below + + or paste URL below
{ invalid={!!validationErrors.youtubeLink} placeholder="Or paste YouTube URL: https://youtube.com/watch?v=..." /> + {validationErrors.youtubeLink && (
{validationErrors.youtubeLink}
)} + {youtubeLink && extractYouTubeId(youtubeLink) && ( ✓ Valid YouTube link detected )} diff --git a/src/components/HGNForm/pages/HGNFormListPage.jsx b/src/components/HGNForm/pages/HGNFormListPage.jsx new file mode 100644 index 00000000000..528510e7a62 --- /dev/null +++ b/src/components/HGNForm/pages/HGNFormListPage.jsx @@ -0,0 +1,63 @@ +import axios from 'axios'; +import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { useSelector } from 'react-redux'; +import { ENDPOINTS } from '~/utils/URL'; +import styles from '../styles/HGNFormListPage.module.css'; + +const HGN_QUESTIONNAIRE_NAME = 'HGN Development Team Questionnaire'; +const HGN_QUESTIONNAIRE_DESCRIPTION = + 'Your answers are used for team collaboration and placement based on your interests and strengths.'; + +function HGNFormListPage() { + const [forms, setForms] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + const darkMode = useSelector(state => state.theme.darkMode); + + useEffect(() => { + const loadForms = async () => { + try { + const response = await axios.get(ENDPOINTS.HGN_FORMS); + setForms(Array.isArray(response.data?.data) ? response.data.data : []); + } catch { + setError(true); + } finally { + setLoading(false); + } + }; + + loadForms(); + }, []); + + return ( +
+

HGN Forms

+
+ +

{HGN_QUESTIONNAIRE_NAME}

+

{HGN_QUESTIONNAIRE_DESCRIPTION}

+ + + {loading &&
Loading forms...
} + {error && ( +
+ Unable to load additional forms. Please try again later. +
+ )} + {!loading && !error && !forms.length && ( +
No additional forms are currently available.
+ )} + + {forms.map(form => ( +
+

{form.formName}

+

{form.description || 'No description available.'}

+
+ ))} +
+
+ ); +} + +export default HGNFormListPage; diff --git a/src/components/HGNForm/pages/__tests__/HGNFormListPage.test.jsx b/src/components/HGNForm/pages/__tests__/HGNFormListPage.test.jsx new file mode 100644 index 00000000000..24cc2703868 --- /dev/null +++ b/src/components/HGNForm/pages/__tests__/HGNFormListPage.test.jsx @@ -0,0 +1,85 @@ +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import axios from 'axios'; +import HGNFormListPage from '../HGNFormListPage'; +import { ENDPOINTS } from '~/utils/URL'; + +vi.mock('axios'); + +const mockStore = configureMockStore([]); + +const renderFormList = () => + render( + + + + + , + ); + +describe('HGNFormListPage', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('renders generic form metadata and the built-in HGN questionnaire entry', async () => { + axios.get.mockResolvedValue({ + data: { + data: [ + { + _id: 'generic-form', + formName: 'Mern Stack Developer', + description: 'Find your best development team fit.', + }, + ], + }, + }); + + renderFormList(); + + expect(await screen.findByText('Mern Stack Developer')).toBeInTheDocument(); + expect(screen.getByText('Find your best development team fit.')).toBeInTheDocument(); + expect(screen.getByText('HGN Development Team Questionnaire')).toBeInTheDocument(); + expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.HGN_FORMS); + expect( + screen.getByRole('link', { name: /HGN Development Team Questionnaire/i }), + ).toHaveAttribute('href', '/hgnform/page1'); + }); + + it('handles forms without descriptions safely', async () => { + axios.get.mockResolvedValue({ data: { data: [{ _id: 'form-2', formName: 'Existing Form' }] } }); + + renderFormList(); + + expect(await screen.findByText('Existing Form')).toBeInTheDocument(); + expect(screen.getByText('No description available.')).toBeInTheDocument(); + }); + + it('keeps the HGN questionnaire available when the generic form list is empty', async () => { + axios.get.mockResolvedValue({ data: { data: [] } }); + + renderFormList(); + + expect( + await screen.findByText('No additional forms are currently available.'), + ).toBeInTheDocument(); + expect( + screen.getByRole('link', { name: /HGN Development Team Questionnaire/i }), + ).toHaveAttribute('href', '/hgnform/page1'); + }); + + it('handles an API failure without exposing backend errors', async () => { + axios.get.mockRejectedValue(new Error('Server error')); + + renderFormList(); + + expect( + await screen.findByText('Unable to load additional forms. Please try again later.'), + ).toBeInTheDocument(); + expect( + screen.getByRole('link', { name: /HGN Development Team Questionnaire/i }), + ).toBeInTheDocument(); + }); +}); diff --git a/src/components/HGNForm/pages/__tests__/Page1.test.jsx b/src/components/HGNForm/pages/__tests__/Page1.test.jsx new file mode 100644 index 00000000000..b27782f06ba --- /dev/null +++ b/src/components/HGNForm/pages/__tests__/Page1.test.jsx @@ -0,0 +1,67 @@ +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import { Provider } from 'react-redux'; +import { createStore, combineReducers, applyMiddleware } from 'redux'; +import thunk from 'redux-thunk'; +import axios from 'axios'; +import Page1 from '../Page1'; +import HGNFormReducer from '~/reducers/hgnFormReducers'; +import { allUserProfilesBasicInfoReducer } from '~/reducers/allUserProfilesBasicInfoReducer'; +import { ENDPOINTS } from '~/utils/URL'; + +vi.mock('axios'); + +const mockUser = { + userid: 'user-123', + firstName: 'Ada', + lastName: 'Lovelace', + email: 'ada@example.com', + role: 'Volunteer', +}; + +const buildStore = () => + createStore( + combineReducers({ + theme: (state = { darkMode: false }) => state, + auth: (state = { user: mockUser }) => state, + allUserProfilesBasicInfo: allUserProfilesBasicInfoReducer, + hgnForm: HGNFormReducer, + }), + applyMiddleware(thunk), + ); + +const renderPage1 = () => + render( + + + + + , + ); + +describe('Page1 basic info loading', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('renders the questionnaire once basic info resolves successfully', async () => { + axios.get.mockResolvedValueOnce({ + data: { _id: 'user-123', firstName: 'Ada', lastName: 'Lovelace' }, + }); + + renderPage1(); + + expect(await screen.findByRole('textbox', { name: /^Name/i })).toHaveValue('Ada Lovelace'); + expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.USER_PROFILE_BASIC_INFO_BY_ID('user-123')); + }); + + it('does not stay on the loading spinner when the basic info request is rejected (400)', async () => { + axios.get.mockRejectedValueOnce({ + response: { status: 400, data: { error: 'Source parameter is required' } }, + }); + + renderPage1(); + + expect(await screen.findByRole('textbox', { name: /^Name/i })).toBeInTheDocument(); + }); +}); diff --git a/src/components/HGNForm/questionpages/FollowupQuestions.jsx b/src/components/HGNForm/questionpages/FollowupQuestions.jsx index c2fa278204d..de597ae1115 100644 --- a/src/components/HGNForm/questionpages/FollowupQuestions.jsx +++ b/src/components/HGNForm/questionpages/FollowupQuestions.jsx @@ -232,7 +232,7 @@ function FollowupQuestions() { const handleEdit = () => { dispatch(setformData(newVolunteer)); - navigate.push('/hgnform'); + navigate.push('/hgnform/page1'); }; const handleTextChange = e => { diff --git a/src/components/HGNForm/questionpages/InfoForm.jsx b/src/components/HGNForm/questionpages/InfoForm.jsx index de394f20c88..99c5c25ee18 100644 --- a/src/components/HGNForm/questionpages/InfoForm.jsx +++ b/src/components/HGNForm/questionpages/InfoForm.jsx @@ -28,6 +28,9 @@ function InfoForm() { const [touched, setTouched] = useState(false); const [isSlackNameWarning, setIsSlackNameWarning] = useState(false); + // Lock the name field only when it was prefilled from the profile, + // not whenever the user has typed something. + const [nameFromProfile, setNameFromProfile] = useState(false); const isValid = newVolunteer.name.length >= 2; const showError = touched && !isValid; @@ -48,10 +51,14 @@ function InfoForm() { if (user && formData) { const firstName = userProfile?.firstName || user?.firstName || ''; const lastName = userProfile?.lastName || user?.lastName || ''; + setNameFromProfile(Boolean(firstName && lastName)); setNewVolunteer(prevState => ({ ...formData, ...prevState, // This preserves any user input - name: firstName && lastName ? `${firstName} ${lastName}` : '', + name: + firstName && lastName + ? `${firstName} ${lastName}` + : prevState.name || formData.name || '', email: user.email, github: prevState.github || formData.github || '', // Preserve GitHub value slack: prevState.slack || formData.slack || '', // Preserve @@ -170,6 +177,7 @@ function InfoForm() { pattern=".{2,}" title="Name must be at least 2 characters long" placeholder="Your First and Last Name" + disabled={nameFromProfile} /> {showError && ( @@ -189,7 +197,7 @@ function InfoForm() { onChange={e => setNewVolunteer({ ...newVolunteer, email: e.target.value })} required placeholder="Your Email" - disabled={!!(user.email !== undefined || user.email !== null)} + disabled={!!user.email} />
diff --git a/src/components/HGNForm/styles/HGNFormListPage.module.css b/src/components/HGNForm/styles/HGNFormListPage.module.css new file mode 100644 index 00000000000..d382e4c5b79 --- /dev/null +++ b/src/components/HGNForm/styles/HGNFormListPage.module.css @@ -0,0 +1,49 @@ +.container { + max-width: 900px; + margin: 0 auto; + padding: 32px 16px; +} + +.formList { + display: grid; + gap: 16px; +} + +.formCard { + display: block; + padding: 20px; + color: inherit; + text-decoration: none; + background: #fff; + border: 1px solid #d9d9d9; + border-radius: 6px; +} + +.formCard:hover, +.formCard:focus { + border-color: #00754a; +} + +.darkMode { + color: #f0f0f0; +} + +.darkMode .formCard { + background: #2a2a2a; + border-color: #555; +} + +.darkMode .formCard p { + color: #f0f0f0; +} + +.message { + padding: 32px 16px; + text-align: center; +} + +@media (width <= 600px) { + .container { + padding: 24px 12px; + } +} diff --git a/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx b/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx index b37c24c70ba..91be446e23b 100644 --- a/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx +++ b/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx @@ -12,17 +12,16 @@ function CommunityMembersPage() { const [selectedSkills, setSelectedSkills] = useState(location.state?.initialSkills || []); const [selectedPreferences, setSelectedPreferences] = useState([]); const [searchQuery, setSearchQuery] = useState(''); - const [sortBy, setSortBy] = useState('name'); const [sortOrder, setSortOrder] = useState('asc'); const [currentPage, setCurrentPage] = useState(1); + const softwareDevTeamOnly = Boolean(location.state?.softwareDevTeamOnly); const darkMode = useSelector(state => state.theme.darkMode); - const handleSortByChange = event => setSortBy(event.target.value); const handleSortOrderChange = event => setSortOrder(event.target.value); useEffect(() => { setCurrentPage(1); - }, [selectedSkills, selectedPreferences, searchQuery, sortBy, sortOrder]); + }, [selectedSkills, selectedPreferences, searchQuery, sortOrder, softwareDevTeamOnly]); return (
@@ -31,21 +30,8 @@ function CommunityMembersPage() {
- - -
@@ -79,10 +65,10 @@ function CommunityMembersPage() { selectedSkills={selectedSkills} selectedPreferences={selectedPreferences} searchQuery={searchQuery.trim()} - sortBy={sortBy} sortOrder={sortOrder} currentPage={currentPage} setCurrentPage={setCurrentPage} + softwareDevTeamOnly={softwareDevTeamOnly} />
diff --git a/src/components/HGNHelpSkillsDashboard/FeedbackModal.jsx b/src/components/HGNHelpSkillsDashboard/FeedbackModal.jsx index f02248352dc..e15326b1548 100644 --- a/src/components/HGNHelpSkillsDashboard/FeedbackModal.jsx +++ b/src/components/HGNHelpSkillsDashboard/FeedbackModal.jsx @@ -2,13 +2,18 @@ import axios from 'axios'; import PropTypes from 'prop-types'; import { useEffect, useState } from 'react'; import { connect } from 'react-redux'; +import { useHistory } from 'react-router-dom'; import { toast } from 'react-toastify'; import { Button, Input, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; import { ENDPOINTS } from '../../utils/URL'; import styles from './FeedbackModal.module.css'; function FeedbackModal({ authUser }) { - const [isOpen, setIsOpen] = useState(false); + const history = useHistory(); + // This component is only reached by navigating directly to /hgnhelp/feedback + // (see routes.jsx), so arriving here is itself the request to open the form - + // it must not stay hidden behind the "shouldShow" auto-popup check below. + const [isOpen, setIsOpen] = useState(true); const [helpRequestId, setHelpRequestId] = useState(null); const [receivedHelp, setReceivedHelp] = useState(''); const [activeMembers, setActiveMembers] = useState([{ name: '', rating: 0, selectedUser: null }]); @@ -28,22 +33,22 @@ function FeedbackModal({ authUser }) { const [showInactiveDropdown, setShowInactiveDropdown] = useState({}); useEffect(() => { - const checkModal = async () => { + const fetchPendingHelpRequest = async () => { try { const userId = authUser?.userid || 'test-user-id'; const response = await axios.get(ENDPOINTS.HELP_REQUEST_CHECK_MODAL(userId)); - if (response.data.shouldShow) { - setIsOpen(true); + if (response.data.helpRequestId) { setHelpRequestId(response.data.helpRequestId); } } catch (error) { - // Silently fail - modal simply won't show + // No pending help request found for this user - the form can still be + // submitted without one, so this is not fatal to showing the page. } }; - checkModal(); + fetchPendingHelpRequest(); }, [authUser]); // Fetch team members on mount @@ -63,6 +68,7 @@ function FeedbackModal({ authUser }) { const handleClose = () => { setIsOpen(false); + history.push('/dashboard'); }; const handleClosePermanently = async () => { @@ -72,6 +78,7 @@ function FeedbackModal({ authUser }) { await axios.post(ENDPOINTS.FEEDBACK_CLOSE_PERMANENTLY, { userId }); toast.success('This modal will not appear again.'); setIsOpen(false); + history.push('/dashboard'); } catch (error) { toast.error('Failed to save. Please try again.'); } @@ -119,6 +126,7 @@ function FeedbackModal({ authUser }) { await axios.post(ENDPOINTS.FEEDBACK_SUBMIT, feedbackData); toast.success('Thank you for your feedback!'); setIsOpen(false); + history.push('/dashboard'); } catch (error) { toast.error('Failed to submit feedback. Please try again.'); } diff --git a/src/components/HGNHelpSkillsDashboard/RankedUserList.jsx b/src/components/HGNHelpSkillsDashboard/RankedUserList.jsx index b852da737c2..ae6ff0e4a0b 100644 --- a/src/components/HGNHelpSkillsDashboard/RankedUserList.jsx +++ b/src/components/HGNHelpSkillsDashboard/RankedUserList.jsx @@ -1,35 +1,100 @@ -import axios from 'axios'; import PropTypes from 'prop-types'; import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import httpService from '../../services/httpService'; +import { ENDPOINTS } from '~/utils/URL'; +import { formatSkillName } from './FilerData.js'; import styles from './style/RankedUserList.module.css'; import UserCard from './UserCard'; +const TOP_SKILLS_PER_SECTION = 4; const PAGE_SIZE = 20; +const SOFTWARE_DEV_TEAM_NAME = 'software development team'; +const SOFTWARE_DEV_TEAM_ALIASES = new Set([ + SOFTWARE_DEV_TEAM_NAME, + 'hgn software development team', +]); + +const getMemberFullName = member => + `${member?.firstName || ''} ${member?.lastName || ''}`.trim().toLowerCase(); + +/** + * Restrict ranked users to Software Development Team members. + * Fail closed: missing team or lookup errors return [] (never the full ranked list). + * Prefer email; only fall back to name when the ranked user has no email. + */ +const filterToSoftwareDevTeam = async users => { + try { + const teamsResponse = await httpService.get(ENDPOINTS.TEAM); + const teams = Array.isArray(teamsResponse.data) ? teamsResponse.data : []; + const softwareDevTeam = teams.find(team => + SOFTWARE_DEV_TEAM_ALIASES.has(team.teamName?.trim().toLowerCase()), + ); + + if (!softwareDevTeam?._id) { + // Team not found — do not leak non-team ranked users. + return []; + } + + const membersResponse = await httpService.get(ENDPOINTS.TEAM_MEMBERS(softwareDevTeam._id)); + const members = Array.isArray(membersResponse.data) ? membersResponse.data : []; + + const memberEmails = new Set( + members.map(member => (member.email || '').trim().toLowerCase()).filter(Boolean), + ); + const memberNames = new Set(members.map(getMemberFullName).filter(Boolean)); + const memberIds = new Set( + members.map(member => (member._id || member.userId || '').toString()).filter(Boolean), + ); + + return users.filter(user => { + const userId = (user.userId || user.user_id || '').toString(); + if (userId && memberIds.has(userId)) return true; + + const email = (user.email || '').trim().toLowerCase(); + if (email) { + // Email is authoritative: never allow a name-only match to override a mismatch. + return memberEmails.has(email); + } + + const name = (user.name || '').trim().toLowerCase(); + return Boolean(name && memberNames.has(name)); + }); + } catch { + // Team membership lookup failed — show empty list rather than all ranked users. + return []; + } +}; const extractSkillEntries = skillData => { if (!skillData || typeof skillData !== 'object') return []; if (Array.isArray(skillData)) { return skillData.flatMap(skill => { - if (typeof skill === 'string') return [{ name: skill, rating: undefined }]; + if (typeof skill === 'string') + return [{ name: skill, rating: undefined, section: 'default' }]; if (skill && typeof skill === 'object') { const name = skill.name || skill.skill || skill.label || skill.type; - return name ? [{ name, rating: skill.rating ?? skill.score ?? undefined }] : []; + return name + ? [{ name, rating: skill.rating ?? skill.score ?? undefined, section: 'default' }] + : []; } return []; }); } - return Object.values(skillData).flatMap(section => { + return Object.entries(skillData).flatMap(([sectionName, section]) => { if (!section || typeof section !== 'object') return []; if (Array.isArray(section)) { return section.flatMap(skill => { - if (typeof skill === 'string') return [{ name: skill, rating: undefined }]; + if (typeof skill === 'string') + return [{ name: skill, rating: undefined, section: sectionName }]; if (skill && typeof skill === 'object') { const name = skill.name || skill.skill || skill.label || skill.type; - return name ? [{ name, rating: skill.rating ?? skill.score ?? undefined }] : []; + return name + ? [{ name, rating: skill.rating ?? skill.score ?? undefined, section: sectionName }] + : []; } return []; }); @@ -38,15 +103,16 @@ const extractSkillEntries = skillData => { return Object.entries(section).map(([skillName, rating]) => ({ name: skillName, rating: typeof rating === 'number' ? rating : undefined, + section: sectionName, })); }); }; const normalizeUser = user => { - if (Array.isArray(user.topSkills) && user.topSkills.length > 0) return user; - const rawSkills = user.skills; - const skillEntries = extractSkillEntries(rawSkills); + const skillEntries = Array.isArray(user.topSkills) + ? user.topSkills.map(name => ({ name, rating: undefined, section: 'default' })) + : extractSkillEntries(rawSkills); const uniqueSkills = Array.from( new Map( @@ -54,64 +120,76 @@ const normalizeUser = user => { ).values(), ); - const sortedSkills = uniqueSkills - .sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0)) - .map(entry => entry.name); + // Filtering and search use every rated skill, matching the backend's /community rule; + // only the card's display list is trimmed to the top skills of each section. + const skillsBySection = uniqueSkills.reduce((acc, entry) => { + const section = entry.section || 'default'; + if (!acc[section]) acc[section] = []; + acc[section].push(entry); + return acc; + }, {}); + + const topSkillNames = Object.values(skillsBySection).flatMap(entries => + entries + .slice() + .sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0)) + .slice(0, TOP_SKILLS_PER_SECTION) + .map(entry => entry.name), + ); return { ...user, - topSkills: sortedSkills, - skills: sortedSkills, + allSkills: uniqueSkills.map(entry => entry.name), + topSkills: topSkillNames, }; }; +// Put the skills the viewer filtered by at the front so they are never pushed out of view. +const withMatchedSkillsFirst = (user, selectedSkills) => { + const matched = selectedSkills.filter(skill => + (user.allSkills || []).some(own => own.toLowerCase() === skill.toLowerCase()), + ); + const names = Array.from(new Set([...matched, ...(user.topSkills || [])])); + return { ...user, displaySkills: names.map(formatSkillName) }; +}; + function RankedUserList({ - selectedSkills, - selectedPreferences, - searchQuery, - sortBy, - sortOrder, + selectedSkills = [], + selectedPreferences = [], + searchQuery = '', + sortOrder = 'asc', currentPage, setCurrentPage, + softwareDevTeamOnly = false, }) { const [allUsers, setAllUsers] = useState([]); const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); const darkMode = useSelector(state => state.theme.darkMode); + // Load every community member once, then filter/search/sort on the client so all + // skills in the filter list work regardless of the backend's skill-key handling. useEffect(() => { const fetchUsers = async () => { setLoading(true); - + setError(null); try { - const params = {}; - const hasFilters = - (selectedSkills && selectedSkills.length > 0) || - (selectedPreferences && selectedPreferences.length > 0) || - (searchQuery && searchQuery.trim().length > 0); - - if (selectedSkills && selectedSkills.length > 0) { - params.skills = selectedSkills.join(','); - } - - if (selectedPreferences && selectedPreferences.length > 0) { - params.preferences = selectedPreferences.join(','); - } - - if (searchQuery && searchQuery.trim().length > 0) { - params.search = searchQuery.trim(); - } + // Help-request flow always uses ranked questionnaire data (Software Dev skills survey). + const endpoint = softwareDevTeamOnly + ? ENDPOINTS.HGN_FORM_RANKED + : ENDPOINTS.HGN_COMMUNITY_MEMBERS; - const endpoint = hasFilters - ? `${process.env.REACT_APP_APIENDPOINT}/hgnform/ranked` - : `${process.env.REACT_APP_APIENDPOINT}/hgnHelp/community`; + const response = await httpService.get(endpoint); + let users = Array.isArray(response.data) ? response.data.map(normalizeUser) : []; - if (!hasFilters && sortBy === 'name' && sortOrder) { - params.sortOrder = sortOrder; + if (softwareDevTeamOnly) { + users = await filterToSoftwareDevTeam(users); } - const response = await axios.get(endpoint, { params }); - setAllUsers(response.data.map(normalizeUser)); + setAllUsers(users); } catch (err) { + const detail = err.response?.status ? ` (${err.response.status})` : ''; + setError(`Unable to load community members. Please try again later.${detail}`); setAllUsers([]); } finally { setLoading(false); @@ -119,27 +197,45 @@ function RankedUserList({ }; fetchUsers(); - }, [selectedSkills, selectedPreferences, searchQuery, sortOrder, sortBy]); + }, [softwareDevTeamOnly]); - const filteredUsers = searchQuery - ? allUsers.filter(user => { - const name = (user.name || '').toLowerCase(); - const skills = (user.topSkills || []).join(' ').toLowerCase(); - const query = searchQuery.toLowerCase(); + const query = searchQuery.trim().toLowerCase(); - return name.includes(query) || skills.includes(query); - }) - : allUsers; + const filteredUsers = allUsers.filter(user => { + const userSkills = (user.allSkills || []).map(skill => skill.toLowerCase()); - const sortedUsers = [...filteredUsers].sort((a, b) => { - if (sortBy === 'score') { - const scoreA = typeof a.score === 'number' ? a.score : -Infinity; - const scoreB = typeof b.score === 'number' ? b.score : -Infinity; + if (selectedSkills && selectedSkills.length > 0) { + const matchesSkills = selectedSkills.every(skill => userSkills.includes(skill.toLowerCase())); + if (!matchesSkills) return false; + } + + if (selectedPreferences && selectedPreferences.length > 0) { + const userPreferences = new Set((user.preferences || []).map(pref => pref.toLowerCase())); + const matchesPreferences = selectedPreferences.every(pref => + userPreferences.has(pref.toLowerCase()), + ); + if (!matchesPreferences) return false; + } - if (scoreA < scoreB) return sortOrder === 'desc' ? 1 : -1; - if (scoreA > scoreB) return sortOrder === 'desc' ? -1 : 1; + if (query) { + const name = (user.name || '').toLowerCase(); + const displaySkills = (user.allSkills || []).map(skill => + formatSkillName(skill).toLowerCase(), + ); + // Match against both the raw skill keys and their human-readable labels, + // since the keys (e.g. "UnitTest") don't contain the words a member + // would actually type (e.g. "testing"). + const matchesQuery = + name.includes(query) || + userSkills.some(skill => skill.includes(query)) || + displaySkills.some(skill => skill.includes(query)); + if (!matchesQuery) return false; } + return true; + }); + + const sortedUsers = [...filteredUsers].sort((a, b) => { const nameA = (a.name || '').toLowerCase(); const nameB = (b.name || '').toLowerCase(); @@ -151,32 +247,27 @@ function RankedUserList({ const totalPages = Math.ceil(sortedUsers.length / PAGE_SIZE); const safeCurrentPage = Math.min(Math.max(currentPage, 1), Math.max(totalPages, 1)); - const startIndex = (safeCurrentPage - 1) * PAGE_SIZE; const paginatedUsers = sortedUsers.slice(startIndex, startIndex + PAGE_SIZE); - const handlePrevious = () => { - setCurrentPage(page => Math.max(page - 1, 1)); - }; - - const handleNext = () => { - setCurrentPage(page => Math.min(page + 1, totalPages)); - }; - - if (loading) { - return

Loading ranked users...

; - } + const handlePrevious = () => setCurrentPage(page => Math.max(page - 1, 1)); + const handleNext = () => setCurrentPage(page => Math.min(page + 1, totalPages)); + if (loading) return

Loading community members...

; + if (error) return

{error}

; if (!sortedUsers.length) { - return

No users found.

; + const emptyMessage = softwareDevTeamOnly + ? 'No Software Development Team members match this skill yet' + : 'No members found.'; + return

{emptyMessage}

; } return ( -
-
+
+
{paginatedUsers.map(user => ( -
- +
+
))}
@@ -214,10 +305,10 @@ RankedUserList.propTypes = { selectedSkills: PropTypes.arrayOf(PropTypes.string), selectedPreferences: PropTypes.arrayOf(PropTypes.string), searchQuery: PropTypes.string, - sortBy: PropTypes.string, sortOrder: PropTypes.string, currentPage: PropTypes.number.isRequired, setCurrentPage: PropTypes.func.isRequired, + softwareDevTeamOnly: PropTypes.bool, }; export default RankedUserList; diff --git a/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx b/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx index 191480bc0d2..aa38bfb825c 100644 --- a/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx +++ b/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx @@ -1,5 +1,9 @@ -import { useState } from 'react'; +import jwtDecode from 'jwt-decode'; +import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import config from '~/config.json'; +import httpService from '~/services/httpService'; +import { ENDPOINTS } from '~/utils/URL'; import RadarChart from '../HGNSkillsDashboard/SkillsProfilePage/components/RadarChart'; import Accordion from './Accordion'; import { PreferenceFilterButtons, SkillFilterButtons } from './FilterButtons'; @@ -11,12 +15,52 @@ function SkillsOverviewPage() { const [selectedSkills, setSelectedSkills] = useState([]); const [selectedPreferences, setSelectedPreferences] = useState([]); const [searchQuery, setSearchQuery] = useState(''); + const [currentPage, setCurrentPage] = useState(1); const darkMode = useSelector(state => state.theme.darkMode); - const userProfile = useSelector(state => state.userProfile); + const [profileData, setProfileData] = useState(null); + const [loadingProfile, setLoadingProfile] = useState(true); + // The skills survey lives behind its own endpoint and is not part of state.userProfile, + // so this page has to fetch it itself rather than read it from the store. + useEffect(() => { + const token = localStorage.getItem(config.tokenKey); + let userId; + try { + userId = token ? jwtDecode(token)?.userid : undefined; + } catch (_) { + userId = undefined; + } + + if (!userId) { + setLoadingProfile(false); + return; + } + + httpService.setjwt(token); + httpService + .get(ENDPOINTS.SKILLS_PROFILE(userId)) + // isPlaceholder means the user has not filled in the survey yet + .then(({ data }) => setProfileData(data?.isPlaceholder ? null : data)) + .catch(() => setProfileData(null)) + .finally(() => setLoadingProfile(false)); + }, []); + useEffect(() => { + setCurrentPage(1); + }, [selectedSkills, selectedPreferences, searchQuery]); const hasFilters = selectedSkills.length > 0 || selectedPreferences.length > 0 || searchQuery.trim().length > 0; + let radarContent; + if (loadingProfile) { + radarContent =

Loading your skills radar...

; + } else if (profileData?.skillInfo) { + radarContent = ; + } else { + radarContent = ( +

Complete the skills survey to view your radar chart.

+ ); + } + return (

Skills Overview

@@ -24,13 +68,7 @@ function SkillsOverviewPage() { {/* Radar Chart for logged-in user */}

Your Skills Radar

-
- {userProfile?.skillInfo ? ( - - ) : ( -

Complete the skills survey to view your radar chart.

- )} -
+
{radarContent}
{/* Search Bar */} @@ -62,6 +100,8 @@ function SkillsOverviewPage() { selectedSkills={selectedSkills} selectedPreferences={selectedPreferences} searchQuery={searchQuery.trim()} + currentPage={currentPage} + setCurrentPage={setCurrentPage} /> ) : (

diff --git a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx index 7878b385d99..bde234c4b70 100644 --- a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx +++ b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import { useState } from 'react'; import { toast } from 'react-toastify'; +import { useSelector } from 'react-redux'; import styles from './TeamCard.module.css'; import { TeamMemberRow } from './TeamMemberRow'; @@ -55,6 +56,7 @@ export default function TeamCard() { const [selectedMembers, setSelectedMembers] = useState([]); const [confirmAction, setConfirmAction] = useState(null); + const darkMode = useSelector(state => state.theme.darkMode); const toggleSelect = id => { setSelectedMembers(prev => (prev.includes(id) ? prev.filter(m => m !== id) : [...prev, id])); @@ -88,7 +90,7 @@ export default function TeamCard() { const noneSelected = selectedMembers.length === 0; return ( -

+

diff --git a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css index 37d00552bec..17d5853dd2d 100644 --- a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css +++ b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css @@ -275,16 +275,34 @@ background: #5a6268; } -@media (prefers-color-scheme: dark) { - .modal { - background: #2b2b2b; - } - - .modalTitle { - color: #fff; - } - - .modalText { - color: #ccc; - } +/* ── Dark Mode ── */ +.darkMode .teamCardContainer { + border-color: #444; +} + +.darkMode .teamCardTitle, +.darkMode .teamCardRatingLabel { + color: #ccc; +} + +.darkMode .teamMemberName, +.darkMode .showMoreText { + color: #f0f0f0; +} + +.darkMode .teamMemberRowSelected { + background: rgb(0 123 255 / 15%); +} + +.darkMode .modal { + background: #2b2b2b; + box-shadow: 0 8px 24px rgb(0 0 0 / 60%); +} + +.darkMode .modalTitle { + color: #fff; +} + +.darkMode .modalText { + color: #ccc; } \ No newline at end of file diff --git a/src/components/HGNHelpSkillsDashboard/UserCard.jsx b/src/components/HGNHelpSkillsDashboard/UserCard.jsx index 3fd84c6ea6c..2e6b08f6ae6 100644 --- a/src/components/HGNHelpSkillsDashboard/UserCard.jsx +++ b/src/components/HGNHelpSkillsDashboard/UserCard.jsx @@ -1,24 +1,31 @@ +import { MdEmail } from 'react-icons/md'; import styles from './style/UserCard.module.css'; import avatar from './style/avatar.png'; -import emailIcon from './style/email_icon.png'; import slackIcon from './style/slack_icon.png'; import { Link } from 'react-router-dom'; import { useSelector } from 'react-redux'; +import { formatSkillName } from './FilerData.js'; + +const getNormalizedSkills = ({ displaySkills, topSkills, skills }) => { + if (Array.isArray(displaySkills)) return displaySkills; + if (Array.isArray(topSkills)) return topSkills.map(formatSkillName); + if (Array.isArray(skills)) { + return skills + .map(skill => { + if (typeof skill === 'string') return skill; + return skill.name || skill.skill || skill.label || skill.type || ''; + }) + .filter(Boolean) + .map(formatSkillName); + } + return []; +}; function UserCard({ user }) { - const { userId, name, email, slack, score, topSkills, skills } = user; + const { userId, name, email, slack, score, topSkills, displaySkills, skills } = user; const darkMode = useSelector(state => state.theme.darkMode); - const normalizedSkills = Array.isArray(topSkills) - ? topSkills - : Array.isArray(skills) - ? skills - .map(skill => { - if (typeof skill === 'string') return skill; - return skill.name || skill.skill || skill.label || skill.type || ''; - }) - .filter(Boolean) - : []; + const normalizedSkills = getNormalizedSkills({ displaySkills, topSkills, skills }); return (
@@ -36,7 +43,7 @@ function UserCard({ user }) { )} {email && (
- Email + {email}
)} @@ -49,19 +56,23 @@ function UserCard({ user }) {
-
- Score: - = 5 ? styles.scoreHigh : styles.scoreLow}`} - > - {score} - - / 10 -
+ {typeof score === 'number' && ( +
+ Score: + = 5 ? styles.scoreHigh : styles.scoreLow}`} + > + {score} + + / 10 +
+ )}
Top Skills:
-
{normalizedSkills.join(', ')}
+
+ {normalizedSkills.length > 0 ? normalizedSkills.join(', ') : 'No skills listed'} +

diff --git a/src/components/HGNHelpSkillsDashboard/style/UserCard.module.css b/src/components/HGNHelpSkillsDashboard/style/UserCard.module.css index 6f1078c3251..0a919fec084 100644 --- a/src/components/HGNHelpSkillsDashboard/style/UserCard.module.css +++ b/src/components/HGNHelpSkillsDashboard/style/UserCard.module.css @@ -72,6 +72,8 @@ .contactIcon { width: 18px; height: 18px; + color: #616161; + flex-shrink: 0; } .scoreSkillsWrapper { @@ -124,9 +126,6 @@ color: #616161; line-height: 22px; overflow-wrap: break-word; - max-height: 60px; - overflow: hidden; - text-overflow: ellipsis; } /* --- DARK MODE --- */ @@ -152,6 +151,10 @@ color: #ccc; } +.darkMode .contactIcon { + color: #ccc; +} + .darkMode .skillsText { color: #dcdcdc; } diff --git a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/ProfileDetails.jsx b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/ProfileDetails.jsx index 705ee699c3d..e9a2c72cfd8 100644 --- a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/ProfileDetails.jsx +++ b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/ProfileDetails.jsx @@ -50,9 +50,6 @@ function ProfileDetails() { Years of Experience:{' '} - - {profileData.skillInfo?.general?.yearsOfExperience || 'N/A'} - {isEditing ? ( general?.leadership_skills || 0, description: 'Skills in team leadership and management', }, @@ -153,6 +154,7 @@ const SKILL_MAPPINGS = [ }, { label: 'Markdown & Graphs', + shortLabel: 'Markdown/Graphs', value: (general, frontend, backend) => frontend?.Documentation || general?.markdown_graphs || 0, description: 'Markdown writing and data visualization', }, @@ -234,7 +236,10 @@ function RadarChart({ profileData, compact = true, onSkillsDataReady }) { const { general = {}, frontend = {}, backend = {} } = profileData?.skillInfo || {}; const chartData = { - labels: skillsData.map(skill => (compact ? skill.shortLabel || skill.label : skill.label)), + // Always prefer the abbreviated label: with 28 dimensions, the wrap-around + // labels at the top (last <-> first) sit within a ~26deg arc and collide + // regardless of chart size, so shortening text is what actually buys room. + labels: skillsData.map(skill => skill.shortLabel || skill.label), datasets: [ { label: 'Skills', @@ -300,6 +305,7 @@ function RadarChart({ profileData, compact = true, onSkillsDataReady }) { }, pointLabels: { + centerPointLabels: true, font: { size: function(context) { const w = context.chart.width; @@ -321,7 +327,9 @@ function RadarChart({ profileData, compact = true, onSkillsDataReady }) { }, ticks: { stepSize: 2, - display: compact ? false : true, + // Always shown: the radial scale numbers are information, not chrome, + // so (like labels above) they shouldn't be gated behind compact. + display: true, color: darkMode ? '#dcdcdc' : '#666', font: { size: 10 }, backdropColor: darkMode ? '#1f1f1f' : '#ffffff', diff --git a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/ProfileDetails.test.jsx b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/ProfileDetails.test.jsx new file mode 100644 index 00000000000..3a4657b6f01 --- /dev/null +++ b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/ProfileDetails.test.jsx @@ -0,0 +1,61 @@ +import { render, screen } from '@testing-library/react'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import ProfileDetails from '../ProfileDetails'; + +const mockStore = configureMockStore([]); + +// Note: socialHandles fields are given real values (rather than left empty) +// so that 'N/A' only ever appears for the field under test here - Slack and +// GitHub also legitimately fall back to 'N/A' elsewhere on the page, which +// would otherwise make a page-wide 'N/A' query ambiguous. +const baseProfileData = { + userId: 'user-1', + loggedInUserId: 'someone-else', + teams: [], + skillInfo: { + general: { + yearsOfExperience: 12, + }, + }, + contactInfo: { + email: 'test@example.com', + phone: '555-1234', + }, + socialHandles: { + slack: '@testuser', + github: 'https://github.com/testuser', + }, +}; + +const renderWithStore = profileData => { + const store = mockStore({ + userSkills: { profileData }, + theme: { darkMode: false }, + }); + return render( + + + , + ); +}; + +describe('ProfileDetails - Years of Experience display', () => { + it('renders a numeric years-of-experience value exactly once, not doubled', () => { + renderWithStore(baseProfileData); + + expect(screen.getByText('12')).toBeInTheDocument(); + expect(screen.queryByText('1212')).not.toBeInTheDocument(); + }); + + it('renders "N/A" exactly once when no value is set, not doubled', () => { + const profileData = { + ...baseProfileData, + skillInfo: { general: { yearsOfExperience: '' } }, + }; + renderWithStore(profileData); + + expect(screen.getByText('N/A')).toBeInTheDocument(); + expect(screen.queryByText('N/AN/A')).not.toBeInTheDocument(); + }); +}); diff --git a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/RadarChart.test.jsx b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/RadarChart.test.jsx new file mode 100644 index 00000000000..8a05d2d18ed --- /dev/null +++ b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/RadarChart.test.jsx @@ -0,0 +1,55 @@ +import { render } from '@testing-library/react'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import RadarChart from '../RadarChart'; + +// react-chartjs-2 renders to a real , which jsdom doesn't implement. +// Capture the props chart.js would receive instead of rendering the chart. +let lastRadarProps; +vi.mock('react-chartjs-2', () => ({ + Radar: props => { + lastRadarProps = props; + return null; + }, +})); + +const mockStore = configureMockStore([]); + +const profileData = { + skillInfo: { + general: { leadership_experience: 5, leadership_skills: 6, markdown_graphs: 7 }, + frontend: {}, + backend: {}, + }, +}; + +const renderChart = compact => { + const store = mockStore({ theme: { darkMode: false } }); + render( + + + , + ); +}; + +describe('RadarChart', () => { + it('uses abbreviated labels even when compact is false, to avoid overlap at high dimension density', () => { + renderChart(false); + expect(lastRadarProps.data.labels).toContain('Leadership Skl'); + expect(lastRadarProps.data.labels).toContain('Markdown/Graphs'); + expect(lastRadarProps.data.labels).not.toContain('Leadership Skills'); + }); + + it('centers point labels between grid lines to reduce crowding near the wrap-around seam', () => { + renderChart(true); + expect(lastRadarProps.options.scales.r.pointLabels.centerPointLabels).toBe(true); + }); + + it('shows the radial scale numbers regardless of compact, so /hgn/profile/skills matches skills-overview', () => { + renderChart(true); + expect(lastRadarProps.options.scales.r.ticks.display).toBe(true); + + renderChart(false); + expect(lastRadarProps.options.scales.r.ticks.display).toBe(true); + }); +}); diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index 1d9caedad9d..45f9f937028 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -846,6 +846,16 @@ export function Header(props) { {canAccessUserManagement && {USER_MANAGEMENT}} {canAccessBadgeManagement && {BADGE_MANAGEMENT}} {canAccessProjects && {PROJECTS}} + {(canAccessProjects || canUpdateTask) && ( + + Resolved Tasks + + )} {canAccessTeams && {TEAMS}} {canAccessSendEmails && {SEND_EMAILS}} {canAccessScheduleMeetings && ( diff --git a/src/components/KitchenandInventory/KitchenReports/KitchenReports.jsx b/src/components/KitchenandInventory/KitchenReports/KitchenReports.jsx new file mode 100644 index 00000000000..8d0169b3c3d --- /dev/null +++ b/src/components/KitchenandInventory/KitchenReports/KitchenReports.jsx @@ -0,0 +1,92 @@ +import { useState } from 'react'; +import { useSelector } from 'react-redux'; +import styles from './KitchenReports.module.css'; +import { REPORT_TABS, DATE_RANGE_OPTIONS, EXPORT_ENDPOINTS_READY } from './kitchenReportsData'; +import useReportExport from './useReportExport'; + +const EXPORT_UNAVAILABLE_MESSAGE = + 'Export is unavailable until the backend export endpoints are deployed.'; + +export function KitchenReports() { + const darkMode = useSelector(state => state.theme.darkMode); + const dm = darkMode ? styles.dark : ''; + + const [activeTab, setActiveTab] = useState(REPORT_TABS[0].id); + const [dateRange, setDateRange] = useState(DATE_RANGE_OPTIONS[0].value); + const { exportReport, loadingFormat } = useReportExport(); + + const activeTabLabel = REPORT_TABS.find(tab => tab.id === activeTab)?.label; + + return ( +
+
+
+
+

Reports & Analytics

+

Comprehensive insights on usage, spending, waste, and sustainability

+
+ +
+ + + + + +
+
+ +
+ {REPORT_TABS.map(tab => ( + + ))} +
+ +
+ {activeTabLabel} content coming soon. +
+
+
+ ); +} + +export default KitchenReports; diff --git a/src/components/KitchenandInventory/KitchenReports/KitchenReports.module.css b/src/components/KitchenandInventory/KitchenReports/KitchenReports.module.css new file mode 100644 index 00000000000..110b43921dc --- /dev/null +++ b/src/components/KitchenandInventory/KitchenReports/KitchenReports.module.css @@ -0,0 +1,137 @@ +.pageWrapper { + min-height: 100vh; + width: 100%; + background-color: #fff; +} + +.pageWrapper.dark { + background-color: #1a1816; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 24px 16px; +} + +.header { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: flex-start; + gap: 16px; + margin-bottom: 20px; +} + +.titleBlock h1 { + font-size: 1.5rem; + font-weight: 700; + margin: 0 0 4px; + color: #1f2937; +} + +.titleBlock p { + margin: 0; + font-size: 0.9rem; + color: #6b7280; +} + +.dark .titleBlock h1 { + color: #f3f4f6; +} + +.dark .titleBlock p { + color: #9ca3af; +} + +.controls { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; +} + +.dateSelect { + padding: 8px 12px; + border-radius: 6px; + border: 1px solid #d1d5db; + background-color: #fff; + color: #1f2937; + font-size: 0.875rem; +} + +.dark .dateSelect { + background-color: #2a2622; + border-color: #4b4642; + color: #f3f4f6; +} + +.exportButton { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 8px 14px; + border-radius: 6px; + border: 1px solid #d1d5db; + background-color: #fff; + color: #1f2937; + font-size: 0.875rem; + cursor: pointer; +} + +.exportButton:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.dark .exportButton { + background-color: #2a2622; + border-color: #4b4642; + color: #f3f4f6; +} + +.tabs { + display: flex; + flex-wrap: wrap; + gap: 4px; + border-bottom: 1px solid #e5e7eb; + margin-bottom: 20px; +} + +.dark .tabs { + border-bottom-color: #3a3632; +} + +.tabButton { + padding: 10px 16px; + border: none; + background: none; + font-size: 0.875rem; + font-weight: 500; + color: #4b5563; + cursor: pointer; + border-bottom: 2px solid transparent; +} + +.tabButton.active { + color: #047857; + border-bottom-color: #047857; +} + +.dark .tabButton { + color: #9ca3af; +} + +.dark .tabButton.active { + color: #34d399; + border-bottom-color: #34d399; +} + +.tabPanel { + min-height: 200px; + color: #374151; +} + +.dark .tabPanel { + color: #d1d5db; +} diff --git a/src/components/KitchenandInventory/KitchenReports/kitchenReportsData.js b/src/components/KitchenandInventory/KitchenReports/kitchenReportsData.js new file mode 100644 index 00000000000..577f52df3ef --- /dev/null +++ b/src/components/KitchenandInventory/KitchenReports/kitchenReportsData.js @@ -0,0 +1,16 @@ +export const REPORT_TABS = [ + { id: 'overview', label: 'Overview' }, + { id: 'sustainability', label: 'Sustainability Dashboard' }, + { id: 'preservation', label: 'Preservation Efficiency' }, + { id: 'forecast', label: 'Forecast Accuracy' }, +]; + +export const DATE_RANGE_OPTIONS = [ + { value: 'thisMonth', label: 'This Month' }, + { value: 'lastMonth', label: 'Last Month' }, + { value: 'last3Months', label: 'Last 3 Months' }, + { value: 'thisYear', label: 'This Year' }, +]; + +// Flip to true once the backend /kitchenandinventory/reports/export/* routes exist in HGNRest. +export const EXPORT_ENDPOINTS_READY = false; diff --git a/src/components/KitchenandInventory/KitchenReports/useReportExport.js b/src/components/KitchenandInventory/KitchenReports/useReportExport.js new file mode 100644 index 00000000000..f50d86908e2 --- /dev/null +++ b/src/components/KitchenandInventory/KitchenReports/useReportExport.js @@ -0,0 +1,56 @@ +import { useCallback, useState } from 'react'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { ENDPOINTS } from '~/utils/URL'; + +const EXPORT_CONFIG = { + pdf: { + url: ENDPOINTS.KITCHEN_REPORTS_EXPORT_PDF, + mimeType: 'application/pdf', + fileName: 'report-overview.pdf', + }, + csv: { + url: ENDPOINTS.KITCHEN_REPORTS_EXPORT_CSV, + mimeType: 'text/csv', + fileName: 'report-overview.csv', + }, +}; + +export default function useReportExport() { + const [loadingFormat, setLoadingFormat] = useState(null); + + const exportReport = useCallback(async (format, dateRange) => { + const config = EXPORT_CONFIG[format]; + setLoadingFormat(format); + + try { + const response = await axios.get(config.url(), { + params: { dateRange }, + responseType: 'blob', + }); + + if (!response.data || response.data.size === 0) { + throw new Error('Received an empty report file.'); + } + + const blob = new Blob([response.data], { type: config.mimeType }); + const downloadUrl = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = downloadUrl; + link.download = config.fileName; + document.body.appendChild(link); + link.click(); + link.remove(); + setTimeout(() => window.URL.revokeObjectURL(downloadUrl), 100); + + toast.success(`${format.toUpperCase()} report downloaded successfully!`); + } catch (error) { + const message = error?.message || `Failed to export ${format.toUpperCase()} report.`; + toast.error(`${message} Please try again.`); + } finally { + setLoadingFormat(null); + } + }, []); + + return { exportReport, loadingFormat }; +} diff --git a/src/components/LandingPage/HelpModal.jsx b/src/components/LandingPage/HelpModal.jsx index c10a2f5f4ef..0603f2702cc 100644 --- a/src/components/LandingPage/HelpModal.jsx +++ b/src/components/LandingPage/HelpModal.jsx @@ -1,13 +1,64 @@ -import axios from 'axios'; import PropTypes from 'prop-types'; import { useEffect, useState } from 'react'; import { Button, Modal } from 'react-bootstrap'; import { connect, useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; import { toast } from 'react-toastify'; +import { availableSkills, formatSkillName } from '../HGNHelpSkillsDashboard/FilerData'; +import httpService from '../../services/httpService'; import { ENDPOINTS } from '~/utils/URL'; import styles from './HelpModal.module.css'; +const SOFTWARE_DEV_TEAM_ALIASES = new Set([ + 'software development team', + 'hgn software development team', +]); + +/** Maps common help-category labels to questionnaire skill keys. */ +const TOPIC_TO_SKILL_KEY = { + figma: 'UIUXTools', + 'ui/ux': 'UIUXTools', + 'frontend and backend overall': 'combined_frontend_backend', + 'frontend/backend': 'combined_frontend_backend', + mern: 'mern_skills', + leadership: 'leadership_skills', +}; + +const buildSkillFallbackOptions = () => + availableSkills.map(skillKey => ({ + value: skillKey, + label: formatSkillName(skillKey), + })); + +const normalizeCategoryOptions = categories => { + if (!Array.isArray(categories) || categories.length === 0) return []; + + return categories + .map(category => { + if (typeof category === 'string') { + return { value: category, label: category }; + } + const name = category?.name; + if (!name) return null; + return { value: name, label: name }; + }) + .filter(Boolean); +}; + +const resolveSkillKey = selectedTopic => { + if (!selectedTopic) return null; + if (availableSkills.includes(selectedTopic)) return selectedTopic; + + const byLabel = availableSkills.find( + skillKey => formatSkillName(skillKey).toLowerCase() === selectedTopic.toLowerCase(), + ); + if (byLabel) return byLabel; + + return TOPIC_TO_SKILL_KEY[selectedTopic.trim().toLowerCase()] || null; +}; + function HelpModal({ show, onHide, auth }) { + const history = useHistory(); const [selectedOption, setSelectedOption] = useState(''); const [isOpen, setIsOpen] = useState(false); const [options, setOptions] = useState([]); @@ -17,16 +68,29 @@ function HelpModal({ show, onHide, auth }) { const [isSubmitting, setIsSubmitting] = useState(false); const darkMode = useSelector(state => state.theme.darkMode); - const userId = auth?.user?.userid; useEffect(() => { const fetchHelpCategories = async () => { + setLoading(true); + setError(null); + try { - const categoriesResponse = await axios.get(ENDPOINTS.HELP_CATEGORIES); - setOptions(categoriesResponse.data.map(category => category.name)); + const categoriesResponse = await httpService.get(ENDPOINTS.HELP_CATEGORIES); + const apiOptions = normalizeCategoryOptions(categoriesResponse.data); + + if (apiOptions.length > 0) { + setOptions(apiOptions); + } else { + // DB may be empty — fall back to questionnaire skills so the dropdown is usable + setOptions(buildSkillFallbackOptions()); + } } catch { - setError('Failed to load help categories'); + // Still offer skill fallback, but surface that the categories endpoint failed. + setOptions(buildSkillFallbackOptions()); + setError( + 'Failed to load help categories from the server. Showing questionnaire skills instead.', + ); } finally { setLoading(false); } @@ -36,11 +100,11 @@ function HelpModal({ show, onHide, auth }) { }, []); useEffect(() => { - if (!userId) return; + if (!userId) return undefined; const fetchUserProfile = async () => { try { - const profileResponse = await axios.get(ENDPOINTS.USER_PROFILE(userId)); + const profileResponse = await httpService.get(ENDPOINTS.USER_PROFILE(userId)); setTeams(profileResponse.data?.teams || []); } catch { setTeams([]); @@ -48,10 +112,11 @@ function HelpModal({ show, onHide, auth }) { }; fetchUserProfile(); + return undefined; }, [userId]); - const handleSelect = option => { - setSelectedOption(option); + const handleSelect = optionValue => { + setSelectedOption(optionValue); setIsOpen(false); }; @@ -69,17 +134,29 @@ function HelpModal({ show, onHide, auth }) { setIsSubmitting(true); try { - await axios.post(ENDPOINTS.HELP_REQUEST_CREATE, { + await httpService.post(ENDPOINTS.HELP_REQUEST_CREATE, { userId, topic: selectedOption, description: `Help request for: ${selectedOption}`, }); toast.success('Help request submitted successfully!'); + + const helpTopic = selectedOption; + const selectedSkillKey = resolveSkillKey(helpTopic); + setSelectedOption(''); - onHide(); + + // Navigate to community helpers; do not call onHide() (HelpPage would redirect to dashboard). + history.push({ + pathname: '/hgnhelp/community', + state: { + initialSkills: selectedSkillKey ? [selectedSkillKey] : [], + softwareDevTeamOnly: true, + helpTopic, + }, + }); } catch (err) { - console.error('Help request submission error:', err); if (err.code === 'ERR_NETWORK' || !err.response) { toast.error('Cannot connect to server. Please ensure the backend is running.'); } else { @@ -97,23 +174,24 @@ function HelpModal({ show, onHide, auth }) { onHide(); }; - /* ---------------- Access Logic ---------------- */ const role = auth?.user?.role?.trim().toLowerCase() || ''; const isSoftwareDevMember = ['owner', 'administrator'].includes(role) || - teams.some(team => - ['software development team', 'hgn software development team'].includes( - team.teamName?.trim().toLowerCase(), - ), - ); + teams.some(team => SOFTWARE_DEV_TEAM_ALIASES.has(team.teamName?.trim().toLowerCase())); + + const selectedLabel = + options.find(option => option.value === selectedOption)?.label || selectedOption; const renderContent = () => { if (loading) return
Loading categories...
; - if (error) return
{error}
; + if (!options.length) { + return
{error || 'No help categories available.'}
; + } return ( <> + {error &&
{error}
}
setIsOpen(!isOpen)} @@ -130,7 +208,7 @@ function HelpModal({ show, onHide, auth }) { ${darkMode && selectedOption ? styles.selectedDark : ''} `} > - {selectedOption || 'Select an option'} + {selectedLabel || 'Select an option'} {options.map(option => (
handleSelect(option)} + onClick={() => handleSelect(option.value)} role="option" tabIndex={0} onKeyDown={e => { - if (e.key === 'Enter' || e.key === ' ') handleSelect(option); + if (e.key === 'Enter' || e.key === ' ') handleSelect(option.value); }} - aria-selected={selectedOption === option} + aria-selected={selectedOption === option.value} > - {option} + {option.label}
))}
@@ -211,7 +289,6 @@ function HelpModal({ show, onHide, auth }) { ); } -/* ---------------- PropTypes ---------------- */ HelpModal.propTypes = { show: PropTypes.bool.isRequired, onHide: PropTypes.func.isRequired, diff --git a/src/components/LandingPage/__tests__/HelpModal.test.jsx b/src/components/LandingPage/__tests__/HelpModal.test.jsx index 6783dc29783..bfa3e6cc801 100644 --- a/src/components/LandingPage/__tests__/HelpModal.test.jsx +++ b/src/components/LandingPage/__tests__/HelpModal.test.jsx @@ -2,16 +2,22 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import axios from 'axios'; +import { MemoryRouter } from 'react-router-dom'; import { ENDPOINTS } from '~/utils/URL'; +import httpService from '../../../services/httpService'; import HelpModal from '../HelpModal'; import styles from '../HelpModal.module.css'; -vi.mock('axios'); +vi.mock('../../../services/httpService', () => ({ + default: { + get: vi.fn(), + post: vi.fn(), + }, +})); test('supports an HGN software team volunteer in dark mode', async () => { const userId = 'test-user'; - axios.get.mockImplementation(url => { + httpService.get.mockImplementation(url => { if (url === ENDPOINTS.HELP_CATEGORIES) { return Promise.resolve({ data: [{ name: 'Software Support' }] }); } @@ -29,7 +35,9 @@ test('supports an HGN software team volunteer in dark mode', async () => { render( - + + + , ); @@ -40,5 +48,5 @@ test('supports an HGN software team volunteer in dark mode', async () => { await userEvent.click(screen.getByRole('option', { name: 'Software Support' })); await waitFor(() => expect(screen.getByRole('button', { name: 'Submit' })).toBeEnabled()); - expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.USER_PROFILE(userId)); + expect(httpService.get).toHaveBeenCalledWith(ENDPOINTS.USER_PROFILE(userId)); }); diff --git a/src/components/MostWastedMaterials/MostWastedMaterials.jsx b/src/components/MostWastedMaterials/MostWastedMaterials.jsx index 050bb64bf8e..62095a21340 100644 --- a/src/components/MostWastedMaterials/MostWastedMaterials.jsx +++ b/src/components/MostWastedMaterials/MostWastedMaterials.jsx @@ -223,6 +223,7 @@ export default function MostWastedMaterials() { id="mw-from" type="date" value={dateRange.from} + max={dateRange.to} onChange={e => setDateRange(r => ({ ...r, from: e.target.value }))} className={styles.input} /> @@ -236,6 +237,7 @@ export default function MostWastedMaterials() { id="mw-to" type="date" value={dateRange.to} + min={dateRange.from} onChange={e => setDateRange(r => ({ ...r, to: e.target.value }))} className={styles.input} /> diff --git a/src/components/PRGradingDashboard/GradingTable.jsx b/src/components/PRGradingDashboard/GradingTable.jsx index 156b769640a..beb5d1bd443 100644 --- a/src/components/PRGradingDashboard/GradingTable.jsx +++ b/src/components/PRGradingDashboard/GradingTable.jsx @@ -10,7 +10,10 @@ function GradingTable({ onAddPRClick, openAddModal, onAddGradedPR, + onRemoveReviewer, + isCurrentWeek, darkMode, + canEdit, }) { return ( //
@@ -30,7 +33,10 @@ function GradingTable({ grading={grading} onUpdatePRsReviewed={onUpdatePRsReviewed} onAddPRClick={onAddPRClick} + onRemoveReviewer={onRemoveReviewer} + isCurrentWeek={isCurrentWeek} darkMode={darkMode} + canEdit={canEdit} /> {openAddModal === grading.reviewer && ( @@ -62,12 +68,17 @@ GradingTable.propTypes = { onAddPRClick: PropTypes.func.isRequired, openAddModal: PropTypes.string, onAddGradedPR: PropTypes.func.isRequired, + onRemoveReviewer: PropTypes.func.isRequired, + isCurrentWeek: PropTypes.bool, darkMode: PropTypes.bool, + canEdit: PropTypes.bool, }; GradingTable.defaultProps = { openAddModal: null, + isCurrentWeek: true, darkMode: false, + canEdit: false, }; export default GradingTable; diff --git a/src/components/PRGradingDashboard/PRGradingDashboard.jsx b/src/components/PRGradingDashboard/PRGradingDashboard.jsx index 82e8a9afe38..6c075ebbcc1 100644 --- a/src/components/PRGradingDashboard/PRGradingDashboard.jsx +++ b/src/components/PRGradingDashboard/PRGradingDashboard.jsx @@ -1,18 +1,57 @@ import axios from 'axios'; import { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { toast } from 'react-toastify'; import AddReviewerModal from './AddReviewerModal'; import ConfirmationModal from './ConfirmationModal'; import GradingTable from './GradingTable'; +import RemoveReviewerModal from './RemoveReviewerModal'; import { MOCK_WEEK_METADATA, MOCK_WEEK_OPTIONS } from './mockWeeklyAuditData'; import styles from './PRGradingDashboard.module.css'; import { SelectionProvider } from './SelectionContext'; import SummaryList from './SummaryList'; +import hasPermission from '~/utils/permissions'; -const TEAM_CODE = 'TeamA'; const TEAM_NAME = 'Team Alpha'; +const formatLocalDate = date => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +}; + +const getWeekStart = () => { + const now = new Date(); + const day = now.getDay(); + const monday = new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() - day + (day === 0 ? -6 : 1), + ); + return formatLocalDate(monday); +}; + +const WEEK_OPTION_OFFSETS = { + 'Current Week': 0, + '1 Week Ago': 1, + '2 Weeks Ago': 2, + '3 Weeks Ago': 3, + '4 Weeks Ago': 4, +}; + +const getWeekStartByOffset = weeksAgo => { + const now = new Date(); + const day = now.getDay(); + const mondayOffset = day === 0 ? -6 : 1 - day; + const monday = new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() + mondayOffset - weeksAgo * 7, + ); + return formatLocalDate(monday); +}; + // Mock data for fallback const mockData = [ { @@ -36,7 +75,10 @@ const mockData = [ ]; function PRGradingDashboard() { + const dispatch = useDispatch(); const darkMode = useSelector(state => state.theme.darkMode); + const authUser = useSelector(state => state.auth.user); + const canEdit = dispatch(hasPermission('accessPRTeamDashboard')); const [gradings, setGradings] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); @@ -44,18 +86,22 @@ function PRGradingDashboard() { const [pendingPR, setPendingPR] = useState(null); // { reviewer, prNumbers, grade } or null const [showConfirmation, setShowConfirmation] = useState(false); const [showAddReviewerModal, setShowAddReviewerModal] = useState(false); + const [pendingRemoveReviewer, setPendingRemoveReviewer] = useState(null); // reviewer name or null const [selectedMockWeek, setSelectedMockWeek] = useState('Current Week'); + const [selectedTeam, setSelectedTeam] = useState('TeamA'); - // Fetch data on mount + // Fetch data on mount and whenever the selected week changes useEffect(() => { - fetchGradings(); - }, []); + void fetchGradings(selectedMockWeek); + }, [selectedMockWeek]); - const fetchGradings = async () => { + const fetchGradings = async (weekLabel = 'Current Week') => { + const offset = WEEK_OPTION_OFFSETS[weekLabel] ?? 0; + const weekDate = getWeekStartByOffset(offset); try { setLoading(true); const response = await axios.get( - `${process.env.REACT_APP_APIENDPOINT}/weekly-grading?team=${TEAM_CODE}`, + `${process.env.REACT_APP_APIENDPOINT}/weekly-grading?team=${selectedTeam}&date=${weekDate}`, ); if (response.data && Array.isArray(response.data)) { // Mark all existing PRs as not new @@ -153,6 +199,39 @@ function PRGradingDashboard() { toast.success(`Reviewer "${newReviewer.reviewer}" added successfully.`); }; + // Request to remove a reviewer (shows confirmation modal) + const requestRemoveReviewer = reviewer => { + setPendingRemoveReviewer(reviewer); + }; + + // Actually remove the reviewer after confirmation + const confirmRemoveReviewer = async () => { + if (!pendingRemoveReviewer) return; + const offset = WEEK_OPTION_OFFSETS[selectedMockWeek] ?? 0; + const weekDate = getWeekStartByOffset(offset); + try { + await axios.delete( + `${ + process.env.REACT_APP_APIENDPOINT + }/weekly-grading?team=${selectedTeam}&date=${weekDate}&reviewer=${encodeURIComponent( + pendingRemoveReviewer, + )}`, + { data: { requestor: { requestorId: authUser.userid } } }, + ); + setGradings(prev => prev.filter(g => g.reviewer !== pendingRemoveReviewer)); + toast.success(`Reviewer "${pendingRemoveReviewer}" removed successfully.`); + } catch (error) { + toast.error('Failed to remove reviewer. Please try again.'); + } finally { + setPendingRemoveReviewer(null); + } + }; + + // Cancel reviewer removal + const cancelRemoveReviewer = () => { + setPendingRemoveReviewer(null); + }; + // Remove a graded PR (only new ones) const removeGradedPR = (reviewer, prIndex) => { // Check if PR can be removed before updating state @@ -191,12 +270,11 @@ function PRGradingDashboard() { const handleSave = async () => { try { setSaving(true); - const currentDate = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format - // Remove isNew flag before sending to API + const offset = WEEK_OPTION_OFFSETS[selectedMockWeek] ?? 0; const payload = { - teamCode: TEAM_CODE, - date: currentDate, + teamCode: selectedTeam, + date: getWeekStartByOffset(offset), gradings: gradings.map(g => ({ reviewer: g.reviewer, prsReviewed: g.prsReviewed, @@ -225,6 +303,8 @@ function PRGradingDashboard() { } }; + const isCurrentWeek = (WEEK_OPTION_OFFSETS[selectedMockWeek] ?? 0) === 0; + const currentDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', @@ -279,22 +359,27 @@ function PRGradingDashboard() { {/* Main Table */}
-
- -
+ {isCurrentWeek && ( +
+ +
+ )}
@@ -311,16 +396,18 @@ function PRGradingDashboard() { {/* Footer */} -
- -
+ {isCurrentWeek && ( +
+ +
+ )}
{/* Confirmation Modal */} @@ -334,6 +421,15 @@ function PRGradingDashboard() { /> )} + {/* Remove Reviewer Modal */} + {pendingRemoveReviewer && ( + + )} + {/* Add Reviewer Modal */} {showAddReviewerModal && ( setShowAddReviewerModal(false)} /> diff --git a/src/components/PRGradingDashboard/RemoveReviewerModal.jsx b/src/components/PRGradingDashboard/RemoveReviewerModal.jsx new file mode 100644 index 00000000000..ce33d180797 --- /dev/null +++ b/src/components/PRGradingDashboard/RemoveReviewerModal.jsx @@ -0,0 +1,85 @@ +import { useEffect } from 'react'; +import { Trash2, X } from 'lucide-react'; +import styles from './ConfirmationModal.module.css'; + +function RemoveReviewerModal({ reviewer, onConfirm, onCancel }) { + useEffect(() => { + const handleEscape = e => { + if (e.key === 'Escape') onCancel(); + }; + document.addEventListener('keydown', handleEscape); + return () => document.removeEventListener('keydown', handleEscape); + }, [onCancel]); + + const handleOverlayClick = e => { + if (e.target === e.currentTarget) onCancel(); + }; + + const handleOverlayKeyDown = e => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + onCancel(); + } + }; + + return ( +
+
+
+

+ Remove Reviewer +

+ +
+
+
+ +
+

+ Remove reviewer {reviewer} from this week? +

+

+ Their past PR review history will remain visible in analytics. +

+
+
+ + +
+
+
+ ); +} + +export default RemoveReviewerModal; diff --git a/src/components/PRGradingDashboard/ReviewerRow.jsx b/src/components/PRGradingDashboard/ReviewerRow.jsx index 6a7c197ec7d..55cfa0a001f 100644 --- a/src/components/PRGradingDashboard/ReviewerRow.jsx +++ b/src/components/PRGradingDashboard/ReviewerRow.jsx @@ -1,9 +1,17 @@ -import { Plus } from 'lucide-react'; +import { Plus, Trash2 } from 'lucide-react'; import PropTypes from 'prop-types'; import styles from './ReviewerRow.module.css'; import { useRowSelection } from './SelectionContext'; -function ReviewerRow({ grading, onUpdatePRsReviewed, onAddPRClick, darkMode }) { +function ReviewerRow({ + grading, + onUpdatePRsReviewed, + onAddPRClick, + onRemoveReviewer, + isCurrentWeek, + darkMode, + canEdit, +}) { const { activeId, selectRow } = useRowSelection(); const handlePRsReviewedChange = e => { @@ -49,14 +57,29 @@ function ReviewerRow({ grading, onUpdatePRsReviewed, onAddPRClick, darkMode }) {
{grading.prsNeeded}
- + {isCurrentWeek && canEdit ? ( +
+ + +
+ ) : ( + Read only + )} ); @@ -69,11 +92,16 @@ ReviewerRow.propTypes = { }).isRequired, onUpdatePRsReviewed: PropTypes.func.isRequired, onAddPRClick: PropTypes.func.isRequired, + onRemoveReviewer: PropTypes.func.isRequired, + isCurrentWeek: PropTypes.bool, darkMode: PropTypes.bool, + canEdit: PropTypes.bool, }; ReviewerRow.defaultProps = { + isCurrentWeek: true, darkMode: false, + canEdit: false, }; export default ReviewerRow; diff --git a/src/components/PRGradingDashboard/ReviewerRow.module.css b/src/components/PRGradingDashboard/ReviewerRow.module.css index 5bb515de925..83e1af3de21 100644 --- a/src/components/PRGradingDashboard/ReviewerRow.module.css +++ b/src/components/PRGradingDashboard/ReviewerRow.module.css @@ -73,6 +73,47 @@ margin-right: 0.5rem; } +.actionsCell { + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.removeButton { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.5rem; + background-color: transparent; + color: #6b7280; + border: 1px solid #d1d5db; + border-radius: 0.375rem; + cursor: pointer; + transition: all 0.2s; +} + +.removeButton:hover { + background-color: #fef2f2; + color: #dc2626; + border-color: #fca5a5; +} + +.removeButton:focus { + outline: none; + box-shadow: 0 0 0 2px rgb(220 38 38 / 50%); +} + +.removeButtonIcon { + width: 1rem; + height: 1rem; +} + +.readOnlyLabel { + font-size: 0.75rem; + color: #9ca3af; + font-style: italic; +} + /* Dark mode support */ :global(.dark-mode) .row:hover { background-color: #374151; @@ -108,4 +149,15 @@ :global(.dark-mode) .addButton:focus { box-shadow: 0 0 0 2px rgb(37 99 235 / 50%), 0 0 0 4px rgb(37 99 235 / 10%); +} + +:global(.dark-mode) .removeButton { + color: #9ca3af; + border-color: #4b5563; +} + +:global(.dark-mode) .removeButton:hover { + background-color: #450a0a; + color: #f87171; + border-color: #991b1b; } \ No newline at end of file diff --git a/src/components/PRGradingScreen/PRGradingScreen.duplicates.test.jsx b/src/components/PRGradingScreen/PRGradingScreen.duplicates.test.jsx new file mode 100644 index 00000000000..c67eabfdf09 --- /dev/null +++ b/src/components/PRGradingScreen/PRGradingScreen.duplicates.test.jsx @@ -0,0 +1,196 @@ +import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'; +import axios from 'axios'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import PRGradingScreen from './PRGradingScreen'; + +vi.mock('axios'); +vi.mock('react-redux', () => ({ + useSelector: selector => selector({ theme: { darkMode: false } }), +})); + +const teamData = { + teamName: 'Test Team', + dateRange: { start: '5/18/2025', end: '5/25/2025' }, +}; +const reviewers = [ + { + id: '1', + reviewer: 'Alice', + prsNeeded: 3, + gradedPrs: [{ id: 'pr1', prNumbers: '1234 + 5678', grade: 'Okay' }], + }, + { id: '2', reviewer: 'Bob', prsNeeded: 3, gradedPrs: [] }, +]; + +const addPR = async (row, numbers) => { + const addNewButton = within(row).getByRole('button', { name: '+ Add new' }); + await waitFor(() => expect(addNewButton).toBeEnabled()); + fireEvent.click(addNewButton); + fireEvent.change(within(row).getByPlaceholderText('1070 or 1070 + 1256'), { + target: { value: numbers }, + }); + fireEvent.click(within(row).getByRole('button', { name: 'Add' })); + await waitFor(() => + expect(within(row).queryByRole('button', { name: 'Adding...' })).not.toBeInTheDocument(), + ); +}; + +describe('Weekly PR grading duplicate entries', () => { + beforeEach(() => { + vi.clearAllMocks(); + axios.get.mockResolvedValue({ data: [] }); + axios.post.mockResolvedValue({ data: { status: 'ok' } }); + }); + + it('allows a pair containing two unused PR numbers and counts it as one review', async () => { + render(); + const aliceRow = screen.getByRole('row', { name: /Alice/ }); + + await addPR(aliceRow, '9981 + 9982'); + + expect(within(aliceRow).getByText('9981 + 9982')).toBeInTheDocument(); + expect(within(aliceRow).getByRole('spinbutton')).toHaveValue(2); + expect(screen.queryByRole('alert')).not.toBeInTheDocument(); + }); + + it('rejects a PR already present inside a pair for the same reviewer', async () => { + render(); + const aliceRow = screen.getByRole('row', { name: /Alice/ }); + + await addPR(aliceRow, '5678 + 9999'); + + expect(screen.getByRole('alert')).toHaveTextContent('already been added'); + expect(within(aliceRow).getByRole('spinbutton')).toHaveValue(1); + expect(within(aliceRow).queryByText('5678 + 9999')).not.toBeInTheDocument(); + }); + + it('rejects a repeated number within a new pair', async () => { + render(); + const aliceRow = screen.getByRole('row', { name: /Alice/ }); + + await addPR(aliceRow, '4321 + 4321'); + + expect(screen.getByRole('alert')).toHaveTextContent('already been added'); + expect(within(aliceRow).getByRole('spinbutton')).toHaveValue(1); + }); + + it('rejects a repeated addition but allows another reviewer to use that PR number', async () => { + render(); + const aliceRow = screen.getByRole('row', { name: /Alice/ }); + const bobRow = screen.getByRole('row', { name: /Bob/ }); + + await addPR(aliceRow, '4321'); + await addPR(aliceRow, '4321'); + + expect(screen.getByRole('alert')).toHaveTextContent('already been added'); + expect(within(aliceRow).getByRole('spinbutton')).toHaveValue(2); + + await addPR(bobRow, '4321'); + expect(within(bobRow).getByRole('spinbutton')).toHaveValue(1); + }); + + it('loads a saved PR again after the screen is remounted', async () => { + axios.get + .mockResolvedValueOnce({ data: [] }) + .mockResolvedValueOnce({ data: [] }) + .mockResolvedValueOnce({ + data: [ + { + reviewer: 'Alice', + gradedPrs: [{ _id: 'saved1', prNumbers: '9981', grade: 'Okay' }], + }, + ], + }); + const { unmount } = render(); + await addPR(screen.getByRole('row', { name: /Alice/ }), '9981'); + unmount(); + + render(); + const aliceRow = screen.getByRole('row', { name: /Alice/ }); + await waitFor(() => expect(within(aliceRow).getByText('9981')).toBeInTheDocument()); + expect(within(aliceRow).getByRole('spinbutton')).toHaveValue(2); + }); + + it('keeps the input open when saving fails instead of showing an unsaved PR', async () => { + axios.post.mockRejectedValueOnce(new Error('Network error')); + render(); + const aliceRow = screen.getByRole('row', { name: /Alice/ }); + + await addPR(aliceRow, '9981'); + + expect(within(aliceRow).getByRole('alert')).toHaveTextContent('Could not save'); + expect(within(aliceRow).getByRole('spinbutton')).toHaveValue(1); + expect(within(aliceRow).queryByText('9981')).not.toBeInTheDocument(); + }); + + it('saves a changed grade and restores it after remounting', async () => { + axios.get.mockResolvedValueOnce({ data: [] }).mockResolvedValueOnce({ + data: [ + { + reviewer: 'Alice', + gradedPrs: [{ prNumbers: '1234 + 5678', grade: 'Exceptional' }], + }, + ], + }); + const { unmount } = render(); + await waitFor(() => + expect( + within(screen.getByRole('row', { name: /Alice/ })).getByText('+ Add new'), + ).toBeEnabled(), + ); + fireEvent.click(within(screen.getByRole('row', { name: /Alice/ })).getByText('1234 + 5678')); + fireEvent.click(screen.getAllByRole('checkbox')[0]); + + await waitFor(() => expect(axios.post).toHaveBeenCalledTimes(1)); + expect(axios.post.mock.calls[0][1].gradings[0].gradedPrs).toEqual([ + { prNumbers: '1234 + 5678', grade: 'Exceptional' }, + ]); + await waitFor(() => expect(screen.getAllByRole('checkbox')[0]).toBeChecked()); + unmount(); + + render(); + await waitFor(() => expect(axios.get).toHaveBeenCalledTimes(2)); + fireEvent.click(within(screen.getByRole('row', { name: /Alice/ })).getByText('1234 + 5678')); + await waitFor(() => expect(screen.getAllByRole('checkbox')[0]).toBeChecked()); + expect(within(screen.getByRole('row', { name: /Alice/ })).getByRole('spinbutton')).toHaveValue( + 1, + ); + }); + + it('keeps the previous grade and shows an error if saving fails', async () => { + axios.post.mockRejectedValueOnce(new Error('Network error')); + render(); + await waitFor(() => + expect( + within(screen.getByRole('row', { name: /Alice/ })).getByText('+ Add new'), + ).toBeEnabled(), + ); + fireEvent.click(within(screen.getByRole('row', { name: /Alice/ })).getByText('1234 + 5678')); + fireEvent.click(screen.getAllByRole('checkbox')[0]); + + expect(await screen.findByRole('alert')).toHaveTextContent('Could not save this grade'); + expect(axios.post.mock.calls[0][1].gradings[0].gradedPrs).toEqual([ + { prNumbers: '1234 + 5678', grade: 'Exceptional' }, + ]); + expect(screen.getAllByRole('checkbox')[0]).not.toBeChecked(); + expect(screen.getAllByRole('checkbox')[1]).toBeChecked(); + }); + + it('sends the backend-supported value for Cannot find image', async () => { + render(); + await waitFor(() => + expect( + within(screen.getByRole('row', { name: /Alice/ })).getByText('+ Add new'), + ).toBeEnabled(), + ); + fireEvent.click(within(screen.getByRole('row', { name: /Alice/ })).getByText('1234 + 5678')); + fireEvent.click(screen.getAllByRole('checkbox')[3]); + + await waitFor(() => + expect(axios.post.mock.calls[0][1].gradings[0].gradedPrs).toEqual([ + { prNumbers: '1234 + 5678', grade: 'No Correct Image' }, + ]), + ); + await waitFor(() => expect(screen.getAllByRole('checkbox')[3]).toBeChecked()); + }); +}); diff --git a/src/components/PRGradingScreen/PRGradingScreen.jsx b/src/components/PRGradingScreen/PRGradingScreen.jsx index 1145610706f..489a6adf9b3 100644 --- a/src/components/PRGradingScreen/PRGradingScreen.jsx +++ b/src/components/PRGradingScreen/PRGradingScreen.jsx @@ -1,53 +1,93 @@ -import React, { useMemo, useState } from 'react'; import PropTypes from 'prop-types'; -import { Button, Card, Col, Container, Row } from 'react-bootstrap'; +import { useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { v4 as uuidv4 } from 'uuid'; -import styles from './PRGradingScreen.module.css'; -import InlinePRSummary from './InlinePRSummary'; -// Shared with InlinePRSummary so both tables stay in sync. See gradeOptions.js. -import GRADE_OPTIONS from './gradeOptions'; +import PRGradingView from './PRGradingView'; +import { + loadSavedGradings, + mergeSavedGradings, + saveAddedPR, + saveGradeChange, +} from './prGradingPersistence'; +import { usePRPromotion } from './usePRPromotion'; + +const hasDuplicatePR = (gradedPrs, value) => { + const enteredNumbers = value.split('+').map(number => number.trim()); + const existingNumbers = new Set( + gradedPrs.flatMap(pr => pr.prNumbers.split('+').map(number => number.trim())), + ); + return ( + new Set(enteredNumbers).size !== enteredNumbers.length || + enteredNumbers.some(number => existingNumbers.has(number)) + ); +}; const PRGradingScreen = ({ teamData, reviewers }) => { const darkMode = useSelector(state => state.theme.darkMode); - const [reviewerData, setReviewerData] = useState(reviewers || []); const [activeInput, setActiveInput] = useState(null); const [inputValue, setInputValue] = useState(''); const [inputError, setInputError] = useState(''); const [showGradingModal, setShowGradingModal] = useState(null); const [isFinalized, setIsFinalized] = useState(false); - - // Search state + const [isLoadingSaved, setIsLoadingSaved] = useState(true); + const [isSavingPR, setIsSavingPR] = useState(false); + const [isSavingGrade, setIsSavingGrade] = useState(false); + const [gradeError, setGradeError] = useState(''); + const [loadError, setLoadError] = useState(''); const [searchTerm, setSearchTerm] = useState(''); const [roleFilter, setRoleFilter] = useState(''); - /* ---------------- SEARCH FILTER ---------------- */ + const { + promotingReviewer, + promotedReviewerIds, + handlePromoteClick, + handleConfirmPromotion, + handleCancelPromotion, + } = usePRPromotion(teamData?.teamName); + + useEffect(() => { + if (!teamData || !reviewers) return undefined; + let active = true; + setIsLoadingSaved(true); + loadSavedGradings(teamData) + .then(saved => { + if (active) { + setReviewerData(mergeSavedGradings(reviewers, saved)); + setLoadError(''); + } + }) + .catch(() => { + if (active) setLoadError('Could not load saved PRs. Try again before adding a PR.'); + }) + .finally(() => { + if (active) setIsLoadingSaved(false); + }); + return () => { + active = false; + }; + }, [teamData, reviewers]); const availableRoles = useMemo(() => { - const roles = reviewerData.map(r => r.role).filter(Boolean); + const roles = reviewerData.map(reviewer => reviewer.role).filter(Boolean); return [...new Set(roles)]; }, [reviewerData]); - const filteredReviewers = useMemo(() => { - return reviewerData.filter(r => { - const nameMatch = r.reviewer.toLowerCase().includes(searchTerm.toLowerCase()); - const roleMatch = roleFilter ? r.role === roleFilter : true; - return nameMatch && roleMatch; - }); - }, [reviewerData, searchTerm, roleFilter]); + const filteredReviewers = useMemo( + () => + reviewerData.filter(reviewer => { + const nameMatch = reviewer.reviewer.toLowerCase().includes(searchTerm.toLowerCase()); + const roleMatch = roleFilter ? reviewer.role === roleFilter : true; + return nameMatch && roleMatch; + }), + [reviewerData, searchTerm, roleFilter], + ); const handleClearSearch = () => { setSearchTerm(''); setRoleFilter(''); }; - if (!teamData || !reviewers) { - return
Error: Missing required props
; - } - - /* ---------------- VALIDATION ---------------- */ - const validatePRNumber = value => { const trimmed = value.trim(); const pattern = /^\d+(\s*\+\s*\d+)?$/; @@ -56,300 +96,153 @@ const PRGradingScreen = ({ teamData, reviewers }) => { return { isValid: true, error: '' }; }; - /* ---------------- ADD PR ---------------- */ - const handleAddNewClick = reviewerId => { - if (isFinalized) return; + if (isFinalized || isLoadingSaved || loadError) return; setActiveInput(reviewerId); setInputValue(''); setInputError(''); }; - const handleInputSubmit = reviewerId => { - if (isFinalized) return; + const handleInputSubmit = async reviewerId => { + if (isFinalized || isLoadingSaved || isSavingPR || loadError) return; const validation = validatePRNumber(inputValue); if (!validation.isValid) { setInputError(validation.error); return; } - const newPREntry = { id: uuidv4(), prNumbers: inputValue.trim(), grade: 'Okay' }; - setReviewerData(prev => - prev.map(r => - r.id === reviewerId - ? { ...r, gradedPrs: [...r.gradedPrs, newPREntry], prsReviewed: r.gradedPrs.length + 1 } - : r, - ), - ); - setActiveInput(null); - setInputValue(''); - setInputError(''); + const reviewer = reviewerData.find(item => item.id === reviewerId); + if (!reviewer) return; + if (hasDuplicatePR(reviewer.gradedPrs, inputValue)) { + setInputError('This PR number has already been added for this reviewer.'); + return; + } + + setIsSavingPR(true); + try { + const saved = await loadSavedGradings(teamData); + const currentReviewers = mergeSavedGradings(reviewerData, saved); + const currentReviewer = currentReviewers.find(item => item.id === reviewerId); + if (!currentReviewer) return; + if (hasDuplicatePR(currentReviewer.gradedPrs, inputValue)) { + setReviewerData(currentReviewers); + setInputError('This PR number has already been added for this reviewer.'); + return; + } + + const prNumbers = inputValue.trim(); + await saveAddedPR(teamData, currentReviewer, prNumbers); + const newPREntry = { id: uuidv4(), prNumbers, grade: 'Okay' }; + setReviewerData( + currentReviewers.map(item => + item.id === reviewerId + ? { + ...item, + gradedPrs: [...item.gradedPrs, newPREntry], + prsReviewed: item.gradedPrs.length + 1, + } + : item, + ), + ); + setActiveInput(null); + setInputValue(''); + setInputError(''); + } catch { + setInputError('Could not save this PR. Please try again.'); + } finally { + setIsSavingPR(false); + } }; - const handleCancel = () => { - if (isFinalized) return; + const handleCancelInput = () => { + if (isFinalized || isSavingPR) return; setActiveInput(null); setInputValue(''); setInputError(''); }; - /* ---------------- MODAL ---------------- */ - const handlePRNumberClick = reviewerId => { - if (isFinalized) return; + if (isFinalized || isLoadingSaved || loadError) return; + setGradeError(''); setShowGradingModal(reviewerId); }; - const handleGradeChange = (reviewerId, prId, newGrade) => { - if (isFinalized) return; - setReviewerData(prev => - prev.map(r => - r.id === reviewerId - ? { - ...r, - gradedPrs: r.gradedPrs.map(pr => (pr.id === prId ? { ...pr, grade: newGrade } : pr)), - } - : r, - ), - ); + const handleGradeChange = async (reviewerId, prId, newGrade) => { + if (isFinalized || isLoadingSaved || isSavingGrade || loadError) return; + const reviewer = reviewerData.find(item => item.id === reviewerId); + const pr = reviewer?.gradedPrs.find(item => item.id === prId); + if (!pr || pr.grade === newGrade) return; + + setIsSavingGrade(true); + setGradeError(''); + try { + const savedGrade = newGrade === 'Cannot find image' ? 'No Correct Image' : newGrade; + await saveGradeChange(teamData, reviewer, pr.prNumbers, savedGrade); + setReviewerData(prev => + prev.map(item => + item.id === reviewerId + ? { + ...item, + gradedPrs: item.gradedPrs.map(gradedPR => + gradedPR.id === prId ? { ...gradedPR, grade: newGrade } : gradedPR, + ), + } + : item, + ), + ); + } catch { + setGradeError('Could not save this grade. Please try again.'); + } finally { + setIsSavingGrade(false); + } }; - const handleCloseGradingModal = () => setShowGradingModal(null); - const handleFinalize = () => setIsFinalized(true); - - /* ---------------- RENDER ---------------- */ + const handleCloseGradingModal = () => { + if (isSavingGrade) return; + setShowGradingModal(null); + setGradeError(''); + }; - const dm = darkMode ? styles['dark-mode'] : ''; + if (!teamData || !reviewers) return
Error: Missing required props
; return ( - - - - - -
-
-

- Weekly PR grading screen -

-
- {teamData.teamName} - {teamData.dateRange.start} to {teamData.dateRange.end} -
-
- -
-
- - - {/* ── Search Bar ── */} -
- setSearchTerm(e.target.value)} - className={`${styles['pr-grading-screen-search-input']} ${dm}`} - /> - - {availableRoles.length > 0 && ( - - )} - - {(searchTerm || roleFilter) && ( - - )} -
- - - - - - - - - - - - - {filteredReviewers.length === 0 ? ( - - - - ) : ( - /* Render each reviewer row followed by its inline summary component using React.Fragment */ - filteredReviewers.map(reviewer => ( - - - - - - - - - - - - - )) - )} - -
Reviewer NamePR reviewedPRs NeededPR Numbers
- No reviewers found -
{reviewer.reviewer} - - {reviewer.prsNeeded} - {reviewer.gradedPrs.map(pr => ( - handlePRNumberClick(reviewer.id)} - onKeyDown={e => { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - handlePRNumberClick(reviewer.id); - } - }} - > - {pr.prNumbers} - - ))} - - {!isFinalized && activeInput !== reviewer.id && ( - - )} - - {!isFinalized && activeInput === reviewer.id && ( -
- setInputValue(e.target.value)} - className={styles['pr-grading-screen-pr-number-input']} - placeholder="1070 or 1070 + 1256" - /> - - -
- )} -
-
-
- -
- - {showGradingModal && ( -
-
-
-

Grade PR

- -
- -
- - - {/* Rendered from GRADE_OPTIONS rather than hardcoded, so these - columns always match the inline summary's. */} - - - {GRADE_OPTIONS.map(opt => ( - - ))} - - - - {reviewerData - .find(r => r.id === showGradingModal) - ?.gradedPrs.map(pr => ( - - - {/* One cell per grade, driven by the shared list. The - value written here and the one compared for `checked` - are the same opt.value, which is what keeps this modal - in sync with the inline summary in both directions. */} - {GRADE_OPTIONS.map(opt => ( - - ))} - - ))} - -
PR Number{opt.label}
{pr.prNumbers} - handleGradeChange(showGradingModal, pr.id, opt.value)} - aria-label={`${pr.prNumbers} ${opt.label}`} - /> -
- -
- -
-
-
-
- )} -
+ setIsFinalized(true)} + searchTerm={searchTerm} + onSearchTermChange={setSearchTerm} + roleFilter={roleFilter} + onRoleFilterChange={setRoleFilter} + availableRoles={availableRoles} + onClearSearch={handleClearSearch} + filteredReviewers={filteredReviewers} + promotedReviewerIds={promotedReviewerIds} + onPromoteClick={handlePromoteClick} + activeInput={activeInput} + inputValue={inputValue} + inputError={inputError} + loadError={loadError} + gradeError={gradeError} + isLoadingSaved={isLoadingSaved} + isSavingPR={isSavingPR} + isSavingGrade={isSavingGrade} + onInputValueChange={value => { + setInputValue(value); + setInputError(''); + }} + onAddNewClick={handleAddNewClick} + onInputSubmit={handleInputSubmit} + onCancelInput={handleCancelInput} + onPRNumberClick={handlePRNumberClick} + promotingReviewer={promotingReviewer} + onConfirmPromotion={handleConfirmPromotion} + onCancelPromotion={handleCancelPromotion} + showGradingModal={showGradingModal} + onCloseGradingModal={handleCloseGradingModal} + gradingReviewer={reviewerData.find(reviewer => reviewer.id === showGradingModal)} + onGradeChange={handleGradeChange} + /> ); }; diff --git a/src/components/PRGradingScreen/PRGradingScreen.module.css b/src/components/PRGradingScreen/PRGradingScreen.module.css index cea7ce1ed2f..38e40fb9641 100644 --- a/src/components/PRGradingScreen/PRGradingScreen.module.css +++ b/src/components/PRGradingScreen/PRGradingScreen.module.css @@ -381,7 +381,7 @@ } .pr-grading-screen-error-message { - color: #f8d7da; + color: #b02a37; font-size: 0.75rem; margin-top: 4px; text-align: center; @@ -463,9 +463,6 @@ /* Grading Table Styles */ .pr-grading-screen-grading-table { width: 100%; - - /* Same four grade columns as the inline summary, so it clips the same way on - narrow screens. Keep a usable minimum and let the modal body scroll. */ min-width: 380px; border-collapse: collapse; margin-bottom: 20px; @@ -578,7 +575,6 @@ font-size: 0.8rem; } - /* Modal responsive styles */ .pr-grading-screen-modal { width: 95%; max-height: 90vh; @@ -620,7 +616,6 @@ /* ===== DARK MODE STYLES ===== */ -/* Container and Card */ .pr-grading-screen-container.dark-mode { background-color: #1b2a41; } @@ -678,7 +673,6 @@ color: #fff; } -/* Table */ .pr-grading-screen-table-container.dark-mode { box-shadow: 0 1px 3px rgb(255 255 255 / 10%); } @@ -721,7 +715,6 @@ border-color: #6a7b98; } -/* PR Number Pills */ .pr-grading-screen-table.dark-mode .pr-grading-screen-pr-number { background-color: #2d4059; color: #fff; @@ -740,7 +733,6 @@ box-shadow: 0 2px 4px rgb(255 255 255 / 10%); } -/* Buttons */ .pr-grading-screen-add-btn.dark-mode { background-color: #28a745; border-color: #28a745; @@ -751,7 +743,6 @@ border-color: #1e7e34; } -/* Modal */ .pr-grading-screen-modal-overlay.dark-mode { background-color: rgb(27 42 65 / 80%); } @@ -808,7 +799,6 @@ background-color: #2d4059; } -/* Input and Form Elements */ .pr-grading-screen-pr-number-input.dark-mode { background-color: #2d4059; border-color: #5a6b88; @@ -824,11 +814,6 @@ border-color: #dc3545; } -/* .pr-grading-screen-pair-message { - color: #a7f3d0; -} */ - -/* Modal Buttons */ .pr-grading-screen-done-btn.dark-mode { background-color: #007bff; border-color: #007bff; @@ -840,12 +825,10 @@ border-color: #004085; } -/* Input Container */ .pr-grading-screen-input-container.dark-mode { background-color: transparent; } -/* Button variants for dark mode */ .btn.dark-mode { border: 1px solid #5a6b88; } @@ -871,7 +854,6 @@ border-color: #4e555b; } -/* Grade badges in dark mode */ .dark-mode .pr-grading-screen-grade-exceptional { background-color: #155724; color: #d4edda; @@ -963,7 +945,6 @@ font-style: italic; } -/* Search bar dark mode */ .pr-grading-screen-search-bar.dark-mode { background-color: transparent; } @@ -1008,7 +989,89 @@ color: #9ab0cc; } -/* ---------------- INLINE PR SUMMARY ---------------- */ +.pr-grading-screen-error-message.dark-mode { + color: #f8d7da; +} + +/* Promotion Confirmation Modal Actions (From Your Branch) */ +.pr-promotion-no-history { + margin-bottom: 16px; + padding: 12px; + border: 1px dashed #ced4da; + border-radius: 6px; + background-color: #f8f9fa; + color: #6c757d; + text-align: center; +} + +.pr-promotion-no-history.dark-mode { + border-color: #4a5a77; + background-color: #1b2a41; + color: #b0b8c4; +} + +.pr-promotion-footer { + display: flex; + justify-content: center; + align-items: center; + gap: 16px; + padding: 18px 24px 24px !important; +} + +.pr-promotion-btn-cancel { + padding: 9px 24px; + border-radius: 6px; + border: 1px solid #6c757d; + background-color: #6c757d; + color: #fff; + cursor: pointer; + font-weight: 600; + font-size: 14px; + transition: all 0.2s ease-in-out; + box-shadow: 0 1px 3px rgb(0 0 0 / 10%); +} + +.pr-promotion-btn-cancel:hover { + background-color: #5a6268; + border-color: #545b62; + transform: translateY(-1px); + box-shadow: 0 4px 8px rgb(0 0 0 / 20%); +} + +.pr-promotion-btn-confirm { + padding: 9px 24px; + border-radius: 6px; + border: none; + background-color: #28a745; + color: #fff; + cursor: pointer; + font-weight: 600; + font-size: 14px; + transition: all 0.2s ease-in-out; + box-shadow: 0 1px 3px rgb(0 0 0 / 10%); +} + +.pr-promotion-btn-confirm:hover { + background-color: #218838; + transform: translateY(-1px); + box-shadow: 0 4px 10px rgb(40 167 69 / 40%); +} + +.dark-mode .pr-promotion-btn-cancel { + border-color: #5a6b88; + background-color: #475569; +} + +.dark-mode .pr-promotion-btn-cancel:hover { + background-color: #5a6b88; + border-color: #8a9bb8; +} + +.dark-mode .pr-promotion-btn-confirm:hover { + background-color: #1e7e34; +} + +/* ---------------- INLINE PR SUMMARY (From Development) ---------------- */ .pr-grading-inline-summary-row { background-color: transparent; @@ -1019,11 +1082,6 @@ border-top: none !important; } -/* ========================================================== - Inline PR Summary Styles (PR #5493) - Scoped strictly with pr-grading-inline-* to avoid global pollution - ========================================================== */ - .pr-grading-inline-summary-container { padding: 16px 20px; background-color: #fff; @@ -1032,29 +1090,21 @@ box-shadow: 0 2px 6px rgb(0 0 0 / 4%); } -/* Dark mode support for inline summary container */ .pr-grading-inline-summary-container.dark-mode { background-color: #2b2b2b; border-color: rgb(255 255 255 / 15%); box-shadow: none; } -/* Horizontal scroll rail. Without this the four grade columns are squeezed until - the rightmost ones ("Unsatisfactory" / "Cannot find image") clip off the edge - on narrow screens. The table keeps a usable minimum width and scrolls instead. */ .pr-grading-inline-table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; - - /* Firefox. Webkit equivalents below — without this Firefox keeps the default - near-invisible overlay bar that prompted this change. */ scrollbar-width: thin; scrollbar-color: #b9b9b9 #ededed; } -/* 10px tall so the bar is an easy pointer target on touch and trackpad. */ .pr-grading-inline-table-scroll::-webkit-scrollbar { height: 10px; } @@ -1064,8 +1114,6 @@ border-radius: 999px; } -/* The transparent border + padding-box clip insets the thumb so it reads as a - separate object instead of fusing with the track at the ends. */ .pr-grading-inline-table-scroll::-webkit-scrollbar-thumb { background-color: #b9b9b9; border: 2px solid transparent; @@ -1077,15 +1125,10 @@ background-color: #9a9a9a; } -/* Dark mode: the light thumb above all but disappears on the #2b2b2b card, so - go high-contrast. Scoped through the container, which already carries the - dark-mode class, so the scroll wrapper itself needs no extra class. */ .pr-grading-inline-summary-container.dark-mode .pr-grading-inline-table-scroll { scrollbar-color: #666 #2b2b2b; } -/* Darker than the #2b2b2b card, so the track and thumb separate from each other - as well as from the card behind them. */ .pr-grading-inline-summary-container.dark-mode .pr-grading-inline-table-scroll::-webkit-scrollbar-track { background-color: #1f1f1f; @@ -1103,9 +1146,6 @@ .pr-grading-inline-summary-table { width: 100%; - - /* Floor for the five columns. Below this the table stops shrinking and the - scroll rail above takes over rather than crushing the grade columns. */ min-width: 380px; margin-bottom: 0; border-collapse: collapse; @@ -1183,9 +1223,6 @@ accent-color: #59359a; } -/* Narrow phones (~420px and below). Reclaim horizontal space so the four grade - columns fit without scrolling where possible; the scroll rail above is the - fallback when they still don't. */ @media (width <= 480px) { .pr-grading-inline-summary-cell { padding: 6px 8px 12px !important; @@ -1205,8 +1242,6 @@ line-height: 1.25; } - /* The PR column is fixed-width on desktop; let the grade columns take the - remaining space instead of it hogging a quarter of a 420px viewport. */ .pr-grading-inline-pr-cell { width: auto; white-space: nowrap; diff --git a/src/components/PRGradingScreen/PRGradingScreenContainer.test.jsx b/src/components/PRGradingScreen/PRGradingScreenContainer.test.jsx new file mode 100644 index 00000000000..448cef10efd --- /dev/null +++ b/src/components/PRGradingScreen/PRGradingScreenContainer.test.jsx @@ -0,0 +1,49 @@ +import { render, screen } from '@testing-library/react'; +import axios from 'axios'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import PRGradingScreenContainer from './index'; + +const route = vi.hoisted(() => ({ search: '', state: null })); + +vi.mock('axios'); +vi.mock('react-router-dom', () => ({ useLocation: () => route })); +vi.mock('./PRGradingScreen', () => ({ + default: ({ teamData, reviewers }) => ( +
+ {teamData.teamName} - {teamData.dateRange.start} - {reviewers.length} reviewers +
+ ), +})); + +describe('PR grading screen team selection', () => { + beforeEach(() => { + vi.clearAllMocks(); + route.search = ''; + route.state = null; + }); + + it('loads the built-in team when opened directly', () => { + render(); + + expect(screen.getByText(/91NePRT - 5\/18\/2025/)).toBeInTheDocument(); + expect(axios.get).not.toHaveBeenCalled(); + }); + + it('reloads a custom team from its URL after a refresh', async () => { + route.search = '?teamId=custom1&weekStart=2026-10-04'; + axios.get.mockResolvedValue({ + data: [ + { + _id: 'custom1', + teamName: 'Custom Team', + reviewerCount: 2, + reviewerNames: ['Alice', 'Bob'], + }, + ], + }); + + render(); + + expect(await screen.findByText(/Custom Team - 10\/4\/2026 - 2 reviewers/)).toBeInTheDocument(); + }); +}); diff --git a/src/components/PRGradingScreen/PRGradingTest.jsx b/src/components/PRGradingScreen/PRGradingTest.jsx index fd33f7d78e7..44bc714296c 100644 --- a/src/components/PRGradingScreen/PRGradingTest.jsx +++ b/src/components/PRGradingScreen/PRGradingTest.jsx @@ -50,7 +50,18 @@ const PRGradingTest = () => { const handleTeamSelect = teamId => { const team = allTeams.find(t => t.id === teamId); - history.push('/pr-grading-screen', { teamId, config: team }); + const params = new URLSearchParams({ teamId }); + if (team?.fromDB) { + const start = new Date(); + start.setDate(start.getDate() - start.getDay()); + const date = [ + start.getFullYear(), + String(start.getMonth() + 1).padStart(2, '0'), + String(start.getDate()).padStart(2, '0'), + ].join('-'); + params.set('weekStart', date); + } + history.push(`/pr-grading-screen?${params.toString()}`, { teamId, config: team }); }; const handleDeleteConfig = async (e, teamId) => { diff --git a/src/components/PRGradingScreen/PRGradingView.jsx b/src/components/PRGradingScreen/PRGradingView.jsx new file mode 100644 index 00000000000..a5ad8671bb2 --- /dev/null +++ b/src/components/PRGradingScreen/PRGradingView.jsx @@ -0,0 +1,470 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Button, Card, Col, Container, Row } from 'react-bootstrap'; +import styles from './PRGradingScreen.module.css'; +import InlinePRSummary from './InlinePRSummary'; +import GRADE_OPTIONS from './gradeOptions'; + +const PRGradingView = ({ + darkMode, + teamData, + isFinalized, + onFinalize, + searchTerm, + onSearchTermChange, + roleFilter, + onRoleFilterChange, + availableRoles, + onClearSearch, + filteredReviewers, + promotedReviewerIds, + onPromoteClick, + activeInput, + inputValue, + inputError, + loadError, + gradeError, + isLoadingSaved, + isSavingPR, + isSavingGrade, + onInputValueChange, + onAddNewClick, + onInputSubmit, + onCancelInput, + onPRNumberClick, + promotingReviewer, + onConfirmPromotion, + onCancelPromotion, + showGradingModal, + onCloseGradingModal, + gradingReviewer, + onGradeChange, +}) => { + const dm = darkMode ? 'dark-mode' : ''; + + return ( + + + + + +
+
+

+ Weekly PR grading screen +

+
+

+ {teamData.teamName} | {teamData.dateRange.start} to {teamData.dateRange.end} +

+
+
+ +
+ {loadError && ( +

+ {loadError} +

+ )} +
+ + + {gradeError && ( +

+ {gradeError} +

+ )} + {/* Search and Filter Bar */} +
+ onSearchTermChange(e.target.value)} + className={`${styles['pr-grading-screen-search-input']} ${dm}`} + /> + + {availableRoles.length > 0 && ( + + )} + + {(searchTerm || roleFilter) && ( + + )} +
+ + {/* Reviewer Table */} +
+ + + + + + + + + + + + {filteredReviewers.length === 0 ? ( + + + + ) : ( + filteredReviewers.map(reviewer => { + const isPromoted = promotedReviewerIds.has(reviewer.id); + + return ( + + + {/* Reviewer Name and Promote Button Cell */} + + + {/* PR Reviewed Count */} + + + {/* PRs Needed */} + + + {/* PR Numbers & Actions */} + + + {/* Render inline summary component below each reviewer row for state synchronization and unit tests */} + + + ); + }) + )} + +
Reviewer NamePR reviewedPRs NeededPR Numbers
+ No reviewers found +
+
+ + {reviewer.reviewer} + + {reviewer.role && ( + + {reviewer.role} + + )} + +
+
+ + + {reviewer.prsNeeded} + +
+ {reviewer.gradedPrs.map(pr => ( + onPRNumberClick(reviewer.id)} + onKeyDown={e => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + onPRNumberClick(reviewer.id); + } + }} + > + {pr.prNumbers} + + ))} +
+ + {!isFinalized && activeInput !== reviewer.id && ( + + )} + + {!isFinalized && activeInput === reviewer.id && ( +
+
+ onInputValueChange(e.target.value)} + className={styles['pr-grading-screen-pr-number-input']} + placeholder="1070 or 1070 + 1256" + /> + {inputError && ( + + {inputError} + + )} +
+
+ + +
+
+ )} +
+
+
+
+ +
+ + {/* PR Grading Modal */} + {showGradingModal && gradingReviewer && ( +
+
+
+

Grade PR for {gradingReviewer.reviewer}

+ +
+ +
+ + + + + {GRADE_OPTIONS.map(opt => ( + + ))} + + + + {gradingReviewer.gradedPrs.map(pr => ( + + + {GRADE_OPTIONS.map(opt => ( + + ))} + + ))} + +
PR Number{opt.label}
+ {pr.prNumbers} + + onGradeChange(gradingReviewer.id, pr.id, opt.value)} + className={styles['pr-grading-screen-grade-checkbox']} + aria-label={`${pr.prNumbers} ${opt.label}`} + /> +
+ +
+ +
+
+
+
+ )} + + {/* Promotion Confirmation Modal */} + {promotingReviewer && ( +
+
+
+

Confirm Promotion

+ +
+ +
+

+ Reviewer: {promotingReviewer.reviewerName} +

+

Team: {promotingReviewer.teamCode}

+

Status: {promotingReviewer.isConsistent ? '✅ Consistent' : '⚠️ Inconsistent'}

+ + {promotingReviewer.weeklyPRs && promotingReviewer.weeklyPRs.length > 0 ? ( + + + + + + + + + {promotingReviewer.weeklyPRs.map((count, index) => ( + + + + + ))} + +
WeekPR Count
Week {index + 1}{count}
+ ) : ( +
+ No weekly PR history is available for this reviewer. +
+ )} + +
+ + +
+
+
+
+ )} +
+ ); +}; + +PRGradingView.propTypes = { + darkMode: PropTypes.bool.isRequired, + teamData: PropTypes.shape({ + teamName: PropTypes.string.isRequired, + dateRange: PropTypes.shape({ + start: PropTypes.string.isRequired, + end: PropTypes.string.isRequired, + }).isRequired, + }).isRequired, + isFinalized: PropTypes.bool.isRequired, + onFinalize: PropTypes.func.isRequired, + searchTerm: PropTypes.string.isRequired, + onSearchTermChange: PropTypes.func.isRequired, + roleFilter: PropTypes.string.isRequired, + onRoleFilterChange: PropTypes.func.isRequired, + availableRoles: PropTypes.arrayOf(PropTypes.string).isRequired, + onClearSearch: PropTypes.func.isRequired, + filteredReviewers: PropTypes.arrayOf(PropTypes.object).isRequired, + promotedReviewerIds: (props, propName) => { + const val = props[propName]; + // Accept Set or array-like objects with a has or includes method + if ( + val && + typeof val === 'object' && + (typeof val.has === 'function' || typeof val.includes === 'function') + ) { + return null; + } + return new Error(`Invalid prop ${propName}: expected Set or Array, got ${typeof val}`); + }, + onPromoteClick: PropTypes.func.isRequired, + activeInput: PropTypes.string, + inputValue: PropTypes.string.isRequired, + inputError: PropTypes.string.isRequired, + loadError: PropTypes.string.isRequired, + gradeError: PropTypes.string.isRequired, + isLoadingSaved: PropTypes.bool.isRequired, + isSavingPR: PropTypes.bool.isRequired, + isSavingGrade: PropTypes.bool.isRequired, + onInputValueChange: PropTypes.func.isRequired, + onAddNewClick: PropTypes.func.isRequired, + onInputSubmit: PropTypes.func.isRequired, + onCancelInput: PropTypes.func.isRequired, + onPRNumberClick: PropTypes.func.isRequired, + promotingReviewer: PropTypes.object, + onConfirmPromotion: PropTypes.func.isRequired, + onCancelPromotion: PropTypes.func.isRequired, + showGradingModal: PropTypes.string, + onCloseGradingModal: PropTypes.func.isRequired, + gradingReviewer: PropTypes.object, + onGradeChange: PropTypes.func.isRequired, +}; + +export default PRGradingView; diff --git a/src/components/PRGradingScreen/PromotionConfirmationBox.jsx b/src/components/PRGradingScreen/PromotionConfirmationBox.jsx index 2244539b6cd..952c408733c 100644 --- a/src/components/PRGradingScreen/PromotionConfirmationBox.jsx +++ b/src/components/PRGradingScreen/PromotionConfirmationBox.jsx @@ -4,9 +4,12 @@ import styles from './PRGradingScreen.module.css'; function PromotionConfirmationBox({ reviewer, onConfirm, onCancel, darkMode }) { const { reviewerName, teamCode, teamReviewerName, weeklyPRs } = reviewer; - const totalPRs = weeklyPRs.reduce((sum, w) => sum + w.count, 0); - const avgPRs = weeklyPRs.length > 0 ? (totalPRs / weeklyPRs.length).toFixed(1) : 0; - const isConsistent = weeklyPRs.every(w => w.count >= 8); + // With no recorded weekly history, show that plainly instead of computing stats: + // `[].every(...)` is true, which would otherwise label an unknown history "Consistent". + const hasWeeklyHistory = Array.isArray(weeklyPRs) && weeklyPRs.length > 0; + const totalPRs = hasWeeklyHistory ? weeklyPRs.reduce((sum, w) => sum + w.count, 0) : 0; + const avgPRs = hasWeeklyHistory ? (totalPRs / weeklyPRs.length).toFixed(1) : 0; + const isConsistent = hasWeeklyHistory && weeklyPRs.every(w => w.count >= 8); return (
Weekly PR Stats - - - - - - - - - {weeklyPRs.map(w => ( - - - - - ))} - -
+ + + + + + + + + {weeklyPRs.map(w => ( + + + + + ))} + +
+ Week + + PR Count +
+ {w.week} + + {w.count} +
+ + {/* Summary Stats */} +
+
- Week -
+ {totalPRs} + +
+ Total PRs +
+ +
- PR Count -
- {w.week} - +
+ Avg PRs/Week +
+ +
+
- {w.count} -
- - {/* Summary Stats */} -
-
-
- {totalPRs} -
-
- Total PRs -
-
-
-
- {avgPRs} -
-
- Avg PRs/Week + {isConsistent ? '✅' : '⚠️'} +
+
+ {isConsistent ? 'Consistent' : 'Inconsistent'} +
+
-
-
+ ) : ( +

-

- {isConsistent ? '✅' : '⚠️'} -
-
- {isConsistent ? 'Consistent' : 'Inconsistent'} -
-
-
+ No weekly PR history is available for this reviewer. +

+ )} {/* Confirmation question */}

-

diff --git a/src/components/PRGradingScreen/ReviewerCell.jsx b/src/components/PRGradingScreen/ReviewerCell.jsx new file mode 100644 index 00000000000..24069df947e --- /dev/null +++ b/src/components/PRGradingScreen/ReviewerCell.jsx @@ -0,0 +1,49 @@ +import PropTypes from 'prop-types'; +import { Button } from 'react-bootstrap'; +import styles from './PRGradingScreen.module.css'; + +const ReviewerCell = ({ reviewer, isPromoted, promoted, onPromoteClick }) => { + // Compatibility fallback for promotion status props + const promotedState = isPromoted !== undefined ? isPromoted : promoted; + + return ( + /* Vertical container anchoring the reviewer name and action button */ +
+ {/* Display the reviewer name */} + {reviewer.reviewer} + + {/* Render the Promote / Promoted button directly beneath the reviewer name */} + +
+ ); +}; + +ReviewerCell.propTypes = { + reviewer: PropTypes.shape({ + id: PropTypes.string.isRequired, + reviewer: PropTypes.string.isRequired, + }).isRequired, + isPromoted: PropTypes.bool, + promoted: PropTypes.bool, + onPromoteClick: PropTypes.func.isRequired, +}; + +export default ReviewerCell; diff --git a/src/components/PRGradingScreen/__tests__/PRGradingScreen.test.jsx b/src/components/PRGradingScreen/__tests__/PRGradingScreen.test.jsx index baa51aa6bf5..a226731c49f 100644 --- a/src/components/PRGradingScreen/__tests__/PRGradingScreen.test.jsx +++ b/src/components/PRGradingScreen/__tests__/PRGradingScreen.test.jsx @@ -1,8 +1,17 @@ -import { fireEvent, render, screen } from '@testing-library/react'; -import { describe, expect, it, vi } from 'vitest'; +import axios from 'axios'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import PRGradingScreen from '../PRGradingScreen'; import GRADE_OPTIONS from '../gradeOptions'; +vi.mock('axios'); + +beforeEach(() => { + vi.clearAllMocks(); + axios.get.mockResolvedValue({ data: [] }); + axios.post.mockResolvedValue({ data: { status: 'ok' } }); +}); + vi.mock('react-redux', async () => { const actual = await vi.importActual('react-redux'); return { ...actual, useSelector: () => false }; @@ -24,8 +33,10 @@ const makeReviewers = () => [ }, ]; -const renderScreen = () => +const renderScreen = async () => { render(); + await waitFor(() => expect(screen.getByRole('button', { name: '+ Add new' })).toBeEnabled()); +}; // Both tables label their checkboxes `${prNumbers} ${label}`. Before the modal // opens only the inline summary is mounted, so there is exactly one match; @@ -37,42 +48,45 @@ const checkboxes = label => screen.queryAllByLabelText(`1070 ${label}`); const openModal = () => fireEvent.click(screen.getByRole('button', { name: '1070' })); describe('PRGradingScreen grade sync between inline summary and modal', () => { - it.each(GRADE_OPTIONS.map(o => o.label))('reflects an inline "%s" grade in the modal', label => { - renderScreen(); - - // Only the inline summary is mounted before the modal opens. - const [inline] = checkboxes(label); - fireEvent.click(inline); - expect(inline).toBeChecked(); - - openModal(); - - // Both tables are mounted now; the second match is the modal's. - const all = checkboxes(label); - expect(all).toHaveLength(2); - expect(all[1]).toBeChecked(); - }); + it.each(GRADE_OPTIONS.map(o => o.label))( + 'reflects an inline "%s" grade in the modal', + async label => { + await renderScreen(); + + // Only the inline summary is mounted before the modal opens. + const [inline] = checkboxes(label); + fireEvent.click(inline); + await waitFor(() => expect(inline).toBeChecked()); + + openModal(); + + // Both tables are mounted now; the second match is the modal's. + const all = checkboxes(label); + expect(all).toHaveLength(2); + expect(all[1]).toBeChecked(); + }, + ); - it('keeps a single grade selected when switching options inline', () => { - renderScreen(); + it('keeps a single grade selected when switching options inline', async () => { + await renderScreen(); fireEvent.click(checkboxes('Cannot find image')[0]); - expect(checkboxes('Cannot find image')[0]).toBeChecked(); + await waitFor(() => expect(checkboxes('Cannot find image')[0]).toBeChecked()); expect(checkboxes('Okay')[0]).not.toBeChecked(); fireEvent.click(checkboxes('Exceptional')[0]); - expect(checkboxes('Exceptional')[0]).toBeChecked(); + await waitFor(() => expect(checkboxes('Exceptional')[0]).toBeChecked()); expect(checkboxes('Cannot find image')[0]).not.toBeChecked(); }); - it('propagates a modal grade back to the inline summary', () => { - renderScreen(); + it('propagates a modal grade back to the inline summary', async () => { + await renderScreen(); openModal(); const [inline, modal] = checkboxes('Cannot find image'); fireEvent.click(modal); - expect(modal).toBeChecked(); + await waitFor(() => expect(modal).toBeChecked()); expect(inline).toBeChecked(); }); }); diff --git a/src/components/PRGradingScreen/index.jsx b/src/components/PRGradingScreen/index.jsx index 37aed6ec1eb..f3eaef45d50 100644 --- a/src/components/PRGradingScreen/index.jsx +++ b/src/components/PRGradingScreen/index.jsx @@ -1,5 +1,8 @@ +import axios from 'axios'; +import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; import { v4 as uuidv4 } from 'uuid'; +import { ENDPOINTS } from '../../utils/URL'; import { getDataByTeamId } from './mockData'; import PRGradingScreen from './PRGradingScreen'; @@ -7,8 +10,43 @@ const STATIC_IDS = ['team1', 'team2', 'team3']; const PRGradingScreenContainer = () => { const location = useLocation(); - const teamId = location.state?.teamId || 'team1'; - const config = location.state?.config || null; + const params = new URLSearchParams(location.search); + const teamId = params.get('teamId') || location.state?.teamId || 'team1'; + const [savedConfig, setSavedConfig] = useState(null); + const [configError, setConfigError] = useState(''); + const locationConfig = location.state?.teamId === teamId ? location.state?.config : null; + const config = locationConfig || (savedConfig?.id === teamId ? savedConfig : null); + + useEffect(() => { + if (STATIC_IDS.includes(teamId) || locationConfig) return undefined; + let active = true; + axios + .get(ENDPOINTS.PR_GRADING_CONFIG) + .then(response => { + if (!active) return; + const match = response.data.find(item => item._id === teamId); + if (match) { + setSavedConfig({ + id: match._id, + name: match.teamName, + reviewerCount: match.reviewerCount, + reviewerNames: match.reviewerNames, + }); + } else { + setConfigError('Team configuration not found.'); + } + }) + .catch(() => { + if (active) setConfigError('Could not load the team configuration.'); + }); + return () => { + active = false; + }; + }, [teamId, locationConfig]); + + if (!STATIC_IDS.includes(teamId) && !config) { + return
{configError || 'Loading team configuration...'}
; + } if (!STATIC_IDS.includes(teamId) && config) { const reviewers = Array.from({ length: config.reviewerCount }, (_, i) => ({ @@ -19,11 +57,20 @@ const PRGradingScreenContainer = () => { gradedPrs: [], })); + const weekStart = params.get('weekStart'); + if (weekStart && !/^\d{4}-\d{2}-\d{2}$/.test(weekStart)) { + return
Invalid week start date.
; + } + const start = weekStart ? new Date(`${weekStart}T12:00:00`) : new Date(); + if (Number.isNaN(start.getTime())) return
Invalid week start date.
; + if (!weekStart) start.setDate(start.getDate() - start.getDay()); + const end = new Date(start); + end.setDate(start.getDate() + 7); const teamData = { teamName: config.name, dateRange: { - start: new Date().toLocaleDateString(), - end: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toLocaleDateString(), + start: start.toLocaleDateString('en-US'), + end: end.toLocaleDateString('en-US'), }, }; diff --git a/src/components/PRGradingScreen/prGradingPersistence.js b/src/components/PRGradingScreen/prGradingPersistence.js new file mode 100644 index 00000000000..8342bb7b345 --- /dev/null +++ b/src/components/PRGradingScreen/prGradingPersistence.js @@ -0,0 +1,85 @@ +import axios from 'axios'; +import { ENDPOINTS } from '../../utils/URL'; + +const getPRNumbers = value => value.split('+').map(number => number.trim()); +const toDisplayGrade = grade => (grade === 'No Correct Image' ? 'Cannot find image' : grade); + +const getGradingKey = teamData => { + const [month, day, year] = teamData.dateRange.start.split('/').map(Number); + const date = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; + return { teamKey: `pr-grading-screen:${teamData.teamName}`, date }; +}; + +export const loadSavedGradings = async teamData => { + const { teamKey, date } = getGradingKey(teamData); + const response = await axios.get(ENDPOINTS.WEEKLY_GRADING, { + params: { team: teamKey, date, weekStart: date }, + }); + return response.data; +}; + +export const saveAddedPR = (teamData, reviewer, prNumbers) => { + const { teamKey, date } = getGradingKey(teamData); + return axios.post(ENDPOINTS.WEEKLY_GRADING_SAVE, { + teamCode: teamKey, + teamName: teamKey, + date, + gradings: [ + { + reviewer: reviewer.reviewer, + prsNeeded: reviewer.prsNeeded, + prsReviewed: reviewer.gradedPrs.length + 1, + gradedPrs: [{ prNumbers, grade: 'Okay' }], + }, + ], + }); +}; + +export const saveGradeChange = (teamData, reviewer, prNumbers, grade) => { + const { teamKey, date } = getGradingKey(teamData); + return axios.post(ENDPOINTS.WEEKLY_GRADING_SAVE, { + teamCode: teamKey, + teamName: teamKey, + date, + gradings: [ + { + reviewer: reviewer.reviewer, + prsNeeded: reviewer.prsNeeded, + prsReviewed: reviewer.gradedPrs.length, + gradedPrs: [{ prNumbers, grade }], + }, + ], + }); +}; + +export const mergeSavedGradings = (reviewers, savedGradings) => { + const savedByReviewer = new Map(savedGradings.map(grading => [grading.reviewer, grading])); + + return reviewers.map(reviewer => { + const savedPrs = savedByReviewer.get(reviewer.reviewer)?.gradedPrs || []; + const savedGrades = new Map( + savedPrs.map(pr => [getPRNumbers(pr.prNumbers).join('+'), toDisplayGrade(pr.grade)]), + ); + const seen = new Set(reviewer.gradedPrs.flatMap(pr => getPRNumbers(pr.prNumbers))); + const additions = savedPrs + .filter(pr => { + const numbers = getPRNumbers(pr.prNumbers); + if (numbers.some(number => seen.has(number))) return false; + numbers.forEach(number => seen.add(number)); + return true; + }) + .map(pr => ({ + ...pr, + id: String(pr._id || pr.id || pr.prNumbers), + grade: toDisplayGrade(pr.grade), + })); + const gradedPrs = [ + ...reviewer.gradedPrs.map(pr => ({ + ...pr, + grade: savedGrades.get(getPRNumbers(pr.prNumbers).join('+')) || pr.grade, + })), + ...additions, + ]; + return { ...reviewer, gradedPrs, prsReviewed: gradedPrs.length }; + }); +}; diff --git a/src/components/PRGradingScreen/prGradingPersistence.test.js b/src/components/PRGradingScreen/prGradingPersistence.test.js new file mode 100644 index 00000000000..f5e59393289 --- /dev/null +++ b/src/components/PRGradingScreen/prGradingPersistence.test.js @@ -0,0 +1,154 @@ +import axios from 'axios'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { ENDPOINTS } from '../../utils/URL'; +import { + loadSavedGradings, + mergeSavedGradings, + saveAddedPR, + saveGradeChange, +} from './prGradingPersistence'; + +vi.mock('axios'); + +const teamData = { + teamName: '91NePRT', + dateRange: { start: '5/18/2025', end: '5/25/2025' }, +}; + +describe('PR grading persistence', () => { + beforeEach(() => vi.clearAllMocks()); + + it('loads saved PRs for the displayed team and week', async () => { + axios.get.mockResolvedValue({ data: [{ reviewer: 'Alice', gradedPrs: [] }] }); + + await expect(loadSavedGradings(teamData)).resolves.toHaveLength(1); + expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.WEEKLY_GRADING, { + params: { + team: 'pr-grading-screen:91NePRT', + date: '2025-05-18', + weekStart: '2025-05-18', + }, + }); + }); + + it('saves only the newly added PR for one reviewer', async () => { + const reviewer = { + reviewer: 'Alice', + prsNeeded: 3, + gradedPrs: [{ prNumbers: '1234', grade: 'Okay' }], + }; + + await saveAddedPR(teamData, reviewer, '5678 + 9999'); + + expect(axios.post).toHaveBeenCalledWith(ENDPOINTS.WEEKLY_GRADING_SAVE, { + teamCode: 'pr-grading-screen:91NePRT', + teamName: 'pr-grading-screen:91NePRT', + date: '2025-05-18', + gradings: [ + { + reviewer: 'Alice', + prsNeeded: 3, + prsReviewed: 2, + gradedPrs: [{ prNumbers: '5678 + 9999', grade: 'Okay' }], + }, + ], + }); + }); + + it('saves only the changed grade without increasing the reviewed count', async () => { + const reviewer = { + reviewer: 'Alice', + prsNeeded: 3, + gradedPrs: [{ prNumbers: '1234', grade: 'Okay' }], + }; + + await saveGradeChange(teamData, reviewer, '1234', 'Exceptional'); + + expect(axios.post).toHaveBeenCalledWith(ENDPOINTS.WEEKLY_GRADING_SAVE, { + teamCode: 'pr-grading-screen:91NePRT', + teamName: 'pr-grading-screen:91NePRT', + date: '2025-05-18', + gradings: [ + { + reviewer: 'Alice', + prsNeeded: 3, + prsReviewed: 1, + gradedPrs: [{ prNumbers: '1234', grade: 'Exceptional' }], + }, + ], + }); + }); + + it('merges saved PRs with built-in entries without duplicating them', () => { + const reviewers = [ + { + id: '1', + reviewer: 'Alice', + prsNeeded: 3, + gradedPrs: [{ id: 'pr1', prNumbers: '1234', grade: 'Okay' }], + }, + ]; + const saved = [ + { + reviewer: 'Alice', + gradedPrs: [ + { _id: 'saved1', prNumbers: '1234', grade: 'Okay' }, + { _id: 'saved2', prNumbers: '5678 + 9999', grade: 'Okay' }, + ], + }, + ]; + + expect(mergeSavedGradings(reviewers, saved)[0]).toMatchObject({ + prsReviewed: 2, + gradedPrs: [ + { id: 'pr1', prNumbers: '1234' }, + { id: 'saved2', prNumbers: '5678 + 9999' }, + ], + }); + }); + + it('uses the saved grade for a built-in PR after reloading', () => { + const reviewers = [ + { + id: '1', + reviewer: 'Alice', + gradedPrs: [{ id: 'pr1', prNumbers: '1234 + 5678', grade: 'Okay' }], + }, + ]; + const saved = [ + { + reviewer: 'Alice', + gradedPrs: [{ prNumbers: '1234+5678', grade: 'Exceptional' }], + }, + ]; + + expect(mergeSavedGradings(reviewers, saved)[0]).toMatchObject({ + prsReviewed: 1, + gradedPrs: [{ id: 'pr1', prNumbers: '1234 + 5678', grade: 'Exceptional' }], + }); + }); + + it('displays the backend image grade for built-in and newly saved PRs', () => { + const reviewers = [ + { + id: '1', + reviewer: 'Alice', + gradedPrs: [{ id: 'pr1', prNumbers: '1234', grade: 'Okay' }], + }, + ]; + const saved = [ + { + reviewer: 'Alice', + gradedPrs: [ + { prNumbers: '1234', grade: 'No Correct Image' }, + { prNumbers: '5678', grade: 'No Correct Image' }, + ], + }, + ]; + + expect(mergeSavedGradings(reviewers, saved)[0].gradedPrs).toMatchObject([ + { prNumbers: '1234', grade: 'Cannot find image' }, + { prNumbers: '5678', grade: 'Cannot find image' }, + ]); + }); +}); diff --git a/src/components/PRGradingScreen/usePRPromotion.js b/src/components/PRGradingScreen/usePRPromotion.js new file mode 100644 index 00000000000..fe1a3facb16 --- /dev/null +++ b/src/components/PRGradingScreen/usePRPromotion.js @@ -0,0 +1,53 @@ +import { useState, useCallback } from 'react'; + +export const usePRPromotion = (defaultTeamName = 'PR Review Team') => { + // State to track the reviewer currently undergoing promotion confirmation + const [promotingReviewer, setPromotingReviewer] = useState(null); + + // Set to track IDs of reviewers who have been successfully promoted + const [promotedReviewerIds, setPromotedReviewerIds] = useState(new Set()); + + // Handler triggered when the Promote button is clicked + const handlePromoteClick = useCallback( + reviewer => { + setPromotingReviewer({ + id: reviewer.id, + reviewerId: reviewer.id, + reviewerName: reviewer.reviewer, + teamCode: reviewer.teamCode || defaultTeamName, + teamReviewerName: reviewer.teamLeader || reviewer.teamReviewerName || 'Team Lead', + // Pass through real history only; an empty list means "no history available". + weeklyPRs: reviewer.weeklyPRs || [], + }); + }, + [defaultTeamName], + ); + + // Handler triggered when the promotion is confirmed in the modal + const handleConfirmPromotion = useCallback(() => { + setPromotedReviewerIds(prev => { + const next = new Set(prev); + if (promotingReviewer) { + const targetId = promotingReviewer.reviewerId || promotingReviewer.id; + if (targetId) { + next.add(targetId); + } + } + return next; + }); + setPromotingReviewer(null); + }, [promotingReviewer]); + + // Handler triggered when the promotion confirmation is cancelled + const handleCancelPromotion = useCallback(() => { + setPromotingReviewer(null); + }, []); + + return { + promotingReviewer, + promotedReviewerIds, + handlePromoteClick, + handleConfirmPromotion, + handleCancelPromotion, + }; +}; diff --git a/src/components/PRPromotions/DisplayBox.jsx b/src/components/PRPromotions/DisplayBox.jsx index 502d265187c..b9447e4ed91 100644 --- a/src/components/PRPromotions/DisplayBox.jsx +++ b/src/components/PRPromotions/DisplayBox.jsx @@ -1,47 +1,115 @@ /* eslint-disable jsx-a11y/no-static-element-interactions */ -import { useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import { toast } from 'react-toastify'; +import { getPromotionPending, postPromotionEligibility } from '../../actions/promotionActions'; import styles from './DisplayBox.module.css'; const VIBGYOR_COLOR_COUNT = 7; +const MONGO_ID_PATTERN = /^[a-fA-F0-9]{24}$/; -const MOCK_PROMOTION_DATA = [ - { - prReviewer: 'Akshay - Jayram', - teamCode: '123', - teamReviewerName: 'Team Leader 1', - weeklyPRs: [ - { week: '2024-06-01', prCount: 12 }, - { week: '2024-06-08', prCount: 15 }, - { week: '2024-06-15', prCount: 10 }, - { week: '2024-06-22', prCount: 18 }, - { week: '2024-06-29', prCount: 14 }, - { week: '2024-07-06', prCount: 16 }, - { week: '2024-07-13', prCount: 20 }, - ], - }, - { - prReviewer: 'Ghazi1212', - teamCode: '456', - teamReviewerName: 'Team Leader 2', - weeklyPRs: [ - { week: '2024-06-01', prCount: 12 }, - { week: '2024-06-08', prCount: 15 }, - { week: '2024-06-15', prCount: 10 }, - { week: '2024-06-22', prCount: 18 }, - { week: '2024-06-29', prCount: 14 }, - ], - }, -]; +function buildRequestor(user) { + if (!user?.userid) { + return null; + } + + return { + requestorId: user.userid, + role: user.role, + }; +} + +function normalizeId(value) { + if (value == null || value === '') { + return undefined; + } + if (typeof value === 'string') { + return value; + } + if (typeof value === 'object') { + if (value.$oid) { + return String(value.$oid); + } + if (value._id) { + return normalizeId(value._id); + } + } + return String(value); +} + +function getPromotableIds(promotions, checkedItems) { + return promotions + .filter((_, index) => checkedItems[index]) + .map(promotion => normalizeId(promotion.reviewerId)) + .filter(id => id && MONGO_ID_PATTERN.test(id)); +} + +function getWeeklyPrCount(pr) { + return pr?.count ?? pr?.prCount ?? 0; +} export default function DisplayBox({ onClose, darkMode = false }) { - const [checkedItems, setCheckedItems] = useState(() => MOCK_PROMOTION_DATA.map(() => true)); + const authUser = useSelector(state => state.auth?.user); + const [promotions, setPromotions] = useState([]); + const [checkedItems, setCheckedItems] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [isConfirming, setIsConfirming] = useState(false); + const [statusMessage, setStatusMessage] = useState(''); const masterCheckboxRef = useRef(null); - const allChecked = checkedItems.length > 0 && checkedItems.every(Boolean); - + const allChecked = + promotions.length > 0 && checkedItems.length > 0 && checkedItems.every(Boolean); const someChecked = checkedItems.some(Boolean); + const confirmDisabled = isLoading || isConfirming || !someChecked; + + const applyPendingRows = useCallback(rows => { + const nextPromotions = Array.isArray(rows) ? rows : []; + setPromotions(nextPromotions); + setCheckedItems(nextPromotions.map(() => true)); + }, []); + + const loadPendingPromotions = useCallback(async () => { + const requestor = buildRequestor(authUser); + if (!requestor) { + throw new Error('Missing requestor'); + } + + const rows = await getPromotionPending(requestor); + applyPendingRows(rows); + return Array.isArray(rows) ? rows : []; + }, [applyPendingRows, authUser]); + + useEffect(() => { + let cancelled = false; + + const load = async () => { + setIsLoading(true); + setStatusMessage(''); + + try { + await loadPendingPromotions(); + } catch { + if (!cancelled) { + applyPendingRows([]); + const message = 'Failed to load pending promotions.'; + setStatusMessage(message); + toast.error(message); + } + } finally { + if (!cancelled) { + setIsLoading(false); + } + } + }; + + void load(); + + return () => { + cancelled = true; + }; + }, [applyPendingRows, loadPendingPromotions]); useEffect(() => { if (masterCheckboxRef.current) { @@ -51,7 +119,7 @@ export default function DisplayBox({ onClose, darkMode = false }) { useEffect(() => { const handleKeyDown = event => { - if (event.key === 'Escape') { + if (event.key === 'Escape' && !isConfirming) { onClose(); } }; @@ -61,7 +129,7 @@ export default function DisplayBox({ onClose, darkMode = false }) { return () => { document.removeEventListener('keydown', handleKeyDown); }; - }, [onClose]); + }, [isConfirming, onClose]); const handleCheckedBoxChange = index => { setCheckedItems(currentItems => @@ -75,16 +143,43 @@ export default function DisplayBox({ onClose, darkMode = false }) { setCheckedItems(currentItems => currentItems.map(() => shouldSelectAll)); }; - const handleConfirm = () => { - const selectedReviewers = MOCK_PROMOTION_DATA.filter((_, index) => checkedItems[index]); + const handleConfirm = async () => { + const selectedCount = checkedItems.filter(Boolean).length; + const selectedIds = getPromotableIds(promotions, checkedItems); + const requestor = buildRequestor(authUser); + + if (selectedIds.length === 0) { + const message = 'No valid reviewers selected for promotion.'; + setStatusMessage(message); + toast.error(message); + return; + } + + setIsConfirming(true); + setStatusMessage(''); + + try { + await postPromotionEligibility(selectedIds, requestor); + const nextPromotions = await loadPendingPromotions(); - console.log('Selected reviewers:', selectedReviewers); + const message = `Successfully promoted ${selectedCount} reviewer(s).`; + setStatusMessage(message); + toast.success(message); - onClose(); + if (nextPromotions.length === 0) { + onClose(); + } + } catch { + const message = 'Failed to process promotions.'; + setStatusMessage(message); + toast.error(message); + } finally { + setIsConfirming(false); + } }; const handleOverlayMouseDown = event => { - if (event.target === event.currentTarget) { + if (event.target === event.currentTarget && !isConfirming) { onClose(); } }; @@ -96,12 +191,17 @@ export default function DisplayBox({ onClose, darkMode = false }) { const getBadgeClassName = index => [styles.prCountBadge, styles[`color-${index % VIBGYOR_COLOR_COUNT}`]].filter(Boolean).join(' '); + const emptyMessage = isLoading + ? 'Loading pending promotions...' + : 'No PR reviewers left to promote.'; + return (

+ {statusMessage && {statusMessage}} + @@ -120,6 +222,7 @@ export default function DisplayBox({ onClose, darkMode = false }) { type="checkbox" checked={allChecked} onChange={handleSelectAll} + disabled={promotions.length === 0 || isLoading || isConfirming} aria-label="Select all reviewers" /> @@ -127,37 +230,59 @@ export default function DisplayBox({ onClose, darkMode = false }) { - + - {MOCK_PROMOTION_DATA.map((promotion, index) => ( - + {promotions.length === 0 && ( + + + + )} + {promotions.map((promotion, index) => ( + - + @@ -170,6 +295,7 @@ export default function DisplayBox({ onClose, darkMode = false }) { type="button" className={`${styles.button} ${styles.cancelButton}`} onClick={onClose} + disabled={isConfirming} > Cancel @@ -177,10 +303,10 @@ export default function DisplayBox({ onClose, darkMode = false }) { diff --git a/src/components/PRPromotions/DisplayBox.module.css b/src/components/PRPromotions/DisplayBox.module.css index 64be6b09538..d307e563f98 100644 --- a/src/components/PRPromotions/DisplayBox.module.css +++ b/src/components/PRPromotions/DisplayBox.module.css @@ -1,6 +1,7 @@ .overlay { position: fixed; inset: 0; + z-index: 2000; display: flex; justify-content: center; align-items: center; @@ -46,6 +47,22 @@ color: #e5e7eb; } +.statusMessage { + display: block; + margin: 0 0 12px; + color: #1d4ed8; + font-size: 14px; + text-align: center; +} + +.popupDark .statusMessage { + color: #93c5fd; +} + +.messageCell { + text-align: center; +} + /* ====================================================== TABLE ====================================================== */ diff --git a/src/components/PRPromotions/__tests__/DisplayBox.test.jsx b/src/components/PRPromotions/__tests__/DisplayBox.test.jsx new file mode 100644 index 00000000000..6e81807c777 --- /dev/null +++ b/src/components/PRPromotions/__tests__/DisplayBox.test.jsx @@ -0,0 +1,211 @@ +import { render, screen, waitFor, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import { vi } from 'vitest'; +import { toast } from 'react-toastify'; +import DisplayBox from '../DisplayBox'; +import { getPromotionPending, postPromotionEligibility } from '../../../actions/promotionActions'; + +vi.mock('../../../actions/promotionActions', () => ({ + getPromotionPending: vi.fn(), + postPromotionEligibility: vi.fn(), +})); + +vi.mock('react-toastify', () => ({ + toast: { + success: vi.fn(), + error: vi.fn(), + info: vi.fn(), + }, +})); + +const mockStore = configureMockStore([]); + +const SAMPLE_PENDING = [ + { + reviewerId: '637af0c0fb9bbc1e308cff01', + prReviewer: 'Akshay Jayaram', + teamCode: 'ABC12', + teamLeaderName: 'Chris Martinez', + weeklyPRs: [ + { week: '2026-W31', count: 7 }, + { week: '2026-W32', count: 7 }, + ], + }, + { + reviewerId: '637af0c0fb9bbc1e308cff02', + prReviewer: 'Ghazi1212', + teamCode: '456', + teamLeaderName: 'Sam Patel', + weeklyPRs: [ + { week: '2026-W31', count: 2 }, + { week: '2026-W32', count: 10 }, + { week: '2026-W33', count: 11 }, + ], + }, +]; + +function renderDisplayBox(darkMode = false) { + const onClose = vi.fn(); + const store = mockStore({ + auth: { user: { userid: 'aaaaaaaaaaaaaaaaaaaaaaaa', role: 'Administrator' } }, + theme: { darkMode }, + }); + + const view = render( + + + , + ); + + return { onClose, unmount: view.unmount }; +} + +describe('DisplayBox promotion confirmation modal', () => { + beforeEach(() => { + vi.clearAllMocks(); + getPromotionPending.mockResolvedValue(SAMPLE_PENDING); + postPromotionEligibility.mockResolvedValue({ message: 'Members promoted successfully.' }); + }); + + it('loads pending reviewers and selects every checkbox by default', async () => { + renderDisplayBox(); + + expect(await screen.findByText('Akshay Jayaram')).toBeInTheDocument(); + expect(screen.getByText('Ghazi1212')).toBeInTheDocument(); + + const checkboxes = screen.getAllByRole('checkbox'); + expect(checkboxes).toHaveLength(3); + checkboxes.forEach(checkbox => { + expect(checkbox).toBeChecked(); + }); + + expect(getPromotionPending).toHaveBeenCalledWith({ + requestorId: 'aaaaaaaaaaaaaaaaaaaaaaaa', + role: 'Administrator', + }); + expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled(); + }); + + it('uses Team Leader Name and Weekly PRs column titles', async () => { + renderDisplayBox(); + + await screen.findByText('Akshay Jayaram'); + + expect(screen.getByText('Team Leader Name')).toBeInTheDocument(); + expect(screen.queryByText('Team Reviewer Name')).not.toBeInTheDocument(); + expect(screen.getByText('Weekly PRs')).toBeInTheDocument(); + expect(screen.queryByText('Weekly PR Counts')).not.toBeInTheDocument(); + }); + + it('shows team leader names and weekly PR counts in circles', async () => { + renderDisplayBox(); + + await screen.findByText('Akshay Jayaram'); + + expect(screen.getByText('Chris Martinez')).toBeInTheDocument(); + expect(screen.getByText('Sam Patel')).toBeInTheDocument(); + + const firstReviewerRow = screen.getByRole('row', { name: /Akshay Jayaram/i }); + expect(within(firstReviewerRow).getAllByText('7')).toHaveLength(2); + }); + + it('disables Confirm while loading and when none are selected', async () => { + let resolvePending; + getPromotionPending.mockReturnValue( + new Promise(resolve => { + resolvePending = resolve; + }), + ); + + renderDisplayBox(); + + expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled(); + expect(screen.getByText('Loading pending promotions...')).toBeInTheDocument(); + + resolvePending(SAMPLE_PENDING); + + await screen.findByText('Akshay Jayaram'); + expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled(); + + await userEvent.click(screen.getByLabelText('Select all reviewers')); + expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled(); + }); + + it('closes without promoting when Cancel is clicked', async () => { + const { onClose } = renderDisplayBox(); + + await screen.findByText('Akshay Jayaram'); + await userEvent.click(screen.getByRole('button', { name: 'Cancel' })); + + expect(onClose).toHaveBeenCalledTimes(1); + expect(postPromotionEligibility).not.toHaveBeenCalled(); + }); + + it('promotes selected reviewers then refetches the pending list', async () => { + const { onClose } = renderDisplayBox(); + + await screen.findByText('Akshay Jayaram'); + + // Uncheck Akshay so only Ghazi is promoted; refetch returns Akshay still pending. + getPromotionPending.mockResolvedValueOnce([SAMPLE_PENDING[0]]); + + await userEvent.click(screen.getByLabelText('Select reviewer Akshay Jayaram')); + await userEvent.click(screen.getByRole('button', { name: 'Confirm' })); + + await waitFor(() => { + expect(postPromotionEligibility).toHaveBeenCalledWith(['637af0c0fb9bbc1e308cff02'], { + requestorId: 'aaaaaaaaaaaaaaaaaaaaaaaa', + role: 'Administrator', + }); + }); + + await waitFor(() => { + expect(toast.success).toHaveBeenCalled(); + }); + + expect(screen.getByText('Akshay Jayaram')).toBeInTheDocument(); + expect(screen.queryByText('Ghazi1212')).not.toBeInTheDocument(); + expect(onClose).not.toHaveBeenCalled(); + expect(getPromotionPending).toHaveBeenCalledTimes(2); + }); + + it('closes when every remaining reviewer is promoted', async () => { + const { onClose } = renderDisplayBox(); + + await screen.findByText('Akshay Jayaram'); + getPromotionPending.mockResolvedValueOnce([]); + + await userEvent.click(screen.getByRole('button', { name: 'Confirm' })); + + await waitFor(() => { + expect(postPromotionEligibility).toHaveBeenCalledWith( + ['637af0c0fb9bbc1e308cff01', '637af0c0fb9bbc1e308cff02'], + { + requestorId: 'aaaaaaaaaaaaaaaaaaaaaaaa', + role: 'Administrator', + }, + ); + }); + + await waitFor(() => { + expect(onClose).toHaveBeenCalledTimes(1); + }); + + expect(toast.success).toHaveBeenCalled(); + }); + + it('shows an error toast when loading pending promotions fails', async () => { + getPromotionPending.mockRejectedValueOnce(new Error('network')); + + renderDisplayBox(); + + await waitFor(() => { + expect(toast.error).toHaveBeenCalledWith('Failed to load pending promotions.'); + }); + + expect(screen.getByText('No PR reviewers left to promote.')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled(); + }); +}); diff --git a/src/components/PermissionsManagement/NewRolePopUp.jsx b/src/components/PermissionsManagement/NewRolePopUp.jsx index c2c05b2d757..686ffc94b1c 100644 --- a/src/components/PermissionsManagement/NewRolePopUp.jsx +++ b/src/components/PermissionsManagement/NewRolePopUp.jsx @@ -5,6 +5,7 @@ import { connect, useDispatch } from 'react-redux'; import { boxStyle, boxStyleDark } from '~/styles'; import { getAllRoles } from '../../actions/role'; import PermissionList from './PermissionList'; +import appStyles from '~/App.module.css'; function CreateNewRolePopup({ toggle, roleNames, darkMode, addRole }) { const [permissionsChecked, setPermissionsChecked] = useState([]); @@ -89,7 +90,7 @@ function CreateNewRolePopup({ toggle, roleNames, darkMode, addRole }) { placeholder="Please enter a new role name" value={newRoleName} onChange={handleRoleName} - className={darkMode ? 'bg-darkmode-liblack text-light border-0' : ''} + className={darkMode ? `${appStyles['bg-darkmode-liblack']} text-light border-0` : ''} /> {isValidRole === false || isNotDuplicateRole === false ? ( diff --git a/src/components/PermissionsManagement/PermissionListItem.jsx b/src/components/PermissionsManagement/PermissionListItem.jsx index 29a8bc2636d..a03bce1b032 100644 --- a/src/components/PermissionsManagement/PermissionListItem.jsx +++ b/src/components/PermissionsManagement/PermissionListItem.jsx @@ -7,6 +7,7 @@ import { boxStyle, boxStyleDark } from '~/styles'; import { ModalContext } from '~/context/ModalContext'; import PermissionList from './PermissionList'; import hasPermission from '../../utils/permissions'; +import appStyles from '~/App.module.css'; import styles from './UserRoleTab.module.css'; import { permissions } from '../../utils/constants'; @@ -294,11 +295,16 @@ function PermissionListItem(props) { id="#modal2-body_new-role--padding" className={darkMode ? 'text-light dark-mode' : ''} > - + Permission Info - {modalContent} - + + {modalContent} + + + ); - const renderSortButton = column => { - const active = props.sorted.column === column && props.sorted.direction !== 'DEFAULT'; + const renderDropdownFilterButton = (id, selectedValue, onChange, list, placeholder) => { + const itemClass = darkMode ? 'bg-darkmode-liblack text-light border-0' : ''; return ( - + + + + + + + {selectedValue ? 'Clear filter' : placeholder} + + + {list.map(item => ( + + {item} + + ))} + + ); }; @@ -62,87 +83,68 @@ const ProjectTableHeader = props => { - {/* */} - + + {/* 2. Category column header */} - - - - + + {/* 7. Archive column header */} {canDeleteProject ? ( - ) : null} @@ -165,8 +167,7 @@ ProjectTableHeader.propTypes = { }; const mapStateToProps = state => ({ - role: state.userProfile.role, // Map 'role' from Redux state to 'role' prop + role: state.userProfile.role, }); -export default connect(mapStateToProps)(ProjectTableHeader) - +export default connect(mapStateToProps)(ProjectTableHeader); \ No newline at end of file diff --git a/src/components/Projects/ProjectTableHeader/__tests__/ProjectTableHeader.test.jsx b/src/components/Projects/ProjectTableHeader/__tests__/ProjectTableHeader.test.jsx index 5639dc0559e..91402b54885 100644 --- a/src/components/Projects/ProjectTableHeader/__tests__/ProjectTableHeader.test.jsx +++ b/src/components/Projects/ProjectTableHeader/__tests__/ProjectTableHeader.test.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { render } from '@testing-library/react' +import { render, screen } from '@testing-library/react' import { Provider } from 'react-redux' import configureMockStore from 'redux-mock-store' import thunk from 'redux-thunk' @@ -87,9 +87,9 @@ describe('ProjectTableHeader Component', () => { }; const hasPermission = vi.fn((a) => true) stateWithDeletePermission.hasPermission = hasPermission; - const { getByText } = renderProjectTableHeader(stateWithDeletePermission); - // eslint-disable-next-line testing-library/prefer-screen-queries - expect(getByText('Archive')).toBeInTheDocument(); + renderProjectTableHeader(stateWithDeletePermission); + + expect(screen.getByText('Archive')).toBeInTheDocument(); }); // Test case to check if the delete column is not shown for users without delete permission @@ -103,9 +103,9 @@ describe('ProjectTableHeader Component', () => { }; const hasPermission = vi.fn((a) => false) stateWithoutDeletePermission.hasPermission = hasPermission; - const { queryByText } = renderProjectTableHeader(stateWithoutDeletePermission); - // eslint-disable-next-line testing-library/prefer-screen-queries - expect(queryByText('Delete')).not.toBeInTheDocument(); + renderProjectTableHeader(stateWithoutDeletePermission); + + expect(screen.queryByText('Delete')).not.toBeInTheDocument(); }); -}); +}); \ No newline at end of file diff --git a/src/components/Projects/Projects.jsx b/src/components/Projects/Projects.jsx index 72038297225..0bb440b225a 100644 --- a/src/components/Projects/Projects.jsx +++ b/src/components/Projects/Projects.jsx @@ -240,14 +240,23 @@ const Projects = function(props) { } } - if (column === "MEMBERS") { + if (column === "MEMBERS") { + // Helper function to safely retrieve active member count, supporting various ID types (string, number, or object) + const getCount = (projectId) => { + if (!projectId) return 0; + return activeMemberCounts[projectId] || + activeMemberCounts[String(projectId)] || + activeMemberCounts[projectId.toString()] || 0; + }; + + const countA = getCount(a._id); + const countB = getCount(b._id); + if (direction === "ASC") { - const countA = activeMemberCounts[a._id] || 0; - const countB = activeMemberCounts[b._id] || 0; + // Sort in ascending order based on active member counts return countA - countB; } else if (direction === "DESC") { - const countA = activeMemberCounts[a._id] || 0; - const countB = activeMemberCounts[b._id] || 0; + // Sort in descending order based on active member counts return countB - countA; } else { return 0; // Default: keep same order as PROJECT sorting diff --git a/src/components/Projects/WBS/SingleTask/SingleTask.jsx b/src/components/Projects/WBS/SingleTask/SingleTask.jsx index 18ac28de493..56401817b46 100644 --- a/src/components/Projects/WBS/SingleTask/SingleTask.jsx +++ b/src/components/Projects/WBS/SingleTask/SingleTask.jsx @@ -93,7 +93,7 @@ function SingleTask(props) { )}
-
PR Reviewer Team Code Team Leader NameWeekly PR CountsWeekly PRs
+ {emptyMessage} +
handleCheckedBoxChange(index)} + disabled={isLoading || isConfirming} aria-label={`Select reviewer ${promotion.prReviewer}`} /> {promotion.prReviewer} {promotion.teamCode}{promotion.teamReviewerName}{promotion.teamLeaderName} -
- {promotion.weeklyPRs.map((pr, prIndex) => ( - - {pr.prCount} - - ))} +
+ {(promotion.weeklyPRs || []).map((pr, prIndex) => { + const prCount = getWeeklyPrCount(pr); + return ( + + {prCount} + + ); + })}
# {PROJECT_NAME} - - {PROJECT_NAME} -
- {renderSortButton('PROJECTS')} -
+ + {/* 1. Project Name column header */} +
+ + {PROJECT_NAME} +
{renderSortButton('PROJECTS')}
- {/* This span holds the header-name and a filter dropdown */} - - {PROJECT_CATEGORY} - } - size="sm" - variant={filterVariant(Boolean(props.selectedValue))} - className="ml-2" - value={props.selectedValue} - onSelect={props.onChange} - menuAlign="right" - > - {props.selectedValue ? 'Clear filter' : 'Choose category'} - - {categoryList.map((category, index) => ( - {category} - ))} - + + {PROJECT_CATEGORY} + {renderDropdownFilterButton('project-category-filter', props.selectedValue, props.onChange, categoryList, 'Choose category')} - - {ACTIVE} - } - size="sm" - variant={filterVariant(Boolean(props.showStatus))} - className="ml-2 align-middle" - value={props.showStatus} - onSelect={props.selectStatus} - menuAlign="right" - > - {props.showStatus ? 'Clear filter' : 'Choose Status'} - {statusList.map((status, index) => ( - {status} - ))} - + + {/* 3. Active status column header */} + + + {ACTIVE} + {renderDropdownFilterButton('project-status-filter', props.showStatus, props.selectStatus, statusList, 'Choose Status')} - - {INVENTORY} -
- {renderSortButton('INVENTORY')} -
+ + {/* 4. Inventory column header */} +
+ + {INVENTORY} +
{renderSortButton('INVENTORY')}
- - {MEMBERS} - {renderSortButton('MEMBERS')} + + {/* 5. Members column header */} + + + {MEMBERS} +
+ {renderSortButton('MEMBERS')} +
-
- {WBS} + + {/* 6. WBS column header */} +
+
+ {WBS}
+ {ARCHIVE}
+
+

Resolved and Closed Tasks

+
diff --git a/src/components/Projects/WBS/SingleTask/SingleTask.module.css b/src/components/Projects/WBS/SingleTask/SingleTask.module.css index 89abb2e7ee6..efd741139a8 100644 --- a/src/components/Projects/WBS/SingleTask/SingleTask.module.css +++ b/src/components/Projects/WBS/SingleTask/SingleTask.module.css @@ -12,4 +12,10 @@ display: inline-flex; align-items: center; justify-content: center; +} +.singleTaskTableDark tbody tr:hover, +.singleTaskTableDark tbody tr:hover > th, +.singleTaskTableDark tbody tr:hover > td { + background-color: #111831 !important; + color: #fff !important; } \ No newline at end of file diff --git a/src/components/Projects/WBS/WBSDetail/components/TagsSearch.jsx b/src/components/Projects/WBS/WBSDetail/components/TagsSearch.jsx index 20054384683..a6a993e78e2 100644 --- a/src/components/Projects/WBS/WBSDetail/components/TagsSearch.jsx +++ b/src/components/Projects/WBS/WBSDetail/components/TagsSearch.jsx @@ -1,6 +1,7 @@ import React, { useState, useMemo } from 'react'; import { connect } from 'react-redux'; import TagSent from './TagSent'; +import appStyles from '~/App.module.css'; import styles from './TagsSearch.module.css'; import ReadOnlySectionWrapper from '../EditTask/ReadOnlySectionWrapper'; import { findProjectMembers } from '../../../../../actions/projectMembers'; @@ -110,7 +111,7 @@ function TagsSearch(props) { type="text" placeholder={placeholder} className={`border border-dark rounded form-control px-2 ${ - darkMode ? 'bg-darkmode-liblack text-light border-0' : '' + darkMode ? `${appStyles['bg-darkmode-liblack']} text-light border-0` : '' }`} value={searchWord} onChange={e => handleFilter(e)} @@ -159,6 +160,7 @@ function TagsSearch(props) { const mapStateToProps = state => ({ // ✅ do NOT overwrite `members` prop anymore membersFromStore: state.projectMembers.members, + darkMode: state.theme.darkMode, foundProjectMembers: state.projectMembers.foundProjectMembers, }); diff --git a/src/components/Projects/WBS/WBSDetail/components/TagsSearch.module.css b/src/components/Projects/WBS/WBSDetail/components/TagsSearch.module.css index 09315534689..7067cf0e3ec 100644 --- a/src/components/Projects/WBS/WBSDetail/components/TagsSearch.module.css +++ b/src/components/Projects/WBS/WBSDetail/components/TagsSearch.module.css @@ -15,8 +15,9 @@ } -:global(body.dark-mode:not(.no-global-theme)) .darkDropdown { +.darkDropdown { background-color: #1e293b; + border-color: #334155; } .darkDropdownItem { diff --git a/src/components/Projects/WBS/WBSDetail/components/__tests__/TagsSearch.test.jsx b/src/components/Projects/WBS/WBSDetail/components/__tests__/TagsSearch.test.jsx index 9cfe6c6a05a..fbae47fb155 100644 --- a/src/components/Projects/WBS/WBSDetail/components/__tests__/TagsSearch.test.jsx +++ b/src/components/Projects/WBS/WBSDetail/components/__tests__/TagsSearch.test.jsx @@ -10,10 +10,16 @@ import { findProjectMembers } from '~/actions/projectMembers'; // Mock member data const allMembers = [ - { firstName: 'aaa', isActive: true, lastName: 'volunteer', _id: 'aaa123' }, - { firstName: 'bbb', isActive: true, lastName: 'test', _id: 'bbb456' }, - { firstName: 'ccc', isActive: false, lastName: 'manager', _id: 'ccc789' }, - { firstName: 'aaa', isActive: true, lastName: 'owner', _id: 'aaa067' }, + { + firstName: 'aaa', + isActive: true, + lastName: 'volunteer', + _id: 'aaa123', + profilePic: 'pic1.jpg', + }, + { firstName: 'bbb', isActive: true, lastName: 'test', _id: 'bbb456', profilePic: 'pic2.jpg' }, + { firstName: 'ccc', isActive: false, lastName: 'manager', _id: 'ccc789', profilePic: 'pic3.jpg' }, + { firstName: 'aaa', isActive: true, lastName: 'owner', _id: 'aaa067', profilePic: 'pic4.jpg' }, ]; const middlewares = [thunk]; @@ -42,6 +48,7 @@ const mockFoundProjectMembers = searchQuery => { const renderTagsSearchComponent = props => { const store = mockStore({ projectMembers: { foundProjectMembers: mockFoundProjectMembers('') }, // Initial empty search + theme: { darkMode: false }, }); return render( diff --git a/src/components/Projects/WBS/WBSDetail/wbs.module.css b/src/components/Projects/WBS/WBSDetail/wbs.module.css index caac3b3bdb0..607b1058e5b 100644 --- a/src/components/Projects/WBS/WBSDetail/wbs.module.css +++ b/src/components/Projects/WBS/WBSDetail/wbs.module.css @@ -406,8 +406,9 @@ justify-content: center; } -.editTaskTableDark tr:hover { - background: #111831; +.editTaskTableDark tbody tr:hover > td { + background-color: #111831 !important; + color: #fff !important; } .editTaskTextareaDark { diff --git a/src/components/Projects/projects.module.css b/src/components/Projects/projects.module.css index 2a3ba4428e2..117d94ac999 100644 --- a/src/components/Projects/projects.module.css +++ b/src/components/Projects/projects.module.css @@ -14,31 +14,31 @@ whatever is left (~25%). Keeping them as percentages lets the table shrink to its wrapper instead of overflowing it. */ :global(#projects__order) { - width: 5%; + width: 4%; } :global(#projects__active) { - width: 8%; + width: 12%; } :global(#projects__category) { - width: 15%; + width: 14%; } :global(#projects__members) { - width: 12%; + width: 13%; } :global(#projects__inv) { - width: 12%; + width: 16%; } :global(#projects__wbs) { - width: 12%; + width: 10%; } :global(#projects__delete) { - width: 11%; + width: 10%; } /* Fixed layout ties column widths to the header row, so long values in a cell @@ -200,12 +200,15 @@ .project-member-badge { position: absolute; top: -10px; - right: -32px; - min-width: 22px; - height: 22px; + right: -48px; + /* Replaced fixed dimensions with padding so the badge expands gracefully for multi-digit numbers */ + padding: 2px 5px; + /* min-width: 22px; */ + min-height: 22px; background: lawngreen; - color: #111; - border-radius: 50%; + color: #111 !important; + border-radius: 50px; /* Adapts from a circle to a clean pill shape as text length increases */ + display: flex; align-items: center; justify-content: center; @@ -215,6 +218,12 @@ z-index: 2; } +/* Increased specificity to ensure badge text remains strictly black in both light and dark modes */ + .project-member-badge.badgeTextBlack { + color: #111 !important; +} + + .project-member-btn .fa-users { font-size: 1.5rem; line-height: 1; @@ -232,12 +241,12 @@ .suggestion-button { display: block; - width: 100%; - padding: 10px; - text-align: left; - background: none; - border: none; - cursor: pointer; + width: 100%; + padding: 10px; + text-align: left; + background: none; + border: none; + cursor: pointer; } .suggestion-button:hover { @@ -271,6 +280,24 @@ background-color: #0056b3; } + +/* Header filter toggles only (Category / Active): fixed 30x30 box, no Bootstrap caret. + Scoped to .projectFilterDropdown so other dropdowns (account, nav menus) keep their size and arrow. */ +.projectFilterDropdown :global(.dropdown-toggle) { + width: 30px !important; + height: 30px !important; + padding: 0 !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; +} + +.projectFilterDropdown :global(.dropdown-toggle)::after { + display: none !important; + content: none !important; + border: none !important; +} + @media (width <= 375px) { #new_project .form-control { flex: 1 1 auto; diff --git a/src/components/Reports/PeopleReport/CompletedTasksPieChart.jsx b/src/components/Reports/PeopleReport/CompletedTasksPieChart.jsx index 5c2e4e746de..ccb1b907c28 100644 --- a/src/components/Reports/PeopleReport/CompletedTasksPieChart.jsx +++ b/src/components/Reports/PeopleReport/CompletedTasksPieChart.jsx @@ -1,15 +1,17 @@ -import React, { useEffect, useMemo, useRef, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { useTable } from 'react-table'; import { Cell, Label, Pie, PieChart, ResponsiveContainer, Tooltip } from 'recharts'; -import { FiFolder } from 'react-icons/fi'; +import { FiChevronDown, FiChevronUp, FiFolder } from 'react-icons/fi'; import { CHART_RADIUS, CHART_SIZE } from '../../common/PieChart/constants'; import { generateArrayOfUniqColors } from '../../common/PieChart/colorsGenerator'; import { peopleTasksPieChartViewData } from './selectors'; import styles from './CompletedTasksPieChart.module.css'; -// Reserve space for the "Show more" footer so it doesn't push the last visible row offscreen. -const FOOTER_RESERVED_ROWS = 1; +// Hard cap on the rows rendered in the collapsed legend. Fixed rather than derived +// from the viewport so the card is the same height on every screen — these reports +// get screenshotted into work confirmation letters and the bottom edge has to line up. +export const MAX_VISIBLE_TASKS = 20; export function ColorSwatchCell({ value, column }) { return ( @@ -80,57 +82,13 @@ function CompletedTasksPieChart({ darkMode }) { const pieChartId = 'completedTasksPieChart'; - // How many rows we can fit in the available height. When `expanded` is true we - // render every row regardless of this number. The renderer slices in half: the - // measurement effect owns the cap, the JSX owns the slice. - const tbodyRef = useRef(null); - const [visibleCount, setVisibleCount] = useState(tasks.length); const [expanded, setExpanded] = useState(false); - // Measure how many rows fit in the clamped tbody height. Uses the height of the - // first measured row — every row in the table has the same layout, so a single - // sample is enough. `expanded` short-circuits the measurement so all rows render. - useEffect(() => { - if (expanded) return undefined; - - const tbody = tbodyRef.current; - if (!tbody) return undefined; - - const recompute = () => { - // Budget comes from CSS (max-height on .legend-scroll-area tbody), NOT from - // the tbody's rendered height — that would feed back on itself because the - // tbody's height is a function of how many rows we render into it. - const tbodyStyles = window.getComputedStyle(tbody); - const maxHeightPx = Number.parseFloat(tbodyStyles.maxHeight); - if (!Number.isFinite(maxHeightPx) || maxHeightPx <= 0) { - setVisibleCount(tasks.length); - return; - } - const firstCell = tbody.querySelector('td'); - const rowHeight = firstCell ? firstCell.getBoundingClientRect().height : 0; - if (!rowHeight) { - setVisibleCount(tasks.length); - return; - } - const fits = Math.max( - 0, - Math.floor(maxHeightPx / rowHeight) - FOOTER_RESERVED_ROWS, - ); - setVisibleCount(Math.min(tasks.length, fits)); - }; - - recompute(); - const ro = new ResizeObserver(recompute); - ro.observe(tbody); - window.addEventListener('resize', recompute); - return () => { - ro.disconnect(); - window.removeEventListener('resize', recompute); - }; - }, [tasks.length, expanded]); - - const hiddenCount = expanded ? 0 : Math.max(0, tasks.length - visibleCount); - const tasksView = expanded ? tasks : tasks.slice(0, visibleCount); + const hiddenCount = Math.max(0, tasks.length - MAX_VISIBLE_TASKS); + const tasksView = expanded ? tasks : tasks.slice(0, MAX_VISIBLE_TASKS); + const moreTasksLabel = `+ ${hiddenCount} more task${hiddenCount === 1 ? '' : 's'}`; + const toggleLabel = expanded ? 'Show less' : moreTasksLabel; + const ToggleIcon = expanded ? FiChevronUp : FiChevronDown; const colorScale = useMemo(() => { const domain = tasks.map(t => t.projectId); @@ -236,7 +194,7 @@ function CompletedTasksPieChart({ darkMode }) {
-
+
{headerGroups.map(headerGroup => { @@ -259,7 +217,7 @@ function CompletedTasksPieChart({ darkMode }) { ); })} - + {rows.map(row => { prepareRow(row); const { key, ...rowProps } = row.getRowProps(); @@ -287,21 +245,13 @@ function CompletedTasksPieChart({ darkMode }) {
-
- )} - {expanded && ( -
-
)} diff --git a/src/components/Reports/PeopleReport/CompletedTasksPieChart.module.css b/src/components/Reports/PeopleReport/CompletedTasksPieChart.module.css index 202af563fd6..fc92f7778f6 100644 --- a/src/components/Reports/PeopleReport/CompletedTasksPieChart.module.css +++ b/src/components/Reports/PeopleReport/CompletedTasksPieChart.module.css @@ -15,7 +15,12 @@ border-radius: 12px; background-color: #fff; padding: 1rem; - margin: 2px; + + /* No margin: this is the last card in PeopleReport's left column, so any margin here + lifts its visible bottom edge above the column's bottom and it no longer lines up + with the profile card on the right. It also keeps the card flush with the metric + cards and pie chart above it. */ + margin: 0; display: flex; flex-direction: column; box-shadow: 0 0 12px #eae1f6; @@ -71,10 +76,8 @@ .completedTasksTable .taskNameRow { color: #888; overflow: hidden; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - line-clamp: 2; + white-space: nowrap; /* Prevent text from wrapping */ + text-overflow: ellipsis; /* Display ellipsis (...) for overflowing text */ padding: 0; margin: 8px; } @@ -88,10 +91,6 @@ background-color: transparent; } -.legend-scroll-area tbody { - max-height: calc(70vh); -} - .more-rows-footer { display: flex; justify-content: center; @@ -99,6 +98,9 @@ } .show-more-btn { + display: inline-flex; + align-items: center; + column-gap: 0.35rem; border: 1px solid #b58cdb; background: #f4ecff; color: #5b2a86; @@ -109,6 +111,10 @@ transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease; } +.show-more-icon { + flex-shrink: 0; +} + .show-more-btn:hover { background: #ead7ff; border-color: #7b3fad; @@ -131,11 +137,14 @@ border-radius: 50%; } +/* Pinned to the bottom of the legend column so the card's bottom edge lines up + with the pie chart whether the list is collapsed or expanded. */ .data-total-hours { display: flex; justify-content: center; align-items: center; column-gap: 0.5rem; + margin-top: auto; } @media(width >= 768px) { @@ -168,12 +177,6 @@ } } -@media (width >= 2000px) { - .legend-scroll-area tbody { - max-height: 65vh; - } -} - :global(.dark-mode) { .report-block { background-color: #1a2639; diff --git a/src/components/Reports/PeopleReport/PeopleReport.jsx b/src/components/Reports/PeopleReport/PeopleReport.jsx index 1b9fc529617..16e6ac40163 100644 --- a/src/components/Reports/PeopleReport/PeopleReport.jsx +++ b/src/components/Reports/PeopleReport/PeopleReport.jsx @@ -18,8 +18,8 @@ import { getTimeEntriesForPeriod } from '../../../actions/timeEntries'; import { ReportPage } from '../sharedComponents/ReportPage'; import { getPeopleReportData } from './selectors'; import { PeopleTasksPieChart } from './components'; -import { Checkbox } from '../../common/Checkbox'; import { updateRehireableStatus } from '../../../actions/userManagement'; +import RehireableStatusControl from '../../UserProfile/RehireableStatusControl'; import InfringementsViz from '../InfringementsViz'; import TimeEntriesViz from '../TimeEntriesViz'; import BadgeSummaryViz from '../BadgeSummaryViz'; @@ -86,15 +86,17 @@ function PeopleReport(props) { }, [userProfile?._id, userProfile?.isRehireable]); const setRehireable = useCallback( - async rehireValue => { + async (rehireValue, reason) => { const previousValue = isRehireable; setIsRehireableState(rehireValue); try { - await updateRehireableStatus(userProfile, rehireValue); + await updateRehireableStatus(userProfile, rehireValue, reason); toast.success(`You have changed the rehireable status of this user to ${rehireValue}`); + return true; } catch (err) { setIsRehireableState(previousValue); - alert('An error occurred while attempting to save the rehireable status of this user.'); + toast.error('An error occurred while attempting to save the rehireable status of this user.'); + return false; } }, [isRehireable, updateRehireableStatus, userProfile], @@ -256,14 +258,13 @@ function PeopleReport(props) {
- setRehireable(event.target.checked)} - label="Rehireable" +
diff --git a/src/components/Reports/PeopleReport/PeopleReport.module.css b/src/components/Reports/PeopleReport/PeopleReport.module.css index b8a0b0901d6..0775613ec21 100644 --- a/src/components/Reports/PeopleReport/PeopleReport.module.css +++ b/src/components/Reports/PeopleReport/PeopleReport.module.css @@ -292,6 +292,19 @@ body { stroke: rgb(255 255 255 / 15%); } +/* When there are only 3 metrics (e.g., for deactivated users): keep each card's width identical to the 4-metric layout without stretching, center them to make the overall section narrower, and eliminate dead space */ +.metrics.threeMetrics { + justify-content: center; + gap: 1.rem; + display: flex; + flex-wrap: wrap; +} + +.metrics.threeMetrics > .metricCard { + flex: 0 1 calc((100% - 3rem) / 4); + min-width: 220px; +} + @media (width <= 850px) { .introDate { margin: 16px 0; @@ -334,7 +347,9 @@ body { @media (width <= 1488px) { .peopleReportTimeLogsWrapper > .peopleReportTimeLogBlock { - flex: 0 1 calc((100% - 1rem) / 2); + /* flex: 0 1 calc((100% - 1rem) / 2); */ + flex: 0 1 calc((100% - 2rem) / 3); + max-width: none; } } @@ -351,6 +366,7 @@ body { .peopleReportTimeLogsWrapper.threeBoxes > .peopleReportTimeLogBlock { flex: 0 1 calc((100% - 2rem) / 3); /* 3 per row */ + flex: 0 1 100%; } /* Prevent wrapping weirdly at mid-screen sizes for 3-box layout */ @@ -462,40 +478,50 @@ body { width: 100%; } +/* Right-side stats card with flexbox layout for even vertical distribution */ .reportStats { - flex-grow: 1; + flex: 1; display: flex; flex-direction: column; justify-content: space-between; + align-items: center; background-color: white; padding: 2rem; border-radius: 16px; box-shadow: 0 0 12px rgb(0 0 0 / 8%); - height: 698px; - margin-top: 2rem; + height: 100%; + margin-top: 0; + width: 100%; + gap: 12px; /* Uniform spacing between internal elements (name, role, title, dates) */ +} + +/* Ensure all direct children of reportStats participate in flex layout */ +.reportStats > * { + width: 100%; + flex-shrink: 0; } @media (width >= 1489px) and (width <= 1784px) { .reportStats { - height: 721px; + /* height removed - now 100% from parent */ } } @media (width >= 1156px) and (width <= 1488px) { .reportStats { - height: 869px; + /* height removed - now 100% from parent */ } } @media (width >= 1025px) and (width <= 1155px) { .reportStats { - height: 873px; + /* height removed - now 100% from parent */ } } @media (width >= 960px) and (width <= 1024px) { .reportStats { - height: 895px; + /* height removed - now 100% from parent */ } } @@ -648,8 +674,32 @@ body { flex-direction: row-reverse; } + /* .userProfile is already stretched to the row's height (align-items: stretch). + Making it a flex column lets the ReportBlock inside fill that height exactly, + instead of relying on percentage heights. */ .userProfile { max-width: 20rem; + display: flex; + flex-direction: column; + } + + /* The shared ReportBlock sets its inner content to height: 100% plus margin: 2px, so + the content overflows its wrapper by 4px and the visible card ends below the left + column. Here we swap the percentage heights for flex: 1 and drop the margin so the + card's bottom edge sits exactly on the row's bottom edge. + ReportBlock's class names are hashed by CSS Modules and can't be referenced from + this file, so we target its data-testid attributes instead. */ + .userProfile > [data-testid='report-block-wrapper'] { + flex: 1; + height: auto; + display: flex; + flex-direction: column; + } + + .userProfile [data-testid='report-block-content'] { + flex: 1; + height: auto; + margin: 0; } .metrics.fourMetrics { diff --git a/src/components/Reports/PeopleReport/__tests__/CompletedTasksPieChart.test.jsx b/src/components/Reports/PeopleReport/__tests__/CompletedTasksPieChart.test.jsx index 3f586d7bc75..5a8d2e177f1 100644 --- a/src/components/Reports/PeopleReport/__tests__/CompletedTasksPieChart.test.jsx +++ b/src/components/Reports/PeopleReport/__tests__/CompletedTasksPieChart.test.jsx @@ -1,11 +1,100 @@ -import { render, screen } from '@testing-library/react'; -import { describe, expect, it } from 'vitest'; -import { +import { fireEvent, render, screen } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import CompletedTasksPieChart, { ColorSwatchCell, + MAX_VISIBLE_TASKS, PieTooltip, TotalHoursLabel, } from '../CompletedTasksPieChart'; +const mockUseSelector = vi.fn(); + +vi.mock('react-redux', async () => { + const actual = await vi.importActual('react-redux'); + return { + ...actual, + useSelector: selector => mockUseSelector(selector), + }; +}); + +const makeTasks = count => + Array.from({ length: count }, (unused, i) => ({ + projectId: `proj-${i}`, + projectName: `Task ${i}`, + totalTime: 1, + })); + +const renderChart = taskCount => { + mockUseSelector.mockReturnValue({ tasksWithLoggedHoursById: makeTasks(taskCount) }); + return render(); +}; + +const countTaskRows = () => + screen.getAllByTestId('color-swatch').length; + +describe('CompletedTasksPieChart task list cap', () => { + beforeEach(() => { + mockUseSelector.mockReset(); + }); + + // Pinned to the literal on purpose: the other tests reference MAX_VISIBLE_TASKS + // symbolically, so they stay green if the cap is lowered for local debugging. + // This one fails if a temporary value gets committed. + it('caps the collapsed list at 20, the agreed product limit', () => { + expect(MAX_VISIBLE_TASKS).toBe(20); + }); + + it('caps the collapsed list at the limit', () => { + renderChart(MAX_VISIBLE_TASKS + 13); + + expect(countTaskRows()).toBe(MAX_VISIBLE_TASKS); + }); + + it('renders every task without a toggle when at or under the cap', () => { + renderChart(MAX_VISIBLE_TASKS); + + expect(countTaskRows()).toBe(MAX_VISIBLE_TASKS); + expect(screen.queryByTestId('toggle-more-tasks')).not.toBeInTheDocument(); + }); + + it('labels the toggle with the number of hidden tasks', () => { + renderChart(MAX_VISIBLE_TASKS + 13); + + expect(screen.getByTestId('toggle-more-tasks')).toHaveTextContent('+ 13 more tasks'); + }); + + it('singularizes the label when exactly one task is hidden', () => { + renderChart(MAX_VISIBLE_TASKS + 1); + + expect(screen.getByTestId('toggle-more-tasks')).toHaveTextContent('+ 1 more task'); + }); + + it('expands to every task and collapses back to the cap', () => { + renderChart(MAX_VISIBLE_TASKS + 13); + const toggle = screen.getByTestId('toggle-more-tasks'); + + expect(toggle).toHaveAttribute('aria-expanded', 'false'); + + fireEvent.click(toggle); + expect(countTaskRows()).toBe(MAX_VISIBLE_TASKS + 13); + expect(toggle).toHaveAttribute('aria-expanded', 'true'); + expect(toggle).toHaveTextContent('Show less'); + + fireEvent.click(toggle); + expect(countTaskRows()).toBe(MAX_VISIBLE_TASKS); + expect(toggle).toHaveAttribute('aria-expanded', 'false'); + expect(toggle).toHaveTextContent('+ 13 more tasks'); + }); + + it('keeps the total hours row rendered after the list in both states', () => { + renderChart(MAX_VISIBLE_TASKS + 5); + + expect(screen.getByText('Total Hours:')).toBeInTheDocument(); + fireEvent.click(screen.getByTestId('toggle-more-tasks')); + expect(screen.getByText('Total Hours:')).toBeInTheDocument(); + }); +}); + describe('ColorSwatchCell', () => { const colorScale = { proj1: '#ff00aa', proj2: '#00aaff' }; diff --git a/src/components/Reports/PeopleTableDetails.jsx b/src/components/Reports/PeopleTableDetails.jsx index 17d29ea540e..745236d3760 100644 --- a/src/components/Reports/PeopleTableDetails.jsx +++ b/src/components/Reports/PeopleTableDetails.jsx @@ -4,6 +4,12 @@ import { useTable } from 'react-table'; import styles from './PeopleTableDetails.module.css'; import TableFilter from './TableFilter/TableFilter'; +/** + * TaskResourceCell Component + * Renders the primary profile pictures for assigned resources (up to 2), + * a collapse/expand toggle button for additional resources, and a hidden/visible + * container for extra resources when expanded. + */ export function TaskResourceCell({ row, column, @@ -16,9 +22,9 @@ export function TaskResourceCell({ return ( <> - {taskResources.slice(0, 2).map((resource, index) => ( + {taskResources.slice(0, 2).map((resource) => ( {resource.name} - {taskResources.slice(2).map((resource, index) => ( + {taskResources.slice(2).map((resource) => ( {resource.name} @@ -65,11 +75,21 @@ export function YesNoCell({ value }) { ); } +/** + * CenteredValueCell Component + * Renders any standard text value centered within its table cell. + */ export function CenteredValueCell({ value }) { return
{value}
; } +/** + * PeopleTableDetails Main Component + * Manages filtering states, table data configuration using react-table, + * desktop table layout, and responsive mobile card view. + */ function PeopleTableDetails(props) { + // Filter search states const [name, setName] = useState(''); const [priority, setPriority] = useState(''); const [status, setStatus] = useState(''); @@ -140,7 +160,6 @@ function PeopleTableDetails(props) { return filteredList; }; - // REFACTORED: Toggle using state instead of direct DOM manipulation const toggleMoreResources = useCallback((id) => { setExpandedTasks((prev) => ({ ...prev, @@ -244,6 +263,7 @@ function PeopleTableDetails(props) { Clear Filters
+
@@ -283,8 +303,53 @@ function PeopleTableDetails(props) {
+ +
+ {filteredTasks.map((task) => ( +
+
+ {task.taskName} + {task.status || 'Started'} +
+
+
+
Priority
+
{task.priority}
+
+
+
Resources
+
+ {(task.resources || []).flat().map((res) => ( + {res.name} + ))} +
+
+
+
Active
+
{task.active}
+
+
+
Assign
+
{task.assign}
+
+
+
Estimated Hours
+
{task.estimatedHours}
+
+
+
Start Date
+
{task.startDate}
+
+
+
End Date
+
{task.endDate}
+
+
+
+ ))} +
); } -export default PeopleTableDetails; +export default PeopleTableDetails; \ No newline at end of file diff --git a/src/components/Reports/PeopleTableDetails.module.css b/src/components/Reports/PeopleTableDetails.module.css index 2a293a9ed93..8103592e245 100644 --- a/src/components/Reports/PeopleTableDetails.module.css +++ b/src/components/Reports/PeopleTableDetails.module.css @@ -1,4 +1,3 @@ -/* stylelint-disable declaration-property-value-no-unknown, no-descending-specificity */ .wrapper { overflow-x: auto; width: 100%; @@ -55,7 +54,6 @@ overflow: hidden; } -/* Profile picture styling */ .img-circle { border-radius: 50%; height: 30px; @@ -95,11 +93,16 @@ color: #f1f1f1; } +.people-table-row-dark { + background-color: transparent !important; + color: #fff !important; + border-bottom: 1px solid #444 !important; +} + .people-table-row:hover { background-color: #fafafa; } -/* ✅ merged hover style */ .people-table-row-dark:hover { background-color: #232946 !important; color: #fff !important; @@ -153,7 +156,7 @@ .extra { display: none; - border: collapse; + border: none; } .extra1 { @@ -173,32 +176,54 @@ } .task-card-dark { - color: black; + color: #fff; + background-color: #232946; + border: 1px solid #444; } .task-header { background-color: #eee7f8; display: flex; justify-content: space-between; + align-items: flex-start; + gap: 10px; padding: 15px; border-top-left-radius: 10px; border-top-right-radius: 10px; - align-items: flex-start; +} + +.task-card-dark .task-header { + background-color: #1a1a2e; + color: #fff; } .task-status { display: flex; align-items: center; - padding: 5px 10px; + justify-content: center; + padding: 4px 10px; border-radius: 20px; background-color: #ffc107; color: #fff; - width: fit-content; - margin-left: 5px; + flex-shrink: 0; + white-space: nowrap; + margin-left: 0; +} + +.task-card-dark .task-status { + background-color: #ca50db; + color: #fff; } .task-info { display: flex; + padding: 6px 0; + border-bottom: 1px solid #f2f2f2; +} + +.task-card-dark .task-info { + border-bottom: 1px solid #374151; + color: #fff; } .sub-head { @@ -206,12 +231,22 @@ text-align: end; width: 50%; padding-right: 2%; + color: #4b5563; +} + +.task-card-dark .sub-head { + color: #9ca3af; } .sub-details { text-align: start; width: 50%; padding-left: 2%; + color: #1f2937; +} + +.task-card-dark .sub-details { + color: #fff; } .table-filter-container { @@ -249,130 +284,99 @@ color: #e7b1ef; } -/* Dark mode styling for Clear Filters button */ -.wrapperDark .tasks-table-clear-filter-button { - background-color: #232946 !important; - border: 2px solid #5A67D8 !important; - color: #fff !important; -} - -.wrapperDark .tasks-table-clear-filter-button:hover { - background-color: #1C2541 !important; - border-color: #ca50db !important; -} - .people-report-task-name { - overflow-wrap: break-word; - min-width: 200px; + flex: 1; + /* Flex items default to min-width: auto (their longest word), so a space-free name + would refuse to shrink and push .task-status out of the card. */ + min-width: 0; + font-weight: 600; + font-size: 16px; text-align: left; -} - -.task-name-word-break { - word-break: break-all; + overflow-wrap: break-word; } .people-table-scrollable { - max-height: 600px; - overflow-y: auto; width: 100%; + max-height: 600px; + overflow: auto; + -webkit-overflow-scrolling: touch; + box-sizing: border-box; } -.peopleTableReact { - width: 100%; - min-width: 720px; - border-collapse: collapse; -} -.peopleTableReact th, -.peopleTableReact td { - padding: 8px; - text-align: left; - overflow-wrap: break-word; - vertical-align: middle; -} +/* ========== FIX: Scrollbar styling for both light and dark modes ========== Light Mode: Display scrollbar with light theme colors for better visibility */ -.peopleTableReact th { - background-color: #eee7f8; - font-size: 18px; +.people-table-scrollable::-webkit-scrollbar { + height: 8px; + width: 8px; } -.peopleTableReact td { - border-bottom: 1px solid #f8f7f8; - font-size: 16px; +.people-table-scrollable::-webkit-scrollbar-track { + background: #f0f0f0; + border-radius: 4px; } -.peopleTableReact th:first-child, -.peopleTableReact td:first-child { - width: 28%; +.people-table-scrollable::-webkit-scrollbar-thumb { + background: #999; + border-radius: 4px; } -.peopleTableReact th:nth-child(4), -.peopleTableReact td:nth-child(4) { - width: 14%; +.people-table-scrollable::-webkit-scrollbar-thumb:hover { + background: #666; } -.peopleTableReact tbody tr:hover { - background-color: #fafafa; -} -.people-table-row-dark td { - border-color: #374151; -} +/* Dark Mode: Override light mode styles with dark theme colors */ -.reports-table-head-dark th { - background-color: #1b2a41; - color: #f9fafb; +:global(.dark-mode) .people-table-scrollable::-webkit-scrollbar-track { + background: #162032; } -.wrapperDark .people-table-scrollable { - background-color: #162032; - border: 1px solid #3a4460; - border-radius: 8px; - padding: 4px 0; +:global(.dark-mode) .people-table-scrollable::-webkit-scrollbar-thumb { + background: #4b5563; } -/* Dark mode for mobile modal cards */ -.task-card.task-card-dark { - background-color: #232946; - color: #fff; - border: 1px solid #444; +:global(.dark-mode) .people-table-scrollable::-webkit-scrollbar-thumb:hover { + background: #6b7280; } -.task-card.task-card-dark .task-header { - background-color: #1a1a2e; - color: #fff; -} +/* ========== END: Scrollbar styling ========== */ -.task-card.task-card-dark .task-status { - background-color: #ca50db; - color: #fff; +.reports-table-head-dark th { + background-color: #1b2a41; + color: #f9fafb; } -.task-card.task-card-dark .task-info { - color: #fff; +.reports-table-head-dark { + background-color: #1a1a2e !important; + color: #fff !important; + border-bottom: 1px solid #444 !important; } -.task-card.task-card-dark .sub-head, -.task-card.task-card-dark .sub-details { - color: #fff; +.people-table-row-dark td { + border-color: #374151; } -/* Modal textarea dark mode */ -.task-card-dark .rectangle { - background: #232946; - color: #fff; - border: 1.5px solid #444; +.peopleTableReact { + width: 100%; + min-width: 850px; + border-collapse: collapse; } -/* Desktop table dark mode */ -.reports-table-head-dark { - background-color: #1a1a2e !important; - color: #fff !important; +.peopleTableReact th, +.peopleTableReact td { + padding: 8px; + text-align: left; + overflow-wrap: break-word; + vertical-align: middle; } -.people-table-row-dark { - background-color: transparent !important; - color: #fff !important; +.peopleTableReact th:first-child, +.peopleTableReact td:first-child { + width: 28%; + min-width: 260px; + max-width: 350px; + overflow-wrap: break-word; } .people-table-row-dark > div, @@ -380,25 +384,31 @@ color: #fff !important; } -.people-table-row-dark .people-table-center-cell, -.people-table-row-dark .people-table-end-cell { - color: #fff !important; +.centerColumn { + text-align: center !important; } -/* Table cell border for dark mode */ -.people-table-row-dark, -.reports-table-head-dark { - border-bottom: 1px solid #444 !important; +:global(.dark-mode) .peopleTableReact { + background-color: #1b2a41; + color: #f9fafb; } -/* Table textarea dark mode */ -.people-table-row-dark .rectangle, -.reports-table-head-dark .rectangle { - background: #232946; - color: #fff; - border: 1px solid #444; +:global(.dark-mode) .people-table-row-dark { + background-color: #1b2a41 !important; + color: #f9fafb !important; } -.centerColumn { - text-align: center !important; +.mobileCardContainer { + display: none; +} + +@media (width <= 600px) { + .people-table-scrollable { + display: none !important; + } + + .mobileCardContainer { + display: block !important; + width: 100%; + } } \ No newline at end of file diff --git a/src/components/Reports/__tests__/PeopleTableDetails.test.jsx b/src/components/Reports/__tests__/PeopleTableDetails.test.jsx index b7bfd66c849..6589022558c 100644 --- a/src/components/Reports/__tests__/PeopleTableDetails.test.jsx +++ b/src/components/Reports/__tests__/PeopleTableDetails.test.jsx @@ -64,9 +64,9 @@ describe('Unit Test case for PeopleTableDetails component', () => { it('Test 3 : Verify row data renders', () => { render(); - expect(screen.getByText('Task 1')).toBeInTheDocument(); - expect(screen.getByText('Task 2')).toBeInTheDocument(); - expect(screen.getByText('Task 3')).toBeInTheDocument(); + expect(screen.getAllByText('Task 1')[0]).toBeInTheDocument(); + expect(screen.getAllByText('Task 2')[0]).toBeInTheDocument(); + expect(screen.getAllByText('Task 3')[0]).toBeInTheDocument(); }); it('displays a task with no resources and no start date', () => { @@ -78,7 +78,7 @@ describe('Unit Test case for PeopleTableDetails component', () => { render(); - expect(screen.getByText('Unassigned task')).toBeInTheDocument(); + expect(screen.getAllByText('Unassigned task')[0]).toBeInTheDocument(); }); it('Test 5 : Verify no toggle button if resources < 2', () => { @@ -88,14 +88,14 @@ describe('Unit Test case for PeopleTableDetails component', () => { it('Test 6 : Verify button renders if resources > 2', () => { render(); - expect(screen.getByRole('button', { name: /^\d+\+$/ })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: /^\d+\+$/ })[0]).toBeInTheDocument(); }); it('shows resource toggle button when there are more than 2 resources', () => { render(); - expect(screen.getByText('Project 2')).toBeInTheDocument(); - const toggleButton = screen.getByText('1+'); + expect(screen.getAllByText('Project 2')[0]).toBeInTheDocument(); + const toggleButton = screen.getAllByText('1+')[0]; expect(toggleButton).toBeInTheDocument(); }); @@ -103,7 +103,7 @@ describe('Unit Test case for PeopleTableDetails component', () => { const taskId = taskFixtureThreeNamedResources[0]._id; render(); - const toggleButton = screen.getByRole('button', { name: /^\d+\+$/ }); + const toggleButton = screen.getAllByRole('button', { name: /^\d+\+$/ })[0]; expect(toggleButton).toBeInTheDocument(); expect(screen.getByTestId(`extra-resources-${taskId}`)).toBeInTheDocument(); @@ -112,13 +112,13 @@ describe('Unit Test case for PeopleTableDetails component', () => { display: 'table-cell', }); - fireEvent.click(screen.getByRole('button', { name: /^\d+\+$/ })); + fireEvent.click(screen.getAllByRole('button', { name: /^\d+\+$/ })[0]); expect(screen.getByTestId(`extra-resources-${taskId}`)).toHaveStyle({ display: 'none' }); }); it('Test 8 : Verify remaining resource count displayed', () => { render(); - expect(screen.getByText('2+')).toBeInTheDocument(); + expect(screen.getAllByText('2+')[0]).toBeInTheDocument(); }); }); @@ -137,7 +137,7 @@ describe('TaskResourceCell', () => { {...baseProps} />, ); - expect(screen.getByText('1+')).toBeInTheDocument(); + expect(screen.getAllByText('1+')[0]).toBeInTheDocument(); }); it('shows the extra-resources block when the task is in expandedTasks', () => { @@ -163,7 +163,7 @@ describe('TaskResourceCell', () => { toggleMoreResources={toggleMoreResources} />, ); - fireEvent.click(screen.getByText('1+')); + fireEvent.click(screen.getAllByText('1+')[0]); expect(toggleMoreResources).toHaveBeenCalledWith(task._id); }); }); @@ -185,4 +185,4 @@ describe('CenteredValueCell', () => { render(); expect(screen.getByText('2022-01-01')).toHaveStyle({ textAlign: 'center' }); }); -}); +}); \ No newline at end of file diff --git a/src/components/Reports/sharedComponents/ReportPage/components/ReportBlock/ReportBlock.module.css b/src/components/Reports/sharedComponents/ReportPage/components/ReportBlock/ReportBlock.module.css index ee239fa557e..4539aabcf3b 100644 --- a/src/components/Reports/sharedComponents/ReportPage/components/ReportBlock/ReportBlock.module.css +++ b/src/components/Reports/sharedComponents/ReportPage/components/ReportBlock/ReportBlock.module.css @@ -9,9 +9,18 @@ .report-block-content { height: 100%; + display: flex; + flex-direction: column; padding: 1rem; border-radius: 12px; margin: 2px; + gap: 12px; /* Consistent spacing for better visual hierarchy */ +} + +/* Ensure children distribute evenly with flex layout and no shrinking */ +.report-block-content > * { + flex: 1; + width: 100%; } .report-block-wrapper-dark { diff --git a/src/components/ResolvedTasks/ResolvedTasks.jsx b/src/components/ResolvedTasks/ResolvedTasks.jsx new file mode 100644 index 00000000000..77dba93b7d9 --- /dev/null +++ b/src/components/ResolvedTasks/ResolvedTasks.jsx @@ -0,0 +1,125 @@ +import React, { useState, useEffect } from 'react'; +import { Container, Row, Col, Table } from 'reactstrap'; +import { connect } from 'react-redux'; +import axios from 'axios'; +import styles from './ResolvedTasks.module.css'; +import moment from 'moment'; +import { Link } from 'react-router-dom'; +import { ENDPOINTS } from '~/utils/URL'; +import PropTypes from 'prop-types'; + +const ResolvedTasks = props => { + const [tasks, setTasks] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const { darkMode } = props.theme; + + useEffect(() => { + const fetchResolvedTasks = async () => { + try { + const response = await axios.get(ENDPOINTS.RESOLVED_TASKS(1, 100)); + setTasks(response.data.tasks); + setLoading(false); + } catch (err) { + setError(err.message); + setLoading(false); + } + }; + + void fetchResolvedTasks(); + }, []); + + if (loading) return
Loading...
; + if (error) return
Error: {error}
; + + return ( + + +
+ + + + + + + + + + + {tasks.length === 0 ? ( + + + + ) : ( + tasks.map(item => ( + + + + + + + + )) + )} + +
#Task NameAssigned ResourcesResolved/Closed ByDate
+ No resolved tasks found. +
{item.taskId?.num || 'N/A'} + {item.taskId ? ( + + {item.taskId.taskName} + + ) : ( + Task deleted/unavailable + )} + + {item.taskId?.resources?.map((res, index) => ( +
+
{res.name}
+
+ {res.userID?.email || 'No email available'} +
+
+ ))} +
+
+ {item.userId + ? `${item.userId.firstName} ${item.userId.lastName}` + : item.userName || 'Unknown'} +
+
+ {item.userId?.email || item.userEmail || 'No email available'} +
+
{moment(item.timestamp).format('LLL')}
+ + + + ); +}; + +const mapStateToProps = state => ({ + theme: state.theme, +}); + +ResolvedTasks.propTypes = { + theme: PropTypes.shape({ + darkMode: PropTypes.bool, + }), +}; + +export default connect(mapStateToProps)(ResolvedTasks); diff --git a/src/components/ResolvedTasks/ResolvedTasks.module.css b/src/components/ResolvedTasks/ResolvedTasks.module.css new file mode 100644 index 00000000000..a0b40ec2059 --- /dev/null +++ b/src/components/ResolvedTasks/ResolvedTasks.module.css @@ -0,0 +1,10 @@ +:global(body.dark-mode) a.resolvedTaskLinkDark { + color: #66bfff !important; + text-decoration: underline; + font-weight: 500; +} + +:global(body.dark-mode) a.resolvedTaskLinkDark:hover { + color: #9dd7ff !important; + text-decoration: underline; +} diff --git a/src/components/ResolvedTasks/__tests__/ResolvedTasks.test.jsx b/src/components/ResolvedTasks/__tests__/ResolvedTasks.test.jsx new file mode 100644 index 00000000000..526da1dac70 --- /dev/null +++ b/src/components/ResolvedTasks/__tests__/ResolvedTasks.test.jsx @@ -0,0 +1,102 @@ +import { render, screen, waitFor } from '@testing-library/react'; +import axios from 'axios'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import { MemoryRouter } from 'react-router-dom'; +import ResolvedTasks from '../ResolvedTasks'; + +vi.mock('axios'); + +const mockStore = configureMockStore([]); + +const renderComponent = () => { + const store = mockStore({ + theme: { darkMode: false }, + }); + + return render( + + + + + , + ); +}; + +describe('ResolvedTasks', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('loads and displays resolved tasks', async () => { + axios.get.mockResolvedValue({ + data: { + tasks: [ + { + _id: 'log-1', + timestamp: '2026-09-30T12:00:00.000Z', + taskId: { + _id: 'task-1', + num: 123, + taskName: 'Test resolved task', + resources: [ + { + name: 'Assigned User', + userID: { + _id: 'user-1', + email: 'assigned@example.com', + }, + }, + ], + }, + userId: { + firstName: 'Admin', + lastName: 'User', + email: 'admin@example.com', + }, + }, + ], + }, + }); + + renderComponent(); + + expect(screen.getByText('Loading...')).toBeInTheDocument(); + + await waitFor(() => { + expect(screen.getByText('Test resolved task')).toBeInTheDocument(); + }); + + expect(axios.get).toHaveBeenCalledWith( + expect.stringContaining('/tasks/resolved?page=1&limit=100'), + ); + expect(screen.getByText('Assigned User')).toBeInTheDocument(); + expect(screen.getByText('assigned@example.com')).toBeInTheDocument(); + expect(screen.getByText('Admin User')).toBeInTheDocument(); + expect(screen.getByText('admin@example.com')).toBeInTheDocument(); + }); + + it('shows empty state when no resolved tasks exist', async () => { + axios.get.mockResolvedValue({ + data: { + tasks: [], + }, + }); + + renderComponent(); + + await waitFor(() => { + expect(screen.getByText('No resolved tasks found.')).toBeInTheDocument(); + }); + }); + + it('shows an error when loading fails', async () => { + axios.get.mockRejectedValue(new Error('Network error')); + + renderComponent(); + + await waitFor(() => { + expect(screen.getByText('Error: Network error')).toBeInTheDocument(); + }); + }); +}); diff --git a/src/components/TeamLocations/TeamLocations.countryCounts.test.jsx b/src/components/TeamLocations/TeamLocations.countryCounts.test.jsx new file mode 100644 index 00000000000..19bcea782af --- /dev/null +++ b/src/components/TeamLocations/TeamLocations.countryCounts.test.jsx @@ -0,0 +1,67 @@ +import axios from 'axios'; +import { render, screen } from '@testing-library/react'; +import TeamLocations from './TeamLocations'; + +const testState = vi.hoisted(() => ({ darkMode: false })); + +vi.mock('axios', () => ({ default: { get: vi.fn() } })); +vi.mock('react-redux', () => ({ + useSelector: selector => + selector({ auth: { user: { role: 'Volunteer' } }, theme: { darkMode: testState.darkMode } }), +})); +vi.mock('react-leaflet', async () => { + const { forwardRef } = await import('react'); + return { + MapContainer: forwardRef(({ children }, ref) =>
{children}
), + TileLayer: () => null, + useMapEvents: () => ({ getZoom: () => 3 }), + }; +}); +vi.mock('./TestSafeMarkerCluster', () => ({ default: ({ children }) =>
{children}
})); +vi.mock('./AddOrEditPopup', () => ({ default: () => null })); +vi.mock('./ListUsersPopUp', () => ({ default: () => null })); +vi.mock('./MarkerPopup', () => ({ default: () => null })); +vi.mock('./TeamLocationsTable', () => ({ default: () => null })); + +describe('Team Locations country counts', () => { + afterEach(() => { + vi.clearAllMocks(); + testState.darkMode = false; + }); + + it('shows the all-time and active counts from the map locations response', async () => { + axios.get.mockResolvedValue({ + data: { users: [], mUsers: [], countryCounts: { allTime: 76, active: 23 } }, + }); + + render(); + + const counts = await screen.findByLabelText('Volunteer country counts'); + expect(screen.getByRole('heading', { level: 5 })).toHaveTextContent('Total Countries:0'); + expect(counts).toHaveTextContent('All-time contributing countries: 76'); + expect(counts).toHaveTextContent('Currently active countries: 23'); + }); + + it('shows the counts in dark mode', async () => { + testState.darkMode = true; + axios.get.mockResolvedValue({ + data: { users: [], mUsers: [], countryCounts: { allTime: 76, active: 23 } }, + }); + + render(); + + const counts = await screen.findByLabelText('Volunteer country counts'); + expect(counts).toHaveTextContent('All-time contributing countries: 76'); + expect(counts).toHaveTextContent('Currently active countries: 23'); + }); + + it('keeps the two labels visible when the backend has not supplied counts', async () => { + axios.get.mockResolvedValue({ data: { users: [], mUsers: [] } }); + + render(); + + const counts = await screen.findByLabelText('Volunteer country counts'); + expect(counts).toHaveTextContent('All-time contributing countries: —'); + expect(counts).toHaveTextContent('Currently active countries: —'); + }); +}); diff --git a/src/components/TeamLocations/TeamLocations.jsx b/src/components/TeamLocations/TeamLocations.jsx index b5d52b1efb9..0db414f4a76 100644 --- a/src/components/TeamLocations/TeamLocations.jsx +++ b/src/components/TeamLocations/TeamLocations.jsx @@ -4,7 +4,7 @@ import { useEffect, useRef, useState, forwardRef, Suspense } from 'react'; import { MapContainer, TileLayer, useMapEvents } from 'react-leaflet'; import MarkerClusterGroup from './TestSafeMarkerCluster'; import { Button, Container, Spinner } from 'reactstrap'; -import './TeamLocations.module.css'; +import styles from './TeamLocations.module.css'; import { useSelector } from 'react-redux'; import { toast } from 'react-toastify'; @@ -36,6 +36,7 @@ const TeamLocations = forwardRef(() => { const [searchText, setSearchText] = useState(''); const [popupsOpen, setPopupsOpen] = useState(false); const [mapMarkers, setMapMarkers] = useState([]); + const [countryCounts, setCountryCounts] = useState(null); const [tableVisible, setTableVisible] = useState(false); const [markerPopupVisible, setMarkerPopupVisible] = useState(false); const role = useSelector(state => state.auth.user.role); @@ -71,6 +72,7 @@ const TeamLocations = forwardRef(() => { setUserProfiles(users); setManuallyAddedProfiles(mUsers); + setCountryCounts(locations.countryCounts ?? null); const allMapMarkers = [...users, ...mUsers]; const allMapMarkersOffset = allMapMarkers.map(ele => ({ ...ele, @@ -190,7 +192,7 @@ const TeamLocations = forwardRef(() => { return ( { Total Countries: {totalUniqueCountries}

+
+

+ All-time contributing countries: {countryCounts?.allTime ?? '—'} +

+

+ Currently active countries: {countryCounts?.active ?? '—'} +

+
{' '} - + {mode === 'details' ? ( + <> + {' '} + {' '} + + + ) : ( + <> + {' '} + + + )} @@ -105,14 +211,27 @@ function RehireableStatusControl({ isRehireable, notRehireableReason, darkMode, RehireableStatusControl.propTypes = { isRehireable: PropTypes.bool, notRehireableReason: PropTypes.string, + notRehireableReasonHistory: PropTypes.arrayOf(PropTypes.shape({ + action: PropTypes.string, + reason: PropTypes.string, + changedAt: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]), + changedBy: PropTypes.shape({ + firstName: PropTypes.string, + lastName: PropTypes.string, + username: PropTypes.string, + }), + })), darkMode: PropTypes.bool, onConfirm: PropTypes.func.isRequired, + showLabel: PropTypes.bool, }; RehireableStatusControl.defaultProps = { isRehireable: true, notRehireableReason: '', + notRehireableReasonHistory: [], darkMode: false, + showLabel: false, }; -export default RehireableStatusControl; \ No newline at end of file +export default RehireableStatusControl; diff --git a/src/components/UserProfile/TeamsAndProjects/UserTeamsTable.jsx b/src/components/UserProfile/TeamsAndProjects/UserTeamsTable.jsx index e04dd5a0230..63609310bc1 100644 --- a/src/components/UserProfile/TeamsAndProjects/UserTeamsTable.jsx +++ b/src/components/UserProfile/TeamsAndProjects/UserTeamsTable.jsx @@ -2,12 +2,10 @@ import { useEffect, useRef, useState } from 'react'; import { Button, Col, Input } from 'reactstrap'; import hasPermission from '../../../utils/permissions'; import './TeamsAndProjects.module.css'; -// import styles from './UserTeamsTable.css'; +import styles from './UserTeamsTable.module.css'; import { connect } from 'react-redux'; import { boxStyle } from '~/styles'; -import './UserTeamsTable.module.css'; - import { AutoCompleteTeamCode } from './AutoCompleteTeamCode'; import ToggleSwitch from '../UserProfileEdit/ToggleSwitch'; @@ -278,17 +276,38 @@ const UserTeamsTable = props => { {props.role && ( - - - - {canAssignTeamToUsers ? ( - <> - - - - ) : null} + + + + + {canAssignTeamToUsers ? ( + <> + + + + + ) : null} + )} @@ -296,13 +315,11 @@ const UserTeamsTable = props => { {teams.length > 0 ? ( teams.map((team, index) => ( - - + + {props.edit && props.role && ( <> -
#Team NameMembers - {} -
+ # + + Team Name + + Members + + {/* Keep the existing header content here */} +
{index + 1}{`${team.teamName}`}{index + 1}{`${team.teamName}`} + + + ); +} + +beforeEach(() => { + vi.clearAllMocks(); + axios.get.mockResolvedValue({ data: [] }); + axios.put.mockResolvedValue({ status: 200 }); +}); + +describe('Profile hours scroll protection', () => { + it.each([ + 'Weekly Committed Hours', + 'Additional Make-up Hours This Week', + 'Total Intangible Hours', + 'Total Tangible Education Hours', + 'Total Tangible Society Hours', + ])('blurs %s on wheel without cancelling page scrolling or changing hours', async placeholder => { + render(); + const input = screen.getByPlaceholderText(placeholder); + const value = input.value; + input.focus(); + expect(input).toHaveFocus(); + // jsdom does not implement native wheel stepping; Chromium covers that separately. + expect(fireEvent.wheel(input, { deltaY: 120, cancelable: true })).toBe(true); + expect(input).not.toHaveFocus(); + expect(input.value).toBe(value); + fireEvent.click(screen.getByRole('button', { name: 'Save fixture' })); + await waitFor(() => expect(axios.put).toHaveBeenCalledWith( + ENDPOINTS.USER_PROFILE(initialProfile._id), initialProfile, + )); + }); + + it.each([false, true])('saves the entered weekly hours for the target volunteer (dark=%s)', async darkMode => { + render(); + const input = screen.getByPlaceholderText('Weekly Committed Hours'); + fireEvent.change(input, { target: { value: '21' } }); + input.focus(); + fireEvent.wheel(input, { deltaY: -120 }); + fireEvent.click(screen.getByRole('button', { name: 'Save fixture' })); + await waitFor(() => expect(axios.put).toHaveBeenCalledWith( + ENDPOINTS.USER_PROFILE(initialProfile._id), + { ...initialProfile, weeklycommittedHours: 21 }, + )); + }); + + it('preserves intentional decimal edits to intangible and category hours', async () => { + render(); + fireEvent.change(screen.getByPlaceholderText('Total Intangible Hours'), { target: { value: '4.75' } }); + fireEvent.change(screen.getByPlaceholderText('Total Tangible Education Hours'), { target: { value: '9.25' } }); + fireEvent.click(screen.getByRole('button', { name: 'Save fixture' })); + await waitFor(() => expect(axios.put).toHaveBeenCalledWith( + ENDPOINTS.USER_PROFILE(initialProfile._id), + { ...initialProfile, totalIntangibleHrs: 4.75, hoursByCategory: { education: 9.25, society: 6 } }, + )); + }); + + it('keeps read-only hours non-editable', () => { + render(); + expect(screen.queryByRole('spinbutton')).not.toBeInTheDocument(); + expect(axios.put).not.toHaveBeenCalled(); + }); + + it.each([0, 168])('preserves the valid weekly-hours boundary %s when scrolling', async hours => { + render(); + const input = screen.getByPlaceholderText('Weekly Committed Hours'); + fireEvent.change(input, { target: { value: String(hours) } }); + input.focus(); + fireEvent.wheel(input, { deltaY: 120 }); + fireEvent.click(screen.getByRole('button', { name: 'Save fixture' })); + await waitFor(() => expect(axios.put).toHaveBeenCalledWith( + ENDPOINTS.USER_PROFILE(initialProfile._id), + { ...initialProfile, weeklycommittedHours: hours }, + )); + }); +}); diff --git a/src/components/UserProfile/__tests__/RehireableStatusControl.test.jsx b/src/components/UserProfile/__tests__/RehireableStatusControl.test.jsx index 1d3b2ab08e0..46ac5166568 100644 --- a/src/components/UserProfile/__tests__/RehireableStatusControl.test.jsx +++ b/src/components/UserProfile/__tests__/RehireableStatusControl.test.jsx @@ -2,29 +2,21 @@ import { fireEvent, render, screen } from '@testing-library/react'; import RehireableStatusControl from '../RehireableStatusControl'; describe('RehireableStatusControl', () => { - it('confirms a non-empty optional reason', () => { + it('requires a nonblank reason before confirming a not-rehireable status', () => { const onConfirm = vi.fn(); render(); fireEvent.click(screen.getByRole('button', { name: 'Rehireable' })); - expect(screen.getByText(/please enter the reason below/i)).toBeInTheDocument(); + expect(screen.getByText(/enter the required reason/i)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled(); + fireEvent.change(screen.getByRole('textbox', { name: /reason for not rehireable status/i }), { target: { value: ' Not a good fit ' }, }); - fireEvent.click(screen.getByRole('button', { name: 'Confirm' })); - - expect(onConfirm).toHaveBeenCalledWith(false, 'Not a good fit'); - }); - - it('allows confirmation with an empty reason', () => { - const onConfirm = vi.fn(); - render(); - - fireEvent.click(screen.getByRole('button', { name: 'Rehireable' })); expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled(); fireEvent.click(screen.getByRole('button', { name: 'Confirm' })); - expect(onConfirm).toHaveBeenCalledWith(false, ''); + expect(onConfirm).toHaveBeenCalledWith(false, 'Not a good fit'); }); it('does not change status or save reason when cancelled', () => { @@ -40,65 +32,101 @@ describe('RehireableStatusControl', () => { expect(onConfirm).not.toHaveBeenCalled(); }); - it('renders each rehireable visual state from persisted props', () => { + it('opens the saved reason and audit history from the orange status control', () => { const onConfirm = vi.fn(); - const { rerender } = render( -
- -
, - ); - const checkedControl = screen.getByRole('button', { name: 'Rehireable' }); - expect(checkedControl).toHaveClass('fa-check-square-o'); - expect(checkedControl.style.border).toBe(''); - - rerender( -
- -
, - ); - const uncheckedControl = screen.getByRole('button', { name: 'Not rehireable' }); - expect(uncheckedControl).toHaveClass('fa-square-o'); - expect(uncheckedControl.title).toBe('Click to change rehirable status'); - expect(uncheckedControl.style.border).toBe(''); - - rerender( -
- -
, - ); - const whitespaceReasonControl = screen.getByRole('button', { name: 'Not rehireable' }); - expect(whitespaceReasonControl).toHaveClass('fa-square-o'); - expect(whitespaceReasonControl.title).toBe('Click to change rehirable status'); - expect(whitespaceReasonControl.style.border).toBe(''); - - rerender( -
- -
, + render( + , ); + const control = screen.getByRole('button', { name: 'Not rehireable' }); - expect(control.className).not.toContain('fa-square-o'); - expect(control.title).toBe('Saved reason'); expect(control.style.border).toBe('2px solid rgb(240, 140, 0)'); - expect(window.getComputedStyle(control).borderColor).toBe('rgb(240, 140, 0)'); - expect(window.getComputedStyle(control).borderStyle).toBe('solid'); - expect(window.getComputedStyle(control).borderWidth).toBe('2px'); - fireEvent.click(control); - expect(screen.queryByRole('textbox')).not.toBeInTheDocument(); + + expect(screen.getByRole('heading', { name: 'Not Rehireable Details' })).toBeInTheDocument(); + expect(screen.getAllByText('Saved reason')).toHaveLength(2); + expect( + screen.getByText((_, element) => element?.textContent === 'Reason submitted by Alex Admin'), + ).toBeInTheDocument(); + expect(screen.getByText('Username: admin@example.org')).toBeInTheDocument(); + expect(screen.getByText(new Date('2026-01-02T03:04:00.000Z').toLocaleString())).toBeInTheDocument(); + }); + + it('opens edit mode and submits the updated reason', () => { + const onConfirm = vi.fn(); + render( + , + ); + + fireEvent.click(screen.getByRole('button', { name: 'Not rehireable' })); + fireEvent.click(screen.getByRole('button', { name: 'Edit reason' })); + const reasonInput = screen.getByRole('textbox', { name: /reason for not rehireable status/i }); + expect(reasonInput).toHaveValue('Old reason'); + fireEvent.change(reasonInput, { target: { value: ' Corrected reason ' } }); + fireEvent.click(screen.getByRole('button', { name: 'Confirm' })); + + expect(onConfirm).toHaveBeenCalledWith(false, 'Corrected reason'); + }); + + it('allows a user to mark the profile rehireable from the reason details', () => { + const onConfirm = vi.fn(); + render( + , + ); + + fireEvent.click(screen.getByRole('button', { name: 'Not rehireable' })); + fireEvent.click(screen.getByRole('button', { name: 'Mark Rehireable' })); fireEvent.click(screen.getByRole('button', { name: 'Confirm' })); + expect(onConfirm).toHaveBeenCalledWith(true, ''); }); -}); \ No newline at end of file + + it('opens an edit prompt for legacy not-rehireable records without a saved reason', () => { + const onConfirm = vi.fn(); + render(); + + fireEvent.click(screen.getByRole('button', { name: 'Not rehireable' })); + + expect(screen.getByRole('heading', { name: 'Edit Not Rehireable Reason' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: /reason for not rehireable status/i })).toBeInTheDocument(); + }); + + it('applies dark-mode classes to the details modal', () => { + render( + , + ); + + fireEvent.click(screen.getByRole('button', { name: 'Not rehireable' })); + + expect(screen.getByRole('document')).toHaveClass('text-light', 'dark-mode'); + expect(screen.getByText('Reason history')).toBeInTheDocument(); + }); +}); diff --git a/src/components/WeeklySummariesReport/BioFunction.jsx b/src/components/WeeklySummariesReport/BioFunction.jsx index 5b580db97de..f8fbb95e4cc 100644 --- a/src/components/WeeklySummariesReport/BioFunction.jsx +++ b/src/components/WeeklySummariesReport/BioFunction.jsx @@ -9,7 +9,7 @@ function BioFunction(props) { const { bioPosted, totalTangibleHrs, - daysInTeam, + weeklySummariesCount, textColors, summary, bioCanEdit, @@ -19,7 +19,7 @@ function BioFunction(props) { const [bioStatus, setBioStatus] = useState(bioPosted); - const isMeetCriteria = isQualifiedForBio({ totalTangibleHrs, daysInTeam, bioPosted }); + const isMeetCriteria = isQualifiedForBio({ totalTangibleHrs, weeklySummariesCount, bioPosted }); const style = { color: textColors[summary?.weeklySummaryOption] || textColors.Default, }; @@ -59,7 +59,7 @@ function BioFunction(props) { BioFunction.propTypes = { bioPosted: PropTypes.string, totalTangibleHrs: PropTypes.number, - daysInTeam: PropTypes.number, + weeklySummariesCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), textColors: PropTypes.object, summary: PropTypes.object, bioCanEdit: PropTypes.bool, diff --git a/src/components/WeeklySummariesReport/FormattedReport.jsx b/src/components/WeeklySummariesReport/FormattedReport.jsx index 94f7fbd808c..de785d1cd9c 100644 --- a/src/components/WeeklySummariesReport/FormattedReport.jsx +++ b/src/components/WeeklySummariesReport/FormattedReport.jsx @@ -50,6 +50,7 @@ import hasPermission, { cantUpdateDevAdminDetails } from '../../utils/permission import GoogleDocIcon from '../common/GoogleDocIcon'; import TriStateToggleSwitch from '../UserProfile/UserProfileEdit/ToggleSwitch/TriStateToggleSwitch'; import styles from './WeeklySummariesReport.module.scss'; +import getActiveTimeOffRequest from './getActiveTimeOffRequest'; const TZ = 'America/Los_Angeles'; @@ -95,6 +96,7 @@ function FormattedReport({ handleTeamCodeChange, handleBioStatusChange, handleSpecialColorDotClick, + timeOffRequests, }) { const dispatch = useDispatch(); const isEditCount = dispatch(hasPermission(permissions.totalValidWeeklySummaries)); @@ -123,6 +125,24 @@ function FormattedReport({ ); } const loggedInUserEmail = auth?.user?.email ? auth.user.email : ''; + const activeTeamCodes = [ + ...new Set( + summaries + .filter(summary => { + if ( + !summary || + !Array.isArray(summary.totalSeconds) || + !Array.isArray(summary.promisedHoursByWeek) + ) { + return false; + } + + return shouldShowSummaryOnTab(summary, weekIndex); + }) + .map(summary => (typeof summary.teamCode === 'string' ? summary.teamCode.trim() : '')) + .filter(Boolean), + ), + ].sort((a, b) => a.localeCompare(b)); return ( <> @@ -147,6 +167,7 @@ function FormattedReport({ key={summary._id} summary={summary} weekIndex={weekIndex} + activeTeamCodes={activeTeamCodes} bioCanEdit={bioCanEdit} canEditSummaryCount={isEditCount} allRoleInfo={allRoleInfo} @@ -161,6 +182,7 @@ function FormattedReport({ auth={auth} handleSpecialColorDotClick={handleSpecialColorDotClick} isFinalWeek={isFinalWeek} + timeOffRequests={timeOffRequests} /> ); })} @@ -265,6 +287,7 @@ function getTextColorForHoursLogged(hoursLogged, promisedHours, darkMode) { function ReportDetails({ summary, weekIndex, + activeTeamCodes, bioCanEdit, canEditSummaryCount, allRoleInfo, @@ -280,6 +303,7 @@ function ReportDetails({ auth, handleSpecialColorDotClick, isFinalWeek, + timeOffRequests, }) { // eslint-disable-next-line no-console // console.log('DEBUG ReportDetails:', { @@ -299,6 +323,7 @@ function ReportDetails({ // No bar for anyone unqualified, whatever the toggle says. 'default' and 'requested' // both count as "still to do"; only 'posted' ends the workflow and clears the bar. + const activeTimeOffRequest = getActiveTimeOffRequest(timeOffRequests, summary._id, weekIndex); const isMeetCriteria = canSeeBioHighlight && isQualifiedForBio(summary); return ( @@ -327,7 +352,7 @@ function ReportDetails({ backgroundColor: isMeetCriteria ? '#FFF200' : 'transparent', color: isMeetCriteria ? '#000000' : 'inherit', width: '100%', - padding: '6px 12px 6px 0px', + padding: '2px 12px 2px 0px', }} > {/* Dev-admin protected records stay read-only here, same as team code and @@ -353,9 +378,17 @@ function ReportDetails({ > + } canEditTeamCode={canEditTeamCode && !cantEditJaeRelatedRecord} summary={summary} handleTeamCodeChange={handleTeamCodeChange} + activeTeamCodes={activeTeamCodes} darkMode={darkMode} /> @@ -467,10 +500,15 @@ function WeeklySummaryMessage({ summary, weekIndex, darkMode }) { { + onClick={async () => { const parsedSummary = summaryText.replace(/<\/?[^>]+>| /g, ''); - navigator.clipboard.writeText(parsedSummary); - toast.success('Summary Copied!'); + + try { + await navigator.clipboard.writeText(parsedSummary); + toast.success('Summary Copied!'); + } catch { + toast.error('Failed to copy summary.'); + } }} /> @@ -495,21 +533,35 @@ function WeeklySummaryMessage({ summary, weekIndex, darkMode }) { ); } -function TeamCodeRow({ canEditTeamCode, summary, handleTeamCodeChange, darkMode }) { +function TeamCodeRow({ + canEditTeamCode, + summary, + handleTeamCodeChange, + activeTeamCodes, + darkMode, + weekOffBadge, +}) { const [teamCode, setTeamCode] = useState(summary.teamCode); const [savedTeamCode, setSavedTeamCode] = useState(summary.teamCode); const [hasError, setHasError] = useState(false); + const [showSuggestions, setShowSuggestions] = useState(false); const fullCodeRegex = /^.{5,7}$/; - const dispatch = useDispatch(); + const filteredTeamCodes = activeTeamCodes.filter(code => + code.toLowerCase().includes((teamCode || '').toLowerCase()), + ); const handleOnChange = async (userProfileSummary, newStatus) => { const url = ENDPOINTS.USERS_ALLTEAMCODE_CHANGE; try { - await axios.patch(url, { userIds: [userProfileSummary._id], replaceCode: newStatus }); - handleTeamCodeChange(userProfileSummary.teamCode, newStatus, { - [userProfileSummary._id]: true, - }); // Update the team code dynamically + const response = await axios.patch(url, { + userIds: [userProfileSummary._id], + replaceCode: newStatus, + }); + const updatedUser = response.data?.updatedUsers?.find( + user => user.userId === userProfileSummary._id, + ); + handleTeamCodeChange(userProfileSummary._id, newStatus, updatedUser?.teamCodeWarning); } catch (err) { // eslint-disable-next-line no-alert alert( @@ -525,7 +577,7 @@ function TeamCodeRow({ canEditTeamCode, summary, handleTeamCodeChange, darkMode setHasError(false); setTeamCode(value); setSavedTeamCode(value); - handleOnChange(summary, value); + void handleOnChange(summary, value); } else { setTeamCode(savedTeamCode); setHasError(true); @@ -539,31 +591,73 @@ function TeamCodeRow({ canEditTeamCode, summary, handleTeamCodeChange, darkMode return ( <>
- {canEditTeamCode ? ( -
- setTeamCode(e.target.value)} - onBlur={e => { - handleCodeChange(e); - }} - onKeyDown={e => { - if (e.key === 'Enter') { - e.currentTarget.blur(); // triggers onBlur - } - }} - placeholder="X-XXX" - className={`${styles.weeklySummariesCodeInput} ${ - darkMode ? 'bg-darkmode-liblack text-light border-0' : '' - }`} - /> -
- ) : ( -
- {teamCode === '' ? 'No assigned team code!' : teamCode} -
- )} +
+ {canEditTeamCode ? ( +
+
+ setShowSuggestions(true)} + onChange={e => { + setTeamCode(e.target.value); + setShowSuggestions(true); + }} + onBlur={e => { + handleCodeChange(e); + setShowSuggestions(false); + }} + onKeyDown={e => { + if (e.key === 'Enter') { + e.currentTarget.blur(); + } + + if (e.key === 'Escape') { + setShowSuggestions(false); + } + }} + placeholder="X-XXX" + className={`${styles.weeklySummariesCodeInput} ${ + darkMode ? 'bg-darkmode-liblack text-light border-0' : '' + }`} + /> + + {showSuggestions && filteredTeamCodes.length > 0 && ( +
+ {filteredTeamCodes.map(code => ( + + ))} +
+ )} +
+
+ ) : ( +
+ {teamCode === '' ? 'No assigned team code!' : teamCode} +
+ )} + + {weekOffBadge} +
+
Media URL: @@ -633,22 +727,25 @@ function TotalValidWeeklySummaries({ summary, canEditSummaryCount, darkMode }) { const handleWeeklySummaryCountChange = e => { setWeeklySummariesCount(e.target.value); - handleOnChange(summary, e.target.value); + void handleOnChange(summary, e.target.value); }; return ( -
+
{weeklySummariesCount === 8 ? ( -
+
Total Valid Weekly Summaries:{' '}
) : ( -
+
Total Valid Weekly Summaries:
)} {canEditSummaryCount ? ( -
+
handleWeeklySummaryCountChange(e)} className={darkMode ? 'bg-darkmode-liblack text-light border-0' : ''} + style={{ width: '65px', height: '28px', padding: '2px 6px' }} min="0" + max="9999" />
) : ( @@ -824,6 +923,39 @@ function WeeklyBadge({ summary, weekIndex, badges }) { ); } +// Shows "Requested Week Off" for the viewed week. Clicking (or pressing Enter/Space on) +// the info button toggles the logged reason, as the ticket asks for; it closes on blur +// or Escape. +function WeekOffBadge({ request, summaryId, weekIndex }) { + const [showReason, setShowReason] = useState(false); + if (!request) return null; + const reasonId = `week-off-reason-${summaryId}-${weekIndex}`; + return ( + + Requested Week Off{' '} + @@ -1121,13 +1267,18 @@ FormattedReport.propTypes = { }), }), }), + // Keyed by userId, each value an array of that user's time-off requests + // ({ _id, reason, startingDate, endingDate, ... }), from timeOffRequestReducer. + timeOffRequests: PropTypes.objectOf(PropTypes.array), }; FormattedReport.defaultProps = { auth: {}, + timeOffRequests: {}, }; ReportDetails.propTypes = { + activeTeamCodes: PropTypes.arrayOf(PropTypes.string).isRequired, summary: PropTypes.shape({ _id: PropTypes.string, email: PropTypes.string, @@ -1142,10 +1293,12 @@ ReportDetails.propTypes = { }), }), }), + timeOffRequests: PropTypes.objectOf(PropTypes.array), }; ReportDetails.defaultProps = { auth: {}, + timeOffRequests: {}, }; export default FormattedReport; diff --git a/src/components/WeeklySummariesReport/TeamCodeWarningButton.jsx b/src/components/WeeklySummariesReport/TeamCodeWarningButton.jsx new file mode 100644 index 00000000000..336e361629f --- /dev/null +++ b/src/components/WeeklySummariesReport/TeamCodeWarningButton.jsx @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types'; +import ReactTooltip from 'react-tooltip'; +import styles from './WeeklySummariesReport.module.css'; + +const TeamCodeWarningButton = ({ count, active, onClick }) => { + if (count === 0) return null; + + return ( + <> +
+ {hiddenCount > 0 && ( +
+ +
+ )} +
+ Array.from({ length: count }, (unused, i) => ({ + projectId: `proj-${i}`, + projectName: `Project ${i}`, + totalTime: 1, + })); + +const renderChart = count => + render(); + +const legendRowCount = () => screen.getAllByTestId('project-color-cell').length; + +describe('UserProjectD3PieChart legend cap', () => { + // Pinned to the literal: the other assertions reference MAX_VISIBLE_PROJECTS + // symbolically and would stay green if the cap were lowered for debugging. + it('caps the collapsed legend at 10, the agreed product limit', () => { + expect(MAX_VISIBLE_PROJECTS).toBe(10); + }); + + it('caps the collapsed legend at the limit', () => { + renderChart(MAX_VISIBLE_PROJECTS + 7); + + expect(legendRowCount()).toBe(MAX_VISIBLE_PROJECTS); + }); + + it('renders every project without a toggle when at or under the cap', () => { + renderChart(MAX_VISIBLE_PROJECTS); + + expect(legendRowCount()).toBe(MAX_VISIBLE_PROJECTS); + expect(screen.queryByTestId('toggle-more-projects')).not.toBeInTheDocument(); + }); + + it('labels the toggle with the number of hidden projects', () => { + renderChart(MAX_VISIBLE_PROJECTS + 7); + + expect(screen.getByTestId('toggle-more-projects')).toHaveTextContent('+ 7 more projects'); + }); + + it('singularizes the label when exactly one project is hidden', () => { + renderChart(MAX_VISIBLE_PROJECTS + 1); + + expect(screen.getByTestId('toggle-more-projects')).toHaveTextContent('+ 1 more project'); + }); + + it('expands to every project and collapses back to the cap', () => { + renderChart(MAX_VISIBLE_PROJECTS + 7); + const toggle = screen.getByTestId('toggle-more-projects'); + + expect(toggle).toHaveAttribute('aria-expanded', 'false'); + + fireEvent.click(toggle); + expect(legendRowCount()).toBe(MAX_VISIBLE_PROJECTS + 7); + expect(toggle).toHaveAttribute('aria-expanded', 'true'); + expect(toggle).toHaveTextContent('Show less'); + + fireEvent.click(toggle); + expect(legendRowCount()).toBe(MAX_VISIBLE_PROJECTS); + expect(toggle).toHaveAttribute('aria-expanded', 'false'); + }); + + it('totals every project, not just the visible ones', () => { + renderChart(MAX_VISIBLE_PROJECTS + 7); + + // 17 projects x 1 hour each — the cap must not change the reported total. + expect(screen.getByText('17.00')).toBeInTheDocument(); + }); +}); describe('ProjectColorCell', () => { it('paints the swatch with the supplied color', () => { diff --git a/src/constants/bmdashboard/weeklyProjectSummaryConstants.js b/src/constants/bmdashboard/weeklyProjectSummaryConstants.js index 29c6ff48e7d..d56eab3b805 100644 --- a/src/constants/bmdashboard/weeklyProjectSummaryConstants.js +++ b/src/constants/bmdashboard/weeklyProjectSummaryConstants.js @@ -1,3 +1,9 @@ export const SET_PROJECT_FILTER = 'SET_PROJECT_FILTER'; export const SET_DATE_RANGE_FILTER = 'SET_DATE_RANGE_FILTER'; export const SET_COMPARISON_PERIOD_FILTER = 'SET_COMPARISON_PERIOD_FILTER'; +export const FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN = + 'FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN'; +export const FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS = + 'FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS'; +export const FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR = + 'FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR'; diff --git a/src/languages/en/ui.js b/src/languages/en/ui.js index 6fe7b523a0f..08953146891 100644 --- a/src/languages/en/ui.js +++ b/src/languages/en/ui.js @@ -49,6 +49,7 @@ export const BADGE_MANAGEMENT = 'Badge Management'; export const VIEW_PROFILE = 'View Profile'; export const WBS = 'WBS'; export const WELCOME = 'Welcome'; +export const TASKS = 'Tasks'; export const NOTICE = 'Notice'; export const FIRST_NAME = 'First Name'; export const LAST_NAME = 'Last Name'; diff --git a/src/reducers/__tests__/weeklyProjectSummaryReducer.test.js b/src/reducers/__tests__/weeklyProjectSummaryReducer.test.js new file mode 100644 index 00000000000..79da02249de --- /dev/null +++ b/src/reducers/__tests__/weeklyProjectSummaryReducer.test.js @@ -0,0 +1,186 @@ +import { weeklyProjectSummaryReducer } from '../bmdashboard/weeklyProjectSummaryReducer'; +import { + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, +} from '../../constants/bmdashboard/weeklyProjectSummaryConstants'; + +const requestA = { requestId: 'request-a', requestKey: 'startDate=2026-09-01' }; +const requestB = { requestId: 'request-b', requestKey: 'startDate=2026-10-01' }; +const requestC = { requestId: 'request-c', requestKey: 'startDate=2026-11-01' }; +const beginAction = meta => ({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN, + meta, +}); +const successAction = (meta, value) => ({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + payload: { current: { metrics: { totalProjects: { value } } } }, + meta, +}); +const errorAction = (meta, message = 'request failed') => ({ + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + payload: new Error(message), + meta, +}); +const createLoadingLatestState = () => + weeklyProjectSummaryReducer( + weeklyProjectSummaryReducer(undefined, beginAction(requestA)), + beginAction(requestB), + ); + +describe('weeklyProjectSummaryReducer Project Status requests', () => { + it('clears previous Project Status data when a new request begins', () => { + const state = { + ...weeklyProjectSummaryReducer(undefined, {}), + projectStatusData: { current: { metrics: { totalProjects: { value: 150 } } } }, + projectStatusDataRequestKey: requestA.requestKey, + projectStatusError: new Error('old error'), + }; + + const nextState = weeklyProjectSummaryReducer(state, { + ...beginAction(requestB), + }); + + expect(nextState).toMatchObject({ + projectStatusLoading: true, + projectStatusData: null, + projectStatusError: null, + projectStatusActiveRequestId: requestB.requestId, + projectStatusActiveRequestKey: requestB.requestKey, + projectStatusDataRequestKey: null, + projectStatusErrorRequestKey: null, + }); + }); + + it('ignores stale Project Status success and error actions after a newer request begins', () => { + const loadingLatestState = createLoadingLatestState(); + + [ + { + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + payload: { current: { metrics: { totalProjects: { value: 1 } } } }, + meta: requestA, + }, + { + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + payload: new Error('stale failure'), + meta: requestA, + }, + ].forEach(action => { + expect(weeklyProjectSummaryReducer(loadingLatestState, action)).toBe(loadingLatestState); + }); + }); + + it('accepts the latest Project Status success after an older response is ignored', () => { + const staleState = weeklyProjectSummaryReducer(createLoadingLatestState(), { + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + payload: { current: { metrics: { totalProjects: { value: 1 } } } }, + meta: requestA, + }); + const latestData = { current: { metrics: { totalProjects: { value: 2 } } } }; + const nextState = weeklyProjectSummaryReducer(staleState, { + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + payload: latestData, + meta: requestB, + }); + + expect(nextState).toMatchObject({ + projectStatusLoading: false, + projectStatusData: latestData, + projectStatusError: null, + projectStatusActiveRequestId: requestB.requestId, + projectStatusActiveRequestKey: requestB.requestKey, + projectStatusDataRequestKey: requestB.requestKey, + }); + }); + + it('clears previous Project Status data when the active request fails', () => { + const state = weeklyProjectSummaryReducer( + { + ...weeklyProjectSummaryReducer(undefined, {}), + projectStatusData: { current: { metrics: { totalProjects: { value: 150 } } } }, + projectStatusDataRequestKey: requestA.requestKey, + }, + { + ...beginAction(requestB), + }, + ); + const error = new Error('latest failure'); + + const nextState = weeklyProjectSummaryReducer(state, { + type: FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, + payload: error, + meta: requestB, + }); + + expect(nextState).toMatchObject({ + projectStatusLoading: false, + projectStatusData: null, + projectStatusError: error, + projectStatusActiveRequestId: requestB.requestId, + projectStatusActiveRequestKey: requestB.requestKey, + projectStatusDataRequestKey: null, + projectStatusErrorRequestKey: requestB.requestKey, + }); + }); + + it('does not let request A success overwrite request B after request B succeeds first', () => { + const loadingBState = createLoadingLatestState(); + const requestBSuccessState = weeklyProjectSummaryReducer( + loadingBState, + successAction(requestB, 2), + ); + + const nextState = weeklyProjectSummaryReducer(requestBSuccessState, successAction(requestA, 1)); + + expect(nextState).toBe(requestBSuccessState); + expect(nextState.projectStatusData.current.metrics.totalProjects.value).toBe(2); + }); + + it('does not let request A failure overwrite request B after request B succeeds first', () => { + const loadingBState = createLoadingLatestState(); + const requestBSuccessState = weeklyProjectSummaryReducer( + loadingBState, + successAction(requestB, 2), + ); + + const nextState = weeklyProjectSummaryReducer( + requestBSuccessState, + errorAction(requestA, 'late request A failure'), + ); + + expect(nextState).toBe(requestBSuccessState); + expect(nextState.projectStatusData.current.metrics.totalProjects.value).toBe(2); + expect(nextState.projectStatusError).toBeNull(); + }); + + it('does not let late request A or B responses overwrite request C after request C succeeds first', () => { + const loadingCState = weeklyProjectSummaryReducer( + createLoadingLatestState(), + beginAction(requestC), + ); + const requestCSuccessState = weeklyProjectSummaryReducer( + loadingCState, + successAction(requestC, 3), + ); + + const afterLateASuccess = weeklyProjectSummaryReducer( + requestCSuccessState, + successAction(requestA, 1), + ); + const afterLateBSuccess = weeklyProjectSummaryReducer( + afterLateASuccess, + successAction(requestB, 2), + ); + const afterLateBFailure = weeklyProjectSummaryReducer( + afterLateBSuccess, + errorAction(requestB, 'late request B failure'), + ); + + expect(afterLateASuccess).toBe(requestCSuccessState); + expect(afterLateBSuccess).toBe(requestCSuccessState); + expect(afterLateBFailure).toBe(requestCSuccessState); + expect(afterLateBFailure.projectStatusData.current.metrics.totalProjects.value).toBe(3); + expect(afterLateBFailure.projectStatusError).toBeNull(); + }); +}); diff --git a/src/reducers/badgeReducer.js b/src/reducers/badgeReducer.js index 814d980b611..5cbc2536d96 100644 --- a/src/reducers/badgeReducer.js +++ b/src/reducers/badgeReducer.js @@ -13,6 +13,7 @@ import { RESET_BADGE_COUNT, SET_ACTIVE_TAB, } from '../constants/badge'; +import { FETCH_ALL_BADGES, FETCH_BADGES_FAILURE } from '../actions/actionTypes'; const badgeInitial = { allBadgeData: [], @@ -25,6 +26,8 @@ const badgeInitial = { alertVisible: false, badgeCount: 0, activeTab: '1', + loading: false, + error: null, }; // eslint-disable-next-line default-param-last @@ -40,6 +43,18 @@ export const badgeReducer = (state = badgeInitial, action) => { ...state, selectedBadges: [...state.selectedBadges, action.badgeId], }; + case FETCH_ALL_BADGES: + return { + ...state, + allBadgeData: action.payload, + loading: false, + }; + case FETCH_BADGES_FAILURE: + return { + ...state, + error: action.payload, + loading: false, + }; case REMOVE_SELECT_BADGE: return { ...state, diff --git a/src/reducers/bmdashboard/weeklyProjectSummaryReducer.js b/src/reducers/bmdashboard/weeklyProjectSummaryReducer.js index f94d30ab5a0..e2e1d0af75b 100644 --- a/src/reducers/bmdashboard/weeklyProjectSummaryReducer.js +++ b/src/reducers/bmdashboard/weeklyProjectSummaryReducer.js @@ -2,12 +2,29 @@ import { SET_PROJECT_FILTER, SET_DATE_RANGE_FILTER, SET_COMPARISON_PERIOD_FILTER, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS, + FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR, } from '../../constants/bmdashboard/weeklyProjectSummaryConstants'; const initialState = { projectFilter: 'One Community', dateRangeFilter: '', - comparisonPeriodFilter: '', + comparisonPeriodFilter: 'No Comparison', + projectStatusData: null, + projectStatusLoading: false, + projectStatusError: null, + projectStatusActiveRequestId: null, + projectStatusActiveRequestKey: null, + projectStatusDataRequestKey: null, + projectStatusErrorRequestKey: null, +}; + +const isStaleProjectStatusAction = (state, action) => { + const activeRequestId = state.projectStatusActiveRequestId; + const actionRequestId = action.meta?.requestId; + + return Boolean(activeRequestId && actionRequestId && actionRequestId !== activeRequestId); }; // eslint-disable-next-line default-param-last, import/prefer-default-export @@ -31,6 +48,52 @@ export const weeklyProjectSummaryReducer = (state = initialState, action) => { comparisonPeriodFilter: action.payload, }; + case FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_BEGIN: + return { + ...state, + projectStatusLoading: true, + projectStatusError: null, + projectStatusData: null, + projectStatusActiveRequestId: action.meta?.requestId || null, + projectStatusActiveRequestKey: action.meta?.requestKey || null, + projectStatusDataRequestKey: null, + projectStatusErrorRequestKey: null, + }; + + case FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_SUCCESS: + if (isStaleProjectStatusAction(state, action)) { + return state; + } + + return { + ...state, + projectStatusLoading: false, + projectStatusData: action.payload, + projectStatusError: null, + projectStatusActiveRequestId: action.meta?.requestId || state.projectStatusActiveRequestId, + projectStatusActiveRequestKey: + action.meta?.requestKey || state.projectStatusActiveRequestKey, + projectStatusDataRequestKey: action.meta?.requestKey || null, + projectStatusErrorRequestKey: null, + }; + + case FETCH_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS_ERROR: + if (isStaleProjectStatusAction(state, action)) { + return state; + } + + return { + ...state, + projectStatusLoading: false, + projectStatusData: null, + projectStatusError: action.payload, + projectStatusActiveRequestId: action.meta?.requestId || state.projectStatusActiveRequestId, + projectStatusActiveRequestKey: + action.meta?.requestKey || state.projectStatusActiveRequestKey, + projectStatusDataRequestKey: null, + projectStatusErrorRequestKey: action.meta?.requestKey || null, + }; + default: return state; } diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js index 8f11253be70..47905897c53 100644 --- a/src/registerServiceWorker.js +++ b/src/registerServiceWorker.js @@ -10,10 +10,10 @@ const isLocalhost = Boolean( globalThis.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - globalThis.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - globalThis.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), + // [::1] is the IPv6 localhost address. + globalThis.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + globalThis.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), ); function registerValidSW(swUrl) { @@ -66,13 +66,14 @@ function checkValidServiceWorker(swUrl) { export default function register() { if (import.meta.env.PROD && 'serviceWorker' in navigator) { - const publicUrl = new URL(import.meta.env.BASE_URL, globalThis.location); + const baseUrl = import.meta.env.BASE_URL || '/'; + const publicUrl = new URL(baseUrl, globalThis.location); if (publicUrl.origin !== globalThis.location.origin) { return; } globalThis.addEventListener('load', () => { - const swUrl = `${import.meta.env.BASE_URL}service-worker.js`; + const swUrl = `${baseUrl}service-worker.js`; if (isLocalhost) { checkValidServiceWorker(swUrl); @@ -80,7 +81,7 @@ export default function register() { // eslint-disable-next-line no-console console.log( 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://goo.gl/SC7cgQ', + 'worker. To learn more, visit https://goo.gl/SC7cgQ', ); }); } else { diff --git a/src/routes.jsx b/src/routes.jsx index 4d8725cad8b..3a90ee43292 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -63,6 +63,7 @@ import ToolsAvailabilityPage from './components/BMDashboard/WeeklyProjectSummary import ResourceUsage from './components/CommunityPortal/ResourceUsage/ResourceUsage'; import DatabaseDesign from './components/CommunityPortal/DatabaseDesign/DatabaseDesign'; import Page1 from './components/HGNForm/pages/Page1'; +import HGNFormListPage from './components/HGNForm/pages/HGNFormListPage'; import Page2 from './components/HGNForm/pages/Page2'; import Page3 from './components/HGNForm/pages/Page3'; import Page4 from './components/HGNForm/pages/Page4'; @@ -88,6 +89,7 @@ import FeedbackModal from './components/HGNHelpSkillsDashboard/FeedbackModal'; import Activity from './components/CommunityPortal/Activities/activityId/Activity'; import ActivityAttendance from './components/CommunityPortal/Activities/ActivityAttendance'; import ActivityAgenda from './components/CommunityPortal/Activities/ActivityAgenda'; +import ResolvedTasks from './components/ResolvedTasks/ResolvedTasks'; import EventList from './components/CommunityPortal/Event/EventList/EventList'; import ResourcesUsage from './components/CommunityPortal/Activities/activityId/ResourcesUsage'; import EventParticipation from './components/CommunityPortal/Reports/Participation/EventParticipation'; @@ -179,6 +181,7 @@ import GardenManagement from './components/KitchenandInventory/GardenManagement/ import RecipesLandingPage from './components/KitchenandInventory/Recipes'; import KIDashboard from './components/KitchenandInventory/KIDashboard/KIDashboard'; +import KitchenReports from './components/KitchenandInventory/KitchenReports/KitchenReports'; import KIINVENTORY from './components/KitchenandInventory/KIInventory/KIInventory'; import KICalendar from './components/KitchenandInventory/KICalendar/KICalendar'; @@ -399,6 +402,7 @@ export default ( + + @@ -1166,7 +1171,8 @@ export default ( - + + @@ -1261,7 +1267,7 @@ export default ( path="/pr-grading-dashboard" exact component={PRGradingDashboard} - fallback + routePermissions={RoutePermissions.prDashboard} /> diff --git a/src/utils/URL.js b/src/utils/URL.js index 7ba42ec5e0c..57df9efcd63 100644 --- a/src/utils/URL.js +++ b/src/utils/URL.js @@ -6,6 +6,7 @@ export const ENDPOINTS = { APIEndpoint: () => APIEndpoint, USER_PROFILES: `${APIEndpoint}/userProfile`, USER_PROFILE: userId => `${APIEndpoint}/userprofile/${userId}`, + HGN_FORMS: `${APIEndpoint}/form`, USER_PROFILE_FIXED: userId => `${APIEndpoint}/userProfile/${userId}`, USER_PROFILE_PROPERTY: userId => `${APIEndpoint}/userprofile/${userId}/property`, USER_PAUSE: userId => `${APIEndpoint}/userProfile/${userId}/pause`, @@ -46,6 +47,8 @@ export const ENDPOINTS = { USERS_REMOVE_PROFILE_IMAGE: `${APIEndpoint}/userProfile/profileImage/remove`, USERS_UPDATE_PROFILE_FROM_WEBSITE: `${APIEndpoint}/userProfile/profileImage/imagefromwebsite`, USER_PROFILE_BASIC_INFO: source => `${APIEndpoint}/userProfile/basicInfo/${source}`, + // Single-user lookup contract: backend reads this as req.query.userId, not a path segment. + USER_PROFILE_BASIC_INFO_BY_ID: userId => `${APIEndpoint}/userProfile/basicInfo?userId=${userId}`, USER_AUTOCOMPLETE: searchText => `${APIEndpoint}/userProfile/autocomplete/${searchText}`, SEARCH_USER: `${APIEndpoint}/users/search`, TOGGLE_BIO_STATUS: userId => `${APIEndpoint}/userProfile/${userId}/toggleBio`, @@ -114,6 +117,7 @@ export const ENDPOINTS = { TASK_WBS: wbsId => `${APIEndpoint}/task/wbs/${wbsId}`, TASKS_UPDATE: `${APIEndpoint}/tasks/update`, TASKS_BY_USERID: userId => `${APIEndpoint}/tasks/user/${userId}`, + RESOLVED_TASKS: (page, limit) => `${APIEndpoint}/tasks/resolved?page=${page}&limit=${limit}`, // TASKS_BY_userID: userId => `${APIEndpoint}/tasks/userProfile/${userId}`, TASK_DEL: (taskId, motherId) => `${APIEndpoint}/task/del/${taskId}/${motherId}`, GET_TASK: taskId => `${APIEndpoint}/task/${taskId}`, @@ -134,6 +138,8 @@ export const ENDPOINTS = { WEEKLY_SUMMARIES_FILTER_REPLACE_INDIVIDUAL_CODES: `${APIEndpoint}/weeklySummariesFilters/replaceIndividualTeamcodes`, SAVE_SUMMARY_RECEPIENTS: userid => `${APIEndpoint}/reports/recepients/${userid}`, GET_SUMMARY_RECEPIENTS: () => `${APIEndpoint}/reports/getrecepients`, + KITCHEN_REPORTS_EXPORT_PDF: () => `${APIEndpoint}/kitchenandinventory/reports/export/pdf`, + KITCHEN_REPORTS_EXPORT_CSV: () => `${APIEndpoint}/kitchenandinventory/reports/export/csv`, GET_CURRENT_WARNINGS: () => `${APIEndpoint}/currentWarnings`, POST_NEW_WARNING: () => `${APIEndpoint}/currentWarnings`, UPDATE_WARNING_DESCRIPTION: warningId => `${APIEndpoint}/currentWarnings/${warningId}`, @@ -165,7 +171,8 @@ export const ENDPOINTS = { TEAM_BY_ID: teamId => `${APIEndpoint}/team/${teamId}`, APPLICANT_VOLUNTEER_RATIO: `${APIEndpoint}/applicant-volunteer-ratio`, USER_UNREAD_TASK_NOTIFICATIONS: userId => `${APIEndpoint}/tasknotification/user/${userId}`, - BADGE: () => `${APIEndpoint}/badge`, + // BADGE: () => `${APIEndpoint}/badge`, + BADGE: () => `${APIEndpoint}/badge/getAllBadges`, BADGE_ASSIGN_MULTIPLE: `${APIEndpoint}/badge/assign`, BADGE_ASSIGN: userId => `${APIEndpoint}/badge/assign/${userId}`, BADGE_BY_ID: badgeId => `${APIEndpoint}/badge/${badgeId}`, @@ -380,9 +387,9 @@ export const ENDPOINTS = { BM_PROJECTS_WITH_LOCATION: `${APIEndpoint}/bm/projects/location`, BM_PROJECT_EXPENSE_BY_ID: projectId => `${APIEndpoint}/bm/project/${projectId}/expenses`, BM_PROJECT_BY_ID: projectId => `${APIEndpoint}/bm/project/${projectId}`, + BM_WEEKLY_PROJECT_SUMMARY_PROJECT_STATUS: `${APIEndpoint}/bm/weekly-project-summary/project-status`, BM_DELETE_INVENTORTY_TYPE_BY_ID: id => `${APIEndpoint}/bm/invtypes/${id}`, BM_UPDATE_INVENTORY_TYPE_BY_ID: id => `${APIEndpoint}/bm/invtypes/${id}`, - BM_PROJECT_MATERIALS_COST: `${APIEndpoint}/material-costs`, BM_UPDATE_MATERIAL: `${APIEndpoint}/bm/updateMaterialRecord`, BM_UPDATE_MATERIAL_BULK: `${APIEndpoint}/bm/updateMaterialRecordBulk`, @@ -649,15 +656,15 @@ export const ENDPOINTS = { APPLICANT_SOURCES: `${APIEndpoint}/applicant-analytics/applicant-sources`, OPT_STATUS_BREAKDOWN: (startDate, endDate, role) => { - let url = `${APIEndpoint}/analytics/opt-status`; - const params = []; + let url = `${APIEndpoint}/analytics/opt-status`; + const params = []; - if (startDate) params.push(`startDate=${startDate}`); - if (endDate) params.push(`endDate=${endDate}`); - if (role) params.push(`role=${role}`); + if (startDate) params.push(`startDate=${startDate}`); + if (endDate) params.push(`endDate=${endDate}`); + if (role) params.push(`role=${role}`); - return params.length > 0 ? `${url}?${params.join("&")}` : url; -}, + return params.length > 0 ? `${url}?${params.join("&")}` : url; + }, @@ -694,6 +701,7 @@ export const ENDPOINTS = { // pr dashboard endpoints PROMOTION_ELIGIBILITY: `${APIEndpoint}/promotion-eligibility`, + PROMOTION_PENDING: `${APIEndpoint}/promotion-pending`, PROMOTE_MEMBERS: `${APIEndpoint}/promote-members`, // LinkedIn autoposter endpoints @@ -770,6 +778,7 @@ export const ENDPOINTS = { // Help Request & Feedback Modal endpoints HGN_FORM_RANKED: `${APIEndpoint}/hgnform/ranked`, + HGN_COMMUNITY_MEMBERS: `${APIEndpoint}/hgnHelp/community`, HELP_REQUEST_CHECK_MODAL: userId => `${APIEndpoint}/helprequest/check-modal/${userId}`, FEEDBACK_CLOSE_PERMANENTLY: `${APIEndpoint}/feedback/close-permanently`, FEEDBACK_SUBMIT: `${APIEndpoint}/feedback/submit`, diff --git a/src/utils/__tests__/bioQualification.test.js b/src/utils/__tests__/bioQualification.test.js index 0bf176e8c66..c33f2faa8fd 100644 --- a/src/utils/__tests__/bioQualification.test.js +++ b/src/utils/__tests__/bioQualification.test.js @@ -1,17 +1,17 @@ import { isQualifiedForBio, BIO_MIN_TANGIBLE_HOURS, - BIO_MIN_DAYS_IN_TEAM, + BIO_MIN_VALID_SUMMARIES, } from '../bioQualification'; const qualified = { totalTangibleHrs: 100, - daysInTeam: 70, + weeklySummariesCount: 10, bioPosted: 'default', }; describe('isQualifiedForBio()', () => { - it('qualifies a user over both thresholds whose bio is not posted', () => { + it('qualifies a user meeting both thresholds whose bio is not posted', () => { expect(isQualifiedForBio(qualified)).toBe(true); }); @@ -23,32 +23,46 @@ describe('isQualifiedForBio()', () => { expect(isQualifiedForBio({ ...qualified, bioPosted: 'posted' })).toBe(false); }); - it('requires strictly more than the hour threshold', () => { + it('requires at least the minimum tangible hours', () => { + expect( + isQualifiedForBio({ ...qualified, totalTangibleHrs: BIO_MIN_TANGIBLE_HOURS - 0.01 }), + ).toBe(false); expect(isQualifiedForBio({ ...qualified, totalTangibleHrs: BIO_MIN_TANGIBLE_HOURS })).toBe( - false, - ); - expect(isQualifiedForBio({ ...qualified, totalTangibleHrs: BIO_MIN_TANGIBLE_HOURS + 1 })).toBe( true, ); }); - it('requires strictly more than the tenure threshold', () => { - expect(isQualifiedForBio({ ...qualified, daysInTeam: BIO_MIN_DAYS_IN_TEAM })).toBe(false); - expect(isQualifiedForBio({ ...qualified, daysInTeam: BIO_MIN_DAYS_IN_TEAM + 1 })).toBe(true); + it('requires at least the minimum valid weekly summaries', () => { + expect( + isQualifiedForBio({ ...qualified, weeklySummariesCount: BIO_MIN_VALID_SUMMARIES - 1 }), + ).toBe(false); + expect( + isQualifiedForBio({ ...qualified, weeklySummariesCount: BIO_MIN_VALID_SUMMARIES }), + ).toBe(true); }); - // Tenure, not weekly summary output: 24e1c6ba2 swapped these and changed who qualifies. - it('ignores weeklySummariesCount entirely', () => { - expect(isQualifiedForBio({ ...qualified, daysInTeam: 10, weeklySummariesCount: 99 })).toBe( - false, - ); - expect(isQualifiedForBio({ ...qualified, weeklySummariesCount: 0 })).toBe(true); + // Reported 2026-10-13: 80+ hours and 60+ days in team, but only 3 valid summaries. + it('does not qualify on hours and tenure alone', () => { + expect( + isQualifiedForBio({ ...qualified, daysInTeam: 400, weeklySummariesCount: 3 }), + ).toBe(false); + }); + + it('ignores daysInTeam entirely', () => { + expect(isQualifiedForBio({ ...qualified, daysInTeam: 1 })).toBe(true); + }); + + it('accepts a numeric string for weeklySummariesCount', () => { + expect(isQualifiedForBio({ ...qualified, weeklySummariesCount: '8' })).toBe(true); + expect(isQualifiedForBio({ ...qualified, weeklySummariesCount: '3' })).toBe(false); }); it('does not qualify when the row is missing or the fields are absent', () => { expect(isQualifiedForBio(null)).toBe(false); expect(isQualifiedForBio(undefined)).toBe(false); expect(isQualifiedForBio({})).toBe(false); - expect(isQualifiedForBio({ ...qualified, daysInTeam: undefined })).toBe(false); + expect(isQualifiedForBio({ ...qualified, weeklySummariesCount: undefined })).toBe(false); + expect(isQualifiedForBio({ ...qualified, weeklySummariesCount: null })).toBe(false); + expect(isQualifiedForBio({ ...qualified, totalTangibleHrs: undefined })).toBe(false); }); }); diff --git a/src/utils/__tests__/emailValidation.test.js b/src/utils/__tests__/emailValidation.test.js new file mode 100644 index 00000000000..8b816722352 --- /dev/null +++ b/src/utils/__tests__/emailValidation.test.js @@ -0,0 +1,140 @@ +import { checkEmail } from '../emailValidation'; + +// With a suggestion on screen the error doesn't repeat "check for a typo"; the hint says it. +const badEnding = (ending, suggestion) => + `"${ending}" isn't a valid email domain ending.${suggestion ? '' : ' Check for a typo.'}`; + +describe('checkEmail', () => { + it('rejects a non-existent TLD and suggests the likely address', () => { + expect(checkEmail('rabstu@gmail.con')).toEqual({ + error: badEnding('.con', true), + suggestion: 'rabstu@gmail.com', + }); + }); + + it.each([ + ['ada@yahoo.cmo', '.cmo', 'ada@yahoo.com'], + ['ada@outlook.comm', '.comm', 'ada@outlook.com'], + ['ada@company.con', '.con', 'ada@company.com'], + ['ada@school.ogr', '.ogr', 'ada@school.org'], + ['ada@company.qwzx', '.qwzx', null], + ['ada@gmial.con', '.con', 'ada@gmail.com'], + ['ada@hotmial.cmo', '.cmo', 'ada@hotmail.com'], + ['ada@gmail.CON', '.CON', 'ada@gmail.com'], + ])('blocks %s (%s) and suggests %s', (email, ending, suggestion) => { + expect(checkEmail(email)).toEqual({ error: badEnding(ending, suggestion), suggestion }); + }); + + it.each([ + ['ada@gmial.com', 'ada@gmail.com'], + ['ada@gamil.com', 'ada@gmail.com'], + ['ada@gmail.co', 'ada@gmail.com'], + ['ada@gmail.cm', 'ada@gmail.com'], + ['ada@hotmial.com', 'ada@hotmail.com'], + ['ada@yahooo.com', 'ada@yahoo.com'], + ['ada@outlok.com', 'ada@outlook.com'], + ['ada@iclod.com', 'ada@icloud.com'], + ['ada@yhoo.com', 'ada@yahoo.com'], + ['ada@hotmial.co.uk', 'ada@hotmail.co.uk'], + ['ada@hotmial.ca', 'ada@hotmail.ca'], + ['ada@yahoo.co', 'ada@yahoo.com'], + ])('allows %s but suggests %s', (email, suggestion) => { + expect(checkEmail(email)).toEqual({ error: '', suggestion }); + }); + + it.each([ + 'ada@gmail.com', + 'Ada.Lovelace+jobs@Gmail.com', + 'ada@mail.com', + 'ada@email.com', + 'ada@ymail.com', + 'ada@gm.com', + 'ada@me.com', + 'ada@company.co', + 'ada@startup.io', + 'ada@uni.ac.uk', + 'ada@yahoo.co.uk', + 'ada@例子.中国', + ' ada@example.org ', + // Real regional or company domains that sit close to a provider + 'ada@hotmail.ca', + 'ada@hotmail.cl', + 'ada@hotmail.co.jp', + 'ada@hotmail.fr', + 'ada@yahoo.co.jp', + 'ada@yahoo.co.id', + 'ada@yahoo.co.nz', + 'ada@yahoo.com.br', + 'ada@outlook.cl', + 'ada@outlook.co.uk', + 'ada@protonmail.ch', + 'ada@live.ca', + 'ada@gmx.de', + 'ada@cloud.com', + 'ada@unicloud.com', + 'ada@comcast.com', + ])('accepts %s without a suggestion', email => { + expect(checkEmail(email)).toEqual({ error: '', suggestion: null }); + }); + + it('requires an email', () => { + expect(checkEmail(' ')).toEqual({ error: 'Email is required.', suggestion: null }); + expect(checkEmail(undefined)).toEqual({ error: 'Email is required.', suggestion: null }); + }); + + it.each([ + ['ada@gmail', 'ada@gmail.com'], + ['ada@hotmail', 'ada@hotmail.com'], + ['ada@company', null], + ['ada', null], + ['ada@gmail.com.', 'ada@gmail.com'], + ['ada@gmail.com..', 'ada@gmail.com'], + ['ada@gmail.con.', 'ada@gmail.com'], + ['ada @gmail.com', null], + ])('flags malformed %s with suggestion %s', (email, suggestion) => { + expect(checkEmail(email)).toEqual({ + error: 'Please enter a valid email address.', + suggestion, + }); + }); + + it.each([ + ['ada@gmail.c', 'ada@gmail.com'], + ['ada@gmail.xyzq', 'ada@gmail.com'], + ])('blocks %s and suggests the provider domain %s', (email, suggestion) => { + expect(checkEmail(email)).toEqual({ error: badEnding(`.${email.split('.').pop()}`, true), suggestion }); + }); + + it('only ever suggests an address that passes the check itself', () => { + [ + 'ada@gmail.c', + 'ada@gmail.con.', + 'ada@gmail.com..', + 'ada@gmial.con', + 'ada@school.ogr', + 'ada@hotmial.cmo', + 'ada@gmail', + ].forEach(email => { + const { suggestion } = checkEmail(email); + expect(suggestion).not.toBeNull(); + expect(checkEmail(suggestion)).toEqual({ error: '', suggestion: null }); + }); + }); + + it('rejects hidden characters pasted into the address', () => { + expect(checkEmail('ada@hotmail.com\u200B')).toEqual({ + error: 'This email has a hidden character in it. Please retype it.', + suggestion: null, + }); + expect(checkEmail('a\u2060da@gmail.com').error).toBe( + 'This email has a hidden character in it. Please retype it.', + ); + }); + + it('rejects addresses longer than 254 characters without slowing down', () => { + const long = `ada@${'a'.repeat(100000)}.com`; + const started = Date.now(); + expect(checkEmail(long)).toEqual({ error: 'Please enter a valid email address.', suggestion: null }); + expect(Date.now() - started).toBeLessThan(50); + }); +}); diff --git a/src/utils/__tests__/ianaTlds.test.js b/src/utils/__tests__/ianaTlds.test.js new file mode 100644 index 00000000000..a0bc5af7836 --- /dev/null +++ b/src/utils/__tests__/ianaTlds.test.js @@ -0,0 +1,15 @@ +import { IANA_TLDS } from '../ianaTlds'; + +describe('IANA_TLDS', () => { + it('holds every entry from the IANA file, each one whole', () => { + expect(IANA_TLDS.size).toBe(1437); + IANA_TLDS.forEach(tld => { + expect(tld).toMatch(/^([a-z]{2,}|xn--[a-z0-9-]+)$/); + }); + }); + + it('includes internationalized endings such as .한국 and .中国', () => { + expect(IANA_TLDS.has('xn--3e0b707e')).toBe(true); + expect(IANA_TLDS.has('xn--fiqs8s')).toBe(true); + }); +}); diff --git a/src/utils/bioQualification.js b/src/utils/bioQualification.js index d912f6e9d71..450ff122890 100644 --- a/src/utils/bioQualification.js +++ b/src/utils/bioQualification.js @@ -1,20 +1,21 @@ /** * Single source of truth for "is this person qualified for a bio". * - * The rule below is the one that ran unchanged from 2023-07-15 (14078de29) until - * 2026-05-12, when 24e1c6ba2 swapped tenure (`daysInTeam`) for weekly summary output - * (`weeklySummariesCount`). Those measure different things — someone can be six months - * in the team with three summaries — so the tenure rule is restored here. + * Business rule (confirmed by Jae, 2026-10-13): a team member qualifies for the yellow + * bio-announcement strip once they have + * 1. a minimum of 80 tangible hours logged, and + * 2. a minimum of 8 Total Valid Weekly Summaries (`weeklySummariesCount`), + * and their bio has not been posted yet. * - * `daysInTeam` is computed server-side in HGNRest (`reporthelper.weeklySummaries`) as a - * $dateDiff in days from the user's createdDate, and survives `formatSummaries`. + * Tenure (`daysInTeam`) is not part of the rule: someone 60+ days in with only three + * valid summaries must not qualify. * * Keep every consumer on this function: the yellow highlight bar and the Bio Status * filter must agree, or a user shows a bar while being absent from the filter list. */ export const BIO_MIN_TANGIBLE_HOURS = 80; -export const BIO_MIN_DAYS_IN_TEAM = 60; +export const BIO_MIN_VALID_SUMMARIES = 8; /** * @param {object} summary A weekly summaries report row. @@ -23,9 +24,13 @@ export const BIO_MIN_DAYS_IN_TEAM = 60; export const isQualifiedForBio = summary => { if (!summary) return false; + // weeklySummariesCount can arrive as a string from the report payload. + const tangibleHrs = Number(summary.totalTangibleHrs); + const validSummaries = Number(summary.weeklySummariesCount); + return ( - summary.totalTangibleHrs > BIO_MIN_TANGIBLE_HOURS && - summary.daysInTeam > BIO_MIN_DAYS_IN_TEAM && + tangibleHrs >= BIO_MIN_TANGIBLE_HOURS && + validSummaries >= BIO_MIN_VALID_SUMMARIES && summary.bioPosted !== 'posted' ); }; diff --git a/src/utils/emailValidation.js b/src/utils/emailValidation.js new file mode 100644 index 00000000000..a33783366d7 --- /dev/null +++ b/src/utils/emailValidation.js @@ -0,0 +1,204 @@ +import { IANA_TLDS } from './ianaTlds'; + +const MAX_EMAIL_LENGTH = 254; +const WHITESPACE = /\s/; +// Zero-width and word-joiner characters ride along with copy-paste and are invisible on screen +const HIDDEN_CHARACTERS = /[\u200B-\u200D\u2060\uFEFF]/; +const INVALID_EMAIL = 'Please enter a valid email address.'; +const HIDDEN_CHARACTER_ERROR = 'This email has a hidden character in it. Please retype it.'; + +// Popular mailbox providers. A near miss of one of these is almost always a typo. +// Regional domains are listed so their own typos get caught (hotmial.ca -> hotmail.ca). +const POPULAR_DOMAINS = [ + 'gmail.com', + 'googlemail.com', + 'yahoo.com', + 'yahoo.co.uk', + 'yahoo.co.in', + 'yahoo.ca', + 'ymail.com', + 'rocketmail.com', + 'outlook.com', + 'hotmail.com', + 'hotmail.co.uk', + 'hotmail.ca', + 'live.com', + 'msn.com', + 'icloud.com', + 'me.com', + 'mac.com', + 'aol.com', + 'protonmail.com', + 'proton.me', + 'mail.com', + 'email.com', + 'gmx.com', + 'gmx.net', + 'zoho.com', + 'yandex.com', + 'comcast.net', + 'verizon.net', + 'att.net', + 'sbcglobal.net', +]; + +// Endings offered when the typed one doesn't exist (".con" -> ".com"). +const COMMON_TLDS = ['com', 'net', 'org', 'edu', 'gov', 'io', 'us', 'uk', 'ca', 'in', 'de', 'info']; + +// Split "hotmail.co.uk" into the provider name and the rest. +function splitDomain(domain) { + const dot = domain.indexOf('.'); + return { name: domain.slice(0, dot), suffix: domain.slice(dot + 1) }; +} + +// Optimal string alignment distance: insertions, deletions, substitutions and adjacent swaps +// each count as one edit, so "gmial" is one edit from "gmail". +function editDistance(a, b) { + const d = Array.from({ length: a.length + 1 }, (_, i) => [i]); + for (let j = 1; j <= b.length; j += 1) d[0][j] = j; + for (let i = 1; i <= a.length; i += 1) { + for (let j = 1; j <= b.length; j += 1) { + const cost = a[i - 1] === b[j - 1] ? 0 : 1; + d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); + if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) { + d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1); + } + } + } + return d[a.length][b.length]; +} + +function closest(value, candidates, maxEdits) { + let best = null; + let bestDistance = maxEdits + 1; + candidates.forEach(candidate => { + const distance = editDistance(value, candidate); + if (distance < bestDistance) { + best = candidate; + bestDistance = distance; + } + }); + return best; +} + +function toAsciiTld(domain) { + try { + // The URL parser converts internationalized domains to punycode, which is how IANA lists them + return new URL(`http://${domain}`).hostname.split('.').pop(); + } catch { + return domain.split('.').pop(); + } +} + +function hasRealTld(domain) { + return IANA_TLDS.has(toAsciiTld(domain)); +} + +// Provider names close enough to count as a typo. Short names allow one edit, long ones two, +// and the first letter must match so different words ("cloud" vs "icloud") aren't "corrected". +function isProviderTypo(name, providerName) { + if (name === providerName) return true; + if (name.length < 4 || name[0] !== providerName[0]) return false; + return editDistance(name, providerName) <= (name.length < 9 ? 1 : 2); +} + +// Only the provider name is fuzzy-matched. The ending is kept unless it doesn't exist +// (gmail.con) or is a one-letter slip of ".com" (gmail.co, gmail.cm), so real regional +// domains like hotmail.ca, hotmail.cl or yahoo.co.jp are left alone. +function suggestProvider(domain) { + const { name, suffix } = splitDomain(domain); + const providers = POPULAR_DOMAINS.filter(d => isProviderTypo(name, splitDomain(d).name)); + const sameSuffix = providers.find(d => splitDomain(d).suffix === suffix); + if (sameSuffix) return sameSuffix; + if (!hasRealTld(domain)) { + const nearest = closest(suffix, providers.map(d => splitDomain(d).suffix), Infinity); + return providers.find(d => splitDomain(d).suffix === nearest) || null; + } + const dotCom = providers.find(d => splitDomain(d).suffix === 'com'); + return dotCom && editDistance(suffix, 'com') === 1 ? dotCom : null; +} + +function suggestDomain(domain) { + if (POPULAR_DOMAINS.includes(domain)) return null; + const provider = suggestProvider(domain); + if (provider) return provider; + if (hasRealTld(domain)) return null; + // Not a provider: fix only the ending ("school.ogr" -> "school.org") + const dot = domain.lastIndexOf('.'); + const fixedTld = closest(domain.slice(dot + 1), COMMON_TLDS, 1); + return fixedTld ? `${domain.slice(0, dot + 1)}${fixedTld}` : null; +} + +// Same rule as /^[^\s@]+@[^\s@]+\.[^\s@]+$/ (exactly one @, a non-empty local part, and a +// dot inside the domain with characters on both sides), checked without a backtracking regex. +function hasEmailFormat(value) { + if (WHITESPACE.test(value)) return false; + const parts = value.split('@'); + if (parts.length !== 2 || !parts[0]) return false; + const domain = parts[1]; + const dot = domain.indexOf('.', 1); + return dot > 0 && dot < domain.length - 1; +} + +function stripTrailingDots(value) { + let end = value.length; + while (end > 0 && value[end - 1] === '.') end -= 1; + return value.slice(0, end); +} + +// A suggestion is only offered if it would pass the check itself. +function validSuggestion(local, domain) { + const suggestion = `${local}@${domain}`; + return hasEmailFormat(suggestion) && hasRealTld(domain) ? suggestion : null; +} + +// A malformed address can still have an obvious intended form worth offering +function suggestForMalformed(local, lowerDomain, at) { + if (at <= 0) return null; + // "name@gmail.com." only has stray trailing dots + const undotted = stripTrailingDots(lowerDomain); + if (undotted !== lowerDomain && hasEmailFormat(`${local}@${undotted}`)) { + const fixed = hasRealTld(undotted) ? undotted : suggestDomain(undotted); + return fixed ? validSuggestion(local, fixed) : null; + } + // "name@gmail" is missing its ending; offer the provider's full domain + if (!lowerDomain || lowerDomain.includes('.')) return null; + const provider = POPULAR_DOMAINS.find(d => d.split('.')[0] === lowerDomain); + return provider ? `${local}@${provider}` : null; +} + +/** + * Validate an applicant's email address. + * `error` blocks submission: the address is malformed or its ending isn't a real top-level + * domain (name@gmail.con). `suggestion` is a likely intended address for common typos + * (name@gmial.com -> name@gmail.com); it never blocks, since the typed address may be real. + * @param {string} rawEmail + * @returns {{ error: string, suggestion: string | null }} + */ +export function checkEmail(rawEmail) { + const email = String(rawEmail ?? '').trim(); + if (!email) return { error: 'Email is required.', suggestion: null }; + if (email.length > MAX_EMAIL_LENGTH) return { error: INVALID_EMAIL, suggestion: null }; + if (HIDDEN_CHARACTERS.test(email)) return { error: HIDDEN_CHARACTER_ERROR, suggestion: null }; + + const at = email.lastIndexOf('@'); + const local = email.slice(0, at); + const domain = email.slice(at + 1); + const lowerDomain = domain.toLowerCase(); + + if (!hasEmailFormat(email) || lowerDomain.endsWith('.')) { + return { error: INVALID_EMAIL, suggestion: suggestForMalformed(local, lowerDomain, at) }; + } + + const suggestedDomain = suggestDomain(lowerDomain); + const suggestion = suggestedDomain ? validSuggestion(local, suggestedDomain) : null; + + if (!hasRealTld(lowerDomain)) { + const tld = domain.split('.').pop(); + // With a suggestion on screen, the hint already says how to fix it + const advice = suggestion ? '' : ' Check for a typo.'; + return { error: `".${tld}" isn't a valid email domain ending.${advice}`, suggestion }; + } + + return { error: '', suggestion }; +} diff --git a/src/utils/ianaTlds.js b/src/utils/ianaTlds.js new file mode 100644 index 00000000000..1b47fef28d1 --- /dev/null +++ b/src/utils/ianaTlds.js @@ -0,0 +1,109 @@ +// Top-level domains from IANA: https://data.iana.org/TLD/tlds-alpha-by-domain.txt +// Version 2026101300, Last Updated Tue Oct 13 07:07:02 2026 UTC. 1437 entries. +// New TLDs are rare; regenerate from that file if a real domain ending is ever rejected. +export const IANA_TLDS = new Set( + ` +aaa aarp abb abbott abbvie abc able abogado abudhabi ac academy accenture accountant accountants +aco actor ad ads adult ae aeg aero aetna af afl africa ag agakhan agency ai aig airbus airforce +airtel akdn al alibaba alipay allfinanz allstate ally alsace alstom am amazon americanexpress +americanfamily amex amfam amica amsterdam analytics android anquan anz ao aol apartments app apple +aq aquarelle ar arab aramco archi army arpa art arte as asda asia associates at athleta attorney +au auction audi audible audio auspost author auto autos aw aws ax axa az azure ba baby baidu +banamex band bank bar barcelona barclaycard barclays barefoot bargains baseball basketball bauhaus +bayern bb bbc bbt bbva bcg bcn bd be beats beauty beer berlin best bestbuy bet bf bg bh bharti bi +bible bid bike bing bingo bio biz bj black blackfriday blockbuster blog bloomberg blue bm bms bmw +bn bnpparibas bo boats boehringer bofa bom bond boo book booking bosch bostik boston bot boutique +box br bradesco bridgestone broadway broker brother brussels bs bt build builders business buy +buzz bv bw by bz bzh ca cab cafe cal call calvinklein cam camera camp canon capetown capital +capitalone car caravan cards care career careers cars casa case cash casino cat catering catholic +cba cbn cbre cc cd center ceo cern cf cfa cfd cg ch chanel channel charity chase chat cheap +chintai christmas chrome church ci cipriani circle cisco citadel citi citic city ck cl claims +cleaning click clinic clinique clothing cloud club clubmed cm cn co coach codes coffee college +cologne com commbank community company compare computer comsec condos construction consulting +contact contractors cooking cool coop corsica country coupon coupons courses cpa cr credit +creditcard creditunion cricket crown crs cruise cruises cu cuisinella cv cw cx cy cymru cyou cz +dad dance data date dating datsun day dclk dds de deal dealer deals degree delivery dell deloitte +delta democrat dental dentist desi design dev dhl diamonds diet digital direct directory discount +discover dish diy dj dk dm dnp do docs doctor dog domains dot download drive dtv dubai dupont +durban dvag dvr dz earth eat ec eco edeka edu education ee eg email emerck energy engineer +engineering enterprises epson equipment er ericsson erni es esq estate et eu eurovision eus events +exchange expert exposed express extraspace fage fail fairwinds faith family fan fans farm farmers +fashion fast fedex feedback ferrari ferrero fi fidelity fido film final finance financial fire +firestone firmdale fish fishing fit fitness fj fk flickr flights flir florist flowers fly fm fo +foo food football ford forex forsale forum foundation fox fr free fresenius frl frogans frontier +ftr fujitsu fun fund furniture futbol fyi ga gal gallery gallo gallup game games gap garden gay gb +gbiz gd gdn ge gea gent genting george gf gg ggee gh gi gift gifts gives giving gl glass gle +global globo gm gmail gmbh gmo gmx gn godaddy gold goldpoint golf goodyear goog google gop got gov +gp gq gr grainger graphics gratis green gripe grocery group gs gt gu gucci guge guide guitars guru +gw gy hair hamburg hangout haus hbo hdfc hdfcbank health healthcare help helsinki here hermes +hiphop hisamitsu hitachi hiv hk hkt hm hn hockey holdings holiday homedepot homegoods homes +homesense honda horse hospital host hosting hot hotels hotmail house how hr hsbc ht hu hughes +hyatt hyundai ibm icbc ice icu id ie ieee ifm ikano il im imamat imdb immo immobilien in inc +industries infiniti info ing ink institute insurance insure int international intuit investments +io ipiranga iq ir irish is ismaili ist istanbul it itau itv jaguar java jcb je jeep jetzt jewelry +jio jll jm jmp jnj jo jobs joburg jot joy jp jpmorgan jprs juegos kaufen kddi ke kerryhotels +kerryproperties kfh kg kh ki kia kids kim kindle kitchen kiwi km kn koeln komatsu kosher kp kpmg +kpn kr krd kred kuokgroup kw ky kyoto kz la lacaixa lamborghini lamer land landrover lanxess +lasalle lat latino latrobe law lawyer lb lc lds lease leclerc lefrak legal lego lexus lgbt li lidl +life lifeinsurance lifestyle lighting like lilly limited limo lincoln link live living lk llc llp +loan loans locker locus lol london lotte lotto love lpl lplfinancial lr ls lt ltd ltda lu lundbeck +luxe luxury lv ly ma madrid maif maison makeup man management mango map market marketing markets +marriott marshalls mattel mba mc mckinsey md me med media meet melbourne meme memorial men menu +merck merckmsd mg mh miami microsoft mil mini mint mit mitsubishi mk ml mlb mls mm mma mn mo mobi +mobile moda moe moi mom monash money monster mormon mortgage moscow moto motorcycles mov movie mp +mq mr ms msd mt mtn mtr mu museum music mv mw mx my mz na nab nagoya name navy nba nc ne nec net +netbank netflix network neustar new news next nextdirect nexus nf nfl ng ngo nhk ni nico nike +nikon ninja nissan nissay nl no nokia norton now nowruz nowtv np nr nra nrw ntt nu nyc nz obi +observer office okinawa olayan olayangroup ollo om omega one ong onl online ooo open oracle orange +org organic origins osaka otsuka ott ovh pa page panasonic paris pars partners parts party pay +pccw pe pet pf pfizer pg ph pharmacy phd philips phone photo photography photos physio pics pictet +pictures pid pin ping pink pioneer pizza pk pl place play playstation plumbing plus pm pn pnc pohl +poker politie porn post pr praxi press prime pro prod productions prof progressive promo +properties property protection pru prudential ps pt pub pw pwc py qa qpon quebec quest racing +radio re read realestate realtor realty recipes red redumbrella rehab reise reisen reit reliance +ren rent rentals repair report republican rest restaurant review reviews rexroth rich richardli +ricoh ril rio rip ro rocks rodeo rogers room rs rsvp ru rugby ruhr run rw rwe ryukyu sa saarland +safe safety sakura sale salon samsclub samsung sandvik sandvikcoromant sanofi sap sarl sas save +saxo sb sbi sbs sc scb schaeffler schmidt scholarships school schule schwarz science scot sd se +search seat secure security seek select sener services seven sew sex sexy sfr sg sh shangrila +sharp shell shia shiksha shoes shop shopping shouji show si silk sina singles site sj sk ski skin +sky skype sl sling sm smart smile sn sncf so soccer social softbank software sohu solar solutions +song sony soy spa space sport spot sr srl ss st stada staples star statebank statefarm stc +stcgroup stockholm storage store stream studio study style su sucks supplies supply support surf +surgery suzuki sv swatch swiss sx sy sydney systems sz tab taipei talk taobao target tatamotors +tatar tattoo tax taxi tc tci td tdk team tech technology tel temasek tennis teva tf tg th thd +theater theatre tiaa tickets tienda tips tires tirol tj tjmaxx tjx tk tkmaxx tl tm tmall tn to +today tokyo tools top toray toshiba total tours town toyota toys tr trade trading training travel +travelers travelersinsurance trust trv tt tube tui tunes tushu tv tvs tw tz ua ubank ubs ug uk +unicom university uno uol ups us uy uz va vacations vana vanguard vc ve vegas ventures verisign +versicherung vet vg vi viajes video vig viking villas vin vip virgin visa vision viva vivo +vlaanderen vn vodka volvo vote voting voto voyage vu wales walmart walter wang wanggou watch +watches weather weatherchannel web webcam weber website wed wedding weibo weir wf whoswho wien +wiki williamhill win windows wine winners wme woodside work works world wow ws wtc wtf xbox xerox +xihuan xin xn--11b4c3d xn--1ck2e1b xn--1qqw23a xn--2scrj9c xn--30rr7y xn--3bst00m xn--3ds443g +xn--3e0b707e xn--3hcrj9c xn--3pxu8k xn--42c2d9a xn--45br5cyl xn--45brj9c xn--45q11c xn--4dbrk0ce +xn--4gbrim xn--54b7fta0cc xn--55qw42g xn--55qx5d xn--5su34j936bgsg xn--5tzm5g xn--6frz82g +xn--6qq986b3xl xn--80adxhks xn--80ao21a xn--80aqecdr1a xn--80asehdb xn--80aswg xn--8y0a063a +xn--90a3ac xn--90ae xn--90ais xn--9dbq2a xn--9et52u xn--9krt00a xn--b4w605ferd xn--bck1b9a5dre4c +xn--c1avg xn--c2br7g xn--cck2b3b xn--cckwcxetd xn--cg4bki xn--clchc0ea0b2g2a9gcd xn--czr694b +xn--czrs0t xn--czru2d xn--d1acj3b xn--d1alf xn--e1a4c xn--eckvdtc9d xn--efvy88h xn--fct429k +xn--fhbei xn--fiq228c5hs xn--fiq64b xn--fiqs8s xn--fiqz9s xn--fjq720a xn--flw351e xn--fpcrj9c3d +xn--fzc2c9e2c xn--fzys8d69uvgm xn--g2xx48c xn--gckr3f0f xn--gecrj9c xn--gk3at1e xn--h2breg3eve +xn--h2brj9c xn--h2brj9c8c xn--hxt814e xn--i1b6b1a6a2e xn--imr513n xn--io0a7i xn--j1aef xn--j1amh +xn--j6w193g xn--jlq480n2rg xn--jvr189m xn--kcrx77d1x4a xn--kprw13d xn--kpry57d xn--kput3i +xn--l1acc xn--lgbbat1ad8j xn--mgb9awbf xn--mgba3a3ejt xn--mgba3a4f16a xn--mgba7c0bbn0a +xn--mgbaam7a8h xn--mgbab2bd xn--mgbah1a3hjkrd xn--mgbai9azgqp6j xn--mgbayh7gpa xn--mgbbh1a +xn--mgbbh1a71e xn--mgbc0a9azcg xn--mgbca7dzdo xn--mgbcpq6gpa1a xn--mgberp4a5d4ar xn--mgbgu82a +xn--mgbi4ecexp xn--mgbpl2fh xn--mgbt3dhd xn--mgbtx2b xn--mgbx4cd0ab xn--mix891f xn--mk1bu44c +xn--mxtq1m xn--ngbc5azd xn--ngbe9e0a xn--ngbrx xn--node xn--nqv7f xn--nqv7fs00ema xn--nyqy26a +xn--o3cw4h xn--ogbpf8fl xn--otu796d xn--p1acf xn--p1ai xn--pgbs0dh xn--pssy2u xn--q7ce6a +xn--q9jyb4c xn--qcka1pmc xn--qxa6a xn--qxam xn--rhqv96g xn--rovu88b xn--rvc1e0am3e xn--s9brj9c +xn--ses554g xn--t60b56a xn--tckwe xn--tiq49xqyj xn--unup4y xn--vermgensberater-ctb +xn--vermgensberatung-pwb xn--vhquv xn--vuq861b xn--w4r85el8fhu5dnra xn--w4rs40l xn--wgbh1c +xn--wgbl6a xn--xhq521b xn--xkc2al3hye2a xn--xkc2dl3a5ee0h xn--y9a3aq xn--yfro4i67o xn--ygbi2ammx +xn--zfr164b xxx xyz yachts yahoo yamaxun yandex ye yodobashi yoga yokohama you youtube yt yun za +zappos zara zero zip zm zone zuerich zw +` + .trim() + .split(/\s+/), +); diff --git a/yarn.lock b/yarn.lock index 1576ab7fb3d..08282b80582 100644 --- a/yarn.lock +++ b/yarn.lock @@ -209,6 +209,19 @@ gl-matrix "^3.4.3" tslib "^2.5.3" +"@antv/g-lite@2.7.2": + version "2.7.2" + resolved "https://registry.npmjs.org/@antv/g-lite/-/g-lite-2.7.2.tgz" + integrity sha512-hno43swzUX3jBSi26O0l9YJxRVTiZ5HcNb3K6YKf8DRyT/hDo1zvnyD3vm/AmNa9va+3W76VznKgJThn4zRhYw== + dependencies: + "@antv/g-math" "3.1.0" + "@antv/util" "^3.3.5" + "@antv/vendor" "^1.0.3" + "@babel/runtime" "^7.25.6" + eventemitter3 "^5.0.1" + gl-matrix "^3.4.3" + tslib "^2.5.3" + "@antv/g-math@3.1.0": version "3.1.0" resolved "https://registry.npmjs.org/@antv/g-math/-/g-math-3.1.0.tgz" @@ -240,6 +253,17 @@ gl-matrix "^3.4.3" tslib "^2.5.3" +"@antv/g@^6.1.11", "@antv/g@^6.1.24", "@antv/g@^6.1.28", "@antv/g@^6.1.7": + version "6.3.3" + resolved "https://registry.npmjs.org/@antv/g/-/g-6.3.3.tgz" + integrity sha512-Fs07ACQ7LqIpGFhL1wrVhdNbpsezL+vZKzKnKQj3dFzmEHu3S0sSumJtx2iCjy5shQPDWFu8vqSRdYrZdTVlGg== + dependencies: + "@antv/g-lite" "2.7.2" + "@antv/util" "^3.3.5" + "@babel/runtime" "^7.25.6" + gl-matrix "^3.4.3" + html2canvas "^1.4.1" + "@antv/g2-extension-plot@^0.2.1": version "0.2.2" resolved "https://registry.npmjs.org/@antv/g2-extension-plot/-/g2-extension-plot-0.2.2.tgz" @@ -275,7 +299,7 @@ "@antv/g" "^6.1.24" "@antv/g-svg" "^2.0.38" -"@antv/g6@^5.0.28", "@antv/g6@^5.0.44": +"@antv/g6@^5.0.28", "@antv/g6@^5.0.44", "@antv/g6@^5.1.0": version "5.1.1" resolved "https://registry.npmjs.org/@antv/g6/-/g6-5.1.1.tgz" integrity sha512-50bXxMUf4mChyOv4ePVeWZLwotih9VunKfp0a++Wofv/wCyY8fb9+CV2wouIBCOZnd5ydBRA4NNaX9yLJzqa2w== @@ -292,17 +316,6 @@ "@antv/util" "^3.3.11" bubblesets-js "^2.3.4" -"@antv/g@^6.1.11", "@antv/g@^6.1.24", "@antv/g@^6.1.28", "@antv/g@^6.1.7": - version "6.3.1" - resolved "https://registry.npmjs.org/@antv/g/-/g-6.3.1.tgz" - integrity sha512-WYEKqy86LHB2PzTmrZXrIsIe+3Epeds2f68zceQ+BJtRoGki7Sy4IhlC8LrUMztgfT1t3d/0L745NWZwITroKA== - dependencies: - "@antv/g-lite" "2.7.0" - "@antv/util" "^3.3.5" - "@babel/runtime" "^7.25.6" - gl-matrix "^3.4.3" - html2canvas "^1.4.1" - "@antv/graphin@^3.0.4": version "3.0.5" resolved "https://registry.npmjs.org/@antv/graphin/-/graphin-3.0.5.tgz" @@ -340,7 +353,16 @@ ml-matrix "^6.10.4" tslib "^2.8.1" -"@antv/scale@^0.4.12", "@antv/scale@^0.4.16": +"@antv/scale@^0.4.12": + version "0.4.16" + resolved "https://registry.npmjs.org/@antv/scale/-/scale-0.4.16.tgz" + integrity sha512-5wg/zB5kXHxpTV5OYwJD3ja6R8yTiqIOkjOhmpEJiowkzRlbEC/BOyMvNUq5fqFIHnMCE9woO7+c3zxEQCKPjw== + dependencies: + "@antv/util" "^3.3.7" + color-string "^1.5.5" + fecha "^4.2.1" + +"@antv/scale@^0.4.16": version "0.4.16" resolved "https://registry.npmjs.org/@antv/scale/-/scale-0.4.16.tgz" integrity sha512-5wg/zB5kXHxpTV5OYwJD3ja6R8yTiqIOkjOhmpEJiowkzRlbEC/BOyMvNUq5fqFIHnMCE9woO7+c3zxEQCKPjw== @@ -433,50 +455,41 @@ "@csstools/css-tokenizer" "^3.0.3" lru-cache "^10.4.3" -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz" - integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== - dependencies: - "@babel/helper-validator-identifier" "^7.27.1" - js-tokens "^4.0.0" - picocolors "^1.1.1" - -"@babel/code-frame@^7.29.0", "@babel/code-frame@^7.29.7": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.29.7": version "7.29.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz" integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw== dependencies: "@babel/helper-validator-identifier" "^7.29.7" js-tokens "^4.0.0" picocolors "^1.1.1" +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0", "@babel/compat-data@^7.29.7": version "7.29.7" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz" integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@^7.29.6": - version "7.29.6" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.29.6.tgz" - integrity sha512-QdxmAo/ikZqqRGA8s43ww8lcql6naWRvEz0FFrl6MIlc7Gi6TroXnSdWa5U/kq6fzcpqpHesicQxFZIieZbyIA== - dependencies: - "@babel/code-frame" "^7.29.0" - "@babel/generator" "^7.29.6" - "@babel/helper-compilation-targets" "^7.28.6" - "@babel/helper-module-transforms" "^7.28.6" - "@babel/helpers" "^7.29.2" - "@babel/parser" "^7.29.3" - "@babel/template" "^7.28.6" - "@babel/traverse" "^7.29.0" - "@babel/types" "^7.29.0" +"@babel/core@^7.0.0", "@babel/core@^7.0.0 || ^8.0.0-0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.0", "@babel/core@^7.11.0 || ^8.0.0-0", "@babel/core@^7.11.0 || ^8.0.0-beta.1 || ^8.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@^7.28.0", "@babel/core@^7.29.6", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.8.0": + version "7.29.7" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz" + integrity sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/generator" "^7.29.7" + "@babel/helper-compilation-targets" "^7.29.7" + "@babel/helper-module-transforms" "^7.29.7" + "@babel/helpers" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/template" "^7.29.7" + "@babel/traverse" "^7.29.7" + "@babel/types" "^7.29.7" "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" @@ -484,15 +497,6 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/core@^7.28.0": - version "7.28.0" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz" - integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ== - dependencies: - "@babel/helper-validator-identifier" "^7.29.7" - js-tokens "^4.0.0" - picocolors "^1.1.1" - "@babel/eslint-parser@^7.28.0": version "7.28.0" resolved "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.0.tgz" @@ -502,7 +506,7 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.1" -"@babel/generator@^7.27.5", "@babel/generator@^7.29.6", "@babel/generator@^7.29.8", "@babel/generator@^7.7.2": +"@babel/generator@^7.27.5", "@babel/generator@^7.29.7", "@babel/generator@^7.29.8": version "7.29.8" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz" integrity sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg== @@ -520,7 +524,7 @@ dependencies: "@babel/types" "^7.27.3" -"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2", "@babel/helper-compilation-targets@^7.28.6": +"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2", "@babel/helper-compilation-targets@^7.29.7": version "7.29.7" resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz" integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g== @@ -585,7 +589,7 @@ "@babel/traverse" "^7.29.7" "@babel/types" "^7.29.7" -"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.6": +"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.29.7": version "7.29.7" resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz" integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg== @@ -601,10 +605,10 @@ dependencies: "@babel/types" "^7.27.1" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" - integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.29.7", "@babel/helper-plugin-utils@^7.8.0": + version "7.29.7" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz" + integrity sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw== "@babel/helper-remap-async-to-generator@^7.27.1": version "7.27.1" @@ -637,7 +641,7 @@ resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz" integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw== -"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.25.9", "@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.29.7": +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.25.9", "@babel/helper-validator-identifier@^7.29.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== @@ -656,13 +660,13 @@ "@babel/traverse" "^7.28.3" "@babel/types" "^7.28.2" -"@babel/helpers@^7.29.2": - version "7.29.7" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz" - integrity sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg== +"@babel/helpers@^7.29.7": + version "7.29.10" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz" + integrity sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg== dependencies: "@babel/template" "^7.29.7" - "@babel/types" "^7.29.7" + "@babel/types" "^7.29.8" "@babel/highlight@^7.10.4": version "7.25.9" @@ -674,10 +678,10 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.4", "@babel/parser@^7.29.3", "@babel/parser@^7.29.7", "@babel/parser@^7.29.8": - version "7.29.8" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz" - integrity sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.4", "@babel/parser@^7.29.7", "@babel/parser@^7.29.8", "@babel/parser@^7.29.9": + version "7.29.9" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz" + integrity sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA== dependencies: "@babel/types" "^7.29.8" @@ -789,7 +793,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.27.1", "@babel/plugin-syntax-jsx@^7.7.2": +"@babel/plugin-syntax-jsx@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz" integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== @@ -852,12 +856,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.27.1", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz" - integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== +"@babel/plugin-syntax-typescript@^7.27.1": + version "7.29.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz" + integrity sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA== dependencies: - "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-plugin-utils" "^7.29.7" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -1064,14 +1068,14 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-modules-systemjs@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz" - integrity sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA== + version "7.29.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.8.tgz" + integrity sha512-6iSnEK0zlkLKU4heofK/AdmRD4e2SHVpJMtrwnTCzhnaM98ria4rTrOXBBi45BTTYnJtO8txnPsX4fChYXkmeA== dependencies: - "@babel/helper-module-transforms" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/helper-module-transforms" "^7.29.7" + "@babel/helper-plugin-utils" "^7.29.7" + "@babel/helper-validator-identifier" "^7.29.7" + "@babel/traverse" "^7.29.8" "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" @@ -1420,7 +1424,7 @@ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz" integrity sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw== -"@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.28.6", "@babel/template@^7.29.7", "@babel/template@^7.3.3": +"@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.29.7", "@babel/template@^7.3.3": version "7.29.7" resolved "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz" integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg== @@ -1429,20 +1433,20 @@ "@babel/parser" "^7.29.7" "@babel/types" "^7.29.7" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.29.0", "@babel/traverse@^7.29.7": - version "7.29.8" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz" - integrity sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg== +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.29.7", "@babel/traverse@^7.29.8": + version "7.29.10" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz" + integrity sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ== dependencies: "@babel/code-frame" "^7.29.7" "@babel/generator" "^7.29.8" "@babel/helper-globals" "^7.29.7" - "@babel/parser" "^7.29.8" + "@babel/parser" "^7.29.9" "@babel/template" "^7.29.7" "@babel/types" "^7.29.8" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.4", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.29.0", "@babel/types@^7.29.7", "@babel/types@^7.29.8", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.4", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.29.7", "@babel/types@^7.29.8", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.29.8" resolved "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz" integrity sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg== @@ -1551,9 +1555,9 @@ integrity sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w== "@csstools/css-syntax-patches-for-csstree@^1.0.19", "@csstools/css-syntax-patches-for-csstree@^1.1.4": - version "1.1.8" - resolved "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.8.tgz" - integrity sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg== + version "1.1.9" + resolved "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.9.tgz" + integrity sha512-iGGw4OsAYsS6pD29MdJ2bX/nJx65a04ZZiw6x+VwWlP2DdXf6f++Zmuv/OzALpdyfVhjbduIIF2cXM7HWBIe9A== "@csstools/css-tokenizer@^3.0.3", "@csstools/css-tokenizer@^3.0.4": version "3.0.4" @@ -1592,28 +1596,6 @@ resolved "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz" integrity sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg== -"@emnapi/core@1.10.0": - version "1.10.0" - resolved "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz" - integrity sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw== - dependencies: - "@emnapi/wasi-threads" "1.2.1" - tslib "^2.4.0" - -"@emnapi/runtime@1.10.0": - version "1.10.0" - resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz" - integrity sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz" - integrity sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w== - dependencies: - tslib "^2.4.0" - "@emotion/babel-plugin@^11.13.5": version "11.13.5" resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz" @@ -1652,7 +1634,7 @@ resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz" integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== -"@emotion/is-prop-valid@1.4.0", "@emotion/is-prop-valid@^1.3.0": +"@emotion/is-prop-valid@^1.3.0", "@emotion/is-prop-valid@1.4.0": 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== @@ -1664,7 +1646,7 @@ resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz" integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== -"@emotion/react@^11.8.1": +"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@^11.8.1", "@emotion/react@^11.9.0": version "11.14.0" resolved "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz" integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== @@ -1694,7 +1676,7 @@ resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz" integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== -"@emotion/styled@^11.14.0": +"@emotion/styled@^11.14.0", "@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1": version "11.14.1" resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz" integrity sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw== @@ -1753,7 +1735,7 @@ "@ephox/bedrock-common" "^13.0.0" "@ephox/dispute" "^1.0.3" -"@ephox/bedrock-common@11 || 12 || 13", "@ephox/bedrock-common@^13.0.0": +"@ephox/bedrock-common@^13.0.0", "@ephox/bedrock-common@11 || 12 || 13": version "13.0.0" resolved "https://registry.npmjs.org/@ephox/bedrock-common/-/bedrock-common-13.0.0.tgz" integrity sha512-aJ3gtezZ0duGJAniT/+uWi0fFCJRqNdJjumxhCwOVTc2MSsXcyqn70s6FIlrp/Fw2QuyiEqxgormgrmBUbWNWA== @@ -1807,136 +1789,11 @@ "@ephox/katamari" "^9.1.6" "@ephox/sand" "^6.0.10" -"@esbuild/aix-ppc64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz" - integrity sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA== - -"@esbuild/android-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz" - integrity sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg== - -"@esbuild/android-arm@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz" - integrity sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ== - -"@esbuild/android-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz" - integrity sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw== - "@esbuild/darwin-arm64@0.25.9": version "0.25.9" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz" integrity sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg== -"@esbuild/darwin-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz" - integrity sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ== - -"@esbuild/freebsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz" - integrity sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q== - -"@esbuild/freebsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz" - integrity sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg== - -"@esbuild/linux-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz" - integrity sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw== - -"@esbuild/linux-arm@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz" - integrity sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw== - -"@esbuild/linux-ia32@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz" - integrity sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A== - -"@esbuild/linux-loong64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz" - integrity sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ== - -"@esbuild/linux-mips64el@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz" - integrity sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA== - -"@esbuild/linux-ppc64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz" - integrity sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w== - -"@esbuild/linux-riscv64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz" - integrity sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg== - -"@esbuild/linux-s390x@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz" - integrity sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA== - -"@esbuild/linux-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz" - integrity sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg== - -"@esbuild/netbsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz" - integrity sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q== - -"@esbuild/netbsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz" - integrity sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g== - -"@esbuild/openbsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz" - integrity sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ== - -"@esbuild/openbsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz" - integrity sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA== - -"@esbuild/openharmony-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz" - integrity sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg== - -"@esbuild/sunos-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz" - integrity sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw== - -"@esbuild/win32-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz" - integrity sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ== - -"@esbuild/win32-ia32@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz" - integrity sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww== - -"@esbuild/win32-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz" - integrity sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ== - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.9.1": version "4.9.1" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz" @@ -2068,7 +1925,7 @@ resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.0.1.tgz" integrity sha512-0VpNtO5cNe1/HQWMkl4OdncYK/mv9hnBte0Ew0n6DMzmo3Q3WzDFABHm6LeNTipt5zAyhQ6Ugjiu8aLaEjh1gg== -"@fortawesome/fontawesome-svg-core@^6.7.2": +"@fortawesome/fontawesome-svg-core@^6.7.2", "@fortawesome/fontawesome-svg-core@~1 || ~6 || ~7": version "6.7.2" resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz" integrity sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA== @@ -2235,29 +2092,29 @@ resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz" - integrity sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA== +"@jest/console@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/console/-/console-30.5.2.tgz" + integrity sha512-e8sQC4pCMHPBrPX7Hk8TJr+DM5dkUnImSTNag8SEWFAFAF6xIz4AJvCKapnrdHnZxep4bxw4PhG+ZbimYBMyKw== dependencies: - "@jest/types" "30.4.1" + "@jest/types" "30.5.1" "@types/node" "*" chalk "^4.1.2" - jest-message-util "30.4.1" - jest-util "30.4.1" + jest-message-util "30.5.1" + jest-util "30.5.1" slash "^3.0.0" -"@jest/core@30.4.2": - version "30.4.2" - resolved "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz" - integrity sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ== - dependencies: - "@jest/console" "30.4.1" - "@jest/pattern" "30.4.0" - "@jest/reporters" "30.4.1" - "@jest/test-result" "30.4.1" - "@jest/transform" "30.4.1" - "@jest/types" "30.4.1" +"@jest/core@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/core/-/core-30.5.2.tgz" + integrity sha512-/jqvFWoJF7LV1a6AUpYMbMm+2yIYsHJfR474H0SCzr9k8tnO/jl9wRg6zSG6lxgf6EozNlCG4amFzWsbZSvvZA== + dependencies: + "@jest/console" "30.5.2" + "@jest/pattern" "30.5.0" + "@jest/reporters" "30.5.2" + "@jest/test-result" "30.5.2" + "@jest/transform" "30.5.2" + "@jest/types" "30.5.1" "@types/node" "*" ansi-escapes "^4.3.2" chalk "^4.1.2" @@ -2265,41 +2122,26 @@ exit-x "^0.2.2" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.11" - jest-changed-files "30.4.1" - jest-config "30.4.2" - jest-haste-map "30.4.1" - jest-message-util "30.4.1" - jest-regex-util "30.4.0" - jest-resolve "30.4.1" - jest-resolve-dependencies "30.4.2" - jest-runner "30.4.2" - jest-runtime "30.4.2" - jest-snapshot "30.4.1" - jest-util "30.4.1" - jest-validate "30.4.1" - jest-watcher "30.4.1" - pretty-format "30.4.1" + jest-changed-files "30.5.1" + jest-config "30.5.2" + jest-haste-map "30.5.1" + jest-message-util "30.5.1" + jest-regex-util "30.5.0" + jest-resolve "30.5.1" + jest-resolve-dependencies "30.5.2" + jest-runner "30.5.2" + jest-runtime "30.5.2" + jest-snapshot "30.5.2" + jest-util "30.5.1" + jest-validate "30.5.1" + jest-watcher "30.5.2" + pretty-format "30.5.1" slash "^3.0.0" -"@jest/diff-sequences@30.0.1": - version "30.0.1" - resolved "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz" - integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw== - -"@jest/diff-sequences@30.4.0": - version "30.4.0" - resolved "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz" - integrity sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g== - -"@jest/environment@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz" - integrity sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w== - dependencies: - "@jest/fake-timers" "30.4.1" - "@jest/types" "30.4.1" - "@types/node" "*" - jest-mock "30.4.1" +"@jest/diff-sequences@30.5.0": + version "30.5.0" + resolved "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.5.0.tgz" + integrity sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg== "@jest/environment@^29.7.0": version "29.7.0" @@ -2311,54 +2153,42 @@ "@types/node" "*" jest-mock "^29.7.0" -"@jest/expect-utils@30.1.1": - version "30.1.1" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.1.1.tgz" - integrity sha512-5YUHr27fpJ64dnvtu+tt11ewATynrHkGYD+uSFgRr8V2eFJis/vEXgToyLwccIwqBihVfz9jwio+Zr1ab1Zihw== - dependencies: - "@jest/get-type" "30.1.0" - -"@jest/expect-utils@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz" - integrity sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ== - dependencies: - "@jest/get-type" "30.1.0" - -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== +"@jest/environment@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz" + integrity sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg== dependencies: - jest-get-type "^29.6.3" + "@jest/fake-timers" "30.5.2" + "@jest/types" "30.5.1" + "@types/node" "*" + jest-mock "30.5.2" -"@jest/expect@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz" - integrity sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA== +"@jest/expect-utils@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.5.2.tgz" + integrity sha512-d/HOLSrJUlBIl6n3LzOa7cjW3xdePm5H5gQw2lixZ/0h157l9sw3mLblzFqnPcTbhDzhRQdBOX3A3KcG73nm5Q== dependencies: - expect "30.4.1" - jest-snapshot "30.4.1" + "@jest/get-type" "30.5.0" "@jest/expect@^29.7.0": version "29.7.0" - resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz" - integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: - expect "^29.7.0" - jest-snapshot "^29.7.0" + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" -"@jest/fake-timers@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz" - integrity sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ== +"@jest/expect@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-30.5.2.tgz" + integrity sha512-2E+1Pg6jJxbRjLNLpciC71iri/3qsKJL222/aXJEFwC0VdUSvfS+JZQQLEVjUYYc8t8pQu2MGE3cF2+bNTYRsg== dependencies: - "@jest/types" "30.4.1" - "@sinonjs/fake-timers" "^15.4.0" - "@types/node" "*" - jest-message-util "30.4.1" - jest-mock "30.4.1" - jest-util "30.4.1" + expect "30.5.2" + jest-snapshot "30.5.2" "@jest/fake-timers@^29.7.0": version "29.7.0" @@ -2372,20 +2202,22 @@ jest-mock "^29.7.0" jest-util "^29.7.0" -"@jest/get-type@30.1.0": - version "30.1.0" - resolved "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz" - integrity sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA== - -"@jest/globals@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz" - integrity sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q== +"@jest/fake-timers@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz" + integrity sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw== dependencies: - "@jest/environment" "30.4.1" - "@jest/expect" "30.4.1" - "@jest/types" "30.4.1" - jest-mock "30.4.1" + "@jest/types" "30.5.1" + "@sinonjs/fake-timers" "^15.4.0" + "@types/node" "*" + jest-message-util "30.5.1" + jest-mock "30.5.2" + jest-util "30.5.1" + +"@jest/get-type@30.5.0": + version "30.5.0" + resolved "https://registry.npmjs.org/@jest/get-type/-/get-type-30.5.0.tgz" + integrity sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q== "@jest/globals@^29.7.0": version "29.7.0" @@ -2397,65 +2229,63 @@ "@jest/types" "^29.6.3" jest-mock "^29.7.0" -"@jest/pattern@30.0.1": - version "30.0.1" - resolved "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz" - integrity sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA== +"@jest/globals@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-30.5.2.tgz" + integrity sha512-62zfS+dL+M5aTNHXCNLyqD+j4oqxTIzDYrZbpqMP8Yn+gvlAGyzC6BSPNb1ZmFOakV1RtFYX/O3FCQXSWmQdgg== dependencies: - "@types/node" "*" - jest-regex-util "30.0.1" + "@jest/environment" "30.5.2" + "@jest/expect" "30.5.2" + "@jest/types" "30.5.1" + jest-mock "30.5.2" -"@jest/pattern@30.4.0": - version "30.4.0" - resolved "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz" - integrity sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg== +"@jest/pattern@30.5.0": + version "30.5.0" + resolved "https://registry.npmjs.org/@jest/pattern/-/pattern-30.5.0.tgz" + integrity sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w== dependencies: "@types/node" "*" - jest-regex-util "30.4.0" + jest-regex-util "30.5.0" + +"@jest/react-is-18@npm:react-is@^18.3.1": + version "18.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== -"@jest/reporters@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz" - integrity sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA== +"@jest/react-is-19@npm:react-is@^19.2.5": + version "19.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-19.3.1.tgz" + integrity sha512-RRieF6IyxQBkcK6pP8xOHprLTPW6QjRkbGdImtqNme+/hYVwCZkLQLdlZGOhUqXwkS9IEynaGvPJtv6XB/cz0Q== + +"@jest/reporters@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-30.5.2.tgz" + integrity sha512-ev6E9iG73twQcfAfoTnviuYkr3yOrYbzAtMFCimv2fxHXPIp9PBt2u1wNMt0aYWgl8FPwIcS8oqRJg6alnht4Q== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "30.4.1" - "@jest/test-result" "30.4.1" - "@jest/transform" "30.4.1" - "@jest/types" "30.4.1" - "@jridgewell/trace-mapping" "^0.3.25" + "@jest/console" "30.5.2" + "@jest/test-result" "30.5.2" + "@jest/transform" "30.5.2" + "@jest/types" "30.5.1" + "@jridgewell/trace-mapping" "^0.3.31" "@types/node" "*" chalk "^4.1.2" collect-v8-coverage "^1.0.2" exit-x "^0.2.2" - glob "^10.5.0" + glob "^13.0.6" graceful-fs "^4.2.11" istanbul-lib-coverage "^3.0.0" istanbul-lib-instrument "^6.0.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^5.0.0" istanbul-reports "^3.1.3" - jest-message-util "30.4.1" - jest-util "30.4.1" - jest-worker "30.4.1" + jest-message-util "30.5.1" + jest-util "30.5.1" + jest-worker "30.5.1" slash "^3.0.0" string-length "^4.0.2" v8-to-istanbul "^9.0.1" -"@jest/schemas@30.0.5": - version "30.0.5" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz" - integrity sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA== - dependencies: - "@sinclair/typebox" "^0.34.0" - -"@jest/schemas@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz" - integrity sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q== - dependencies: - "@sinclair/typebox" "^0.34.0" - "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" @@ -2463,64 +2293,52 @@ dependencies: "@sinclair/typebox" "^0.27.8" -"@jest/snapshot-utils@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz" - integrity sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA== +"@jest/schemas@30.5.0": + version "30.5.0" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz" + integrity sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg== + dependencies: + "@sinclair/typebox" "^0.34.0" + +"@jest/snapshot-utils@30.5.1": + version "30.5.1" + resolved "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.5.1.tgz" + integrity sha512-V3wnxNtiVmw5PPVg433Cn3VdXnsOeu/ofLw3KC04Bn2y1wIlU5kozXQn48rhrgj/02LrCVtntTEF1yBha0XSUw== dependencies: - "@jest/types" "30.4.1" + "@jest/types" "30.5.1" chalk "^4.1.2" graceful-fs "^4.2.11" natural-compare "^1.4.0" -"@jest/source-map@30.0.1": - version "30.0.1" - resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz" - integrity sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg== +"@jest/source-map@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-30.5.2.tgz" + integrity sha512-c5CehvkbfHX6yyNg7bMn2ylqlp9AHXuZ/3hPH/Lh5bxD/vefd/lV9HBjMqXef9yQNqkdwyZvkLSVSwB38hy8Qw== dependencies: - "@jridgewell/trace-mapping" "^0.3.25" + "@jridgewell/trace-mapping" "^0.3.31" callsites "^3.1.0" + convert-source-map "^2.0.0" graceful-fs "^4.2.11" -"@jest/test-result@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz" - integrity sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw== +"@jest/test-result@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-30.5.2.tgz" + integrity sha512-eO6YU5rsLfs60ne694e0IAmRgeBnoA8mu0nlxXDbl/1j5km0o2vO9/VbbUIKIH+WRKKEI+ELgwraRGn2Lhep8g== dependencies: - "@jest/console" "30.4.1" - "@jest/types" "30.4.1" + "@jest/console" "30.5.2" + "@jest/types" "30.5.1" "@types/istanbul-lib-coverage" "^2.0.6" collect-v8-coverage "^1.0.2" -"@jest/test-sequencer@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz" - integrity sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw== - dependencies: - "@jest/test-result" "30.4.1" - graceful-fs "^4.2.11" - jest-haste-map "30.4.1" - slash "^3.0.0" - -"@jest/transform@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz" - integrity sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ== +"@jest/test-sequencer@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.5.2.tgz" + integrity sha512-bmij8jZyYAC47ExT2GeP7PcrlwSNS+Bp3KeRuBH88gpcxqDv6fljN8PemS4J/lLZ79xb6mpaennQTTq0zUAVVg== dependencies: - "@babel/core" "^7.27.4" - "@jest/types" "30.4.1" - "@jridgewell/trace-mapping" "^0.3.25" - babel-plugin-istanbul "^7.0.1" - chalk "^4.1.2" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" + "@jest/test-result" "30.5.2" graceful-fs "^4.2.11" - jest-haste-map "30.4.1" - jest-regex-util "30.4.0" - jest-util "30.4.1" - pirates "^4.0.7" + jest-haste-map "30.5.1" slash "^3.0.0" - write-file-atomic "^5.0.1" "@jest/transform@^29.7.0": version "29.7.0" @@ -2543,31 +2361,25 @@ slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@30.0.5": - version "30.0.5" - resolved "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz" - integrity sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ== - dependencies: - "@jest/pattern" "30.0.1" - "@jest/schemas" "30.0.5" - "@types/istanbul-lib-coverage" "^2.0.6" - "@types/istanbul-reports" "^3.0.4" - "@types/node" "*" - "@types/yargs" "^17.0.33" - chalk "^4.1.2" - -"@jest/types@30.4.1": - version "30.4.1" - resolved "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz" - integrity sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ== +"@jest/transform@30.5.2": + version "30.5.2" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz" + integrity sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ== dependencies: - "@jest/pattern" "30.4.0" - "@jest/schemas" "30.4.1" - "@types/istanbul-lib-coverage" "^2.0.6" - "@types/istanbul-reports" "^3.0.4" - "@types/node" "*" - "@types/yargs" "^17.0.33" + "@babel/core" "^7.27.4" + "@jest/types" "30.5.1" + "@jridgewell/trace-mapping" "^0.3.31" + babel-plugin-istanbul "^8.0.0" chalk "^4.1.2" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.11" + jest-haste-map "30.5.1" + jest-regex-util "30.5.0" + jest-util "30.5.1" + pirates "^4.0.7" + slash "^3.0.0" + write-file-atomic "^5.0.1" "@jest/types@^26.6.2": version "26.6.2" @@ -2592,6 +2404,19 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@30.5.1": + version "30.5.1" + resolved "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz" + integrity sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g== + dependencies: + "@jest/pattern" "30.5.0" + "@jest/schemas" "30.5.0" + "@types/istanbul-lib-coverage" "^2.0.6" + "@types/istanbul-reports" "^3.0.4" + "@types/node" "*" + "@types/yargs" "^17.0.33" + chalk "^4.1.2" + "@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": version "0.3.13" resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz" @@ -2675,7 +2500,7 @@ resolved "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz" integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg== -"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": +"@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0", "@mapbox/point-geometry@0.1.0": version "0.1.0" resolved "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz" integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ== @@ -2754,7 +2579,7 @@ clsx "^2.1.1" prop-types "^15.8.1" -"@mui/material@^7.1.0": +"@mui/material@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/material@^7.1.0", "@mui/material@^7.3.1": version "7.3.1" resolved "https://registry.npmjs.org/@mui/material/-/material-7.3.1.tgz" integrity sha512-Xf6Shbo03YmcBedZMwSpEFOwpYDtU7tC+rhAHTrA9FHk0FpsDqiQ9jUa1j/9s3HLs7KWb5mDcGnlwdh9Q9KAag== @@ -2793,10 +2618,10 @@ csstype "^3.2.3" prop-types "^15.8.1" -"@mui/system@^7.3.1": - version "7.3.1" - resolved "https://registry.npmjs.org/@mui/system/-/system-7.3.1.tgz" - integrity sha512-mIidecvcNVpNJMdPDmCeoSL5zshKBbYPcphjuh6ZMjhybhqhZ4mX6k9zmIWh6XOXcqRQMg5KrcjnO0QstrNj3w== +"@mui/system@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system@^7.3.1": + version "7.3.11" + resolved "https://registry.npmjs.org/@mui/system/-/system-7.3.11.tgz" + integrity sha512-7izwGWdNawAKpBKcRlx7f2gFnAAjmASBWvMcyX4YYEeLOFsbfGRbUYGInvnAcUeql3rPxI7F9Ft4oY2OLRz44g== dependencies: "@babel/runtime" "^7.28.6" "@mui/private-theming" "^7.3.11" @@ -2849,13 +2674,6 @@ reselect "^5.1.1" use-sync-external-store "^1.5.0" -"@napi-rs/wasm-runtime@^1.1.4": - version "1.1.4" - resolved "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz" - integrity sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow== - dependencies: - "@tybys/wasm-util" "^0.10.1" - "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" resolved "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz" @@ -2871,7 +2689,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2902,94 +2720,33 @@ resolved "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz" integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== -"@parcel/watcher-android-arm64@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz" - integrity sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA== - -"@parcel/watcher-darwin-arm64@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz" - integrity sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw== - -"@parcel/watcher-darwin-x64@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz" - integrity sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg== - -"@parcel/watcher-freebsd-x64@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz" - integrity sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ== - -"@parcel/watcher-linux-arm-glibc@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz" - integrity sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA== - -"@parcel/watcher-linux-arm-musl@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz" - integrity sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q== - -"@parcel/watcher-linux-arm64-glibc@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz" - integrity sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w== - -"@parcel/watcher-linux-arm64-musl@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz" - integrity sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg== - -"@parcel/watcher-linux-x64-glibc@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz" - integrity sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A== - -"@parcel/watcher-linux-x64-musl@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz" - integrity sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg== - -"@parcel/watcher-win32-arm64@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz" - integrity sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw== - -"@parcel/watcher-win32-ia32@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz" - integrity sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ== - -"@parcel/watcher-win32-x64@2.5.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz" - integrity sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA== +"@parcel/watcher-darwin-arm64@2.6.0": + version "2.6.0" + resolved "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz" + integrity sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw== -"@parcel/watcher@^2.4.1": - version "2.5.1" - resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz" - integrity sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg== +"@parcel/watcher@^2.4.1", "@parcel/watcher@^2.6.0": + version "2.6.0" + resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz" + integrity sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w== dependencies: - detect-libc "^1.0.3" + detect-libc "^2.0.3" is-glob "^4.0.3" - micromatch "^4.0.5" node-addon-api "^7.0.0" + picomatch "^4.0.4" optionalDependencies: - "@parcel/watcher-android-arm64" "2.5.1" - "@parcel/watcher-darwin-arm64" "2.5.1" - "@parcel/watcher-darwin-x64" "2.5.1" - "@parcel/watcher-freebsd-x64" "2.5.1" - "@parcel/watcher-linux-arm-glibc" "2.5.1" - "@parcel/watcher-linux-arm-musl" "2.5.1" - "@parcel/watcher-linux-arm64-glibc" "2.5.1" - "@parcel/watcher-linux-arm64-musl" "2.5.1" - "@parcel/watcher-linux-x64-glibc" "2.5.1" - "@parcel/watcher-linux-x64-musl" "2.5.1" - "@parcel/watcher-win32-arm64" "2.5.1" - "@parcel/watcher-win32-ia32" "2.5.1" - "@parcel/watcher-win32-x64" "2.5.1" + "@parcel/watcher-android-arm64" "2.6.0" + "@parcel/watcher-darwin-arm64" "2.6.0" + "@parcel/watcher-darwin-x64" "2.6.0" + "@parcel/watcher-freebsd-x64" "2.6.0" + "@parcel/watcher-linux-arm-glibc" "2.6.0" + "@parcel/watcher-linux-arm-musl" "2.6.0" + "@parcel/watcher-linux-arm64-glibc" "2.6.0" + "@parcel/watcher-linux-arm64-musl" "2.6.0" + "@parcel/watcher-linux-x64-glibc" "2.6.0" + "@parcel/watcher-linux-x64-musl" "2.6.0" + "@parcel/watcher-win32-arm64" "2.6.0" + "@parcel/watcher-win32-x64" "2.6.0" "@pkgjs/parseargs@^0.11.0": version "0.11.0" @@ -3079,7 +2836,7 @@ resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz" integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== -"@popperjs/core@^2.11.6", "@popperjs/core@^2.11.8": +"@popperjs/core@^2.0.0", "@popperjs/core@^2.11.6", "@popperjs/core@^2.11.8": version "2.11.8" resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== @@ -3164,7 +2921,7 @@ "@radix-ui/react-use-is-hydrated" "0.1.3" "@radix-ui/react-use-layout-effect" "1.1.4" -"@radix-ui/react-slot@1.3.3", "@radix-ui/react-slot@^1.2.4": +"@radix-ui/react-slot@^1.2.4", "@radix-ui/react-slot@1.3.3": version "1.3.3" resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz" integrity sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q== @@ -3338,105 +3095,10 @@ resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz" integrity sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA== -"@rollup/rollup-android-arm-eabi@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.49.0.tgz" - integrity sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA== - -"@rollup/rollup-android-arm64@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.49.0.tgz" - integrity sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w== - -"@rollup/rollup-darwin-arm64@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.49.0.tgz" - integrity sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw== - -"@rollup/rollup-darwin-x64@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.49.0.tgz" - integrity sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg== - -"@rollup/rollup-freebsd-arm64@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.49.0.tgz" - integrity sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA== - -"@rollup/rollup-freebsd-x64@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.49.0.tgz" - integrity sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w== - -"@rollup/rollup-linux-arm-gnueabihf@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.49.0.tgz" - integrity sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w== - -"@rollup/rollup-linux-arm-musleabihf@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.49.0.tgz" - integrity sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA== - -"@rollup/rollup-linux-arm64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.49.0.tgz" - integrity sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg== - -"@rollup/rollup-linux-arm64-musl@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.49.0.tgz" - integrity sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg== - -"@rollup/rollup-linux-loongarch64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.49.0.tgz" - integrity sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ== - -"@rollup/rollup-linux-ppc64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.49.0.tgz" - integrity sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g== - -"@rollup/rollup-linux-riscv64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.49.0.tgz" - integrity sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw== - -"@rollup/rollup-linux-riscv64-musl@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.49.0.tgz" - integrity sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw== - -"@rollup/rollup-linux-s390x-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.49.0.tgz" - integrity sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A== - -"@rollup/rollup-linux-x64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.49.0.tgz" - integrity sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA== - -"@rollup/rollup-linux-x64-musl@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.49.0.tgz" - integrity sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg== - -"@rollup/rollup-win32-arm64-msvc@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.49.0.tgz" - integrity sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA== - -"@rollup/rollup-win32-ia32-msvc@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.49.0.tgz" - integrity sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA== - -"@rollup/rollup-win32-x64-msvc@4.49.0": - version "4.49.0" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.49.0.tgz" - integrity sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg== +"@rollup/rollup-darwin-arm64@4.66.0": + version "4.66.0" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.66.0.tgz" + integrity sha512-6vkDCfyDjNLokh+Rt1D2KtNgFFMEPdkWha/mbtP4cSjh9xiN8T/JBS/A7nDYKjmMAXHrvR9J3AzUk2LtFbIBLg== "@rtsao/scc@^1.1.0": version "1.1.0" @@ -3495,9 +3157,9 @@ integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@sinclair/typebox@^0.34.0": - version "0.34.49" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz" - integrity sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A== + version "0.34.52" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz" + integrity sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw== "@sinonjs/commons@^3.0.0", "@sinonjs/commons@^3.0.1": version "3.0.1" @@ -3543,7 +3205,7 @@ "@tanstack/query-core" "4.41.0" use-sync-external-store "^1.2.0" -"@testing-library/dom@^10.4.0": +"@testing-library/dom@^10.4.0", "@testing-library/dom@>=7.21.4": version "10.4.1" resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz" integrity sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg== @@ -3665,13 +3327,6 @@ "@types/geojson" "^7946.0.10" tslib "^2.8.1" -"@tybys/wasm-util@^0.10.1": - version "0.10.2" - resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz" - integrity sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg== - dependencies: - tslib "^2.4.0" - "@types/aria-query@^4.2.0": version "4.2.2" resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz" @@ -3838,10 +3493,10 @@ resolved "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz" integrity sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== -"@types/estree@1.0.8", "@types/estree@^1.0.0", "@types/estree@^1.0.8": - version "1.0.8" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" - integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== +"@types/estree@^1.0.0", "@types/estree@^1.0.8", "@types/estree@1.0.9": + version "1.0.9" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz" + integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg== "@types/geojson-vt@3.2.5": version "3.2.5" @@ -3947,7 +3602,7 @@ "@types/mapbox__point-geometry" "*" "@types/pbf" "*" -"@types/node@*": +"@types/node@*", "@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@>=18": version "24.3.0" resolved "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz" integrity sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow== @@ -4035,10 +3690,10 @@ resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== -"@types/react@*", "@types/react@>=16.14.8", "@types/react@>=16.9.11": - version "19.1.12" - resolved "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz" - integrity sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w== +"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^18.2.25 || ^19", "@types/react@>=16.14.8", "@types/react@>=16.9.11": + version "19.3.0" + resolved "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz" + integrity sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg== dependencies: csstype "^3.2.2" @@ -4097,9 +3752,9 @@ integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^15.0.0": - version "15.0.19" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz" - integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== + version "15.0.20" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.20.tgz" + integrity sha512-KIkX+/GgfFitlASYCGoSF+T4XRXhOubJLhkLVtSfsRTe9jWMmuM2g28zQ41BtPTG7TRBb2xHW+LCNVE9QR/vsg== dependencies: "@types/yargs-parser" "*" @@ -4119,6 +3774,14 @@ "@typescript-eslint/types" "^8.60.0" debug "^4.4.3" +"@typescript-eslint/scope-manager@^8.15.0": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.1.tgz" + integrity sha512-lC/t6eMCZZQAAKZEYGL6RDVSuFehpdmMT6h+nJIjIa6oylN/PwDgDVtEIbB7O9xFfZYtZAYLoLlDNWKJhtF+uQ== + dependencies: + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" + "@typescript-eslint/scope-manager@7.18.0": version "7.18.0" resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz" @@ -4127,7 +3790,7 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/visitor-keys" "7.18.0" -"@typescript-eslint/scope-manager@8.60.0", "@typescript-eslint/scope-manager@^8.15.0": +"@typescript-eslint/scope-manager@8.60.0": version "8.60.0" resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.0.tgz" integrity sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw== @@ -4135,17 +3798,22 @@ "@typescript-eslint/types" "8.60.0" "@typescript-eslint/visitor-keys" "8.60.0" -"@typescript-eslint/tsconfig-utils@8.60.0", "@typescript-eslint/tsconfig-utils@^8.60.0": +"@typescript-eslint/tsconfig-utils@^8.60.0", "@typescript-eslint/tsconfig-utils@8.60.0": version "8.60.0" resolved "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.0.tgz" integrity sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ== +"@typescript-eslint/types@^8.60.0", "@typescript-eslint/types@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.1.tgz" + integrity sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw== + "@typescript-eslint/types@7.18.0": version "7.18.0" resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz" integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== -"@typescript-eslint/types@8.60.0", "@typescript-eslint/types@^8.60.0": +"@typescript-eslint/types@8.60.0": version "8.60.0" resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.0.tgz" integrity sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA== @@ -4215,125 +3883,24 @@ "@typescript-eslint/types" "8.60.0" eslint-visitor-keys "^5.0.0" +"@typescript-eslint/visitor-keys@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.1.tgz" + integrity sha512-SB8xqipSzZHUePCCLNeYxqnxq83X61/qzNhjQGbTfjxGZIeOEP7tBgWYX05Tcd6CgE02WdTJnh5b8kMZJ/+bnQ== + dependencies: + "@typescript-eslint/types" "8.72.1" + eslint-visitor-keys "^5.0.0" + "@ungap/structured-clone@^1.2.0", "@ungap/structured-clone@^1.3.0": version "1.3.0" resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== -"@unrs/resolver-binding-android-arm-eabi@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz" - integrity sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w== - -"@unrs/resolver-binding-android-arm64@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz" - integrity sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ== - "@unrs/resolver-binding-darwin-arm64@1.12.2": version "1.12.2" resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz" integrity sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w== -"@unrs/resolver-binding-darwin-x64@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz" - integrity sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA== - -"@unrs/resolver-binding-freebsd-x64@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz" - integrity sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg== - -"@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz" - integrity sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A== - -"@unrs/resolver-binding-linux-arm-musleabihf@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz" - integrity sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g== - -"@unrs/resolver-binding-linux-arm64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz" - integrity sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg== - -"@unrs/resolver-binding-linux-arm64-musl@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz" - integrity sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA== - -"@unrs/resolver-binding-linux-loong64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz" - integrity sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q== - -"@unrs/resolver-binding-linux-loong64-musl@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz" - integrity sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew== - -"@unrs/resolver-binding-linux-ppc64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz" - integrity sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg== - -"@unrs/resolver-binding-linux-riscv64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz" - integrity sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A== - -"@unrs/resolver-binding-linux-riscv64-musl@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz" - integrity sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w== - -"@unrs/resolver-binding-linux-s390x-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz" - integrity sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw== - -"@unrs/resolver-binding-linux-x64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz" - integrity sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ== - -"@unrs/resolver-binding-linux-x64-musl@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz" - integrity sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A== - -"@unrs/resolver-binding-openharmony-arm64@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz" - integrity sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ== - -"@unrs/resolver-binding-wasm32-wasi@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz" - integrity sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A== - dependencies: - "@emnapi/core" "1.10.0" - "@emnapi/runtime" "1.10.0" - "@napi-rs/wasm-runtime" "^1.1.4" - -"@unrs/resolver-binding-win32-arm64-msvc@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz" - integrity sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g== - -"@unrs/resolver-binding-win32-ia32-msvc@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz" - integrity sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g== - -"@unrs/resolver-binding-win32-x64-msvc@1.12.2": - version "1.12.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz" - integrity sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA== - "@vitejs/plugin-react@^4.5.0": version "4.7.0" resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz" @@ -4347,9 +3914,9 @@ react-refresh "^0.17.0" "@vitest/coverage-v8@^3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz" - integrity sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ== + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.7.tgz" + integrity sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg== dependencies: "@ampproject/remapping" "^2.3.0" "@bcoe/v8-coverage" "^1.0.2" @@ -4365,64 +3932,64 @@ test-exclude "^7.0.1" tinyrainbow "^2.0.0" -"@vitest/expect@3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz" - integrity sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig== +"@vitest/expect@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz" + integrity sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w== dependencies: "@types/chai" "^5.2.2" - "@vitest/spy" "3.2.4" - "@vitest/utils" "3.2.4" + "@vitest/spy" "3.2.7" + "@vitest/utils" "3.2.7" chai "^5.2.0" tinyrainbow "^2.0.0" -"@vitest/mocker@3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz" - integrity sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ== +"@vitest/mocker@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz" + integrity sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA== dependencies: - "@vitest/spy" "3.2.4" + "@vitest/spy" "3.2.7" estree-walker "^3.0.3" magic-string "^0.30.17" -"@vitest/pretty-format@3.2.4", "@vitest/pretty-format@^3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz" - integrity sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA== +"@vitest/pretty-format@^3.2.7", "@vitest/pretty-format@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz" + integrity sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA== dependencies: tinyrainbow "^2.0.0" -"@vitest/runner@3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz" - integrity sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ== +"@vitest/runner@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz" + integrity sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA== dependencies: - "@vitest/utils" "3.2.4" + "@vitest/utils" "3.2.7" pathe "^2.0.3" strip-literal "^3.0.0" -"@vitest/snapshot@3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz" - integrity sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ== +"@vitest/snapshot@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz" + integrity sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g== dependencies: - "@vitest/pretty-format" "3.2.4" + "@vitest/pretty-format" "3.2.7" magic-string "^0.30.17" pathe "^2.0.3" -"@vitest/spy@3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz" - integrity sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw== +"@vitest/spy@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz" + integrity sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ== dependencies: tinyspy "^4.0.3" -"@vitest/ui@^3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.4.tgz" - integrity sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA== +"@vitest/ui@^3.2.4", "@vitest/ui@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.7.tgz" + integrity sha512-eVtcpJXGhS0GjMuHROfbXLhlxooyUcuip8GNzzjDD5jzafZqzanJH4W3VGmUxHNx4fv6qQGUGJHRpGUdj+9D6Q== dependencies: - "@vitest/utils" "3.2.4" + "@vitest/utils" "3.2.7" fflate "^0.8.2" flatted "^3.3.3" pathe "^2.0.3" @@ -4430,16 +3997,16 @@ tinyglobby "^0.2.14" tinyrainbow "^2.0.0" -"@vitest/utils@3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz" - integrity sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA== +"@vitest/utils@3.2.7": + version "3.2.7" + resolved "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz" + integrity sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw== dependencies: - "@vitest/pretty-format" "3.2.4" + "@vitest/pretty-format" "3.2.7" loupe "^3.1.4" tinyrainbow "^2.0.0" -"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": +"@webassemblyjs/ast@^1.14.1", "@webassemblyjs/ast@1.14.1": version "1.14.1" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz" integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== @@ -4540,7 +4107,7 @@ "@webassemblyjs/wasm-gen" "1.14.1" "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": +"@webassemblyjs/wasm-parser@^1.14.1", "@webassemblyjs/wasm-parser@1.14.1": version "1.14.1" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz" integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== @@ -4566,9 +4133,9 @@ integrity sha512-+i7+JmNiE/3c9FKxzWFi2IjRJ+KzZl1QPu6QNrsgaa2MuBgXvUy4gA1TVzf/JMdIIloB76xSKikTWuyYAIVLww== "@xmldom/xmldom@^0.8.2": - version "0.8.11" - resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz" - integrity sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw== + version "0.8.15" + resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.15.tgz" + integrity sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -4595,21 +4162,31 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.14.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.9.0: + version "8.19.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz" + integrity sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw== + acorn@^7.1.1: version "7.4.1" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.15.0, acorn@^8.16.0, acorn@^8.9.0: - version "8.16.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz" - integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== - adler-32@~1.3.0: version "1.3.1" resolved "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz" integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A== +agent-base@^7.1.0: + version "7.1.4" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + +agent-base@^7.1.2: + version "7.1.4" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -4617,11 +4194,6 @@ agent-base@6: dependencies: debug "4" -agent-base@^7.1.0, agent-base@^7.1.2: - version "7.1.4" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz" - integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" @@ -4637,16 +4209,16 @@ ajv-keywords@^5.1.0: fast-deep-equal "^3.1.3" ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + version "6.15.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz" + integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.0.1, ajv@^8.18.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.0.1, ajv@^8.18.0, ajv@^8.8.2, ajv@^8.9.0: version "8.20.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz" integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA== @@ -4665,7 +4237,7 @@ ansi-escapes@^4.3.2: ansi-escapes@^7.0.0: version "7.3.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-7.3.0.tgz#5395bb74b2150a4a1d6e3c2565f4aeca78d28627" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz" integrity sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg== dependencies: environment "^1.0.0" @@ -4675,7 +4247,12 @@ ansi-regex@^5.0.0, ansi-regex@^5.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1, ansi-regex@^6.2.2: +ansi-regex@^6.0.1: + version "6.2.2" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== + +ansi-regex@^6.2.2: version "6.2.2" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz" integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== @@ -4694,12 +4271,22 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^5.0.0, ansi-styles@^5.2.0: +ansi-styles@^5.0.0: version "5.2.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0, ansi-styles@^6.2.1: +ansi-styles@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +ansi-styles@^6.1.0: + version "6.2.3" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz" + integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== + +ansi-styles@^6.2.1: version "6.2.3" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz" integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== @@ -4784,13 +4371,6 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@5.3.0, aria-query@^5.0.0: - version "5.3.0" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - aria-query@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz" @@ -4799,6 +4379,13 @@ aria-query@^4.2.2: "@babel/runtime" "^7.10.2" "@babel/runtime-corejs3" "^7.10.2" +aria-query@^5.0.0, aria-query@5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + aria-query@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz" @@ -5001,10 +4588,10 @@ axios-mock-adapter@^1.22.0: fast-deep-equal "^3.1.3" is-buffer "^2.0.5" -axios@^1.18.0: - version "1.20.0" - resolved "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz" - integrity sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg== +axios@^1.18.0, "axios@>= 0.17.0": + version "1.21.0" + resolved "https://registry.npmjs.org/axios/-/axios-1.21.0.tgz" + integrity sha512-YCzXMB53Q9PZBsh7yN7wtapit4WepwcHS2fP8QhGsBxSz5YtgYobV7GGlWlAJi+RxfU77GQTQi2DSLUma42EYA== dependencies: follow-redirects "^1.16.0" form-data "^4.0.6" @@ -5016,19 +4603,6 @@ axobject-query@^4.1.0: resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz" integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== -babel-jest@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz" - integrity sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw== - dependencies: - "@jest/transform" "30.4.1" - "@types/babel__core" "^7.20.5" - babel-plugin-istanbul "^7.0.1" - babel-preset-jest "30.4.0" - chalk "^4.1.2" - graceful-fs "^4.2.11" - slash "^3.0.0" - babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" @@ -5042,6 +4616,19 @@ babel-jest@^29.7.0: graceful-fs "^4.2.9" slash "^3.0.0" +babel-jest@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-30.5.2.tgz" + integrity sha512-ES8WeJ2fNWPEDunyAtUfJ12nHyaWUloCHdkfK2oW5uSoQSUmjNKdWiGaXJITJwvFEWoD/evHEg/QoCXAvLaQqQ== + dependencies: + "@jest/transform" "30.5.2" + "@types/babel__core" "^7.20.5" + babel-plugin-istanbul "^8.0.0" + babel-preset-jest "30.5.0" + chalk "^4.1.2" + graceful-fs "^4.2.11" + slash "^3.0.0" + babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" @@ -5053,23 +4640,16 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-istanbul@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz" - integrity sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA== +babel-plugin-istanbul@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz" + integrity sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/schema" "^0.1.3" istanbul-lib-instrument "^6.0.2" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@30.4.0: - version "30.4.0" - resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz" - integrity sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA== - dependencies: - "@types/babel__core" "^7.20.5" + test-exclude "^7.0.1" babel-plugin-jest-hoist@^29.6.3: version "29.6.3" @@ -5081,6 +4661,13 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@30.5.0: + version "30.5.0" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.5.0.tgz" + integrity sha512-gtGo1B+u14jrZQv6TdSWIWkTqclboo7Qn+dFAGUOIuXLFuJKAdg3U5MIWzZnW4vfUb4dX9skmAMiby86e/SF4A== + dependencies: + "@types/babel__core" "^7.20.5" + babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz" @@ -5135,14 +4722,6 @@ babel-preset-current-node-syntax@^1.0.0, babel-preset-current-node-syntax@^1.2.0 "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" -babel-preset-jest@30.4.0: - version "30.4.0" - resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz" - integrity sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg== - dependencies: - babel-plugin-jest-hoist "30.4.0" - babel-preset-current-node-syntax "^1.2.0" - babel-preset-jest@^29.6.3: version "29.6.3" resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" @@ -5151,6 +4730,14 @@ babel-preset-jest@^29.6.3: babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@30.5.0: + version "30.5.0" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.5.0.tgz" + integrity sha512-ZGPn5ClP4lBDpuOK8W1yQIOy359HmbnZv3suucAlIe+SEE9yDsxV4S2PjSbH2Vc97U+WmzYD7vw3kr8NsQ/i6w== + dependencies: + babel-plugin-jest-hoist "30.5.0" + babel-preset-current-node-syntax "^1.2.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -5171,20 +4758,20 @@ base64-arraybuffer@^1.0.2: resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz" integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ== -base64-js@1.3.1: - version "1.3.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -baseline-browser-mapping@^2.11.23: - version "2.11.25" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.25.tgz#88b942ce372bdf2d6a2652136bbf7826c65c77be" - integrity sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw== +base64-js@1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +baseline-browser-mapping@^2.11.33: + version "2.11.34" + resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.34.tgz" + integrity sha512-Aqr8mA1kIvyJ3UY5YAY7ib8LSo1DmDMbMnVqGPtsKW1LxaFQFwn9Eb3yvq2fUKJsRvaXjnAV7R5osqETapzNiA== binary-search-bounds@^2.0.4: version "2.0.5" @@ -5214,15 +4801,25 @@ bluebird@~3.7.2: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: - version "4.12.2" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz" - integrity sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw== +bn.js@^4.0.0: + version "4.12.5" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz" + integrity sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ== -bn.js@^5.2.1: - version "5.2.2" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz" - integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== +bn.js@^4.1.0: + version "4.12.5" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz" + integrity sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ== + +bn.js@^4.11.9: + version "4.12.5" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz" + integrity sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ== + +bn.js@^5.2.1, bn.js@^5.2.3: + version "5.2.5" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.5.tgz" + integrity sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg== boolbase@^1.0.0: version "1.0.0" @@ -5235,24 +4832,31 @@ bootstrap@^4.5.3: integrity sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ== brace-expansion@^1.1.7: - version "1.1.12" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz" - integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + version "1.1.21" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz" + integrity sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" brace-expansion@^2.0.2: - version "2.1.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz" - integrity sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA== + version "2.1.7" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz" + integrity sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g== dependencies: balanced-match "^1.0.0" brace-expansion@^5.0.5: - version "5.0.6" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz" - integrity sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g== + version "5.0.12" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz" + integrity sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ== + dependencies: + balanced-match "^4.0.2" + +brace-expansion@^5.0.8: + version "5.0.12" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz" + integrity sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ== dependencies: balanced-match "^4.0.2" @@ -5306,7 +4910,7 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: +browserify-rsa@^4.0.0, browserify-rsa@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz" integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ== @@ -5316,31 +4920,30 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: safe-buffer "^5.2.1" browserify-sign@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz" - integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw== + version "4.2.6" + resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.6.tgz" + integrity sha512-sd+Q65fjlWCYWtZKXiKfrUc8d+4jtp/8f0W2NkwzLtoW4bI6UDnWusLWIurHnmurW0XShIRxpwiOX4EoPtXUAg== dependencies: - bn.js "^5.2.1" - browserify-rsa "^4.1.0" + bn.js "^5.2.3" + browserify-rsa "^4.1.1" create-hash "^1.2.0" create-hmac "^1.1.7" - elliptic "^6.5.5" - hash-base "~3.0" + elliptic "^6.6.1" inherits "^2.0.4" - parse-asn1 "^5.1.7" + parse-asn1 "^5.1.9" readable-stream "^2.3.8" safe-buffer "^5.2.1" -browserslist@^4.24.0, browserslist@^4.25.3, browserslist@^4.28.1: - version "4.29.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.29.0.tgz#e50e72c30c4b5f7ec894c09feb6ed525167f5344" - integrity sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA== +browserslist@^4.24.0, browserslist@^4.25.3, browserslist@^4.28.1, "browserslist@>= 4.21.0": + version "4.29.5" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.29.5.tgz" + integrity sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ== dependencies: - baseline-browser-mapping "^2.11.23" - caniuse-lite "^1.0.30001810" - electron-to-chromium "^1.5.427" - node-releases "^2.0.55" - update-browserslist-db "^1.3.3" + baseline-browser-mapping "^2.11.33" + caniuse-lite "^1.0.30001819" + electron-to-chromium "^1.5.464" + node-releases "^2.0.60" + update-browserslist-db "^1.3.4" bser@2.1.1: version "2.1.1" @@ -5439,10 +5042,10 @@ camelize@^1.0.0: resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz" integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== -caniuse-lite@^1.0.30001810: - version "1.0.30001810" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz#4970b477dea3278374de9bc43aa8f5d39fc3cda2" - integrity sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg== +caniuse-lite@^1.0.30001819: + version "1.0.30001820" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001820.tgz" + integrity sha512-gfWD6MxqVCqAOwmODfZf7DchWvlrA+SRdNX7ceLfg3xRqe5ssjjpF7EgslC/0tiLiNTajdaNN/q8c/5u/7Gz8w== canvas-confetti@^1.9.3: version "1.9.3" @@ -5512,7 +5115,7 @@ char-regex@^1.0.2: resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chart.js@^4.5.0: +chart.js@^4.1.1, chart.js@^4.5.0, chart.js@>=3.0.0: version "4.5.0" resolved "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz" integrity sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ== @@ -5588,10 +5191,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.4" safe-buffer "^5.2.1" -cjs-module-lexer@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz" - integrity sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ== +cjs-module-lexer@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.3.0.tgz" + integrity sha512-lmNyBzi6iYiqyrExTctfmjd8tInx+dHu9PBomTfH5RXS53c27JMFJgzNv5TyAnm3PgGf+MLy0+Ws41/HlVxdKQ== clamp@^1.0.1: version "1.0.1" @@ -5605,7 +5208,7 @@ class-variance-authority@^0.7.1: dependencies: clsx "^2.1.1" -classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1, classnames@^2.3.2, classnames@^2.5.1: +classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1, classnames@^2.3.2, classnames@^2.5.1, classnames@2.x: version "2.5.1" resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== @@ -5692,11 +5295,6 @@ color-id@^1.1.0: dependencies: clamp "^1.0.1" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" @@ -5707,7 +5305,12 @@ color-name@^2.0.0: resolved "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz" integrity sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg== -color-normalize@1.5.0, color-normalize@^1.5.0: +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-normalize@^1.5.0, color-normalize@1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/color-normalize/-/color-normalize-1.5.0.tgz" integrity sha512-rUT/HDXMr6RFffrR53oX3HGWkDOP9goSAQGBkUaAYKjOE2JxozccdGyufageWDlInRAjm/jYPrf/Y38oa+7obw== @@ -5716,7 +5319,14 @@ color-normalize@1.5.0, color-normalize@^1.5.0: color-rgba "^2.1.1" dtype "^2.0.0" -color-parse@^1.4.1, color-parse@^1.4.2: +color-parse@^1.4.1: + version "1.4.3" + resolved "https://registry.npmjs.org/color-parse/-/color-parse-1.4.3.tgz" + integrity sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A== + dependencies: + color-name "^1.0.0" + +color-parse@^1.4.2: version "1.4.3" resolved "https://registry.npmjs.org/color-parse/-/color-parse-1.4.3.tgz" integrity sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A== @@ -5730,14 +5340,6 @@ color-parse@^2.0.0: dependencies: color-name "^2.0.0" -color-rgba@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/color-rgba/-/color-rgba-3.0.0.tgz" - integrity sha512-PPwZYkEY3M2THEHHV6Y95sGUie77S7X8v+h1r6LSAPF3/LL2xJ8duUXSrkic31Nzc4odPwHgUbiX/XuTYzQHQg== - dependencies: - color-parse "^2.0.0" - color-space "^2.0.0" - color-rgba@^2.1.1: version "2.4.0" resolved "https://registry.npmjs.org/color-rgba/-/color-rgba-2.4.0.tgz" @@ -5746,6 +5348,14 @@ color-rgba@^2.1.1: color-parse "^1.4.2" color-space "^2.0.0" +color-rgba@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/color-rgba/-/color-rgba-3.0.0.tgz" + integrity sha512-PPwZYkEY3M2THEHHV6Y95sGUie77S7X8v+h1r6LSAPF3/LL2xJ8duUXSrkic31Nzc4odPwHgUbiX/XuTYzQHQg== + dependencies: + color-parse "^2.0.0" + color-space "^2.0.0" + color-space@^2.0.0: version "2.3.2" resolved "https://registry.npmjs.org/color-space/-/color-space-2.3.2.tgz" @@ -5760,9 +5370,9 @@ color-string@^1.5.5: simple-swizzle "^0.2.2" colord@^2.9.3: - version "2.9.3" - resolved "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz" - integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + version "2.10.0" + resolved "https://registry.npmjs.org/colord/-/colord-2.10.0.tgz" + integrity sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw== colorette@^2.0.20: version "2.0.20" @@ -5781,7 +5391,22 @@ comlink@^4.4.1: resolved "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz" integrity sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g== -commander@2, commander@^2.15.1, commander@^2.20.0: +commander@^14.0.1: + version "14.0.1" + resolved "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz" + integrity sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A== + +commander@^2.15.1: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@2: version "2.20.3" resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -5791,11 +5416,6 @@ commander@7: resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commander@^14.0.1: - version "14.0.1" - resolved "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz" - integrity sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A== - compute-scroll-into-view@^3.0.2: version "3.1.1" resolved "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz" @@ -5910,16 +5530,6 @@ create-hash@^1.1.0, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hash@~1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz" - integrity sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - ripemd160 "^2.0.0" - sha.js "^2.4.0" - create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" @@ -6107,23 +5717,24 @@ cssstyle@^4.2.1: "@asamuzakjp/css-color" "^3.2.0" rrweb-cssom "^0.8.0" -csstype@3.2.3, csstype@^3.0.2, csstype@^3.0.8, csstype@^3.1.3: +csstype@^3.0.2, csstype@^3.0.8, csstype@^3.1.3, csstype@^3.2.2, csstype@^3.2.3, csstype@3.2.3: version "3.2.3" resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== -d3-array@1, d3-array@^1.2.1: +d@^1.0.1, d@^1.0.2, d@1: + version "1.0.2" + resolved "https://registry.npmjs.org/d/-/d-1.0.2.tgz" + integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== + dependencies: + es5-ext "^0.10.64" + type "^2.7.2" + +d3-array@^1.2.1: version "1.2.4" resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz" integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== -"d3-array@1 - 3", "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.1.6, d3-array@^3.2.0, d3-array@^3.2.4: - version "3.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - d3-array@^2.5.0: version "2.12.1" resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" @@ -6131,6 +5742,18 @@ d3-array@^2.5.0: dependencies: internmap "^1.0.0" +d3-array@^3.1.6, d3-array@^3.2.0, d3-array@^3.2.4, "d3-array@1 - 3", "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3: + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +d3-array@1: + version "1.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + d3-axis@3: version "3.0.0" resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" @@ -6159,21 +5782,21 @@ d3-chord@3: dependencies: d3-path "1 - 3" -d3-collection@1, d3-collection@^1.0.4: +d3-collection@^1.0.4, d3-collection@1: version "1.0.7" resolved "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz" integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== +d3-color@^3.1.0, "d3-color@1 - 3", d3-color@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + "d3-color@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz" integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== -"d3-color@1 - 3", d3-color@3, d3-color@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" - integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== - d3-contour@4: version "4.0.2" resolved "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz" @@ -6188,28 +5811,20 @@ d3-delaunay@6: dependencies: delaunator "5" -d3-dispatch@1: - version "1.0.6" - resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz" - integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== +d3-dispatch@^3.0.1, "d3-dispatch@1 - 3", d3-dispatch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== "d3-dispatch@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz" integrity sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA== -"d3-dispatch@1 - 3", d3-dispatch@3, d3-dispatch@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" - integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== - -d3-drag@2: - version "2.0.0" - resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz" - integrity sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w== - dependencies: - d3-dispatch "1 - 2" - d3-selection "2" +d3-dispatch@1: + version "1.0.6" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz" + integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== "d3-drag@2 - 3", d3-drag@3: version "3.0.0" @@ -6219,7 +5834,15 @@ d3-drag@2: d3-dispatch "1 - 3" d3-selection "3" -"d3-dsv@1 - 3", d3-dsv@3, d3-dsv@^3.0.1: +d3-drag@2: + version "2.0.0" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz" + integrity sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w== + dependencies: + d3-dispatch "1 - 2" + d3-selection "2" + +d3-dsv@^3.0.1, "d3-dsv@1 - 3", d3-dsv@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz" integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== @@ -6228,17 +5851,17 @@ d3-drag@2: iconv-lite "0.6" rw "1" +d3-ease@^3.0.1, "d3-ease@1 - 3", d3-ease@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + "d3-ease@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz" integrity sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ== -"d3-ease@1 - 3", d3-ease@3, d3-ease@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" - integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== - -d3-fetch@3, d3-fetch@^3.0.1: +d3-fetch@^3.0.1, d3-fetch@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz" integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== @@ -6256,15 +5879,6 @@ d3-force-3d@^3.0.5: d3-quadtree "1 - 3" d3-timer "1 - 3" -d3-force@3, d3-force@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" - integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== - dependencies: - d3-dispatch "1 - 3" - d3-quadtree "1 - 3" - d3-timer "1 - 3" - d3-force@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz" @@ -6275,16 +5889,25 @@ d3-force@^1.2.1: d3-quadtree "1" d3-timer "1" -"d3-format@1 - 3", d3-format@3, d3-format@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" - integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== +d3-force@^3.0.0, d3-force@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" + integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== + dependencies: + d3-dispatch "1 - 3" + d3-quadtree "1 - 3" + d3-timer "1 - 3" d3-format@^1.4.5: version "1.4.5" resolved "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz" integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== +d3-format@^3.1.0, "d3-format@1 - 3", d3-format@3: + version "3.1.2" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz" + integrity sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg== + d3-geo-projection@^2.9.0: version "2.9.0" resolved "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-2.9.0.tgz" @@ -6304,13 +5927,6 @@ d3-geo-projection@^4.0.0: d3-array "1 - 3" d3-geo "1.12.0 - 3" -"d3-geo@1.12.0 - 3", d3-geo@3, d3-geo@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz" - integrity sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q== - dependencies: - d3-array "2.5.0 - 3" - d3-geo@^1.12.0, d3-geo@^1.12.1: version "1.12.1" resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz" @@ -6325,61 +5941,68 @@ d3-geo@^2.0.2: dependencies: d3-array "^2.5.0" -d3-hierarchy@3, d3-hierarchy@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" - integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== +d3-geo@^3.1.1, "d3-geo@1.12.0 - 3", d3-geo@3: + version "3.1.1" + resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz" + integrity sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q== + dependencies: + d3-array "2.5.0 - 3" d3-hierarchy@^1.1.9: version "1.1.9" resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz" integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== -"d3-interpolate@1 - 2": - version "2.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz" - integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== - dependencies: - d3-color "1 - 2" +d3-hierarchy@^3.1.2, d3-hierarchy@3: + version "3.1.2" + resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" + integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== -"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3, d3-interpolate@^3.0.1: +d3-interpolate@^3.0.1, "d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== dependencies: d3-color "1 - 3" -d3-octree@1, d3-octree@^1.0.2: +"d3-interpolate@1 - 2": + version "2.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== + dependencies: + d3-color "1 - 2" + +d3-octree@^1.0.2, d3-octree@1: version "1.1.0" resolved "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz" integrity sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A== +d3-path@^3.1.0, "d3-path@1 - 3", d3-path@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + d3-path@1: version "1.0.9" resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== -"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - d3-polygon@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== +d3-quadtree@^3.0.1, "d3-quadtree@1 - 3", d3-quadtree@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + d3-quadtree@1: version "1.0.7" resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz" integrity sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA== -"d3-quadtree@1 - 3", d3-quadtree@3, d3-quadtree@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" - integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== - -d3-random@3, d3-random@^3.0.1: +d3-random@^3.0.1, d3-random@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz" integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== @@ -6389,7 +6012,7 @@ d3-regression@^1.3.10: resolved "https://registry.npmjs.org/d3-regression/-/d3-regression-1.3.10.tgz" integrity sha512-PF8GWEL70cHHWpx2jUQXc68r1pyPHIA+St16muk/XRokETzlegj5LriNKg7o4LR0TySug4nHYPJNNRz/W+/Niw== -d3-scale-chromatic@3, d3-scale-chromatic@^3.1.0: +d3-scale-chromatic@^3.1.0, d3-scale-chromatic@3: version "3.1.0" resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz" integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== @@ -6397,7 +6020,7 @@ d3-scale-chromatic@3, d3-scale-chromatic@^3.1.0: d3-color "1 - 3" d3-interpolate "1 - 3" -d3-scale@4, d3-scale@^4.0.2: +d3-scale@^4.0.2, d3-scale@4: version "4.0.2" resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== @@ -6408,7 +6031,7 @@ d3-scale@4, d3-scale@^4.0.2: d3-time "2.1.1 - 3" d3-time-format "2 - 4" -d3-selection@2, d3-selection@^2.0.0: +d3-selection@^2.0.0, d3-selection@2: version "2.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz" integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA== @@ -6418,13 +6041,6 @@ d3-selection@2, d3-selection@^2.0.0: resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== -d3-shape@3, d3-shape@^3.1.0, d3-shape@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" - integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== - dependencies: - d3-path "^3.1.0" - d3-shape@^1.2.0: version "1.3.7" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" @@ -6432,12 +6048,12 @@ d3-shape@^1.2.0: dependencies: d3-path "1" -"d3-time-format@2 - 4", d3-time-format@4: - version "4.1.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" - integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== +d3-shape@^3.1.0, d3-shape@^3.2.0, d3-shape@3: + version "3.2.0" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== dependencies: - d3-time "1 - 3" + d3-path "^3.1.0" d3-time-format@^2.2.3: version "2.3.0" @@ -6446,32 +6062,50 @@ d3-time-format@^2.2.3: dependencies: d3-time "1" -d3-time@1, d3-time@^1.1.0: +"d3-time-format@2 - 4", d3-time-format@4: + version "4.1.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +d3-time@^1.1.0, d3-time@1: version "1.1.0" resolved "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz" integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== -"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3, d3-time@^3.0.0, d3-time@^3.1.0: +d3-time@^3.0.0, d3-time@^3.1.0, "d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: version "3.1.0" resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== dependencies: d3-array "2 - 3" -d3-timer@1: - version "1.0.10" - resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz" - integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== +d3-timer@^3.0.1, "d3-timer@1 - 3", d3-timer@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== "d3-timer@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz" integrity sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA== -"d3-timer@1 - 3", d3-timer@3, d3-timer@^3.0.1: +d3-timer@1: + version "1.0.10" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz" + integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== + +"d3-transition@2 - 3", d3-transition@3: version "3.0.1" - resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" - integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" d3-transition@2: version "2.0.0" @@ -6484,16 +6118,16 @@ d3-transition@2: d3-interpolate "1 - 2" d3-timer "1 - 2" -"d3-transition@2 - 3", d3-transition@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" - integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== +d3-zoom@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz" + integrity sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw== dependencies: - d3-color "1 - 3" - d3-dispatch "1 - 3" - d3-ease "1 - 3" - d3-interpolate "1 - 3" - d3-timer "1 - 3" + d3-dispatch "1 - 2" + d3-drag "2" + d3-interpolate "1 - 2" + d3-selection "2" + d3-transition "2" d3-zoom@3: version "3.0.0" @@ -6506,17 +6140,6 @@ d3-zoom@3: d3-selection "2 - 3" d3-transition "2 - 3" -d3-zoom@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz" - integrity sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw== - dependencies: - d3-dispatch "1 - 2" - d3-drag "2" - d3-interpolate "1 - 2" - d3-selection "2" - d3-transition "2" - d3@^7.8.5: version "7.9.0" resolved "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz" @@ -6547,19 +6170,11 @@ d3@^7.8.5: d3-scale-chromatic "3" d3-selection "3" d3-shape "3" - d3-time "3" - d3-time-format "4" - d3-timer "3" - d3-transition "3" - d3-zoom "3" - -d@1, d@^1.0.1, d@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/d/-/d-1.0.2.tgz" - integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== - dependencies: - es5-ext "^0.10.64" - type "^2.7.2" + d3-time "3" + d3-time-format "4" + d3-timer "3" + d3-transition "3" + d3-zoom "3" dagre@^0.8.5: version "0.8.5" @@ -6614,7 +6229,7 @@ date-fns-tz@^2.0.1: resolved "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.1.tgz" integrity sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA== -date-fns@^2.14.0, date-fns@^2.30.0: +date-fns@^2.14.0, "date-fns@^2.25.0 || ^3.2.0 || ^4.0.0", "date-fns@^2.28.0 || ^3.0.0", date-fns@^2.30.0, "date-fns@>= 2.x", date-fns@2.x: version "2.30.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz" integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== @@ -6626,32 +6241,32 @@ date-fns@^3.3.1: resolved "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz" integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== -dayjs@^1.11.11, dayjs@^1.11.13: +dayjs@^1.10.7, dayjs@^1.11.11, dayjs@^1.11.13, dayjs@^1.8.17, "dayjs@>= 1.x": version "1.11.18" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz" integrity sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA== -debug@2: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.1, debug@^4.4.3: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== +debug@^3.2.6: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "^2.1.3" + ms "^2.1.1" -debug@^3.2.6, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.1, debug@^4.4.3, debug@4: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decimal.js-light@^2.4.1: version "2.5.1" resolved "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz" @@ -6747,10 +6362,10 @@ detect-kerning@^2.1.2: resolved "https://registry.npmjs.org/detect-kerning/-/detect-kerning-2.1.2.tgz" integrity sha512-I3JIbrnKPAntNLl1I6TpSQQdQ4AutYzv/sKMFKbepawV/hlH0GmYKhUoOEMd4xqaUHT+Bm0f4127lh5qs1m1tw== -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz" - integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== +detect-libc@^2.0.3: + version "2.1.2" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz" + integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== detect-newline@^3.1.0: version "3.1.0" @@ -6762,11 +6377,6 @@ dfa@^1.2.0: resolved "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz" integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q== -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - diff@^5.0.0, diff@^5.2.2: version "5.2.2" resolved "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz" @@ -6845,7 +6455,7 @@ domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== -domhandler@4.3.1, domhandler@^4.2.0, domhandler@^4.2.2: +domhandler@^4.2.0, domhandler@^4.2.2, domhandler@4.3.1: version "4.3.1" resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== @@ -6860,14 +6470,14 @@ domhandler@^5.0.2, domhandler@^5.0.3: domelementtype "^2.3.0" dompurify@^2.5.4: - version "2.5.8" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.5.8.tgz" - integrity sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw== + version "2.5.9" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.5.9.tgz" + integrity sha512-i6mvVmWN4xo9LrhCOZrDgSs9noW6nOahbrmzjRbPF36YPyj5Ue5lgok0MHDWkG7xzpWFO2OYttXdzM7rJxHvNA== dompurify@^3.3.1, dompurify@^3.4.16: - version "3.4.16" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.16.tgz#c51b3709ea15ee9abb07e804f2ef30ea9b953128" - integrity sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ== + version "3.4.17" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.4.17.tgz" + integrity sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -6948,10 +6558,10 @@ eastasianwidth@^0.2.0: resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -electron-to-chromium@^1.5.427: - version "1.5.430" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.430.tgz#788eada5bbfda8095a95149184368a2bb4fb8e4a" - integrity sha512-e1QEj72Y4zd8RlNZVmoTg+iCOSVwpk05IOiiQwdrkwCSVlZfPthevErhE+nckGd2YbsXfp1SkisznhGVIXP2NQ== +electron-to-chromium@^1.5.464: + version "1.5.468" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.468.tgz" + integrity sha512-8XdEp3sIqO+PzmVPxhzqHq/3+yCxp44m27cm2WY1sRn3ZhwKyKmqSi2hx6gEhmnOXmh8NUuYE00z6Onzn5m6DA== elementary-circuits-directed-graph@^1.0.4: version "1.3.1" @@ -6960,7 +6570,7 @@ elementary-circuits-directed-graph@^1.0.4: dependencies: strongly-connected-components "^1.0.1" -elliptic@^6.5.3, elliptic@^6.5.5, elliptic@^6.6.1: +elliptic@^6.5.3, elliptic@^6.6.1: version "6.6.1" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz" integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== @@ -7151,9 +6761,9 @@ es-module-lexer@^1.7.0: integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== es-module-lexer@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz" - integrity sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ== + version "2.3.2" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz" + integrity sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -7421,14 +7031,6 @@ eslint-plugin-vitest@^0.5.4: dependencies: "@typescript-eslint/utils" "^7.7.1" -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" @@ -7437,6 +7039,14 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" @@ -7457,7 +7067,7 @@ eslint-visitor-keys@^5.0.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz" integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== -eslint@^8.57.1: +"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.5.0 || ^8.0.0 || ^9.0.0", eslint@^8.56.0, "eslint@^8.57.0 || ^9.0.0", "eslint@^8.57.0 || ^9.0.0 || ^10.0.0", eslint@^8.57.1, eslint@>=3.14.1, eslint@>=5.0.0: version "8.57.1" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz" integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== @@ -7626,40 +7236,17 @@ expect-type@^1.2.1: resolved "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz" integrity sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA== -expect@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz" - integrity sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA== - dependencies: - "@jest/expect-utils" "30.4.1" - "@jest/get-type" "30.1.0" - jest-matcher-utils "30.4.1" - jest-message-util "30.4.1" - jest-mock "30.4.1" - jest-util "30.4.1" - -expect@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - -expect@^30.0.0: - version "30.1.1" - resolved "https://registry.npmjs.org/expect/-/expect-30.1.1.tgz" - integrity sha512-OKe7cdic4qbfWd/CcgwJvvCrNX2KWfuMZee9AfJHL1gTYmvqjBjZG1a2NwfhspBzxzlXwsN75WWpKTYfsJpBxg== +expect@^30.0.0, expect@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/expect/-/expect-30.5.2.tgz" + integrity sha512-0LNuMvs8/5mRYhnCR4k+lGV7fqPMs6Bnksda4S3zsCUmdxBpAn4zU4NNzXdq1pMKe/H4W5t/zVIDSJ/H3e0vDA== dependencies: - "@jest/expect-utils" "30.1.1" - "@jest/get-type" "30.1.0" - jest-matcher-utils "30.1.1" - jest-message-util "30.1.0" - jest-mock "30.0.5" - jest-util "30.0.5" + "@jest/expect-utils" "30.5.2" + "@jest/get-type" "30.5.0" + jest-matcher-utils "30.5.2" + jest-message-util "30.5.1" + jest-mock "30.5.2" + jest-util "30.5.1" ext@^1.7.0: version "1.7.0" @@ -7736,9 +7323,9 @@ fast-png@^6.2.0: pako "^2.1.0" fast-uri@^3.0.1: - version "3.1.8" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.8.tgz#f7db8d942e20eead3cfe93b0beeb4eb0169e938b" - integrity sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg== + version "3.1.9" + resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz" + integrity sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ== fastest-levenshtein@^1.0.16: version "1.0.16" @@ -7759,7 +7346,12 @@ fb-watchman@^2.0.0, fb-watchman@^2.0.2: dependencies: bser "2.1.1" -fdir@^6.4.4, fdir@^6.5.0: +fdir@^6.4.4: + version "6.5.0" + resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz" + integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + +fdir@^6.5.0: version "6.5.0" resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz" integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== @@ -7770,14 +7362,14 @@ fecha@^4.2.1: integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== fflate@^0.7.3: - version "0.7.4" - resolved "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz" - integrity sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw== + version "0.7.5" + resolved "https://registry.npmjs.org/fflate/-/fflate-0.7.5.tgz" + integrity sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g== fflate@^0.8.1, fflate@^0.8.2: - version "0.8.2" - resolved "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz" - integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + version "0.8.3" + resolved "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz" + integrity sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA== file-entry-cache@^11.1.1: version "11.1.5" @@ -7857,9 +7449,9 @@ flru@^1.0.2: integrity sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog== follow-redirects@^1.16.0: - version "1.16.0" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz" - integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== + version "1.16.2" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.2.tgz" + integrity sha512-/kVP2U8z596Ia0gwFrwyIeo74ta5aVmSeU1FfAUMAmcEP5EP7zydmag3SLiN64NaRKef3lxsq7i/g7ltJQDGow== font-atlas@^2.1.0: version "2.1.0" @@ -7933,7 +7525,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2, fsevents@^2.3.3, fsevents@~2.3.2, fsevents@~2.3.3: +fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -8110,7 +7702,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^10.4.1, glob@^10.5.0: +glob@^10.4.1: version "10.5.0" resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== @@ -8122,17 +7714,14 @@ glob@^10.4.1, glob@^10.5.0: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^10.5.0: - version "10.5.0" - resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" - integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== +glob@^13.0.6: + version "13.0.6" + resolved "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz" + integrity sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw== dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" + minimatch "^10.2.2" + minipass "^7.1.3" + path-scurry "^2.0.2" glob@^7.1.3: version "7.2.3" @@ -8439,14 +8028,7 @@ has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" -hash-base@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz" - integrity sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw== - dependencies: - inherits "^2.0.1" - -hash-base@^3.0.0, hash-base@~3.0, hash-base@~3.0.4: +hash-base@^3.0.0, hash-base@~3.0.4: version "3.0.5" resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz" integrity sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg== @@ -8454,6 +8036,16 @@ hash-base@^3.0.0, hash-base@~3.0, hash-base@~3.0.4: inherits "^2.0.4" safe-buffer "^5.2.1" +hash-base@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz" + integrity sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg== + dependencies: + inherits "^2.0.4" + readable-stream "^2.3.8" + safe-buffer "^5.2.1" + to-buffer "^1.2.1" + hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" @@ -8567,16 +8159,6 @@ html2canvas@^1.0.0-rc.5, html2canvas@^1.4.1: css-line-break "^2.1.0" text-segmentation "^1.0.3" -htmlparser2@7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz" - integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.2" - domutils "^2.8.0" - entities "^3.0.1" - htmlparser2@^10.0.0: version "10.0.0" resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz" @@ -8587,6 +8169,16 @@ htmlparser2@^10.0.0: domutils "^3.2.1" entities "^6.0.0" +htmlparser2@7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz" + integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.2" + domutils "^2.8.0" + entities "^3.0.1" + http-proxy-agent@^7.0.2: version "7.0.2" resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz" @@ -8621,13 +8213,6 @@ husky@^7.0.4: resolved "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz" integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== -iconv-lite@0.6, iconv-lite@0.6.3, iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" @@ -8635,6 +8220,13 @@ iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.6.3, iconv-lite@0.6, iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.12, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" @@ -8656,9 +8248,9 @@ immer@^10.0.3: integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw== immutable@^5.0.2: - version "5.1.3" - resolved "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz" - integrity sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg== + version "5.1.9" + resolved "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz" + integrity sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg== import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.1" @@ -8694,7 +8286,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: +inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4, inherits@2: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -8723,16 +8315,16 @@ internal-slot@^1.1.0: hasown "^2.0.2" side-channel "^1.1.0" -"internmap@1 - 2": - version "2.0.3" - resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" - integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== - internmap@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + invariant@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" @@ -9050,12 +8642,12 @@ is-weakset@^2.0.3: call-bound "^1.0.3" get-intrinsic "^1.2.6" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@^2.0.1, isarray@^2.0.5: +isarray@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== @@ -9065,6 +8657,11 @@ isarray@~1.0.0: resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -9149,169 +8746,127 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" -jest-changed-files@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz" - integrity sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg== +jest-changed-files@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.5.1.tgz" + integrity sha512-0+bvMM/ENhDI29Z8q1r4HxiDIi4G5tnBmSw4esfPQoj9q8Nik7KIyuxHkTVnnniJQf05SxpGaKDQ+4h28ynGPg== dependencies: execa "^5.1.1" - jest-util "30.4.1" + jest-util "30.5.1" p-limit "^3.1.0" -jest-circus@30.4.2: - version "30.4.2" - resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz" - integrity sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ== +jest-circus@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-30.5.2.tgz" + integrity sha512-vffFgjs5JSJ9q4ds1vNW3klKYPJfYfIY61LT/zaZgvTeASJOWZUt8LBfHgIcV4rwxlPBLl/ePBGccHEclS4PlQ== dependencies: - "@jest/environment" "30.4.1" - "@jest/expect" "30.4.1" - "@jest/test-result" "30.4.1" - "@jest/types" "30.4.1" + "@jest/environment" "30.5.2" + "@jest/expect" "30.5.2" + "@jest/test-result" "30.5.2" + "@jest/types" "30.5.1" "@types/node" "*" chalk "^4.1.2" co "^4.6.0" dedent "^1.6.0" is-generator-fn "^2.1.0" - jest-each "30.4.1" - jest-matcher-utils "30.4.1" - jest-message-util "30.4.1" - jest-runtime "30.4.2" - jest-snapshot "30.4.1" - jest-util "30.4.1" + jest-each "30.5.2" + jest-matcher-utils "30.5.2" + jest-message-util "30.5.1" + jest-runtime "30.5.2" + jest-snapshot "30.5.2" + jest-util "30.5.1" p-limit "^3.1.0" - pretty-format "30.4.1" + pretty-format "30.5.1" pure-rand "^7.0.0" slash "^3.0.0" stack-utils "^2.0.6" -jest-cli@30.4.2: - version "30.4.2" - resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz" - integrity sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q== +jest-cli@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-30.5.2.tgz" + integrity sha512-YYYxUUVjFgPvgEleKNKMaYGIFgR3l3832Cl0kRL/oCiDZ03v7wImUtquHl2OOBCCNgprjZgBN5bczS/JklPBDg== dependencies: - "@jest/core" "30.4.2" - "@jest/test-result" "30.4.1" - "@jest/types" "30.4.1" + "@jest/core" "30.5.2" + "@jest/test-result" "30.5.2" + "@jest/types" "30.5.1" chalk "^4.1.2" exit-x "^0.2.2" import-local "^3.2.0" - jest-config "30.4.2" - jest-util "30.4.1" - jest-validate "30.4.1" + jest-config "30.5.2" + jest-util "30.5.1" + jest-validate "30.5.1" yargs "^17.7.2" -jest-config@30.4.2: - version "30.4.2" - resolved "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz" - integrity sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg== +jest-config@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-30.5.2.tgz" + integrity sha512-U6221OZekabePvGcGPf4raIBKMvYQWFHvhobDJRojOYaFMj2HaGytAdknjDhYc6JTz2fdHW9+6k0wWUDaNeOFQ== dependencies: "@babel/core" "^7.27.4" - "@jest/get-type" "30.1.0" - "@jest/pattern" "30.4.0" - "@jest/test-sequencer" "30.4.1" - "@jest/types" "30.4.1" - babel-jest "30.4.1" + "@jest/get-type" "30.5.0" + "@jest/pattern" "30.5.0" + "@jest/test-sequencer" "30.5.2" + "@jest/types" "30.5.1" + babel-jest "30.5.2" chalk "^4.1.2" ci-info "^4.2.0" deepmerge "^4.3.1" - glob "^10.5.0" + glob "^13.0.6" graceful-fs "^4.2.11" - jest-circus "30.4.2" - jest-docblock "30.4.0" - jest-environment-node "30.4.1" - jest-regex-util "30.4.0" - jest-resolve "30.4.1" - jest-runner "30.4.2" - jest-util "30.4.1" - jest-validate "30.4.1" + jest-circus "30.5.2" + jest-docblock "30.5.0" + jest-environment-node "30.5.2" + jest-regex-util "30.5.0" + jest-resolve "30.5.1" + jest-runner "30.5.2" + jest-util "30.5.1" + jest-validate "30.5.1" parse-json "^5.2.0" - pretty-format "30.4.1" + pretty-format "30.5.1" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@30.1.1: - version "30.1.1" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-30.1.1.tgz" - integrity sha512-LUU2Gx8EhYxpdzTR6BmjL1ifgOAQJQELTHOiPv9KITaKjZvJ9Jmgigx01tuZ49id37LorpGc9dPBPlXTboXScw== - dependencies: - "@jest/diff-sequences" "30.0.1" - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - pretty-format "30.0.5" - -jest-diff@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz" - integrity sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA== +jest-diff@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-30.5.2.tgz" + integrity sha512-rBtHnI6BWTiWj3lM7fOLVfChx7R9B0u9VV3PRHawKs79x6ZjW1QoSrKenaigNGWlvhtoi2BqvDbABDie+Os3xQ== dependencies: - "@jest/diff-sequences" "30.4.0" - "@jest/get-type" "30.1.0" + "@jest/diff-sequences" "30.5.0" + "@jest/get-type" "30.5.0" chalk "^4.1.2" - pretty-format "30.4.1" - -jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" + pretty-format "30.5.1" -jest-docblock@30.4.0: - version "30.4.0" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz" - integrity sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA== +jest-docblock@30.5.0: + version "30.5.0" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.5.0.tgz" + integrity sha512-NwDqcxtoZi33RhuW+zJS/RVA3rmheQ8BnwpYZuc/Eruaz6seQb7+aoCeDZu/3X7W2XmD8DbSo9Pn72DbKsBFYw== dependencies: detect-newline "^3.1.0" -jest-each@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz" - integrity sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA== +jest-each@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-30.5.2.tgz" + integrity sha512-GRrW+7fmmgmkvyfEBqc1QFdWnF1Ex5yG6Y6AWL4TTxnkWlKIT98dsKh3P3UuWm6v4XsQwVE6DEzXIPMzWJ3ZbA== dependencies: - "@jest/get-type" "30.1.0" - "@jest/types" "30.4.1" + "@jest/get-type" "30.5.0" + "@jest/types" "30.5.1" chalk "^4.1.2" - jest-util "30.4.1" - pretty-format "30.4.1" - -jest-environment-node@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz" - integrity sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw== - dependencies: - "@jest/environment" "30.4.1" - "@jest/fake-timers" "30.4.1" - "@jest/types" "30.4.1" - "@types/node" "*" - jest-mock "30.4.1" - jest-util "30.4.1" - jest-validate "30.4.1" - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - -jest-haste-map@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz" - integrity sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw== - dependencies: - "@jest/types" "30.4.1" + jest-regex-util "30.5.0" + jest-util "30.5.1" + pretty-format "30.5.1" + +jest-environment-node@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.5.2.tgz" + integrity sha512-Ciz4KgTGIbojxSKpuFImgWJj5EyqfE8xMq9NxWmOXnQywHHS03H9Mv+vaCB29J5pr3JBrY27WbRV18rBdjh8Dg== + dependencies: + "@jest/environment" "30.5.2" + "@jest/fake-timers" "30.5.2" + "@jest/types" "30.5.1" "@types/node" "*" - anymatch "^3.1.3" - fb-watchman "^2.0.2" - graceful-fs "^4.2.11" - jest-regex-util "30.4.0" - jest-util "30.4.1" - jest-worker "30.4.1" - picomatch "^4.0.3" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.3" + jest-mock "30.5.2" + jest-util "30.5.1" + jest-validate "30.5.1" jest-haste-map@^29.7.0: version "29.7.0" @@ -9332,74 +8887,40 @@ jest-haste-map@^29.7.0: optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz" - integrity sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ== - dependencies: - "@jest/get-type" "30.1.0" - pretty-format "30.4.1" - -jest-matcher-utils@30.1.1: - version "30.1.1" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.1.1.tgz" - integrity sha512-SuH2QVemK48BNTqReti6FtjsMPFsSOD/ZzRxU1TttR7RiRsRSe78d03bb4Cx6D4bQC/80Q8U4VnaaAH9FlbZ9w== - dependencies: - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - jest-diff "30.1.1" - pretty-format "30.0.5" - -jest-matcher-utils@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz" - integrity sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A== - dependencies: - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - jest-diff "30.4.1" - pretty-format "30.4.1" - -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== +jest-haste-map@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz" + integrity sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ== dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" + "@jest/types" "30.5.1" + "@parcel/watcher" "^2.6.0" + "@types/node" "*" + anymatch "^3.1.3" + fb-watchman "^2.0.2" + fdir "^6.5.0" + graceful-fs "^4.2.11" + jest-regex-util "30.5.0" + jest-util "30.5.1" + jest-worker "30.5.1" + picomatch "^4.0.3" -jest-message-util@30.1.0: - version "30.1.0" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.1.0.tgz" - integrity sha512-HizKDGG98cYkWmaLUHChq4iN+oCENohQLb7Z5guBPumYs+/etonmNFlg1Ps6yN9LTPyZn+M+b/9BbnHx3WTMDg== +jest-leak-detector@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.5.1.tgz" + integrity sha512-gt4GT2aWgEoCNTcBe4rqS74xTIUJxi+UD9SNSu9aOk5LmTEd6fS5KSTmAKAfitCCktQHNN+upUuL6EkBfFbMDQ== dependencies: - "@babel/code-frame" "^7.27.1" - "@jest/types" "30.0.5" - "@types/stack-utils" "^2.0.3" - chalk "^4.1.2" - graceful-fs "^4.2.11" - micromatch "^4.0.8" - pretty-format "30.0.5" - slash "^3.0.0" - stack-utils "^2.0.6" + "@jest/get-type" "30.5.0" + pretty-format "30.5.1" -jest-message-util@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz" - integrity sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ== +jest-matcher-utils@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.5.2.tgz" + integrity sha512-lFkB365PTIHOhPzwrb9T6gvlDnPpOZ7/c3ewOKKB7bzztqjVrtlyRL2MkyfJXpyY2u2SKw001JKrTx14fBUFcQ== dependencies: - "@babel/code-frame" "^7.27.1" - "@jest/types" "30.4.1" - "@types/stack-utils" "^2.0.3" + "@jest/get-type" "30.5.0" chalk "^4.1.2" - graceful-fs "^4.2.11" - jest-util "30.4.1" - picomatch "^4.0.3" - pretty-format "30.4.1" - slash "^3.0.0" - stack-utils "^2.0.6" + jest-diff "30.5.2" + pretty-format "30.5.1" jest-message-util@^29.7.0: version "29.7.0" @@ -9416,23 +8937,21 @@ jest-message-util@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@30.0.5: - version "30.0.5" - resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz" - integrity sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ== - dependencies: - "@jest/types" "30.0.5" - "@types/node" "*" - jest-util "30.0.5" - -jest-mock@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz" - integrity sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw== +jest-message-util@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz" + integrity sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg== dependencies: - "@jest/types" "30.4.1" - "@types/node" "*" - jest-util "30.4.1" + "@babel/code-frame" "^7.27.1" + "@jest/types" "30.5.1" + "@types/stack-utils" "^2.0.3" + chalk "^4.1.2" + graceful-fs "^4.2.11" + jest-util "30.5.1" + picomatch "^4.0.3" + pretty-format "30.5.1" + slash "^3.0.0" + stack-utils "^2.0.6" jest-mock@^29.7.0: version "29.7.0" @@ -9443,230 +8962,181 @@ jest-mock@^29.7.0: "@types/node" "*" jest-util "^29.7.0" -jest-pnp-resolver@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@30.0.1: - version "30.0.1" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz" - integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA== - -jest-regex-util@30.4.0: - version "30.4.0" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz" - integrity sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg== +jest-mock@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz" + integrity sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA== + dependencies: + "@jest/expect-utils" "30.5.2" + "@jest/types" "30.5.1" + "@types/node" "*" + jest-util "30.5.1" jest-regex-util@^29.6.3: version "29.6.3" resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== -jest-resolve-dependencies@30.4.2: - version "30.4.2" - resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz" - integrity sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ== +jest-regex-util@30.5.0: + version "30.5.0" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz" + integrity sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A== + +jest-resolve-dependencies@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.5.2.tgz" + integrity sha512-GMI0DP5enX9Z2qW2zFy1bOkrCfWAOPRJQ7qHt0pdfrxBPsgWxglMPrRSK2TX/wRWYxcPRSLFg3Z88qPOzHx7FQ== dependencies: - jest-regex-util "30.4.0" - jest-snapshot "30.4.1" + jest-regex-util "30.5.0" + jest-snapshot "30.5.2" -jest-resolve@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz" - integrity sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q== +jest-resolve@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.5.1.tgz" + integrity sha512-wprhLejRtwN6h8ZgaqC0eYjGJ1uMdGPT/+b3eFncbG4NWuuP9QL+vWwRinu9waw7hkOLcpMJGVJAMgBwsPssMQ== dependencies: chalk "^4.1.2" graceful-fs "^4.2.11" - jest-haste-map "30.4.1" - jest-pnp-resolver "^1.2.3" - jest-util "30.4.1" - jest-validate "30.4.1" + jest-haste-map "30.5.1" + jest-util "30.5.1" + jest-validate "30.5.1" slash "^3.0.0" - unrs-resolver "^1.7.11" - -jest-runner@30.4.2: - version "30.4.2" - resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz" - integrity sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg== - dependencies: - "@jest/console" "30.4.1" - "@jest/environment" "30.4.1" - "@jest/test-result" "30.4.1" - "@jest/transform" "30.4.1" - "@jest/types" "30.4.1" + unrs-resolver "^1.12.1" + +jest-runner@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-30.5.2.tgz" + integrity sha512-/B6px7hiiNhVSRwuv9AGn0nawYvwsHeQZ3ItTd5Gp2diFd0EOKaWVeWqcbw3L88vx1GfpCKjQkxWItZCTl11Rw== + dependencies: + "@jest/console" "30.5.2" + "@jest/environment" "30.5.2" + "@jest/source-map" "30.5.2" + "@jest/test-result" "30.5.2" + "@jest/transform" "30.5.2" + "@jest/types" "30.5.1" "@types/node" "*" chalk "^4.1.2" emittery "^0.13.1" exit-x "^0.2.2" graceful-fs "^4.2.11" - jest-docblock "30.4.0" - jest-environment-node "30.4.1" - jest-haste-map "30.4.1" - jest-leak-detector "30.4.1" - jest-message-util "30.4.1" - jest-resolve "30.4.1" - jest-runtime "30.4.2" - jest-util "30.4.1" - jest-watcher "30.4.1" - jest-worker "30.4.1" + jest-docblock "30.5.0" + jest-environment-node "30.5.2" + jest-haste-map "30.5.1" + jest-leak-detector "30.5.1" + jest-message-util "30.5.1" + jest-resolve "30.5.1" + jest-runtime "30.5.2" + jest-util "30.5.1" + jest-watcher "30.5.2" + jest-worker "30.5.1" p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@30.4.2: - version "30.4.2" - resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz" - integrity sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ== - dependencies: - "@jest/environment" "30.4.1" - "@jest/fake-timers" "30.4.1" - "@jest/globals" "30.4.1" - "@jest/source-map" "30.0.1" - "@jest/test-result" "30.4.1" - "@jest/transform" "30.4.1" - "@jest/types" "30.4.1" + +jest-runtime@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.5.2.tgz" + integrity sha512-0paUAHBlheai10A3XSy9Xh+YBG0IROy+/qzcDPzQ/nbbXrznQzeWy5qniICWK6d3W3scaRQCVAbXdcK0ibBq4w== + dependencies: + "@jest/environment" "30.5.2" + "@jest/fake-timers" "30.5.2" + "@jest/globals" "30.5.2" + "@jest/source-map" "30.5.2" + "@jest/test-result" "30.5.2" + "@jest/transform" "30.5.2" + "@jest/types" "30.5.1" "@types/node" "*" chalk "^4.1.2" - cjs-module-lexer "^2.1.0" + cjs-module-lexer "^2.2.0" collect-v8-coverage "^1.0.2" - glob "^10.5.0" + es-module-lexer "^2.1.0" + glob "^13.0.6" graceful-fs "^4.2.11" - jest-haste-map "30.4.1" - jest-message-util "30.4.1" - jest-mock "30.4.1" - jest-regex-util "30.4.0" - jest-resolve "30.4.1" - jest-snapshot "30.4.1" - jest-util "30.4.1" + jest-haste-map "30.5.1" + jest-message-util "30.5.1" + jest-mock "30.5.2" + jest-regex-util "30.5.0" + jest-resolve "30.5.1" + jest-snapshot "30.5.2" + jest-util "30.5.1" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz" - integrity sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw== +jest-snapshot@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.5.2.tgz" + integrity sha512-jKIdes25AnAH73dOCi2qE6J6vHJ6L2vyBS11M89kT50DVJcLTf2AOjvcc+2vVaN8lUbY5v2R83aqXo3Ro9fqYA== dependencies: "@babel/core" "^7.27.4" "@babel/generator" "^7.27.5" "@babel/plugin-syntax-jsx" "^7.27.1" "@babel/plugin-syntax-typescript" "^7.27.1" "@babel/types" "^7.27.3" - "@jest/expect-utils" "30.4.1" - "@jest/get-type" "30.1.0" - "@jest/snapshot-utils" "30.4.1" - "@jest/transform" "30.4.1" - "@jest/types" "30.4.1" + "@jest/expect-utils" "30.5.2" + "@jest/get-type" "30.5.0" + "@jest/snapshot-utils" "30.5.1" + "@jest/transform" "30.5.2" + "@jest/types" "30.5.1" babel-preset-current-node-syntax "^1.2.0" chalk "^4.1.2" - expect "30.4.1" + expect "30.5.2" graceful-fs "^4.2.11" - jest-diff "30.4.1" - jest-matcher-utils "30.4.1" - jest-message-util "30.4.1" - jest-util "30.4.1" - pretty-format "30.4.1" + jest-diff "30.5.2" + jest-matcher-utils "30.5.2" + jest-message-util "30.5.1" + jest-util "30.5.1" + pretty-format "30.5.1" semver "^7.7.2" synckit "^0.11.8" -jest-snapshot@^29.7.0: +jest-util@^29.7.0: version "29.7.0" - resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz" - integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.7.0" - "@jest/transform" "^29.7.0" "@jest/types" "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" + "@types/node" "*" chalk "^4.0.0" - expect "^29.7.0" + ci-info "^3.2.0" graceful-fs "^4.2.9" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - natural-compare "^1.4.0" - pretty-format "^29.7.0" - semver "^7.5.3" - -jest-util@30.0.5: - version "30.0.5" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-30.0.5.tgz" - integrity sha512-pvyPWssDZR0FlfMxCBoc0tvM8iUEskaRFALUtGQYzVEAqisAztmy+R8LnU14KT4XA0H/a5HMVTXat1jLne010g== - dependencies: - "@jest/types" "30.0.5" - "@types/node" "*" - chalk "^4.1.2" - ci-info "^4.2.0" - graceful-fs "^4.2.11" - picomatch "^4.0.2" + picomatch "^2.2.3" -jest-util@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz" - integrity sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw== +jest-util@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz" + integrity sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg== dependencies: - "@jest/types" "30.4.1" + "@jest/types" "30.5.1" "@types/node" "*" chalk "^4.1.2" ci-info "^4.2.0" graceful-fs "^4.2.11" picomatch "^4.0.3" -jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz" - integrity sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw== +jest-validate@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-30.5.1.tgz" + integrity sha512-i/buJ56wTpxihE93hQYNMfdOThS87+HGvLZzZJmU4xggPcdTYQq051iwALLCHp3q+SkCGH+EFejQZz5EbBSkkg== dependencies: - "@jest/get-type" "30.1.0" - "@jest/types" "30.4.1" + "@jest/get-type" "30.5.0" + "@jest/types" "30.5.1" camelcase "^6.3.0" chalk "^4.1.2" leven "^3.1.0" - pretty-format "30.4.1" + pretty-format "30.5.1" -jest-watcher@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz" - integrity sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw== +jest-watcher@30.5.2: + version "30.5.2" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.5.2.tgz" + integrity sha512-rqRgg4R11GA9m1UsEZwQeixHsgZReCn6TOHAHtIH33yXrIvoX0OGPA20Yzzjkz7X40fZvcRSxEpQppYPcWzmcQ== dependencies: - "@jest/test-result" "30.4.1" - "@jest/types" "30.4.1" + "@jest/test-result" "30.5.2" + "@jest/types" "30.5.1" "@types/node" "*" ansi-escapes "^4.3.2" chalk "^4.1.2" emittery "^0.13.1" - jest-util "30.4.1" + jest-util "30.5.1" string-length "^4.0.2" -jest-worker@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz" - integrity sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g== - dependencies: - "@types/node" "*" - "@ungap/structured-clone" "^1.3.0" - jest-util "30.4.1" - merge-stream "^2.0.0" - supports-color "^8.1.1" - jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" @@ -9686,15 +9156,26 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-30.5.1.tgz" + integrity sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA== + dependencies: + "@types/node" "*" + "@ungap/structured-clone" "^1.3.0" + jest-util "30.5.1" + merge-stream "^2.0.0" + supports-color "^8.1.1" + jest@^30.2.0: - version "30.4.2" - resolved "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz" - integrity sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ== + version "30.5.2" + resolved "https://registry.npmjs.org/jest/-/jest-30.5.2.tgz" + integrity sha512-3gnpdBIza8ijCl3iMV9ChE3hSt1+46865qqod863gQtJr1DixOkAU5DoGbi3u+XlRcw++BhZQMu/y4xBdHBvSQ== dependencies: - "@jest/core" "30.4.2" - "@jest/types" "30.4.1" + "@jest/core" "30.5.2" + "@jest/types" "30.5.1" import-local "^3.2.0" - jest-cli "30.4.2" + jest-cli "30.5.2" joi-browser@^13.4.0: version "13.4.0" @@ -9702,9 +9183,9 @@ joi-browser@^13.4.0: integrity sha512-TfzJd2JaJ/lg/gU+q5j9rLAjnfUNF9DUmXTP9w+GfmG79LjFOXFeM7hIFuXCBcZCivUDFwd9l1btTV9rhHumtQ== joi@^18.2.5: - version "18.2.5" - resolved "https://registry.yarnpkg.com/joi/-/joi-18.2.5.tgz#aae38f2a7e056d88aaf5d62c6f414f5fd6516be0" - integrity sha512-+gEA7rLfaNWx9JzawWPrPetSZwT16NUqHtECDgjyAJreXcs4TM7tx2Pa+VVJJK0YHM83ybrVdaT6UekHH50FJQ== + version "18.3.0" + resolved "https://registry.npmjs.org/joi/-/joi-18.3.0.tgz" + integrity sha512-/RwAK4BAfzcdbdFg073tzq4/xhY6Q7lMd5AmjqTL6pu0QFJdEmtswgm8BvgwXvOKuPNYQ8XrdQrrW/gF65LiNw== dependencies: "@hapi/address" "^5.1.1" "@hapi/formula" "^3.0.2" @@ -9719,7 +9200,7 @@ jpeg-exif@^1.1.4: resolved "https://registry.npmjs.org/jpeg-exif/-/jpeg-exif-1.1.4.tgz" integrity sha512-a+bKEcCjtuW5WTdgeXFzswSrdqi0jk4XlEtZlx5A94wCoBpFjfFTbo/Tra5SpNCl/YFZPvcV1dJc+TAYeg6ROQ== -jquery@^3.7.1: +jquery@^3.7.1, "jquery@1.9.1 - 3": version "3.7.1" resolved "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz" integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== @@ -9740,21 +9221,21 @@ js-tokens@^9.0.1: integrity sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ== js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + version "3.15.2" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz" + integrity sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w== dependencies: argparse "^1.0.7" esprima "^4.0.0" js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + version "4.3.2" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz" + integrity sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA== dependencies: argparse "^2.0.1" -jsdom@^26.1.0: +jsdom@*, jsdom@^26.1.0: version "26.1.0" resolved "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz" integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg== @@ -9853,6 +9334,20 @@ jspdf-autotable@^5.0.7: resolved "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-5.0.8.tgz" integrity sha512-Hy05N86yBO7CXBrnSLOge7i1ZYpKH2DjQ94iybaP7vBhSInjvRBgDc99ngKzSbSO8Jc98ZCally8I6n0tj2RJQ== +"jspdf@^2 || ^3 || ^4", jspdf@^4.2.1: + version "4.2.1" + resolved "https://registry.npmjs.org/jspdf/-/jspdf-4.2.1.tgz" + integrity sha512-YyAXyvnmjTbR4bHQRLzex3CuINCDlQnBqoSYyjJwTP2x9jDLuKDzy7aKUl0hgx3uhcl7xzg32agn5vlie6HIlQ== + dependencies: + "@babel/runtime" "^7.28.6" + fast-png "^6.2.0" + fflate "^0.8.1" + optionalDependencies: + canvg "^3.0.11" + core-js "^3.6.0" + dompurify "^3.3.1" + html2canvas "^1.0.0-rc.5" + jspdf@^2.5.1: version "2.5.2" resolved "https://registry.npmjs.org/jspdf/-/jspdf-2.5.2.tgz" @@ -9868,20 +9363,6 @@ jspdf@^2.5.1: dompurify "^2.5.4" html2canvas "^1.0.0-rc.5" -jspdf@^4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/jspdf/-/jspdf-4.2.1.tgz" - integrity sha512-YyAXyvnmjTbR4bHQRLzex3CuINCDlQnBqoSYyjJwTP2x9jDLuKDzy7aKUl0hgx3uhcl7xzg32agn5vlie6HIlQ== - dependencies: - "@babel/runtime" "^7.28.6" - fast-png "^6.2.0" - fflate "^0.8.1" - optionalDependencies: - canvg "^3.0.11" - core-js "^3.6.0" - dompurify "^3.3.1" - html2canvas "^1.0.0-rc.5" - "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz" @@ -9958,7 +9439,7 @@ leaflet.markercluster@^1.5.3: resolved "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz" integrity sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA== -leaflet@^1.8.0, leaflet@^1.9.4: +leaflet@^1.3.1, leaflet@^1.8.0, leaflet@^1.9.0, leaflet@^1.9.4: version "1.9.4" resolved "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz" integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA== @@ -10066,9 +9547,9 @@ lodash.truncate@^4.4.2: integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== lodash@^4.17.15, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + version "4.18.1" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz" + integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q== log-update@^6.1.0: version "6.1.0" @@ -10093,11 +9574,21 @@ loupe@^3.1.0, loupe@^3.1.4: resolved "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz" integrity sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ== -lru-cache@^10.2.0, lru-cache@^10.4.3: +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +lru-cache@^10.4.3: version "10.4.3" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.0: + version "11.5.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz" + integrity sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -10159,6 +9650,34 @@ map-limit@0.0.1: dependencies: once "~1.3.0" +"mapbox-gl@>=0.32.1 <2.0.0": + version "1.13.3" + resolved "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.3.tgz" + integrity sha512-p8lJFEiqmEQlyv+DQxFAOG/XPWN0Wp7j/Psq93Zywz7qt9CcUKFYDBOoOEKzqe6gudHVJY8/Bhqw6VDpX2lSBg== + dependencies: + "@mapbox/geojson-rewind" "^0.5.2" + "@mapbox/geojson-types" "^1.0.2" + "@mapbox/jsonlint-lines-primitives" "^2.0.2" + "@mapbox/mapbox-gl-supported" "^1.5.0" + "@mapbox/point-geometry" "^0.1.0" + "@mapbox/tiny-sdf" "^1.1.1" + "@mapbox/unitbezier" "^0.0.0" + "@mapbox/vector-tile" "^1.3.1" + "@mapbox/whoots-js" "^3.1.0" + csscolorparser "~1.0.3" + earcut "^2.2.2" + geojson-vt "^3.2.1" + gl-matrix "^3.2.1" + grid-index "^1.1.0" + murmurhash-js "^1.0.0" + pbf "^3.2.1" + potpack "^1.0.1" + quickselect "^2.0.0" + rw "^1.3.3" + supercluster "^7.1.0" + tinyqueue "^2.0.3" + vt-pbf "^3.1.1" + maplibre-gl@^4.7.1: version "4.7.1" resolved "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.1.tgz" @@ -10228,16 +9747,16 @@ mem@^8.0.0: map-age-cleaner "^0.1.3" mimic-fn "^3.1.0" -"memoize-one@>=3.1.1 <6": - version "5.2.1" - resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" - integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== - memoize-one@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz" integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== +"memoize-one@>=3.1.1 <6": + version "5.2.1" + resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + meow@^13.2.0: version "13.2.0" resolved "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz" @@ -10253,7 +9772,7 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8: +micromatch@^4.0.4, micromatch@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -10269,16 +9788,16 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - mime-db@^1.54.0: version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@^2.1.35: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" @@ -10317,16 +9836,16 @@ minimalistic-crypto-utils@^1.0.1: integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== minimatch@^10.2.2: - version "10.2.5" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz" - integrity sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg== + version "10.2.6" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz" + integrity sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A== dependencies: - brace-expansion "^5.0.5" + brace-expansion "^5.0.8" minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + version "3.1.5" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz" + integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== dependencies: brace-expansion "^1.1.7" @@ -10342,10 +9861,10 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2, minipass@^7.1.3: + version "7.1.3" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz" + integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A== ml-array-max@^2.0.0: version "2.0.0" @@ -10385,9 +9904,9 @@ moment-timezone@^0.5.33: dependencies: moment "^2.29.4" -moment@^2.29.4, moment@^2.31.0: +moment@^2.29.4, moment@^2.31.0, "moment@>= 2.x": version "2.31.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.31.0.tgz#6e19184e8005a9dfc61c9351263d4d6ea2ace7aa" + resolved "https://registry.npmjs.org/moment/-/moment-2.31.0.tgz" integrity sha512-0acOTfMiWOheYS4eoWb80yYMb/JLvVv9SHbs2PehaDzfUG0Bw855SKyk0IKTnPGa5+U2bmi3W68l1+sGLX/pvw== mouse-event-offset@^3.0.2: @@ -10400,17 +9919,12 @@ mrmime@^2.0.0: resolved "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz" integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -msw@^2.10.4: +msw@^2.10.4, msw@^2.4.9: version "2.11.0" resolved "https://registry.npmjs.org/msw/-/msw-2.11.0.tgz" integrity sha512-jEqa5J5B1OMD1jHu0gasCb5YriIDiWGdoS22Ie8CNNrl1iGRzCVfok3zuerdfb7GNFeIbYePXDA5c2bwRKMpBA== @@ -10449,15 +9963,15 @@ nano-spawn@^2.0.0: resolved "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz" integrity sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw== -nanoid@^3.3.11: - version "3.3.11" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" - integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== +nanoid@^3.3.20: + version "3.3.20" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz" + integrity sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ== napi-postinstall@^0.3.4: - version "0.3.4" - resolved "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz" - integrity sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ== + version "0.3.7" + resolved "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.7.tgz" + integrity sha512-jyU4cU4kVAmy/3qjP+DcoQTNXfINHc+dFw54gGqWC8nu0mpV0kOnk7kff+J+Q18SbX0k3Np8Rm7yFjd3phatNQ== native-promise-only@^0.8.1: version "0.8.1" @@ -10503,10 +10017,10 @@ node-int64@^0.4.0: resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.55: - version "2.0.56" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.56.tgz#fff6a4093fe05d994a2a5e415eee5fcef874e6dc" - integrity sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A== +node-releases@^2.0.60: + version "2.0.61" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.61.tgz" + integrity sha512-5NUN6QCxNFrS9oEA9RPS+d0AP+ooGBzzovY2JhIpDRHacPvOhHjXjUsUMX9qp4nLHZ+5jVgXB2jj/P4arGOE/g== normalize-path@^3.0.0: version "3.0.0" @@ -10754,16 +10268,15 @@ parenthesis@^3.1.5: resolved "https://registry.npmjs.org/parenthesis/-/parenthesis-3.1.8.tgz" integrity sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw== -parse-asn1@^5.0.0, parse-asn1@^5.1.7: - version "5.1.7" - resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz" - integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg== +parse-asn1@^5.0.0, parse-asn1@^5.1.9: + version "5.1.10" + resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.10.tgz" + integrity sha512-gBlTKLbYnAJN9WjmawVOMfaGvVoy4lX0LH18t7ccwtEG9RgAa4ETf2eu3d2J4e/5SoCjCms0A0UF4tTw/Eyn6Q== dependencies: asn1.js "^4.10.1" browserify-aes "^1.2.0" evp_bytestokey "^1.0.3" - hash-base "~3.0" - pbkdf2 "^3.1.2" + pbkdf2 "^3.1.7" safe-buffer "^5.2.1" parse-json@^5.0.0, parse-json@^5.2.0: @@ -10853,6 +10366,14 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz" + integrity sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-to-regexp@^1.7.0: version "1.9.0" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz" @@ -10888,17 +10409,17 @@ pbf@^3.2.1, pbf@^3.3.0: ieee754 "^1.1.12" resolve-protobuf-schema "^2.1.0" -pbkdf2@^3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz" - integrity sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA== +pbkdf2@^3.1.2, pbkdf2@^3.1.7: + version "3.1.7" + resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.7.tgz" + integrity sha512-nS4mvFgVwUrecPTRdpdseM2fwpdfnX0/HibA8DgBRQtihUAzHQYJFU2l+OlEtiXtpqkrMvCPDwyXMUnASDt6Qw== dependencies: - create-hash "~1.1.3" + create-hash "^1.2.0" create-hmac "^1.1.7" - ripemd160 "=2.0.1" + ripemd160 "^2.0.3" safe-buffer "^5.2.1" - sha.js "^2.4.11" - to-buffer "^1.2.0" + sha.js "^2.4.12" + to-buffer "^1.2.2" pdfast@^0.2.0: version "0.2.0" @@ -10925,25 +10446,25 @@ pick-by-alias@^1.2.0: resolved "https://registry.npmjs.org/pick-by-alias/-/pick-by-alias-1.2.0.tgz" integrity sha512-ESj2+eBxhGrcA1azgHs7lARG5+5iLakc/6nlfbpjcLl00HuuUOIuORhYXN4D1HfvMSKuVtFQjAlnwi1JHEeDIw== -picocolors@1.1.1, picocolors@^1.0.0, picocolors@^1.1.1: +picocolors@^1.0.0, picocolors@^1.1.1, picocolors@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + version "2.3.2" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz" + integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA== -picomatch@^4.0.2: - version "4.0.3" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" - integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== +"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3, picomatch@^4.0.4: + version "4.0.7" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz" + integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA== -picomatch@^4.0.3, picomatch@^4.0.4: - version "4.0.4" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz" - integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== +picomatch@^4.0.2: + version "4.0.7" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz" + integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA== pidtree@^0.6.0: version "0.6.0" @@ -10962,10 +10483,10 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -plotly.js@^3.5.0: - version "3.5.1" - resolved "https://registry.npmjs.org/plotly.js/-/plotly.js-3.5.1.tgz" - integrity sha512-rUzQ7Q46whi1aWT2JlvKE2dnryNORPrxyy66OGSMXgejK3XgD4ysD9SapMOI1RzzUJyX0KbfVDFcB9/DqOyH9Q== +plotly.js@^3.5.0, plotly.js@>1.34.0: + version "3.7.0" + resolved "https://registry.npmjs.org/plotly.js/-/plotly.js-3.7.0.tgz" + integrity sha512-r17/w3Ob/E+A1vqN382PV/6Dz+IAxAsxNCpWcnGfGFLqE0M6vPUa+ve7HPhivrl9LMicZg2Fy0U5GbpauHo32A== dependencies: "@plotly/d3" "3.8.2" "@plotly/d3-sankey" "0.7.2" @@ -11051,10 +10572,10 @@ postcss-safe-parser@^7.0.1: resolved "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz" integrity sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A== -postcss-selector-parser@^7.1.0, postcss-selector-parser@^7.1.1: - version "7.1.5" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.5.tgz" - integrity sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw== +postcss-selector-parser@^7.0.0, postcss-selector-parser@^7.1.0, postcss-selector-parser@^7.1.1: + version "7.1.7" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.7.tgz" + integrity sha512-wWBro/7hJ40ye6TPiXkUQoXKCw23xSsjriUvqd7Uls9Sso3oLiON1flc18cCdnjgCRXw4fBVqUJJeOdDTh3P3g== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -11064,14 +10585,14 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.5.3, postcss@^8.5.6: - version "8.5.6" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz" - integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== +postcss@^8.4.31, postcss@^8.5.3, postcss@^8.5.6: + version "8.5.32" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz" + integrity sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g== dependencies: - nanoid "^3.3.11" + nanoid "^3.3.20" picocolors "^1.1.1" - source-map-js "^1.2.1" + source-map-js "^1.2.2" potpack@^1.0.1: version "1.0.2" @@ -11095,30 +10616,11 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^1.19.1: +prettier@^1.19.1, prettier@>=1.13.0: version "1.19.1" resolved "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== -pretty-format@30.0.5, pretty-format@^30.0.0: - version "30.0.5" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz" - integrity sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw== - dependencies: - "@jest/schemas" "30.0.5" - ansi-styles "^5.2.0" - react-is "^18.3.1" - -pretty-format@30.4.1: - version "30.4.1" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz" - integrity sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw== - dependencies: - "@jest/schemas" "30.4.1" - ansi-styles "^5.2.0" - react-is-18 "npm:react-is@^18.3.1" - react-is-19 "npm:react-is@^19.2.5" - pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz" @@ -11147,14 +10649,33 @@ pretty-format@^29.7.0: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-format@^30.0.0: + version "30.5.1" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz" + integrity sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg== + dependencies: + "@jest/react-is-18" "npm:react-is@^18.3.1" + "@jest/react-is-19" "npm:react-is@^19.2.5" + "@jest/schemas" "30.5.0" + ansi-styles "^5.2.0" + +pretty-format@30.5.1: + version "30.5.1" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz" + integrity sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg== + dependencies: + "@jest/react-is-18" "npm:react-is@^18.3.1" + "@jest/react-is-19" "npm:react-is@^19.2.5" + "@jest/schemas" "30.5.0" + ansi-styles "^5.2.0" + probe-image-size@^7.2.3: - version "7.3.0" - resolved "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.3.0.tgz" - integrity sha512-7CaDeBwiAbh6ohXsvLbAZhO7wzsZAmaevfxe39qvCwRh8LyaZfDlBGGLU1CCTgrTLtCOdwBBhjOrIHaIIimHfQ== + version "7.5.0" + resolved "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.5.0.tgz" + integrity sha512-ietdx4XPgmnzHRZOq1/KtcnsBkL4bRsBe+Szj5Tuq1/KPqDG42OspG1IhJb7vz6Z9pSzhp0J6UPnw6hujJTWoQ== dependencies: lodash.merge "^4.6.2" needle "^2.5.2" - stream-parser "~0.3.1" process-nextick-args@~2.0.0: version "2.0.1" @@ -11169,7 +10690,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -11708,9 +11229,9 @@ react-day-picker@^8.10.1: resolved "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz" integrity sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA== -react-dom@18.3.1, react-dom@^18.3.1: +react-dom@*, "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16 || ^17 || ^18", "react-dom@^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0", "react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^16.8.0 || 17.x || 18.x", "react-dom@^16.9.0 || ^17 || ^18", "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", react-dom@^18.0.0, "react-dom@^18.0.0 || ^19.0.0", "react-dom@^18.0.0 || ^19.1.0", "react-dom@^18.2.0 || ^19.0.0", react-dom@^18.3.1, "react-dom@^19.0.0 || ^18.0.0 || ^17.0.1 || ^16.7.0", "react-dom@>= 16.8.0", react-dom@>=15, react-dom@>=15.0.0, react-dom@>=16, react-dom@>=16.0.0, react-dom@>=16.11.0, react-dom@>=16.3.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=16.8.4, react-dom@>=16.9.0, react-dom@>=18.0.0, "react-dom@~15 || ~16 || ~17 || ~18": version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== dependencies: loose-envify "^1.1.0" @@ -11726,27 +11247,47 @@ react-icons@^4.12.0: resolved "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz" integrity sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw== -"react-is-18@npm:react-is@^18.3.1": - version "18.3.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" - integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^16.3.2: + version "16.13.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -"react-is-19@npm:react-is@^19.2.5": - version "19.2.6" - resolved "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz" - integrity sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw== +react-is@^16.6.0: + version "16.13.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0: +react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^17.0.1, react-is@^17.0.2: +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-is@^17.0.2: version "17.0.2" resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0, react-is@^18.2.0, react-is@^18.3.1: +react-is@^18.0.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +react-is@^18.2.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +react-is@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== @@ -11757,9 +11298,9 @@ react-is@^19.1.1: integrity sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA== react-is@^19.2.3: - version "19.3.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-19.3.0.tgz" - integrity sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA== + version "19.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-19.3.1.tgz" + integrity sha512-RRieF6IyxQBkcK6pP8xOHprLTPW6QjRkbGdImtqNme+/hYVwCZkLQLdlZGOhUqXwkS9IEynaGvPJtv6XB/cz0Q== react-leaflet-cluster@^3.1.0: version "3.1.1" @@ -11768,7 +11309,7 @@ react-leaflet-cluster@^3.1.0: dependencies: leaflet.markercluster "^1.5.3" -react-leaflet@4.2.1, react-leaflet@^4.0.0: +react-leaflet@^4.0.0, react-leaflet@4.2.1: version "4.2.1" resolved "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz" integrity sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q== @@ -11849,7 +11390,7 @@ react-property@2.0.0: resolved "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz" integrity sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw== -react-redux@^7.2.0: +react-redux@^7.2.0, "react-redux@^7.2.1 || ^8.1.3 || ^9.0.0": version "7.2.9" resolved "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz" integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ== @@ -11874,7 +11415,7 @@ react-refresh@^0.17.0: resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz" integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ== -react-router-dom@^5.2.0: +react-router-dom@^5.2.0, react-router-dom@>=4: version "5.3.4" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz" integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ== @@ -11894,7 +11435,7 @@ react-router-hash-link@^2.3.1: dependencies: prop-types "^15.7.2" -react-router@5.3.4, react-router@^5.3.4: +react-router@^5.3.4, react-router@5.3.4: version "5.3.4" resolved "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz" integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== @@ -12042,9 +11583,9 @@ react-window@^1.8.11: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@18.3.1, react@^18.3.1: +react@*, "react@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16 || ^17 || ^18", "react@^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0", "react@^16.3 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ~19", "react@^16.8.0 || 17.x || 18.x", "react@^16.8.3 || ^17 || ^18", "react@^16.8.3 || ^17.0.0-0 || ^18.0.0", "react@^16.9.0 || ^17 || ^18", "react@^16.9.0 || ^17.0.0 || ^18 || ^19", "react@^17.0.0 || ^18.0.0 || ^19.0.0", "react@^18.0 || ^19", react@^18.0.0, "react@^18.0.0 || ^19.0.0", "react@^18.0.0 || ^19.1.0", "react@^18.2.0 || ^19.0.0", react@^18.3.1, "react@^19.0.0 || ^18.0.0 || ^17.0.1 || ^16.7.0", "react@>= 16.8.0", react@>=0.14.0, react@>=15, react@>=15.0.0, react@>=16, react@>=16.0.0, react@>=16.11.0, react@>=16.3.0, react@>=16.3.2, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.8.4, react@>=16.9.0, react@>=18.0.0, react@>0.13.0, "react@~15 || ~16 || ~17 || ~18", "react@0.14 || 15 || 16 || 17 || 18", "react@0.14.x || ^15.0.0 || ^16.0.0 || ^17.0.0": version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== dependencies: loose-envify "^1.1.0" @@ -12074,16 +11615,6 @@ read-excel-file@^5.5.3: fflate "^0.7.3" unzipper "^0.12.2" -"readable-stream@>=1.0.33-1 <1.1.0-0": - version "1.0.34" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@^2.3.8, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" @@ -12106,6 +11637,16 @@ readable-stream@^3.5.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^4.0.1: version "4.1.2" resolved "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz" @@ -12185,14 +11726,14 @@ redux-thunk@^3.1.0: resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz" integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw== -redux@^4.0.0, redux@^4.0.5: +redux@*, redux@^4, redux@^4.0.0, redux@^4.0.5, redux@>3.0.0: version "4.2.1" resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz" integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== dependencies: "@babel/runtime" "^7.9.2" -redux@^5.0.1: +redux@^5.0.0, redux@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz" integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== @@ -12436,21 +11977,13 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -ripemd160@=2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz" - integrity sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w== - dependencies: - hash-base "^2.0.0" - inherits "^2.0.1" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz" + integrity sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA== dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" + hash-base "^3.1.2" + inherits "^2.0.4" robust-predicates@^3.0.2: version "3.0.2" @@ -12458,32 +11991,38 @@ robust-predicates@^3.0.2: integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== rollup@^4.34.9: - version "4.49.0" - resolved "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz" - integrity sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA== + version "4.66.0" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.66.0.tgz" + integrity sha512-Onq6/qO4ARhxIs+jYiHE0pYehadLyMECAiGEqQ+0/aWND3+2PmifJIIqBLYtuBODqHTlOUEQFtIVPyCy0Lck7A== dependencies: - "@types/estree" "1.0.8" + "@types/estree" "1.0.9" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.49.0" - "@rollup/rollup-android-arm64" "4.49.0" - "@rollup/rollup-darwin-arm64" "4.49.0" - "@rollup/rollup-darwin-x64" "4.49.0" - "@rollup/rollup-freebsd-arm64" "4.49.0" - "@rollup/rollup-freebsd-x64" "4.49.0" - "@rollup/rollup-linux-arm-gnueabihf" "4.49.0" - "@rollup/rollup-linux-arm-musleabihf" "4.49.0" - "@rollup/rollup-linux-arm64-gnu" "4.49.0" - "@rollup/rollup-linux-arm64-musl" "4.49.0" - "@rollup/rollup-linux-loongarch64-gnu" "4.49.0" - "@rollup/rollup-linux-ppc64-gnu" "4.49.0" - "@rollup/rollup-linux-riscv64-gnu" "4.49.0" - "@rollup/rollup-linux-riscv64-musl" "4.49.0" - "@rollup/rollup-linux-s390x-gnu" "4.49.0" - "@rollup/rollup-linux-x64-gnu" "4.49.0" - "@rollup/rollup-linux-x64-musl" "4.49.0" - "@rollup/rollup-win32-arm64-msvc" "4.49.0" - "@rollup/rollup-win32-ia32-msvc" "4.49.0" - "@rollup/rollup-win32-x64-msvc" "4.49.0" + "@napi-rs/lzma-linux-x64-gnu" "1.5.1" + "@rollup/rollup-android-arm-eabi" "4.66.0" + "@rollup/rollup-android-arm64" "4.66.0" + "@rollup/rollup-darwin-arm64" "4.66.0" + "@rollup/rollup-darwin-x64" "4.66.0" + "@rollup/rollup-freebsd-arm64" "4.66.0" + "@rollup/rollup-freebsd-x64" "4.66.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.66.0" + "@rollup/rollup-linux-arm-musleabihf" "4.66.0" + "@rollup/rollup-linux-arm64-gnu" "4.66.0" + "@rollup/rollup-linux-arm64-musl" "4.66.0" + "@rollup/rollup-linux-loong64-gnu" "4.66.0" + "@rollup/rollup-linux-loong64-musl" "4.66.0" + "@rollup/rollup-linux-ppc64-gnu" "4.66.0" + "@rollup/rollup-linux-ppc64-musl" "4.66.0" + "@rollup/rollup-linux-riscv64-gnu" "4.66.0" + "@rollup/rollup-linux-riscv64-musl" "4.66.0" + "@rollup/rollup-linux-s390x-gnu" "4.66.0" + "@rollup/rollup-linux-x64-gnu" "4.66.0" + "@rollup/rollup-linux-x64-musl" "4.66.0" + "@rollup/rollup-openbsd-x64" "4.66.0" + "@rollup/rollup-openharmony-arm64" "4.66.0" + "@rollup/rollup-win32-arm64-msvc" "4.66.0" + "@rollup/rollup-win32-ia32-msvc" "4.66.0" + "@rollup/rollup-win32-x64-gnu" "4.66.0" + "@rollup/rollup-win32-x64-msvc" "4.66.0" fsevents "~2.3.2" rrweb-cssom@^0.8.0: @@ -12498,7 +12037,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rw@1, rw@^1.3.3: +rw@^1.3.3, rw@1: version "1.3.3" resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== @@ -12519,7 +12058,12 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@~5.1.0: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -12553,7 +12097,7 @@ sass-loader@^16.0.5: dependencies: neo-async "^2.6.2" -sass@^1.86.3: +sass@*, sass@^1.3.0, sass@^1.86.3: version "1.91.0" resolved "https://registry.npmjs.org/sass/-/sass-1.91.0.tgz" integrity sha512-aFOZHGf+ur+bp1bCHZ+u8otKGh77ZtmFyXDo4tlYvT7PWql41Kwd8wdkPqhhT+h2879IVblcHFglIMofsFd1EA== @@ -12615,7 +12159,12 @@ semver@^5.5.0: resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.0, semver@^6.3.1: +semver@^6.3.0: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -12656,7 +12205,7 @@ set-proto@^1.0.0: es-errors "^1.3.0" es-object-atoms "^1.0.0" -sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: +sha.js@^2.4.0, sha.js@^2.4.12, sha.js@^2.4.8: version "2.4.12" resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz" integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== @@ -12749,7 +12298,12 @@ siginfo@^2.0.0: resolved "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz" integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== -signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -12802,18 +12356,10 @@ slice-ansi@^7.1.0: ansi-styles "^6.2.1" is-fullwidth-code-point "^5.0.0" -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.0, source-map-js@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" - integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" +source-map-js@^1.2.0, source-map-js@^1.2.1, source-map-js@^1.2.2, "source-map-js@>=0.6.2 <2.0.0": + version "1.2.2" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz" + integrity sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw== source-map-support@~0.5.20: version "0.5.21" @@ -12828,7 +12374,12 @@ source-map@^0.5.7: resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0, source-map@~0.6.1: +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -12900,13 +12451,6 @@ stream-browserify@^3.0.0: inherits "~2.0.4" readable-stream "^3.5.0" -stream-parser@~0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz" - integrity sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ== - dependencies: - debug "2" - stream-shift@^1.0.0: version "1.0.3" resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz" @@ -12917,6 +12461,18 @@ strict-event-emitter@^0.5.1: resolved "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz" integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== +string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + string-argv@^0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" @@ -12951,7 +12507,7 @@ string-split-by@^1.0.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12969,16 +12525,7 @@ string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string-width@^5.1.2: +string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -13072,18 +12619,6 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1, string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -13105,12 +12640,12 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.2.2" -strip-ansi@^7.1.0, strip-ansi@^7.1.2: +strip-ansi@^7.1.0: version "7.1.2" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== dependencies: - ansi-regex "^6.2.2" + ansi-regex "^6.0.1" strip-ansi@^7.1.2: version "7.2.0" @@ -13218,7 +12753,7 @@ stylelint-scss@^7.0.0: postcss-selector-parser "^7.1.1" postcss-value-parser "^4.2.0" -stylelint@^16.26.1: +"stylelint@^14.5.1 || ^15.0.0 || ^16.0.0 || ^17.0.0", stylelint@^16.23.0, stylelint@^16.26.1, "stylelint@^16.8.2 || ^17.0.0": version "16.26.1" resolved "https://registry.npmjs.org/stylelint/-/stylelint-16.26.1.tgz" integrity sha512-v20V59/crfc8sVTAtge0mdafI3AdnzQ2KsWe6v523L4OA1bJO02S7MO2oyXDCS6iWb9ckIPnqAFVItqSBQr7jw== @@ -13263,12 +12798,17 @@ stylelint@^16.26.1: table "^6.9.0" write-file-atomic "^5.0.1" +stylis@^4.3.4: + version "4.4.0" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz" + integrity sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA== + stylis@4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== -stylis@4.3.6, stylis@^4.3.4: +stylis@4.3.6: version "4.3.6" resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz" integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== @@ -13301,7 +12841,14 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0, supports-color@^8.1.1: +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.1.1: version "8.1.1" resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -13410,7 +12957,7 @@ terser-webpack-plugin@^5.5.0: schema-utils "^4.3.0" terser "^5.31.1" -terser@^5.31.1: +terser@^5.16.0, terser@^5.31.1: version "5.44.0" resolved "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz" integrity sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w== @@ -13509,7 +13056,7 @@ tinyglobby@^0.2.13, tinyglobby@^0.2.14, tinyglobby@^0.2.15: fdir "^6.5.0" picomatch "^4.0.4" -tinymce@^7.9.3: +tinymce@^7.9.3, "tinymce@^8.0.0 || ^7.0.0 || ^6.0.0 || ^5.5.1", tinymce@>=4.0.0: version "7.9.3" resolved "https://registry.npmjs.org/tinymce/-/tinymce-7.9.3.tgz" integrity sha512-Mtm54U5YJ6Pyo/GaAx+JSHXTGEuxrg2AowVWCD9zy1eBolp5Ub7S1rTtsyQdxhPegfhLuR3VLiTKGw1tacv09g== @@ -13535,9 +13082,9 @@ tinyrainbow@^2.0.0: integrity sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw== tinyspy@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz" - integrity sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q== + version "4.0.6" + resolved "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.6.tgz" + integrity sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg== tldts-core@^6.1.86: version "6.1.86" @@ -13556,10 +13103,10 @@ tmpl@1.0.5: resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-buffer@^1.2.0: - version "1.2.1" - resolved "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz" - integrity sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ== +to-buffer@^1.2.0, to-buffer@^1.2.1, to-buffer@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz" + integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== dependencies: isarray "^2.0.5" safe-buffer "^5.2.1" @@ -13764,7 +13311,7 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@^4.8.4: +typescript@^4.8.4, "typescript@>= 4.8.x", typescript@>=4.2.0, typescript@>=4.8.4, "typescript@>=4.8.4 <6.1.0", typescript@>=4.9.5: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -13795,9 +13342,9 @@ undici-types@~7.10.0: integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag== undici@^7.12.0: - version "7.30.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-7.30.0.tgz#64a947266eb7e21dbeac8b99f8720feef308bbe0" - integrity sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ== + version "7.30.1" + resolved "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz" + integrity sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" @@ -13853,7 +13400,7 @@ unquote@^1.1.0: resolved "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz" integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== -unrs-resolver@^1.7.11: +unrs-resolver@^1.12.1: version "1.12.2" resolved "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz" integrity sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ== @@ -13894,10 +13441,10 @@ unzipper@^0.12.2: graceful-fs "^4.2.2" node-int64 "^0.4.0" -update-browserslist-db@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz#197e21fb2561fa89f8b94fad605a2b296a18993a" - integrity sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ== +update-browserslist-db@^1.3.4: + version "1.3.4" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz" + integrity sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -14015,10 +13562,10 @@ vite-node@3.2.4: pathe "^2.0.3" vite "^5.0.0 || ^6.0.0 || ^7.0.0-0" -"vite@^5.0.0 || ^6.0.0 || ^7.0.0-0", vite@^6.4.3: - version "6.4.3" - resolved "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz" - integrity sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A== +"vite@^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vite@^5.0.0 || ^6.0.0 || ^7.0.0-0", vite@^6.4.3: + version "6.4.5" + resolved "https://registry.npmjs.org/vite/-/vite-6.4.5.tgz" + integrity sha512-4enwjFfi4IwtEh0w+jPzpLVOFQiPHmmzPxcHXQOyEur47o6u0jE573DmGpjA+7irXoMLYRZD5ZaFUEneS3abPg== dependencies: esbuild "^0.25.0" fdir "^6.4.4" @@ -14029,19 +13576,19 @@ vite-node@3.2.4: optionalDependencies: fsevents "~2.3.3" -vitest@^3.2.4: - version "3.2.4" - resolved "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz" - integrity sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A== +vitest@*, vitest@^3.2.4, vitest@3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz" + integrity sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg== dependencies: "@types/chai" "^5.2.2" - "@vitest/expect" "3.2.4" - "@vitest/mocker" "3.2.4" - "@vitest/pretty-format" "^3.2.4" - "@vitest/runner" "3.2.4" - "@vitest/snapshot" "3.2.4" - "@vitest/spy" "3.2.4" - "@vitest/utils" "3.2.4" + "@vitest/expect" "3.2.7" + "@vitest/mocker" "3.2.7" + "@vitest/pretty-format" "^3.2.7" + "@vitest/runner" "3.2.7" + "@vitest/snapshot" "3.2.7" + "@vitest/spy" "3.2.7" + "@vitest/utils" "3.2.7" chai "^5.2.0" debug "^4.4.1" expect-type "^1.2.1" @@ -14118,7 +13665,7 @@ webpack-sources@^3.5.0: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz" integrity sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ== -webpack@^5.104.1: +webpack@^5.0.0, webpack@^5.1.0, webpack@^5.104.1: version "5.107.2" resolved "https://registry.npmjs.org/webpack/-/webpack-5.107.2.tgz" integrity sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ== @@ -14220,7 +13767,14 @@ which-typed-array@^1.1.16, which-typed-array@^1.1.19, which-typed-array@^1.1.2: gopd "^1.2.0" has-tostringtag "^1.0.2" -which@^1.2.9, which@^1.3.1: +which@^1.2.9: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -14338,9 +13892,9 @@ write-file-atomic@^5.0.1: signal-exit "^4.0.1" ws@^8.18.0: - version "8.18.3" - resolved "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz" - integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== + version "8.22.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz" + integrity sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg== xlsx@^0.18.5: version "0.18.5" @@ -14372,16 +13926,16 @@ xmldoc@^2.0.1: dependencies: sax "^1.2.4" -"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - xtend@^2.1.2: version "2.2.0" resolved "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz" integrity sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw== +xtend@^4.0.0, "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" @@ -14393,14 +13947,14 @@ yallist@^3.0.2: integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + version "1.10.3" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz" + integrity sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA== -yaml@^2.8.1: - version "2.8.1" - resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz" - integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw== +yaml@^2.4.2, yaml@^2.8.1: + version "2.9.1" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz" + integrity sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw== yargs-parser@^21.1.1: version "21.1.1"