diff --git a/package-lock.json b/package-lock.json
index 73b8c7784f2..adf1b787a4e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4282,20 +4282,10 @@
"@octokit/openapi-types": "^27.0.0"
}
},
- "node_modules/@oxc-project/runtime": {
- "version": "0.115.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.115.0.tgz",
- "integrity": "sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
"node_modules/@oxc-project/types": {
- "version": "0.115.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.115.0.tgz",
- "integrity": "sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==",
+ "version": "0.122.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz",
+ "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -5001,12 +4991,58 @@
},
"node_modules/@radix-ui/rect": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
+ "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
+ "license": "MIT"
+ },
+ "node_modules/@reduxjs/toolkit": {
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz",
+ "integrity": "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "@standard-schema/utils": "^0.3.0",
+ "immer": "^11.0.0",
+ "redux": "^5.0.1",
+ "redux-thunk": "^3.1.0",
+ "reselect": "^5.1.0"
+ },
+ "peerDependencies": {
+ "react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
+ "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-redux": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@reduxjs/toolkit/node_modules/redux": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
+ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
+ "dev": true,
"license": "MIT"
},
+ "node_modules/@reduxjs/toolkit/node_modules/redux-thunk": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
+ "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "redux": "^5.0.0"
+ }
+ },
"node_modules/@rolldown/binding-android-arm64": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.9.tgz",
- "integrity": "sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.11.tgz",
+ "integrity": "sha512-SJ+/g+xNnOh6NqYxD0V3uVN4W3VfnrGsC9/hoglicgTNfABFG9JjISvkkU0dNY84MNHLWyOgxP9v9Y9pX4S7+A==",
"cpu": [
"arm64"
],
@@ -5021,9 +5057,9 @@
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.9.tgz",
- "integrity": "sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.11.tgz",
+ "integrity": "sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg==",
"cpu": [
"arm64"
],
@@ -5038,9 +5074,9 @@
}
},
"node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.9.tgz",
- "integrity": "sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.11.tgz",
+ "integrity": "sha512-39Ks6UvIHq4rEogIfQBoBRusj0Q0nPVWIvqmwBLaT6aqQGIakHdESBVOPRRLacy4WwUPIx4ZKzfZ9PMW+IeyUQ==",
"cpu": [
"x64"
],
@@ -5055,9 +5091,9 @@
}
},
"node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.9.tgz",
- "integrity": "sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.11.tgz",
+ "integrity": "sha512-jfsm0ZHfhiqrvWjJAmzsqiIFPz5e7mAoCOPBNTcNgkiid/LaFKiq92+0ojH+nmJmKYkre4t71BWXUZDNp7vsag==",
"cpu": [
"x64"
],
@@ -5072,9 +5108,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.9.tgz",
- "integrity": "sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.11.tgz",
+ "integrity": "sha512-zjQaUtSyq1nVe3nxmlSCuR96T1LPlpvmJ0SZy0WJFEsV4kFbXcq2u68L4E6O0XeFj4aex9bEauqjW8UQBeAvfQ==",
"cpu": [
"arm"
],
@@ -5089,9 +5125,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.9.tgz",
- "integrity": "sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.11.tgz",
+ "integrity": "sha512-WMW1yE6IOnehTcFE9eipFkm3XN63zypWlrJQ2iF7NrQ9b2LDRjumFoOGJE8RJJTJCTBAdmLMnJ8uVitACUUo1Q==",
"cpu": [
"arm64"
],
@@ -5106,9 +5142,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.9.tgz",
- "integrity": "sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.11.tgz",
+ "integrity": "sha512-jfndI9tsfm4APzjNt6QdBkYwre5lRPUgHeDHoI7ydKUuJvz3lZeCfMsI56BZj+7BYqiKsJm7cfd/6KYV7ubrBg==",
"cpu": [
"arm64"
],
@@ -5123,9 +5159,9 @@
}
},
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.9.tgz",
- "integrity": "sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.11.tgz",
+ "integrity": "sha512-ZlFgw46NOAGMgcdvdYwAGu2Q+SLFA9LzbJLW+iyMOJyhj5wk6P3KEE9Gct4xWwSzFoPI7JCdYmYMzVtlgQ+zfw==",
"cpu": [
"ppc64"
],
@@ -5140,9 +5176,9 @@
}
},
"node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.9.tgz",
- "integrity": "sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.11.tgz",
+ "integrity": "sha512-hIOYmuT6ofM4K04XAZd3OzMySEO4K0/nc9+jmNcxNAxRi6c5UWpqfw3KMFV4MVFWL+jQsSh+bGw2VqmaPMTLyw==",
"cpu": [
"s390x"
],
@@ -5157,9 +5193,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.9.tgz",
- "integrity": "sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.11.tgz",
+ "integrity": "sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==",
"cpu": [
"x64"
],
@@ -5174,9 +5210,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.9.tgz",
- "integrity": "sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.11.tgz",
+ "integrity": "sha512-/tpFfoSTzUkH9LPY+cYbqZBDyyX62w5fICq9qzsHLL8uTI6BHip3Q9Uzft0wylk/i8OOwKik8OxW+QAhDmzwmg==",
"cpu": [
"x64"
],
@@ -5191,9 +5227,9 @@
}
},
"node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.9.tgz",
- "integrity": "sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.11.tgz",
+ "integrity": "sha512-mcp3Rio2w72IvdZG0oQ4bM2c2oumtwHfUfKncUM6zGgz0KgPz4YmDPQfnXEiY5t3+KD/i8HG2rOB/LxdmieK2g==",
"cpu": [
"arm64"
],
@@ -5208,9 +5244,9 @@
}
},
"node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.9.tgz",
- "integrity": "sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.11.tgz",
+ "integrity": "sha512-LXk5Hii1Ph9asuGRjBuz8TUxdc1lWzB7nyfdoRgI0WGPZKmCxvlKk8KfYysqtr4MfGElu/f/pEQRh8fcEgkrWw==",
"cpu": [
"wasm32"
],
@@ -5225,9 +5261,9 @@
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.9.tgz",
- "integrity": "sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.11.tgz",
+ "integrity": "sha512-dDwf5otnx0XgRY1yqxOC4ITizcdzS/8cQ3goOWv3jFAo4F+xQYni+hnMuO6+LssHHdJW7+OCVL3CoU4ycnh35Q==",
"cpu": [
"arm64"
],
@@ -5242,9 +5278,9 @@
}
},
"node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.9.tgz",
- "integrity": "sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.11.tgz",
+ "integrity": "sha512-LN4/skhSggybX71ews7dAj6r2geaMJfm3kMbK2KhFMg9B10AZXnKoLCVVgzhMHL0S+aKtr4p8QbAW8k+w95bAA==",
"cpu": [
"x64"
],
@@ -5259,9 +5295,9 @@
}
},
"node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.9.tgz",
- "integrity": "sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.11.tgz",
+ "integrity": "sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==",
"dev": true,
"license": "MIT"
},
@@ -8165,9 +8201,14 @@
}
},
"node_modules/@standard-schema/spec": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
- "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@standard-schema/utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
"dev": true,
"license": "MIT"
},
@@ -10966,31 +11007,45 @@
"license": "BSD-3-Clause"
},
"node_modules/@webpack-cli/configtest": {
- "version": "1.2.0",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
+ "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
"dev": true,
"license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
"peerDependencies": {
- "webpack": "4.x.x || 5.x.x",
- "webpack-cli": "4.x.x"
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
}
},
"node_modules/@webpack-cli/info": {
- "version": "1.5.0",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "envinfo": "^7.7.3"
+ "engines": {
+ "node": ">=14.15.0"
},
"peerDependencies": {
- "webpack-cli": "4.x.x"
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
}
},
"node_modules/@webpack-cli/serve": {
- "version": "1.7.0",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
"dev": true,
"license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
"peerDependencies": {
- "webpack-cli": "4.x.x"
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
},
"peerDependenciesMeta": {
"webpack-dev-server": {
@@ -14640,11 +14695,6 @@
"node": ">=6"
}
},
- "node_modules/docdash": {
- "version": "1.2.0",
- "dev": true,
- "license": "Apache-2.0"
- },
"node_modules/doctrine": {
"version": "2.1.0",
"dev": true,
@@ -18617,6 +18667,17 @@
"version": "3.0.6",
"license": "MIT"
},
+ "node_modules/immer": {
+ "version": "11.1.4",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.4.tgz",
+ "integrity": "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/immer"
+ }
+ },
"node_modules/immutable": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.3.tgz",
@@ -19054,6 +19115,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/intl": {
"version": "1.2.5",
"license": "MIT"
@@ -30291,14 +30362,16 @@
}
},
"node_modules/rechoir": {
- "version": "0.7.1",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "resolve": "^1.9.0"
+ "resolve": "^1.20.0"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/redent": {
@@ -30667,6 +30740,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/reselect": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/reserved-identifiers": {
"version": "1.2.0",
"dev": true,
@@ -30872,14 +30952,14 @@
}
},
"node_modules/rolldown": {
- "version": "1.0.0-rc.9",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.9.tgz",
- "integrity": "sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==",
+ "version": "1.0.0-rc.11",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.11.tgz",
+ "integrity": "sha512-NRjoKMusSjfRbSYiH3VSumlkgFe7kYAa3pzVOsVYVFY3zb5d7nS+a3KGQ7hJKXuYWbzJKPVQ9Wxq2UvyK+ENpw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/types": "=0.115.0",
- "@rolldown/pluginutils": "1.0.0-rc.9"
+ "@oxc-project/types": "=0.122.0",
+ "@rolldown/pluginutils": "1.0.0-rc.11"
},
"bin": {
"rolldown": "bin/cli.mjs"
@@ -30888,21 +30968,21 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.0.0-rc.9",
- "@rolldown/binding-darwin-arm64": "1.0.0-rc.9",
- "@rolldown/binding-darwin-x64": "1.0.0-rc.9",
- "@rolldown/binding-freebsd-x64": "1.0.0-rc.9",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.9",
- "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.9",
- "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.9",
- "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.9",
- "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.9",
- "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.9",
- "@rolldown/binding-linux-x64-musl": "1.0.0-rc.9",
- "@rolldown/binding-openharmony-arm64": "1.0.0-rc.9",
- "@rolldown/binding-wasm32-wasi": "1.0.0-rc.9",
- "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.9",
- "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.9"
+ "@rolldown/binding-android-arm64": "1.0.0-rc.11",
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.11",
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.11",
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.11",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.11",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.11",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.11",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.11",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.11",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.11",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.11",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.11",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.11",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.11",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.11"
}
},
"node_modules/rrweb-cssom": {
@@ -35596,17 +35676,16 @@
"license": "MIT"
},
"node_modules/vite": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.0.tgz",
- "integrity": "sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.2.tgz",
+ "integrity": "sha512-1gFhNi+bHhRE/qKZOJXACm6tX4bA3Isy9KuKF15AgSRuRazNBOJfdDemPBU16/mpMxApDPrWvZ08DcLPEoRnuA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/runtime": "0.115.0",
"lightningcss": "^1.32.0",
"picomatch": "^4.0.3",
"postcss": "^8.5.8",
- "rolldown": "1.0.0-rc.9",
+ "rolldown": "1.0.0-rc.11",
"tinyglobby": "^0.2.15"
},
"bin": {
@@ -35623,7 +35702,7 @@
},
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
- "@vitejs/devtools": "^0.0.0-alpha.31",
+ "@vitejs/devtools": "^0.1.0",
"esbuild": "^0.27.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
@@ -35766,15 +35845,22 @@
},
"node_modules/vlq": {
"version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
+ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==",
"license": "MIT"
},
"node_modules/vscode-uri": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
"dev": true,
"license": "MIT"
},
"node_modules/w3c-hr-time": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -35783,6 +35869,8 @@
},
"node_modules/w3c-xmlserializer": {
"version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
+ "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -35803,6 +35891,8 @@
},
"node_modules/walker": {
"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": {
@@ -35811,6 +35901,8 @@
},
"node_modules/warning": {
"version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.0.0"
@@ -35818,6 +35910,8 @@
},
"node_modules/watchpack": {
"version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz",
+ "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==",
"license": "MIT",
"dependencies": {
"glob-to-regexp": "^0.4.1",
@@ -35829,10 +35923,14 @@
},
"node_modules/wav-encoder": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/wav-encoder/-/wav-encoder-1.3.0.tgz",
+ "integrity": "sha512-FXJdEu2qDOI+wbVYZpu21CS1vPEg5NaxNskBr4SaULpOJMrLE6xkH8dECa7PiS+ZoeyvP7GllWUAxPN3AvFSEw==",
"license": "MIT"
},
"node_modules/wbuf": {
"version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -35841,11 +35939,15 @@
},
"node_modules/web-audio-test-api": {
"version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/web-audio-test-api/-/web-audio-test-api-0.5.2.tgz",
+ "integrity": "sha512-RevLfVjp+wwe/dBPe361IpmNpeXXW6JVmlp8dk0YIxLwAh7evn6JpEQQalVgX4PH/jA8tpLpjD/8tFNUYTf88w==",
"dev": true,
"license": "MIT"
},
"node_modules/webidl-conversions": {
"version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
"dev": true,
"license": "BSD-2-Clause"
},
@@ -35897,43 +35999,43 @@
}
},
"node_modules/webpack-cli": {
- "version": "4.10.0",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^1.2.0",
- "@webpack-cli/info": "^1.5.0",
- "@webpack-cli/serve": "^1.7.0",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
"colorette": "^2.0.14",
- "commander": "^7.0.0",
+ "commander": "^10.0.1",
"cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2",
- "interpret": "^2.2.0",
- "rechoir": "^0.7.0",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
"webpack-merge": "^5.7.3"
},
"bin": {
"webpack-cli": "bin/cli.js"
},
"engines": {
- "node": ">=10.13.0"
+ "node": ">=14.15.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "4.x.x || 5.x.x"
+ "webpack": "5.x.x"
},
"peerDependenciesMeta": {
"@webpack-cli/generators": {
"optional": true
},
- "@webpack-cli/migrate": {
- "optional": true
- },
"webpack-bundle-analyzer": {
"optional": true
},
@@ -35943,23 +36045,19 @@
}
},
"node_modules/webpack-cli/node_modules/commander": {
- "version": "7.2.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/webpack-cli/node_modules/interpret": {
- "version": "2.2.0",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.10"
+ "node": ">=14"
}
},
"node_modules/webpack-dev-middleware": {
"version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz",
+ "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -35988,6 +36086,8 @@
},
"node_modules/webpack-dev-middleware/node_modules/mime-db": {
"version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -35995,22 +36095,22 @@
}
},
"node_modules/webpack-dev-middleware/node_modules/mime-types": {
- "version": "3.0.2",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
+ "node": ">= 0.6"
}
},
"node_modules/webpack-dev-server": {
"version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz",
+ "integrity": "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36066,7 +36166,9 @@
}
},
"node_modules/webpack-dev-server/node_modules/ws": {
- "version": "8.18.3",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -36087,6 +36189,8 @@
},
"node_modules/webpack-merge": {
"version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+ "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36100,6 +36204,8 @@
},
"node_modules/webpack-node-externals": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz",
+ "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -36108,6 +36214,8 @@
},
"node_modules/webpack-sources": {
"version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
"license": "MIT",
"dependencies": {
"source-list-map": "^2.0.0",
@@ -36116,6 +36224,8 @@
},
"node_modules/webpack-virtual-modules": {
"version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"dev": true,
"license": "MIT"
},
@@ -36161,6 +36271,8 @@
},
"node_modules/websocket-driver": {
"version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -36174,6 +36286,8 @@
},
"node_modules/websocket-extensions": {
"version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -36182,6 +36296,8 @@
},
"node_modules/whatwg-encoding": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
@@ -36192,6 +36308,8 @@
},
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -36199,6 +36317,8 @@
},
"node_modules/whatwg-url": {
"version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36209,6 +36329,8 @@
},
"node_modules/which": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -36223,6 +36345,8 @@
},
"node_modules/which-boxed-primitive": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36241,6 +36365,8 @@
},
"node_modules/which-builtin-type": {
"version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36267,6 +36393,8 @@
},
"node_modules/which-collection": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36284,6 +36412,8 @@
},
"node_modules/which-typed-array": {
"version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36374,13 +36504,13 @@
}
},
"node_modules/widest-line/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==",
+ "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.2.2"
+ "ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
@@ -36391,11 +36521,15 @@
},
"node_modules/wildcard": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
"dev": true,
"license": "MIT"
},
"node_modules/word-wrap": {
"version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -36403,20 +36537,24 @@
},
"node_modules/wordwrap": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi": {
- "version": "9.0.2",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "ansi-styles": "^6.2.1",
- "string-width": "^7.0.0",
- "strip-ansi": "^7.1.0"
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
},
"engines": {
- "node": ">=18"
+ "node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
@@ -36500,10 +36638,14 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
"node_modules/write": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36515,6 +36657,8 @@
},
"node_modules/write-file-atomic": {
"version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -36527,6 +36671,8 @@
},
"node_modules/write/node_modules/mkdirp": {
"version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36538,6 +36684,8 @@
},
"node_modules/ws": {
"version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
+ "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36546,6 +36694,8 @@
},
"node_modules/wsl-utils": {
"version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36560,6 +36710,8 @@
},
"node_modules/xhr": {
"version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz",
+ "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==",
"license": "MIT",
"dependencies": {
"global": "~4.4.0",
@@ -36570,16 +36722,22 @@
},
"node_modules/xml": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
+ "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
"dev": true,
"license": "MIT"
},
"node_modules/xml-name-validator": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/xml2js": {
"version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+ "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36592,6 +36750,8 @@
},
"node_modules/xmlbuilder": {
"version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -36600,10 +36760,14 @@
},
"node_modules/xmlchars": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"license": "MIT"
},
"node_modules/xtend": {
"version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
@@ -36611,6 +36775,8 @@
},
"node_modules/y18n": {
"version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"license": "ISC",
"engines": {
"node": ">=10"
@@ -36618,6 +36784,8 @@
},
"node_modules/yallist": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC"
},
"node_modules/yaml": {
@@ -36631,9 +36799,6 @@
},
"engines": {
"node": ">= 14.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/yaml-types": {
@@ -36652,6 +36817,8 @@
},
"node_modules/yargs": {
"version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -36669,6 +36836,8 @@
},
"node_modules/yargs-parser": {
"version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"license": "ISC",
"engines": {
"node": ">=10"
@@ -36676,6 +36845,8 @@
},
"node_modules/yargs/node_modules/yargs-parser": {
"version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -36698,6 +36869,8 @@
},
"node_modules/yn": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -36706,6 +36879,8 @@
},
"node_modules/yocto-queue": {
"version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"license": "MIT",
"engines": {
"node": ">=10"
@@ -36716,6 +36891,8 @@
},
"node_modules/yoctocolors": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz",
+ "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
"dev": true,
"license": "MIT",
"engines": {
@@ -36733,7 +36910,9 @@
"license": "MIT"
},
"node_modules/zod": {
- "version": "4.1.13",
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
+ "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -36742,6 +36921,8 @@
},
"node_modules/zod-validation-error": {
"version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
+ "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -36753,6 +36934,8 @@
},
"node_modules/zwitch": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
"dev": true,
"license": "MIT",
"funding": {
@@ -36841,6 +37024,7 @@
"@babel/preset-env": "7.29.3",
"@babel/preset-react": "7.28.5",
"@playwright/test": "1.59.1",
+ "@reduxjs/toolkit": "^2.11.2",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "14.3.1",
"@types/jest": "25.2.3",
@@ -36894,116 +37078,21 @@
"integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q==",
"extraneous": true
},
- "packages/scratch-gui/node_modules/@webpack-cli/configtest": {
- "version": "2.1.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- }
- },
- "packages/scratch-gui/node_modules/@webpack-cli/info": {
- "version": "2.0.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- }
- },
- "packages/scratch-gui/node_modules/@webpack-cli/serve": {
- "version": "2.0.5",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- },
- "peerDependenciesMeta": {
- "webpack-dev-server": {
- "optional": true
- }
- }
- },
- "packages/scratch-gui/node_modules/commander": {
- "version": "10.0.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- }
- },
- "packages/scratch-gui/node_modules/interpret": {
- "version": "3.1.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "packages/scratch-gui/node_modules/rechoir": {
- "version": "0.8.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve": "^1.20.0"
- },
- "engines": {
- "node": ">= 10.13.0"
- }
- },
- "packages/scratch-gui/node_modules/webpack-cli": {
- "version": "5.1.4",
- "dev": true,
- "license": "MIT",
+ "packages/scratch-gui/node_modules/@scratch/scratch-vm/node_modules/scratch-storage": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-6.1.3.tgz",
+ "integrity": "sha512-xoUIB7/MNF2864lz6mfwGxKwlp7LdpvM4k+amzp3RwtYlQIjca9t/U8dngKKS0zEz4Fc1fuykYRqRPchVnE+Fg==",
+ "extraneous": true,
+ "license": "AGPL-3.0-only",
"dependencies": {
- "@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.1.1",
- "@webpack-cli/info": "^2.0.2",
- "@webpack-cli/serve": "^2.0.5",
- "colorette": "^2.0.14",
- "commander": "^10.0.1",
- "cross-spawn": "^7.0.3",
- "envinfo": "^7.7.3",
- "fastest-levenshtein": "^1.0.12",
- "import-local": "^3.0.2",
- "interpret": "^3.1.1",
- "rechoir": "^0.8.0",
- "webpack-merge": "^5.7.3"
- },
- "bin": {
- "webpack-cli": "bin/cli.js"
- },
- "engines": {
- "node": ">=14.15.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- },
- "peerDependencies": {
- "webpack": "5.x.x"
- },
- "peerDependenciesMeta": {
- "@webpack-cli/generators": {
- "optional": true
- },
- "webpack-bundle-analyzer": {
- "optional": true
- },
- "webpack-dev-server": {
- "optional": true
- }
+ "@babel/runtime": "^7.21.0",
+ "@scratch/task-herder": "12.6.0",
+ "arraybuffer-loader": "^1.0.3",
+ "base64-js": "^1.3.0",
+ "buffer": "6.0.3",
+ "fastestsmallesttextencoderdecoder": "^1.0.7",
+ "js-md5": "^0.7.3",
+ "minilog": "^3.1.0"
}
},
"packages/scratch-media-lib-scripts": {
@@ -38462,18 +38551,9 @@
}
},
"packages/scratch-render/node_modules/raw-loader": {
- "version": "0.5.1"
- },
- "packages/scratch-render/node_modules/rechoir": {
- "version": "0.8.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve": "^1.20.0"
- },
- "engines": {
- "node": ">= 10.13.0"
- }
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
+ "integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q=="
},
"packages/scratch-render/node_modules/webpack-cli": {
"version": "5.1.4",
@@ -38565,47 +38645,6 @@
"scratch-render-fonts": "1.0.252"
}
},
- "packages/scratch-svg-renderer/node_modules/@webpack-cli/configtest": {
- "version": "2.1.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- }
- },
- "packages/scratch-svg-renderer/node_modules/@webpack-cli/info": {
- "version": "2.0.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- }
- },
- "packages/scratch-svg-renderer/node_modules/@webpack-cli/serve": {
- "version": "2.0.5",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- },
- "peerDependenciesMeta": {
- "webpack-dev-server": {
- "optional": true
- }
- }
- },
"packages/scratch-svg-renderer/node_modules/canvas": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.3.tgz",
@@ -38621,24 +38660,10 @@
"node": "^18.12.0 || >= 20.9.0"
}
},
- "packages/scratch-svg-renderer/node_modules/commander": {
- "version": "10.0.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- }
- },
- "packages/scratch-svg-renderer/node_modules/interpret": {
- "version": "3.1.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10.13.0"
- }
- },
"packages/scratch-svg-renderer/node_modules/mkdirp": {
"version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
+ "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==",
"dev": true,
"license": "MIT",
"bin": {
@@ -38651,19 +38676,11 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "packages/scratch-svg-renderer/node_modules/rechoir": {
- "version": "0.8.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve": "^1.20.0"
- },
- "engines": {
- "node": ">= 10.13.0"
- }
- },
"packages/scratch-svg-renderer/node_modules/rimraf": {
"version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -38676,50 +38693,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "packages/scratch-svg-renderer/node_modules/webpack-cli": {
- "version": "5.1.4",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.1.1",
- "@webpack-cli/info": "^2.0.2",
- "@webpack-cli/serve": "^2.0.5",
- "colorette": "^2.0.14",
- "commander": "^10.0.1",
- "cross-spawn": "^7.0.3",
- "envinfo": "^7.7.3",
- "fastest-levenshtein": "^1.0.12",
- "import-local": "^3.0.2",
- "interpret": "^3.1.1",
- "rechoir": "^0.8.0",
- "webpack-merge": "^5.7.3"
- },
- "bin": {
- "webpack-cli": "bin/cli.js"
- },
- "engines": {
- "node": ">=14.15.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- },
- "peerDependencies": {
- "webpack": "5.x.x"
- },
- "peerDependenciesMeta": {
- "@webpack-cli/generators": {
- "optional": true
- },
- "webpack-bundle-analyzer": {
- "optional": true
- },
- "webpack-dev-server": {
- "optional": true
- }
- }
- },
"packages/scratch-vm": {
"name": "@scratch/scratch-vm",
"version": "13.7.2",
@@ -38780,6 +38753,62 @@
"webpack-dev-server": "5.2.3"
}
},
+ "packages/scratch-vm/node_modules/@webpack-cli/configtest": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
+ "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "webpack": "4.x.x || 5.x.x",
+ "webpack-cli": "4.x.x"
+ }
+ },
+ "packages/scratch-vm/node_modules/@webpack-cli/info": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
+ "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "envinfo": "^7.7.3"
+ },
+ "peerDependencies": {
+ "webpack-cli": "4.x.x"
+ }
+ },
+ "packages/scratch-vm/node_modules/@webpack-cli/serve": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
+ "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "webpack-cli": "4.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "packages/scratch-vm/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "packages/scratch-vm/node_modules/docdash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/docdash/-/docdash-1.2.0.tgz",
+ "integrity": "sha512-IYZbgYthPTspgqYeciRJNPhSwL51yer7HAwDXhF5p+H7mTDbPvY3PCk/QDjNxdPCpWkaJVFC4t7iCNB/t9E5Kw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
"packages/scratch-vm/node_modules/dom-serializer": {
"version": "0.2.2",
"license": "MIT",
@@ -38840,6 +38869,16 @@
"readable-stream": "^3.1.1"
}
},
+ "packages/scratch-vm/node_modules/interpret": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
+ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"packages/scratch-vm/node_modules/readable-stream": {
"version": "3.6.2",
"license": "MIT",
@@ -38852,6 +38891,67 @@
"node": ">= 6"
}
},
+ "packages/scratch-vm/node_modules/rechoir": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
+ "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve": "^1.9.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "packages/scratch-vm/node_modules/webpack-cli": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
+ "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^1.2.0",
+ "@webpack-cli/info": "^1.5.0",
+ "@webpack-cli/serve": "^1.7.0",
+ "colorette": "^2.0.14",
+ "commander": "^7.0.0",
+ "cross-spawn": "^7.0.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^2.2.0",
+ "rechoir": "^0.7.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "4.x.x || 5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "@webpack-cli/migrate": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
"packages/task-herder": {
"name": "@scratch/task-herder",
"version": "13.7.2",
@@ -39106,31 +39206,14 @@
"dev": true,
"license": "MIT"
},
- "packages/task-herder/node_modules/balanced-match": {
- "version": "4.0.3",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "packages/task-herder/node_modules/brace-expansion": {
- "version": "5.0.2",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^4.0.2"
- },
- "engines": {
- "node": "20 || >=22"
- }
- },
"packages/task-herder/node_modules/glob": {
- "version": "13.0.5",
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
+ "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "minimatch": "^10.2.1",
+ "minimatch": "^10.1.1",
"minipass": "^7.1.2",
"path-scurry": "^2.0.0"
},
@@ -39141,12 +39224,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "packages/task-herder/node_modules/minimatch": {
- "version": "10.2.1",
+ "packages/task-herder/node_modules/glob/node_modules/minimatch": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
+ "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^5.0.2"
+ "@isaacs/brace-expansion": "^5.0.0"
},
"engines": {
"node": "20 || >=22"
@@ -39157,6 +39242,8 @@
},
"packages/task-herder/node_modules/minipass": {
"version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -39165,6 +39252,8 @@
},
"packages/task-herder/node_modules/rimraf": {
"version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz",
+ "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
diff --git a/packages/scratch-gui/package.json b/packages/scratch-gui/package.json
index 7b085c07ebb..34476456f35 100644
--- a/packages/scratch-gui/package.json
+++ b/packages/scratch-gui/package.json
@@ -198,6 +198,7 @@
"@babel/core": "7.29.0",
"@babel/preset-env": "7.29.3",
"@babel/preset-react": "7.28.5",
+ "@reduxjs/toolkit": "^2.11.2",
"@playwright/test": "1.59.1",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "14.3.1",
diff --git a/packages/scratch-gui/src/components/action-menu/action-menu.css b/packages/scratch-gui/src/components/action-menu/action-menu.css
index 3c9bfa0ddff..ce2fc087558 100644
--- a/packages/scratch-gui/src/components/action-menu/action-menu.css
+++ b/packages/scratch-gui/src/components/action-menu/action-menu.css
@@ -29,7 +29,8 @@ button::-moz-focus-inner {
border: 0;
}
-.button:hover {
+.button:hover,
+.button:focus {
background: $extensions-primary;
}
diff --git a/packages/scratch-gui/src/components/action-menu/action-menu.jsx b/packages/scratch-gui/src/components/action-menu/action-menu.jsx
index a09fd906819..97996e4cbac 100644
--- a/packages/scratch-gui/src/components/action-menu/action-menu.jsx
+++ b/packages/scratch-gui/src/components/action-menu/action-menu.jsx
@@ -1,152 +1,217 @@
+import React, {useState, useRef, useEffect, useCallback} from 'react';
import PropTypes from 'prop-types';
-import React from 'react';
import classNames from 'classnames';
-import bindAll from 'lodash.bindall';
import ReactTooltip from 'react-tooltip';
-
import styles from './action-menu.css';
+import {KEY} from '../../lib/navigation-keys';
const CLOSE_DELAY = 300; // ms
-class ActionMenu extends React.Component {
- constructor (props) {
- super(props);
- bindAll(this, [
- 'clickDelayer',
- 'handleClosePopover',
- 'handleToggleOpenState',
- 'handleTouchStart',
- 'handleTouchOutside',
- 'setButtonRef',
- 'setContainerRef'
- ]);
- this.state = {
- isOpen: false,
- forceHide: false
- };
- this.mainTooltipId = `tooltip-${Math.random()}`;
- }
- componentDidMount () {
- // Touch start on the main button is caught to trigger open and not click
- this.buttonRef.addEventListener('touchstart', this.handleTouchStart);
- // Touch start on document is used to trigger close if it is outside
- document.addEventListener('touchstart', this.handleTouchOutside);
- }
- shouldComponentUpdate (newProps, newState) {
- // This check prevents re-rendering while the project is updating.
- // @todo check only the state and the title because it is enough to know
- // if anything substantial has changed
- // This is needed because of the sloppy way the props are passed as a new object,
- // which should be refactored.
- return newState.isOpen !== this.state.isOpen ||
- newState.forceHide !== this.state.forceHide ||
- newProps.title !== this.props.title;
- }
- componentWillUnmount () {
- this.buttonRef.removeEventListener('touchstart', this.handleTouchStart);
- document.removeEventListener('touchstart', this.handleTouchOutside);
- }
- handleClosePopover () {
- this.closeTimeoutId = setTimeout(() => {
- this.setState({isOpen: false});
- this.closeTimeoutId = null;
- }, CLOSE_DELAY);
- }
- handleToggleOpenState () {
+const ActionMenu = ({
+ className,
+ img: mainImg,
+ title: mainTitle,
+ moreButtons,
+ tooltipPlace,
+ onClick
+}) => {
+ const [forceHide, setForceHide] = useState(false);
+ const [isExpanded, setIsExpanded] = useState(false);
+
+ const closeTimeoutRef = useRef(null);
+ const mainTooltipId = useRef(`tooltip-${Math.random()}`).current;
+ // refs to handle custom keyboard navigation behavior
+ const containerRef = useRef(null);
+ const buttonRef = useRef(null);
+ const itemRefs = useRef([]);
+
+ const focusItem = useCallback(item => {
+ if (item) {
+ item.focus();
+ }
+ }, []);
+
+ const refocusActiveElement = useCallback(() => {
+ setTimeout(() => {
+ const focusedElement = document.activeElement;
+ focusedElement.blur();
+ focusItem(focusedElement);
+ }, 500);
+ // wait enough time for rerenders to happen on the page
+ // that may lose the focus on the page, forcing us to rerender tooltip
+ }, [focusItem]);
+
+ // Restore focus after expanding (e.g., returning from a modal).
+ useEffect(() => {
+ if (isExpanded) {
+ refocusActiveElement();
+ }
+ }, [isExpanded]);
+
+ const handleToggleOpenState = useCallback(() => {
// Mouse enter back in after timeout was started prevents it from closing.
- if (this.closeTimeoutId) {
- clearTimeout(this.closeTimeoutId);
- this.closeTimeoutId = null;
- } else if (!this.state.isOpen) {
- this.setState({
- isOpen: true,
- forceHide: false
- });
+ if (closeTimeoutRef.current) {
+ clearTimeout(closeTimeoutRef.current);
+ closeTimeoutRef.current = null;
+ } else if (!isExpanded) {
+ setIsExpanded(true);
+ setForceHide(false);
}
- }
- handleTouchOutside (e) {
- if (this.state.isOpen && !this.containerRef.contains(e.target)) {
- this.setState({isOpen: false});
- ReactTooltip.hide();
+ }, [isExpanded]);
+
+ const handleTouchStart = useCallback(e => {
+ // Prevent this touch from becoming a click if menu is closed
+ if (!isExpanded) {
+ e.preventDefault();
+ handleToggleOpenState();
}
- }
- clickDelayer (fn) {
- // Return a wrapped action that manages the menu closing.
- // @todo we may be able to use react-transition for this in the future
- // for now all this work is to ensure the menu closes BEFORE the
- // (possibly slow) action is started.
- return event => {
- ReactTooltip.hide();
- if (fn) fn(event);
- // Blur the button so it does not keep focus after being clicked
- // This prevents keyboard events from triggering the button
- this.buttonRef.blur();
- this.setState({forceHide: true, isOpen: false}, () => {
- setTimeout(() => this.setState({forceHide: false}));
- });
+ }, [isExpanded, handleToggleOpenState]);
+
+ // Use native `touchstart` so the first tap opens the menu
+ // instead of triggering the button's click on touch devices.
+ useEffect(() => {
+ const buttonEl = buttonRef.current;
+ if (!buttonEl) return;
+
+ buttonEl.addEventListener('touchstart', handleTouchStart);
+ return () => {
+ buttonEl.removeEventListener('touchstart', handleTouchStart);
};
- }
- handleTouchStart (e) {
- // Prevent this touch from becoming a click if menu is closed
- if (!this.state.isOpen) {
+ }, [handleTouchStart]);
+
+ // Close the menu when clicking outside
+ useEffect(() => {
+ const handleTouchOutside = e => {
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
+ setIsExpanded(false);
+ ReactTooltip.hide();
+ }
+ };
+
+ document.addEventListener('mousedown', handleTouchOutside);
+ return () => {
+ document.removeEventListener('mousedown', handleTouchOutside);
+ };
+ }, [containerRef, setIsExpanded]);
+
+ const handleMove = useCallback(direction => {
+ const items = itemRefs.current;
+ if (!items.length) return;
+
+ if (!items.includes(document.activeElement)) {
+ focusItem(direction === 1 ? items[0] : items[items.length - 1]);
+ return;
+ }
+
+ const currentIndex = items.indexOf(document.activeElement);
+ const nextIndex = (currentIndex + direction + items.length) % items.length;
+ focusItem(items[nextIndex]);
+ }, [itemRefs, focusItem]);
+
+ const handleClosePopover = useCallback(() => {
+ closeTimeoutRef.current = setTimeout(() => {
+ setIsExpanded(false);
+ closeTimeoutRef.current = null;
+ }, CLOSE_DELAY);
+ }, []);
+
+ const handleKeyDown = useCallback(e => {
+ if (e.key === KEY.ARROW_DOWN || e.key === KEY.ARROW_UP) {
+ const direction = e.key === KEY.ARROW_UP ? -1 : 1;
e.preventDefault();
- this.handleToggleOpenState();
+ if (isExpanded) {
+ handleMove(direction);
+ } else {
+ setIsExpanded(true);
+ // wait to expand before moving focus to menu item and displaying tooltip
+ setTimeout(() => {
+ handleMove(direction);
+ }, CLOSE_DELAY);
+ }
+ } else if (e.key === KEY.TAB) {
+ setIsExpanded(false);
+ focusItem(buttonRef.current);
+ } else if (e.key === KEY.ESCAPE) {
+ focusItem(buttonRef.current);
}
- }
- setButtonRef (ref) {
- this.buttonRef = ref;
- }
- setContainerRef (ref) {
- this.containerRef = ref;
- }
- render () {
- const {
- className,
- img: mainImg,
- title: mainTitle,
- moreButtons,
- tooltipPlace,
- onClick
- } = this.props;
-
- return (
-
() => {
+ const items = itemRefs.current;
+ const currentFocusedIndex = items.indexOf(document.activeElement);
+ if (currentFocusedIndex === index) return;
+
+ if (items[currentFocusedIndex]) {
+ items[currentFocusedIndex].blur();
+ }
+ if (items[index]) {
+ focusItem(items[index]);
+ } else {
+ // Not a menu item, so it must be the main button
+ focusItem(buttonRef.current);
+ }
+ }, [focusItem]);
+
+ const handleItemClick = useCallback(onClickItem => e => {
+ onClickItem(e);
+ refocusActiveElement();
+ }, []);
+
+ return (
+
+
+ );
+};
ActionMenu.propTypes = {
className: PropTypes.string,
img: PropTypes.string,
- moreButtons: PropTypes.arrayOf(PropTypes.shape({
- img: PropTypes.string,
- title: PropTypes.node.isRequired,
- onClick: PropTypes.func, // Optional, "coming soon" if no callback provided
- fileAccept: PropTypes.string, // Optional, only for file upload
- fileChange: PropTypes.func, // Optional, only for file upload
- fileInput: PropTypes.func, // Optional, only for file upload
- fileMultiple: PropTypes.bool // Optional, only for file upload
- })),
+ moreButtons: PropTypes.arrayOf(
+ PropTypes.shape({
+ img: PropTypes.string,
+ title: PropTypes.node.isRequired,
+ onClick: PropTypes.func, // Optional, "coming soon" if no callback provided
+ fileAccept: PropTypes.string, // Optional, only for file upload
+ fileChange: PropTypes.func, // Optional, only for file upload
+ fileInput: PropTypes.func, // Optional, only for file upload
+ fileMultiple: PropTypes.bool // Optional, only for file upload
+ })
+ ),
onClick: PropTypes.func.isRequired,
title: PropTypes.node.isRequired,
tooltipPlace: PropTypes.string
};
-export default ActionMenu;
+export default React.memo(ActionMenu, (prevProps, nextProps) =>
+ // This check prevents re-rendering while the project is updating.
+ // This is needed because of the sloppy way the props are passed as a new object,
+ // which should be refactored.
+ // Only re-render if the title changes
+ prevProps.title === nextProps.title
+);
diff --git a/packages/scratch-gui/src/components/cards/cards.jsx b/packages/scratch-gui/src/components/cards/cards.jsx
index 393f7f63019..46b51ff3a9a 100644
--- a/packages/scratch-gui/src/components/cards/cards.jsx
+++ b/packages/scratch-gui/src/components/cards/cards.jsx
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
-import React, {Fragment} from 'react';
+import React, {Fragment, useRef, useEffect} from 'react';
import classNames from 'classnames';
import {FormattedMessage} from 'react-intl';
import Draggable from 'react-draggable';
@@ -354,6 +354,21 @@ const Cards = props => {
if (activeDeckId === null) return;
+ const cardRef = useRef(null);
+
+ useEffect(() => {
+ // Only focus if there’s an actual tutorial step (image/video)
+ const steps = content[activeDeckId]?.steps;
+ const isTutorialStep = steps?.[step]?.video;
+
+ if (isTutorialStep && cardRef.current) {
+ // Defer focus to next animation frame for layout stability
+ requestAnimationFrame(() => {
+ cardRef.current.focus();
+ });
+ }
+ }, [activeDeckId, step, content]);
+
// Tutorial cards need to calculate their own dragging bounds
// to allow for dragging the cards off the left, right and bottom
// edges of the workspace.
@@ -385,6 +400,8 @@ const Cards = props => {
top: `${menuBarHeight}px`,
left: `${-cardHorizontalDragOffset}px`
}}
+ ref={cardRef}
+ tabIndex={-1}
>
{turbo ? (
@@ -55,6 +58,7 @@ const Controls = function (props) {
};
Controls.propTypes = {
+ isFullScreen: PropTypes.bool,
active: PropTypes.bool,
className: PropTypes.string,
onGreenFlagClick: PropTypes.func.isRequired,
diff --git a/packages/scratch-gui/src/components/debug-modal/debug-modal.css b/packages/scratch-gui/src/components/debug-modal/debug-modal.css
index c7e624ebae8..750b80935ef 100644
--- a/packages/scratch-gui/src/components/debug-modal/debug-modal.css
+++ b/packages/scratch-gui/src/components/debug-modal/debug-modal.css
@@ -99,6 +99,7 @@
.topic-item {
display: flex;
+ width: 100%;
gap: 8px;
align-items: center;
padding: 8px;
@@ -156,7 +157,20 @@
margin-top: 20px;
}
- button {
+ .modal-header button,
+ .navigation-buttons button {
margin: 5px;
}
}
+
+/* TO DO: export this class for reuse */
+.button-style-remover {
+ background: none;
+ border: none;
+ padding: 0;
+ margin: 0;
+ font: inherit;
+ color: inherit;
+ cursor: pointer;
+ text-align: inherit;
+}
diff --git a/packages/scratch-gui/src/components/debug-modal/debug-modal.jsx b/packages/scratch-gui/src/components/debug-modal/debug-modal.jsx
index e79a6195fec..b36d6a8cefe 100644
--- a/packages/scratch-gui/src/components/debug-modal/debug-modal.jsx
+++ b/packages/scratch-gui/src/components/debug-modal/debug-modal.jsx
@@ -1,5 +1,5 @@
import React, {useState, useCallback, useEffect} from 'react';
-import {defineMessages, FormattedMessage} from 'react-intl';
+import {defineMessages, FormattedMessage, useIntl} from 'react-intl';
import PropTypes from 'prop-types';
import ReactModal from 'react-modal';
import classNames from 'classnames';
@@ -12,12 +12,23 @@ import debugIconInverted from './icons/icon--debug-inverted.svg';
import closeIcon from './icons/icon--close.svg';
import prevIcon from './icons/icon--prev.svg';
import nextIcon from './icons/icon--next.svg';
+import {KEY} from '../../lib/navigation-keys';
const messages = defineMessages({
title: {
id: 'gui.debugModal.title',
defaultMessage: 'Debugging | Getting Unstuck',
description: 'title for the debugging modal'
+ },
+ previous: {
+ id: 'gui.debugModal.previous',
+ defaultMessage: 'Previous',
+ description: 'Button to go to previous debugging topic'
+ },
+ next: {
+ id: 'gui.debugModal.next',
+ defaultMessage: 'Next',
+ description: 'Button to go to next debugging topic'
}
});
@@ -64,6 +75,36 @@ const DebugModal = ({isOpen, onClose = () => {}}) => {
onClose();
}, [onClose]);
+ const handleKeyDownSlides = useCallback(e => {
+ if ([KEY.ARROW_LEFT, KEY.ARROW_UP, KEY.ARROW_RIGHT, KEY.ARROW_DOWN].includes(e.key)) {
+ e.preventDefault();
+
+ setSelectedTopicIndex(prev => {
+ let nextIndex = prev;
+
+ if ((e.key === KEY.ARROW_LEFT || e.key === KEY.ARROW_UP) && prev > 0) {
+ nextIndex = prev - 1;
+ } else if ((e.key === KEY.ARROW_RIGHT || e.key === KEY.ARROW_DOWN) &&
+ prev < sections.length - 1) {
+ nextIndex = prev + 1;
+ }
+
+ if (nextIndex !== prev) {
+ logTopicChange(nextIndex);
+ }
+
+ return nextIndex;
+ });
+ }
+ }, []);
+
+ useEffect(() => {
+ if (!isOpen) return;
+
+ document.addEventListener('keydown', handleKeyDownSlides);
+ return () => document.removeEventListener('keydown', handleKeyDownSlides);
+ }, [isOpen, handleKeyDownSlides]);
+
useEffect(() => {
if (isOpen) {
GA4.event({
@@ -75,6 +116,8 @@ const DebugModal = ({isOpen, onClose = () => {}}) => {
if (!isOpen) return null;
+ const intl = useIntl();
+
return (
{}}) => {
{sections.map((section, index) => (
-
handleTopicSelect(index)}
+ tabIndex={-1}
>
![]()
{}}) => {
-
+
))}
@@ -143,22 +188,30 @@ const DebugModal = ({isOpen, onClose = () => {}}) => {
/>
-

-

+

+
+
+ className={classNames(styles.nextIcon,
+ styles.buttonStyleRemover,
+ {
+ [styles.hidden]: selectedTopicIndex === sections.length - 1
+ })}
+ >
+

+
diff --git a/packages/scratch-gui/src/components/delete-button/delete-button.jsx b/packages/scratch-gui/src/components/delete-button/delete-button.jsx
index 86c01bc8856..76a8e73c237 100644
--- a/packages/scratch-gui/src/components/delete-button/delete-button.jsx
+++ b/packages/scratch-gui/src/components/delete-button/delete-button.jsx
@@ -26,7 +26,6 @@ const DeleteButton = props => (
/>
-
);
DeleteButton.propTypes = {
diff --git a/packages/scratch-gui/src/components/direction-picker/direction-picker.jsx b/packages/scratch-gui/src/components/direction-picker/direction-picker.jsx
index 55c1a0dabd0..4b61af5ae22 100644
--- a/packages/scratch-gui/src/components/direction-picker/direction-picker.jsx
+++ b/packages/scratch-gui/src/components/direction-picker/direction-picker.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, {useRef, useEffect} from 'react';
import PropTypes from 'prop-types';
import Popover from 'react-popover';
import {defineMessages, FormattedMessage, useIntl} from 'react-intl';
@@ -51,15 +51,43 @@ const messages = defineMessages({
const DirectionPicker = props => {
const intl = useIntl();
+
+ const containerRef = useRef(null);
+ const popoverRef = useRef(null);
+
+ // Close the popover once we focus out of it
+ useEffect(() => {
+ if (!props.popoverOpen) return;
+
+ const handleFocusIn = event => {
+ const target = event.target;
+ if (
+ (containerRef.current && containerRef.current.contains(target)) ||
+ (popoverRef.current && popoverRef.current.contains(target))
+ ) {
+ return;
+ }
+
+ props.onClosePopover();
+ };
+
+ document.addEventListener('focusin', handleFocusIn);
+
+ return () => {
+ document.removeEventListener('focusin', handleFocusIn);
+ };
+ }, [props.popoverOpen, props.onClosePopover]);
+
return (