diff --git a/package-lock.json b/package-lock.json index 5be40a9a..ac204637 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2066,6 +2066,614 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@firebase/ai": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", + "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", + "peer": true, + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", + "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", + "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", + "peer": true, + "dependencies": { + "@firebase/analytics": "0.10.17", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "peer": true + }, + "node_modules/@firebase/app": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", + "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", + "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", + "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", + "peer": true, + "dependencies": { + "@firebase/app-check": "0.10.1", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "peer": true + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "peer": true + }, + "node_modules/@firebase/app-compat": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", + "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", + "peer": true, + "dependencies": { + "@firebase/app": "0.13.2", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "peer": true + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.28", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", + "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", + "peer": true, + "dependencies": { + "@firebase/auth": "1.10.8", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "peer": true + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "peer": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", + "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", + "peer": true, + "dependencies": { + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", + "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", + "peer": true, + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", + "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", + "peer": true, + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", + "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/database": "1.0.20", + "@firebase/database-types": "1.0.15", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", + "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", + "peer": true, + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.12.1" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", + "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.53", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", + "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "peer": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", + "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", + "peer": true, + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", + "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/functions": "0.12.9", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "peer": true + }, + "node_modules/@firebase/installations": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", + "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", + "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "peer": true, + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "peer": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", + "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", + "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/messaging": "0.12.22", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "peer": true + }, + "node_modules/@firebase/performance": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", + "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", + "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.7.7", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "peer": true + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", + "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", + "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "peer": true + }, + "node_modules/@firebase/storage": { + "version": "0.13.14", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", + "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", + "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "peer": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", + "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", + "peer": true + }, "node_modules/@floating-ui/core": { "version": "1.6.9", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", @@ -2167,6 +2775,37 @@ "resolved": "https://registry.npmjs.org/@gilbarbara/deep-equal/-/deep-equal-0.3.1.tgz", "integrity": "sha512-I7xWjLs2YSVMc5gGx1Z3ZG1lgFpITPndpi8Ku55GeEIKpACCPQNS/OTqQbxgTCfq0Ncvcc+CrFov96itVh6Qvw==" }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "peer": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "peer": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@headlessui/react": { "version": "1.7.15", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz", @@ -3031,6 +3670,70 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "peer": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "peer": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "peer": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "peer": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "peer": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "peer": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "peer": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "peer": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "peer": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "peer": true + }, "node_modules/@puppeteer/browsers": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", @@ -3507,10 +4210,30 @@ "@types/ms": "*" } }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", @@ -4032,6 +4755,152 @@ } } }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, "node_modules/@webcontainer/api": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/@webcontainer/api/-/api-1.5.3.tgz", @@ -4042,6 +4911,18 @@ "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "peer": true + }, "node_modules/accessor-fn": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.5.3.tgz", @@ -4051,9 +4932,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "bin": { "acorn": "bin/acorn" }, @@ -4061,6 +4942,18 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.3.tgz", + "integrity": "sha512-jtKLnfoOzm28PazuQ4dVBcE9Jeo6ha1GAJvq3N0LlNOszmTfx+wSycBehn+FN0RnyeR77IBxN/qVYMw0Rlj0Xw==", + "peer": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -4965,6 +5858,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/chromium-bidi": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", @@ -6029,6 +6931,19 @@ "node": ">=10.0.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -6134,6 +7049,12 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "peer": true + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -6689,7 +7610,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -6736,6 +7656,15 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -6842,6 +7771,18 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "peer": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -6941,6 +7882,66 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", + "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", + "peer": true, + "dependencies": { + "@firebase/ai": "1.4.1", + "@firebase/analytics": "0.10.17", + "@firebase/analytics-compat": "0.2.23", + "@firebase/app": "0.13.2", + "@firebase/app-check": "0.10.1", + "@firebase/app-check-compat": "0.3.26", + "@firebase/app-compat": "0.4.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.10.8", + "@firebase/auth-compat": "0.5.28", + "@firebase/data-connect": "0.3.10", + "@firebase/database": "1.0.20", + "@firebase/database-compat": "2.0.11", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-compat": "0.3.53", + "@firebase/functions": "0.12.9", + "@firebase/functions-compat": "0.3.26", + "@firebase/installations": "0.6.18", + "@firebase/installations-compat": "0.2.18", + "@firebase/messaging": "0.12.22", + "@firebase/messaging-compat": "0.2.22", + "@firebase/performance": "0.7.7", + "@firebase/performance-compat": "0.2.20", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-compat": "0.2.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-compat": "0.3.24", + "@firebase/util": "1.12.1" + } + }, + "node_modules/firebase/node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "peer": true, + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -7293,6 +8294,12 @@ "node": ">= 6" } }, + "node_modules/glob-to-regexp": { + "version": "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==", + "peer": true + }, "node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -7772,6 +8779,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "peer": true + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -8580,6 +9593,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, "node_modules/loader-utils": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", @@ -8630,6 +9652,12 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "peer": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -8647,6 +9675,12 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "peer": true + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -9656,6 +10690,12 @@ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" }, + "node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", + "peer": true + }, "node_modules/motion-dom": { "version": "11.18.1", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", @@ -9734,6 +10774,12 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "peer": true + }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", @@ -10815,6 +11861,30 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/protobufjs": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-agent": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", @@ -13275,6 +14345,15 @@ "node": ">=10.13.0" } }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tar-fs": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz", @@ -13827,6 +14906,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/typo-js": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.3.tgz", @@ -14185,6 +15278,19 @@ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", "license": "MIT" }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/web-namespaces": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", @@ -14194,12 +15300,173 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "peer": true + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, + "node_modules/webpack": { + "version": "5.100.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.1.tgz", + "integrity": "sha512-YJB/ESPUe2Locd0NKXmw72Dx8fZQk1gTzI6rc9TAT4+Sypbnhl8jd8RywB1bDsDF9Dy1RUR7gn3q/ZJTd0OZZg==", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.2", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "peer": true + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "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==", + "peer": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "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==", + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", diff --git a/src/components/AccountReactivation.jsx b/src/components/AccountReactivation.jsx new file mode 100644 index 00000000..07149308 --- /dev/null +++ b/src/components/AccountReactivation.jsx @@ -0,0 +1,395 @@ +import React, { useState, useEffect } from 'react'; +import request from '@/utils/request'; + +const AccountReactivation = ({ + email, + accountType, + password, + deletionInfo, + onReactivated, + onCancel, +}) => { + const [isReactivating, setIsReactivating] = useState(false); + const [notification, setNotification] = useState(null); + const [detectedAccountType, setDetectedAccountType] = useState( + accountType || 'EMAIL' + ); + + // Detect account type on mount + useEffect(() => { + if (accountType) { + setDetectedAccountType(accountType); + } + }, [accountType]); + + const showNotification = (message, type = 'info') => { + setNotification({ message, type }); + setTimeout(() => setNotification(null), 5000); + }; + + // Calculate deletion deadline + const getDeletionInfo = () => { + if (!deletionInfo?.scheduledFor) { + return { + hasDeadline: false, + message: 'Your account deletion is pending.', + }; + } + + try { + const deadline = new Date(deletionInfo.scheduledFor); + const now = new Date(); + const timeRemaining = deadline.getTime() - now.getTime(); + const daysRemaining = Math.max( + 0, + Math.ceil(timeRemaining / (1000 * 60 * 60 * 24)) + ); + const hoursRemaining = Math.max( + 0, + Math.ceil(timeRemaining / (1000 * 60 * 60)) + ); + + if (timeRemaining > 0) { + return { + hasDeadline: true, + deadline: deadline.toLocaleDateString(), + daysRemaining, + hoursRemaining, + message: `You have ${daysRemaining} day(s) to save your account!`, + urgency: + daysRemaining <= 1 ? 'high' : daysRemaining <= 3 ? 'medium' : 'low', + }; + } else { + return { + hasDeadline: false, + message: 'Your deletion deadline has passed.', + }; + } + } catch (error) { + return { + hasDeadline: false, + message: 'Your account deletion is pending.', + }; + } + }; + + const deletionData = getDeletionInfo(); + + const handleReactivation = async () => { + setIsReactivating(true); + try { + // Validate that we have password for EMAIL accounts + if (detectedAccountType === 'EMAIL' && !password) { + throw new Error( + 'Password is required for email accounts. Please try logging in again.' + ); + } + + const requestData = { + email: email, + accountType: detectedAccountType, + }; + + // Include password for EMAIL accounts + if (detectedAccountType === 'EMAIL' && password) { + requestData.password = password; + } + + const response = await request( + `${process.env.NEXT_PUBLIC_API_URL}/account/reactivate`, + 'POST', + requestData + ); + + if (response.success) { + const successMessage = deletionInfo + ? 'Account saved successfully! Your deletion has been cancelled.' + : 'Account reactivated successfully!'; + showNotification(successMessage, 'success'); + + // Store the token securely + if (response.token) { + localStorage.setItem('token', response.token); + } + + setTimeout(() => { + onReactivated?.(response.token); + }, 1500); + } else { + throw new Error(response.error || 'Failed to reactivate account'); + } + } catch (error) { + let errorMessage = error.message || 'Failed to reactivate account.'; + + // Handle specific error cases + if (errorMessage.includes('Password is required')) { + errorMessage = + 'Password verification failed. Please go back and try logging in again.'; + } else if (errorMessage.includes('Invalid password')) { + errorMessage = + 'The password you entered is incorrect. Please go back and try again.'; + } + + showNotification(errorMessage, 'error'); + } finally { + setIsReactivating(false); + } + }; + + const NotificationModal = () => { + if (!notification) return null; + + const getIcon = () => { + switch (notification.type) { + case 'success': + return 'fas fa-check-circle text-green-400'; + case 'error': + return 'fas fa-exclamation-circle text-red-400'; + case 'warning': + return 'fas fa-exclamation-triangle text-yellow-400'; + default: + return 'fas fa-info-circle text-blue-400'; + } + }; + + return ( +
+
setNotification(null)} + /> +
+
+ +
+

{notification.message}

+
+ +
+
+
+ ); + }; + + return ( + <> +
+
+ {/* Header */} +
+
+
+ + {/* Main Card */} +
+ {/* Title */} +
+

+ {deletionInfo && deletionData.hasDeadline + ? 'Save Your Account from Permanent Deletion' + : deletionInfo + ? 'Account Deletion Request' + : 'Account Reactivation'} +

+

+ {deletionInfo && deletionData.hasDeadline + ? `Login before ${deletionData.deadline} to prevent permanent deletion` + : deletionInfo + ? 'Your account deletion request is pending' + : 'Your account is temporarily suspended'} +

+
+ + {/* Deletion Deadline Warning - Only show if account deletion is scheduled */} + {deletionInfo && deletionData.hasDeadline && ( +
+
+
+ +
+
+

+ Deleting in {deletionData.daysRemaining} day(s) +

+

+ Scheduled: {deletionData.deadline} +

+ {deletionData.daysRemaining <= 3 && ( +

+ {deletionData.daysRemaining}d,{' '} + {deletionData.hoursRemaining % 24}h remaining +

+ )} +
+
+
+ )} + + {/* Account Info */} +
+
+
+ {detectedAccountType === 'GOOGLE' ? ( + + ) : ( + + )} +
+
+

{email}

+

+ {detectedAccountType === 'GOOGLE' + ? 'Google Account' + : 'Email Account'} +

+
+
+ +
+
+
+ + {/* Info Cards */} +
+
+

+ What happened? +

+

+ {deletionInfo + ? 'You requested account deletion and your account has been suspended for 7 days as a safety measure.' + : 'Your account has been temporarily suspended but can be reactivated instantly.'} +

+
+ +
+

+ {deletionInfo ? 'Your content is still safe!' : 'Good news!'} +

+

+ {deletionInfo + ? 'All your challenges, comments, and progress remain visible and intact during this 7-day period. Nothing is transferred to the system account until the deadline passes.' + : 'All your data is safe and will be restored immediately upon reactivation.'} +

+
+
+ + {/* Ready to Reactivate Notice */} +
+
+
+ +
+
+

+ {deletionInfo + ? 'Ready to Cancel Deletion' + : 'Ready to Reactivate'} +

+

+ {deletionInfo + ? 'Click below to immediately cancel your deletion request' + : "You're already authenticated - just click the button below"} +

+
+
+
+ + {/* Buttons */} +
+ + + +
+ + {/* Footer */} +
+

+ Need help?{' '} + + support@ctfguide.com + +

+
+
+ + {/* Bottom Footer */} +
+

© CTFGuide Corporation 2025

+
+
+
+ + + + ); +}; + +export default AccountReactivation; diff --git a/src/components/CommentReporter.jsx b/src/components/CommentReporter.jsx new file mode 100644 index 00000000..a05815fc --- /dev/null +++ b/src/components/CommentReporter.jsx @@ -0,0 +1,219 @@ +import React, { useState } from 'react'; +import request from '@/utils/request'; + +const CommentReporter = ({ commentId, commentContent, challengeId }) => { + const [isOpen, setIsOpen] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); + const [selectedReason, setSelectedReason] = useState(''); + const [customReason, setCustomReason] = useState(''); + const [notification, setNotification] = useState(null); + + const reportReasons = [ + { value: 'SPAM', label: 'Spam or unwanted commercial content' }, + { value: 'HARASSMENT', label: 'Harassment or bullying' }, + { value: 'INAPPROPRIATE', label: 'Inappropriate content' }, + { value: 'MISINFORMATION', label: 'False or misleading information' }, + { value: 'SPOILER', label: 'Contains spoilers or solution hints' }, + { value: 'OFF_TOPIC', label: 'Off-topic or irrelevant' }, + { value: 'OTHER', label: 'Other (please specify)' }, + ]; + + const showNotification = (message, type = 'info') => { + setNotification({ message, type }); + setTimeout(() => setNotification(null), 4000); + }; + + const handleSubmitReport = async () => { + if (!selectedReason) { + showNotification('Please select a reason for reporting', 'error'); + return; + } + + if (selectedReason === 'OTHER' && !customReason.trim()) { + showNotification('Please provide a custom reason', 'error'); + return; + } + + setIsSubmitting(true); + + try { + const reportData = { + type: 'COMMENT', + desc: + selectedReason === 'OTHER' + ? customReason + : reportReasons.find((r) => r.value === selectedReason)?.label, + metadata: { + commentId, + challengeId, + reason: selectedReason, + commentContent: commentContent?.substring(0, 200) || '', // First 200 chars for context + }, + }; + + const response = await request( + `${process.env.NEXT_PUBLIC_API_URL}/reports`, + 'POST', + reportData + ); + + if (response.success) { + showNotification( + 'Comment reported successfully. Thank you for helping keep our community safe.', + 'success' + ); + setIsOpen(false); + setSelectedReason(''); + setCustomReason(''); + } else { + throw new Error(response.error || 'Failed to submit report'); + } + } catch (error) { + console.error('Error reporting comment:', error); + showNotification( + error.message || 'Failed to submit report. Please try again.', + 'error' + ); + } finally { + setIsSubmitting(false); + } + }; + + const NotificationModal = () => { + if (!notification) return null; + + const getIcon = () => { + switch (notification.type) { + case 'success': + return 'fas fa-check-circle text-green-400'; + case 'error': + return 'fas fa-exclamation-circle text-red-400'; + case 'warning': + return 'fas fa-exclamation-triangle text-yellow-400'; + default: + return 'fas fa-info-circle text-blue-400'; + } + }; + + return ( +
+
setNotification(null)} + /> +
+
+ +
+

{notification.message}

+
+ +
+
+
+ ); + }; + + return ( + <> + + + {isOpen && ( +
+
setIsOpen(false)} + /> +
+
+

+ Report Comment +

+ +
+ +

+ Help us keep the community safe by reporting inappropriate + content. +

+ +
+ {reportReasons.map((reason) => ( + + ))} +
+ + {selectedReason === 'OTHER' && ( + - -

Uploaded Files

-
- {files && files.length > 0 ? ( - files.map((file, index) => ( -
- {file.name} - - Download - -
- )) - ) : ( -

No files uploaded

- )} -
- -

Moderator Notes

- - - -



-
-

Set Base Points

-
-

Beginner: 100, - Easy: 200, - Medium: 300, - Hard: 400, - Insane: 500 -

-
- - -
-
- - -
+ return ( + + +
+
+ + + {/* Sticky Close Button */} +
+ + {challenge.title || 'Loading...'} + + +
+ {/* Modal Content */} +
+
+

+ {' '} + Don't forget + to make sure the challenge is including an explanation. +

+
+
+
+

+ Description +

+ +
+
+

Flag

+

+ {(challenge && + challenge.solution && + challenge.solution.keyword) || + 'N/A'} +

+
+
+

Difficulty

+

{challenge && challenge.difficulty}

+
+ +
+

Category

+

{challenge && challenge.category && challenge.category.join(", ")}

+
+
+

+ Date of Creation +

+

+ {challenge && + new Date(challenge.createdAt).toLocaleString([], { + hour: 'numeric', + minute: 'numeric', + hour12: true, + month: 'short', + day: 'numeric', + })} +

+
+
+

+ Last Updated +

+

+ {challenge && + new Date(challenge.updatedAt).toLocaleString([], { + hour: 'numeric', + minute: 'numeric', + hour12: true, + month: 'short', + day: 'numeric', + })} +

+
+
+

+ Environment Container Configuration +

+ +

+ Uploaded Files +

+
+ {files && files.length > 0 ? ( + files.map((file, index) => ( +
+ {file.name} + + Download + +
+ )) + ) : ( +

No files uploaded

+ )}
-
- - - - - - - +

+ Moderator Notes +

+ -
- - - - - - +
+ + {/* Tab Navigation */} +
+ {/* Mobile Dropdown */} +
+
+ + {showMobileMenu && ( +
+
+ + + + + + + +
+
+ )} +
+
+ {/* Desktop Tabs */} +
+
+ +
+
+
+ + {/* Tab Content */} + {activeTab === 'activity' && ( +
+ {/* Activity Tab Navigation */} +
+ +
+ + {/* Activity Content */} +
+
+
+

+ Recent{' '} + {activeActivityTab.charAt(0).toUpperCase() + + activeActivityTab.slice(1)} +

+

+ Latest {activeActivityTab} across the platform +

+
+ +
+ + {loadingActivity ? ( +
+
+ Loading recent {activeActivityTab}... +
+
+ ) : ( +
+ {/* Comments Content */} + {activeActivityTab === 'comments' && ( +
+ {recentActivity.comments.length === 0 ? ( +
+ +

+ No recent comments +

+

+ No comments have been posted recently. +

+
+ ) : ( +
+ {recentActivity.comments.map((comment) => ( +
+ window.open( + `/challenges/${ + comment.challengeSlug || + comment.challengeId || + '' + }?tab=comments`, + '_blank' + ) + } + > +
+ {comment.username} { + e.target.src = `https://robohash.org/${comment.username}.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+ + {comment.username} + + + {new Date( + comment.createdAt + ).toLocaleDateString()}{' '} + {new Date( + comment.createdAt + ).toLocaleTimeString([], { + hour: 'numeric', + minute: 'numeric', + hour12: true, + })} + +
+
+ on {comment.challengeTitle} +
+
+ {comment.content} +
+
+
+
+ ))} +
+ )} +
+ )} + + {/* Writeups Content */} + {activeActivityTab === 'writeups' && ( +
+ {recentActivity.writeups.length === 0 ? ( +
+ +

+ No recent writeups +

+

+ No writeups have been posted recently. +

+
+ ) : ( +
+ {recentActivity.writeups.map((writeup) => ( +
+ window.open( + `/challenges/${ + writeup.challengeSlug || + writeup.challengeId || + '' + }?tab=writeups`, + '_blank' + ) + } + > +
+ {writeup.username} { + e.target.src = `https://robohash.org/${writeup.username}.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+ + {writeup.username} + + + {new Date( + writeup.createdAt + ).toLocaleDateString()}{' '} + {new Date( + writeup.createdAt + ).toLocaleTimeString([], { + hour: 'numeric', + minute: 'numeric', + hour12: true, + })} + +
+
+ for {writeup.challengeTitle} +
+
+ {writeup.content} +
+
+
+
+ ))} +
+ )} +
+ )} + + {/* Lessons Content */} + {activeActivityTab === 'lessons' && ( +
+ {recentActivity.lessons.length === 0 ? ( +
+ +

+ No recent lessons +

+

+ No lessons have been created recently. +

+
+ ) : ( +
+ {recentActivity.lessons.map((lesson) => ( +
+ window.open( + `/learn/lessons/${lesson.id}`, + '_blank' + ) + } + > +
+
+ +
+
+
+ + {lesson.title} + + + {new Date( + lesson.createdAt + ).toLocaleDateString()}{' '} + {new Date( + lesson.createdAt + ).toLocaleTimeString([], { + hour: 'numeric', + minute: 'numeric', + hour12: true, + })} + +
+
+ + by {lesson.author} + + + {lesson.status} + +
+
+ {lesson.description} +
+
+
+
+ ))} +
+ )} +
+ )} +
+ )} +
+
+ )} + + {activeTab === 'overview' && ( +
+ {/* Enhanced Platform Statistics Dashboard */} +
+
+
+
+

+ Platform Analytics +

+

+ Real-time platform statistics and insights +

+
+
+
+
+ + Live + +
+
+ + {stats ? ( + <> + {/* Primary Stats Grid */} +
+ {/* Total Users */} +
+
+

+ {stats?.userCount?.toLocaleString() || '0'} +

+

+ Total Users +

+
+
+
+
+
+
+
+ + {/* New Joiners (24h) */} +
+
+

+ {stats?.recentSignUpsCount24h || 0} +

+

+ New Joiners (24h) +

+
+
+
+ + + + {( + (stats?.recentSignUpsCount24h || 0) / 7 + ).toFixed(1)} + % vs avg + +
+
+
+ + {/* Total Challenges */} +
+
+

+ {stats?.challengeCount?.toLocaleString() || '0'} +

+

+ Total Challenges +

+
+
+
+
+
+
+
+ + {/* Verified Challenges */} +
+
+

+ {stats?.verifiedChallengeCount?.toLocaleString() || + '0'} +

+

+ Verified Challenges +

+
+
+
+ + {( + ((stats?.verifiedChallengeCount || 0) / + (stats?.challengeCount || 1)) * + 100 + ).toFixed(1)} + % verified + +
+
+
+
+ + {/* Secondary Stats Grid */} +
+ {/* Pending Challenges */} +
+

+ {pendingChallenges.length} +

+

+ Pending +

+
+ + {/* Reports */} +
+

+ {reportStats?.totalReports || reports.length} +

+

+ Reports +

+
+ + {/* Suspended Accounts */} +
+

+ {totalSuspendedAccounts} +

+

+ Suspended +

+
+ + {/* Account Deletions */} +
+

+ {pendingDeletions.length} +

+

+ Deletions +

+
+ + {/* Verification Rate */} +
+

+ {( + ((stats?.verifiedChallengeCount || 0) / + (stats?.challengeCount || 1)) * + 100 + ).toFixed(0)} + % +

+

+ Verified +

+
+ + {/* Weekly Projection */} +
+

+ {(stats?.recentSignUpsCount24h || 0) * 7} +

+

+ Weekly User Est. +

+
+
+ + {/* Recent Activity Section */} +
+ {/* Recent Joiners */} +
+
+
+
+ +
+
+

+ Recent Joiners +

+

+ Latest members to join the platform +

+
+
+
+

+ {stats?.recentSignUpsCount24h || 0} in last 24h +

+

+ Showing latest{' '} + {Math.min(6, stats?.recentSignUps?.length || 0)} +

+
+
+ + {stats?.recentSignUps && + stats?.recentSignUps.length > 0 ? ( +
+ {stats?.recentSignUps.slice(0, 6).map((user) => ( +
+ window.open( + `/users/${user.username}`, + '_blank' + ) + } + > +
+
+ {`${user.username}'s +
+
+
+

+ {user.username} +

+

+ {new Date( + user.createdAt + ).toLocaleDateString()} +

+
+
+
+ ))} +
+ ) : ( +
+
+ +
+

+ No recent sign-ups +

+
+ )} +
+ + {/* Recent Logins */} +
+
+
+
+ +
+
+

+ Recent Logins +

+

+ Users active in last 24h +

+
+
+
+ + {stats?.recentLogins?.length || 0} users + +
+
+ + {stats?.recentLogins?.length > 0 ? ( +
+ {stats?.recentLogins + .slice(0, 4) + .map((user, index) => ( +
+ window.open( + `/users/${user.username}`, + '_blank' + ) + } + > +
+
+ {user.username} { + e.target.src = `https://robohash.org/${user.username}?set=set1&size=48x48`; + }} + /> +
+
+
+

+ {user.username} +

+

+ {new Date( + user.lastLogin + ).toLocaleTimeString()} +

+ {user.role === 'ADMIN' && ( + + ADMIN + + )} + {user.role === 'PRO' && ( + + PRO + + )} +
+
+
+ ))} +
+ ) : ( +
+
+ +
+

No recent logins

+
+ )} +
+
+ + ) : ( +
+
+ +
+

+ Failed to load statistics +

+

+ Unable to fetch platform analytics data +

+ +
+ )} +
+ + {/* Quick Actions */} +
+ {/* User Actions */} +
+
+

User Management

+
+ +
+
+ { + if (userSuggestions.length > 0) { + setShowUserSuggestions(true); + } + }} + onBlur={() => { + // Delay hiding suggestions to allow clicking + setTimeout( + () => setShowUserSuggestions(false), + 200 + ); + }} + autoComplete="off" + /> + + {/* User Suggestions Dropdown */} + {showUserSuggestions && userSuggestions.length > 0 && ( +
+ {userSuggestions.map((user) => ( +
handleUserSelection(user)} + > + {`${user.username}'s +
+

+ {user.username} +

+

{user.email || ''}

+

+ {user.points || 0} points • Joined{' '} + {new Date( + user.createdAt + ).toLocaleDateString()} +

+
+ {user.disabled && ( + + Disabled + + )} +
+ ))} +
+ )} +
+ +
+ - - - -
-
-
-
-

Challenges Pending Approval

- {selectedChallenges.length > 0 && } -
+
{pendingChallenges && pendingChallenges.length > 0 ? ( pendingChallenges.map((challenge) => ( -
{setSelectedId(challenge.id); setChallengeIsOpen(true);}} className='bg-neutral-800 w-full mb-2 border focus:bg-blue-900 focus:border-blue-500 border-neutral-700 hover:bg-neutral-700/50 cursor-pointer px-2 py-1 flex items-center text-sm'> - e.stopPropagation()} // Prevent click event propagation - type="checkbox" - checked={selectedChallenges.includes(challenge.id)} - onChange={() => handleSelectChallenge(challenge.id)} - className="" - /> -
-

{challenge.title}

-
-
-

Submitted by {challenge.creator}

-

{new Date(challenge.createdAt).toLocaleString([], { hour: 'numeric', minute: 'numeric', hour12: true, month: 'short', day: 'numeric' })}

+
+
+ e.stopPropagation()} + type="checkbox" + checked={selectedChallenges.includes(challenge.id)} + onChange={() => handleSelectChallenge(challenge.id)} + className="h-4 w-4 border-neutral-500 bg-neutral-600 text-blue-600 focus:ring-blue-500" + /> +
+

+ {challenge.title} +

+

+ Submitted by{' '} + + {challenge.creator} + +

+
+
+
+

+ {new Date(challenge.createdAt).toLocaleString( + [], + { + hour: 'numeric', + minute: 'numeric', + hour12: true, + month: 'short', + day: 'numeric', + } + )} +

+
+ +
)) ) : ( -

Nothing to show

+
+

No pending challenges

+
+ )} +
+
+ )} + + {activeTab === 'reports' && ( +
+ {/* Report Statistics */} + {reportStats && ( +
+

+ Report Statistics +

+
+
+

+ {reportStats.totalReports || 0} +

+

Total Reports

+
+
+

+ {reportStats.statusStats?.pending || 0} +

+

Pending

+
+
+

+ {reportStats.statusStats?.in_review || 0} +

+

In Review

+
+
+

+ {reportStats.statusStats?.resolved || 0} +

+

Resolved

+
+
+

+ {reportStats.recentCount || 0} +

+

This Week

+
+
+
+ )} + + {/* Report Filters */} +
+

+ Filter Reports +

+
+ + + + + +
+
+ + {/* All Reports */} +
+
+

+ All Reports +

+ +
+ + {reports.length > 0 ? ( +
+ {reports.map((report) => { + const getStatusColor = (status) => { + switch (status) { + case 'PENDING': + return 'bg-yellow-900/20 text-yellow-400 border-yellow-600/20'; + case 'IN_REVIEW': + return 'bg-blue-900/20 text-blue-400 border-blue-600/20'; + case 'RESOLVED': + return 'bg-green-900/20 text-green-400 border-green-600/20'; + case 'REJECTED': + return 'bg-red-900/20 text-red-400 border-red-600/20'; + default: + return 'bg-gray-900/20 text-gray-400 border-gray-600/20'; + } + }; + + return ( +
+
+
+
+ + {report.status} + + + {report.type} Report by{' '} + {report.user?.username || 'Unknown'} + +
+ +

{report.desc}

+ + {report.metadata && + Object.keys(report.metadata).length > 0 && ( +
+ {report.metadata.challengeId && ( +

+ Challenge ID:{' '} + {report.metadata.challengeId} +

+ )} + {report.metadata.commentId && ( +

+ Comment ID:{' '} + {report.metadata.commentId} +

+ )} + {report.metadata.reportedUserId && ( +

+ Reported User:{' '} + {report.metadata.reportedUserId} +

+ )} +
+ )} + + {report.resolution && ( +
+

+ Resolution:{' '} + {report.resolution} +

+
+ )} +
+ +
+ {report.status === 'PENDING' && ( + <> + + + + + )} + {report.status === 'IN_REVIEW' && ( + <> + + + + )} +
+
+ +
+ + Submitted:{' '} + {new Date( + report.createdAt + ).toLocaleDateString()} + + {report.resolvedAt && ( + + Resolved:{' '} + {new Date( + report.resolvedAt + ).toLocaleDateString()} + + )} +
+
+ ); + })} +
+ ) : ( +
+
+ +
+

+ No reports found +

+

+ No reports match your current filters. +

+
+ )} +
+
+ )} + + {activeTab === 'deletions' && ( +
+ {/* Deletion Statistics */} + {deletionStats && ( +
+

+ Account Deletion Statistics +

+
+
+

+ {deletionStats.stats?.pending || 0} +

+

Pending

+
+
+

+ {deletionStats.stats?.processing || 0} +

+

Processing

+
+
+

+ {deletionStats.stats?.completed || 0} +

+

Completed

+
+
+

+ {deletionStats.stats?.cancelled || 0} +

+

Cancelled

+
+
+
+ )} + + {/* Search and Controls */} +
+
+

+ Account Deletions +

+
+ + {pendingDeletions.length} deletion requests + +
+
+ + {/* Search Bar */} +
+
+ +
+ { + const value = e.target.value; + setDeletionsSearchFilter(value); + // Clear previous timeout + clearTimeout(window.deletionsSearchFilterTimeout); + // Debounce search + window.deletionsSearchFilterTimeout = setTimeout(() => { + fetchPendingDeletions(value); + }, 500); + }} + /> +
+ +
+ +
+
+ + {/* Pending Deletions */} +
+

+ Deletion Requests +

+ + {pendingDeletions.length > 0 ? ( +
+ {pendingDeletions.map((deletion) => ( +
+
+
+
+
+ +
+
+

+ {deletion.user?.username || 'Unknown User'} +

+

+ Account created:{' '} + {new Date( + deletion.user?.createdAt + ).toLocaleDateString()} +

+
+
+ +
+

+ Reason for leaving: +

+

+ {deletion.reason} +

+
+ +
+
+ + Requested: + + + {new Date( + deletion.createdAt + ).toLocaleDateString()} + +
+
+ + Scheduled for: + + + {deletion.scheduledFor + ? new Date( + deletion.scheduledFor + ).toLocaleDateString() + : 'Date unavailable'} + +
+
+
+ +
+ + + +
+
+
+ ))} +
+ ) : ( +
+
+ +
+

+ No pending deletions +

+

+ All account deletion requests have been processed. +

+
)}
-
-

Submitted Reports

- -
- {reports && reports.length > 0 ? ( - reports.map((report) => ( -
+ {/* Accounts Tab Navigation */} +
+ +
+ + {/* Suspended Accounts Content */} + {activeAccountsTab === 'suspended' && ( +
+ {/* Search and Controls */} +
+
+

+ Suspended Accounts +

+
+ + Page {suspendedAccountsPage + 1} of{' '} + {suspendedAccountsPagination?.totalPages || 1} ( + {totalSuspendedAccounts} suspended accounts) + +
+
+ + {/* Search Bar */} +
+
+ +
+ { + const value = e.target.value; + setSuspendedSearchFilter(value); + // Clear previous timeout + clearTimeout(window.suspendedSearchFilterTimeout); + // Debounce search + window.suspendedSearchFilterTimeout = setTimeout( + () => { + fetchSuspendedAccounts(0, value); + }, + 500 + ); + }} + /> +
+ + {/* Pagination */} + {suspendedAccountsPagination && + suspendedAccountsPagination.totalPages > 1 && ( +
+ + + Page {suspendedAccountsPage + 1} of{' '} + {suspendedAccountsPagination.totalPages} - )} - -
-
-

Reported by {report.userId}

-

{new Date(report.createdAt).toLocaleString([], { hour: 'numeric', minute: 'numeric', hour12: true, month: 'short', day: 'numeric' })}

+ +
+ )} +
+ + {/* Suspended Accounts List */} +
+

+ Suspended Users ({totalSuspendedAccounts}) +

+ + {suspendedAccounts.length > 0 ? ( +
+ {suspendedAccounts.map((user) => ( +
+
+
+
+ {user.profileImage && + user.profileImage.trim() !== '' ? ( + {`${user.username}'s { + e.target.style.display = 'none'; + e.target.nextSibling.style.display = + 'flex'; + }} + /> + ) : null} +
+ {user.username + .substring(0, 2) + .toUpperCase()} +
+
+
+
+

+ {user.username} +

+ + SUSPENDED + + + {user.accountType || 'USER'} + +
+

+ {user.firstName && user.lastName + ? `${user.firstName} ${user.lastName}` + : user.firstName || + user.lastName || + 'No name provided'}{' '} + • {user.email} +

+

+ Account created:{' '} + {user.createdAt + ? new Date( + user.createdAt + ).toLocaleDateString() + : 'Unknown'} +

+

+ Suspended:{' '} + {user.suspensionInfo?.suspendedAt + ? new Date( + user.suspensionInfo.suspendedAt + ).toLocaleDateString() + : user.disableInfo?.disabledAt + ? new Date( + user.disableInfo.disabledAt + ).toLocaleDateString() + : user.updatedAt + ? new Date( + user.updatedAt + ).toLocaleDateString() + : 'Unknown'} +

+ {user.suspensionInfo?.reason && ( +

+ Reason: {user.suspensionInfo.reason} +

+ )} + {!user.suspensionInfo?.reason && + user.bio && + user.bio.includes('[DISABLED:') && ( +

+ Reason:{' '} + {user.bio.match( + /\[DISABLED:([^\]]+)\]/ + )?.[1] || 'Not specified'} +

+ )} + {!user.suspensionInfo?.reason && + (!user.bio || + !user.bio.includes('[DISABLED:')) && ( +

+ Reason: No reason provided +

+ )} +
+
+
+ + + +
+
+ + {user.disableInfo && ( +
+

+ Disable Information: +

+
+

+ Reason:{' '} + {user.disableInfo.reason} +

+ {user.disableInfo.disabledAt && ( +

+ Disabled At:{' '} + {new Date( + user.disableInfo.disabledAt + ).toLocaleString()} +

+ )} +

+ Self-disabled:{' '} + {user.disableInfo.disabled ? 'Yes' : 'No'} +

+
+
+ )} +
+ ))} +
+ ) : ( +
+
+ +
+

+ No suspended accounts +

+

+ All user accounts are in good standing. +

+
+ )} +
+
+ )} + + {/* Disabled Accounts Content */} + {activeAccountsTab === 'disabled' && ( +
+
+

+ Disabled Accounts +

+
+
+ +
+

+ No disabled accounts +

+

+ This feature is not yet implemented. +

- )) - ) : ( -

No reports to show

+
)} -
-
-
-
-

Platform Stats

- {stats ? ( -
-
-
-

{stats.userCount}

-

Total Users

+ {/* Deletion Requests Content */} + {activeAccountsTab === 'deleted' && ( +
+ {/* Deletion Statistics */} + {deletionStats && ( +
+

+ Account Deletion Statistics +

+
+
+

+ {deletionStats.stats?.pending || 0} +

+

Pending

+
+
+

+ {deletionStats.stats?.processing || 0} +

+

Processing

+
+
+

+ {deletionStats.stats?.completed || 0} +

+

Completed

+
+
+

+ {deletionStats.stats?.cancelled || 0} +

+

Cancelled

+
+
-
-

{stats.challengeCount}

-

Total Challenges

+ )} + + {/* Search and Controls */} +
+
+

+ Account Deletions +

+
+ + {pendingDeletions.length} deletion requests + +
-
-

{stats.verifiedChallengeCount}

-

Verified Challenges

+ + {/* Search Bar */} +
+
+ +
+ { + const value = e.target.value; + setDeletionsSearchFilter(value); + // Clear previous timeout + clearTimeout(window.deletionsSearchFilterTimeout); + // Debounce search + window.deletionsSearchFilterTimeout = setTimeout( + () => { + fetchPendingDeletions(value); + }, + 500 + ); + }} + />
- + +
- -

Recent Sign-Ups

-
- {stats.recentSignUps.map((user) => ( -
window.open(`/users/${user.username}`, '_blank')}> - {`${user.username}'s -
-

{user.username}

-

{new Date(user.createdAt).toLocaleString()}

+ + {/* Pending Deletions */} +
+

+ Deletion Requests +

+ + {pendingDeletions.length > 0 ? ( +
+ {pendingDeletions.map((deletion) => ( +
+
+
+
+
+ +
+
+

+ {deletion.user?.username || + 'Unknown User'} +

+

+ Account created:{' '} + {new Date( + deletion.user?.createdAt + ).toLocaleDateString()} +

+
+
+ +
+

+ Reason for leaving: +

+

+ {deletion.reason} +

+
+ +
+
+ + Requested: + + + {new Date( + deletion.createdAt + ).toLocaleDateString()} + +
+
+ + Status: + + + {deletion.status} + +
+
+
+ +
+ + + +
+
+
+ ))} +
+ ) : ( +
+
+
+

+ No pending deletions +

+

+ All account deletion requests have been processed. +

- ))} + )}
- ) : ( -

Failed to load stats

)} -
-

Selected Content ID's

- + {/* Suspension History Content */} + {activeAccountsTab === 'history' && ( +
+ {/* Search and Filters */} +
+
+
+ + setSuspensionHistorySearchFilter(e.target.value) + } + className="w-full border border-neutral-600 bg-neutral-700 px-4 py-2 pl-10 text-white placeholder-gray-400 focus:border-blue-500 focus:outline-none" + /> + +
+ +
+ {suspensionHistoryPagination && ( +
+ Page {suspensionHistoryPage + 1} of{' '} + {suspensionHistoryPagination.totalPages} ( + {suspensionHistoryPagination.totalCount} total + entries) +
+ )} +
+ + {/* Suspension History Content */} +
+

+ Suspension History ( + {suspensionHistoryPagination?.totalCount || 0}) +

+ + {suspensionHistoryLoading ? ( +
+
+

+ Loading suspension history... +

+
+ ) : suspensionHistory.length === 0 ? ( +
+
+ No suspension history found +
+

+ {suspensionHistorySearchFilter || + suspensionHistoryStatusFilter !== 'all' + ? 'Try adjusting your search criteria.' + : 'No suspension history available.'} +

+
+ ) : ( + <> + {/* Desktop Table View */} +
+
+ + + + + + + + + + + + + {suspensionHistory.map((entry) => ( + + + + + + + + + ))} + +
+ USER + + STATUS + + ACCOUNT TYPE + + EMAIL + + DATES + + REASON +
+
+
+ {entry.user?.username { + e.target.src = `https://robohash.org/${ + entry.user?.username || 'user' + }.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+
+ {entry.user?.username || + 'Unknown'} +
+
+ {entry.user?.firstName && + entry.user?.lastName + ? `${entry.user.firstName} ${entry.user.lastName}` + : entry.user?.firstName || + entry.user?.lastName || + 'No name provided'} +
+
+
+
+ + {entry.user?.status === 'ACTIVE' + ? 'ACTIVE' + : 'SUSPENDED'} + + + + {entry.user?.accountType || 'USER'} + + + {entry.user?.email || 'No email'} + +
+ Created:{' '} + {entry.user?.createdAt + ? new Date( + entry.user.createdAt + ).toLocaleDateString() + : 'Unknown'} +
+
+ Suspended:{' '} + {entry.suspendedAt + ? new Date( + entry.suspendedAt + ).toLocaleDateString() + : 'Unknown'} +
+ {entry.reactivatedAt && ( +
+ Reactivated:{' '} + {new Date( + entry.reactivatedAt + ).toLocaleDateString()} +
+ )} +
+ {entry.reason && ( +

+ {entry.reason} +

+ )} + {entry.reactivationReason && ( +

+ + Reactivation reason: + {' '} + {entry.reactivationReason} +

+ )} +
+
+
+ + {/* Mobile Card View */} +
+
+ {suspensionHistory.map((entry) => ( +
+
+
+ {entry.user?.username { + e.target.src = `https://robohash.org/${ + entry.user?.username || 'user' + }.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+
+ {entry.user?.username || 'Unknown'} +
+
+ {entry.user?.firstName && + entry.user?.lastName + ? `${entry.user.firstName} ${entry.user.lastName}` + : entry.user?.firstName || + entry.user?.lastName || + 'No name provided'} +
+
+ + {entry.user?.status === 'ACTIVE' + ? 'ACTIVE' + : 'SUSPENDED'} + + + {entry.user?.accountType || 'USER'} + +
+
+
+ Created:{' '} + {entry.user?.createdAt + ? new Date( + entry.user.createdAt + ).toLocaleDateString() + : 'Unknown'} +
+
+ Suspended:{' '} + {entry.suspendedAt + ? new Date( + entry.suspendedAt + ).toLocaleDateString() + : 'Unknown'} +
+ {entry.reactivatedAt && ( +
+ Reactivated:{' '} + {new Date( + entry.reactivatedAt + ).toLocaleDateString()} +
+ )} +
+
+ {entry.reason && ( +

+ {entry.reason} +

+ )} + {entry.reactivationReason && ( +

+ + Reactivation reason: + {' '} + {entry.reactivationReason} +

+ )} +
+
+
+ By: {entry.suspendedBy || 'Unknown'} +
+ {entry.reactivatedBy && ( +
+ Reactivated by:{' '} + {entry.reactivatedBy} +
+ )} +
+
+
+
+ ))} +
+
+ + )} + + {/* Pagination */} + {suspensionHistoryPagination && + suspensionHistoryPagination.totalPages > 1 && ( +
+ + + Page {suspensionHistoryPage + 1} of{' '} + {suspensionHistoryPagination.totalPages} + + +
+ )} +
+
+ )} +
+ )} + + {activeTab === 'warnings' && ( +
+ {/* History Section Header */} +
+
+

+ History +

+ +
+ + {/* History Sub-tabs */} +
+
+ + +
+
+ + {/* Grouped Suspensions Tab */} + {activeHistoryTab === 'suspended' && ( + <> + {/* Smart Search Bar for Suspended */} +
+
+ +
+ { + setSuspendedSearchFilter(e.target.value); + handleUserInputChange(e); // trigger suggestions + clearTimeout(window.suspendedSearchTimeout2); + window.suspendedSearchTimeout2 = setTimeout(() => { + fetchGroupedSuspensions(1, e.target.value); + }, 500); + }} + onFocus={() => { + if (userSuggestions.length > 0) { + setShowUserSuggestions(true); + } + }} + onBlur={() => { + setTimeout( + () => setShowUserSuggestions(false), + 200 + ); + }} + autoComplete="off" + /> + {/* User Suggestions Dropdown */} + {showUserSuggestions && userSuggestions.length > 0 && ( +
+ {userSuggestions.map((user) => ( +
{ + setSuspendedSearchFilter(user.username); + setShowUserSuggestions(false); + setUserSuggestions([]); + fetchGroupedSuspensions(1, user.username); + }} + > + {`${user.username}'s +
+

+ {user.username} +

+

+ {user.points || 0} points • Joined{' '} + {new Date( + user.createdAt + ).toLocaleDateString()} +

+
+ {user.disabled && ( + + Disabled + + )} +
+ ))} +
+ )} +
+ {groupedSuspensionsLoading ? ( +
+
+

+ Loading grouped suspensions... +

+
+ ) : groupedSuspensions.length === 0 ? ( +
+
+ No suspensions found +
+
+ ) : ( + <> + {/* Desktop View */} +
+
+ {groupedSuspensions.map((userSuspensions) => ( +
+ {/* User Header */} +
+
+ {userSuspensions.username} { + e.target.src = `https://robohash.org/${userSuspensions.username}.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+ {userSuspensions.username} +
+
+ {userSuspensions.user?.email || + 'No email'} +
+
+ + {userSuspensions.totalSuspensions}{' '} + Suspensions + + + {userSuspensions.user?.status === + 'ACTIVE' + ? 'ACTIVE' + : 'SUSPENDED'} + +
+
+
+ +
+ + {/* Expanded Details */} + {expandedSuspensionUsers.has( + userSuspensions.userId + ) && ( +
+ {/* Suspensions */} + {userSuspensions.suspensions.length > + 0 && ( +
+

+ Suspensions ( + {userSuspensions.suspensions.length} + ) +

+
+ {userSuspensions.suspensions.map( + (suspension) => ( +
+
+ {suspension.reason} +
+
+ {new Date( + suspension.suspendedAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + suspension.suspendedAt + ).toLocaleTimeString()}{' '} + by{' '} + {suspension.suspendedBy || + 'Unknown'} +
+ {suspension.reactivatedAt && ( +
+ Reactivated:{' '} + {new Date( + suspension.reactivatedAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + suspension.reactivatedAt + ).toLocaleTimeString()} +
+ )} +
+ ) + )} +
+
+ )} +
+ )} +
+ ))} +
+
+ + {/* Mobile View */} +
+
+ {groupedSuspensions.map((userSuspensions) => ( +
+ {/* User Header */} +
+
+ {userSuspensions.username} { + e.target.src = `https://robohash.org/${userSuspensions.username}.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+ {userSuspensions.username} +
+
+ {userSuspensions.user?.email || + 'No email'} +
+
+ + {userSuspensions.totalSuspensions}{' '} + Suspensions + + + {userSuspensions.user?.status === + 'ACTIVE' + ? 'ACTIVE' + : 'SUSPENDED'} + +
+
+
+ +
+ + {/* Expanded Details */} + {expandedSuspensionUsers.has( + userSuspensions.userId + ) && ( +
+ {/* Suspensions */} + {userSuspensions.suspensions.length > + 0 && ( +
+

+ Suspensions ( + {userSuspensions.suspensions.length} + ) +

+
+ {userSuspensions.suspensions.map( + (suspension) => ( +
+
+ {suspension.reason} +
+
+ {new Date( + suspension.suspendedAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + suspension.suspendedAt + ).toLocaleTimeString()}{' '} + by{' '} + {suspension.suspendedBy || + 'Unknown'} +
+ {suspension.reactivatedAt && ( +
+ Reactivated:{' '} + {new Date( + suspension.reactivatedAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + suspension.reactivatedAt + ).toLocaleTimeString()} +
+ )} +
+ ) + )} +
+
+ )} +
+ )} +
+ ))} +
+
+ + {/* Pagination */} + {groupedSuspensionsTotal > + groupedSuspensionsPerPage && ( +
+
+ Showing{' '} + {(groupedSuspensionsPage - 1) * + groupedSuspensionsPerPage + + 1}{' '} + to{' '} + {Math.min( + groupedSuspensionsPage * + groupedSuspensionsPerPage, + groupedSuspensionsTotal + )}{' '} + of {groupedSuspensionsTotal} users +
+
+ + + Page {groupedSuspensionsPage} of{' '} + {Math.ceil( + groupedSuspensionsTotal / + groupedSuspensionsPerPage + )} + + +
+
+ )} + + )} + + )} + + {/* Grouped Warnings Tab */} + {activeHistoryTab === 'warnings' && ( + <> + {/* Smart Search Bar for Warnings */} +
+
+ +
+ { + setSuspendedSearchFilter(e.target.value); + handleUserInputChange(e); // trigger suggestions + clearTimeout(window.warningsSearchTimeout2); + window.warningsSearchTimeout2 = setTimeout(() => { + fetchGroupedWarnings(1, e.target.value); + }, 500); + }} + onFocus={() => { + if (userSuggestions.length > 0) { + setShowUserSuggestions(true); + } + }} + onBlur={() => { + setTimeout( + () => setShowUserSuggestions(false), + 200 + ); + }} + autoComplete="off" + /> + {/* User Suggestions Dropdown */} + {showUserSuggestions && userSuggestions.length > 0 && ( +
+ {userSuggestions.map((user) => ( +
{ + setSuspendedSearchFilter(user.username); + setShowUserSuggestions(false); + setUserSuggestions([]); + fetchGroupedWarnings(1, user.username); + }} + > + {`${user.username}'s +
+

+ {user.username} +

+

+ {user.points || 0} points • Joined{' '} + {new Date( + user.createdAt + ).toLocaleDateString()} +

+
+ {user.disabled && ( + + Disabled + + )} +
+ ))} +
+ )} +
+ {groupedWarningsLoading ? ( +
+
+

+ Loading grouped warnings... +

+
+ ) : groupedWarnings.length === 0 ? ( +
+
+ No warnings found +
+
+ ) : ( + <> + {/* Desktop View */} +
+
+ {groupedWarnings.map((userWarnings) => ( +
+ {/* User Header */} +
+
+ {userWarnings.username} { + e.target.src = `https://robohash.org/${userWarnings.username}.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+ {userWarnings.username} +
+
+ {userWarnings.user?.email || + 'No email'} +
+
+ + {userWarnings.totalWarnings}{' '} + Warnings + +
+
+
+ +
+ + {/* Expanded Details */} + {expandedWarningUsers.has( + userWarnings.userId + ) && ( +
+ {/* Warnings */} + {userWarnings.warnings.length > 0 && ( +
+

+ Warnings ( + {userWarnings.warnings.length}) +

+
+ {userWarnings.warnings.map( + (warning) => ( +
+
+ {warning.reason} +
+
+ {new Date( + warning.createdAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + warning.createdAt + ).toLocaleTimeString()}{' '} + by{' '} + {warning.warnedBy + ?.username || 'Unknown'} +
+
+ ) + )} +
+
+ )} +
+ )} +
+ ))} +
+
+ + {/* Mobile View */} +
+
+ {groupedWarnings.map((userWarnings) => ( +
+ {/* User Header */} +
+
+ {userWarnings.username} { + e.target.src = `https://robohash.org/${userWarnings.username}.png?set=set1&size=150x150`; + e.target.onerror = null; + }} + /> +
+
+ {userWarnings.username} +
+
+ {userWarnings.user?.email || + 'No email'} +
+
+ + {userWarnings.totalWarnings}{' '} + Warnings + +
+
+
+ +
+ {/* Expanded Details */} + {expandedWarningUsers.has( + userWarnings.userId + ) && ( +
+ {/* Warnings */} + {userWarnings.warnings.length > 0 && ( +
+

+ Warnings ( + {userWarnings.warnings.length}) +

+
+ {userWarnings.warnings.map( + (warning) => ( +
+
+ {warning.reason} +
+
+ {new Date( + warning.createdAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + warning.createdAt + ).toLocaleTimeString()}{' '} + by{' '} + {warning.warnedBy + ?.username || 'Unknown'} +
+ {warning.reactivatedAt && ( +
+ Reactivated:{' '} + {new Date( + warning.reactivatedAt + ).toLocaleDateString()}{' '} + at{' '} + {new Date( + warning.reactivatedAt + ).toLocaleTimeString()} +
+ )} +
+ ) + )} +
+
+ )} +
+ )} +
+ ))} +
+
+ {/* Pagination */} + {groupedWarningsTotal > groupedWarningsPerPage && ( +
+
+ Showing{' '} + {(groupedWarningsPage - 1) * + groupedWarningsPerPage + + 1}{' '} + to{' '} + {Math.min( + groupedWarningsPage * groupedWarningsPerPage, + groupedWarningsTotal + )}{' '} + of {groupedWarningsTotal} users +
+
+ + + Page {groupedWarningsPage} of{' '} + {Math.ceil( + groupedWarningsTotal / + groupedWarningsPerPage + )} + + +
+
+ )} + + )} + + )} +
+
+ )}
-
- - + + +