diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4a7ea30 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a6769ef --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +node_modules +dist +.kilo +*.lock +e2e/ +load/ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..5014f01 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,45 @@ +module.exports = { + root: true, + env: { + es2021: true, + }, + extends: ['eslint:recommended'], + parserOptions: { + ecmaVersion: 'latest', + }, + overrides: [ + { + files: ['api/**/*.js', '*.config.js', '*.config.mjs', '.eslintrc.js'], + env: { node: true, es2021: true }, + parserOptions: { sourceType: 'script' }, + rules: { + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'no-console': 'off', + }, + }, + { + files: ['pro/**/*.js', 'pro/**/*.jsx'], + env: { browser: true, es2021: true }, + parserOptions: { + sourceType: 'module', + ecmaFeatures: { jsx: true }, + }, + plugins: ['react', 'react-hooks'], + extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended'], + settings: { react: { version: 'detect' } }, + rules: { + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + 'no-console': 'off', + }, + }, + { + files: ['*.test.js', '*.test.jsx'], + env: { mocha: true, jest: true }, + rules: { + 'no-unused-expressions': 'off', + }, + }, + ], +}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6aeb5ff --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,157 @@ +name: CI + +on: + push: + branches: [main, fix/*, feat/*] + pull_request: + branches: [main] + +jobs: + api: + name: API (Server) + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: | + package-lock.json + api/package-lock.json + + - name: Install root dependencies + run: npm ci + working-directory: . + - name: Install API dependencies + run: npm ci + working-directory: api + - name: Lint + run: npx eslint --ext .js . --max-warnings 50 + working-directory: . + - name: Test + run: npm test + working-directory: api + + pro: + name: Frontend + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: | + package-lock.json + pro/package-lock.json + + - name: Install root dependencies + run: npm ci + working-directory: . + - name: Install Frontend dependencies + run: npm ci + working-directory: pro + - name: Lint + run: npx eslint --ext .js,.jsx . --max-warnings 50 + working-directory: . + - name: Test + run: npx vitest run + working-directory: pro + + e2e: + name: E2E (Playwright) + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: | + api/package-lock.json + pro/package-lock.json + + - name: Install API dependencies + run: npm ci + working-directory: api + + - name: Install Frontend dependencies + run: npm ci + working-directory: pro + + - name: Install E2E dependencies + run: npm install + working-directory: e2e + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + working-directory: e2e + + - name: Run E2E tests + run: npx playwright test + working-directory: e2e + env: + CI: true + + - name: Upload Playwright report + uses: actions/upload-artifact@v4 + if: failure() + with: + name: playwright-report + path: e2e/playwright-report/ + retention-days: 7 + + load: + name: Load Test + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: | + api/package-lock.json + + - name: Install API dependencies + run: npm ci + working-directory: api + + - name: Install Load Test dependencies + run: npm install + working-directory: load + + - name: Start API server + run: | + node index.js & + echo "Waiting for server..." + for i in $(seq 1 10); do + curl -s http://localhost:4000/health > /dev/null && echo "Server ready" && break + sleep 1 + done + working-directory: api + + - name: Run load test + run: node runner.js --connections 10 --duration 15 + working-directory: load + env: + LOAD_SERVER_URL: http://localhost:4000 + + - name: Stop API server + run: kill $(lsof -t -i:4000) 2>/dev/null || true + + - name: Upload load report + uses: actions/upload-artifact@v4 + if: always() + with: + name: load-report + path: load/*.log + retention-days: 7 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..2312dc5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.kilo/package-lock.json b/.kilo/package-lock.json new file mode 100644 index 0000000..29429a8 --- /dev/null +++ b/.kilo/package-lock.json @@ -0,0 +1,378 @@ +{ + "name": ".kilo", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@kilocode/plugin": "7.2.31" + } + }, + "node_modules/@kilocode/plugin": { + "version": "7.2.31", + "resolved": "https://registry.npmjs.org/@kilocode/plugin/-/plugin-7.2.31.tgz", + "integrity": "sha512-KmKTTIly7hRlJdXKhqZ/j/brvTPh0z0UTjWSjJWq5fqf4pATgYGn7G0g3ZjILnN7MUkkZXuljgqExTEeQJHGkQ==", + "license": "MIT", + "dependencies": { + "@kilocode/sdk": "7.2.31", + "effect": "4.0.0-beta.48", + "zod": "4.1.8" + }, + "peerDependencies": { + "@opentui/core": ">=0.1.100", + "@opentui/solid": ">=0.1.100" + }, + "peerDependenciesMeta": { + "@opentui/core": { + "optional": true + }, + "@opentui/solid": { + "optional": true + } + } + }, + "node_modules/@kilocode/sdk": { + "version": "7.2.31", + "resolved": "https://registry.npmjs.org/@kilocode/sdk/-/sdk-7.2.31.tgz", + "integrity": "sha512-Sx05yv+3TIlc6M4Ze+YGgKCLoIg8B0WRE15JXDriVncT+wz7M6+e+4mjNWkwfsuywdeOTYPfeFViqX8iO7ckKA==", + "license": "MIT", + "dependencies": { + "cross-spawn": "7.0.6" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/effect": { + "version": "4.0.0-beta.48", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-beta.48.tgz", + "integrity": "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "fast-check": "^4.6.0", + "find-my-way-ts": "^0.1.6", + "ini": "^6.0.0", + "kubernetes-types": "^1.30.0", + "msgpackr": "^1.11.9", + "multipasta": "^0.2.7", + "toml": "^4.1.1", + "uuid": "^13.0.0", + "yaml": "^2.8.3" + } + }, + "node_modules/fast-check": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.8.0.tgz", + "integrity": "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^8.0.0" + }, + "engines": { + "node": ">=12.17.0" + } + }, + "node_modules/find-my-way-ts": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.6.tgz", + "integrity": "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==", + "license": "MIT" + }, + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/kubernetes-types": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/kubernetes-types/-/kubernetes-types-1.30.0.tgz", + "integrity": "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==", + "license": "Apache-2.0" + }, + "node_modules/msgpackr": { + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.12.tgz", + "integrity": "sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==", + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multipasta": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/multipasta/-/multipasta-0.2.7.tgz", + "integrity": "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==", + "license": "MIT" + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pure-rand": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz", + "integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/toml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/toml/-/toml-4.1.1.tgz", + "integrity": "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/uuid": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.2.tgz", + "integrity": "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/zod": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.8.tgz", + "integrity": "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/.kilo/plans/1779339173170-crisp-wizard.md b/.kilo/plans/1779339173170-crisp-wizard.md new file mode 100644 index 0000000..df9d893 --- /dev/null +++ b/.kilo/plans/1779339173170-crisp-wizard.md @@ -0,0 +1,225 @@ +# Comprehensive Fix for DAB (Dots & Boxes) Game + +## Bugs Identified + +### 1. Loading State - No Room Creation/Join UI + +**File:** `pro/src/dab/DabGame.jsx` lines 361-370 + +- Shows "Connecting..." with no buttons to create/join a room +- Missing `handleCreateRoom` and `handleJoinRoom` functions + +### 2. Event Name Mismatches (Critical) + +| Component | Emits | Should Be | +| --------- | ------------------ | --------------------- | +| Backend | `dab_redoRequest` | → `dab_redoRequested` | +| Frontend | `dab_approveRedo` | → `dab_respondRedo` | +| Frontend | `dab_denyRedo` | → `dab_respondRedo` | +| Backend | `dab_redoAccepted` | → `dab_moveUndone` | + +**Verification:** + +- Backend line 174: `dab_redoRequest` +- Frontend line 253: listens for `dab_redoRequested` +- Backend line 14: listens for `dab_respondRedo` +- Frontend lines 707, 717: emit `dab_approveRedo`/`dab_denyRedo` +- Frontend line 264: listens for `dab_moveUndone` +- Backend line 214: emits `dab_redoAccepted` + +### 3. Crash Bug in Redo System + +**File:** `api/game-logic/dab.js` line 198 + +- `respondRedo` tries to destructure `room.redoRequest.lastMove` +- But `requestRedo` (lines 167-172) never stores `lastMove` or `claimedBox` in the request object +- **Result:** `TypeError: Cannot destructure property 'lineType' of 'undefined'` + +### 4. Memory Leak in Frontend + +**File:** `pro/src/dab/DabGame.jsx` line 296 + +- `useEffect` dependency array includes `[socket, players, rows, cols, playLine, playBox]` +- When `players`, `rows`, `cols` change, new socket listeners are added without proper cleanup +- **Result:** Multiple listeners fire for single events + +--- + +## Fix Implementation + +### Phase 1: Backend Fixes (`api/game-logic/dab.js`) + +#### 1.1 Fix Event Name: `dab_redoRequest` → `dab_redoRequested` + +**Line 174:** + +```javascript +// Change from: +this.io.to(room.id).emit('dab_redoRequest', {...}); +// To: +this.io.to(room.id).emit('dab_redoRequested', { requester: room.players[playerIndex].name }); +``` + +#### 1.2 Fix RedoRequest Object - Store Move Data + +**Lines 167-172 - Replace with:** + +```javascript +room.redoRequest = { + requesterId: socket.id, + requesterIndex: playerIndex, + requesterName: room.players[playerIndex].name, + targetId: prevPlayer.id, + targetIndex: prevPlayerIndex, + lastMove: room.lastMove ? { ...room.lastMove } : null, // CRITICAL FIX + claimedBox: room.lastClaimedBox || null, // Track last claimed box +}; +``` + +#### 1.3 Track lastClaimedBox in makeMove + +**After line 299 (after checkBoxes call):** + +```javascript +// Track last claimed box for potential redo: +if (claimedBoxes.length > 0) { + room.lastClaimedBox = claimedBoxes[claimedBoxes.length - 1]; +} +``` + +#### 1.4 Fix Event Name: `dab_redoAccepted` → `dab_moveUndone` + +**Lines 214-221 - Replace with:** + +```javascript +if (accept) { + const { lineType, r, c } = room.redoRequest.lastMove; + if (lineType === 'h') { + room.horizontalLines[r][c] = null; + } else { + room.verticalLines[r][c] = null; + } + const claimedBox = room.redoRequest.claimedBox; + if (claimedBox) { + room.boxes[claimedBox.r][claimedBox.c] = null; + room.scores[room.redoRequest.requesterIndex]--; + } + room.lastMove = null; + room.lastClaimedBox = null; + room.currentTurn = room.redoRequest.targetIndex; + + // Emit full state update that frontend expects: + this.io.to(room.id).emit('dab_moveUndone', { + horizontalLines: room.horizontalLines, + verticalLines: room.verticalLines, + boxes: room.boxes, + scores: [...room.scores], + currentTurn: room.currentTurn, + }); +} +``` + +#### 1.5 Add `dab_startGame` Listener + +**Add in handleConnection (line 15):** + +```javascript +socket.on('dab_startGame', (data) => this.startGame(socket, data)); +``` + +**Add new method:** + +```javascript +startGame(socket, { roomId }) { + const room = this.rooms.get(roomId); + if (!room || room.creator !== socket.id) return; + room.gameState = 'playing'; + this.io.to(roomId).emit('dab_gameStarted', { firstTurn: room.players[0].id }); + this.sendRoomInfo(roomId); +} +``` + +--- + +### Phase 2: Frontend Fixes (`pro/src/dab/DabGame.jsx`) + +#### 2.1 Add Create/Join Room Functions + +**After line 75 (after reconnectAttempted ref):** + +```javascript +const handleCreateRoom = () => { + logger.socket('➡️', 'dab_createRoom', { mode, customRows, customCols, customPlayers, playerName }); + socket.emit('dab_createRoom', { mode, customRows, customCols, customPlayers, playerName }); +}; + +const handleJoinRoom = async () => { + const { value: joinRoomId } = await Swal.fire({ + title: 'Join DAB Room', + input: 'text', + inputPlaceholder: 'Enter Room ID', + showCancelButton: true, + customClass: { popup: 'sketch-popup' }, + }); + if (joinRoomId) { + logger.socket('➡️', 'dab_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); + socket.emit('dab_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); + } +}; +``` + +#### 2.2 Replace Loading Screen with Lobby UI + +**Lines 361-370 - Replace:** + +```javascript +{!roomId ? ( +
+
+

Dots & Boxes

+
+ + +
+ {/* Mode selection UI here */} +
+
+) : (...existing game UI...)} +``` + +#### 2.3 Fix Redo Response Event Names + +**Line 708:** + +```javascript +socket.emit('dab_respondRedo', { roomId, accept: true }); +``` + +**Line 717:** + +```javascript +socket.emit('dab_respondRedo', { roomId, accept: false }); +``` + +#### 2.4 Fix useEffect Memory Leak + +**Line 296 - Change dependency array:** + +```javascript +}, [socket]); // Remove players, rows, cols, playLine, playBox +``` + +For state values that change, use refs or functional updates inside the effect. + +--- + +## Testing Checklist + +- [ ] Navigate to `/dab` → See Create/Join buttons (not "Connecting...") +- [ ] Create Room → Room code displayed +- [ ] Join Room → Second player added +- [ ] Game starts automatically when room is full +- [ ] `dab_redoRequested` event received on frontend +- [ ] `dab_respondRedo` reaches backend +- [ ] `dab_moveUndone` received with full board state +- [ ] No duplicate event listeners (check memory usage) diff --git a/.kilo/plans/1779339733462-quiet-meadow.md b/.kilo/plans/1779339733462-quiet-meadow.md new file mode 100644 index 0000000..6ab09d4 --- /dev/null +++ b/.kilo/plans/1779339733462-quiet-meadow.md @@ -0,0 +1,40 @@ +# Reusable Sketch-Style Components for Paper Hand-Drawn UI + +## Status: COMPLETED ✓ + +## Components Created + +1. `SketchButton.jsx` - Hand-drawn style button with sketch wobble effect +2. `SketchCard.jsx` - Paper-like card container with double border +3. `SketchBorder.jsx` - Dashed border section container +4. `PlayerBadge.jsx` - Player indicator with color coding and disconnected state +5. `ModeSelector.jsx` - Game mode selection with classic/custom toggle and sliders +6. `LeaveButton.jsx` - Leave game button with confirmation dialog +7. `SketchPopup.jsx` - Exports `sketchPopupClass` constant for SweetAlert +8. `index.js` - Barrel export for all components +9. `RoomLobby.jsx` - Create/join room screen (created but not integrated) + +## Files Modified + +- `pro/src/index.css` - Moved all sketch styles from inline ` + + +
+ + + \ No newline at end of file diff --git a/e2e/playwright.config.js b/e2e/playwright.config.js new file mode 100644 index 0000000..6dad382 --- /dev/null +++ b/e2e/playwright.config.js @@ -0,0 +1,37 @@ +const { defineConfig } = require('@playwright/test'); +const path = require('path'); + +const API_PORT = 4000; +const FRONTEND_PORT = 5173; +const BASE_URL = `http://localhost:${FRONTEND_PORT}`; + +module.exports = defineConfig({ + testDir: '.', + testMatch: '*.spec.js', + timeout: 60000, + fullyParallel: false, + retries: process.env.CI ? 1 : 0, + workers: 1, + reporter: [['list'], ['html', { outputFolder: 'playwright-report' }]], + use: { + baseURL: BASE_URL, + trace: 'on-first-retry', + screenshot: 'only-on-failure', + }, + webServer: [ + { + command: `node ${path.resolve(__dirname, '..', 'api', 'index.js')}`, + port: API_PORT, + timeout: 15000, + reuseExistingServer: !process.env.CI, + cwd: path.resolve(__dirname, '..', 'api'), + }, + { + command: `npx vite --port ${FRONTEND_PORT} --host 0.0.0.0`, + port: FRONTEND_PORT, + timeout: 30000, + reuseExistingServer: !process.env.CI, + cwd: path.resolve(__dirname, '..', 'pro'), + }, + ], +}); diff --git a/e2e/reconnect.spec.js b/e2e/reconnect.spec.js new file mode 100644 index 0000000..1b8f878 --- /dev/null +++ b/e2e/reconnect.spec.js @@ -0,0 +1,179 @@ +const { test, expect } = require('@playwright/test'); +const { + navigateToGame, + clickCreateRoom, + getRoomCode, + clickJoinRoom, + fillSwalInput, + confirmSwal, + dismissSwalIfPresent, +} = require('./helpers'); + +test.describe('Reconnect E2E', () => { + test('TTT: make a move and verify it syncs to other player', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => localStorage.setItem('playerName', 'Alpha')); + await page2.addInitScript(() => localStorage.setItem('playerName', 'Beta')); + await page1.goto('/'); + await page2.goto('/'); + + await navigateToGame(page1, '/tictactoe'); + await page1.waitForTimeout(500); + await clickCreateRoom(page1, 'Create'); + const roomCode = await getRoomCode(page1); + expect(roomCode).toBeTruthy(); + + await navigateToGame(page2, '/tictactoe'); + await page2.waitForTimeout(500); + await clickJoinRoom(page2, 'Join'); + await fillSwalInput(page2, roomCode); + await confirmSwal(page2); + + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + await dismissSwalIfPresent(page1); + await dismissSwalIfPresent(page2); + + const boardSelector = '.grid.grid-cols-3'; + + // P1 makes a move (position 4 = center) + await clickCell(page1, boardSelector, 4); + await page2.waitForTimeout(800); + + // Verify P2 sees the X + const p2cells = page2.locator(boardSelector).locator('button'); + await expect(p2cells.nth(4)).toHaveText('X'); + + await ctx.close(); + }); + + test('TTT: disconnect and reconnect preserves game state', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => localStorage.setItem('playerName', 'Xena')); + await page2.addInitScript(() => localStorage.setItem('playerName', 'Odin')); + await page1.goto('/'); + await page2.goto('/'); + + await navigateToGame(page1, '/tictactoe'); + await page1.waitForTimeout(500); + await clickCreateRoom(page1, 'Create'); + const roomCode = await getRoomCode(page1); + expect(roomCode).toBeTruthy(); + + await navigateToGame(page2, '/tictactoe'); + await page2.waitForTimeout(500); + await clickJoinRoom(page2, 'Join'); + await fillSwalInput(page2, roomCode); + await confirmSwal(page2); + + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + await dismissSwalIfPresent(page1); + await dismissSwalIfPresent(page2); + + const boardSelector = '.grid.grid-cols-3'; + + // Xena (P1, X) moves: position 0 + await clickCell(page1, boardSelector, 0); + await page2.waitForTimeout(500); + + // Odin (P2, O) moves: position 4 + await clickCell(page2, boardSelector, 4); + await page1.waitForTimeout(500); + + // Save reconnect info before disconnecting P2 + const reconnectInfo = await page2.evaluate(() => { + return sessionStorage.getItem('ttt_reconnect'); + }); + expect(reconnectInfo).toBeTruthy(); + + // Close P2 (simulate disconnect) + await page2.close(); + + // Game pauses on server. Wait for pause to propagate. + await page1.waitForTimeout(2000); + + // Open a new page for Odin to reconnect + const page2Re = await ctx.newPage(); + await page2Re.addInitScript(() => localStorage.setItem('playerName', 'Odin')); + await page2Re.addInitScript((info) => { + sessionStorage.setItem('ttt_reconnect', info); + }, reconnectInfo); + await page2Re.goto('/tictactoe'); + await page2Re.waitForTimeout(3000); + + // Odin should see Xena's X at position 0 + const reP2cells = page2Re.locator(boardSelector).locator('button'); + await expect(reP2cells.nth(0)).toHaveText('X'); + // Odin's own O at position 4 should still be there + await expect(reP2cells.nth(4)).toHaveText('O'); + + // Game should be resumed (playing) and it should be Xena's turn + await expect(page2Re.locator('text=Waiting')).toBeVisible({ timeout: 5000 }); + + await ctx.close(); + }); + + test('full TTT game plays to completion', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => localStorage.setItem('playerName', 'Xena')); + await page2.addInitScript(() => localStorage.setItem('playerName', 'Odin')); + await page1.goto('/'); + await page2.goto('/'); + + await navigateToGame(page1, '/tictactoe'); + await page1.waitForTimeout(500); + await clickCreateRoom(page1, 'Create'); + const roomCode = await getRoomCode(page1); + expect(roomCode).toBeTruthy(); + + await navigateToGame(page2, '/tictactoe'); + await page2.waitForTimeout(500); + await clickJoinRoom(page2, 'Join'); + await fillSwalInput(page2, roomCode); + await confirmSwal(page2); + + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + await dismissSwalIfPresent(page1); + await dismissSwalIfPresent(page2); + + const boardSelector = '.grid.grid-cols-3'; + + // X wins with top row: positions 0, 1, 2 + // X: 0 → O: 3 → X: 1 → O: 6 → X: 2 (X wins!) + await clickCell(page1, boardSelector, 0); + await clickCell(page2, boardSelector, 3); + await clickCell(page1, boardSelector, 1); + await clickCell(page2, boardSelector, 6); + await clickCell(page1, boardSelector, 2); + + await page1.waitForTimeout(2000); + await page2.waitForTimeout(1500); + + // Rematch button should appear (from MatchReport) + const playAgain1 = page1.locator('button:has-text("Rematch")'); + const playAgain2 = page2.locator('button:has-text("Rematch")'); + await expect(playAgain1).toBeVisible({ timeout: 5000 }); + await expect(playAgain2).toBeVisible({ timeout: 5000 }); + + await ctx.close(); + }); +}); + +async function clickCell(page, boardSelector, index) { + const cell = page.locator(boardSelector).locator('button').nth(index); + await cell.waitFor({ state: 'visible', timeout: 5000 }); + await page.waitForTimeout(300); + await cell.click({ force: true }); + await page.waitForTimeout(500); +} diff --git a/e2e/sos.spec.js b/e2e/sos.spec.js new file mode 100644 index 0000000..2e4181c --- /dev/null +++ b/e2e/sos.spec.js @@ -0,0 +1,139 @@ +const { test, expect } = require('@playwright/test'); +const { navigateToGame, clickCreateRoom, dismissSwalIfPresent } = require('./helpers'); + +test.describe('SOS E2E', () => { + test('full flow: create room, join, start game, make moves', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => + localStorage.setItem('playerProfile', JSON.stringify({ name: 'Alice', avatarIcon: 'cat', color: '#2a2a3e' })), + ); + await page2.addInitScript(() => + localStorage.setItem('playerProfile', JSON.stringify({ name: 'Bob', avatarIcon: 'fox', color: '#2a2a3e' })), + ); + await page1.goto('/'); + await page2.goto('/'); + + // Navigate and create room + await navigateToGame(page1, '/sos'); + await page1.waitForTimeout(500); + await clickCreateRoom(page1); + + // Wait for GameLobby and read room code from

element + const roomCodeEl = page1.locator('p.text-3xl.font-sketch.text-ink.tracking-widest'); + await roomCodeEl.waitFor({ state: 'visible', timeout: 10000 }); + const roomCode = await roomCodeEl.textContent(); + expect(roomCode).toBeTruthy(); + + // Navigate P2 to the game + await navigateToGame(page2, '/sos'); + await page2.waitForTimeout(1000); + + // Fill room code and join + const joinInput = page2.locator('input[placeholder="Room Code"]'); + await joinInput.waitFor({ state: 'visible', timeout: 5000 }); + await joinInput.fill(roomCode); + await page2.locator('button:has-text("Join as Player")').click(); + + // Wait for P2's GameLobby to appear + const p2RoomCodeEl = page2.locator('p.text-3xl.font-sketch.text-ink.tracking-widest'); + await p2RoomCodeEl.waitFor({ state: 'visible', timeout: 10000 }); + + // Both should see the room code in GameLobby + await expect(page1.locator('p.text-3xl.font-sketch.text-ink.tracking-widest')).toHaveText(roomCode); + await expect(p2RoomCodeEl).toHaveText(roomCode); + + // Dismiss any modals + await dismissSwalIfPresent(page1); + await dismissSwalIfPresent(page2); + + // Start game via host + await page1.locator('button:has-text("Start Game")').click(); + await page1.waitForTimeout(2000); + await page2.waitForTimeout(2000); + + // Both should see the game board with 36 cells (6x6 default) + const grid1 = page1.locator('.grid.gap-1.p-4.sketch-card'); + const grid2 = page2.locator('.grid.gap-1.p-4.sketch-card'); + await expect(grid1).toBeVisible(); + await expect(grid2).toBeVisible(); + + const cells1 = grid1.locator('button'); + const cells2 = grid2.locator('button'); + await expect(cells1).toHaveCount(36); + await expect(cells2).toHaveCount(36); + + // Alice (P1) selects 'S' and places at row 0, col 0 + await page1.getByRole('button', { name: 'S', exact: true }).click(); + await cells1.nth(0).click(); + await page1.waitForTimeout(800); + await page2.waitForTimeout(800); + + await expect(cells1.nth(0)).toHaveText('S'); + await expect(cells2.nth(0)).toHaveText('S'); + + // Bob (P2) selects 'O' and places at row 0, col 1 + await page2.getByRole('button', { name: 'O', exact: true }).click(); + await cells2.nth(1).click(); + await page1.waitForTimeout(800); + await page2.waitForTimeout(800); + + await expect(cells1.nth(1)).toHaveText('O'); + await expect(cells2.nth(1)).toHaveText('O'); + + await ctx.close(); + }); + + test('board size selection creates correct grid', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => + localStorage.setItem('playerProfile', JSON.stringify({ name: 'Tester', avatarIcon: 'cat', color: '#2a2a3e' })), + ); + await page2.addInitScript(() => + localStorage.setItem('playerProfile', JSON.stringify({ name: 'Tester2', avatarIcon: 'fox', color: '#2a2a3e' })), + ); + await page1.goto('/'); + await page2.goto('/'); + + await navigateToGame(page1, '/sos'); + await page1.waitForTimeout(500); + + // Change board size to 4x4 + await page1.locator('select.sketch-input').selectOption('4'); + await page1.waitForTimeout(300); + + // Create room + await clickCreateRoom(page1); + const roomCodeEl = page1.locator('p.text-3xl.font-sketch.text-ink.tracking-widest'); + await roomCodeEl.waitFor({ state: 'visible', timeout: 10000 }); + const roomCode = await roomCodeEl.textContent(); + expect(roomCode).toBeTruthy(); + + // P2 join + await navigateToGame(page2, '/sos'); + await page2.waitForTimeout(1000); + const joinInput = page2.locator('input[placeholder="Room Code"]'); + await joinInput.waitFor({ state: 'visible', timeout: 5000 }); + await joinInput.fill(roomCode); + await page2.locator('button:has-text("Join as Player")').click(); + await page2 + .locator('p.text-3xl.font-sketch.text-ink.tracking-widest') + .waitFor({ state: 'visible', timeout: 10000 }); + + // Start game + await page1.locator('button:has-text("Start Game")').click(); + await page1.waitForTimeout(1500); + await page2.waitForTimeout(1500); + + // Verify 4x4 = 16 cells + const grid = page1.locator('.grid.gap-1.p-4.sketch-card'); + await expect(grid.locator('button')).toHaveCount(16); + + await ctx.close(); + }); +}); diff --git a/e2e/test-results/.last-run.json b/e2e/test-results/.last-run.json new file mode 100644 index 0000000..f740f7c --- /dev/null +++ b/e2e/test-results/.last-run.json @@ -0,0 +1,4 @@ +{ + "status": "passed", + "failedTests": [] +} diff --git a/e2e/tictactoe.spec.js b/e2e/tictactoe.spec.js new file mode 100644 index 0000000..1fdc261 --- /dev/null +++ b/e2e/tictactoe.spec.js @@ -0,0 +1,85 @@ +const { test, expect } = require('@playwright/test'); +const { + navigateToGame, + clickCreateRoom, + getRoomCode, + clickJoinRoom, + fillSwalInput, + confirmSwal, + dismissSwalIfPresent, +} = require('./helpers'); + +test.describe('TicTacToe E2E', () => { + test('full flow: create room, join, play game to win, restart', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => localStorage.setItem('playerName', 'Xena')); + await page2.addInitScript(() => localStorage.setItem('playerName', 'Odin')); + await page1.goto('/'); + await page2.goto('/'); + + // Navigate and create room + await navigateToGame(page1, '/tictactoe'); + await page1.waitForTimeout(1500); + await clickCreateRoom(page1, 'Create'); + const roomCode = await getRoomCode(page1); + expect(roomCode).toBeTruthy(); + + // Join room + await navigateToGame(page2, '/tictactoe'); + await page2.waitForTimeout(500); + await clickJoinRoom(page2, 'Join'); + await page2.waitForTimeout(500); + await fillSwalInput(page2, roomCode); + await confirmSwal(page2); + + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + await dismissSwalIfPresent(page1); + await dismissSwalIfPresent(page2); + + // Both should see the room code + await expect(page1.locator('button[title="Click to copy room ID"]')).toHaveText(roomCode); + await expect(page2.locator('button[title="Click to copy room ID"]')).toHaveText(roomCode); + + // Play a game: Xena goes first (X) + const boardSelector = '.grid.grid-cols-3'; + + // Xena: position 0 + const board1 = page1.locator(boardSelector); + await board1.locator('button').nth(0).click(); + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + + // Odin: position 4 + const board2 = page2.locator(boardSelector); + await board2.locator('button').nth(4).click(); + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + + // Xena: position 1 + await board1.locator('button').nth(1).click(); + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + + // Odin: position 5 + await board2.locator('button').nth(5).click(); + await page1.waitForTimeout(1000); + await page2.waitForTimeout(1000); + + // Xena: position 2 - wins! + await board1.locator('button').nth(2).click(); + + // Wait for game end + await page1.waitForTimeout(2000); + await page2.waitForTimeout(2000); + + // Both should see Rematch button (from MatchReport) + await expect(page1.locator('button:has-text("Rematch")')).toBeVisible(); + await expect(page2.locator('button:has-text("Rematch")')).toBeVisible(); + + await ctx.close(); + }); +}); diff --git a/e2e/uttt.spec.js b/e2e/uttt.spec.js new file mode 100644 index 0000000..c59677c --- /dev/null +++ b/e2e/uttt.spec.js @@ -0,0 +1,128 @@ +const { test, expect } = require('@playwright/test'); +const { + navigateToGame, + clickCreateRoom, + getRoomCode, + clickJoinRoom, + fillSwalInput, + confirmSwal, + dismissSwalIfPresent, +} = require('./helpers'); + +test.describe('UTTT E2E', () => { + test('create room, join, play a few moves, verify board updates', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => localStorage.setItem('playerName', 'Alpha')); + await page2.addInitScript(() => localStorage.setItem('playerName', 'Beta')); + await page1.goto('/'); + await page2.goto('/'); + + // Manually create/join + await navigateToGame(page1, '/uttt'); + await page1.waitForTimeout(2000); + await clickCreateRoom(page1, 'Create Room'); + const roomCode = await getRoomCode(page1); + expect(roomCode).toBeTruthy(); + + await navigateToGame(page2, '/uttt'); + await page2.waitForTimeout(2000); + await clickJoinRoom(page2, 'Join Room'); + await fillSwalInput(page2, roomCode); + await confirmSwal(page2); + + await page1.waitForTimeout(1500); + await page2.waitForTimeout(1500); + + await expect(page1.locator('button[title="Click to copy room ID"]')).toHaveText(roomCode); + await expect(page2.locator('button[title="Click to copy room ID"]')).toHaveText(roomCode); + + // All 81 cell buttons should be present + const allCells = page1.locator('button.font-sketch:not(nav button)'); + await expect(allCells.first()).toBeAttached(); + + // Pick the first clickable cell on P1's board and click it (grid 4, cell 4 = center) + const macroGrid = page1.locator('.relative.grid.grid-cols-3').first(); + const innerGridContainers = macroGrid.locator('> div:not(.absolute)'); + const centerGrid = innerGridContainers.nth(4); + const centerGridCells = centerGrid.locator('button'); + await centerGridCells.nth(4).click(); + await page1.waitForTimeout(800); + await page2.waitForTimeout(800); + + // P2 should see the move reflected + const p2MacroGrid = page2.locator('.relative.grid.grid-cols-3').first(); + const p2InnerGrids = p2MacroGrid.locator('> div:not(.absolute)'); + const p2CenterGrid = p2InnerGrids.nth(4); + const p2Cells = p2CenterGrid.locator('button'); + + // Wait and check P2 made a move (they play in grid 4 too since last move sent them there) + await page2.waitForTimeout(1000); + const isBetasTurn = await page2 + .locator('text=Your Turn') + .isVisible() + .catch(() => false); + if (isBetasTurn) { + const available = p2Cells.filter({ hasNotText: /[XO]/ }); + const count = await available.count(); + if (count > 0) { + await available.first().click(); + await page1.waitForTimeout(800); + } + } + + // Verify P1 can make another move + await page1.waitForTimeout(500); + await expect(page1.locator('text=Your Turn').or(page1.locator('text=Waiting'))).toBeVisible({ timeout: 5000 }); + + await ctx.close(); + }); + + test('displays grid hint for active grid', async ({ browser }) => { + const ctx = await browser.newContext(); + const page1 = await ctx.newPage(); + const page2 = await ctx.newPage(); + + await page1.addInitScript(() => localStorage.setItem('playerName', 'A')); + await page2.addInitScript(() => localStorage.setItem('playerName', 'B')); + await page1.goto('/'); + await page2.goto('/'); + + // Manually create/join + await navigateToGame(page1, '/uttt'); + await page1.waitForTimeout(2000); + await clickCreateRoom(page1, 'Create Room'); + const roomCode = await getRoomCode(page1); + expect(roomCode).toBeTruthy(); + + await navigateToGame(page2, '/uttt'); + await page2.waitForTimeout(2000); + await clickJoinRoom(page2, 'Join Room'); + await fillSwalInput(page2, roomCode); + await confirmSwal(page2); + + await page1.waitForTimeout(1500); + await page2.waitForTimeout(1500); + + // P1 clicks grid 0, cell 0 — sends P2 to grid 0 + const macroGrid = page1.locator('.relative.grid.grid-cols-3').first(); + const innerGrids = macroGrid.locator('> div:not(.absolute)'); + await innerGrids.nth(0).locator('button').nth(0).click(); + await page1.waitForTimeout(800); + await page2.waitForTimeout(800); + + // P2 should see the grid hint: "You must play in grid 1" + // Wait for hint to appear after state update + await page2.waitForTimeout(500); + const hintVisible = await page2 + .locator('div.font-handwriting') + .filter({ hasText: /You must play in grid/ }) + .isVisible() + .catch(() => false); + expect(hintVisible).toBeTruthy(); + + await ctx.close(); + }); +}); diff --git a/load/games/bingo.js b/load/games/bingo.js new file mode 100644 index 0000000..47e43d7 --- /dev/null +++ b/load/games/bingo.js @@ -0,0 +1,112 @@ +const { io } = require('socket.io-client'); +const { SERVER_URL, stats, sleep } = require('../runner'); + +const PLAYER_NAMES = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo']; + +async function runScenario() { + const p1 = await createClient(); + if (!p1.socket) return; + + const p2 = await createClient(); + if (!p2.socket) { + p1.socket.close(); + return; + } + + try { + let roomId = null; + + // P1 creates room + p1.socket.emit('bingo_createRoom', PLAYER_NAMES[Math.floor(Math.random() * PLAYER_NAMES.length)]); + + roomId = await waitForRoomId(p1.socket, 'bingo_roomInfo'); + + if (!roomId) { + p1.socket.close(); + p2.socket.close(); + return; + } + + await sleep(200); + + // P2 joins + p2.socket.emit('bingo_joinRoom', { + roomId, + playerName: PLAYER_NAMES[Math.floor(Math.random() * PLAYER_NAMES.length)], + }); + + await waitForRoomId(p2.socket, 'bingo_roomInfo'); + + await sleep(300); + + // Start game + p1.socket.emit('bingo_startGame', roomId); + await sleep(500); + + // P1 marks some numbers + for (let i = 0; i < 3; i++) { + const moveStart = Date.now(); + p1.socket.emit('bingo_markNumber', { roomId, number: i + 1 }); + stats.totalMoves++; + + await new Promise((resolve) => { + const onMarked = () => { + stats.moveLatencies.push(Date.now() - moveStart); + resolve(); + }; + p1.socket.once('bingo_numberMarked', onMarked); + setTimeout(resolve, 2000); + }); + + await sleep(200); + } + } catch (err) { + stats.failedMoves++; + stats.errors.push(err.message); + } + + setTimeout(() => { + p1.socket.close(); + p2.socket.close(); + }, 300); +} + +function createClient() { + const start = Date.now(); + const socket = io(SERVER_URL, { + transports: ['websocket'], + forceNew: true, + }); + + return new Promise((resolve) => { + const timeout = setTimeout(() => { + socket.close(); + resolve({ socket: null }); + }, 5000); + + socket.on('connect', () => { + clearTimeout(timeout); + stats.successfulConnections++; + stats.connectionLatencies.push(Date.now() - start); + resolve({ socket }); + }); + + socket.on('connect_error', () => { + clearTimeout(timeout); + stats.failedConnections++; + resolve({ socket: null }); + }); + }); +} + +function waitForRoomId(socket, event) { + return new Promise((resolve) => { + const timeout = setTimeout(() => resolve(null), 3000); + socket.once(event, (data) => { + clearTimeout(timeout); + resolve(data.id); + }); + }); +} + +module.exports = { runScenario }; diff --git a/load/games/tictactoe.js b/load/games/tictactoe.js new file mode 100644 index 0000000..b83346d --- /dev/null +++ b/load/games/tictactoe.js @@ -0,0 +1,145 @@ +const { io } = require('socket.io-client'); +const { SERVER_URL, stats, sleep } = require('../runner'); + +const PLAYER_NAMES = [ + 'Alpha', + 'Bravo', + 'Charlie', + 'Delta', + 'Echo', + 'Foxtrot', + 'Golf', + 'Hotel', + 'India', + 'Juliet', + 'Kilo', + 'Lima', + 'Mike', + 'November', + 'Oscar', +]; + +async function runScenario() { + const name = PLAYER_NAMES[Math.floor(Math.random() * PLAYER_NAMES.length)]; + const opponentName = PLAYER_NAMES[Math.floor(Math.random() * PLAYER_NAMES.length)]; + + const p1 = await createConnectedClient(name); + if (!p1.socket) return; + + const p2 = await createConnectedClient(opponentName); + if (!p2.socket) { + p1.socket.close(); + return; + } + + const p1Socket = p1.socket; + const p2Socket = p2.socket; + + try { + let roomId = null; + + // P1 creates room + await emitAndWait(p1Socket, 'ttt_createRoom', name, 'ttt_roomInfo'); + roomId = await getRoomId(p1Socket); + + if (!roomId) { + p1Socket.close(); + p2Socket.close(); + return; + } + + // P2 joins room + await emitAndWait(p2Socket, 'ttt_joinRoom', { roomId, playerName: opponentName }, 'ttt_roomInfo'); + + await sleep(300); + + // Play a few moves + const moves = [4, 1, 2, 7, 6]; + for (let i = 0; i < moves.length; i++) { + const isP1Turn = i % 2 === 0; + const socket = isP1Turn ? p1Socket : p2Socket; + const pos = moves[i]; + + const moveStart = Date.now(); + socket.emit('ttt_makeMove', { roomId, position: pos }); + stats.totalMoves++; + + // Wait for move to be confirmed + await new Promise((resolve) => { + const onMove = () => { + socket.off('ttt_moveMade', onMove); + socket.off('ttt_gameWon', onMove); + socket.off('ttt_gameDraw', onMove); + stats.moveLatencies.push(Date.now() - moveStart); + resolve(); + }; + socket.once('ttt_moveMade', onMove); + socket.once('ttt_gameWon', onMove); + socket.once('ttt_gameDraw', onMove); + setTimeout(resolve, 2000); + }); + + await sleep(150); + } + } catch (err) { + stats.failedMoves++; + stats.errors.push(err.message); + } + + // Cleanup + setTimeout(() => { + p1Socket.close(); + p2Socket.close(); + }, 500); +} + +async function createConnectedClient(name) { + const start = Date.now(); + const socket = io(SERVER_URL, { + transports: ['websocket'], + forceNew: true, + }); + + return new Promise((resolve) => { + const timeout = setTimeout(() => { + socket.close(); + resolve({ socket: null, latency: null }); + }, 5000); + + socket.on('connect', () => { + clearTimeout(timeout); + stats.successfulConnections++; + stats.connectionLatencies.push(Date.now() - start); + resolve({ socket, latency: Date.now() - start }); + }); + + socket.on('connect_error', () => { + clearTimeout(timeout); + stats.failedConnections++; + resolve({ socket: null, latency: null }); + }); + }); +} + +function emitAndWait(socket, event, data, responseEvent) { + return new Promise((resolve) => { + const timeout = setTimeout(() => resolve(), 3000); + socket.once(responseEvent, () => { + clearTimeout(timeout); + resolve(); + }); + socket.emit(event, data); + }); +} + +function getRoomId(socket) { + return new Promise((resolve) => { + const timeout = setTimeout(() => resolve(null), 3000); + socket.once('ttt_roomInfo', (room) => { + clearTimeout(timeout); + resolve(room.id); + }); + }); +} + +module.exports = { runScenario }; diff --git a/load/package-lock.json b/load/package-lock.json new file mode 100644 index 0000000..c51be01 --- /dev/null +++ b/load/package-lock.json @@ -0,0 +1,123 @@ +{ + "name": "socket.io-games-load", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "socket.io-games-load", + "version": "1.0.0", + "dependencies": { + "socket.io-client": "^4.8.3" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io-client": { + "version": "6.6.5", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.5.tgz", + "integrity": "sha512-QCwxUDULPlXv8F6tqMMKx5dNkTe6OaBYRMPYeXKBlyOoKvAmE0ac6pW7fFhSscJ/5SI7666/U/B+MElbsrJlIg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.20.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/socket.io-client": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ws": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + } + } +} diff --git a/load/package.json b/load/package.json new file mode 100644 index 0000000..f7784fd --- /dev/null +++ b/load/package.json @@ -0,0 +1,14 @@ +{ + "name": "socket.io-games-load", + "version": "1.0.0", + "private": true, + "scripts": { + "test": "node runner.js", + "test:ttt": "node runner.js --game tictactoe --connections 10 --duration 30", + "test:bingo": "node runner.js --game bingo --connections 10 --duration 30", + "test:http": "node runner.js --http-only" + }, + "dependencies": { + "socket.io-client": "^4.8.3" + } +} diff --git a/load/runner.js b/load/runner.js new file mode 100644 index 0000000..75dd4d9 --- /dev/null +++ b/load/runner.js @@ -0,0 +1,257 @@ +const { io } = require('socket.io-client'); +const { createServer } = require('http'); +const path = require('path'); + +const SERVER_URL = process.env.LOAD_SERVER_URL || 'http://localhost:4000'; +const DEFAULT_CONNECTIONS = parseInt(process.env.LOAD_CONNECTIONS || '20', 10); +const DEFAULT_DURATION = parseInt(process.env.LOAD_DURATION || '30', 10); + +const stats = { + totalConnections: 0, + successfulConnections: 0, + failedConnections: 0, + totalMoves: 0, + failedMoves: 0, + moveLatencies: [], + connectionLatencies: [], + errors: [], + startTime: null, + endTime: null, +}; + +function createClient(options = {}) { + const start = Date.now(); + const socket = io(SERVER_URL, { + transports: ['websocket'], + forceNew: true, + ...options, + }); + + return new Promise((resolve) => { + const timeout = setTimeout(() => { + socket.close(); + resolve({ socket: null, latency: null, error: 'Connection timeout' }); + }, 5000); + + socket.on('connect', () => { + clearTimeout(timeout); + const latency = Date.now() - start; + stats.successfulConnections++; + stats.connectionLatencies.push(latency); + resolve({ socket, latency }); + }); + + socket.on('connect_error', (err) => { + clearTimeout(timeout); + stats.failedConnections++; + stats.errors.push(err.message); + resolve({ socket: null, latency: null, error: err.message }); + }); + }); +} + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +async function simulateGame(scenarioFn, numConnections, durationSec) { + stats.startTime = Date.now(); + stats.totalConnections = numConnections; + + console.log(`\n========================================`); + console.log(` LOAD TEST: ${scenarioFn.name || 'custom'}`); + console.log(` Connections: ${numConnections}`); + console.log(` Duration: ${durationSec}s`); + console.log(` Server: ${SERVER_URL}`); + console.log(`========================================\n`); + + const endTime = Date.now() + durationSec * 1000; + const results = []; + + while (Date.now() < endTime) { + const batchSize = Math.min(4, numConnections - stats.totalConnections); + if (batchSize <= 0) break; + + const batch = []; + for (let i = 0; i < batchSize; i++) { + batch.push(scenarioFn()); + } + + const batchResults = await Promise.allSettled(batch); + for (const r of batchResults) { + if (r.status === 'fulfilled') results.push(r.value); + } + + const elapsed = ((Date.now() - stats.startTime) / 1000).toFixed(1); + const active = stats.successfulConnections - stats.failedConnections; + process.stdout.write( + `\r [${elapsed}s] Connected: ${stats.successfulConnections} | Failed: ${stats.failedConnections} | Active: ${active} | Moves: ${stats.totalMoves}`, + ); + + await sleep(200); + } + + stats.endTime = Date.now(); + + printReport(); + cleanup(); +} + +function printReport() { + const elapsed = ((stats.endTime - stats.startTime) / 1000).toFixed(2); + const avgConnLatency = + stats.connectionLatencies.length > 0 + ? (stats.connectionLatencies.reduce((a, b) => a + b, 0) / stats.connectionLatencies.length).toFixed(1) + : 'N/A'; + const avgMoveLatency = + stats.moveLatencies.length > 0 + ? (stats.moveLatencies.reduce((a, b) => a + b, 0) / stats.moveLatencies.length).toFixed(1) + : 'N/A'; + + console.log(`\n\n========================================`); + console.log(` LOAD TEST REPORT`); + console.log(`========================================`); + console.log(` Duration: ${elapsed}s`); + console.log(` Connections: ${stats.totalConnections}`); + console.log(` Successful: ${stats.successfulConnections}`); + console.log(` Failed: ${stats.failedConnections}`); + console.log(` Total Moves: ${stats.totalMoves}`); + console.log(` Failed Moves: ${stats.failedMoves}`); + console.log(` Avg Conn Latency: ${avgConnLatency}ms`); + console.log(` Avg Move Latency: ${avgMoveLatency}ms`); + console.log(` Errors: ${stats.errors.length}`); + if (stats.errors.length > 0) { + const topErrors = [...new Set(stats.errors)].slice(0, 5); + for (const e of topErrors) { + console.log(` - ${e}`); + } + } + console.log(`========================================\n`); +} + +function cleanup() { + process.exit(0); +} + +async function ensureServer() { + try { + const res = await fetch(`${SERVER_URL}/health`); + const data = await res.json(); + if (data.status === 'ok') { + console.log(`✓ Server is running at ${SERVER_URL}`); + return true; + } + } catch { + console.log(`✗ Server not running at ${SERVER_URL}`); + console.log(' Start the API server first: cd api && npm start'); + console.log(' Or set LOAD_SERVER_URL env var'); + return false; + } +} + +async function main() { + const args = process.argv.slice(2); + const gameArg = parseArg(args, '--game'); + const connectionsArg = parseInt(parseArg(args, '--connections') || String(DEFAULT_CONNECTIONS), 10); + const durationArg = parseInt(parseArg(args, '--duration') || String(DEFAULT_DURATION), 10); + const httpOnly = args.includes('--http-only'); + + const running = await ensureServer(); + if (!running) process.exit(1); + + if (httpOnly) { + await runHttpLoad(); + return; + } + + let scenarioFn; + const game = gameArg || 'tictactoe'; + + switch (game) { + case 'tictactoe': + scenarioFn = require('./games/tictactoe').runScenario; + break; + case 'bingo': + scenarioFn = require('./games/bingo').runScenario; + break; + default: + console.error(`Unknown game: ${game}`); + process.exit(1); + } + + if (scenarioFn) { + await simulateGame(scenarioFn, connectionsArg, durationArg); + } +} + +function parseArg(args, name) { + const idx = args.indexOf(name); + if (idx !== -1 && idx + 1 < args.length) return args[idx + 1]; + return null; +} + +async function runHttpLoad() { + try { + const autocannon = require('autocannon'); + console.log(`\n Running HTTP load test against ${SERVER_URL}...\n`); + + const result = await autocannon({ + url: SERVER_URL, + connections: 20, + duration: 15, + requests: [ + { method: 'GET', path: '/health' }, + { method: 'GET', path: '/stats' }, + ], + }); + + console.log(` Requests/sec: ${result.requests.average.toFixed(0)}`); + console.log(` Latency avg: ${result.latency.average.toFixed(1)}ms`); + console.log(` Latency p99: ${result.latency.p99.toFixed(1)}ms`); + console.log(` Errors: ${result.errors}`); + console.log(`========================================\n`); + } catch { + console.log(' autocannon not available. Install: npm install autocannon'); + console.log(' Falling back to simple HTTP test...\n'); + + const http = require('http'); + const start = Date.now(); + let success = 0; + let fail = 0; + + for (let i = 0; i < 50; i++) { + try { + await new Promise((resolve, reject) => { + http + .get(`${SERVER_URL}/health`, (res) => { + let data = ''; + res.on('data', (chunk) => (data += chunk)); + res.on('end', () => { + if (res.statusCode === 200) success++; + else fail++; + resolve(); + }); + }) + .on('error', reject); + }); + } catch { + fail++; + } + } + + const elapsed = ((Date.now() - start) / 1000).toFixed(2); + console.log(` Requests: 50 in ${elapsed}s`); + console.log(` Success: ${success}`); + console.log(` Failed: ${fail}`); + console.log(` RPS: ${(50 / parseFloat(elapsed)).toFixed(0)}`); + } +} + +if (require.main === module) { + main().catch((err) => { + console.error('Load test failed:', err.message); + process.exit(1); + }); +} + +module.exports = { simulateGame, createClient, stats, sleep, SERVER_URL }; diff --git a/nul b/nul deleted file mode 100644 index ab56a48..0000000 --- a/nul +++ /dev/null @@ -1,2 +0,0 @@ -ERROR: Invalid argument/option - 'F:/'. -Type "TASKKILL /?" for usage. diff --git a/package-lock.json b/package-lock.json index 582b6be..5d5ffe3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,478 +4,4003 @@ "requires": true, "packages": { "": { + "name": "socket.io-games", + "devDependencies": { + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react-hooks": "^4.6.0", + "husky": "^9.0.0", + "lint-staged": "^15.2.0", + "prettier": "^3.2.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@mui/material": "^7.2.0", - "canvas-confetti": "^1.9.3", - "use-sound": "^5.0.0" + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@emotion/cache": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", - "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, "license": "MIT", "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.2", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } }, - "node_modules/@emotion/serialize": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", - "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "license": "MIT", "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.2", - "csstype": "^3.0.2" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", - "license": "MIT" + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/@emotion/utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", - "license": "MIT" + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "dev": true, + "license": "ISC" }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "license": "MIT" + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/@mui/core-downloads-tracker": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.2.0.tgz", - "integrity": "sha512-d49s7kEgI5iX40xb2YPazANvo7Bx0BLg/MNRwv+7BVpZUzXj1DaVCKlQTDex3gy/0jsCb4w7AY2uH4t4AJvSog==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@mui/material": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.2.0.tgz", - "integrity": "sha512-NTuyFNen5Z2QY+I242MDZzXnFIVIR6ERxo7vntFi9K1wCgSwvIl0HcAO2OOydKqqKApE6omRiYhpny1ZhGuH7Q==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.27.6", - "@mui/core-downloads-tracker": "^7.2.0", - "@mui/system": "^7.2.0", - "@mui/types": "^7.4.4", - "@mui/utils": "^7.2.0", - "@popperjs/core": "^2.11.8", - "@types/react-transition-group": "^4.4.12", - "clsx": "^2.1.1", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^19.1.0", - "react-transition-group": "^4.4.5" + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^7.2.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@mui/material-pigment-css": { - "optional": true - }, - "@types/react": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@mui/private-theming": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.2.0.tgz", - "integrity": "sha512-y6N1Yt3T5RMxVFnCh6+zeSWBuQdNDm5/UlM0EAYZzZR/1u+XKJWYQmbpx4e+F+1EpkYi3Nk8KhPiQDi83M3zIw==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.6", - "@mui/utils": "^7.2.0", - "prop-types": "^15.8.1" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@mui/styled-engine": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.2.0.tgz", - "integrity": "sha512-yq08xynbrNYcB1nBcW9Fn8/h/iniM3ewRguGJXPIAbHvxEF7Pz95kbEEOAAhwzxMX4okhzvHmk0DFuC5ayvgIQ==", + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.6", - "@emotion/cache": "^11.14.0", - "@emotion/serialize": "^1.3.3", - "@emotion/sheet": "^1.4.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@mui/system": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.2.0.tgz", - "integrity": "sha512-PG7cm/WluU6RAs+gNND2R9vDwNh+ERWxPkqTaiXQJGIFAyJ+VxhyKfzpdZNk0z0XdmBxxi9KhFOpgxjehf/O0A==", + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.6", - "@mui/private-theming": "^7.2.0", - "@mui/styled-engine": "^7.2.0", - "@mui/types": "^7.4.4", - "@mui/utils": "^7.2.0", - "clsx": "^2.1.1", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@mui/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz", - "integrity": "sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==", + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.6" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">= 0.4" } }, - "node_modules/@mui/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.6", - "@mui/types": "^7.4.4", - "@types/prop-types": "^15.7.15", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^19.1.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, "license": "MIT" }, - "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "csstype": "^3.0.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.12", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", - "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", - "peerDependencies": { - "@types/react": "*" + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/canvas-confetti": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz", - "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==", - "license": "ISC", + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { - "type": "donate", - "url": "https://www.paypal.me/kirilvatev" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/howler": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/howler/-/howler-2.2.4.tgz", - "integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==", - "license": "MIT" + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, "license": "MIT", "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "restore-cursor": "^5.0.0" }, - "bin": { - "loose-envify": "cli.js" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "license": "MIT", "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, "license": "MIT" }, - "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "scheduler": "^0.26.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "peerDependencies": { - "react": "^19.1.0" + "engines": { + "node": ">= 8" } }, - "node_modules/react-is": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", - "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", - "license": "MIT" + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "license": "BSD-3-Clause", + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, "license": "MIT" }, - "node_modules/use-sound": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/use-sound/-/use-sound-5.0.0.tgz", - "integrity": "sha512-MNHT3FFC5HxNCrgZtrnpIMJI2cw/0D2xismcrtyht8BTuF5FhFhb57xO/jlQr2xJaFrc/0btzRQvGyHQwB7PVA==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { - "howler": "^2.2.4" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, - "peerDependencies": { - "react": ">=16.8" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", + "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "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" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lint-staged": { + "version": "15.5.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.2.tgz", + "integrity": "sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.4.1", + "commander": "^13.1.0", + "debug": "^4.4.0", + "execa": "^8.0.1", + "lilconfig": "^3.1.3", + "listr2": "^8.2.5", + "micromatch": "^4.0.8", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.7.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/listr2": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } } diff --git a/package.json b/package.json index af66b8d..269e455 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,27 @@ { - "dependencies": { - "@mui/material": "^7.2.0", - "canvas-confetti": "^1.9.3", - "use-sound": "^5.0.0" + "name": "socket.io-games", + "private": true, + "scripts": { + "lint": "eslint . --ext .js,.jsx", + "format": "prettier --write .", + "format:check": "prettier --check .", + "prepare": "husky" + }, + "lint-staged": { + "*.{js,jsx}": [ + "eslint --fix", + "prettier --write" + ], + "*.{json,md,css}": [ + "prettier --write" + ] + }, + "devDependencies": { + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react-hooks": "^4.6.0", + "husky": "^9.0.0", + "lint-staged": "^15.2.0", + "prettier": "^3.2.0" } } diff --git a/pro/README.md b/pro/README.md deleted file mode 100644 index 58beeac..0000000 --- a/pro/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Getting Started with Create React App - -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). - -## Available Scripts - -In the project directory, you can run: - -### `npm start` - -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in your browser. - -The page will reload when you make changes.\ -You may also see any lint errors in the console. - -### `npm test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `npm run build` - -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `npm run eject` - -**Note: this is a one-way operation. Once you `eject`, you can't go back!** - -If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. - -You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). - -### Code Splitting - -This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) - -### Analyzing the Bundle Size - -This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) - -### Making a Progressive Web App - -This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) - -### Advanced Configuration - -This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) - -### Deployment - -This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) - -### `npm run build` fails to minify - -This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/pro/dist/assets/howler-CESL1Llt.js b/pro/dist/assets/howler-CESL1Llt.js deleted file mode 100644 index a9e968d..0000000 --- a/pro/dist/assets/howler-CESL1Llt.js +++ /dev/null @@ -1 +0,0 @@ -import{t as e}from"./index-BqANBEcr.js";var t=e((e=>{(function(){var t=function(){this.init()};t.prototype={init:function(){var e=this||n;return e._counter=1e3,e._html5AudioPool=[],e.html5PoolSize=10,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent=`canplaythrough`,e._navigator=typeof window<`u`&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.autoUnlock=!0,e._setup(),e},volume:function(e){var t=this||n;if(e=parseFloat(e),t.ctx||u(),e!==void 0&&e>=0&&e<=1){if(t._volume=e,t._muted)return t;t.usingWebAudio&&t.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var r=0;r=0;t--)e._howls[t].unload();return e.usingWebAudio&&e.ctx&&e.ctx.close!==void 0&&(e.ctx.close(),e.ctx=null,u()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,``)]},_setup:function(){var e=this||n;if(e.state=e.ctx&&e.ctx.state||`suspended`,e._autoSuspend(),!e.usingWebAudio)if(typeof Audio<`u`)try{var t=new Audio;t.oncanplaythrough===void 0&&(e._canPlayEvent=`canplay`)}catch{e.noAudio=!0}else e.noAudio=!0;try{var t=new Audio;t.muted&&(e.noAudio=!0)}catch{}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,t=null;try{t=typeof Audio<`u`?new Audio:null}catch{return e}if(!t||typeof t.canPlayType!=`function`)return e;var r=t.canPlayType(`audio/mpeg;`).replace(/^no$/,``),i=e._navigator?e._navigator.userAgent:``,a=i.match(/OPR\/(\d+)/g),o=a&&parseInt(a[0].split(`/`)[1],10)<33,s=i.indexOf(`Safari`)!==-1&&i.indexOf(`Chrome`)===-1,c=i.match(/Version\/(.*?) /),l=s&&c&&parseInt(c[1],10)<15;return e._codecs={mp3:!!(!o&&(r||t.canPlayType(`audio/mp3;`).replace(/^no$/,``))),mpeg:!!r,opus:!!t.canPlayType(`audio/ogg; codecs="opus"`).replace(/^no$/,``),ogg:!!t.canPlayType(`audio/ogg; codecs="vorbis"`).replace(/^no$/,``),oga:!!t.canPlayType(`audio/ogg; codecs="vorbis"`).replace(/^no$/,``),wav:!!(t.canPlayType(`audio/wav; codecs="1"`)||t.canPlayType(`audio/wav`)).replace(/^no$/,``),aac:!!t.canPlayType(`audio/aac;`).replace(/^no$/,``),caf:!!t.canPlayType(`audio/x-caf;`).replace(/^no$/,``),m4a:!!(t.canPlayType(`audio/x-m4a;`)||t.canPlayType(`audio/m4a;`)||t.canPlayType(`audio/aac;`)).replace(/^no$/,``),m4b:!!(t.canPlayType(`audio/x-m4b;`)||t.canPlayType(`audio/m4b;`)||t.canPlayType(`audio/aac;`)).replace(/^no$/,``),mp4:!!(t.canPlayType(`audio/x-mp4;`)||t.canPlayType(`audio/mp4;`)||t.canPlayType(`audio/aac;`)).replace(/^no$/,``),weba:!!(!l&&t.canPlayType(`audio/webm; codecs="vorbis"`).replace(/^no$/,``)),webm:!!(!l&&t.canPlayType(`audio/webm; codecs="vorbis"`).replace(/^no$/,``)),dolby:!!t.canPlayType(`audio/mp4; codecs="ec-3"`).replace(/^no$/,``),flac:!!(t.canPlayType(`audio/x-flac;`)||t.canPlayType(`audio/flac;`)).replace(/^no$/,``)},e},_unlockAudio:function(){var e=this||n;if(!(e._audioUnlocked||!e.ctx)){e._audioUnlocked=!1,e.autoUnlock=!1,!e._mobileUnloaded&&e.ctx.sampleRate!==44100&&(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var t=function(n){for(;e._html5AudioPool.length0?s._seek:r._sprite[e][0]/1e3),u=Math.max(0,(r._sprite[e][0]+r._sprite[e][1])/1e3-l),d=u*1e3/Math.abs(s._rate),f=r._sprite[e][0]/1e3,p=(r._sprite[e][0]+r._sprite[e][1])/1e3;s._sprite=e,s._ended=!1;var m=function(){s._paused=!1,s._seek=l,s._start=f,s._stop=p,s._loop=!!(s._loop||r._sprite[e][2])};if(l>=p){r._ended(s);return}var h=s._node;if(r._webAudio){var g=function(){r._playLock=!1,m(),r._refreshBuffer(s);var e=s._muted||r._muted?0:s._volume;h.gain.setValueAtTime(e,n.ctx.currentTime),s._playStart=n.ctx.currentTime,h.bufferSource.start===void 0?s._loop?h.bufferSource.noteGrainOn(0,l,86400):h.bufferSource.noteGrainOn(0,l,u):s._loop?h.bufferSource.start(0,l,86400):h.bufferSource.start(0,l,u),d!==1/0&&(r._endTimers[s._id]=setTimeout(r._ended.bind(r,s),d)),t||setTimeout(function(){r._emit(`play`,s._id),r._loadQueue()},0)};n.state===`running`&&n.ctx.state!==`interrupted`?g():(r._playLock=!0,r.once(`resume`,g),r._clearTimer(s._id))}else{var _=function(){h.currentTime=l,h.muted=s._muted||r._muted||n._muted||h.muted,h.volume=s._volume*n.volume(),h.playbackRate=s._rate;try{var i=h.play();if(i&&typeof Promise<`u`&&(i instanceof Promise||typeof i.then==`function`)?(r._playLock=!0,m(),i.then(function(){r._playLock=!1,h._unlocked=!0,t?r._loadQueue():r._emit(`play`,s._id)}).catch(function(){r._playLock=!1,r._emit(`playerror`,s._id,`Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.`),s._ended=!0,s._paused=!0})):t||(r._playLock=!1,m(),r._emit(`play`,s._id)),h.playbackRate=s._rate,h.paused){r._emit(`playerror`,s._id,`Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.`);return}e!==`__default`||s._loop?r._endTimers[s._id]=setTimeout(r._ended.bind(r,s),d):(r._endTimers[s._id]=function(){r._ended(s),h.removeEventListener(`ended`,r._endTimers[s._id],!1)},h.addEventListener(`ended`,r._endTimers[s._id],!1))}catch(e){r._emit(`playerror`,s._id,e)}};h.src===`data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA`&&(h.src=r._src,h.load());var v=window&&window.ejecta||!h.readyState&&n._navigator.isCocoonJS;if(h.readyState>=3||v)_();else{r._playLock=!0,r._state=`loading`;var y=function(){r._state=`loaded`,_(),h.removeEventListener(n._canPlayEvent,y,!1)};h.addEventListener(n._canPlayEvent,y,!1),r._clearTimer(s._id)}}return s._id},pause:function(e){var t=this;if(t._state!==`loaded`||t._playLock)return t._queue.push({event:`pause`,action:function(){t.pause(e)}}),t;for(var n=t._getSoundIds(e),r=0;r=0?i=parseInt(t[0],10):r=parseFloat(t[0]):t.length>=2&&(r=parseFloat(t[0]),i=parseInt(t[1],10));var a;if(r!==void 0&&r>=0&&r<=1){if(e._state!==`loaded`||e._playLock)return e._queue.push({event:`volume`,action:function(){e.volume.apply(e,t)}}),e;i===void 0&&(e._volume=r),i=e._getSoundIds(i);for(var o=0;o0?r/l:r),d=Date.now();e._fadeTo=n,e._interval=setInterval(function(){var i=(Date.now()-d)/r;d=Date.now(),s+=c*i,s=Math.round(s*100)/100,s=c<0?Math.max(n,s):Math.min(n,s),o._webAudio?e._volume=s:o.volume(s,e._id,!0),a&&(o._volume=s),(nt&&s>=n)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,o.volume(n,e._id),o._emit(`fade`,e._id))},u)},_stopFade:function(e){var t=this,r=t._soundById(e);return r&&r._interval&&(t._webAudio&&r._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(r._interval),r._interval=null,t.volume(r._fadeTo,e),r._fadeTo=null,t._emit(`fade`,e)),t},loop:function(){var e=this,t=arguments,n,r,i;if(t.length===0)return e._loop;if(t.length===1)if(typeof t[0]==`boolean`)n=t[0],e._loop=n;else return i=e._soundById(parseInt(t[0],10)),i?i._loop:!1;else t.length===2&&(n=t[0],r=parseInt(t[1],10));for(var a=e._getSoundIds(r),o=0;o=0?i=parseInt(t[0],10):r=parseFloat(t[0]):t.length===2&&(r=parseFloat(t[0]),i=parseInt(t[1],10));var a;if(typeof r==`number`){if(e._state!==`loaded`||e._playLock)return e._queue.push({event:`rate`,action:function(){e.rate.apply(e,t)}}),e;i===void 0&&(e._rate=r),i=e._getSoundIds(i);for(var o=0;o=0?i=parseInt(t[0],10):e._sounds.length&&(i=e._sounds[0]._id,r=parseFloat(t[0])):t.length===2&&(r=parseFloat(t[0]),i=parseInt(t[1],10)),i===void 0)return 0;if(typeof r==`number`&&(e._state!==`loaded`||e._playLock))return e._queue.push({event:`seek`,action:function(){e.seek.apply(e,t)}}),e;var a=e._soundById(i);if(a)if(typeof r==`number`&&r>=0){var o=e.playing(i);o&&e.pause(i,!0),a._seek=r,a._ended=!1,e._clearTimer(i),!e._webAudio&&a._node&&!isNaN(a._node.duration)&&(a._node.currentTime=r);var s=function(){o&&e.play(i,!0),e._emit(`seek`,i)};if(o&&!e._webAudio){var c=function(){e._playLock?setTimeout(c,0):s()};setTimeout(c,0)}else s()}else if(e._webAudio){var l=e.playing(i)?n.ctx.currentTime-a._playStart:0,u=a._rateSeek?a._rateSeek-a._seek:0;return a._seek+(u+l*Math.abs(a._rate))}else return a._node.currentTime;return e},playing:function(e){var t=this;if(typeof e==`number`){var n=t._soundById(e);return n?!n._paused:!1}for(var r=0;r=0&&n._howls.splice(i,1);var o=!0;for(r=0;r=0){o=!1;break}return a&&o&&delete a[e._src],n.noAudio=!1,e._state=`unloaded`,e._sounds=[],e=null,null},on:function(e,t,n,r){var i=this,a=i[`_on`+e];return typeof t==`function`&&a.push(r?{id:n,fn:t,once:r}:{id:n,fn:t}),i},off:function(e,t,n){var r=this,i=r[`_on`+e],a=0;if(typeof t==`number`&&(n=t,t=null),t||n)for(a=0;a=0;a--)(!i[a].id||i[a].id===t||e===`load`)&&(setTimeout(function(e){e.call(this,t,n)}.bind(r,i[a].fn),0),i[a].once&&r.off(e,i[a].fn,i[a].id));return r._loadQueue(e),r},_loadQueue:function(e){var t=this;if(t._queue.length>0){var n=t._queue[0];n.event===e&&(t._queue.shift(),t._loadQueue()),e||n.action()}return t},_ended:function(e){var t=this,r=e._sprite;if(!t._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime=0;r--){if(n<=t)return;e._sounds[r]._ended&&(e._webAudio&&e._sounds[r]._node&&e._sounds[r]._node.disconnect(0),e._sounds.splice(r,1),n--)}}},_getSoundIds:function(e){var t=this;if(e===void 0){for(var n=[],r=0;r=0;if(!e.bufferSource)return t;if(n._scratchBuffer&&e.bufferSource&&(e.bufferSource.onended=null,e.bufferSource.disconnect(0),r))try{e.bufferSource.buffer=n._scratchBuffer}catch{}return e.bufferSource=null,t},_clearSound:function(e){/MSIE |Trident\//.test(n._navigator&&n._navigator.userAgent)||(e.src=`data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA`)}};var i=function(e){this._parent=e,this.init()};i.prototype={init:function(){var e=this,t=e._parent;return e._muted=t._muted,e._loop=t._loop,e._volume=t._volume,e._rate=t._rate,e._seek=0,e._paused=!0,e._ended=!0,e._sprite=`__default`,e._id=++n._counter,t._sounds.push(e),e.create(),e},create:function(){var e=this,t=e._parent,r=n._muted||e._muted||e._parent._muted?0:e._volume;return t._webAudio?(e._node=n.ctx.createGain===void 0?n.ctx.createGainNode():n.ctx.createGain(),e._node.gain.setValueAtTime(r,n.ctx.currentTime),e._node.paused=!0,e._node.connect(n.masterGain)):n.noAudio||(e._node=n._obtainHtml5Audio(),e._errorFn=e._errorListener.bind(e),e._node.addEventListener(`error`,e._errorFn,!1),e._loadFn=e._loadListener.bind(e),e._node.addEventListener(n._canPlayEvent,e._loadFn,!1),e._endFn=e._endListener.bind(e),e._node.addEventListener(`ended`,e._endFn,!1),e._node.src=t._src,e._node.preload=t._preload===!0?`auto`:t._preload,e._node.volume=r*n.volume(),e._node.load()),e},reset:function(){var e=this,t=e._parent;return e._muted=t._muted,e._loop=t._loop,e._volume=t._volume,e._rate=t._rate,e._seek=0,e._rateSeek=0,e._paused=!0,e._ended=!0,e._sprite=`__default`,e._id=++n._counter,e},_errorListener:function(){var e=this;e._parent._emit(`loaderror`,e._id,e._node.error?e._node.error.code:0),e._node.removeEventListener(`error`,e._errorFn,!1)},_loadListener:function(){var e=this,t=e._parent;t._duration=Math.ceil(e._node.duration*10)/10,Object.keys(t._sprite).length===0&&(t._sprite={__default:[0,t._duration*1e3]}),t._state!==`loaded`&&(t._state=`loaded`,t._emit(`load`),t._loadQueue()),e._node.removeEventListener(n._canPlayEvent,e._loadFn,!1)},_endListener:function(){var e=this,t=e._parent;t._duration===1/0&&(t._duration=Math.ceil(e._node.duration*10)/10,t._sprite.__default[1]===1/0&&(t._sprite.__default[1]=t._duration*1e3),t._ended(e)),e._node.removeEventListener(`ended`,e._endFn,!1)}};var a={},o=function(e){var t=e._src;if(a[t]){e._duration=a[t].duration,l(e);return}if(/^data:[^;]+;base64,/.test(t)){for(var n=atob(t.split(`,`)[1]),r=new Uint8Array(n.length),i=0;i0?(a[t._src]=e,l(t,e)):r()};typeof Promise<`u`&&n.ctx.decodeAudioData.length===1?n.ctx.decodeAudioData(e).then(i).catch(r):n.ctx.decodeAudioData(e,i,r)},l=function(e,t){t&&!e._duration&&(e._duration=t.duration),Object.keys(e._sprite).length===0&&(e._sprite={__default:[0,e._duration*1e3]}),e._state!==`loaded`&&(e._state=`loaded`,e._emit(`load`),e._loadQueue())},u=function(){if(n.usingWebAudio){try{typeof AudioContext<`u`?n.ctx=new AudioContext:typeof webkitAudioContext<`u`?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch{n.usingWebAudio=!1}n.ctx||(n.usingWebAudio=!1);var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),t=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),r=t?parseInt(t[1],10):null;if(e&&r&&r<9){var i=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());n._navigator&&!i&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=n.ctx.createGain===void 0?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:n._volume,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()}};typeof define==`function`&&define.amd&&define([],function(){return{Howler:n,Howl:r}}),e!==void 0&&(e.Howler=n,e.Howl=r),typeof global<`u`?(global.HowlerGlobal=t,global.Howler=n,global.Howl=r,global.Sound=i):typeof window<`u`&&(window.HowlerGlobal=t,window.Howler=n,window.Howl=r,window.Sound=i)})(),(function(){HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(e){var t=this;if(!t.ctx||!t.ctx.listener)return t;for(var n=t._howls.length-1;n>=0;n--)t._howls[n].stereo(e);return t},HowlerGlobal.prototype.pos=function(e,t,n){var r=this;if(!r.ctx||!r.ctx.listener)return r;if(t=typeof t==`number`?t:r._pos[1],n=typeof n==`number`?n:r._pos[2],typeof e==`number`)r._pos=[e,t,n],r.ctx.listener.positionX===void 0?r.ctx.listener.setPosition(r._pos[0],r._pos[1],r._pos[2]):(r.ctx.listener.positionX.setTargetAtTime(r._pos[0],Howler.ctx.currentTime,.1),r.ctx.listener.positionY.setTargetAtTime(r._pos[1],Howler.ctx.currentTime,.1),r.ctx.listener.positionZ.setTargetAtTime(r._pos[2],Howler.ctx.currentTime,.1));else return r._pos;return r},HowlerGlobal.prototype.orientation=function(e,t,n,r,i,a){var o=this;if(!o.ctx||!o.ctx.listener)return o;var s=o._orientation;if(t=typeof t==`number`?t:s[1],n=typeof n==`number`?n:s[2],r=typeof r==`number`?r:s[3],i=typeof i==`number`?i:s[4],a=typeof a==`number`?a:s[5],typeof e==`number`)o._orientation=[e,t,n,r,i,a],o.ctx.listener.forwardX===void 0?o.ctx.listener.setOrientation(e,t,n,r,i,a):(o.ctx.listener.forwardX.setTargetAtTime(e,Howler.ctx.currentTime,.1),o.ctx.listener.forwardY.setTargetAtTime(t,Howler.ctx.currentTime,.1),o.ctx.listener.forwardZ.setTargetAtTime(n,Howler.ctx.currentTime,.1),o.ctx.listener.upX.setTargetAtTime(r,Howler.ctx.currentTime,.1),o.ctx.listener.upY.setTargetAtTime(i,Howler.ctx.currentTime,.1),o.ctx.listener.upZ.setTargetAtTime(a,Howler.ctx.currentTime,.1));else return s;return o},Howl.prototype.init=(function(e){return function(t){var n=this;return n._orientation=t.orientation||[1,0,0],n._stereo=t.stereo||null,n._pos=t.pos||null,n._pannerAttr={coneInnerAngle:t.coneInnerAngle===void 0?360:t.coneInnerAngle,coneOuterAngle:t.coneOuterAngle===void 0?360:t.coneOuterAngle,coneOuterGain:t.coneOuterGain===void 0?0:t.coneOuterGain,distanceModel:t.distanceModel===void 0?`inverse`:t.distanceModel,maxDistance:t.maxDistance===void 0?1e4:t.maxDistance,panningModel:t.panningModel===void 0?`HRTF`:t.panningModel,refDistance:t.refDistance===void 0?1:t.refDistance,rolloffFactor:t.rolloffFactor===void 0?1:t.rolloffFactor},n._onstereo=t.onstereo?[{fn:t.onstereo}]:[],n._onpos=t.onpos?[{fn:t.onpos}]:[],n._onorientation=t.onorientation?[{fn:t.onorientation}]:[],e.call(this,t)}})(Howl.prototype.init),Howl.prototype.stereo=function(t,n){var r=this;if(!r._webAudio)return r;if(r._state!==`loaded`)return r._queue.push({event:`stereo`,action:function(){r.stereo(t,n)}}),r;var i=Howler.ctx.createStereoPanner===void 0?`spatial`:`stereo`;if(n===void 0)if(typeof t==`number`)r._stereo=t,r._pos=[t,0,0];else return r._stereo;for(var a=r._getSoundIds(n),o=0;o { + ((function () { + var t = function () { + this.init(); + }; + t.prototype = { + init: function () { + var e = this || n; + return ( + (e._counter = 1e3), + (e._html5AudioPool = []), + (e.html5PoolSize = 10), + (e._codecs = {}), + (e._howls = []), + (e._muted = !1), + (e._volume = 1), + (e._canPlayEvent = `canplaythrough`), + (e._navigator = typeof window < `u` && window.navigator ? window.navigator : null), + (e.masterGain = null), + (e.noAudio = !1), + (e.usingWebAudio = !0), + (e.autoSuspend = !0), + (e.ctx = null), + (e.autoUnlock = !0), + e._setup(), + e + ); + }, + volume: function (e) { + var t = this || n; + if (((e = parseFloat(e)), t.ctx || u(), e !== void 0 && e >= 0 && e <= 1)) { + if (((t._volume = e), t._muted)) return t; + t.usingWebAudio && t.masterGain.gain.setValueAtTime(e, n.ctx.currentTime); + for (var r = 0; r < t._howls.length; r++) + if (!t._howls[r]._webAudio) + for (var i = t._howls[r]._getSoundIds(), a = 0; a < i.length; a++) { + var o = t._howls[r]._soundById(i[a]); + o && o._node && (o._node.volume = o._volume * e); + } + return t; + } + return t._volume; + }, + mute: function (e) { + var t = this || n; + (t.ctx || u(), + (t._muted = e), + t.usingWebAudio && t.masterGain.gain.setValueAtTime(e ? 0 : t._volume, n.ctx.currentTime)); + for (var r = 0; r < t._howls.length; r++) + if (!t._howls[r]._webAudio) + for (var i = t._howls[r]._getSoundIds(), a = 0; a < i.length; a++) { + var o = t._howls[r]._soundById(i[a]); + o && o._node && (o._node.muted = e ? !0 : o._muted); + } + return t; + }, + stop: function () { + for (var e = this || n, t = 0; t < e._howls.length; t++) e._howls[t].stop(); + return e; + }, + unload: function () { + for (var e = this || n, t = e._howls.length - 1; t >= 0; t--) e._howls[t].unload(); + return (e.usingWebAudio && e.ctx && e.ctx.close !== void 0 && (e.ctx.close(), (e.ctx = null), u()), e); + }, + codecs: function (e) { + return (this || n)._codecs[e.replace(/^x-/, ``)]; + }, + _setup: function () { + var e = this || n; + if (((e.state = (e.ctx && e.ctx.state) || `suspended`), e._autoSuspend(), !e.usingWebAudio)) + if (typeof Audio < `u`) + try { + var t = new Audio(); + t.oncanplaythrough === void 0 && (e._canPlayEvent = `canplay`); + } catch { + e.noAudio = !0; + } + else e.noAudio = !0; + try { + var t = new Audio(); + t.muted && (e.noAudio = !0); + } catch {} + return (e.noAudio || e._setupCodecs(), e); + }, + _setupCodecs: function () { + var e = this || n, + t = null; + try { + t = typeof Audio < `u` ? new Audio() : null; + } catch { + return e; + } + if (!t || typeof t.canPlayType != `function`) return e; + var r = t.canPlayType(`audio/mpeg;`).replace(/^no$/, ``), + i = e._navigator ? e._navigator.userAgent : ``, + a = i.match(/OPR\/(\d+)/g), + o = a && parseInt(a[0].split(`/`)[1], 10) < 33, + s = i.indexOf(`Safari`) !== -1 && i.indexOf(`Chrome`) === -1, + c = i.match(/Version\/(.*?) /), + l = s && c && parseInt(c[1], 10) < 15; + return ( + (e._codecs = { + mp3: !!(!o && (r || t.canPlayType(`audio/mp3;`).replace(/^no$/, ``))), + mpeg: !!r, + opus: !!t.canPlayType(`audio/ogg; codecs="opus"`).replace(/^no$/, ``), + ogg: !!t.canPlayType(`audio/ogg; codecs="vorbis"`).replace(/^no$/, ``), + oga: !!t.canPlayType(`audio/ogg; codecs="vorbis"`).replace(/^no$/, ``), + wav: !!(t.canPlayType(`audio/wav; codecs="1"`) || t.canPlayType(`audio/wav`)).replace(/^no$/, ``), + aac: !!t.canPlayType(`audio/aac;`).replace(/^no$/, ``), + caf: !!t.canPlayType(`audio/x-caf;`).replace(/^no$/, ``), + m4a: !!( + t.canPlayType(`audio/x-m4a;`) || + t.canPlayType(`audio/m4a;`) || + t.canPlayType(`audio/aac;`) + ).replace(/^no$/, ``), + m4b: !!( + t.canPlayType(`audio/x-m4b;`) || + t.canPlayType(`audio/m4b;`) || + t.canPlayType(`audio/aac;`) + ).replace(/^no$/, ``), + mp4: !!( + t.canPlayType(`audio/x-mp4;`) || + t.canPlayType(`audio/mp4;`) || + t.canPlayType(`audio/aac;`) + ).replace(/^no$/, ``), + weba: !!(!l && t.canPlayType(`audio/webm; codecs="vorbis"`).replace(/^no$/, ``)), + webm: !!(!l && t.canPlayType(`audio/webm; codecs="vorbis"`).replace(/^no$/, ``)), + dolby: !!t.canPlayType(`audio/mp4; codecs="ec-3"`).replace(/^no$/, ``), + flac: !!(t.canPlayType(`audio/x-flac;`) || t.canPlayType(`audio/flac;`)).replace(/^no$/, ``), + }), + e + ); + }, + _unlockAudio: function () { + var e = this || n; + if (!(e._audioUnlocked || !e.ctx)) { + ((e._audioUnlocked = !1), + (e.autoUnlock = !1), + !e._mobileUnloaded && e.ctx.sampleRate !== 44100 && ((e._mobileUnloaded = !0), e.unload()), + (e._scratchBuffer = e.ctx.createBuffer(1, 1, 22050))); + var t = function (n) { + for (; e._html5AudioPool.length < e.html5PoolSize; ) + try { + var r = new Audio(); + ((r._unlocked = !0), e._releaseHtml5Audio(r)); + } catch { + e.noAudio = !0; + break; + } + for (var i = 0; i < e._howls.length; i++) + if (!e._howls[i]._webAudio) + for (var a = e._howls[i]._getSoundIds(), o = 0; o < a.length; o++) { + var s = e._howls[i]._soundById(a[o]); + s && s._node && !s._node._unlocked && ((s._node._unlocked = !0), s._node.load()); + } + e._autoResume(); + var c = e.ctx.createBufferSource(); + ((c.buffer = e._scratchBuffer), + c.connect(e.ctx.destination), + c.start === void 0 ? c.noteOn(0) : c.start(0), + typeof e.ctx.resume == `function` && e.ctx.resume(), + (c.onended = function () { + (c.disconnect(0), + (e._audioUnlocked = !0), + document.removeEventListener(`touchstart`, t, !0), + document.removeEventListener(`touchend`, t, !0), + document.removeEventListener(`click`, t, !0), + document.removeEventListener(`keydown`, t, !0)); + for (var n = 0; n < e._howls.length; n++) e._howls[n]._emit(`unlock`); + })); + }; + return ( + document.addEventListener(`touchstart`, t, !0), + document.addEventListener(`touchend`, t, !0), + document.addEventListener(`click`, t, !0), + document.addEventListener(`keydown`, t, !0), + e + ); + } + }, + _obtainHtml5Audio: function () { + var e = this || n; + if (e._html5AudioPool.length) return e._html5AudioPool.pop(); + var t = new Audio().play(); + return ( + t && + typeof Promise < `u` && + (t instanceof Promise || typeof t.then == `function`) && + t.catch(function () { + console.warn(`HTML5 Audio pool exhausted, returning potentially locked audio object.`); + }), + new Audio() + ); + }, + _releaseHtml5Audio: function (e) { + var t = this || n; + return (e._unlocked && t._html5AudioPool.push(e), t); + }, + _autoSuspend: function () { + var e = this; + if (!(!e.autoSuspend || !e.ctx || e.ctx.suspend === void 0 || !n.usingWebAudio)) { + for (var t = 0; t < e._howls.length; t++) + if (e._howls[t]._webAudio) { + for (var r = 0; r < e._howls[t]._sounds.length; r++) if (!e._howls[t]._sounds[r]._paused) return e; + } + return ( + e._suspendTimer && clearTimeout(e._suspendTimer), + (e._suspendTimer = setTimeout(function () { + if (e.autoSuspend) { + ((e._suspendTimer = null), (e.state = `suspending`)); + var t = function () { + ((e.state = `suspended`), e._resumeAfterSuspend && (delete e._resumeAfterSuspend, e._autoResume())); + }; + e.ctx.suspend().then(t, t); + } + }, 3e4)), + e + ); + } + }, + _autoResume: function () { + var e = this; + if (!(!e.ctx || e.ctx.resume === void 0 || !n.usingWebAudio)) + return ( + e.state === `running` && e.ctx.state !== `interrupted` && e._suspendTimer + ? (clearTimeout(e._suspendTimer), (e._suspendTimer = null)) + : e.state === `suspended` || (e.state === `running` && e.ctx.state === `interrupted`) + ? (e.ctx.resume().then(function () { + e.state = `running`; + for (var t = 0; t < e._howls.length; t++) e._howls[t]._emit(`resume`); + }), + (e._suspendTimer &&= (clearTimeout(e._suspendTimer), null))) + : e.state === `suspending` && (e._resumeAfterSuspend = !0), + e + ); + }, + }; + var n = new t(), + r = function (e) { + var t = this; + if (!e.src || e.src.length === 0) { + console.error(`An array of source files must be passed with any new Howl.`); + return; + } + t.init(e); + }; + r.prototype = { + init: function (e) { + var t = this; + return ( + n.ctx || u(), + (t._autoplay = e.autoplay || !1), + (t._format = typeof e.format == `string` ? [e.format] : e.format), + (t._html5 = e.html5 || !1), + (t._muted = e.mute || !1), + (t._loop = e.loop || !1), + (t._pool = e.pool || 5), + (t._preload = typeof e.preload == `boolean` || e.preload === `metadata` ? e.preload : !0), + (t._rate = e.rate || 1), + (t._sprite = e.sprite || {}), + (t._src = typeof e.src == `string` ? [e.src] : e.src), + (t._volume = e.volume === void 0 ? 1 : e.volume), + (t._xhr = { + method: e.xhr && e.xhr.method ? e.xhr.method : `GET`, + headers: e.xhr && e.xhr.headers ? e.xhr.headers : null, + withCredentials: e.xhr && e.xhr.withCredentials ? e.xhr.withCredentials : !1, + }), + (t._duration = 0), + (t._state = `unloaded`), + (t._sounds = []), + (t._endTimers = {}), + (t._queue = []), + (t._playLock = !1), + (t._onend = e.onend ? [{ fn: e.onend }] : []), + (t._onfade = e.onfade ? [{ fn: e.onfade }] : []), + (t._onload = e.onload ? [{ fn: e.onload }] : []), + (t._onloaderror = e.onloaderror ? [{ fn: e.onloaderror }] : []), + (t._onplayerror = e.onplayerror ? [{ fn: e.onplayerror }] : []), + (t._onpause = e.onpause ? [{ fn: e.onpause }] : []), + (t._onplay = e.onplay ? [{ fn: e.onplay }] : []), + (t._onstop = e.onstop ? [{ fn: e.onstop }] : []), + (t._onmute = e.onmute ? [{ fn: e.onmute }] : []), + (t._onvolume = e.onvolume ? [{ fn: e.onvolume }] : []), + (t._onrate = e.onrate ? [{ fn: e.onrate }] : []), + (t._onseek = e.onseek ? [{ fn: e.onseek }] : []), + (t._onunlock = e.onunlock ? [{ fn: e.onunlock }] : []), + (t._onresume = []), + (t._webAudio = n.usingWebAudio && !t._html5), + n.ctx !== void 0 && n.ctx && n.autoUnlock && n._unlockAudio(), + n._howls.push(t), + t._autoplay && + t._queue.push({ + event: `play`, + action: function () { + t.play(); + }, + }), + t._preload && t._preload !== `none` && t.load(), + t + ); + }, + load: function () { + var e = this, + t = null; + if (n.noAudio) { + e._emit(`loaderror`, null, `No audio support.`); + return; + } + typeof e._src == `string` && (e._src = [e._src]); + for (var r = 0; r < e._src.length; r++) { + var a, s; + if (e._format && e._format[r]) a = e._format[r]; + else { + if (((s = e._src[r]), typeof s != `string`)) { + e._emit(`loaderror`, null, `Non-string found in selected audio sources - ignoring.`); + continue; + } + ((a = /^data:audio\/([^;,]+);/i.exec(s)), + (a ||= /\.([^.]+)$/.exec(s.split(`?`, 1)[0])), + (a &&= a[1].toLowerCase())); + } + if ( + (a || + console.warn( + `No file extension was found. Consider using the "format" property or specify an extension.`, + ), + a && n.codecs(a)) + ) { + t = e._src[r]; + break; + } + } + if (!t) { + e._emit(`loaderror`, null, `No codec support for selected audio sources.`); + return; + } + return ( + (e._src = t), + (e._state = `loading`), + window.location.protocol === `https:` && t.slice(0, 5) === `http:` && ((e._html5 = !0), (e._webAudio = !1)), + new i(e), + e._webAudio && o(e), + e + ); + }, + play: function (e, t) { + var r = this, + i = null; + if (typeof e == `number`) ((i = e), (e = null)); + else if (typeof e == `string` && r._state === `loaded` && !r._sprite[e]) return null; + else if (e === void 0 && ((e = `__default`), !r._playLock)) { + for (var a = 0, o = 0; o < r._sounds.length; o++) + r._sounds[o]._paused && !r._sounds[o]._ended && (a++, (i = r._sounds[o]._id)); + a === 1 ? (e = null) : (i = null); + } + var s = i ? r._soundById(i) : r._inactiveSound(); + if (!s) return null; + if ((i && !e && (e = s._sprite || `__default`), r._state !== `loaded`)) { + ((s._sprite = e), (s._ended = !1)); + var c = s._id; + return ( + r._queue.push({ + event: `play`, + action: function () { + r.play(c); + }, + }), + c + ); + } + if (i && !s._paused) return (t || r._loadQueue(`play`), s._id); + r._webAudio && n._autoResume(); + var l = Math.max(0, s._seek > 0 ? s._seek : r._sprite[e][0] / 1e3), + u = Math.max(0, (r._sprite[e][0] + r._sprite[e][1]) / 1e3 - l), + d = (u * 1e3) / Math.abs(s._rate), + f = r._sprite[e][0] / 1e3, + p = (r._sprite[e][0] + r._sprite[e][1]) / 1e3; + ((s._sprite = e), (s._ended = !1)); + var m = function () { + ((s._paused = !1), (s._seek = l), (s._start = f), (s._stop = p), (s._loop = !!(s._loop || r._sprite[e][2]))); + }; + if (l >= p) { + r._ended(s); + return; + } + var h = s._node; + if (r._webAudio) { + var g = function () { + ((r._playLock = !1), m(), r._refreshBuffer(s)); + var e = s._muted || r._muted ? 0 : s._volume; + (h.gain.setValueAtTime(e, n.ctx.currentTime), + (s._playStart = n.ctx.currentTime), + h.bufferSource.start === void 0 + ? s._loop + ? h.bufferSource.noteGrainOn(0, l, 86400) + : h.bufferSource.noteGrainOn(0, l, u) + : s._loop + ? h.bufferSource.start(0, l, 86400) + : h.bufferSource.start(0, l, u), + d !== 1 / 0 && (r._endTimers[s._id] = setTimeout(r._ended.bind(r, s), d)), + t || + setTimeout(function () { + (r._emit(`play`, s._id), r._loadQueue()); + }, 0)); + }; + n.state === `running` && n.ctx.state !== `interrupted` + ? g() + : ((r._playLock = !0), r.once(`resume`, g), r._clearTimer(s._id)); + } else { + var _ = function () { + ((h.currentTime = l), + (h.muted = s._muted || r._muted || n._muted || h.muted), + (h.volume = s._volume * n.volume()), + (h.playbackRate = s._rate)); + try { + var i = h.play(); + if ( + (i && typeof Promise < `u` && (i instanceof Promise || typeof i.then == `function`) + ? ((r._playLock = !0), + m(), + i + .then(function () { + ((r._playLock = !1), (h._unlocked = !0), t ? r._loadQueue() : r._emit(`play`, s._id)); + }) + .catch(function () { + ((r._playLock = !1), + r._emit( + `playerror`, + s._id, + `Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.`, + ), + (s._ended = !0), + (s._paused = !0)); + })) + : t || ((r._playLock = !1), m(), r._emit(`play`, s._id)), + (h.playbackRate = s._rate), + h.paused) + ) { + r._emit( + `playerror`, + s._id, + `Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.`, + ); + return; + } + e !== `__default` || s._loop + ? (r._endTimers[s._id] = setTimeout(r._ended.bind(r, s), d)) + : ((r._endTimers[s._id] = function () { + (r._ended(s), h.removeEventListener(`ended`, r._endTimers[s._id], !1)); + }), + h.addEventListener(`ended`, r._endTimers[s._id], !1)); + } catch (e) { + r._emit(`playerror`, s._id, e); + } + }; + h.src === `data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA` && + ((h.src = r._src), h.load()); + var v = (window && window.ejecta) || (!h.readyState && n._navigator.isCocoonJS); + if (h.readyState >= 3 || v) _(); + else { + ((r._playLock = !0), (r._state = `loading`)); + var y = function () { + ((r._state = `loaded`), _(), h.removeEventListener(n._canPlayEvent, y, !1)); + }; + (h.addEventListener(n._canPlayEvent, y, !1), r._clearTimer(s._id)); + } + } + return s._id; + }, + pause: function (e) { + var t = this; + if (t._state !== `loaded` || t._playLock) + return ( + t._queue.push({ + event: `pause`, + action: function () { + t.pause(e); + }, + }), + t + ); + for (var n = t._getSoundIds(e), r = 0; r < n.length; r++) { + t._clearTimer(n[r]); + var i = t._soundById(n[r]); + if ( + i && + !i._paused && + ((i._seek = t.seek(n[r])), (i._rateSeek = 0), (i._paused = !0), t._stopFade(n[r]), i._node) + ) + if (t._webAudio) { + if (!i._node.bufferSource) continue; + (i._node.bufferSource.stop === void 0 ? i._node.bufferSource.noteOff(0) : i._node.bufferSource.stop(0), + t._cleanBuffer(i._node)); + } else (!isNaN(i._node.duration) || i._node.duration === 1 / 0) && i._node.pause(); + arguments[1] || t._emit(`pause`, i ? i._id : null); + } + return t; + }, + stop: function (e, t) { + var n = this; + if (n._state !== `loaded` || n._playLock) + return ( + n._queue.push({ + event: `stop`, + action: function () { + n.stop(e); + }, + }), + n + ); + for (var r = n._getSoundIds(e), i = 0; i < r.length; i++) { + n._clearTimer(r[i]); + var a = n._soundById(r[i]); + a && + ((a._seek = a._start || 0), + (a._rateSeek = 0), + (a._paused = !0), + (a._ended = !0), + n._stopFade(r[i]), + a._node && + (n._webAudio + ? a._node.bufferSource && + (a._node.bufferSource.stop === void 0 + ? a._node.bufferSource.noteOff(0) + : a._node.bufferSource.stop(0), + n._cleanBuffer(a._node)) + : (!isNaN(a._node.duration) || a._node.duration === 1 / 0) && + ((a._node.currentTime = a._start || 0), + a._node.pause(), + a._node.duration === 1 / 0 && n._clearSound(a._node))), + t || n._emit(`stop`, a._id)); + } + return n; + }, + mute: function (e, t) { + var r = this; + if (r._state !== `loaded` || r._playLock) + return ( + r._queue.push({ + event: `mute`, + action: function () { + r.mute(e, t); + }, + }), + r + ); + if (t === void 0) + if (typeof e == `boolean`) r._muted = e; + else return r._muted; + for (var i = r._getSoundIds(t), a = 0; a < i.length; a++) { + var o = r._soundById(i[a]); + o && + ((o._muted = e), + o._interval && r._stopFade(o._id), + r._webAudio && o._node + ? o._node.gain.setValueAtTime(e ? 0 : o._volume, n.ctx.currentTime) + : o._node && (o._node.muted = n._muted ? !0 : e), + r._emit(`mute`, o._id)); + } + return r; + }, + volume: function () { + var e = this, + t = arguments, + r, + i; + if (t.length === 0) return e._volume; + t.length === 1 || (t.length === 2 && t[1] === void 0) + ? e._getSoundIds().indexOf(t[0]) >= 0 + ? (i = parseInt(t[0], 10)) + : (r = parseFloat(t[0])) + : t.length >= 2 && ((r = parseFloat(t[0])), (i = parseInt(t[1], 10))); + var a; + if (r !== void 0 && r >= 0 && r <= 1) { + if (e._state !== `loaded` || e._playLock) + return ( + e._queue.push({ + event: `volume`, + action: function () { + e.volume.apply(e, t); + }, + }), + e + ); + (i === void 0 && (e._volume = r), (i = e._getSoundIds(i))); + for (var o = 0; o < i.length; o++) + ((a = e._soundById(i[o])), + a && + ((a._volume = r), + t[2] || e._stopFade(i[o]), + e._webAudio && a._node && !a._muted + ? a._node.gain.setValueAtTime(r, n.ctx.currentTime) + : a._node && !a._muted && (a._node.volume = r * n.volume()), + e._emit(`volume`, a._id))); + } else return ((a = i ? e._soundById(i) : e._sounds[0]), a ? a._volume : 0); + return e; + }, + fade: function (e, t, r, i) { + var a = this; + if (a._state !== `loaded` || a._playLock) + return ( + a._queue.push({ + event: `fade`, + action: function () { + a.fade(e, t, r, i); + }, + }), + a + ); + ((e = Math.min(Math.max(0, parseFloat(e)), 1)), + (t = Math.min(Math.max(0, parseFloat(t)), 1)), + (r = parseFloat(r)), + a.volume(e, i)); + for (var o = a._getSoundIds(i), s = 0; s < o.length; s++) { + var c = a._soundById(o[s]); + if (c) { + if ((i || a._stopFade(o[s]), a._webAudio && !c._muted)) { + var l = n.ctx.currentTime, + u = l + r / 1e3; + ((c._volume = e), c._node.gain.setValueAtTime(e, l), c._node.gain.linearRampToValueAtTime(t, u)); + } + a._startFadeInterval(c, e, t, r, o[s], i === void 0); + } + } + return a; + }, + _startFadeInterval: function (e, t, n, r, i, a) { + var o = this, + s = t, + c = n - t, + l = Math.abs(c / 0.01), + u = Math.max(4, l > 0 ? r / l : r), + d = Date.now(); + ((e._fadeTo = n), + (e._interval = setInterval(function () { + var i = (Date.now() - d) / r; + ((d = Date.now()), + (s += c * i), + (s = Math.round(s * 100) / 100), + (s = c < 0 ? Math.max(n, s) : Math.min(n, s)), + o._webAudio ? (e._volume = s) : o.volume(s, e._id, !0), + a && (o._volume = s), + ((n < t && s <= n) || (n > t && s >= n)) && + (clearInterval(e._interval), + (e._interval = null), + (e._fadeTo = null), + o.volume(n, e._id), + o._emit(`fade`, e._id))); + }, u))); + }, + _stopFade: function (e) { + var t = this, + r = t._soundById(e); + return ( + r && + r._interval && + (t._webAudio && r._node.gain.cancelScheduledValues(n.ctx.currentTime), + clearInterval(r._interval), + (r._interval = null), + t.volume(r._fadeTo, e), + (r._fadeTo = null), + t._emit(`fade`, e)), + t + ); + }, + loop: function () { + var e = this, + t = arguments, + n, + r, + i; + if (t.length === 0) return e._loop; + if (t.length === 1) + if (typeof t[0] == `boolean`) ((n = t[0]), (e._loop = n)); + else return ((i = e._soundById(parseInt(t[0], 10))), i ? i._loop : !1); + else t.length === 2 && ((n = t[0]), (r = parseInt(t[1], 10))); + for (var a = e._getSoundIds(r), o = 0; o < a.length; o++) + ((i = e._soundById(a[o])), + i && + ((i._loop = n), + e._webAudio && + i._node && + i._node.bufferSource && + ((i._node.bufferSource.loop = n), + n && + ((i._node.bufferSource.loopStart = i._start || 0), + (i._node.bufferSource.loopEnd = i._stop), + e.playing(a[o]) && (e.pause(a[o], !0), e.play(a[o], !0)))))); + return e; + }, + rate: function () { + var e = this, + t = arguments, + r, + i; + t.length === 0 + ? (i = e._sounds[0]._id) + : t.length === 1 + ? e._getSoundIds().indexOf(t[0]) >= 0 + ? (i = parseInt(t[0], 10)) + : (r = parseFloat(t[0])) + : t.length === 2 && ((r = parseFloat(t[0])), (i = parseInt(t[1], 10))); + var a; + if (typeof r == `number`) { + if (e._state !== `loaded` || e._playLock) + return ( + e._queue.push({ + event: `rate`, + action: function () { + e.rate.apply(e, t); + }, + }), + e + ); + (i === void 0 && (e._rate = r), (i = e._getSoundIds(i))); + for (var o = 0; o < i.length; o++) + if (((a = e._soundById(i[o])), a)) { + (e.playing(i[o]) && + ((a._rateSeek = e.seek(i[o])), (a._playStart = e._webAudio ? n.ctx.currentTime : a._playStart)), + (a._rate = r), + e._webAudio && a._node && a._node.bufferSource + ? a._node.bufferSource.playbackRate.setValueAtTime(r, n.ctx.currentTime) + : a._node && (a._node.playbackRate = r)); + var s = e.seek(i[o]), + c = (((e._sprite[a._sprite][0] + e._sprite[a._sprite][1]) / 1e3 - s) * 1e3) / Math.abs(a._rate); + ((e._endTimers[i[o]] || !a._paused) && + (e._clearTimer(i[o]), (e._endTimers[i[o]] = setTimeout(e._ended.bind(e, a), c))), + e._emit(`rate`, a._id)); + } + } else return ((a = e._soundById(i)), a ? a._rate : e._rate); + return e; + }, + seek: function () { + var e = this, + t = arguments, + r, + i; + if ( + (t.length === 0 + ? e._sounds.length && (i = e._sounds[0]._id) + : t.length === 1 + ? e._getSoundIds().indexOf(t[0]) >= 0 + ? (i = parseInt(t[0], 10)) + : e._sounds.length && ((i = e._sounds[0]._id), (r = parseFloat(t[0]))) + : t.length === 2 && ((r = parseFloat(t[0])), (i = parseInt(t[1], 10))), + i === void 0) + ) + return 0; + if (typeof r == `number` && (e._state !== `loaded` || e._playLock)) + return ( + e._queue.push({ + event: `seek`, + action: function () { + e.seek.apply(e, t); + }, + }), + e + ); + var a = e._soundById(i); + if (a) + if (typeof r == `number` && r >= 0) { + var o = e.playing(i); + (o && e.pause(i, !0), + (a._seek = r), + (a._ended = !1), + e._clearTimer(i), + !e._webAudio && a._node && !isNaN(a._node.duration) && (a._node.currentTime = r)); + var s = function () { + (o && e.play(i, !0), e._emit(`seek`, i)); + }; + if (o && !e._webAudio) { + var c = function () { + e._playLock ? setTimeout(c, 0) : s(); + }; + setTimeout(c, 0); + } else s(); + } else if (e._webAudio) { + var l = e.playing(i) ? n.ctx.currentTime - a._playStart : 0, + u = a._rateSeek ? a._rateSeek - a._seek : 0; + return a._seek + (u + l * Math.abs(a._rate)); + } else return a._node.currentTime; + return e; + }, + playing: function (e) { + var t = this; + if (typeof e == `number`) { + var n = t._soundById(e); + return n ? !n._paused : !1; + } + for (var r = 0; r < t._sounds.length; r++) if (!t._sounds[r]._paused) return !0; + return !1; + }, + duration: function (e) { + var t = this, + n = t._duration, + r = t._soundById(e); + return (r && (n = t._sprite[r._sprite][1] / 1e3), n); + }, + state: function () { + return this._state; + }, + unload: function () { + for (var e = this, t = e._sounds, r = 0; r < t.length; r++) + (t[r]._paused || e.stop(t[r]._id), + e._webAudio || + (e._clearSound(t[r]._node), + t[r]._node.removeEventListener(`error`, t[r]._errorFn, !1), + t[r]._node.removeEventListener(n._canPlayEvent, t[r]._loadFn, !1), + t[r]._node.removeEventListener(`ended`, t[r]._endFn, !1), + n._releaseHtml5Audio(t[r]._node)), + delete t[r]._node, + e._clearTimer(t[r]._id)); + var i = n._howls.indexOf(e); + i >= 0 && n._howls.splice(i, 1); + var o = !0; + for (r = 0; r < n._howls.length; r++) + if (n._howls[r]._src === e._src || e._src.indexOf(n._howls[r]._src) >= 0) { + o = !1; + break; + } + return ( + a && o && delete a[e._src], + (n.noAudio = !1), + (e._state = `unloaded`), + (e._sounds = []), + (e = null), + null + ); + }, + on: function (e, t, n, r) { + var i = this, + a = i[`_on` + e]; + return (typeof t == `function` && a.push(r ? { id: n, fn: t, once: r } : { id: n, fn: t }), i); + }, + off: function (e, t, n) { + var r = this, + i = r[`_on` + e], + a = 0; + if ((typeof t == `number` && ((n = t), (t = null)), t || n)) + for (a = 0; a < i.length; a++) { + var o = n === i[a].id; + if ((t === i[a].fn && o) || (!t && o)) { + i.splice(a, 1); + break; + } + } + else if (e) r[`_on` + e] = []; + else { + var s = Object.keys(r); + for (a = 0; a < s.length; a++) s[a].indexOf(`_on`) === 0 && Array.isArray(r[s[a]]) && (r[s[a]] = []); + } + return r; + }, + once: function (e, t, n) { + var r = this; + return (r.on(e, t, n, 1), r); + }, + _emit: function (e, t, n) { + for (var r = this, i = r[`_on` + e], a = i.length - 1; a >= 0; a--) + (!i[a].id || i[a].id === t || e === `load`) && + (setTimeout( + function (e) { + e.call(this, t, n); + }.bind(r, i[a].fn), + 0, + ), + i[a].once && r.off(e, i[a].fn, i[a].id)); + return (r._loadQueue(e), r); + }, + _loadQueue: function (e) { + var t = this; + if (t._queue.length > 0) { + var n = t._queue[0]; + (n.event === e && (t._queue.shift(), t._loadQueue()), e || n.action()); + } + return t; + }, + _ended: function (e) { + var t = this, + r = e._sprite; + if (!t._webAudio && e._node && !e._node.paused && !e._node.ended && e._node.currentTime < e._stop) + return (setTimeout(t._ended.bind(t, e), 100), t); + var i = !!(e._loop || t._sprite[r][2]); + if ((t._emit(`end`, e._id), !t._webAudio && i && t.stop(e._id, !0).play(e._id), t._webAudio && i)) { + (t._emit(`play`, e._id), (e._seek = e._start || 0), (e._rateSeek = 0), (e._playStart = n.ctx.currentTime)); + var a = ((e._stop - e._start) * 1e3) / Math.abs(e._rate); + t._endTimers[e._id] = setTimeout(t._ended.bind(t, e), a); + } + return ( + t._webAudio && + !i && + ((e._paused = !0), + (e._ended = !0), + (e._seek = e._start || 0), + (e._rateSeek = 0), + t._clearTimer(e._id), + t._cleanBuffer(e._node), + n._autoSuspend()), + !t._webAudio && !i && t.stop(e._id, !0), + t + ); + }, + _clearTimer: function (e) { + var t = this; + if (t._endTimers[e]) { + if (typeof t._endTimers[e] != `function`) clearTimeout(t._endTimers[e]); + else { + var n = t._soundById(e); + n && n._node && n._node.removeEventListener(`ended`, t._endTimers[e], !1); + } + delete t._endTimers[e]; + } + return t; + }, + _soundById: function (e) { + for (var t = this, n = 0; n < t._sounds.length; n++) if (e === t._sounds[n]._id) return t._sounds[n]; + return null; + }, + _inactiveSound: function () { + var e = this; + e._drain(); + for (var t = 0; t < e._sounds.length; t++) if (e._sounds[t]._ended) return e._sounds[t].reset(); + return new i(e); + }, + _drain: function () { + var e = this, + t = e._pool, + n = 0, + r = 0; + if (!(e._sounds.length < t)) { + for (r = 0; r < e._sounds.length; r++) e._sounds[r]._ended && n++; + for (r = e._sounds.length - 1; r >= 0; r--) { + if (n <= t) return; + e._sounds[r]._ended && + (e._webAudio && e._sounds[r]._node && e._sounds[r]._node.disconnect(0), e._sounds.splice(r, 1), n--); + } + } + }, + _getSoundIds: function (e) { + var t = this; + if (e === void 0) { + for (var n = [], r = 0; r < t._sounds.length; r++) n.push(t._sounds[r]._id); + return n; + } else return [e]; + }, + _refreshBuffer: function (e) { + var t = this; + return ( + (e._node.bufferSource = n.ctx.createBufferSource()), + (e._node.bufferSource.buffer = a[t._src]), + e._panner ? e._node.bufferSource.connect(e._panner) : e._node.bufferSource.connect(e._node), + (e._node.bufferSource.loop = e._loop), + e._loop && ((e._node.bufferSource.loopStart = e._start || 0), (e._node.bufferSource.loopEnd = e._stop || 0)), + e._node.bufferSource.playbackRate.setValueAtTime(e._rate, n.ctx.currentTime), + t + ); + }, + _cleanBuffer: function (e) { + var t = this, + r = n._navigator && n._navigator.vendor.indexOf(`Apple`) >= 0; + if (!e.bufferSource) return t; + if (n._scratchBuffer && e.bufferSource && ((e.bufferSource.onended = null), e.bufferSource.disconnect(0), r)) + try { + e.bufferSource.buffer = n._scratchBuffer; + } catch {} + return ((e.bufferSource = null), t); + }, + _clearSound: function (e) { + /MSIE |Trident\//.test(n._navigator && n._navigator.userAgent) || + (e.src = `data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA`); + }, + }; + var i = function (e) { + ((this._parent = e), this.init()); + }; + i.prototype = { + init: function () { + var e = this, + t = e._parent; + return ( + (e._muted = t._muted), + (e._loop = t._loop), + (e._volume = t._volume), + (e._rate = t._rate), + (e._seek = 0), + (e._paused = !0), + (e._ended = !0), + (e._sprite = `__default`), + (e._id = ++n._counter), + t._sounds.push(e), + e.create(), + e + ); + }, + create: function () { + var e = this, + t = e._parent, + r = n._muted || e._muted || e._parent._muted ? 0 : e._volume; + return ( + t._webAudio + ? ((e._node = n.ctx.createGain === void 0 ? n.ctx.createGainNode() : n.ctx.createGain()), + e._node.gain.setValueAtTime(r, n.ctx.currentTime), + (e._node.paused = !0), + e._node.connect(n.masterGain)) + : n.noAudio || + ((e._node = n._obtainHtml5Audio()), + (e._errorFn = e._errorListener.bind(e)), + e._node.addEventListener(`error`, e._errorFn, !1), + (e._loadFn = e._loadListener.bind(e)), + e._node.addEventListener(n._canPlayEvent, e._loadFn, !1), + (e._endFn = e._endListener.bind(e)), + e._node.addEventListener(`ended`, e._endFn, !1), + (e._node.src = t._src), + (e._node.preload = t._preload === !0 ? `auto` : t._preload), + (e._node.volume = r * n.volume()), + e._node.load()), + e + ); + }, + reset: function () { + var e = this, + t = e._parent; + return ( + (e._muted = t._muted), + (e._loop = t._loop), + (e._volume = t._volume), + (e._rate = t._rate), + (e._seek = 0), + (e._rateSeek = 0), + (e._paused = !0), + (e._ended = !0), + (e._sprite = `__default`), + (e._id = ++n._counter), + e + ); + }, + _errorListener: function () { + var e = this; + (e._parent._emit(`loaderror`, e._id, e._node.error ? e._node.error.code : 0), + e._node.removeEventListener(`error`, e._errorFn, !1)); + }, + _loadListener: function () { + var e = this, + t = e._parent; + ((t._duration = Math.ceil(e._node.duration * 10) / 10), + Object.keys(t._sprite).length === 0 && (t._sprite = { __default: [0, t._duration * 1e3] }), + t._state !== `loaded` && ((t._state = `loaded`), t._emit(`load`), t._loadQueue()), + e._node.removeEventListener(n._canPlayEvent, e._loadFn, !1)); + }, + _endListener: function () { + var e = this, + t = e._parent; + (t._duration === 1 / 0 && + ((t._duration = Math.ceil(e._node.duration * 10) / 10), + t._sprite.__default[1] === 1 / 0 && (t._sprite.__default[1] = t._duration * 1e3), + t._ended(e)), + e._node.removeEventListener(`ended`, e._endFn, !1)); + }, + }; + var a = {}, + o = function (e) { + var t = e._src; + if (a[t]) { + ((e._duration = a[t].duration), l(e)); + return; + } + if (/^data:[^;]+;base64,/.test(t)) { + for (var n = atob(t.split(`,`)[1]), r = new Uint8Array(n.length), i = 0; i < n.length; ++i) + r[i] = n.charCodeAt(i); + c(r.buffer, e); + } else { + var o = new XMLHttpRequest(); + (o.open(e._xhr.method, t, !0), + (o.withCredentials = e._xhr.withCredentials), + (o.responseType = `arraybuffer`), + e._xhr.headers && + Object.keys(e._xhr.headers).forEach(function (t) { + o.setRequestHeader(t, e._xhr.headers[t]); + }), + (o.onload = function () { + var t = (o.status + ``)[0]; + if (t !== `0` && t !== `2` && t !== `3`) { + e._emit(`loaderror`, null, `Failed loading audio file with status: ` + o.status + `.`); + return; + } + c(o.response, e); + }), + (o.onerror = function () { + e._webAudio && ((e._html5 = !0), (e._webAudio = !1), (e._sounds = []), delete a[t], e.load()); + }), + s(o)); + } + }, + s = function (e) { + try { + e.send(); + } catch { + e.onerror(); + } + }, + c = function (e, t) { + var r = function () { + t._emit(`loaderror`, null, `Decoding audio data failed.`); + }, + i = function (e) { + e && t._sounds.length > 0 ? ((a[t._src] = e), l(t, e)) : r(); + }; + typeof Promise < `u` && n.ctx.decodeAudioData.length === 1 + ? n.ctx.decodeAudioData(e).then(i).catch(r) + : n.ctx.decodeAudioData(e, i, r); + }, + l = function (e, t) { + (t && !e._duration && (e._duration = t.duration), + Object.keys(e._sprite).length === 0 && (e._sprite = { __default: [0, e._duration * 1e3] }), + e._state !== `loaded` && ((e._state = `loaded`), e._emit(`load`), e._loadQueue())); + }, + u = function () { + if (n.usingWebAudio) { + try { + typeof AudioContext < `u` + ? (n.ctx = new AudioContext()) + : typeof webkitAudioContext < `u` + ? (n.ctx = new webkitAudioContext()) + : (n.usingWebAudio = !1); + } catch { + n.usingWebAudio = !1; + } + n.ctx || (n.usingWebAudio = !1); + var e = /iP(hone|od|ad)/.test(n._navigator && n._navigator.platform), + t = n._navigator && n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/), + r = t ? parseInt(t[1], 10) : null; + if (e && r && r < 9) { + var i = /safari/.test(n._navigator && n._navigator.userAgent.toLowerCase()); + n._navigator && !i && (n.usingWebAudio = !1); + } + (n.usingWebAudio && + ((n.masterGain = n.ctx.createGain === void 0 ? n.ctx.createGainNode() : n.ctx.createGain()), + n.masterGain.gain.setValueAtTime(n._muted ? 0 : n._volume, n.ctx.currentTime), + n.masterGain.connect(n.ctx.destination)), + n._setup()); + } + }; + (typeof define == `function` && + define.amd && + define([], function () { + return { Howler: n, Howl: r }; + }), + e !== void 0 && ((e.Howler = n), (e.Howl = r)), + typeof global < `u` + ? ((global.HowlerGlobal = t), (global.Howler = n), (global.Howl = r), (global.Sound = i)) + : typeof window < `u` && + ((window.HowlerGlobal = t), (window.Howler = n), (window.Howl = r), (window.Sound = i))); + })(), + (function () { + ((HowlerGlobal.prototype._pos = [0, 0, 0]), + (HowlerGlobal.prototype._orientation = [0, 0, -1, 0, 1, 0]), + (HowlerGlobal.prototype.stereo = function (e) { + var t = this; + if (!t.ctx || !t.ctx.listener) return t; + for (var n = t._howls.length - 1; n >= 0; n--) t._howls[n].stereo(e); + return t; + }), + (HowlerGlobal.prototype.pos = function (e, t, n) { + var r = this; + if (!r.ctx || !r.ctx.listener) return r; + if ( + ((t = typeof t == `number` ? t : r._pos[1]), + (n = typeof n == `number` ? n : r._pos[2]), + typeof e == `number`) + ) + ((r._pos = [e, t, n]), + r.ctx.listener.positionX === void 0 + ? r.ctx.listener.setPosition(r._pos[0], r._pos[1], r._pos[2]) + : (r.ctx.listener.positionX.setTargetAtTime(r._pos[0], Howler.ctx.currentTime, 0.1), + r.ctx.listener.positionY.setTargetAtTime(r._pos[1], Howler.ctx.currentTime, 0.1), + r.ctx.listener.positionZ.setTargetAtTime(r._pos[2], Howler.ctx.currentTime, 0.1))); + else return r._pos; + return r; + }), + (HowlerGlobal.prototype.orientation = function (e, t, n, r, i, a) { + var o = this; + if (!o.ctx || !o.ctx.listener) return o; + var s = o._orientation; + if ( + ((t = typeof t == `number` ? t : s[1]), + (n = typeof n == `number` ? n : s[2]), + (r = typeof r == `number` ? r : s[3]), + (i = typeof i == `number` ? i : s[4]), + (a = typeof a == `number` ? a : s[5]), + typeof e == `number`) + ) + ((o._orientation = [e, t, n, r, i, a]), + o.ctx.listener.forwardX === void 0 + ? o.ctx.listener.setOrientation(e, t, n, r, i, a) + : (o.ctx.listener.forwardX.setTargetAtTime(e, Howler.ctx.currentTime, 0.1), + o.ctx.listener.forwardY.setTargetAtTime(t, Howler.ctx.currentTime, 0.1), + o.ctx.listener.forwardZ.setTargetAtTime(n, Howler.ctx.currentTime, 0.1), + o.ctx.listener.upX.setTargetAtTime(r, Howler.ctx.currentTime, 0.1), + o.ctx.listener.upY.setTargetAtTime(i, Howler.ctx.currentTime, 0.1), + o.ctx.listener.upZ.setTargetAtTime(a, Howler.ctx.currentTime, 0.1))); + else return s; + return o; + }), + (Howl.prototype.init = (function (e) { + return function (t) { + var n = this; + return ( + (n._orientation = t.orientation || [1, 0, 0]), + (n._stereo = t.stereo || null), + (n._pos = t.pos || null), + (n._pannerAttr = { + coneInnerAngle: t.coneInnerAngle === void 0 ? 360 : t.coneInnerAngle, + coneOuterAngle: t.coneOuterAngle === void 0 ? 360 : t.coneOuterAngle, + coneOuterGain: t.coneOuterGain === void 0 ? 0 : t.coneOuterGain, + distanceModel: t.distanceModel === void 0 ? `inverse` : t.distanceModel, + maxDistance: t.maxDistance === void 0 ? 1e4 : t.maxDistance, + panningModel: t.panningModel === void 0 ? `HRTF` : t.panningModel, + refDistance: t.refDistance === void 0 ? 1 : t.refDistance, + rolloffFactor: t.rolloffFactor === void 0 ? 1 : t.rolloffFactor, + }), + (n._onstereo = t.onstereo ? [{ fn: t.onstereo }] : []), + (n._onpos = t.onpos ? [{ fn: t.onpos }] : []), + (n._onorientation = t.onorientation ? [{ fn: t.onorientation }] : []), + e.call(this, t) + ); + }; + })(Howl.prototype.init)), + (Howl.prototype.stereo = function (t, n) { + var r = this; + if (!r._webAudio) return r; + if (r._state !== `loaded`) + return ( + r._queue.push({ + event: `stereo`, + action: function () { + r.stereo(t, n); + }, + }), + r + ); + var i = Howler.ctx.createStereoPanner === void 0 ? `spatial` : `stereo`; + if (n === void 0) + if (typeof t == `number`) ((r._stereo = t), (r._pos = [t, 0, 0])); + else return r._stereo; + for (var a = r._getSoundIds(n), o = 0; o < a.length; o++) { + var s = r._soundById(a[o]); + if (s) + if (typeof t == `number`) + ((s._stereo = t), + (s._pos = [t, 0, 0]), + s._node && + ((s._pannerAttr.panningModel = `equalpower`), + (!s._panner || !s._panner.pan) && e(s, i), + i === `spatial` + ? s._panner.positionX === void 0 + ? s._panner.setPosition(t, 0, 0) + : (s._panner.positionX.setValueAtTime(t, Howler.ctx.currentTime), + s._panner.positionY.setValueAtTime(0, Howler.ctx.currentTime), + s._panner.positionZ.setValueAtTime(0, Howler.ctx.currentTime)) + : s._panner.pan.setValueAtTime(t, Howler.ctx.currentTime)), + r._emit(`stereo`, s._id)); + else return s._stereo; + } + return r; + }), + (Howl.prototype.pos = function (t, n, r, i) { + var a = this; + if (!a._webAudio) return a; + if (a._state !== `loaded`) + return ( + a._queue.push({ + event: `pos`, + action: function () { + a.pos(t, n, r, i); + }, + }), + a + ); + if (((n = typeof n == `number` ? n : 0), (r = typeof r == `number` ? r : -0.5), i === void 0)) + if (typeof t == `number`) a._pos = [t, n, r]; + else return a._pos; + for (var o = a._getSoundIds(i), s = 0; s < o.length; s++) { + var c = a._soundById(o[s]); + if (c) + if (typeof t == `number`) + ((c._pos = [t, n, r]), + c._node && + ((!c._panner || c._panner.pan) && e(c, `spatial`), + c._panner.positionX === void 0 + ? c._panner.setPosition(t, n, r) + : (c._panner.positionX.setValueAtTime(t, Howler.ctx.currentTime), + c._panner.positionY.setValueAtTime(n, Howler.ctx.currentTime), + c._panner.positionZ.setValueAtTime(r, Howler.ctx.currentTime))), + a._emit(`pos`, c._id)); + else return c._pos; + } + return a; + }), + (Howl.prototype.orientation = function (t, n, r, i) { + var a = this; + if (!a._webAudio) return a; + if (a._state !== `loaded`) + return ( + a._queue.push({ + event: `orientation`, + action: function () { + a.orientation(t, n, r, i); + }, + }), + a + ); + if ( + ((n = typeof n == `number` ? n : a._orientation[1]), + (r = typeof r == `number` ? r : a._orientation[2]), + i === void 0) + ) + if (typeof t == `number`) a._orientation = [t, n, r]; + else return a._orientation; + for (var o = a._getSoundIds(i), s = 0; s < o.length; s++) { + var c = a._soundById(o[s]); + if (c) + if (typeof t == `number`) + ((c._orientation = [t, n, r]), + c._node && + (c._panner || ((c._pos ||= a._pos || [0, 0, -0.5]), e(c, `spatial`)), + c._panner.orientationX === void 0 + ? c._panner.setOrientation(t, n, r) + : (c._panner.orientationX.setValueAtTime(t, Howler.ctx.currentTime), + c._panner.orientationY.setValueAtTime(n, Howler.ctx.currentTime), + c._panner.orientationZ.setValueAtTime(r, Howler.ctx.currentTime))), + a._emit(`orientation`, c._id)); + else return c._orientation; + } + return a; + }), + (Howl.prototype.pannerAttr = function () { + var t = this, + n = arguments, + r, + i, + a; + if (!t._webAudio) return t; + if (n.length === 0) return t._pannerAttr; + if (n.length === 1) + if (typeof n[0] == `object`) + ((r = n[0]), + i === void 0 && + ((r.pannerAttr ||= { + coneInnerAngle: r.coneInnerAngle, + coneOuterAngle: r.coneOuterAngle, + coneOuterGain: r.coneOuterGain, + distanceModel: r.distanceModel, + maxDistance: r.maxDistance, + refDistance: r.refDistance, + rolloffFactor: r.rolloffFactor, + panningModel: r.panningModel, + }), + (t._pannerAttr = { + coneInnerAngle: + r.pannerAttr.coneInnerAngle === void 0 ? t._coneInnerAngle : r.pannerAttr.coneInnerAngle, + coneOuterAngle: + r.pannerAttr.coneOuterAngle === void 0 ? t._coneOuterAngle : r.pannerAttr.coneOuterAngle, + coneOuterGain: + r.pannerAttr.coneOuterGain === void 0 ? t._coneOuterGain : r.pannerAttr.coneOuterGain, + distanceModel: + r.pannerAttr.distanceModel === void 0 ? t._distanceModel : r.pannerAttr.distanceModel, + maxDistance: r.pannerAttr.maxDistance === void 0 ? t._maxDistance : r.pannerAttr.maxDistance, + refDistance: r.pannerAttr.refDistance === void 0 ? t._refDistance : r.pannerAttr.refDistance, + rolloffFactor: + r.pannerAttr.rolloffFactor === void 0 ? t._rolloffFactor : r.pannerAttr.rolloffFactor, + panningModel: r.pannerAttr.panningModel === void 0 ? t._panningModel : r.pannerAttr.panningModel, + }))); + else return ((a = t._soundById(parseInt(n[0], 10))), a ? a._pannerAttr : t._pannerAttr); + else n.length === 2 && ((r = n[0]), (i = parseInt(n[1], 10))); + for (var o = t._getSoundIds(i), s = 0; s < o.length; s++) + if (((a = t._soundById(o[s])), a)) { + var c = a._pannerAttr; + c = { + coneInnerAngle: r.coneInnerAngle === void 0 ? c.coneInnerAngle : r.coneInnerAngle, + coneOuterAngle: r.coneOuterAngle === void 0 ? c.coneOuterAngle : r.coneOuterAngle, + coneOuterGain: r.coneOuterGain === void 0 ? c.coneOuterGain : r.coneOuterGain, + distanceModel: r.distanceModel === void 0 ? c.distanceModel : r.distanceModel, + maxDistance: r.maxDistance === void 0 ? c.maxDistance : r.maxDistance, + refDistance: r.refDistance === void 0 ? c.refDistance : r.refDistance, + rolloffFactor: r.rolloffFactor === void 0 ? c.rolloffFactor : r.rolloffFactor, + panningModel: r.panningModel === void 0 ? c.panningModel : r.panningModel, + }; + var l = a._panner; + ((l ||= ((a._pos ||= t._pos || [0, 0, -0.5]), e(a, `spatial`), a._panner)), + (l.coneInnerAngle = c.coneInnerAngle), + (l.coneOuterAngle = c.coneOuterAngle), + (l.coneOuterGain = c.coneOuterGain), + (l.distanceModel = c.distanceModel), + (l.maxDistance = c.maxDistance), + (l.refDistance = c.refDistance), + (l.rolloffFactor = c.rolloffFactor), + (l.panningModel = c.panningModel)); + } + return t; + }), + (Sound.prototype.init = (function (e) { + return function () { + var t = this, + n = t._parent; + ((t._orientation = n._orientation), + (t._stereo = n._stereo), + (t._pos = n._pos), + (t._pannerAttr = n._pannerAttr), + e.call(this), + t._stereo ? n.stereo(t._stereo) : t._pos && n.pos(t._pos[0], t._pos[1], t._pos[2], t._id)); + }; + })(Sound.prototype.init)), + (Sound.prototype.reset = (function (e) { + return function () { + var t = this, + n = t._parent; + return ( + (t._orientation = n._orientation), + (t._stereo = n._stereo), + (t._pos = n._pos), + (t._pannerAttr = n._pannerAttr), + t._stereo + ? n.stereo(t._stereo) + : t._pos + ? n.pos(t._pos[0], t._pos[1], t._pos[2], t._id) + : t._panner && (t._panner.disconnect(0), (t._panner = void 0), n._refreshBuffer(t)), + e.call(this) + ); + }; + })(Sound.prototype.reset))); + var e = function (e, t) { + ((t ||= `spatial`), + t === `spatial` + ? ((e._panner = Howler.ctx.createPanner()), + (e._panner.coneInnerAngle = e._pannerAttr.coneInnerAngle), + (e._panner.coneOuterAngle = e._pannerAttr.coneOuterAngle), + (e._panner.coneOuterGain = e._pannerAttr.coneOuterGain), + (e._panner.distanceModel = e._pannerAttr.distanceModel), + (e._panner.maxDistance = e._pannerAttr.maxDistance), + (e._panner.refDistance = e._pannerAttr.refDistance), + (e._panner.rolloffFactor = e._pannerAttr.rolloffFactor), + (e._panner.panningModel = e._pannerAttr.panningModel), + e._panner.positionX === void 0 + ? e._panner.setPosition(e._pos[0], e._pos[1], e._pos[2]) + : (e._panner.positionX.setValueAtTime(e._pos[0], Howler.ctx.currentTime), + e._panner.positionY.setValueAtTime(e._pos[1], Howler.ctx.currentTime), + e._panner.positionZ.setValueAtTime(e._pos[2], Howler.ctx.currentTime)), + e._panner.orientationX === void 0 + ? e._panner.setOrientation(e._orientation[0], e._orientation[1], e._orientation[2]) + : (e._panner.orientationX.setValueAtTime(e._orientation[0], Howler.ctx.currentTime), + e._panner.orientationY.setValueAtTime(e._orientation[1], Howler.ctx.currentTime), + e._panner.orientationZ.setValueAtTime(e._orientation[2], Howler.ctx.currentTime))) + : ((e._panner = Howler.ctx.createStereoPanner()), + e._panner.pan.setValueAtTime(e._stereo, Howler.ctx.currentTime)), + e._panner.connect(e._node), + e._paused || e._parent.pause(e._id, !0).play(e._id, !0)); + }; + })()); +}); +export default t(); diff --git a/pro/dist/assets/index-BqANBEcr.js b/pro/dist/assets/index-BqANBEcr.js deleted file mode 100644 index eec788b..0000000 --- a/pro/dist/assets/index-BqANBEcr.js +++ /dev/null @@ -1,124 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=o((e=>{var t=Symbol.for(`react.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.provider`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.iterator;function p(e){return typeof e!=`object`||!e?null:(e=f&&e[f]||e[`@@iterator`],typeof e==`function`?e:null)}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function _(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}_.prototype.isReactComponent={},_.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`setState(...): takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},_.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function v(){}v.prototype=_.prototype;function y(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}var b=y.prototype=new v;b.constructor=y,h(b,_.prototype),b.isPureReactComponent=!0;var x=Array.isArray,S=Object.prototype.hasOwnProperty,C={current:null},w={key:!0,ref:!0,__self:!0,__source:!0};function T(e,n,r){var i,a={},o=null,s=null;if(n!=null)for(i in n.ref!==void 0&&(s=n.ref),n.key!==void 0&&(o=``+n.key),n)S.call(n,i)&&!w.hasOwnProperty(i)&&(a[i]=n[i]);var c=arguments.length-2;if(c===1)a.children=r;else if(1{t.exports=u()})),f=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=typeof setTimeout==`function`?setTimeout:null,_=typeof clearTimeout==`function`?clearTimeout:null,v=typeof setImmediate<`u`?setImmediate:null;typeof navigator<`u`&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function y(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function b(e){if(h=!1,y(e),!m)if(n(c)!==null)m=!0,ie(x);else{var t=n(l);t!==null&&ae(b,t.startTime-e)}}function x(t,i){m=!1,h&&(h=!1,_(w),w=-1),p=!0;var a=f;try{for(y(i),d=n(c);d!==null&&(!(d.expirationTime>i)||t&&!D());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=i);i=e.unstable_now(),typeof s==`function`?d.callback=s:d===n(c)&&r(c),y(i)}else r(c);d=n(c)}if(d!==null)var u=!0;else{var g=n(l);g!==null&&ae(b,g.startTime-i),u=!1}return u}finally{d=null,f=a,p=!1}}var S=!1,C=null,w=-1,T=5,E=-1;function D(){return!(e.unstable_now()-Ee||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(_(w),w=-1):h=!0,ae(b,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ie(x))),r},e.unstable_shouldYield=D,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),p=o(((e,t)=>{t.exports=f()})),m=o((e=>{var t=d(),n=p();function r(e){for(var t=`https://reactjs.org/docs/error-decoder.html?invariant=`+e,n=1;n`u`||window.document===void 0||window.document.createElement===void 0),l=Object.prototype.hasOwnProperty,u=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},m={};function h(e){return l.call(m,e)?!0:l.call(f,e)?!1:u.test(e)?m[e]=!0:(f[e]=!0,!1)}function g(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case`function`:case`symbol`:return!0;case`boolean`:return r?!1:n===null?(e=e.toLowerCase().slice(0,5),e!==`data-`&&e!==`aria-`):!n.acceptsBooleans;default:return!1}}function _(e,t,n,r){if(t==null||g(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function v(e,t,n,r,i,a,o){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=o}var y={};`children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style`.split(` `).forEach(function(e){y[e]=new v(e,0,!1,e,null,!1,!1)}),[[`acceptCharset`,`accept-charset`],[`className`,`class`],[`htmlFor`,`for`],[`httpEquiv`,`http-equiv`]].forEach(function(e){var t=e[0];y[t]=new v(t,1,!1,e[1],null,!1,!1)}),[`contentEditable`,`draggable`,`spellCheck`,`value`].forEach(function(e){y[e]=new v(e,2,!1,e.toLowerCase(),null,!1,!1)}),[`autoReverse`,`externalResourcesRequired`,`focusable`,`preserveAlpha`].forEach(function(e){y[e]=new v(e,2,!1,e,null,!1,!1)}),`allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope`.split(` `).forEach(function(e){y[e]=new v(e,3,!1,e.toLowerCase(),null,!1,!1)}),[`checked`,`multiple`,`muted`,`selected`].forEach(function(e){y[e]=new v(e,3,!0,e,null,!1,!1)}),[`capture`,`download`].forEach(function(e){y[e]=new v(e,4,!1,e,null,!1,!1)}),[`cols`,`rows`,`size`,`span`].forEach(function(e){y[e]=new v(e,6,!1,e,null,!1,!1)}),[`rowSpan`,`start`].forEach(function(e){y[e]=new v(e,5,!1,e.toLowerCase(),null,!1,!1)});var b=/[\-:]([a-z])/g;function x(e){return e[1].toUpperCase()}`accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height`.split(` `).forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,null,!1,!1)}),`xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type`.split(` `).forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,`http://www.w3.org/1999/xlink`,!1,!1)}),[`xml:base`,`xml:lang`,`xml:space`].forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,`http://www.w3.org/XML/1998/namespace`,!1,!1)}),[`tabIndex`,`crossOrigin`].forEach(function(e){y[e]=new v(e,1,!1,e.toLowerCase(),null,!1,!1)}),y.xlinkHref=new v(`xlinkHref`,1,!1,`xlink:href`,`http://www.w3.org/1999/xlink`,!0,!1),[`src`,`href`,`action`,`formAction`].forEach(function(e){y[e]=new v(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,t,n,r){var i=y.hasOwnProperty(t)?y[t]:null;(i===null?r||!(2s||i[o]!==a[s]){var c=` -`+i[o].replace(` at new `,` at `);return e.displayName&&c.includes(``)&&(c=c.replace(``,e.displayName)),c}while(1<=o&&0<=s);break}}}finally{de=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:``)?ue(e):``}function pe(e){switch(e.tag){case 5:return ue(e.type);case 16:return ue(`Lazy`);case 13:return ue(`Suspense`);case 19:return ue(`SuspenseList`);case 0:case 2:case 15:return e=fe(e.type,!1),e;case 11:return e=fe(e.type.render,!1),e;case 1:return e=fe(e.type,!0),e;default:return``}}function me(e){if(e==null)return null;if(typeof e==`function`)return e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case E:return`Fragment`;case T:return`Portal`;case ee:return`Profiler`;case D:return`StrictMode`;case ie:return`Suspense`;case ae:return`SuspenseList`}if(typeof e==`object`)switch(e.$$typeof){case ne:return(e.displayName||`Context`)+`.Consumer`;case te:return(e._context.displayName||`Context`)+`.Provider`;case re:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case O:return t=e.displayName||null,t===null?me(e.type)||`Memo`:t;case k:t=e._payload,e=e._init;try{return me(e(t))}catch{}}return null}function he(e){var t=e.type;switch(e.tag){case 24:return`Cache`;case 9:return(t.displayName||`Context`)+`.Consumer`;case 10:return(t._context.displayName||`Context`)+`.Provider`;case 18:return`DehydratedFragment`;case 11:return e=t.render,e=e.displayName||e.name||``,t.displayName||(e===``?`ForwardRef`:`ForwardRef(`+e+`)`);case 7:return`Fragment`;case 5:return t;case 4:return`Portal`;case 3:return`Root`;case 6:return`Text`;case 16:return me(t);case 8:return t===D?`StrictMode`:`Mode`;case 22:return`Offscreen`;case 12:return`Profiler`;case 21:return`Scope`;case 13:return`Suspense`;case 19:return`SuspenseList`;case 25:return`TracingMarker`;case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t==`function`)return t.displayName||t.name||null;if(typeof t==`string`)return t}return null}function j(e){switch(typeof e){case`boolean`:case`number`:case`string`:case`undefined`:return e;case`object`:return e;default:return``}}function ge(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()===`input`&&(t===`checkbox`||t===`radio`)}function _e(e){var t=ge(e)?`checked`:`value`,n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=``+e[t];if(!e.hasOwnProperty(t)&&n!==void 0&&typeof n.get==`function`&&typeof n.set==`function`){var i=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(e){r=``+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=``+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function ve(e){e._valueTracker||=_e(e)}function ye(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r=``;return e&&(r=ge(e)?e.checked?`true`:`false`:e.value),e=r,e===n?!1:(t.setValue(e),!0)}function be(e){if(e||=typeof document<`u`?document:void 0,e===void 0)return null;try{return e.activeElement||e.body}catch{return e.body}}function xe(e,t){var n=t.checked;return A({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function M(e,t){var n=t.defaultValue==null?``:t.defaultValue,r=t.checked==null?t.defaultChecked:t.checked;n=j(t.value==null?n:t.value),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type===`checkbox`||t.type===`radio`?t.checked!=null:t.value!=null}}function Se(e,t){t=t.checked,t!=null&&S(e,`checked`,t,!1)}function Ce(e,t){Se(e,t);var n=j(t.value),r=t.type;if(n!=null)r===`number`?(n===0&&e.value===``||e.value!=n)&&(e.value=``+n):e.value!==``+n&&(e.value=``+n);else if(r===`submit`||r===`reset`){e.removeAttribute(`value`);return}t.hasOwnProperty(`value`)?Te(e,t.type,n):t.hasOwnProperty(`defaultValue`)&&Te(e,t.type,j(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function we(e,t,n){if(t.hasOwnProperty(`value`)||t.hasOwnProperty(`defaultValue`)){var r=t.type;if(!(r!==`submit`&&r!==`reset`||t.value!==void 0&&t.value!==null))return;t=``+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==``&&(e.name=``),e.defaultChecked=!!e._wrapperState.initialChecked,n!==``&&(e.name=n)}function Te(e,t,n){(t!==`number`||be(e.ownerDocument)!==e)&&(n==null?e.defaultValue=``+e._wrapperState.initialValue:e.defaultValue!==``+n&&(e.defaultValue=``+n))}var N=Array.isArray;function Ee(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i`+t.valueOf().toString()+``,t=Ne.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Fe(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Ie={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Le=[`Webkit`,`ms`,`Moz`,`O`];Object.keys(Ie).forEach(function(e){Le.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Ie[t]=Ie[e]})});function Re(e,t,n){return t==null||typeof t==`boolean`||t===``?``:n||typeof t!=`number`||t===0||Ie.hasOwnProperty(e)&&Ie[e]?(``+t).trim():t+`px`}function ze(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=n.indexOf(`--`)===0,i=Re(n,t[n],r);n===`float`&&(n=`cssFloat`),r?e.setProperty(n,i):e[n]=i}}var Be=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ve(e,t){if(t){if(Be[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(r(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(r(60));if(typeof t.dangerouslySetInnerHTML!=`object`||!(`__html`in t.dangerouslySetInnerHTML))throw Error(r(61))}if(t.style!=null&&typeof t.style!=`object`)throw Error(r(62))}}function He(e,t){if(e.indexOf(`-`)===-1)return typeof t.is==`string`;switch(e){case`annotation-xml`:case`color-profile`:case`font-face`:case`font-face-src`:case`font-face-uri`:case`font-face-format`:case`font-face-name`:case`missing-glyph`:return!1;default:return!0}}var Ue=null;function We(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Ge=null,Ke=null,qe=null;function Je(e){if(e=Fi(e)){if(typeof Ge!=`function`)throw Error(r(280));var t=e.stateNode;t&&(t=Li(t),Ge(e.stateNode,e.type,t))}}function Ye(e){Ke?qe?qe.push(e):qe=[e]:Ke=e}function Xe(){if(Ke){var e=Ke,t=qe;if(qe=Ke=null,Je(e),t)for(e=0;e>>=0,e===0?32:31-(At(e)/jt|0)|0}var Nt=64,Pt=4194304;function Ft(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function It(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,i=e.suspendedLanes,a=e.pingedLanes,o=n&268435455;if(o!==0){var s=o&~i;s===0?(a&=o,a!==0&&(r=Ft(a))):r=Ft(s)}else o=n&~i,o===0?a!==0&&(r=Ft(a)):r=Ft(o);if(r===0)return 0;if(t!==0&&t!==r&&(t&i)===0&&(i=r&-r,a=t&-t,i>=a||i===16&&a&4194240))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function L(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-kt(t),e[t]=n}function Ht(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=B),H=` `,rr=!1;function ir(e,t){switch(e){case`keyup`:return er.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function ar(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var U=!1;function or(e,t){switch(e){case`compositionend`:return ar(t);case`keypress`:return t.which===32?(rr=!0,H):null;case`textInput`:return e=t.data,e===H&&rr?null:e;default:return null}}function sr(e,t){if(U)return e===`compositionend`||!tr&&ir(e,t)?(e=En(),Tn=wn=Cn=null,U=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=kr(n)}}function W(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?W(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function jr(){for(var e=window,t=be();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=be(e.document)}return t}function Mr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}function Nr(e){var t=jr(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&W(n.ownerDocument.documentElement,n)){if(r!==null&&Mr(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),`selectionStart`in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var i=n.textContent.length,a=Math.min(r.start,i);r=r.end===void 0?a:Math.min(r.end,i),!e.extend&&a>r&&(i=r,r=a,a=i),i=Ar(n,a);var o=Ar(n,r);i&&o&&(e.rangeCount!==1||e.anchorNode!==i.node||e.anchorOffset!==i.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&(t=t.createRange(),t.setStart(i.node,i.offset),e.removeAllRanges(),a>r?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus==`function`&&n.focus(),n=0;n=document.documentMode,Fr=null,Ir=null,Lr=null,Rr=!1;function zr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Rr||Fr==null||Fr!==be(r)||(r=Fr,`selectionStart`in r&&Mr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Lr&&Or(Lr,r)||(Lr=r,r=ci(Ir,`onSelect`),0zi||(e.current=Ri[zi],Ri[zi]=null,zi--)}function Y(e,t){zi++,Ri[zi]=e.current,e.current=t}var Vi={},Hi=Bi(Vi),Ui=Bi(!1),Wi=Vi;function Gi(e,t){var n=e.type.contextTypes;if(!n)return Vi;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i={},a;for(a in n)i[a]=t[a];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function Ki(e){return e=e.childContextTypes,e!=null}function qi(){J(Ui),J(Hi)}function Ji(e,t,n){if(Hi.current!==Vi)throw Error(r(168));Y(Hi,t),Y(Ui,n)}function Yi(e,t,n){var i=e.stateNode;if(t=t.childContextTypes,typeof i.getChildContext!=`function`)return n;for(var a in i=i.getChildContext(),i)if(!(a in t))throw Error(r(108,he(e)||`Unknown`,a));return A({},n,i)}function Xi(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Vi,Wi=Hi.current,Y(Hi,e),Y(Ui,Ui.current),!0}function X(e,t,n){var i=e.stateNode;if(!i)throw Error(r(169));n?(e=Yi(e,t,Wi),i.__reactInternalMemoizedMergedChildContext=e,J(Ui),J(Hi),Y(Hi,e)):J(Ui),Y(Ui,n)}var Zi=null,Qi=!1,$i=!1;function ea(e){Zi===null?Zi=[e]:Zi.push(e)}function ta(e){Qi=!0,ea(e)}function na(){if(!$i&&Zi!==null){$i=!0;var e=0,t=R;try{var n=Zi;for(R=1;e>=o,i-=o,ua=1<<32-kt(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(r,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(r,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(r,d),Z&&fa(r,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),Z&&fa(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return Z&&fa(a,g),u}for(h=i(a,h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),Z&&fa(a,g),u}function _(e,r,i,o){if(typeof i==`object`&&i&&i.type===E&&i.key===null&&(i=i.props.children),typeof i==`object`&&i){switch(i.$$typeof){case w:a:{for(var c=i.key,l=r;l!==null;){if(l.key===c){if(c=i.type,c===E){if(l.tag===7){n(e,l.sibling),r=a(l,i.props.children),r.return=e,e=r;break a}}else if(l.elementType===c||typeof c==`object`&&c&&c.$$typeof===k&&ja(c)===l.type){n(e,l.sibling),r=a(l,i.props),r.ref=ka(e,l,i),r.return=e,e=r;break a}n(e,l);break}else t(e,l);l=l.sibling}i.type===E?(r=Zl(i.props.children,e.mode,o,i.key),r.return=e,e=r):(o=Xl(i.type,i.key,i.props,null,e.mode,o),o.ref=ka(e,r,i),o.return=e,e=o)}return s(e);case T:a:{for(l=i.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===i.containerInfo&&r.stateNode.implementation===i.implementation){n(e,r.sibling),r=a(r,i.children||[]),r.return=e,e=r;break a}else{n(e,r);break}else t(e,r);r=r.sibling}r=eu(i,e.mode,o),r.return=e,e=r}return s(e);case k:return l=i._init,_(e,r,l(i._payload),o)}if(N(i))return h(e,r,i,o);if(ce(i))return g(e,r,i,o);Aa(e,i)}return typeof i==`string`&&i!==``||typeof i==`number`?(i=``+i,r!==null&&r.tag===6?(n(e,r.sibling),r=a(r,i),r.return=e,e=r):(n(e,r),r=$l(i,e.mode,o),r.return=e,e=r),s(e)):n(e,r)}return _}var Na=Ma(!0),Pa=Ma(!1),Fa=Bi(null),Ia=null,La=null,Ra=null;function za(){Ra=La=Ia=null}function Ba(e){var t=Fa.current;J(Fa),e._currentValue=t}function Va(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)===t?r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t):(e.childLanes|=t,r!==null&&(r.childLanes|=t)),e===n)break;e=e.return}}function Ha(e,t){Ia=e,Ra=La=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(Ms=!0),e.firstContext=null)}function Ua(e){var t=e._currentValue;if(Ra!==e)if(e={context:e,memoizedValue:t,next:null},La===null){if(Ia===null)throw Error(r(308));La=e,Ia.dependencies={lanes:0,firstContext:e}}else La=La.next=e;return t}var Wa=null;function Ga(e){Wa===null?Wa=[e]:Wa.push(e)}function Ka(e,t,n,r){var i=t.interleaved;return i===null?(n.next=n,Ga(t)):(n.next=i.next,i.next=n),t.interleaved=n,qa(e,r)}function qa(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var Ja=!1;function Ya(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Xa(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Za(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Qa(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,$&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,qa(e,n)}return i=r.interleaved,i===null?(t.next=t,Ga(r)):(t.next=i.next,i.next=t),r.interleaved=t,qa(e,n)}function $a(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194240)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Ut(e,n)}}function eo(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function to(e,t,n,r){var i=e.updateQueue;Ja=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane,p=s.eventTime;if((r&f)===f){u!==null&&(u=u.next={eventTime:p,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});a:{var m=e,h=s;switch(f=t,p=n,h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(p,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(p,d,f):m,f==null)break a;d=A({},d,f);break a;case 2:Ja=!0}}s.callback!==null&&s.lane!==0&&(e.flags|=64,f=i.effects,f===null?i.effects=[s]:f.push(s))}else p={eventTime:p,lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;f=s,s=f.next,f.next=null,i.lastBaseUpdate=f,i.shared.pending=null}}while(1);if(u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,t=i.shared.interleaved,t!==null){i=t;do o|=i.lane,i=i.next;while(i!==t)}else a===null&&(i.shared.lanes=0);Jc|=o,e.lanes=o,e.memoizedState=d}}function no(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=vo.transition;vo.transition={};try{e(!1),t()}finally{R=n,vo.transition=r}}function as(){return Mo().memoizedState}function os(e,t,n){var r=pl(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},cs(e))ls(t,n);else if(n=Ka(e,t,n,r),n!==null){var i=fl();ml(n,e,r,i),us(n,t,r)}}function ss(e,t,n){var r=pl(e),i={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(cs(e))ls(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Dr(s,o)){var c=t.interleaved;c===null?(i.next=i,Ga(t)):(i.next=c.next,c.next=i),t.interleaved=i;return}}catch{}n=Ka(e,t,i,r),n!==null&&(i=fl(),ml(n,e,r,i),us(n,t,r))}}function cs(e){var t=e.alternate;return e===bo||t!==null&&t===bo}function ls(e,t){wo=Co=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function us(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Ut(e,n)}}var ds={readContext:Ua,useCallback:Do,useContext:Do,useEffect:Do,useImperativeHandle:Do,useInsertionEffect:Do,useLayoutEffect:Do,useMemo:Do,useReducer:Do,useRef:Do,useState:Do,useDebugValue:Do,useDeferredValue:Do,useTransition:Do,useMutableSource:Do,useSyncExternalStore:Do,useId:Do,unstable_isNewReconciler:!1},fs={readContext:Ua,useCallback:function(e,t){return jo().memoizedState=[e,t===void 0?null:t],e},useContext:Ua,useEffect:Jo,useImperativeHandle:function(e,t,n){return n=n==null?null:n.concat([e]),Ko(4194308,4,Qo.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Ko(4194308,4,e,t)},useInsertionEffect:function(e,t){return Ko(4,2,e,t)},useMemo:function(e,t){var n=jo();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=jo();return t=n===void 0?t:n(t),r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=os.bind(null,bo,e),[r.memoizedState,e]},useRef:function(e){var t=jo();return e={current:e},t.memoizedState=e},useState:Uo,useDebugValue:es,useDeferredValue:function(e){return jo().memoizedState=e},useTransition:function(){var e=Uo(!1),t=e[0];return e=is.bind(null,e[1]),jo().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var i=bo,a=jo();if(Z){if(n===void 0)throw Error(r(407));n=n()}else{if(n=t(),Vc===null)throw Error(r(349));yo&30||Ro(i,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,Jo(Bo.bind(null,i,o,e),[e]),i.flags|=2048,Wo(9,zo.bind(null,i,o,n,t),void 0,null),n},useId:function(){var e=jo(),t=Vc.identifierPrefix;if(Z){var n=da,r=ua;n=(r&~(1<<32-kt(r)-1)).toString(32)+n,t=`:`+t+`R`+n,n=To++,0<\/script>`,e=e.removeChild(e.firstChild)):typeof i.is==`string`?e=c.createElement(n,{is:i.is}):(e=c.createElement(n),n===`select`&&(c=e,i.multiple?c.multiple=!0:i.size&&(c.size=i.size))):e=c.createElementNS(e,n),e[Oi]=t,e[ki]=i,nc(e,t,!1,!1),t.stateNode=e;a:{switch(c=He(n,i),n){case`dialog`:K(`cancel`,e),K(`close`,e),o=i;break;case`iframe`:case`object`:case`embed`:K(`load`,e),o=i;break;case`video`:case`audio`:for(o=0;o<$r.length;o++)K($r[o],e);o=i;break;case`source`:K(`error`,e),o=i;break;case`img`:case`image`:case`link`:K(`error`,e),K(`load`,e),o=i;break;case`details`:K(`toggle`,e),o=i;break;case`input`:M(e,i),o=xe(e,i),K(`invalid`,e);break;case`option`:o=i;break;case`select`:e._wrapperState={wasMultiple:!!i.multiple},o=A({},i,{value:void 0}),K(`invalid`,e);break;case`textarea`:Oe(e,i),o=De(e,i),K(`invalid`,e);break;default:o=i}for(s in Ve(n,o),l=o,l)if(l.hasOwnProperty(s)){var u=l[s];s===`style`?ze(e,u):s===`dangerouslySetInnerHTML`?(u=u?u.__html:void 0,u!=null&&Pe(e,u)):s===`children`?typeof u==`string`?(n!==`textarea`||u!==``)&&Fe(e,u):typeof u==`number`&&Fe(e,``+u):s!==`suppressContentEditableWarning`&&s!==`suppressHydrationWarning`&&s!==`autoFocus`&&(a.hasOwnProperty(s)?u!=null&&s===`onScroll`&&K(`scroll`,e):u!=null&&S(e,s,u,c))}switch(n){case`input`:ve(e),we(e,i,!1);break;case`textarea`:ve(e),Ae(e);break;case`option`:i.value!=null&&e.setAttribute(`value`,``+j(i.value));break;case`select`:e.multiple=!!i.multiple,s=i.value,s==null?i.defaultValue!=null&&Ee(e,!!i.multiple,i.defaultValue,!0):Ee(e,!!i.multiple,s,!1);break;default:typeof o.onClick==`function`&&(e.onclick=hi)}switch(n){case`button`:case`input`:case`select`:case`textarea`:i=!!i.autoFocus;break a;case`img`:i=!0;break a;default:i=!1}}i&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return oc(t),null;case 6:if(e&&t.stateNode!=null)ic(e,t,e.memoizedProps,i);else{if(typeof i!=`string`&&t.stateNode===null)throw Error(r(166));if(n=so(oo.current),so(io.current),wa(t)){if(i=t.stateNode,n=t.memoizedProps,i[Oi]=t,(s=i.nodeValue!==n)&&(e=ga,e!==null))switch(e.tag){case 3:mi(i.nodeValue,n,(e.mode&1)!=0);break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&mi(i.nodeValue,n,(e.mode&1)!=0)}s&&(t.flags|=4)}else i=(n.nodeType===9?n:n.ownerDocument).createTextNode(i),i[Oi]=t,t.stateNode=i}return oc(t),null;case 13:if(J(po),i=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(Z&&_a!==null&&t.mode&1&&!(t.flags&128))Ta(),Ea(),t.flags|=98560,s=!1;else if(s=wa(t),i!==null&&i.dehydrated!==null){if(e===null){if(!s)throw Error(r(318));if(s=t.memoizedState,s=s===null?null:s.dehydrated,!s)throw Error(r(317));s[Oi]=t}else Ea(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;oc(t),s=!1}else va!==null&&(vl(va),va=null),s=!0;if(!s)return t.flags&65536?t:null}return t.flags&128?(t.lanes=n,t):(i=i!==null,i!==(e!==null&&e.memoizedState!==null)&&i&&(t.child.flags|=8192,t.mode&1&&(e===null||po.current&1?Kc===0&&(Kc=3):Ol())),t.updateQueue!==null&&(t.flags|=4),oc(t),null);case 4:return lo(),e===null&&ai(t.stateNode.containerInfo),oc(t),null;case 10:return Ba(t.type._context),oc(t),null;case 17:return Ki(t.type)&&qi(),oc(t),null;case 19:if(J(po),s=t.memoizedState,s===null)return oc(t),null;if(i=(t.flags&128)!=0,c=s.rendering,c===null)if(i)ac(s,!1);else{if(Kc!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(c=mo(e),c!==null){for(t.flags|=128,ac(s,!1),i=c.updateQueue,i!==null&&(t.updateQueue=i,t.flags|=4),t.subtreeFlags=0,i=n,n=t.child;n!==null;)s=n,e=i,s.flags&=14680066,c=s.alternate,c===null?(s.childLanes=0,s.lanes=e,s.child=null,s.subtreeFlags=0,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=c.childLanes,s.lanes=c.lanes,s.child=c.child,s.subtreeFlags=0,s.deletions=null,s.memoizedProps=c.memoizedProps,s.memoizedState=c.memoizedState,s.updateQueue=c.updateQueue,s.type=c.type,e=c.dependencies,s.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return Y(po,po.current&1|2),t.child}e=e.sibling}s.tail!==null&&I()>el&&(t.flags|=128,i=!0,ac(s,!1),t.lanes=4194304)}else{if(!i)if(e=mo(c),e!==null){if(t.flags|=128,i=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),ac(s,!0),s.tail===null&&s.tailMode===`hidden`&&!c.alternate&&!Z)return oc(t),null}else 2*I()-s.renderingStartTime>el&&n!==1073741824&&(t.flags|=128,i=!0,ac(s,!1),t.lanes=4194304);s.isBackwards?(c.sibling=t.child,t.child=c):(n=s.last,n===null?t.child=c:n.sibling=c,s.last=c)}return s.tail===null?(oc(t),null):(t=s.tail,s.rendering=t,s.tail=t.sibling,s.renderingStartTime=I(),t.sibling=null,n=po.current,Y(po,i?n&1|2:n&1),t);case 22:case 23:return wl(),i=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==i&&(t.flags|=8192),i&&t.mode&1?Wc&1073741824&&(oc(t),t.subtreeFlags&6&&(t.flags|=8192)):oc(t),null;case 24:return null;case 25:return null}throw Error(r(156,t.tag))}function cc(e,t){switch(ha(t),t.tag){case 1:return Ki(t.type)&&qi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return lo(),J(Ui),J(Hi),go(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return fo(t),null;case 13:if(J(po),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(r(340));Ea()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return J(po),null;case 4:return lo(),null;case 10:return Ba(t.type._context),null;case 22:case 23:return wl(),null;case 24:return null;default:return null}}var lc=!1,uc=!1,dc=typeof WeakSet==`function`?WeakSet:Set,Q=null;function fc(e,t){var n=e.ref;if(n!==null)if(typeof n==`function`)try{n(null)}catch(n){Rl(e,t,n)}else n.current=null}function pc(e,t,n){try{n()}catch(n){Rl(e,t,n)}}var mc=!1;function hc(e,t){if(gi=gn,e=jr(),Mr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var i=n.getSelection&&n.getSelection();if(i&&i.rangeCount!==0){n=i.anchorNode;var a=i.anchorOffset,o=i.focusNode;i=i.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||i!==0&&f.nodeType!==3||(l=s+i),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===i&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(_i={focusedElem:e,selectionRange:n},gn=!1,Q=t;Q!==null;)if(t=Q,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,Q=e;else for(;Q!==null;){t=Q;try{var h=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(h!==null){var g=h.memoizedProps,_=h.memoizedState,v=t.stateNode;v.__reactInternalSnapshotBeforeUpdate=v.getSnapshotBeforeUpdate(t.elementType===t.type?g:hs(t.type,g),_)}break;case 3:var y=t.stateNode.containerInfo;y.nodeType===1?y.textContent=``:y.nodeType===9&&y.documentElement&&y.removeChild(y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(r(163))}}catch(e){Rl(t,t.return,e)}if(e=t.sibling,e!==null){e.return=t.return,Q=e;break}Q=t.return}return h=mc,mc=!1,h}function gc(e,t,n){var r=t.updateQueue;if(r=r===null?null:r.lastEffect,r!==null){var i=r=r.next;do{if((i.tag&e)===e){var a=i.destroy;i.destroy=void 0,a!==void 0&&pc(t,n,a)}i=i.next}while(i!==r)}}function _c(e,t){if(t=t.updateQueue,t=t===null?null:t.lastEffect,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function vc(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t==`function`?t(e):t.current=e}}function yc(e){var t=e.alternate;t!==null&&(e.alternate=null,yc(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Oi],delete t[ki],delete t[ji],delete t[Mi],delete t[Ni])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function bc(e){return e.tag===5||e.tag===3||e.tag===4}function xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||bc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Sc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=hi));else if(r!==4&&(e=e.child,e!==null))for(Sc(e,t,n),e=e.sibling;e!==null;)Sc(e,t,n),e=e.sibling}function Cc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(Cc(e,t,n),e=e.sibling;e!==null;)Cc(e,t,n),e=e.sibling}var wc=null,Tc=!1;function Ec(e,t,n){for(n=n.child;n!==null;)Dc(e,t,n),n=n.sibling}function Dc(e,t,n){if(Dt&&typeof Dt.onCommitFiberUnmount==`function`)try{Dt.onCommitFiberUnmount(Et,n)}catch{}switch(n.tag){case 5:uc||fc(n,t);case 6:var r=wc,i=Tc;wc=null,Ec(e,t,n),wc=r,Tc=i,wc!==null&&(Tc?(e=wc,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):wc.removeChild(n.stateNode));break;case 18:wc!==null&&(Tc?(e=wc,n=n.stateNode,e.nodeType===8?wi(e.parentNode,n):e.nodeType===1&&wi(e,n),mn(e)):wi(wc,n.stateNode));break;case 4:r=wc,i=Tc,wc=n.stateNode.containerInfo,Tc=!0,Ec(e,t,n),wc=r,Tc=i;break;case 0:case 11:case 14:case 15:if(!uc&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){i=r=r.next;do{var a=i,o=a.destroy;a=a.tag,o!==void 0&&(a&2||a&4)&&pc(n,t,o),i=i.next}while(i!==r)}Ec(e,t,n);break;case 1:if(!uc&&(fc(n,t),r=n.stateNode,typeof r.componentWillUnmount==`function`))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(e){Rl(n,t,e)}Ec(e,t,n);break;case 21:Ec(e,t,n);break;case 22:n.mode&1?(uc=(r=uc)||n.memoizedState!==null,Ec(e,t,n),uc=r):Ec(e,t,n);break;default:Ec(e,t,n)}}function Oc(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new dc),t.forEach(function(t){var r=Hl.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))})}}function kc(e,t){var n=t.deletions;if(n!==null)for(var i=0;ia&&(a=s),i&=~o}if(i=a,i=I()-i,i=(120>i?120:480>i?480:1080>i?1080:1920>i?1920:3e3>i?3e3:4320>i?4320:1960*Lc(i/1960))-i,10e?16:e,ol===null)var i=!1;else{if(e=ol,ol=null,sl=0,$&6)throw Error(r(331));var a=$;for($|=4,Q=e.current;Q!==null;){var o=Q,s=o.child;if(Q.flags&16){var c=o.deletions;if(c!==null){for(var l=0;lI()-$c?Tl(e,0):Xc|=n),hl(e,t)}function Bl(e,t){t===0&&(e.mode&1?(t=Pt,Pt<<=1,!(Pt&130023424)&&(Pt=4194304)):t=1);var n=fl();e=qa(e,t),e!==null&&(L(e,t,n),hl(e,n))}function Vl(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Bl(e,n)}function Hl(e,t){var n=0;switch(e.tag){case 13:var i=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:i=e.stateNode;break;default:throw Error(r(314))}i!==null&&i.delete(t),Bl(e,n)}var Ul=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||Ui.current)Ms=!0;else{if((e.lanes&n)===0&&!(t.flags&128))return Ms=!1,tc(e,t,n);Ms=!!(e.flags&131072)}else Ms=!1,Z&&t.flags&1048576&&pa(t,oa,t.index);switch(t.lanes=0,t.tag){case 2:var i=t.type;$s(e,t),e=t.pendingProps;var a=Gi(t,Hi.current);Ha(t,n),a=ko(null,t,i,e,a,n);var o=Ao();return t.flags|=1,typeof a==`object`&&a&&typeof a.render==`function`&&a.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Ki(i)?(o=!0,Xi(t)):o=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,Ya(t),a.updater=_s,t.stateNode=a,a._reactInternals=t,xs(t,i,e,n),t=Vs(null,t,i,!0,o,n)):(t.tag=0,Z&&o&&ma(t),Ns(null,t,a,n),t=t.child),t;case 16:i=t.elementType;a:{switch($s(e,t),e=t.pendingProps,a=i._init,i=a(i._payload),t.type=i,a=t.tag=Jl(i),e=hs(i,e),a){case 0:t=zs(null,t,i,e,n);break a;case 1:t=Bs(null,t,i,e,n);break a;case 11:t=Ps(null,t,i,e,n);break a;case 14:t=Fs(null,t,i,hs(i.type,e),n);break a}throw Error(r(306,i,``))}return t;case 0:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:hs(i,a),zs(e,t,i,a,n);case 1:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:hs(i,a),Bs(e,t,i,a,n);case 3:a:{if(Hs(t),e===null)throw Error(r(387));i=t.pendingProps,o=t.memoizedState,a=o.element,Xa(e,t),to(t,i,null,n);var s=t.memoizedState;if(i=s.element,o.isDehydrated)if(o={element:i,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){a=Ss(Error(r(423)),t),t=Us(e,t,i,n,a);break a}else if(i!==a){a=Ss(Error(r(424)),t),t=Us(e,t,i,n,a);break a}else for(_a=Ti(t.stateNode.containerInfo.firstChild),ga=t,Z=!0,va=null,n=Pa(t,null,i,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Ea(),i===a){t=ec(e,t,n);break a}Ns(e,t,i,n)}t=t.child}return t;case 5:return uo(t),e===null&&Sa(t),i=t.type,a=t.pendingProps,o=e===null?null:e.memoizedProps,s=a.children,vi(i,a)?s=null:o!==null&&vi(i,o)&&(t.flags|=32),Rs(e,t),Ns(e,t,s,n),t.child;case 6:return e===null&&Sa(t),null;case 13:return Ks(e,t,n);case 4:return co(t,t.stateNode.containerInfo),i=t.pendingProps,e===null?t.child=Na(t,null,i,n):Ns(e,t,i,n),t.child;case 11:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:hs(i,a),Ps(e,t,i,a,n);case 7:return Ns(e,t,t.pendingProps,n),t.child;case 8:return Ns(e,t,t.pendingProps.children,n),t.child;case 12:return Ns(e,t,t.pendingProps.children,n),t.child;case 10:a:{if(i=t.type._context,a=t.pendingProps,o=t.memoizedProps,s=a.value,Y(Fa,i._currentValue),i._currentValue=s,o!==null)if(Dr(o.value,s)){if(o.children===a.children&&!Ui.current){t=ec(e,t,n);break a}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var c=o.dependencies;if(c!==null){s=o.child;for(var l=c.firstContext;l!==null;){if(l.context===i){if(o.tag===1){l=Za(-1,n&-n),l.tag=2;var u=o.updateQueue;if(u!==null){u=u.shared;var d=u.pending;d===null?l.next=l:(l.next=d.next,d.next=l),u.pending=l}}o.lanes|=n,l=o.alternate,l!==null&&(l.lanes|=n),Va(o.return,n,t),c.lanes|=n;break}l=l.next}}else if(o.tag===10)s=o.type===t.type?null:o.child;else if(o.tag===18){if(s=o.return,s===null)throw Error(r(341));s.lanes|=n,c=s.alternate,c!==null&&(c.lanes|=n),Va(s,n,t),s=o.sibling}else s=o.child;if(s!==null)s.return=o;else for(s=o;s!==null;){if(s===t){s=null;break}if(o=s.sibling,o!==null){o.return=s.return,s=o;break}s=s.return}o=s}Ns(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,i=t.pendingProps.children,Ha(t,n),a=Ua(a),i=i(a),t.flags|=1,Ns(e,t,i,n),t.child;case 14:return i=t.type,a=hs(i,t.pendingProps),a=hs(i.type,a),Fs(e,t,i,a,n);case 15:return Is(e,t,t.type,t.pendingProps,n);case 17:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:hs(i,a),$s(e,t),t.tag=1,Ki(i)?(e=!0,Xi(t)):e=!1,Ha(t,n),ys(t,i,a),xs(t,i,a,n),Vs(null,t,i,!0,e,n);case 19:return Qs(e,t,n);case 22:return Ls(e,t,n)}throw Error(r(156,t.tag))};function Wl(e,t){return gt(e,t)}function Gl(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Kl(e,t,n,r){return new Gl(e,t,n,r)}function ql(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Jl(e){if(typeof e==`function`)return+!!ql(e);if(e!=null){if(e=e.$$typeof,e===re)return 11;if(e===O)return 14}return 2}function Yl(e,t){var n=e.alternate;return n===null?(n=Kl(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Xl(e,t,n,i,a,o){var s=2;if(i=e,typeof e==`function`)ql(e)&&(s=1);else if(typeof e==`string`)s=5;else a:switch(e){case E:return Zl(n.children,a,o,t);case D:s=8,a|=8;break;case ee:return e=Kl(12,n,t,a|2),e.elementType=ee,e.lanes=o,e;case ie:return e=Kl(13,n,t,a),e.elementType=ie,e.lanes=o,e;case ae:return e=Kl(19,n,t,a),e.elementType=ae,e.lanes=o,e;case oe:return Ql(n,a,o,t);default:if(typeof e==`object`&&e)switch(e.$$typeof){case te:s=10;break a;case ne:s=9;break a;case re:s=11;break a;case O:s=14;break a;case k:s=16,i=null;break a}throw Error(r(130,e==null?e:typeof e,``))}return t=Kl(s,n,t,a),t.elementType=e,t.type=i,t.lanes=o,t}function Zl(e,t,n,r){return e=Kl(7,e,r,t),e.lanes=n,e}function Ql(e,t,n,r){return e=Kl(22,e,r,t),e.elementType=oe,e.lanes=n,e.stateNode={isHidden:!1},e}function $l(e,t,n){return e=Kl(6,e,null,t),e.lanes=n,e}function eu(e,t,n){return t=Kl(4,e.children===null?[]:e.children,e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function tu(e,t,n,r,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Vt(0),this.expirationTimes=Vt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Vt(0),this.identifierPrefix=r,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function nu(e,t,n,r,i,a,o,s,c){return e=new tu(e,t,n,s,c),t===1?(t=1,!0===a&&(t|=8)):t=0,a=Kl(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Ya(a),e}function ru(e,t,n){var r=3{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=m()})),g=o((e=>{var t=h();e.createRoot=t.createRoot,e.hydrateRoot=t.hydrateRoot})),_=l(d()),v=l(g());h();function y(){return y=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf(`?`);r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function ne(e,t,n,r){r===void 0&&(r={});let{window:i=document.defaultView,v5Compat:a=!1}=r,o=i.history,s=b.Pop,c=null,l=u();l??(l=0,o.replaceState(y({},o.state,{idx:l}),``));function u(){return(o.state||{idx:null}).idx}function d(){s=b.Pop;let e=u(),t=e==null?null:e-l;l=e,c&&c({action:s,location:h.location,delta:t})}function f(e,t){s=b.Push;let r=D(h.location,e,t);n&&n(r,e),l=u()+1;let d=E(r,l),f=h.createHref(r);try{o.pushState(d,``,f)}catch(e){if(e instanceof DOMException&&e.name===`DataCloneError`)throw e;i.location.assign(f)}a&&c&&c({action:s,location:h.location,delta:1})}function p(e,t){s=b.Replace;let r=D(h.location,e,t);n&&n(r,e),l=u();let i=E(r,l),d=h.createHref(r);o.replaceState(i,``,d),a&&c&&c({action:s,location:h.location,delta:0})}function m(e){let t=i.location.origin===`null`?i.location.href:i.location.origin,n=typeof e==`string`?e:ee(e);return n=n.replace(/ $/,`%20`),C(t,`No window.location.(origin|href) available to create URL for href: `+n),new URL(n,t)}let h={get action(){return s},get location(){return e(i,o)},listen(e){if(c)throw Error(`A history only accepts one active listener`);return i.addEventListener(x,d),c=e,()=>{i.removeEventListener(x,d),c=null}},createHref(e){return t(i,e)},createURL:m,encodeLocation(e){let t=m(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:f,replace:p,go(e){return o.go(e)}};return h}var re;(function(e){e.data=`data`,e.deferred=`deferred`,e.redirect=`redirect`,e.error=`error`})(re||={});function ie(e,t,n){return n===void 0&&(n=`/`),ae(e,t,n,!1)}function ae(e,t,n,r){let i=ve((typeof t==`string`?te(t):t).pathname||`/`,n);if(i==null)return null;let a=O(e);oe(a);let o=null;for(let e=0;o==null&&e{let o={relativePath:a===void 0?e.path||``:a,caseSensitive:e.caseSensitive===!0,childrenIndex:i,route:e};o.relativePath.startsWith(`/`)&&(C(o.relativePath.startsWith(r),`Absolute route path "`+o.relativePath+`" nested under path `+(`"`+r+`" is not valid. An absolute child route path `)+`must start with the combined path of all its parent routes.`),o.relativePath=o.relativePath.slice(r.length));let s=N([r,o.relativePath]),c=n.concat(o);e.children&&e.children.length>0&&(C(e.index!==!0,`Index routes must not have child routes. Please remove `+(`all child routes from route path "`+s+`".`)),O(e.children,t,c,s)),!(e.path==null&&!e.index)&&t.push({path:s,score:pe(s,e.index),routesMeta:c})};return e.forEach((e,t)=>{var n;if(e.path===``||!((n=e.path)!=null&&n.includes(`?`)))i(e,t);else for(let n of k(e.path))i(e,t,n)}),t}function k(e){let t=e.split(`/`);if(t.length===0)return[];let[n,...r]=t,i=n.endsWith(`?`),a=n.replace(/\?$/,``);if(r.length===0)return i?[a,``]:[a];let o=k(r.join(`/`)),s=[];return s.push(...o.map(e=>e===``?a:[a,e].join(`/`))),i&&s.push(...o),s.map(t=>e.startsWith(`/`)&&t===``?`/`:t)}function oe(e){e.sort((e,t)=>e.score===t.score?me(e.routesMeta.map(e=>e.childrenIndex),t.routesMeta.map(e=>e.childrenIndex)):t.score-e.score)}var se=/^:[\w-]+$/,ce=3,A=2,le=1,ue=10,de=-2,fe=e=>e===`*`;function pe(e,t){let n=e.split(`/`),r=n.length;return n.some(fe)&&(r+=de),t&&(r+=A),n.filter(e=>!fe(e)).reduce((e,t)=>e+(se.test(t)?ce:t===``?le:ue),r)}function me(e,t){return e.length===t.length&&e.slice(0,-1).every((e,n)=>e===t[n])?e[e.length-1]-t[t.length-1]:0}function he(e,t,n){n===void 0&&(n=!1);let{routesMeta:r}=e,i={},a=`/`,o=[];for(let e=0;e{let{paramName:r,isOptional:i}=t;if(r===`*`){let e=s[n]||``;o=a.slice(0,a.length-e.length).replace(/(.)\/+$/,`$1`)}let c=s[n];return i&&!c?e[r]=void 0:e[r]=(c||``).replace(/%2F/g,`/`),e},{}),pathname:a,pathnameBase:o,pattern:e}}function ge(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),w(e===`*`||!e.endsWith(`*`)||e.endsWith(`/*`),`Route path "`+e+`" will be treated as if it were `+(`"`+e.replace(/\*$/,`/*`)+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+(`please change the route path to "`+e.replace(/\*$/,`/*`)+`".`));let r=[],i=`^`+e.replace(/\/*\*?$/,``).replace(/^\/*/,`/`).replace(/[\\.*+^${}|()[\]]/g,`\\$&`).replace(/\/:([\w-]+)(\?)?/g,(e,t,n)=>(r.push({paramName:t,isOptional:n!=null}),n?`/?([^\\/]+)?`:`/([^\\/]+)`));return e.endsWith(`*`)?(r.push({paramName:`*`}),i+=e===`*`||e===`/*`?`(.*)$`:`(?:\\/(.+)|\\/*)$`):n?i+=`\\/*$`:e!==``&&e!==`/`&&(i+=`(?:(?=\\/|$))`),[new RegExp(i,t?void 0:`i`),r]}function _e(e){try{return e.split(`/`).map(e=>decodeURIComponent(e).replace(/\//g,`%2F`)).join(`/`)}catch(t){return w(!1,`The URL path "`+e+`" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent `+(`encoding (`+t+`).`)),e}}function ve(e,t){if(t===`/`)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith(`/`)?t.length-1:t.length,r=e.charAt(n);return r&&r!==`/`?null:e.slice(n)||`/`}var ye=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,be=e=>ye.test(e);function xe(e,t){t===void 0&&(t=`/`);let{pathname:n,search:r=``,hash:i=``}=typeof e==`string`?te(e):e,a;if(n)if(be(n))a=n;else{if(n.includes(`//`)){let e=n;n=n.replace(/\/\/+/g,`/`),w(!1,`Pathnames cannot have embedded double slashes - normalizing `+(e+` -> `+n))}a=n.startsWith(`/`)?M(n.substring(1),`/`):M(n,t)}else a=t;return{pathname:a,search:De(r),hash:Oe(i)}}function M(e,t){let n=t.replace(/\/+$/,``).split(`/`);return e.split(`/`).forEach(e=>{e===`..`?n.length>1&&n.pop():e!==`.`&&n.push(e)}),n.length>1?n.join(`/`):`/`}function Se(e,t,n,r){return`Cannot include a '`+e+`' character in a manually specified `+("`to."+t+"` field ["+JSON.stringify(r)+`]. Please separate it out to the `)+("`to."+n+"` field. Alternatively you may provide the full path as ")+`a string in and the router will parse it for you.`}function Ce(e){return e.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function we(e,t){let n=Ce(e);return t?n.map((e,t)=>t===n.length-1?e.pathname:e.pathnameBase):n.map(e=>e.pathnameBase)}function Te(e,t,n,r){r===void 0&&(r=!1);let i;typeof e==`string`?i=te(e):(i=y({},e),C(!i.pathname||!i.pathname.includes(`?`),Se(`?`,`pathname`,`search`,i)),C(!i.pathname||!i.pathname.includes(`#`),Se(`#`,`pathname`,`hash`,i)),C(!i.search||!i.search.includes(`#`),Se(`#`,`search`,`hash`,i)));let a=e===``||i.pathname===``,o=a?`/`:i.pathname,s;if(o==null)s=n;else{let e=t.length-1;if(!r&&o.startsWith(`..`)){let t=o.split(`/`);for(;t[0]===`..`;)t.shift(),--e;i.pathname=t.join(`/`)}s=e>=0?t[e]:`/`}let c=xe(i,s),l=o&&o!==`/`&&o.endsWith(`/`),u=(a||o===`.`)&&n.endsWith(`/`);return!c.pathname.endsWith(`/`)&&(l||u)&&(c.pathname+=`/`),c}var N=e=>e.join(`/`).replace(/\/\/+/g,`/`),Ee=e=>e.replace(/\/+$/,``).replace(/^\/*/,`/`),De=e=>!e||e===`?`?``:e.startsWith(`?`)?e:`?`+e,Oe=e=>!e||e===`#`?``:e.startsWith(`#`)?e:`#`+e;function ke(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.internal==`boolean`&&`data`in e}var Ae=[`post`,`put`,`patch`,`delete`];new Set(Ae);var je=[`get`,...Ae];new Set(je);function Me(){return Me=Object.assign?Object.assign.bind():function(e){for(var t=1;t{s.current=!0}),_.useCallback(function(n,i){if(i===void 0&&(i={}),!s.current)return;if(typeof n==`number`){r.go(n);return}let c=Te(n,JSON.parse(o),a,i.relative===`path`);e==null&&t!==`/`&&(c.pathname=c.pathname===`/`?t:N([t,c.pathname])),(i.replace?r.replace:r.push)(c,i.state,i)},[t,r,o,a,e])}function We(e,t){return Ge(e,t)}function Ge(e,t,n,r){!ze()&&C(!1);let{navigator:i}=_.useContext(Fe),{matches:a}=_.useContext(Le),o=a[a.length-1],s=o?o.params:{};o&&o.pathname;let c=o?o.pathnameBase:`/`;o&&o.route;let l=Be(),u;if(t){let e=typeof t==`string`?te(t):t;!(c===`/`||e.pathname?.startsWith(c))&&C(!1),u=e}else u=l;let d=u.pathname||`/`,f=d;if(c!==`/`){let e=c.replace(/^\//,``).split(`/`);f=`/`+d.replace(/^\//,``).split(`/`).slice(e.length).join(`/`)}let p=ie(e,{pathname:f}),m=Xe(p&&p.map(e=>Object.assign({},e,{params:Object.assign({},s,e.params),pathname:N([c,i.encodeLocation?i.encodeLocation(e.pathname).pathname:e.pathname]),pathnameBase:e.pathnameBase===`/`?c:N([c,i.encodeLocation?i.encodeLocation(e.pathnameBase).pathname:e.pathnameBase])})),a,n,r);return t&&m?_.createElement(Ie.Provider,{value:{location:Me({pathname:`/`,search:``,hash:``,state:null,key:`default`},u),navigationType:b.Pop}},m):m}function Ke(){let e=rt(),t=ke(e)?e.status+` `+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null;return _.createElement(_.Fragment,null,_.createElement(`h2`,null,`Unexpected Application Error!`),_.createElement(`h3`,{style:{fontStyle:`italic`}},t),n?_.createElement(`pre`,{style:{padding:`0.5rem`,backgroundColor:`rgba(200,200,200, 0.5)`}},n):null,null)}var qe=_.createElement(Ke,null),Je=class extends _.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!==`idle`&&e.revalidation===`idle`?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error===void 0?t.error:e.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){console.error(`React Router caught the following error during render`,e,t)}render(){return this.state.error===void 0?this.props.children:_.createElement(Le.Provider,{value:this.props.routeContext},_.createElement(Re.Provider,{value:this.state.error,children:this.props.component}))}};function Ye(e){let{routeContext:t,match:n,children:r}=e,i=_.useContext(Ne);return i&&i.static&&i.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=n.route.id),_.createElement(Le.Provider,{value:t},r)}function Xe(e,t,n,r){if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var i;if(!n)return null;if(n.errors)e=n.matches;else if((i=r)!=null&&i.v7_partialHydration&&t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let a=e,o=n?.errors;if(o!=null){let e=a.findIndex(e=>e.route.id&&o?.[e.route.id]!==void 0);!(e>=0)&&C(!1),a=a.slice(0,Math.min(a.length,e+1))}let s=!1,c=-1;if(n&&r&&r.v7_partialHydration)for(let e=0;e=0?a.slice(0,c+1):[a[0]];break}}}return a.reduceRight((e,r,i)=>{let l,u=!1,d=null,f=null;n&&(l=o&&r.route.id?o[r.route.id]:void 0,d=r.route.errorElement||qe,s&&(c<0&&i===0?(at(`route-fallback`,!1,"No `HydrateFallback` element provided to render during initial hydration"),u=!0,f=null):c===i&&(u=!0,f=r.route.hydrateFallbackElement||null)));let p=t.concat(a.slice(0,i+1)),m=()=>{let t;return t=l?d:u?f:r.route.Component?_.createElement(r.route.Component,null):r.route.element?r.route.element:e,_.createElement(Ye,{match:r,routeContext:{outlet:e,matches:p,isDataRoute:n!=null},children:t})};return n&&(r.route.ErrorBoundary||r.route.errorElement||i===0)?_.createElement(Je,{location:n.location,revalidation:n.revalidation,component:d,error:l,children:m(),routeContext:{outlet:null,matches:p,isDataRoute:!0}}):m()},null)}var Ze=function(e){return e.UseBlocker=`useBlocker`,e.UseRevalidator=`useRevalidator`,e.UseNavigateStable=`useNavigate`,e}(Ze||{}),Qe=function(e){return e.UseBlocker=`useBlocker`,e.UseLoaderData=`useLoaderData`,e.UseActionData=`useActionData`,e.UseRouteError=`useRouteError`,e.UseNavigation=`useNavigation`,e.UseRouteLoaderData=`useRouteLoaderData`,e.UseMatches=`useMatches`,e.UseRevalidator=`useRevalidator`,e.UseNavigateStable=`useNavigate`,e.UseRouteId=`useRouteId`,e}(Qe||{});function $e(e){let t=_.useContext(Ne);return!t&&C(!1),t}function et(e){let t=_.useContext(Pe);return!t&&C(!1),t}function tt(e){let t=_.useContext(Le);return!t&&C(!1),t}function nt(e){let t=tt(e),n=t.matches[t.matches.length-1];return!n.route.id&&C(!1),n.route.id}function rt(){let e=_.useContext(Re),t=et(Qe.UseRouteError),n=nt(Qe.UseRouteError);return e===void 0?t.errors?.[n]:e}function P(){let{router:e}=$e(Ze.UseNavigateStable),t=nt(Qe.UseNavigateStable),n=_.useRef(!1);return Ve(()=>{n.current=!0}),_.useCallback(function(r,i){i===void 0&&(i={}),n.current&&(typeof r==`number`?e.navigate(r):e.navigate(r,Me({fromRouteId:t},i)))},[e,t])}var it={};function at(e,t,n){!t&&!it[e]&&(it[e]=!0)}var ot=(e,t,n)=>(``+t+("You can use the `"+e+"` future flag to opt-in early. ")+(`For more information, see `+n+`.`),void 0);function st(e,t){e?.v7_startTransition===void 0&&ot(`v7_startTransition`,"React Router will begin wrapping state updates in `React.startTransition` in v7",`https://reactrouter.com/v6/upgrading/future#v7_starttransition`),e?.v7_relativeSplatPath===void 0&&(!t||t.v7_relativeSplatPath===void 0)&&ot(`v7_relativeSplatPath`,`Relative route resolution within Splat routes is changing in v7`,`https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath`),t&&(t.v7_fetcherPersist===void 0&&ot(`v7_fetcherPersist`,`The persistence behavior of fetchers is changing in v7`,`https://reactrouter.com/v6/upgrading/future#v7_fetcherpersist`),t.v7_normalizeFormMethod===void 0&&ot(`v7_normalizeFormMethod`,"Casing of `formMethod` fields is being normalized to uppercase in v7",`https://reactrouter.com/v6/upgrading/future#v7_normalizeformmethod`),t.v7_partialHydration===void 0&&ot(`v7_partialHydration`,"`RouterProvider` hydration behavior is changing in v7",`https://reactrouter.com/v6/upgrading/future#v7_partialhydration`),t.v7_skipActionErrorRevalidation===void 0&&ot(`v7_skipActionErrorRevalidation`,"The revalidation behavior after 4xx/5xx `action` responses is changing in v7",`https://reactrouter.com/v6/upgrading/future#v7_skipactionerrorrevalidation`))}function ct(e){C(!1)}function lt(e){let{basename:t=`/`,children:n=null,location:r,navigationType:i=b.Pop,navigator:a,static:o=!1,future:s}=e;ze()&&C(!1);let c=t.replace(/^\/*/,`/`),l=_.useMemo(()=>({basename:c,navigator:a,static:o,future:Me({v7_relativeSplatPath:!1},s)}),[c,s,a,o]);typeof r==`string`&&(r=te(r));let{pathname:u=`/`,search:d=``,hash:f=``,state:p=null,key:m=`default`}=r,h=_.useMemo(()=>{let e=ve(u,c);return e==null?null:{location:{pathname:e,search:d,hash:f,state:p,key:m},navigationType:i}},[c,u,d,f,p,m,i]);return h==null?null:_.createElement(Fe.Provider,{value:l},_.createElement(Ie.Provider,{children:n,value:h}))}function ut(e){let{children:t,location:n}=e;return We(ft(t),n)}var dt=function(e){return e[e.pending=0]=`pending`,e[e.success=1]=`success`,e[e.error=2]=`error`,e}(dt||{});new Promise(()=>{}),_.Component;function ft(e,t){t===void 0&&(t=[]);let n=[];return _.Children.forEach(e,(e,r)=>{if(!_.isValidElement(e))return;let i=[...t,r];if(e.type===_.Fragment){n.push.apply(n,ft(e.props.children,i));return}e.type!==ct&&C(!1),!(!e.props.index||!e.props.children)&&C(!1);let a={id:e.props.id||i.join(`-`),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,loader:e.props.loader,action:e.props.action,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:e.props.ErrorBoundary!=null||e.props.errorElement!=null,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(a.children=ft(e.props.children,i)),n.push(a)}),n}var pt=`6`;try{window.__reactRouterVersion=pt}catch{}var F=_.startTransition;function mt(e){let{basename:t,children:n,future:r,window:i}=e,a=_.useRef();a.current??=S({window:i,v5Compat:!0});let o=a.current,[s,c]=_.useState({action:o.action,location:o.location}),{v7_startTransition:l}=r||{},u=_.useCallback(e=>{l&&F?F(()=>c(e)):c(e)},[c,l]);return _.useLayoutEffect(()=>o.listen(u),[o,u]),_.useEffect(()=>st(r),[r]),_.createElement(lt,{basename:t,children:n,location:s.location,navigationType:s.action,navigator:o,future:r})}typeof window<`u`&&window.document!==void 0&&window.document.createElement;var ht;(function(e){e.UseScrollRestoration=`useScrollRestoration`,e.UseSubmit=`useSubmit`,e.UseSubmitFetcher=`useSubmitFetcher`,e.UseFetcher=`useFetcher`,e.useViewTransitionState=`useViewTransitionState`})(ht||={});var gt;(function(e){e.UseFetcher=`useFetcher`,e.UseFetchers=`useFetchers`,e.UseScrollRestoration=`useScrollRestoration`})(gt||={});var _t=Object.create(null);_t.open=`0`,_t.close=`1`,_t.ping=`2`,_t.pong=`3`,_t.message=`4`,_t.upgrade=`5`,_t.noop=`6`;var vt=Object.create(null);Object.keys(_t).forEach(e=>{vt[_t[e]]=e});var yt={type:`error`,data:`parser error`},I=typeof Blob==`function`||typeof Blob<`u`&&Object.prototype.toString.call(Blob)===`[object BlobConstructor]`,bt=typeof ArrayBuffer==`function`,xt=e=>typeof ArrayBuffer.isView==`function`?ArrayBuffer.isView(e):e&&e.buffer instanceof ArrayBuffer,St=({type:e,data:t},n,r)=>I&&t instanceof Blob?n?r(t):Ct(t,r):bt&&(t instanceof ArrayBuffer||xt(t))?n?r(t):Ct(new Blob([t]),r):r(_t[e]+(t||``)),Ct=(e,t)=>{let n=new FileReader;return n.onload=function(){let e=n.result.split(`,`)[1];t(`b`+(e||``))},n.readAsDataURL(e)};function wt(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}var Tt;function Et(e,t){if(I&&e.data instanceof Blob)return e.data.arrayBuffer().then(wt).then(t);if(bt&&(e.data instanceof ArrayBuffer||xt(e.data)))return t(wt(e.data));St(e,!1,e=>{Tt||=new TextEncoder,t(Tt.encode(e))})}var Dt=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`,Ot=typeof Uint8Array>`u`?[]:new Uint8Array(256);for(let e=0;e<64;e++)Ot[Dt.charCodeAt(e)]=e;var kt=e=>{let t=e.length*.75,n=e.length,r,i=0,a,o,s,c;e[e.length-1]===`=`&&(t--,e[e.length-2]===`=`&&t--);let l=new ArrayBuffer(t),u=new Uint8Array(l);for(r=0;r>4,u[i++]=(o&15)<<4|s>>2,u[i++]=(s&3)<<6|c&63;return l},At=typeof ArrayBuffer==`function`,jt=(e,t)=>{if(typeof e!=`string`)return{type:`message`,data:Nt(e,t)};let n=e.charAt(0);return n===`b`?{type:`message`,data:Mt(e.substring(1),t)}:vt[n]?e.length>1?{type:vt[n],data:e.substring(1)}:{type:vt[n]}:yt},Mt=(e,t)=>At?Nt(kt(e),t):{base64:!0,data:e},Nt=(e,t)=>{switch(t){case`blob`:return e instanceof Blob?e:new Blob([e]);default:return e instanceof ArrayBuffer?e:e.buffer}},Pt=``,Ft=(e,t)=>{let n=e.length,r=Array(n),i=0;e.forEach((e,a)=>{St(e,!1,e=>{r[a]=e,++i===n&&t(r.join(Pt))})})},It=(e,t)=>{let n=e.split(Pt),r=[];for(let e=0;e{let r=n.length,i;if(r<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,r);else if(r<65536){i=new Uint8Array(3);let e=new DataView(i.buffer);e.setUint8(0,126),e.setUint16(1,r)}else{i=new Uint8Array(9);let e=new DataView(i.buffer);e.setUint8(0,127),e.setBigUint64(1,BigInt(r))}e.data&&typeof e.data!=`string`&&(i[0]|=128),t.enqueue(i),t.enqueue(n)})}})}var Rt;function zt(e){return e.reduce((e,t)=>e+t.length,0)}function Bt(e,t){if(e[0].length===t)return e.shift();let n=new Uint8Array(t),r=0;for(let i=0;i2**21-1){s.enqueue(yt);break}i=a*2**32+t.getUint32(4),r=3}else{if(zt(n)e){s.enqueue(yt);break}}}})}function L(e){if(e)return Ht(e)}function Ht(e){for(var t in L.prototype)e[t]=L.prototype[t];return e}L.prototype.on=L.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks[`$`+e]=this._callbacks[`$`+e]||[]).push(t),this},L.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},L.prototype.off=L.prototype.removeListener=L.prototype.removeAllListeners=L.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var n=this._callbacks[`$`+e];if(!n)return this;if(arguments.length==1)return delete this._callbacks[`$`+e],this;for(var r,i=0;iPromise.resolve().then(e):(e,t)=>t(e,0),R=typeof self<`u`?self:typeof window<`u`?window:Function(`return this`)(),Wt=`arraybuffer`;function Gt(e,...t){return t.reduce((t,n)=>(e.hasOwnProperty(n)&&(t[n]=e[n]),t),{})}var Kt=R.setTimeout,qt=R.clearTimeout;function Jt(e,t){t.useNativeTimers?(e.setTimeoutFn=Kt.bind(R),e.clearTimeoutFn=qt.bind(R)):(e.setTimeoutFn=R.setTimeout.bind(R),e.clearTimeoutFn=R.clearTimeout.bind(R))}var Yt=1.33;function Xt(e){return typeof e==`string`?Zt(e):Math.ceil((e.byteLength||e.size)*Yt)}function Zt(e){let t=0,n=0;for(let r=0,i=e.length;r=57344?n+=3:(r++,n+=4);return n}function Qt(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function $t(e){let t=``;for(let n in e)e.hasOwnProperty(n)&&(t.length&&(t+=`&`),t+=encodeURIComponent(n)+`=`+encodeURIComponent(e[n]));return t}function en(e){let t={},n=e.split(`&`);for(let e=0,r=n.length;e{this.readyState=`paused`,e()};if(this._polling||!this.writable){let e=0;this._polling&&(e++,this.once(`pollComplete`,function(){--e||t()})),this.writable||(e++,this.once(`drain`,function(){--e||t()}))}else t()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved(`poll`)}onData(e){It(e,this.socket.binaryType).forEach(e=>{if(this.readyState===`opening`&&e.type===`open`&&this.onOpen(),e.type===`close`)return this.onClose({description:`transport closed by the server`}),!1;this.onPacket(e)}),this.readyState!==`closed`&&(this._polling=!1,this.emitReserved(`pollComplete`),this.readyState===`open`&&this._poll())}doClose(){let e=()=>{this.write([{type:`close`}])};this.readyState===`open`?e():this.once(`open`,e)}write(e){this.writable=!1,Ft(e,e=>{this.doWrite(e,()=>{this.writable=!0,this.emitReserved(`drain`)})})}uri(){let e=this.opts.secure?`https`:`http`,t=this.query||{};return!1!==this.opts.timestampRequests&&(t[this.opts.timestampParam]=Qt()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}},an=!1;try{an=typeof XMLHttpRequest<`u`&&`withCredentials`in new XMLHttpRequest}catch{}var on=an;function sn(){}var cn=class extends rn{constructor(e){if(super(e),typeof location<`u`){let t=location.protocol===`https:`,n=location.port;n||=t?`443`:`80`,this.xd=typeof location<`u`&&e.hostname!==location.hostname||n!==e.port}}doWrite(e,t){let n=this.request({method:`POST`,data:e});n.on(`success`,t),n.on(`error`,(e,t)=>{this.onError(`xhr post error`,e,t)})}doPoll(){let e=this.request();e.on(`data`,this.onData.bind(this)),e.on(`error`,(e,t)=>{this.onError(`xhr poll error`,e,t)}),this.pollXhr=e}},ln=class e extends L{constructor(e,t,n){super(),this.createRequest=e,Jt(this,n),this._opts=n,this._method=n.method||`GET`,this._uri=t,this._data=n.data===void 0?null:n.data,this._create()}_create(){var t;let n=Gt(this._opts,`agent`,`pfx`,`key`,`passphrase`,`cert`,`ca`,`ciphers`,`rejectUnauthorized`,`autoUnref`);n.xdomain=!!this._opts.xd;let r=this._xhr=this.createRequest(n);try{r.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){r.setDisableHeaderCheck&&r.setDisableHeaderCheck(!0);for(let e in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(e)&&r.setRequestHeader(e,this._opts.extraHeaders[e])}}catch{}if(this._method===`POST`)try{r.setRequestHeader(`Content-type`,`text/plain;charset=UTF-8`)}catch{}try{r.setRequestHeader(`Accept`,`*/*`)}catch{}(t=this._opts.cookieJar)==null||t.addCookies(r),`withCredentials`in r&&(r.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(r.timeout=this._opts.requestTimeout),r.onreadystatechange=()=>{var e;r.readyState===3&&((e=this._opts.cookieJar)==null||e.parseCookies(r.getResponseHeader(`set-cookie`))),r.readyState===4&&(r.status===200||r.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof r.status==`number`?r.status:0)},0))},r.send(this._data)}catch(e){this.setTimeoutFn(()=>{this._onError(e)},0);return}typeof document<`u`&&(this._index=e.requestsCount++,e.requests[this._index]=this)}_onError(e){this.emitReserved(`error`,e,this._xhr),this._cleanup(!0)}_cleanup(t){if(!(this._xhr===void 0||this._xhr===null)){if(this._xhr.onreadystatechange=sn,t)try{this._xhr.abort()}catch{}typeof document<`u`&&delete e.requests[this._index],this._xhr=null}}_onLoad(){let e=this._xhr.responseText;e!==null&&(this.emitReserved(`data`,e),this.emitReserved(`success`),this._cleanup())}abort(){this._cleanup()}};if(ln.requestsCount=0,ln.requests={},typeof document<`u`){if(typeof attachEvent==`function`)attachEvent(`onunload`,un);else if(typeof addEventListener==`function`){let e=`onpagehide`in R?`pagehide`:`unload`;addEventListener(e,un,!1)}}function un(){for(let e in ln.requests)ln.requests.hasOwnProperty(e)&&ln.requests[e].abort()}var dn=(function(){let e=pn({xdomain:!1});return e&&e.responseType!==null})(),fn=class extends cn{constructor(e){super(e);let t=e&&e.forceBase64;this.supportsBinary=dn&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new ln(pn,this.uri(),e)}};function pn(e){let t=e.xdomain;try{if(typeof XMLHttpRequest<`u`&&(!t||on))return new XMLHttpRequest}catch{}if(!t)try{return new R[[`Active`,`Object`].join(`X`)](`Microsoft.XMLHTTP`)}catch{}}var mn=typeof navigator<`u`&&typeof navigator.product==`string`&&navigator.product.toLowerCase()===`reactnative`,hn=class extends nn{get name(){return`websocket`}doOpen(){let e=this.uri(),t=this.opts.protocols,n=mn?{}:Gt(this.opts,`agent`,`perMessageDeflate`,`pfx`,`key`,`passphrase`,`cert`,`ca`,`ciphers`,`rejectUnauthorized`,`localAddress`,`protocolVersion`,`origin`,`maxPayload`,`family`,`checkServerIdentity`);this.opts.extraHeaders&&(n.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,t,n)}catch(e){return this.emitReserved(`error`,e)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:`websocket connection closed`,context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError(`websocket error`,e)}write(e){this.writable=!1;for(let t=0;t{try{this.doWrite(n,e)}catch{}r&&Ut(()=>{this.writable=!0,this.emitReserved(`drain`)},this.setTimeoutFn)})}}doClose(){this.ws!==void 0&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){let e=this.opts.secure?`wss`:`ws`,t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=Qt()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}},gn=R.WebSocket||R.MozWebSocket,_n={websocket:class extends hn{createSocket(e,t,n){return mn?new gn(e,t,n):t?new gn(e,t):new gn(e)}doWrite(e,t){this.ws.send(t)}},webtransport:class extends nn{get name(){return`webtransport`}doOpen(){try{this._transport=new WebTransport(this.createUri(`https`),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved(`error`,e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError(`webtransport error`,e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{let t=Vt(2**53-1,this.socket.binaryType),n=e.readable.pipeThrough(t).getReader(),r=Lt();r.readable.pipeTo(e.writable),this._writer=r.writable.getWriter();let i=()=>{n.read().then(({done:e,value:t})=>{e||(this.onPacket(t),i())}).catch(e=>{})};i();let a={type:`open`};this.query.sid&&(a.data=`{"sid":"${this.query.sid}"}`),this._writer.write(a).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let t=0;t{r&&Ut(()=>{this.writable=!0,this.emitReserved(`drain`)},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)==null||e.close()}},polling:fn},vn=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,yn=[`source`,`protocol`,`authority`,`userInfo`,`user`,`password`,`host`,`port`,`relative`,`path`,`directory`,`file`,`query`,`anchor`];function bn(e){if(e.length>8e3)throw`URI too long`;let t=e,n=e.indexOf(`[`),r=e.indexOf(`]`);n!=-1&&r!=-1&&(e=e.substring(0,n)+e.substring(n,r).replace(/:/g,`;`)+e.substring(r,e.length));let i=vn.exec(e||``),a={},o=14;for(;o--;)a[yn[o]]=i[o]||``;return n!=-1&&r!=-1&&(a.source=t,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,`:`),a.authority=a.authority.replace(`[`,``).replace(`]`,``).replace(/;/g,`:`),a.ipv6uri=!0),a.pathNames=xn(a,a.path),a.queryKey=Sn(a,a.query),a}function xn(e,t){let n=t.replace(/\/{2,9}/g,`/`).split(`/`);return(t.slice(0,1)==`/`||t.length===0)&&n.splice(0,1),t.slice(-1)==`/`&&n.splice(n.length-1,1),n}function Sn(e,t){let n={};return t.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(e,t,r){t&&(n[t]=r)}),n}var Cn=typeof addEventListener==`function`&&typeof removeEventListener==`function`,wn=[];Cn&&addEventListener(`offline`,()=>{wn.forEach(e=>e())},!1);var Tn=class e extends L{constructor(e,t){if(super(),this.binaryType=Wt,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e==`object`&&(t=e,e=null),e){let n=bn(e);t.hostname=n.host,t.secure=n.protocol===`https`||n.protocol===`wss`,t.port=n.port,n.query&&(t.query=n.query)}else t.host&&(t.hostname=bn(t.host).host);Jt(this,t),this.secure=t.secure==null?typeof location<`u`&&location.protocol===`https:`:t.secure,t.hostname&&!t.port&&(t.port=this.secure?`443`:`80`),this.hostname=t.hostname||(typeof location<`u`?location.hostname:`localhost`),this.port=t.port||(typeof location<`u`&&location.port?location.port:this.secure?`443`:`80`),this.transports=[],this._transportsByName={},t.transports.forEach(e=>{let t=e.prototype.name;this.transports.push(t),this._transportsByName[t]=e}),this.opts=Object.assign({path:`/engine.io`,agent:!1,withCredentials:!1,upgrade:!0,timestampParam:`t`,rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},t),this.opts.path=this.opts.path.replace(/\/$/,``)+(this.opts.addTrailingSlash?`/`:``),typeof this.opts.query==`string`&&(this.opts.query=en(this.opts.query)),Cn&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener(`beforeunload`,this._beforeunloadEventListener,!1)),this.hostname!==`localhost`&&(this._offlineEventListener=()=>{this._onClose(`transport close`,{description:`network connection lost`})},wn.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){let t=Object.assign({},this.opts.query);t.EIO=4,t.transport=e,this.id&&(t.sid=this.id);let n=Object.assign({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](n)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved(`error`,`No transports available`)},0);return}let t=this.opts.rememberUpgrade&&e.priorWebsocketSuccess&&this.transports.indexOf(`websocket`)!==-1?`websocket`:this.transports[0];this.readyState=`opening`;let n=this.createTransport(t);n.open(),this.setTransport(n)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on(`drain`,this._onDrain.bind(this)).on(`packet`,this._onPacket.bind(this)).on(`error`,this._onError.bind(this)).on(`close`,e=>this._onClose(`transport close`,e))}onOpen(){this.readyState=`open`,e.priorWebsocketSuccess=this.transport.name===`websocket`,this.emitReserved(`open`),this.flush()}_onPacket(e){if(this.readyState===`opening`||this.readyState===`open`||this.readyState===`closing`)switch(this.emitReserved(`packet`,e),this.emitReserved(`heartbeat`),e.type){case`open`:this.onHandshake(JSON.parse(e.data));break;case`ping`:this._sendPacket(`pong`),this.emitReserved(`ping`),this.emitReserved(`pong`),this._resetPingTimeout();break;case`error`:let t=Error(`server error`);t.code=e.data,this._onError(t);break;case`message`:this.emitReserved(`data`,e.data),this.emitReserved(`message`,e.data);break}}onHandshake(e){this.emitReserved(`handshake`,e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!==`closed`&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);let e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose(`ping timeout`)},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved(`drain`):this.flush()}flush(){if(this.readyState!==`closed`&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){let e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved(`flush`)}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name===`polling`&&this.writeBuffer.length>1))return this.writeBuffer;let e=1;for(let t=0;t0&&e>this._maxPayload)return this.writeBuffer.slice(0,t);e+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;let e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,Ut(()=>{this._onClose(`ping timeout`)},this.setTimeoutFn)),e}write(e,t,n){return this._sendPacket(`message`,e,t,n),this}send(e,t,n){return this._sendPacket(`message`,e,t,n),this}_sendPacket(e,t,n,r){if(typeof t==`function`&&(r=t,t=void 0),typeof n==`function`&&(r=n,n=null),this.readyState===`closing`||this.readyState===`closed`)return;n||={},n.compress=!1!==n.compress;let i={type:e,data:t,options:n};this.emitReserved(`packetCreate`,i),this.writeBuffer.push(i),r&&this.once(`flush`,r),this.flush()}close(){let e=()=>{this._onClose(`forced close`),this.transport.close()},t=()=>{this.off(`upgrade`,t),this.off(`upgradeError`,t),e()},n=()=>{this.once(`upgrade`,t),this.once(`upgradeError`,t)};return(this.readyState===`opening`||this.readyState===`open`)&&(this.readyState=`closing`,this.writeBuffer.length?this.once(`drain`,()=>{this.upgrading?n():e()}):this.upgrading?n():e()),this}_onError(t){if(e.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState===`opening`)return this.transports.shift(),this._open();this.emitReserved(`error`,t),this._onClose(`transport error`,t)}_onClose(e,t){if(this.readyState===`opening`||this.readyState===`open`||this.readyState===`closing`){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners(`close`),this.transport.close(),this.transport.removeAllListeners(),Cn&&(this._beforeunloadEventListener&&removeEventListener(`beforeunload`,this._beforeunloadEventListener,!1),this._offlineEventListener)){let e=wn.indexOf(this._offlineEventListener);e!==-1&&wn.splice(e,1)}this.readyState=`closed`,this.id=null,this.emitReserved(`close`,e,t),this.writeBuffer=[],this._prevBufferLen=0}}};Tn.protocol=4;var En=class extends Tn{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState===`open`&&this.opts.upgrade)for(let e=0;e{n||(t.send([{type:`ping`,data:`probe`}]),t.once(`packet`,e=>{if(!n)if(e.type===`pong`&&e.data===`probe`){if(this.upgrading=!0,this.emitReserved(`upgrading`,t),!t)return;Tn.priorWebsocketSuccess=t.name===`websocket`,this.transport.pause(()=>{n||this.readyState!==`closed`&&(l(),this.setTransport(t),t.send([{type:`upgrade`}]),this.emitReserved(`upgrade`,t),t=null,this.upgrading=!1,this.flush())})}else{let e=Error(`probe error`);e.transport=t.name,this.emitReserved(`upgradeError`,e)}}))};function i(){n||(n=!0,l(),t.close(),t=null)}let a=e=>{let n=Error(`probe error: `+e);n.transport=t.name,i(),this.emitReserved(`upgradeError`,n)};function o(){a(`transport closed`)}function s(){a(`socket closed`)}function c(e){t&&e.name!==t.name&&i()}let l=()=>{t.removeListener(`open`,r),t.removeListener(`error`,a),t.removeListener(`close`,o),this.off(`close`,s),this.off(`upgrading`,c)};t.once(`open`,r),t.once(`error`,a),t.once(`close`,o),this.once(`close`,s),this.once(`upgrading`,c),this._upgrades.indexOf(`webtransport`)!==-1&&e!==`webtransport`?this.setTimeoutFn(()=>{n||t.open()},200):t.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){let t=[];for(let n=0;n_n[e]).filter(e=>!!e)),super(e,n)}};Dn.protocol;function On(e,t=``,n){let r=e;n||=typeof location<`u`&&location,e??=n.protocol+`//`+n.host,typeof e==`string`&&(e.charAt(0)===`/`&&(e=e.charAt(1)===`/`?n.protocol+e:n.host+e),/^(https?|wss?):\/\//.test(e)||(e=n===void 0?`https://`+e:n.protocol+`//`+e),r=bn(e)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port=`80`:/^(http|ws)s$/.test(r.protocol)&&(r.port=`443`)),r.path=r.path||`/`;let i=r.host.indexOf(`:`)===-1?r.host:`[`+r.host+`]`;return r.id=r.protocol+`://`+i+`:`+r.port+t,r.href=r.protocol+`://`+i+(n&&n.port===r.port?``:`:`+r.port),r}var kn=typeof ArrayBuffer==`function`,An=e=>typeof ArrayBuffer.isView==`function`?ArrayBuffer.isView(e):e.buffer instanceof ArrayBuffer,jn=Object.prototype.toString,Mn=typeof Blob==`function`||typeof Blob<`u`&&jn.call(Blob)===`[object BlobConstructor]`,Nn=typeof File==`function`||typeof File<`u`&&jn.call(File)===`[object FileConstructor]`;function Pn(e){return kn&&(e instanceof ArrayBuffer||An(e))||Mn&&e instanceof Blob||Nn&&e instanceof File}function Fn(e,t){if(!e||typeof e!=`object`)return!1;if(Array.isArray(e)){for(let t=0,n=e.length;t=0&&e.numWn,Encoder:()=>Hn,PacketType:()=>z,protocol:()=>5}),Vn=[`connect`,`connect_error`,`disconnect`,`disconnecting`,`newListener`,`removeListener`],z;(function(e){e[e.CONNECT=0]=`CONNECT`,e[e.DISCONNECT=1]=`DISCONNECT`,e[e.EVENT=2]=`EVENT`,e[e.ACK=3]=`ACK`,e[e.CONNECT_ERROR=4]=`CONNECT_ERROR`,e[e.BINARY_EVENT=5]=`BINARY_EVENT`,e[e.BINARY_ACK=6]=`BINARY_ACK`})(z||={});var Hn=class{constructor(e){this.replacer=e}encode(e){return(e.type===z.EVENT||e.type===z.ACK)&&Fn(e)?this.encodeAsBinary({type:e.type===z.EVENT?z.BINARY_EVENT:z.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=``+e.type;return(e.type===z.BINARY_EVENT||e.type===z.BINARY_ACK)&&(t+=e.attachments+`-`),e.nsp&&e.nsp!==`/`&&(t+=e.nsp+`,`),e.id!=null&&(t+=e.id),e.data!=null&&(t+=JSON.stringify(e.data,this.replacer)),t}encodeAsBinary(e){let t=In(e),n=this.encodeAsString(t.packet),r=t.buffers;return r.unshift(n),r}};function Un(e){return Object.prototype.toString.call(e)===`[object Object]`}var Wn=class e extends L{constructor(e){super(),this.reviver=e}add(e){let t;if(typeof e==`string`){if(this.reconstructor)throw Error(`got plaintext data when reconstructing a packet`);t=this.decodeString(e);let n=t.type===z.BINARY_EVENT;n||t.type===z.BINARY_ACK?(t.type=n?z.EVENT:z.ACK,this.reconstructor=new Gn(t),t.attachments===0&&super.emitReserved(`decoded`,t)):super.emitReserved(`decoded`,t)}else if(Pn(e)||e.base64)if(this.reconstructor)t=this.reconstructor.takeBinaryData(e),t&&(this.reconstructor=null,super.emitReserved(`decoded`,t));else throw Error(`got binary data when not reconstructing a packet`);else throw Error(`Unknown type: `+e)}decodeString(t){let n=0,r={type:Number(t.charAt(0))};if(z[r.type]===void 0)throw Error(`unknown packet type `+r.type);if(r.type===z.BINARY_EVENT||r.type===z.BINARY_ACK){let e=n+1;for(;t.charAt(++n)!==`-`&&n!=t.length;);let i=t.substring(e,n);if(i!=Number(i)||t.charAt(n)!==`-`)throw Error(`Illegal attachments`);r.attachments=Number(i)}if(t.charAt(n+1)===`/`){let e=n+1;for(;++n&&!(t.charAt(n)===`,`||n===t.length););r.nsp=t.substring(e,n)}else r.nsp=`/`;let i=t.charAt(n+1);if(i!==``&&Number(i)==i){let e=n+1;for(;++n;){let e=t.charAt(n);if(e==null||Number(e)!=e){--n;break}if(n===t.length)break}r.id=Number(t.substring(e,n+1))}if(t.charAt(++n)){let i=this.tryParse(t.substr(n));if(e.isPayloadValid(r.type,i))r.data=i;else throw Error(`invalid payload`)}return r}tryParse(e){try{return JSON.parse(e,this.reviver)}catch{return!1}}static isPayloadValid(e,t){switch(e){case z.CONNECT:return Un(t);case z.DISCONNECT:return t===void 0;case z.CONNECT_ERROR:return typeof t==`string`||Un(t);case z.EVENT:case z.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]==`number`||typeof t[0]==`string`&&Vn.indexOf(t[0])===-1);case z.ACK:case z.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&=(this.reconstructor.finishedReconstruction(),null)}},Gn=class{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){let e=Rn(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}};function Kn(e,t,n){return e.on(t,n),function(){e.off(t,n)}}var qn=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1}),Jn=class extends L{constructor(e,t,n){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=t,n&&n.auth&&(this.auth=n.auth),this._opts=Object.assign({},n),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;let e=this.io;this.subs=[Kn(e,`open`,this.onopen.bind(this)),Kn(e,`packet`,this.onpacket.bind(this)),Kn(e,`error`,this.onerror.bind(this)),Kn(e,`close`,this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState===`open`&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift(`message`),this.emit.apply(this,e),this}emit(e,...t){if(qn.hasOwnProperty(e))throw Error(`"`+e.toString()+`" is a reserved event name`);if(t.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(t),this;let n={type:z.EVENT,data:t};if(n.options={},n.options.compress=this.flags.compress!==!1,typeof t[t.length-1]==`function`){let e=this.ids++,r=t.pop();this._registerAckCallback(e,r),n.id=e}let r=this.io.engine?.transport?.writable,i=this.connected&&!this.io.engine?._hasPingExpired();return this.flags.volatile&&!r||(i?(this.notifyOutgoingListeners(n),this.packet(n)):this.sendBuffer.push(n)),this.flags={},this}_registerAckCallback(e,t){let n=this.flags.timeout??this._opts.ackTimeout;if(n===void 0){this.acks[e]=t;return}let r=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let t=0;t{this.io.clearTimeoutFn(r),t.apply(this,e)};i.withError=!0,this.acks[e]=i}emitWithAck(e,...t){return new Promise((n,r)=>{let i=(e,t)=>e?r(e):n(t);i.withError=!0,t.push(i),this.emit(e,...t)})}_addToQueue(e){let t;typeof e[e.length-1]==`function`&&(t=e.pop());let n={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((e,...r)=>(this._queue[0],e===null?(this._queue.shift(),t&&t(null,...r)):n.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(e)),n.pending=!1,this._drainQueue())),this._queue.push(n),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;let t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth==`function`?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:z.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved(`connect_error`,e)}onclose(e,t){this.connected=!1,delete this.id,this.emitReserved(`disconnect`,e,t),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(t=>String(t.id)===e)){let t=this.acks[e];delete this.acks[e],t.withError&&t.call(this,Error(`socket has been disconnected`))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case z.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved(`connect_error`,Error(`It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)`));break;case z.EVENT:case z.BINARY_EVENT:this.onevent(e);break;case z.ACK:case z.BINARY_ACK:this.onack(e);break;case z.DISCONNECT:this.ondisconnect();break;case z.CONNECT_ERROR:this.destroy();let t=Error(e.data.message);t.data=e.data.data,this.emitReserved(`connect_error`,t);break}}onevent(e){let t=e.data||[];e.id!=null&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){let t=this._anyListeners.slice();for(let n of t)n.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]==`string`&&(this._lastOffset=e[e.length-1])}ack(e){let t=this,n=!1;return function(...r){n||(n=!0,t.packet({type:z.ACK,id:e,data:r}))}}onack(e){let t=this.acks[e.id];typeof t==`function`&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}onconnect(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved(`connect`)}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose(`io server disconnect`)}destroy(){this.subs&&=(this.subs.forEach(e=>e()),void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:z.DISCONNECT}),this.destroy(),this.connected&&this.onclose(`io client disconnect`),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){let t=this._anyListeners;for(let n=0;n0&&e.jitter<=1?e.jitter:0,this.attempts=0}Yn.prototype.duration=function(){var e=this.ms*this.factor**+ this.attempts++;if(this.jitter){var t=Math.random(),n=Math.floor(t*this.jitter*e);e=Math.floor(t*10)&1?e+n:e-n}return Math.min(e,this.max)|0},Yn.prototype.reset=function(){this.attempts=0},Yn.prototype.setMin=function(e){this.ms=e},Yn.prototype.setMax=function(e){this.max=e},Yn.prototype.setJitter=function(e){this.jitter=e};var Xn=class extends L{constructor(e,t){super(),this.nsps={},this.subs=[],e&&typeof e==`object`&&(t=e,e=void 0),t||={},t.path=t.path||`/socket.io`,this.opts=t,Jt(this,t),this.reconnection(t.reconnection!==!1),this.reconnectionAttempts(t.reconnectionAttempts||1/0),this.reconnectionDelay(t.reconnectionDelay||1e3),this.reconnectionDelayMax(t.reconnectionDelayMax||5e3),this.randomizationFactor(t.randomizationFactor??.5),this.backoff=new Yn({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState=`closed`,this.uri=e;let n=t.parser||Bn;this.encoder=new n.Encoder,this.decoder=new n.Decoder,this._autoConnect=t.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var t;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(t=this.backoff)==null||t.setMin(e),this)}randomizationFactor(e){var t;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(t=this.backoff)==null||t.setJitter(e),this)}reconnectionDelayMax(e){var t;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(t=this.backoff)==null||t.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf(`open`))return this;this.engine=new Dn(this.uri,this.opts);let t=this.engine,n=this;this._readyState=`opening`,this.skipReconnect=!1;let r=Kn(t,`open`,function(){n.onopen(),e&&e()}),i=t=>{this.cleanup(),this._readyState=`closed`,this.emitReserved(`error`,t),e?e(t):this.maybeReconnectOnOpen()},a=Kn(t,`error`,i);if(!1!==this._timeout){let e=this._timeout,n=this.setTimeoutFn(()=>{r(),i(Error(`timeout`)),t.close()},e);this.opts.autoUnref&&n.unref(),this.subs.push(()=>{this.clearTimeoutFn(n)})}return this.subs.push(r),this.subs.push(a),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState=`open`,this.emitReserved(`open`);let e=this.engine;this.subs.push(Kn(e,`ping`,this.onping.bind(this)),Kn(e,`data`,this.ondata.bind(this)),Kn(e,`error`,this.onerror.bind(this)),Kn(e,`close`,this.onclose.bind(this)),Kn(this.decoder,`decoded`,this.ondecoded.bind(this)))}onping(){this.emitReserved(`ping`)}ondata(e){try{this.decoder.add(e)}catch(e){this.onclose(`parse error`,e)}}ondecoded(e){Ut(()=>{this.emitReserved(`packet`,e)},this.setTimeoutFn)}onerror(e){this.emitReserved(`error`,e)}socket(e,t){let n=this.nsps[e];return n?this._autoConnect&&!n.active&&n.connect():(n=new Jn(this,e,t),this.nsps[e]=n),n}_destroy(e){let t=Object.keys(this.nsps);for(let e of t)if(this.nsps[e].active)return;this._close()}_packet(e){let t=this.encoder.encode(e);for(let n=0;ne()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose(`forced close`)}disconnect(){return this._close()}onclose(e,t){var n;this.cleanup(),(n=this.engine)==null||n.close(),this.backoff.reset(),this._readyState=`closed`,this.emitReserved(`close`,e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;let e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved(`reconnect_failed`),this._reconnecting=!1;else{let t=this.backoff.duration();this._reconnecting=!0;let n=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved(`reconnect_attempt`,e.backoff.attempts),!e.skipReconnect&&e.open(t=>{t?(e._reconnecting=!1,e.reconnect(),this.emitReserved(`reconnect_error`,t)):e.onreconnect()}))},t);this.opts.autoUnref&&n.unref(),this.subs.push(()=>{this.clearTimeoutFn(n)})}}onreconnect(){let e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved(`reconnect`,e)}},Zn={};function Qn(e,t){typeof e==`object`&&(t=e,e=void 0),t||={};let n=On(e,t.path||`/socket.io`),r=n.source,i=n.id,a=n.path,o=Zn[i]&&a in Zn[i].nsps,s=t.forceNew||t[`force new connection`]||!1===t.multiplex||o,c;return s?c=new Xn(r,t):(Zn[i]||(Zn[i]=new Xn(r,t)),c=Zn[i]),n.query&&!t.query&&(t.query=n.queryKey),c.socket(n.path,t)}Object.assign(Qn,{Manager:Xn,Socket:Jn,io:Qn,connect:Qn});var $n={debug:0,info:1,warn:2,error:3},er=$n.info,tr=()=>new Date().toLocaleTimeString(),B={reset:`\x1B[0m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,green:`\x1B[32m`,yellow:`\x1B[33m`,red:`\x1B[31m`,magenta:`\x1B[35m`,gray:`\x1B[90m`},V={debug:(e,t,n)=>{er<=$n.debug&&console.log(`${B.blue}[${tr()}]${B.reset} ${B.gray}[${e}]${B.reset} ${t}`,n||``)},info:(e,t,n)=>{er<=$n.info&&console.log(`${B.blue}[${tr()}]${B.reset} ${B.cyan}[${e}]${B.reset} ${t}`,n||``)},warn:(e,t,n)=>{er<=$n.warn&&console.warn(`${B.blue}[${tr()}]${B.reset} ${B.yellow}[${e}]${B.reset} ${t}`,n||``)},error:(e,t,n)=>{er<=$n.error&&console.error(`${B.blue}[${tr()}]${B.reset} ${B.red}[${e}]${B.reset} ${t}`,n||``)},socket:(e,t,n)=>{let r=e===`⬅️`?B.yellow:B.green,i=e===`⬅️`?B.cyan:B.magenta;console.log(`${B.blue}[${tr()}]${B.reset} ${r}[${e}]${B.reset} ${i}[${t}]${B.reset}`,n||``)}},nr=o((e=>{var t=d(),n=Symbol.for(`react.element`),r=Symbol.for(`react.fragment`),i=Object.prototype.hasOwnProperty,a=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function s(e,t,r){var s,c={},l=null,u=null;for(s in r!==void 0&&(l=``+r),t.key!==void 0&&(l=``+t.key),t.ref!==void 0&&(u=t.ref),t)i.call(t,s)&&!o.hasOwnProperty(s)&&(c[s]=t[s]);if(e&&e.defaultProps)for(s in t=e.defaultProps,t)c[s]===void 0&&(c[s]=t[s]);return{$$typeof:n,type:e,key:l,ref:u,props:c,_owner:a.current}}e.Fragment=r,e.jsx=s,e.jsxs=s})),H=o(((e,t)=>{t.exports=nr()}))(),rr=(0,_.createContext)(),ir=()=>{let e=(0,_.useContext)(rr);if(!e)throw Error(`useGameContext must be used within a GameProvider`);return e},ar=({children:e})=>{let[t,n]=(0,_.useState)(localStorage.getItem(`playerName`)||``),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)(null),s=(0,_.useRef)(null);(0,_.useEffect)(()=>{let e=Qn(`http://localhost:4000`);return s.current=e,o(e),e.on(`connect`,()=>{V.info(`SOCKET`,`Connected with ID: ${e.id}`)}),e.on(`disconnect`,e=>{V.warn(`SOCKET`,`Disconnected: ${e}`)}),e.on(`connect_error`,e=>{V.error(`SOCKET`,`Connection error: ${e.message}`)}),V.info(`SOCKET`,`Initializing socket connection...`),()=>{V.info(`SOCKET`,`Cleaning up socket connection`),e.disconnect()}},[]),(0,_.useEffect)(()=>{t&&localStorage.setItem(`playerName`,t)},[t]);let c={playerName:t,setPlayerName:n,roomId:r,setRoomId:i,socket:a};return(0,H.jsx)(rr.Provider,{value:c,children:e})},U=({children:e,onClick:t,disabled:n,className:r=``,variant:i=`primary`})=>(0,H.jsx)(`button`,{onClick:t,disabled:n,className:`px-6 py-2 rounded-lg font-bold transition-all duration-300 transform active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none glass ${{primary:`bg-blue-500/40 hover:bg-blue-500/60 text-blue-900 border-blue-400/50`,secondary:`bg-purple-500/40 hover:bg-purple-500/60 text-purple-900 border-purple-400/50`,success:`bg-green-500/40 hover:bg-green-500/60 text-green-900 border-green-400/50`,danger:`bg-red-500/40 hover:bg-red-500/60 text-red-900 border-red-400/50`}[i]} ${r}`,children:e}),or=o(((e,t)=>{(function(n,r){typeof e==`object`&&t!==void 0?t.exports=r():typeof define==`function`&&define.amd?define(r):(n=typeof globalThis<`u`?globalThis:n||self,n.Sweetalert2=r())})(e,(function(){function e(e,t,n){if(typeof e==`function`?e===t:e.has(t))return arguments.length<3?t:n;throw TypeError(`Private element is not present on this object`)}function t(e,t){if(t.has(e))throw TypeError(`Cannot initialize the same private elements twice on an object`)}function n(t,n){return t.get(e(t,n))}function r(e,n,r){t(e,n),n.set(e,r)}function i(t,n,r){return t.set(e(t,n),r),r}let a={},o=()=>{a.previousActiveElement instanceof HTMLElement?(a.previousActiveElement.focus(),a.previousActiveElement=null):document.body&&document.body.focus()},s=e=>new Promise(t=>{if(!e)return t();let n=window.scrollX,r=window.scrollY;a.restoreFocusTimeout=setTimeout(()=>{o(),t()},100),window.scrollTo(n,r)}),c=`swal2-`,l=`container.shown.height-auto.iosfix.popup.modal.no-backdrop.no-transition.toast.toast-shown.show.hide.close.title.html-container.actions.confirm.deny.cancel.footer.icon.icon-content.image.input.file.range.select.radio.checkbox.label.textarea.inputerror.input-label.validation-message.progress-steps.active-progress-step.progress-step.progress-step-line.loader.loading.styled.top.top-start.top-end.top-left.top-right.center.center-start.center-end.center-left.center-right.bottom.bottom-start.bottom-end.bottom-left.bottom-right.grow-row.grow-column.grow-fullscreen.rtl.timer-progress-bar.timer-progress-bar-container.scrollbar-measure.icon-success.icon-warning.icon-info.icon-question.icon-error.draggable.dragging`.split(`.`).reduce((e,t)=>(e[t]=c+t,e),{}),u=[`success`,`warning`,`info`,`question`,`error`].reduce((e,t)=>(e[t]=c+t,e),{}),d=`SweetAlert2:`,f=e=>e.charAt(0).toUpperCase()+e.slice(1),p=e=>{console.warn(`${d} ${typeof e==`object`?e.join(` `):e}`)},m=e=>{console.error(`${d} ${e}`)},h=[],g=e=>{h.includes(e)||(h.push(e),p(e))},_=(e,t=null)=>{g(`"${e}" is deprecated and will be removed in the next major release.${t?` Use "${t}" instead.`:``}`)},v=e=>typeof e==`function`?e():e,y=e=>e&&typeof e.toPromise==`function`,b=e=>y(e)?e.toPromise():Promise.resolve(e),x=e=>e&&Promise.resolve(e)===e,S=()=>navigator.userAgent.includes(`Firefox`),C=()=>document.body.querySelector(`.${l.container}`),w=e=>{let t=C();return t?t.querySelector(e):null},T=e=>w(`.${e}`),E=()=>T(l.popup),D=()=>T(l.icon),ee=()=>T(l[`icon-content`]),te=()=>T(l.title),ne=()=>T(l[`html-container`]),re=()=>T(l.image),ie=()=>T(l[`progress-steps`]),ae=()=>T(l[`validation-message`]),O=()=>w(`.${l.actions} .${l.confirm}`),k=()=>w(`.${l.actions} .${l.cancel}`),oe=()=>w(`.${l.actions} .${l.deny}`),se=()=>T(l[`input-label`]),ce=()=>w(`.${l.loader}`),A=()=>T(l.actions),le=()=>T(l.footer),ue=()=>T(l[`timer-progress-bar`]),de=()=>T(l.close),fe=()=>{let e=E();if(!e)return[];let t=e.querySelectorAll(`[tabindex]:not([tabindex="-1"]):not([tabindex="0"])`),n=Array.from(t).sort((e,t)=>{let n=parseInt(e.getAttribute(`tabindex`)||`0`),r=parseInt(t.getAttribute(`tabindex`)||`0`);return n>r?1:ne.getAttribute(`tabindex`)!==`-1`);return[...new Set(n.concat(i))].filter(e=>ke(e))},pe=()=>ge(document.body,l.shown)&&!ge(document.body,l[`toast-shown`])&&!ge(document.body,l[`no-backdrop`]),me=()=>{let e=E();return e?ge(e,l.toast):!1},he=()=>{let e=E();return e?e.hasAttribute(`data-loading`):!1},j=(e,t)=>{if(e.textContent=``,t){let n=new DOMParser().parseFromString(t,`text/html`),r=n.querySelector(`head`);r&&Array.from(r.childNodes).forEach(t=>{e.appendChild(t)});let i=n.querySelector(`body`);i&&Array.from(i.childNodes).forEach(t=>{t instanceof HTMLVideoElement||t instanceof HTMLAudioElement?e.appendChild(t.cloneNode(!0)):e.appendChild(t)})}},ge=(e,t)=>{if(!t)return!1;let n=t.split(/\s+/);for(let t=0;t{Array.from(e.classList).forEach(n=>{!Object.values(l).includes(n)&&!Object.values(u).includes(n)&&!Object.values(t.showClass||{}).includes(n)&&e.classList.remove(n)})},ve=(e,t,n)=>{if(_e(e,t),!t.customClass)return;let r=t.customClass[n];if(r){if(typeof r!=`string`&&!r.forEach){p(`Invalid type of customClass.${n}! Expected string or iterable object, got "${typeof r}"`);return}M(e,r)}},ye=(e,t)=>{if(!t)return null;switch(t){case`select`:case`textarea`:case`file`:return e.querySelector(`.${l.popup} > .${l[t]}`);case`checkbox`:return e.querySelector(`.${l.popup} > .${l.checkbox} input`);case`radio`:return e.querySelector(`.${l.popup} > .${l.radio} input:checked`)||e.querySelector(`.${l.popup} > .${l.radio} input:first-child`);case`range`:return e.querySelector(`.${l.popup} > .${l.range} input`);default:return e.querySelector(`.${l.popup} > .${l.input}`)}},be=e=>{if(e.focus(),e.type!==`file`){let t=e.value;e.value=``,e.value=t}},xe=(e,t,n)=>{if(!e||!t)return;let r=typeof t==`string`?t.split(/\s+/).filter(Boolean):t;(Array.isArray(e)?e:[e]).forEach(e=>{r.forEach(t=>{n?e.classList.add(t):e.classList.remove(t)})})},M=(e,t)=>{xe(e,t,!0)},Se=(e,t)=>{xe(e,t,!1)},Ce=(e,t)=>{let n=Array.from(e.children);for(let e=0;e{n===`${parseInt(`${n}`)}`&&(n=parseInt(n)),n||n===0?e.style.setProperty(t,typeof n==`number`?`${n}px`:n):e.style.removeProperty(t)},Te=(e,t=`flex`)=>{e&&(e.style.display=t)},N=e=>{e&&(e.style.display=`none`)},Ee=(e,t=`block`)=>{e&&new MutationObserver(()=>{Oe(e,e.innerHTML,t)}).observe(e,{childList:!0,subtree:!0})},De=(e,t,n,r)=>{let i=e.querySelector(t);i&&i.style.setProperty(n,r)},Oe=(e,t,n=`flex`)=>{t?Te(e,n):N(e)},ke=e=>!!(e&&(e.offsetWidth||e.offsetHeight||e.getClientRects().length)),Ae=()=>!ke(O())&&!ke(oe())&&!ke(k()),je=e=>e.scrollHeight>e.clientHeight,Me=(e,t)=>{let n=e;for(;n&&n!==t;){if(je(n))return!0;n=n.parentElement}return!1},Ne=e=>{let t=window.getComputedStyle(e),n=parseFloat(t.getPropertyValue(`animation-duration`)||`0`),r=parseFloat(t.getPropertyValue(`transition-duration`)||`0`);return n>0||r>0},Pe=(e,t=!1)=>{let n=ue();n&&ke(n)&&(t&&(n.style.transition=`none`,n.style.width=`100%`),setTimeout(()=>{n.style.transition=`width ${e/1e3}s linear`,n.style.width=`0%`},10))},Fe=()=>{let e=ue();if(!e)return;let t=parseInt(window.getComputedStyle(e).width);e.style.removeProperty(`transition`),e.style.width=`100%`;let n=t/parseInt(window.getComputedStyle(e).width)*100;e.style.width=`${n}%`},Ie=()=>typeof window>`u`||typeof document>`u`,Le=` -

- - -
- -

-
- - -
- - -
- -
- - -
-
-
- - - -
-
-
-
-
-
-`.replace(/(^|\n)\s*/g,``),Re=()=>{let e=C();return e?(e.remove(),Se([document.documentElement,document.body],[l[`no-backdrop`],l[`toast-shown`],l[`has-column`]]),!0):!1},ze=()=>{a.currentInstance&&a.currentInstance.resetValidationMessage()},Be=()=>{let e=E();if(!e)return;let t=Ce(e,l.input),n=Ce(e,l.file),r=e.querySelector(`.${l.range} input`),i=e.querySelector(`.${l.range} output`),a=Ce(e,l.select),o=e.querySelector(`.${l.checkbox} input`),s=Ce(e,l.textarea);t&&(t.oninput=ze),n&&(n.onchange=ze),a&&(a.onchange=ze),o&&(o.onchange=ze),s&&(s.oninput=ze),r&&i&&(r.oninput=()=>{ze(),i.value=r.value},r.onchange=()=>{ze(),i.value=r.value})},Ve=e=>{if(typeof e==`string`){let t=document.querySelector(e);if(!t)throw Error(`Target element "${e}" not found`);return t}return e},He=e=>{let t=E();t&&(t.setAttribute(`role`,e.toast?`alert`:`dialog`),t.setAttribute(`aria-live`,e.toast?`polite`:`assertive`),e.toast||t.setAttribute(`aria-modal`,`true`))},Ue=e=>{window.getComputedStyle(e).direction===`rtl`&&(M(C(),l.rtl),a.isRTL=!0)},We=e=>{let t=Re();if(Ie()){m(`SweetAlert2 requires document to initialize`);return}let n=document.createElement(`div`);n.className=l.container,t&&M(n,l[`no-transition`]),j(n,Le),n.dataset.swal2Theme=e.theme;let r=Ve(e.target||`body`);r.appendChild(n),e.topLayer&&(n.setAttribute(`popover`,``),n.showPopover()),He(e),Ue(r),Be()},Ge=(e,t)=>{e instanceof HTMLElement?t.appendChild(e):typeof e==`object`?Ke(e,t):e&&j(t,e)},Ke=(e,t)=>{`jquery`in e?qe(t,e):j(t,e.toString())},qe=(e,t)=>{if(e.textContent=``,0 in t)for(let n=0;n in t;n++)e.appendChild(t[n].cloneNode(!0));else e.appendChild(t.cloneNode(!0))},Je=(e,t)=>{let n=A(),r=ce();!n||!r||(!t.showConfirmButton&&!t.showDenyButton&&!t.showCancelButton?N(n):Te(n),ve(n,t,`actions`),Ye(n,r,t),j(r,t.loaderHtml||``),ve(r,t,`loader`))};function Ye(e,t,n){let r=O(),i=oe(),a=k();!r||!i||!a||(Qe(r,`confirm`,n),Qe(i,`deny`,n),Qe(a,`cancel`,n),Xe(r,i,a,n),n.reverseButtons&&(n.toast?(e.insertBefore(a,r),e.insertBefore(i,r)):(e.insertBefore(a,t),e.insertBefore(i,t),e.insertBefore(r,t))))}function Xe(e,t,n,r){if(!r.buttonsStyling){Se([e,t,n],l.styled);return}M([e,t,n],l.styled),[[e,`confirm`,r.confirmButtonColor],[t,`deny`,r.denyButtonColor],[n,`cancel`,r.cancelButtonColor]].forEach(([e,t,n])=>{n&&e.style.setProperty(`--swal2-${t}-button-background-color`,n),Ze(e)})}function Ze(e){let t=window.getComputedStyle(e);if(t.getPropertyValue(`--swal2-action-button-focus-box-shadow`))return;let n=t.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/,`rgba($1, $2, $3, 0.5)`);e.style.setProperty(`--swal2-action-button-focus-box-shadow`,t.getPropertyValue(`--swal2-outline`).replace(/ rgba\(.*/,` ${n}`))}function Qe(e,t,n){Oe(e,n[`show${f(t)}Button`],`inline-block`),j(e,n[`${t}ButtonText`]||``),e.setAttribute(`aria-label`,n[`${t}ButtonAriaLabel`]||``),e.className=l[t],ve(e,n,`${t}Button`)}let $e=(e,t)=>{let n=de();n&&(j(n,t.closeButtonHtml||``),ve(n,t,`closeButton`),Oe(n,t.showCloseButton),n.setAttribute(`aria-label`,t.closeButtonAriaLabel||``))},et=(e,t)=>{let n=C();n&&(tt(n,t.backdrop),nt(n,t.position),rt(n,t.grow),ve(n,t,`container`))};function tt(e,t){typeof t==`string`?e.style.background=t:t||M([document.documentElement,document.body],l[`no-backdrop`])}function nt(e,t){t&&(t in l?M(e,l[t]):(p(`The "position" parameter is not valid, defaulting to "center"`),M(e,l.center)))}function rt(e,t){t&&M(e,l[`grow-${t}`])}var P={innerParams:new WeakMap,domCache:new WeakMap,focusedElement:new WeakMap};let it=[`input`,`file`,`range`,`select`,`radio`,`checkbox`,`textarea`],at=(e,t)=>{let n=E();if(!n)return;let r=P.innerParams.get(e),i=!r||t.input!==r.input;it.forEach(e=>{let r=Ce(n,l[e]);r&&(ct(e,t.inputAttributes),r.className=l[e],i&&N(r))}),t.input&&(i&&ot(t),lt(t))},ot=e=>{if(!e.input)return;if(!F[e.input]){m(`Unexpected type of input! Expected ${Object.keys(F).join(` | `)}, got "${e.input}"`);return}let t=ft(e.input);if(!t)return;let n=F[e.input](t,e);Te(t),e.inputAutoFocus&&setTimeout(()=>{be(n)})},st=e=>{for(let t=0;t{let n=E();if(!n)return;let r=ye(n,e);if(r){st(r);for(let e in t)r.setAttribute(e,t[e])}},lt=e=>{if(!e.input)return;let t=ft(e.input);t&&ve(t,e,`input`)},ut=(e,t)=>{!e.placeholder&&t.inputPlaceholder&&(e.placeholder=t.inputPlaceholder)},dt=(e,t,n)=>{if(n.inputLabel){let r=document.createElement(`label`),i=l[`input-label`];r.setAttribute(`for`,e.id),r.className=i,typeof n.customClass==`object`&&M(r,n.customClass.inputLabel),r.innerText=n.inputLabel,t.insertAdjacentElement(`beforebegin`,r)}},ft=e=>{let t=E();if(t)return Ce(t,l[e]||l.input)},pt=(e,t)=>{[`string`,`number`].includes(typeof t)?e.value=`${t}`:x(t)||p(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof t}"`)},F={};F.text=F.email=F.password=F.number=F.tel=F.url=F.search=F.date=F[`datetime-local`]=F.time=F.week=F.month=(e,t)=>{let n=e;return pt(n,t.inputValue),dt(n,n,t),ut(n,t),n.type=t.input,n},F.file=(e,t)=>{let n=e;return dt(n,n,t),ut(n,t),n},F.range=(e,t)=>{let n=e,r=n.querySelector(`input`),i=n.querySelector(`output`);return r&&(pt(r,t.inputValue),r.type=t.input,dt(r,e,t)),i&&pt(i,t.inputValue),e},F.select=(e,t)=>{let n=e;if(n.textContent=``,t.inputPlaceholder){let e=document.createElement(`option`);j(e,t.inputPlaceholder),e.value=``,e.disabled=!0,e.selected=!0,n.appendChild(e)}return dt(n,n,t),n},F.radio=e=>{let t=e;return t.textContent=``,e},F.checkbox=(e,t)=>{let n=E();if(!n)throw Error(`Popup not found`);let r=ye(n,`checkbox`);if(!r)throw Error(`Checkbox input not found`);r.value=`1`,r.checked=!!t.inputValue;let i=e.querySelector(`span`);if(i){let e=t.inputPlaceholder||t.inputLabel;e&&j(i,e)}return r},F.textarea=(e,t)=>{let n=e;pt(n,t.inputValue),ut(n,t),dt(n,n,t);let r=e=>parseInt(window.getComputedStyle(e).marginLeft)+parseInt(window.getComputedStyle(e).marginRight);return setTimeout(()=>{if(`MutationObserver`in window){let e=E();if(!e)return;let i=parseInt(window.getComputedStyle(e).width);new MutationObserver(()=>{if(!document.body.contains(n))return;let e=n.offsetWidth+r(n),a=E();a&&(e>i?a.style.width=`${e}px`:we(a,`width`,t.width))}).observe(n,{attributes:!0,attributeFilter:[`style`]})}}),n};let mt=(e,t)=>{let n=ne();n&&(Ee(n),ve(n,t,`htmlContainer`),t.html?(Ge(t.html,n),Te(n,`block`)):t.text?(n.textContent=t.text,Te(n,`block`)):N(n),at(e,t))},ht=(e,t)=>{let n=le();n&&(Ee(n),Oe(n,!!t.footer,`block`),t.footer&&Ge(t.footer,n),ve(n,t,`footer`))},gt=(e,t)=>{let n=P.innerParams.get(e),r=D();if(r){if(n&&t.icon===n.icon){I(r,t),_t(r,t);return}if(!t.icon&&!t.iconHtml){N(r);return}if(t.icon&&Object.keys(u).indexOf(t.icon)===-1){m(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${t.icon}"`),N(r);return}Te(r),I(r,t),_t(r,t),M(r,t.showClass&&t.showClass.icon),window.matchMedia(`(prefers-color-scheme: dark)`).addEventListener(`change`,vt)}},_t=(e,t)=>{for(let[n,r]of Object.entries(u))t.icon!==n&&Se(e,r);M(e,t.icon&&u[t.icon]),bt(e,t),vt(),ve(e,t,`icon`)},vt=()=>{let e=E();if(!e)return;let t=window.getComputedStyle(e).getPropertyValue(`background-color`),n=e.querySelectorAll(`[class^=swal2-success-circular-line], .swal2-success-fix`);for(let e=0;e` - ${e.animation?`
`:``} - -
- ${e.animation?`
`:``} - ${e.animation?`
`:``} -`,I=(e,t)=>{if(!t.icon&&!t.iconHtml)return;let n=e.innerHTML,r=``;t.iconHtml?r=xt(t.iconHtml):t.icon===`success`?(r=yt(t),n=n.replace(/ style=".*?"/g,``)):t.icon===`error`?r=` - - - - -`:t.icon&&(r=xt({question:`?`,warning:`!`,info:`i`}[t.icon])),n.trim()!==r.trim()&&j(e,r)},bt=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(let n of[`.swal2-success-line-tip`,`.swal2-success-line-long`,`.swal2-x-mark-line-left`,`.swal2-x-mark-line-right`])De(e,n,`background-color`,t.iconColor);De(e,`.swal2-success-ring`,`border-color`,t.iconColor)}},xt=e=>`
${e}
`,St=(e,t)=>{let n=re();if(n){if(!t.imageUrl){N(n);return}Te(n,``),n.setAttribute(`src`,t.imageUrl),n.setAttribute(`alt`,t.imageAlt||``),we(n,`width`,t.imageWidth),we(n,`height`,t.imageHeight),n.className=l.image,ve(n,t,`image`)}},Ct=!1,wt=0,Tt=0,Et=0,Dt=0,Ot=e=>{e.addEventListener(`mousedown`,At),document.body.addEventListener(`mousemove`,jt),e.addEventListener(`mouseup`,Mt),e.addEventListener(`touchstart`,At),document.body.addEventListener(`touchmove`,jt),e.addEventListener(`touchend`,Mt)},kt=e=>{e.removeEventListener(`mousedown`,At),document.body.removeEventListener(`mousemove`,jt),e.removeEventListener(`mouseup`,Mt),e.removeEventListener(`touchstart`,At),document.body.removeEventListener(`touchmove`,jt),e.removeEventListener(`touchend`,Mt)},At=e=>{let t=E();if(!t)return;let n=D();if(e.target===t||n&&n.contains(e.target)){Ct=!0;let n=Nt(e);wt=n.clientX,Tt=n.clientY,Et=parseInt(t.style.insetInlineStart)||0,Dt=parseInt(t.style.insetBlockStart)||0,M(t,`swal2-dragging`)}},jt=e=>{let t=E();if(t&&Ct){let{clientX:n,clientY:r}=Nt(e),i=n-wt;t.style.insetInlineStart=`${Et+(a.isRTL?-i:i)}px`,t.style.insetBlockStart=`${Dt+(r-Tt)}px`}},Mt=()=>{let e=E();Ct=!1,Se(e,`swal2-dragging`)},Nt=e=>{let t=e.type.startsWith(`touch`)?e.touches[0]:e;return{clientX:t.clientX,clientY:t.clientY}},Pt=(e,t)=>{let n=C(),r=E();if(!(!n||!r)){if(t.toast){we(n,`width`,t.width),r.style.width=`100%`;let e=ce();e&&r.insertBefore(e,D())}else we(r,`width`,t.width);we(r,`padding`,t.padding),t.color&&(r.style.color=t.color),t.background&&(r.style.background=t.background),N(ae()),Ft(r,t),t.draggable&&!t.toast?(M(r,l.draggable),Ot(r)):(Se(r,l.draggable),kt(r))}},Ft=(e,t)=>{let n=t.showClass||{};e.className=`${l.popup} ${ke(e)?n.popup:``}`,t.toast?(M([document.documentElement,document.body],l[`toast-shown`]),M(e,l.toast)):M(e,l.modal),ve(e,t,`popup`),typeof t.customClass==`string`&&M(e,t.customClass),t.icon&&M(e,l[`icon-${t.icon}`])},It=(e,t)=>{let n=ie();if(!n)return;let{progressSteps:r,currentProgressStep:i}=t;if(!r||r.length===0||i===void 0){N(n);return}Te(n),n.textContent=``,i>=r.length&&p(`Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)`),r.forEach((e,a)=>{let o=Lt(e);if(n.appendChild(o),a===i&&M(o,l[`active-progress-step`]),a!==r.length-1){let e=Rt(t);n.appendChild(e)}})},Lt=e=>{let t=document.createElement(`li`);return M(t,l[`progress-step`]),j(t,e),t},Rt=e=>{let t=document.createElement(`li`);return M(t,l[`progress-step-line`]),e.progressStepsDistance&&we(t,`width`,e.progressStepsDistance),t},zt=(e,t)=>{let n=te();n&&(Ee(n),Oe(n,!!(t.title||t.titleText),`block`),t.title&&Ge(t.title,n),t.titleText&&(n.innerText=t.titleText),ve(n,t,`title`))},Bt=(e,t)=>{var n;Pt(e,t),et(e,t),It(e,t),gt(e,t),St(e,t),zt(e,t),$e(e,t),mt(e,t),Je(e,t),ht(e,t);let r=E();typeof t.didRender==`function`&&r&&t.didRender(r),(n=a.eventEmitter)==null||n.emit(`didRender`,r)},Vt=()=>ke(E()),L=()=>O()?.click(),Ht=()=>oe()?.click(),Ut=()=>k()?.click(),R=Object.freeze({cancel:`cancel`,backdrop:`backdrop`,close:`close`,esc:`esc`,timer:`timer`}),Wt=e=>{if(e.keydownTarget&&e.keydownHandlerAdded&&e.keydownHandler){let t=e.keydownHandler;e.keydownTarget.removeEventListener(`keydown`,t,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1}},Gt=(e,t,n)=>{if(Wt(e),!t.toast){let r=e=>Yt(t,e,n);e.keydownHandler=r;let i=t.keydownListenerCapture?window:E();if(i){e.keydownTarget=i,e.keydownListenerCapture=t.keydownListenerCapture;let n=r;e.keydownTarget.addEventListener(`keydown`,n,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!0}}},Kt=(e,t)=>{var n;let r=fe();return r.length?(e+=t,e===-2&&(e=r.length-1),e===r.length?e=0:e===-1&&(e=r.length-1),r[e].focus(),!(S()&&r[e]instanceof HTMLIFrameElement)):((n=E())==null||n.focus(),!0)},qt=[`ArrowRight`,`ArrowDown`],Jt=[`ArrowLeft`,`ArrowUp`],Yt=(e,t,n)=>{e&&(t.isComposing||t.keyCode===229||(e.stopKeydownPropagation&&t.stopPropagation(),t.key===`Enter`?Xt(t,e):t.key===`Tab`?Zt(t):[...qt,...Jt].includes(t.key)?Qt(t.key):t.key===`Escape`&&$t(t,e,n)))},Xt=(e,t)=>{if(!v(t.allowEnterKey))return;let n=E();if(!n||!t.input)return;let r=ye(n,t.input);if(e.target&&r&&e.target instanceof HTMLElement&&e.target.outerHTML===r.outerHTML){if([`textarea`,`file`].includes(t.input))return;L(),e.preventDefault()}},Zt=e=>{let t=e.target,n=fe(),r=-1;for(let e=0;e{let t=A(),n=O(),r=oe(),i=k();if(!t||!n||!r||!i)return;let a=[n,r,i];if(document.activeElement instanceof HTMLElement&&!a.includes(document.activeElement))return;let o=qt.includes(e)?`nextElementSibling`:`previousElementSibling`,s=document.activeElement;if(s){for(let e=0;e{e.preventDefault(),v(t.allowEscapeKey)&&n(R.esc)};var en={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap};let tn=()=>{let e=C();Array.from(document.body.children).forEach(t=>{t.contains(e)||(t.hasAttribute(`aria-hidden`)&&t.setAttribute(`data-previous-aria-hidden`,t.getAttribute(`aria-hidden`)||``),t.setAttribute(`aria-hidden`,`true`))})},nn=()=>{Array.from(document.body.children).forEach(e=>{e.hasAttribute(`data-previous-aria-hidden`)?(e.setAttribute(`aria-hidden`,e.getAttribute(`data-previous-aria-hidden`)||``),e.removeAttribute(`data-previous-aria-hidden`)):e.removeAttribute(`aria-hidden`)})},rn=typeof window<`u`&&!!window.GestureEvent,an=rn&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,on=()=>{if(rn&&!ge(document.body,l.iosfix)){let e=document.body.scrollTop;document.body.style.top=`${e*-1}px`,M(document.body,l.iosfix),sn()}},sn=()=>{let e=C();if(!e)return;let t;e.ontouchstart=e=>{t=cn(e)},e.ontouchmove=e=>{t&&(e.preventDefault(),e.stopPropagation())}},cn=e=>{let t=e.target,n=C(),r=ne();return!n||!r||ln(e)||un(e)?!1:t===n||!je(n)&&t instanceof HTMLElement&&!Me(t,r)&&t.tagName!==`INPUT`&&t.tagName!==`TEXTAREA`&&!(je(r)&&r.contains(t))},ln=e=>!!(e.touches&&e.touches.length&&e.touches[0].touchType===`stylus`),un=e=>e.touches&&e.touches.length>1,dn=()=>{if(ge(document.body,l.iosfix)){let e=parseInt(document.body.style.top,10);Se(document.body,l.iosfix),document.body.style.top=``,document.body.scrollTop=e*-1}},fn=()=>{let e=document.createElement(`div`);e.className=l[`scrollbar-measure`],document.body.appendChild(e);let t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},pn=null,mn=e=>{pn===null&&(document.body.scrollHeight>window.innerHeight||e===`scroll`)&&(pn=parseInt(window.getComputedStyle(document.body).getPropertyValue(`padding-right`)),document.body.style.paddingRight=`${pn+fn()}px`)},hn=()=>{pn!==null&&(document.body.style.paddingRight=`${pn}px`,pn=null)};function gn(e,t,n,r){me()?Tn(e,r):(s(n).then(()=>Tn(e,r)),Wt(a)),rn?(t.setAttribute(`style`,`display:none !important`),t.removeAttribute(`class`),t.innerHTML=``):t.remove(),pe()&&(hn(),dn(),nn()),_n()}function _n(){Se([document.documentElement,document.body],[l.shown,l[`height-auto`],l[`no-backdrop`],l[`toast-shown`]])}function vn(e){e=Sn(e);let t=en.swalPromiseResolve.get(this),n=yn(this);this.isAwaitingPromise?e.isDismissed||(xn(this),t(e)):n&&t(e)}let yn=e=>{let t=E();if(!t)return!1;let n=P.innerParams.get(e);if(!n||ge(t,n.hideClass.popup))return!1;Se(t,n.showClass.popup),M(t,n.hideClass.popup);let r=C();return Se(r,n.showClass.backdrop),M(r,n.hideClass.backdrop),Cn(e,t,n),!0};function bn(e){let t=en.swalPromiseReject.get(this);xn(this),t&&t(e)}let xn=e=>{e.isAwaitingPromise&&(delete e.isAwaitingPromise,P.innerParams.get(e)||e._destroy())},Sn=e=>e===void 0?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},e),Cn=(e,t,n)=>{var r;let i=C(),o=Ne(t);typeof n.willClose==`function`&&n.willClose(t),(r=a.eventEmitter)==null||r.emit(`willClose`,t),o&&i?wn(e,t,i,!!n.returnFocus,n.didClose):i&&gn(e,i,!!n.returnFocus,n.didClose)},wn=(e,t,n,r,i)=>{a.swalCloseEventFinishedCallback=gn.bind(null,e,n,r,i);let o=function(e){if(e.target===t){var n;(n=a.swalCloseEventFinishedCallback)==null||n.call(a),delete a.swalCloseEventFinishedCallback,t.removeEventListener(`animationend`,o),t.removeEventListener(`transitionend`,o)}};t.addEventListener(`animationend`,o),t.addEventListener(`transitionend`,o)},Tn=(e,t)=>{setTimeout(()=>{var n;typeof t==`function`&&t.bind(e.params)(),(n=a.eventEmitter)==null||n.emit(`didClose`),e._destroy&&e._destroy()})},En=e=>{let t=E();if(t||new hi,t=E(),!t)return;let n=ce();me()?N(D()):Dn(t,e),Te(n),t.setAttribute(`data-loading`,`true`),t.setAttribute(`aria-busy`,`true`),t.focus()},Dn=(e,t)=>{let n=A(),r=ce();!n||!r||(!t&&ke(O())&&(t=O()),Te(n),t&&(N(t),r.setAttribute(`data-button-to-replace`,t.className),n.insertBefore(r,t)),M([e,n],l.loading))},On=(e,t)=>{t.input===`select`||t.input===`radio`?Nn(e,t):[`text`,`email`,`number`,`tel`,`textarea`].some(e=>e===t.input)&&(y(t.inputValue)||x(t.inputValue))&&(En(O()),Pn(e,t))},kn=(e,t)=>{let n=e.getInput();if(!n)return null;switch(t.input){case`checkbox`:return An(n);case`radio`:return jn(n);case`file`:return Mn(n);default:return t.inputAutoTrim?n.value.trim():n.value}},An=e=>+!!e.checked,jn=e=>e.checked?e.value:null,Mn=e=>e.files&&e.files.length?e.getAttribute(`multiple`)===null?e.files[0]:e.files:null,Nn=(e,t)=>{let n=E();if(!n)return;let r=e=>{t.input===`select`?Fn(n,Ln(e),t):t.input===`radio`&&In(n,Ln(e),t)};y(t.inputOptions)||x(t.inputOptions)?(En(O()),b(t.inputOptions).then(t=>{e.hideLoading(),r(t)})):typeof t.inputOptions==`object`?r(t.inputOptions):m(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof t.inputOptions}`)},Pn=(e,t)=>{let n=e.getInput();n&&(N(n),b(t.inputValue).then(r=>{n.value=t.input===`number`?`${parseFloat(r)||0}`:`${r}`,Te(n),n.focus(),e.hideLoading()}).catch(t=>{m(`Error in inputValue promise: ${t}`),n.value=``,Te(n),n.focus(),e.hideLoading()}))};function Fn(e,t,n){let r=Ce(e,l.select);if(!r)return;let i=(e,t,r)=>{let i=document.createElement(`option`);i.value=r,j(i,t),i.selected=Rn(r,n.inputValue),e.appendChild(i)};t.forEach(e=>{let t=e[0],n=e[1];if(Array.isArray(n)){let e=document.createElement(`optgroup`);e.label=t,e.disabled=!1,r.appendChild(e),n.forEach(t=>i(e,t[1],t[0]))}else i(r,n,t)}),r.focus()}function In(e,t,n){let r=Ce(e,l.radio);if(!r)return;t.forEach(e=>{let t=e[0],i=e[1],a=document.createElement(`input`),o=document.createElement(`label`);a.type=`radio`,a.name=l.radio,a.value=t,Rn(t,n.inputValue)&&(a.checked=!0);let s=document.createElement(`span`);j(s,i),s.className=l.label,o.appendChild(a),o.appendChild(s),r.appendChild(o)});let i=r.querySelectorAll(`input`);i.length&&i[0].focus()}let Ln=e=>(e instanceof Map?Array.from(e):Object.entries(e)).map(([e,t])=>[e,typeof t==`object`?Ln(t):t]),Rn=(e,t)=>!!t&&t!=null&&t.toString()===e.toString(),zn=e=>{let t=P.innerParams.get(e);e.disableButtons(),t.input?z(e,`confirm`):Kn(e,!0)},Bn=e=>{let t=P.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?z(e,`deny`):Un(e,!1)},Vn=(e,t)=>{e.disableButtons(),t(R.cancel)},z=(e,t)=>{let n=P.innerParams.get(e);if(!n.input){m(`The "input" parameter is needed to be set when using returnInputValueOn${f(t)}`);return}let r=e.getInput(),i=kn(e,n);n.inputValidator?Hn(e,i,t):r&&!r.checkValidity()?(e.enableButtons(),e.showValidationMessage(n.validationMessage||r.validationMessage)):t===`deny`?Un(e,i):Kn(e,i)},Hn=(e,t,n)=>{let r=P.innerParams.get(e);e.disableInput(),Promise.resolve().then(()=>b(r.inputValidator(t,r.validationMessage))).then(r=>{e.enableButtons(),e.enableInput(),r?e.showValidationMessage(r):n===`deny`?Un(e,t):Kn(e,t)})},Un=(e,t)=>{let n=P.innerParams.get(e);n.showLoaderOnDeny&&En(oe()),n.preDeny?(e.isAwaitingPromise=!0,Promise.resolve().then(()=>b(n.preDeny(t,n.validationMessage))).then(n=>{n===!1?(e.hideLoading(),xn(e)):e.close({isDenied:!0,value:n===void 0?t:n})}).catch(t=>Gn(e,t))):e.close({isDenied:!0,value:t})},Wn=(e,t)=>{e.close({isConfirmed:!0,value:t})},Gn=(e,t)=>{e.rejectPromise(t)},Kn=(e,t)=>{let n=P.innerParams.get(e);n.showLoaderOnConfirm&&En(),n.preConfirm?(e.resetValidationMessage(),e.isAwaitingPromise=!0,Promise.resolve().then(()=>b(n.preConfirm(t,n.validationMessage))).then(n=>{ke(ae())||n===!1?(e.hideLoading(),xn(e)):Wn(e,n===void 0?t:n)}).catch(t=>Gn(e,t))):Wn(e,t)};function qn(){let e=P.innerParams.get(this);if(!e)return;let t=P.domCache.get(this);N(t.loader),me()?e.icon&&Te(D()):Jn(t),Se([t.popup,t.actions],l.loading),t.popup.removeAttribute(`aria-busy`),t.popup.removeAttribute(`data-loading`),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1;let n=P.focusedElement.get(this);n instanceof HTMLElement&&document.activeElement===document.body&&n.focus(),P.focusedElement.delete(this)}let Jn=e=>{let t=e.loader.getAttribute(`data-button-to-replace`),n=t?e.popup.getElementsByClassName(t):[];n.length?Te(n[0],`inline-block`):Ae()&&N(e.actions)};function Yn(){let e=P.innerParams.get(this),t=P.domCache.get(this);return t?ye(t.popup,e.input):null}function Xn(e,t,n){let r=P.domCache.get(e);t.forEach(e=>{r[e].disabled=n})}function Zn(e,t){let n=E();if(!(!n||!e))if(e.type===`radio`){let e=n.querySelectorAll(`[name="${l.radio}"]`);for(let n=0;nObject.prototype.hasOwnProperty.call(nr,e),U=e=>H.indexOf(e)!==-1,or=e=>rr[e],sr=e=>{ar(e)||p(`Unknown parameter "${e}"`)},cr=e=>{ir.includes(e)&&p(`The parameter "${e}" is incompatible with toasts`)},lr=e=>{let t=or(e);t&&_(e,t)},ur=e=>{e.backdrop===!1&&e.allowOutsideClick&&p('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),e.theme&&![`light`,`dark`,`auto`,`minimal`,`borderless`,`bootstrap-4`,`bootstrap-4-light`,`bootstrap-4-dark`,`bootstrap-5`,`bootstrap-5-light`,`bootstrap-5-dark`,`material-ui`,`material-ui-light`,`material-ui-dark`,`embed-iframe`,`bulma`,`bulma-light`,`bulma-dark`].includes(e.theme)&&p(`Invalid theme "${e.theme}"`);for(let t in e)sr(t),e.toast&&cr(t),lr(t)};function dr(e){let t=C(),n=E(),r=P.innerParams.get(this);if(!n||ge(n,r.hideClass.popup)){p(`You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.`);return}let i=fr(e),a=Object.assign({},r,i);ur(a),t&&(t.dataset.swal2Theme=a.theme),Bt(this,a),P.innerParams.set(this,a),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})}let fr=e=>{let t={};return Object.keys(e).forEach(n=>{U(n)?t[n]=e[n]:p(`Invalid parameter to update: ${n}`)}),t};function pr(){var e;let t=P.domCache.get(this),n=P.innerParams.get(this);if(!n){hr(this);return}t.popup&&a.swalCloseEventFinishedCallback&&(a.swalCloseEventFinishedCallback(),delete a.swalCloseEventFinishedCallback),typeof n.didDestroy==`function`&&n.didDestroy(),(e=a.eventEmitter)==null||e.emit(`didDestroy`),mr(this)}let mr=e=>{hr(e),delete e.params,delete a.keydownHandler,delete a.keydownTarget,delete a.currentInstance},hr=e=>{e.isAwaitingPromise?(gr(P,e),e.isAwaitingPromise=!0):(gr(en,e),gr(P,e),delete e.isAwaitingPromise,delete e.disableButtons,delete e.enableButtons,delete e.getInput,delete e.disableInput,delete e.enableInput,delete e.hideLoading,delete e.disableLoading,delete e.showValidationMessage,delete e.resetValidationMessage,delete e.close,delete e.closePopup,delete e.closeModal,delete e.closeToast,delete e.rejectPromise,delete e.update,delete e._destroy)},gr=(e,t)=>{for(let n in e)e[n].delete(t)};var _r=Object.freeze({__proto__:null,_destroy:pr,close:vn,closeModal:vn,closePopup:vn,closeToast:vn,disableButtons:$n,disableInput:tr,disableLoading:qn,enableButtons:Qn,enableInput:er,getInput:Yn,handleAwaitingPromise:xn,hideLoading:qn,rejectPromise:bn,resetValidationMessage:V,showValidationMessage:B,update:dr});let vr=(e,t,n)=>{e.toast?yr(e,t,n):(Sr(t),Cr(t),wr(e,t,n))},yr=(e,t,n)=>{t.popup.onclick=()=>{e&&(br(e)||e.timer||e.input)||n(R.close)}},br=e=>!!(e.showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton),xr=!1,Sr=e=>{e.popup.onmousedown=()=>{e.container.onmouseup=function(t){e.container.onmouseup=()=>{},t.target===e.container&&(xr=!0)}}},Cr=e=>{e.container.onmousedown=t=>{t.target===e.container&&t.preventDefault(),e.popup.onmouseup=function(t){e.popup.onmouseup=()=>{},(t.target===e.popup||t.target instanceof HTMLElement&&e.popup.contains(t.target))&&(xr=!0)}}},wr=(e,t,n)=>{t.container.onclick=r=>{if(xr){xr=!1;return}r.target===t.container&&v(e.allowOutsideClick)&&n(R.backdrop)}},Tr=e=>typeof e==`object`&&!!e&&`jquery`in e,Er=e=>e instanceof Element||Tr(e),Dr=e=>{let t={};return typeof e[0]==`object`&&!Er(e[0])?Object.assign(t,e[0]):[`title`,`html`,`icon`].forEach((n,r)=>{let i=e[r];typeof i==`string`||Er(i)?t[n]=i:i!==void 0&&m(`Unexpected type of ${n}! Expected "string" or "Element", got ${typeof i}`)}),t};function Or(...e){return new this(...e)}function kr(e){class t extends this{_main(t,n){return super._main(t,Object.assign({},e,n))}}return t}let Ar=()=>a.timeout&&a.timeout.getTimerLeft(),W=()=>{if(a.timeout)return Fe(),a.timeout.stop()},jr=()=>{if(a.timeout){let e=a.timeout.start();return Pe(e),e}},Mr=()=>{let e=a.timeout;return e&&(e.running?W():jr())},Nr=e=>{if(a.timeout){let t=a.timeout.increase(e);return Pe(t,!0),t}},Pr=()=>!!(a.timeout&&a.timeout.isRunning()),Fr=!1,Ir={};function Lr(e=`data-swal-template`){Ir[e]=this,Fr||=(document.body.addEventListener(`click`,Rr),!0)}let Rr=e=>{for(let t=e.target;t&&t!==document;t=t.parentNode)for(let e in Ir){let n=t.getAttribute&&t.getAttribute(e);if(n){Ir[e].fire({template:n});return}}};class zr{constructor(){this.events={}}_getHandlersByEventName(e){return this.events[e]===void 0&&(this.events[e]=[]),this.events[e]}on(e,t){let n=this._getHandlersByEventName(e);n.includes(t)||n.push(t)}once(e,t){let n=(...r)=>{this.removeListener(e,n),t.apply(this,r)};this.on(e,n)}emit(e,...t){this._getHandlersByEventName(e).forEach(e=>{try{e.apply(this,t)}catch(e){console.error(e)}})}removeListener(e,t){let n=this._getHandlersByEventName(e),r=n.indexOf(t);r>-1&&n.splice(r,1)}removeAllListeners(e){this.events[e]!==void 0&&(this.events[e].length=0)}reset(){this.events={}}}a.eventEmitter=new zr;var Br=Object.freeze({__proto__:null,argsToParams:Dr,bindClickHandler:Lr,clickCancel:Ut,clickConfirm:L,clickDeny:Ht,enableLoading:En,fire:Or,getActions:A,getCancelButton:k,getCloseButton:de,getConfirmButton:O,getContainer:C,getDenyButton:oe,getFocusableElements:fe,getFooter:le,getHtmlContainer:ne,getIcon:D,getIconContent:ee,getImage:re,getInputLabel:se,getLoader:ce,getPopup:E,getProgressSteps:ie,getTimerLeft:Ar,getTimerProgressBar:ue,getTitle:te,getValidationMessage:ae,increaseTimer:Nr,isDeprecatedParameter:or,isLoading:he,isTimerRunning:Pr,isUpdatableParameter:U,isValidParameter:ar,isVisible:Vt,mixin:kr,off:(e,t)=>{if(a.eventEmitter){if(!e){a.eventEmitter.reset();return}t?a.eventEmitter.removeListener(e,t):a.eventEmitter.removeAllListeners(e)}},on:(e,t)=>{a.eventEmitter&&a.eventEmitter.on(e,t)},once:(e,t)=>{a.eventEmitter&&a.eventEmitter.once(e,t)},resumeTimer:jr,showLoading:En,stopTimer:W,toggleTimer:Mr});class Vr{constructor(e,t){this.callback=e,this.remaining=t,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.started&&this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date().getTime()-this.started.getTime()),this.remaining}increase(e){let t=this.running;return t&&this.stop(),this.remaining+=e,t&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}}let Hr=[`swal-title`,`swal-html`,`swal-footer`],Ur=e=>{let t=typeof e.template==`string`?document.querySelector(e.template):e.template;if(!t)return{};let n=t.content;return G(n),Object.assign(Wr(n),Gr(n),Kr(n),qr(n),Jr(n),Yr(n),Xr(n,Hr))},Wr=e=>{let t={};return Array.from(e.querySelectorAll(`swal-param`)).forEach(e=>{Zr(e,[`name`,`value`]);let n=e.getAttribute(`name`),r=e.getAttribute(`value`);!n||!r||(n in nr&&typeof nr[n]==`boolean`?t[n]=r!==`false`:n in nr&&typeof nr[n]==`object`?t[n]=JSON.parse(r):t[n]=r)}),t},Gr=e=>{let t={};return Array.from(e.querySelectorAll(`swal-function-param`)).forEach(e=>{let n=e.getAttribute(`name`),r=e.getAttribute(`value`);!n||!r||(t[n]=Function(`return ${r}`)())}),t},Kr=e=>{let t={};return Array.from(e.querySelectorAll(`swal-button`)).forEach(e=>{Zr(e,[`type`,`color`,`aria-label`]);let n=e.getAttribute(`type`);if(!n||![`confirm`,`cancel`,`deny`].includes(n))return;t[`${n}ButtonText`]=e.innerHTML,t[`show${f(n)}Button`]=!0;let r=e.getAttribute(`color`);r!==null&&(t[`${n}ButtonColor`]=r);let i=e.getAttribute(`aria-label`);i!==null&&(t[`${n}ButtonAriaLabel`]=i)}),t},qr=e=>{let t={},n=e.querySelector(`swal-image`);if(n){Zr(n,[`src`,`width`,`height`,`alt`]);let e=n.getAttribute(`src`);e!==null&&(t.imageUrl=e||void 0);let r=n.getAttribute(`width`);r!==null&&(t.imageWidth=r||void 0);let i=n.getAttribute(`height`);i!==null&&(t.imageHeight=i||void 0);let a=n.getAttribute(`alt`);a!==null&&(t.imageAlt=a||void 0)}return t},Jr=e=>{let t={},n=e.querySelector(`swal-icon`);return n&&(Zr(n,[`type`,`color`]),n.hasAttribute(`type`)&&(t.icon=n.getAttribute(`type`)),n.hasAttribute(`color`)&&(t.iconColor=n.getAttribute(`color`)),t.iconHtml=n.innerHTML),t},Yr=e=>{let t={},n=e.querySelector(`swal-input`);n&&(Zr(n,[`type`,`label`,`placeholder`,`value`]),t.input=n.getAttribute(`type`)||`text`,n.hasAttribute(`label`)&&(t.inputLabel=n.getAttribute(`label`)),n.hasAttribute(`placeholder`)&&(t.inputPlaceholder=n.getAttribute(`placeholder`)),n.hasAttribute(`value`)&&(t.inputValue=n.getAttribute(`value`)));let r=Array.from(e.querySelectorAll(`swal-input-option`));return r.length&&(t.inputOptions={},r.forEach(e=>{Zr(e,[`value`]);let n=e.getAttribute(`value`);if(!n)return;let r=e.innerHTML;t.inputOptions[n]=r})),t},Xr=(e,t)=>{let n={};for(let r in t){let i=t[r],a=e.querySelector(i);a&&(Zr(a,[]),n[i.replace(/^swal-/,``)]=a.innerHTML.trim())}return n},G=e=>{let t=Hr.concat([`swal-param`,`swal-function-param`,`swal-button`,`swal-image`,`swal-icon`,`swal-input`,`swal-input-option`]);Array.from(e.children).forEach(e=>{let n=e.tagName.toLowerCase();t.includes(n)||p(`Unrecognized element <${n}>`)})},Zr=(e,t)=>{Array.from(e.attributes).forEach(n=>{t.indexOf(n.name)===-1&&p([`Unrecognized attribute "${n.name}" on <${e.tagName.toLowerCase()}>.`,`${t.length?`Allowed attributes are: ${t.join(`, `)}`:`To set the value, use HTML within the element.`}`])})},Qr=e=>{var t,n;let r=C(),i=E();if(!r||!i)return;typeof e.willOpen==`function`&&e.willOpen(i),(t=a.eventEmitter)==null||t.emit(`willOpen`,i);let o=window.getComputedStyle(document.body).overflowY;if(ni(r,i,e),setTimeout(()=>{ei(r,i)},10),pe()&&(ti(r,e.scrollbarPadding===void 0?!1:e.scrollbarPadding,o),tn()),an&&e.backdrop===!1&&i.scrollHeight>r.clientHeight&&(r.style.pointerEvents=`auto`),!me()&&!a.previousActiveElement&&(a.previousActiveElement=document.activeElement),typeof e.didOpen==`function`){let t=e.didOpen;setTimeout(()=>t(i))}(n=a.eventEmitter)==null||n.emit(`didOpen`,i)},$r=e=>{let t=E();if(!t||e.target!==t)return;let n=C();n&&(t.removeEventListener(`animationend`,$r),t.removeEventListener(`transitionend`,$r),n.style.overflowY=`auto`,Se(n,l[`no-transition`]))},ei=(e,t)=>{Ne(t)?(e.style.overflowY=`hidden`,t.addEventListener(`animationend`,$r),t.addEventListener(`transitionend`,$r)):e.style.overflowY=`auto`},ti=(e,t,n)=>{on(),t&&n!==`hidden`&&mn(n),setTimeout(()=>{e.scrollTop=0})},ni=(e,t,n)=>{var r;(r=n.showClass)!=null&&r.backdrop&&M(e,n.showClass.backdrop),n.animation?(t.style.setProperty(`opacity`,`0`,`important`),Te(t,`grid`),setTimeout(()=>{var e;(e=n.showClass)!=null&&e.popup&&M(t,n.showClass.popup),t.style.removeProperty(`opacity`)},10)):Te(t,`grid`),M([document.documentElement,document.body],l.shown),n.heightAuto&&n.backdrop&&!n.toast&&M([document.documentElement,document.body],l[`height-auto`])};var K={email:(e,t)=>/^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(e)?Promise.resolve():Promise.resolve(t||`Invalid email address`),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||`Invalid URL`)};function ri(e){e.inputValidator||(e.input===`email`&&(e.inputValidator=K.email),e.input===`url`&&(e.inputValidator=K.url))}function ii(e){(!e.target||typeof e.target==`string`&&!document.querySelector(e.target)||typeof e.target!=`string`&&!e.target.appendChild)&&(p(`Target parameter is not valid, defaulting to "body"`),e.target=`body`)}function ai(e){ri(e),e.showLoaderOnConfirm&&!e.preConfirm&&p(`showLoaderOnConfirm is set to true, but preConfirm is not defined. -showLoaderOnConfirm should be used together with preConfirm, see usage example: -https://sweetalert2.github.io/#ajax-request`),ii(e),typeof e.title==`string`&&(e.title=e.title.split(` -`).join(`
`)),We(e)}let oi;var si=new WeakMap;class q{constructor(...e){if(r(this,si,Promise.resolve({isConfirmed:!1,isDenied:!1,isDismissed:!0})),typeof window>`u`)return;oi=this;let t=Object.freeze(this.constructor.argsToParams(e));this.params=t,this.isAwaitingPromise=!1,i(si,this,this._main(oi.params))}_main(e,t={}){if(ur(Object.assign({},t,e)),a.currentInstance){let e=en.swalPromiseResolve.get(a.currentInstance),{isAwaitingPromise:t}=a.currentInstance;a.currentInstance._destroy(),t||e({isDismissed:!0}),pe()&&nn()}a.currentInstance=oi;let n=li(e,t);ai(n),Object.freeze(n),a.timeout&&(a.timeout.stop(),delete a.timeout),clearTimeout(a.restoreFocusTimeout);let r=ui(oi);return Bt(oi,n),P.innerParams.set(oi,n),ci(oi,r,n)}then(e){return n(si,this).then(e)}finally(e){return n(si,this).finally(e)}}let ci=(e,t,n)=>new Promise((r,i)=>{let o=t=>{e.close({isDismissed:!0,dismiss:t,isConfirmed:!1,isDenied:!1})};en.swalPromiseResolve.set(e,r),en.swalPromiseReject.set(e,i),t.confirmButton.onclick=()=>{zn(e)},t.denyButton.onclick=()=>{Bn(e)},t.cancelButton.onclick=()=>{Vn(e,o)},t.closeButton.onclick=()=>{o(R.close)},vr(n,t,o),Gt(a,n,o),On(e,n),Qr(n),di(a,n,o),fi(t,n),setTimeout(()=>{t.container.scrollTop=0})}),li=(e,t)=>{let n=Ur(e),r=Object.assign({},nr,t,n,e);return r.showClass=Object.assign({},nr.showClass,r.showClass),r.hideClass=Object.assign({},nr.hideClass,r.hideClass),r.animation===!1&&(r.showClass={backdrop:`swal2-noanimation`},r.hideClass={}),r},ui=e=>{let t={popup:E(),container:C(),actions:A(),confirmButton:O(),denyButton:oe(),cancelButton:k(),loader:ce(),closeButton:de(),validationMessage:ae(),progressSteps:ie()};return P.domCache.set(e,t),t},di=(e,t,n)=>{let r=ue();N(r),t.timer&&(e.timeout=new Vr(()=>{n(`timer`),delete e.timeout},t.timer),t.timerProgressBar&&r&&(Te(r),ve(r,t,`timerProgressBar`),setTimeout(()=>{e.timeout&&e.timeout.running&&Pe(t.timer)})))},fi=(e,t)=>{if(!t.toast){if(!v(t.allowEnterKey)){_(`allowEnterKey`,`preConfirm: () => false`),e.popup.focus();return}pi(e)||mi(e,t)||Kt(-1,1)}},pi=e=>{let t=Array.from(e.popup.querySelectorAll(`[autofocus]`));for(let e of t)if(e instanceof HTMLElement&&ke(e))return e.focus(),!0;return!1},mi=(e,t)=>t.focusDeny&&ke(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&ke(e.cancelButton)?(e.cancelButton.focus(),!0):t.focusConfirm&&ke(e.confirmButton)?(e.confirmButton.focus(),!0):!1;q.prototype.disableButtons=$n,q.prototype.enableButtons=Qn,q.prototype.getInput=Yn,q.prototype.disableInput=tr,q.prototype.enableInput=er,q.prototype.hideLoading=qn,q.prototype.disableLoading=qn,q.prototype.showValidationMessage=B,q.prototype.resetValidationMessage=V,q.prototype.close=vn,q.prototype.closePopup=vn,q.prototype.closeModal=vn,q.prototype.closeToast=vn,q.prototype.rejectPromise=bn,q.prototype.update=dr,q.prototype._destroy=pr,Object.assign(q,Br),Object.keys(_r).forEach(e=>{q[e]=function(...t){if(oi&&oi[e])return oi[e](...t)}}),q.DismissReason=R,q.version=`11.26.24`;let hi=q;return hi.default=hi,hi})),e!==void 0&&e.Sweetalert2&&(e.swal=e.sweetAlert=e.Swal=e.SweetAlert=e.Sweetalert2),typeof document<`u`&&function(e,t){var n=e.createElement(`style`);if(e.getElementsByTagName(`head`)[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch{n.innerText=t}}(document,`:root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:auto}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:auto}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}`)})),sr=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),cr=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),lr=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),ur=e=>{let t=lr(e);return t.charAt(0).toUpperCase()+t.slice(1)},dr={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},fr=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},pr=(0,_.createContext)({}),mr=()=>(0,_.useContext)(pr),hr=(0,_.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>{let{size:l=24,strokeWidth:u=2,absoluteStrokeWidth:d=!1,color:f=`currentColor`,className:p=``}=mr()??{},m=r??d?Number(n??u)*24/Number(t??l):n??u;return(0,_.createElement)(`svg`,{ref:c,...dr,width:t??l??dr.width,height:t??l??dr.height,stroke:e??f,strokeWidth:m,className:sr(`lucide`,p,i),...!a&&!fr(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,_.createElement)(e,t)),...Array.isArray(a)?a:[a]])}),gr=(e,t)=>{let n=(0,_.forwardRef)(({className:n,...r},i)=>(0,_.createElement)(hr,{ref:i,iconNode:t,className:sr(`lucide-${cr(ur(e))}`,`lucide-${e}`,n),...r}));return n.displayName=ur(e),n},_r=gr(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]),vr=gr(`dices`,[[`rect`,{width:`12`,height:`12`,x:`2`,y:`10`,rx:`2`,ry:`2`,key:`6agr2n`}],[`path`,{d:`m17.92 14 3.5-3.5a2.24 2.24 0 0 0 0-3l-5-4.92a2.24 2.24 0 0 0-3 0L10 6`,key:`1o487t`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M10 14h.01`,key:`ssrbsk`}],[`path`,{d:`M15 6h.01`,key:`cblpky`}],[`path`,{d:`M18 9h.01`,key:`2061c0`}]]),yr=gr(`grid-3x3`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`M3 15h18`,key:`5xshup`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}]]),br=gr(`hash`,[[`line`,{x1:`4`,x2:`20`,y1:`9`,y2:`9`,key:`4lhtct`}],[`line`,{x1:`4`,x2:`20`,y1:`15`,y2:`15`,key:`vyu0kd`}],[`line`,{x1:`10`,x2:`8`,y1:`3`,y2:`21`,key:`1ggp8o`}],[`line`,{x1:`16`,x2:`14`,y1:`3`,y2:`21`,key:`weycgp`}]]),xr=gr(`minus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}]]),Sr=gr(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]),Cr=gr(`rotate-ccw`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]]),wr=gr(`square`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]),Tr=gr(`star`,[[`path`,{d:`M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z`,key:`r04s7s`}]]),Er=gr(`swatch-book`,[[`path`,{d:`M11 17a4 4 0 0 1-8 0V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2Z`,key:`1ldrpk`}],[`path`,{d:`M16.7 13H19a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H7`,key:`11i5po`}],[`path`,{d:`M 7 17h.01`,key:`1euzgo`}],[`path`,{d:`m11 8 2.3-2.3a2.4 2.4 0 0 1 3.404.004L18.6 7.6a2.4 2.4 0 0 1 .026 3.434L9.9 19.8`,key:`o2gii7`}]]),Dr=gr(`timer`,[[`line`,{x1:`10`,x2:`14`,y1:`2`,y2:`2`,key:`14vaq8`}],[`line`,{x1:`12`,x2:`15`,y1:`14`,y2:`11`,key:`17fdiu`}],[`circle`,{cx:`12`,cy:`14`,r:`8`,key:`1e1u0o`}]]),Or=gr(`trophy`,[[`path`,{d:`M10 14.66v1.626a2 2 0 0 1-.976 1.696A5 5 0 0 0 7 21.978`,key:`1n3hpd`}],[`path`,{d:`M14 14.66v1.626a2 2 0 0 0 .976 1.696A5 5 0 0 1 17 21.978`,key:`rfe1zi`}],[`path`,{d:`M18 9h1.5a1 1 0 0 0 0-5H18`,key:`7xy6bh`}],[`path`,{d:`M4 22h16`,key:`57wxv0`}],[`path`,{d:`M6 9a6 6 0 0 0 12 0V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1z`,key:`1mhfuq`}],[`path`,{d:`M6 9H4.5a1 1 0 0 1 0-5H6`,key:`tex48p`}]]),kr=gr(`user`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),Ar=gr(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),W=l(or()),jr=({title:e,description:t,onClick:n,icon:r})=>(0,H.jsxs)(`div`,{onClick:n,className:`group relative p-4 sm:p-8 rounded-xl sm:rounded-2xl glass cursor-pointer transition-all duration-500 hover:scale-105 hover:-translate-y-2`,children:[(0,H.jsx)(`div`,{className:`absolute inset-0 bg-gradient-to-br from-white/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity rounded-xl sm:rounded-2xl`}),(0,H.jsx)(`div`,{className:`mb-2 sm:mb-4 text-blue-600 transition-transform duration-500 group-hover:rotate-12 group-hover:scale-110`,children:(0,H.jsx)(r,{size:32,className:`sm:size-48`,strokeWidth:1.5})}),(0,H.jsx)(`h3`,{className:`text-lg sm:text-2xl font-bold mb-1 sm:mb-2 hand-drawn text-gray-800`,children:e}),(0,H.jsx)(`p`,{className:`text-xs sm:text-gray-600 paper-font text-[10px] sm:text-base`,children:t})]}),Mr=()=>{let{playerName:e,setPlayerName:t}=ir(),n=He();return(0,_.useEffect)(()=>{e||W.default.fire({title:`Welcome to PaperParty!`,text:`What is your name, player?`,input:`text`,inputPlaceholder:`Enter your name...`,allowOutsideClick:!1,confirmButtonText:`Let's Play!`,customClass:{popup:`glass rounded-3xl paper-font`,title:`hand-drawn text-3xl`,confirmButton:`bg-blue-500/80 hover:bg-blue-500 px-8 py-3 rounded-xl font-bold transition-all`},buttonsStyling:!1,inputValidator:e=>{if(!e)return`We need a name to start the party!`}}).then(e=>{e.isConfirmed&&t(e.value)})},[e,t]),(0,H.jsxs)(`div`,{className:`min-h-screen flex flex-col items-center justify-center p-2 sm:p-4`,children:[(0,H.jsxs)(`div`,{className:`text-center mb-6 sm:mb-16`,children:[(0,H.jsx)(`h1`,{className:`text-4xl sm:text-6xl md:text-7xl lg:text-9xl hand-drawn mb-2 sm:mb-4 text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600 animate-pulse`,children:`PaperParty`}),(0,H.jsx)(`p`,{className:`text-sm sm:text-xl md:text-2xl paper-font text-gray-600 max-w-2xl mx-auto`,children:`Multiplayer games that feel like the back of your notebook.`})]}),(0,H.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-8 max-w-5xl w-full px-2 sm:px-0`,children:[(0,H.jsx)(jr,{title:`Bingo`,description:`The classic 5x5 numbers game. Race to cross out your lines!`,icon:br,onClick:()=>n(`/bingo`)}),(0,H.jsx)(jr,{title:`Tic Tac Toe`,description:`Strategize and outsmart your opponent in this timeless 3x3 battle.`,icon:vr,onClick:()=>n(`/tictactoe`)}),(0,H.jsx)(jr,{title:`Ultimate Tic-Tac-Toe`,description:`The mind-bending 9x9 grid where every move sends your opponent to a new battlefield!`,icon:yr,onClick:()=>n(`/uttt`)}),(0,H.jsx)(jr,{title:`Dots & Boxes`,description:`Connect the dots and claim boxes in this classic strategy game!`,icon:wr,onClick:()=>n(`/dab`)})]}),e&&(0,H.jsxs)(`div`,{className:`mt-6 sm:mt-12 paper-font text-gray-500 glass px-4 sm:px-6 py-1 sm:py-2 rounded-full flex items-center gap-1 sm:gap-2 text-xs sm:text-base`,children:[(0,H.jsx)(kr,{size:14,className:`sm:w-[18px] text-blue-600`}),(0,H.jsxs)(`span`,{children:[`Playing as `,(0,H.jsx)(`span`,{className:`font-bold text-blue-600`,children:e})]})]})]})},Nr=`modulepreload`,Pr=function(e){return`/`+e},Fr={},Ir=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=Pr(t,n),t in Fr)return;Fr[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:Nr,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};function Lr(){return Lr=Object.assign?Object.assign.bind():function(e){for(var t=1;timport(`./howler-CESL1Llt.js`).then(e=>l(e.default)).then(function(t){h.current||(m.current=t.Howl??t.default.Howl,h.current=!0,new m.current(Lr({src:Array.isArray(e)?e:[e],volume:i,rate:o,onload:C},p)))}),[]),function(){h.current=!1}}),_.useEffect(function(){m.current&&x&&S(new m.current(Lr({src:Array.isArray(e)?e:[e],volume:i,onload:C},p)))},[JSON.stringify(e)]),_.useEffect(function(){x&&(x.volume(i),p.sprite||x.rate(o))},[x,i,o]),[_.useCallback(function(e){e===void 0&&(e={}),!(!x||!c&&!e.forceSoundEnabled)&&(d&&x.stop(),e.playbackRate&&x.rate(e.playbackRate),x.play(e.id))},[x,c,d]),{sound:x,stop:_.useCallback(function(e){x&&x.stop(e)},[x]),pause:_.useCallback(function(e){x&&x.pause(e)},[x]),duration:v}]}var Hr={};(function e(t,n,r,i){var a=!!(t.Worker&&t.Blob&&t.Promise&&t.OffscreenCanvas&&t.OffscreenCanvasRenderingContext2D&&t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype.transferControlToOffscreen&&t.URL&&t.URL.createObjectURL),o=typeof Path2D==`function`&&typeof DOMMatrix==`function`,s=(function(){if(!t.OffscreenCanvas)return!1;try{var e=new OffscreenCanvas(1,1),n=e.getContext(`2d`);n.fillRect(0,0,1,1);var r=e.transferToImageBitmap();n.createPattern(r,`no-repeat`)}catch{return!1}return!0})();function c(){}function l(e){var r=n.exports.Promise,i=r===void 0?t.Promise:r;return typeof i==`function`?new i(e):(e(c,c),null)}var u=(function(e,t){return{transform:function(n){if(e)return n;if(t.has(n))return t.get(n);var r=new OffscreenCanvas(n.width,n.height);return r.getContext(`2d`).drawImage(n,0,0),t.set(n,r),r},clear:function(){t.clear()}}})(s,new Map),d=function(){var e=16,t,n,r={},i=0;return typeof requestAnimationFrame==`function`&&typeof cancelAnimationFrame==`function`?(t=function(t){var n=Math.random();return r[n]=requestAnimationFrame(function a(o){i===o||i+e-1{let{socket:e,playerName:t,roomId:n,setRoomId:r}=ir(),[i,a]=(0,_.useState)(()=>Array.from({length:25},(e,t)=>t+1).sort(()=>Math.random()-.5)),[o,s]=(0,_.useState)([]),[c,l]=(0,_.useState)(`waiting`),[u,d]=(0,_.useState)(null),[f,p]=(0,_.useState)(!1),[m,h]=(0,_.useState)(``),[g,v]=(0,_.useState)(30),y=He(),[b]=Vr(`/sounds/pop.mp3`,{volume:.5}),[x]=Vr(`/sounds/win.mp3`,{volume:.7}),[S]=Vr(`/sounds/turn.mp3`,{volume:.6});(0,_.useEffect)(()=>{let e;return c===`playing`&&g>0&&(e=setInterval(()=>{v(e=>e-1)},1e3)),()=>clearInterval(e)},[c,g]),(0,_.useEffect)(()=>{if(e)return e.on(`bingo_roomInfo`,({id:t,creator:n,players:i,gameState:a,currentTurn:o})=>{r(t),s(i),l(a),d(o),p(n===e.id)}),e.on(`bingo_gameStarted`,e=>{l(`playing`),d(e),v(30),W.default.fire({title:`Eyes Down!`,text:`Bingo has started!`,timer:1500,showConfirmButton:!1,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`bingo_gameRestarted`,()=>{a(Array.from({length:25},(e,t)=>t+1).sort(()=>Math.random()-.5)),h(``),l(`ready`),W.default.fire({title:`Game Restarted`,text:`New card generated!`,timer:1500,showConfirmButton:!1,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`bingo_numberMarked`,({number:e,playerId:t})=>{a(t=>t.map(t=>t===e?`X`:t)),b()}),e.on(`bingo_nextTurn`,t=>{d(t),v(30),t===e.id&&S()}),e.on(`bingo_playerWon`,e=>{x(),Ur({particleCount:150,spread:70,origin:{y:.6}});let t=o.find(t=>t.id===e)?.name||`Someone`;W.default.fire({title:`BINGO!`,text:`${t} has achieved Bingo!`,icon:`success`,customClass:{popup:`glass rounded-3xl paper-font`}}),l(`ended`)}),e.on(`bingo_playerLeft`,e=>{W.default.fire({title:`Player Left`,text:`A player has left the game.`,icon:`warning`,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`bingo_alert`,({icon:e,title:t,text:n})=>{W.default.fire({icon:e,title:t,text:n,customClass:{popup:`glass rounded-3xl paper-font`}})}),()=>{e.off(`bingo_roomInfo`),e.off(`bingo_gameStarted`),e.off(`bingo_gameRestarted`),e.off(`bingo_numberMarked`),e.off(`bingo_nextTurn`),e.off(`bingo_playerWon`),e.off(`bingo_playerLeft`),e.off(`bingo_alert`)}},[e,o,r,b,x,S]);let C=(0,_.useCallback)(()=>{let t=[];for(let e=0;e<5;e++)t.push(Array.from({length:5},(t,n)=>e*5+n));for(let e=0;e<5;e++)t.push(Array.from({length:5},(t,n)=>e+n*5));t.push(Array.from({length:5},(e,t)=>t*5+t)),t.push(Array.from({length:5},(e,t)=>(t+1)*5-(t+1)));let r=t.filter(e=>e.every(e=>i[e]===`X`)).length,a=`BINGO`.slice(0,Math.min(r,5));a.length>m.length&&(h(a),a===`BINGO`&&e.emit(`bingo_achieved`,n))},[i,m,n,e]);(0,_.useEffect)(()=>{C()},[i,C]);let w=t=>{c===`playing`&&u===e?.id&&t!==`X`&&e.emit(`bingo_markNumber`,{roomId:n,number:t})};return(0,H.jsxs)(`div`,{className:`min-h-screen flex flex-col items-center justify-center p-4`,children:[(0,H.jsxs)(U,{onClick:()=>y(`/`),variant:`secondary`,className:`absolute top-8 left-8 flex items-center gap-2`,children:[(0,H.jsx)(_r,{size:18}),`Back`]}),(0,H.jsx)(`h1`,{className:`text-6xl hand-drawn mb-8 text-purple-600`,children:`Bingo Party`}),n?(0,H.jsxs)(`div`,{className:`w-full max-w-4xl flex flex-col md:flex-row gap-8 items-start`,children:[(0,H.jsxs)(`div`,{className:`flex-1 w-full`,children:[(0,H.jsxs)(`div`,{className:`glass p-4 rounded-2xl mb-8 flex justify-between items-center`,children:[(0,H.jsxs)(`div`,{className:`paper-font text-gray-600 flex items-center gap-2`,children:[(0,H.jsx)(Er,{size:18,className:`text-purple-500`}),`Room: `,(0,H.jsx)(`span`,{className:`font-bold text-purple-600 uppercase`,children:n})]}),(0,H.jsx)(`div`,{className:`flex gap-2`,children:`BINGO`.split(``).map((e,t)=>(0,H.jsx)(`span`,{className:`w-8 h-8 flex items-center justify-center rounded-lg font-bold transition-all duration-500 - ${t(0,H.jsx)(`button`,{onClick:()=>w(t),disabled:t===`X`||c!==`playing`||u!==e?.id,className:`glass text-xl md:text-3xl paper-font flex items-center justify-center transition-all duration-300 rounded-xl - ${t===`X`?`bg-purple-500/50 text-white rotate-12`:`hover:bg-white/40 cursor-pointer`} - ${c===`playing`&&u===e?.id&&t!==`X`?`ring-2 ring-purple-400 ring-offset-2`:``}`,children:t===`X`?`★`:t},n))})]}),(0,H.jsxs)(`div`,{className:`w-full md:w-64 flex flex-col gap-6`,children:[(0,H.jsxs)(`div`,{className:`glass p-6 rounded-2xl`,children:[(0,H.jsxs)(`h3`,{className:`hand-drawn text-2xl mb-4 flex items-center gap-2`,children:[(0,H.jsx)(Ar,{size:24,className:`text-purple-500`}),`Players`]}),(0,H.jsx)(`div`,{className:`flex flex-col gap-3`,children:o.map(e=>(0,H.jsxs)(`div`,{className:`flex items-center justify-between p-2 rounded-lg transition-all - ${e.id===u?`bg-purple-100 scale-105`:`opacity-70`}`,children:[(0,H.jsx)(`span`,{className:`font-bold paper-font truncate flex-1`,children:e.name}),e.id===u&&(0,H.jsx)(Ar,{size:16,className:`text-purple-500 animate-pulse`})]},e.id))})]}),f&&c===`ready`&&(0,H.jsx)(U,{onClick:()=>{if(o.length<2){W.default.fire({title:`Wait!`,text:`Need at least 2 players!`,icon:`info`});return}e.emit(`bingo_startGame`,n)},variant:`success`,className:`w-full text-xl py-4 animate-pulse flex items-center justify-center gap-2`,children:`🚀 Start Party!`}),c===`playing`&&(0,H.jsxs)(`div`,{className:`glass p-6 rounded-2xl text-center`,children:[(0,H.jsxs)(`div`,{className:`text-sm paper-font text-gray-500 mb-1 flex items-center justify-center gap-1`,children:[(0,H.jsx)(Dr,{size:14}),`Time Remaining`]}),(0,H.jsxs)(`div`,{className:`text-4xl font-bold paper-font ${g<10?`text-red-500 animate-ping`:`text-purple-600`}`,children:[g,`s`]}),u===e?.id&&(0,H.jsxs)(`div`,{className:`mt-2 text-purple-600 flex items-center justify-center gap-1 text-sm animate-bounce`,children:[(0,H.jsx)(Or,{size:14}),`Your Turn!`]})]})]})]}):(0,H.jsxs)(`div`,{className:`flex gap-4`,children:[(0,H.jsx)(U,{onClick:()=>{e.emit(`bingo_createRoom`,t)},children:`Create Room`}),(0,H.jsx)(U,{onClick:async()=>{let{value:n}=await W.default.fire({title:`Join Bingo Room`,input:`text`,inputPlaceholder:`Enter Room ID`,showCancelButton:!0,customClass:{popup:`glass rounded-3xl paper-font`}});n&&e.emit(`bingo_joinRoom`,{roomId:n.toUpperCase(),playerName:t})},variant:`secondary`,children:`Join Room`})]})]})},Gr=()=>{let{socket:e,playerName:t,roomId:n,setRoomId:r}=ir(),[i,a]=(0,_.useState)(Array(9).fill(null)),[o,s]=(0,_.useState)([]),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)(`waiting`),[f,p]=(0,_.useState)([]),[m,h]=(0,_.useState)(null),g=He(),[v]=Vr(`/sounds/move.mp3`,{volume:.5}),[y]=Vr(`/sounds/win.mp3`,{volume:.7});return(0,_.useEffect)(()=>{if(e)return V.info(`TTT`,`Socket connected: ${e.id}`),e.on(`ttt_roomInfo`,({id:t,players:n,gameState:i,currentTurn:o,board:c})=>{V.socket(`⬅️`,`ttt_roomInfo`,{roomId:t,gameState:i}),r(t),s(n),d(i),l(o),c&&a(c);let u=n.findIndex(t=>t.id===e.id);u!==-1&&h(u===0?`X`:`O`)}),e.on(`ttt_gameStarted`,()=>{V.socket(`⬅️`,`ttt_gameStarted`,`Game started`),d(`playing`),p([]),W.default.fire({title:`Game Started!`,text:`The battle begins!`,timer:1500,showConfirmButton:!1,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`ttt_gameRestarted`,()=>{V.socket(`⬅️`,`ttt_gameRestarted`,`Game restarted`),d(`playing`),p([]),a(Array(9).fill(null)),W.default.fire({title:`Game Restarted`,text:`Round 2!`,timer:1500,showConfirmButton:!1,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`ttt_moveMade`,({position:e,symbol:t,board:n})=>{V.socket(`⬅️`,`ttt_moveMade`,{position:e,symbol:t}),v(),a(n)}),e.on(`ttt_nextTurn`,e=>{V.socket(`⬅️`,`ttt_nextTurn`,{playerId:e}),l(e)}),e.on(`ttt_gameWon`,({winner:e,winningLine:t})=>{V.socket(`⬅️`,`ttt_gameWon`,{winner:e,winningLine:t}),y(),p(t),Ur({particleCount:150,spread:70,origin:{y:.6}});let n=o.find(t=>t.id===e)?.name||`Someone`;W.default.fire({title:`🎉 Victory!`,text:`${n} has won!`,icon:`success`,customClass:{popup:`glass rounded-3xl paper-font`}}),d(`ended`)}),e.on(`ttt_gameDraw`,()=>{V.socket(`⬅️`,`ttt_gameDraw`,`Draw!`),W.default.fire({title:`🤝 Draw!`,text:`It's a tie!`,icon:`info`,customClass:{popup:`glass rounded-3xl paper-font`}}),d(`ended`)}),e.on(`ttt_playerLeft`,e=>{V.socket(`⬅️`,`ttt_playerLeft`,{playerId:e}),W.default.fire({title:`Player Left`,text:`The opponent has left the party.`,icon:`warning`,customClass:{popup:`glass rounded-3xl paper-font`}}),d(`waiting`),a(Array(9).fill(null))}),e.on(`ttt_alert`,({icon:e,title:t,text:n})=>{V.socket(`⬅️`,`ttt_alert`,{icon:e,title:t,text:n}),W.default.fire({icon:e,title:t,text:n,customClass:{popup:`glass rounded-3xl paper-font`}})}),()=>{e.off(`ttt_roomInfo`),e.off(`ttt_gameStarted`),e.off(`ttt_gameRestarted`),e.off(`ttt_moveMade`),e.off(`ttt_nextTurn`),e.off(`ttt_gameWon`),e.off(`ttt_gameDraw`),e.off(`ttt_playerLeft`),e.off(`ttt_alert`)}},[e,o,r,v,y]),(0,H.jsxs)(`div`,{className:`min-h-screen flex flex-col items-center justify-center p-2 sm:p-4`,children:[(0,H.jsxs)(U,{onClick:()=>g(`/`),variant:`secondary`,className:`absolute top-2 sm:top-8 left-2 sm:left-8 flex items-center gap-1 sm:gap-2 text-xs sm:text-base px-2 sm:px-4`,children:[(0,H.jsx)(_r,{size:14,className:`sm:w-[18px]`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Back`})]}),(0,H.jsx)(`h1`,{className:`text-3xl sm:text-5xl md:text-6xl hand-drawn mb-4 sm:mb-8 text-blue-600`,children:`Tic Tac Toe`}),n?(0,H.jsxs)(`div`,{className:`w-full max-w-sm sm:max-w-md`,children:[(0,H.jsxs)(`div`,{className:`glass p-2 sm:p-4 rounded-xl sm:rounded-2xl mb-4 sm:mb-8 flex flex-col sm:flex-row justify-between items-center gap-2 sm:gap-4`,children:[(0,H.jsxs)(`div`,{className:`paper-font text-gray-600 flex items-center gap-1 sm:gap-2 text-xs sm:text-base`,children:[(0,H.jsx)(Er,{size:14,className:`sm:w-[18px] text-blue-500`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Room:`}),(0,H.jsx)(`span`,{className:`font-bold text-blue-600 uppercase`,children:n})]}),(0,H.jsx)(`div`,{className:`flex gap-2 sm:gap-4 text-xs sm:text-sm`,children:o.map((e,t)=>(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 transition-all duration-300 ${e.id===c?`scale-105`:`opacity-60`}`,children:[e.id===c?(0,H.jsx)(Ar,{size:12,className:`sm:w-4 text-blue-500 animate-pulse`}):(0,H.jsx)(`div`,{className:`w-2 h-2 sm:w-3 sm:h-3 rounded-full ${t===0?`bg-blue-500`:`bg-red-500`}`}),(0,H.jsx)(`span`,{className:`font-bold paper-font`,children:e.name.length>8?e.name.slice(0,8)+`...`:e.name})]},e.id))})]}),(0,H.jsx)(`div`,{className:`text-center paper-font text-xs sm:text-lg text-gray-700 flex flex-col items-center gap-2`,children:u===`playing`?c===e?.id?(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 text-blue-600 animate-bounce`,children:[(0,H.jsx)(Or,{size:16,className:`sm:w-6`}),(0,H.jsx)(`span`,{children:`Your turn!`})]}):(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2`,children:[(0,H.jsx)(`div`,{className:`w-3 h-3 sm:w-4 sm:h-4 border-2 border-blue-600 border-t-transparent rounded-full animate-spin`}),(0,H.jsxs)(`span`,{className:`hidden sm:inline`,children:[`Waiting for `,o.find(e=>e.id===c)?.name,`...`]}),(0,H.jsx)(`span`,{className:`sm:hidden`,children:`Waiting...`})]}):u===`waiting`?`Waiting for opponent...`:`Game Over!`})]}):(0,H.jsxs)(`div`,{className:`flex gap-2 sm:gap-4 flex-wrap justify-center`,children:[(0,H.jsx)(U,{onClick:()=>{V.socket(`➡️`,`ttt_createRoom`,{playerName:t}),e.emit(`ttt_createRoom`,t)},className:`text-sm sm:text-base px-3 sm:px-6 py-2`,children:`Create`}),(0,H.jsx)(U,{onClick:async()=>{let{value:n}=await W.default.fire({title:`Join Room`,input:`text`,inputPlaceholder:`Enter Room ID`,showCancelButton:!0,customClass:{popup:`glass rounded-3xl paper-font`}});n&&(V.socket(`➡️`,`ttt_joinRoom`,{roomId:n.toUpperCase(),playerName:t}),e.emit(`ttt_joinRoom`,{roomId:n.toUpperCase(),playerName:t}))},variant:`secondary`,className:`text-sm sm:text-base px-3 sm:px-6 py-2`,children:`Join`})]})]})},Kr=({gridIndex:e,gridData:t,macroWinner:n,isActive:r,isLastMoveGrid:i,lastMoveSquare:a,onSquareClick:o})=>{let s=()=>{let e=`relative rounded transition-all duration-300`;return n===`DEAD`?`${e} bg-gray-100/80`:n?`${e} ${n===`X`?`bg-blue-50/80`:`bg-red-50/80`}`:r?`${e} bg-white/90 ring-2 ring-blue-400 shadow-lg`:`${e} bg-white/40 opacity-60`},c=e=>{let s=t[e];return(0,H.jsx)(`button`,{onClick:()=>o(e),disabled:!r||s!==null||n!==null,className:` - relative aspect-square flex items-center justify-center - text-xs sm:text-sm md:text-2xl font-bold hand-drawn transition-all duration-150 - ${!r||s!==null||n!==null?`cursor-not-allowed`:`hover:bg-blue-200/50 cursor-pointer active:scale-95`} - ${i&&a===e?`bg-yellow-300/70 ring-2 ring-yellow-500`:``} - ${s===`X`?`text-blue-600`:s===`O`?`text-red-600`:`text-transparent`} - `,children:s||``},e)};return(0,H.jsxs)(`div`,{className:`${s()} p-0.5 sm:p-1`,children:[(0,H.jsxs)(`div`,{className:`relative grid grid-cols-3 gap-0`,children:[Array(9).fill(null).map((e,t)=>c(t)),(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(`div`,{className:`absolute top-1/3 left-0 w-full h-px bg-gray-400/40`}),(0,H.jsx)(`div`,{className:`absolute top-2/3 left-0 w-full h-px bg-gray-400/40`}),(0,H.jsx)(`div`,{className:`absolute left-1/3 top-0 h-full w-px bg-gray-400/40`}),(0,H.jsx)(`div`,{className:`absolute left-2/3 top-0 h-full w-px bg-gray-400/40`})]})]}),n===`DEAD`?(0,H.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center pointer-events-none`,children:(0,H.jsx)(`div`,{className:`grid grid-cols-3 gap-0 opacity-40`,children:Array(9).fill(null).map((e,t)=>(0,H.jsx)(`span`,{className:`text-[8px] sm:text-xs md:text-base text-gray-400 font-bold`,children:`×`},t))})}):n===`X`||n===`O`?(0,H.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center pointer-events-none`,children:(0,H.jsx)(`span`,{className:`text-2xl sm:text-4xl md:text-7xl font-bold opacity-25 ${n===`X`?`text-blue-600`:`text-red-600`}`,children:n})}):null]})},qr=({board:e,macroBoard:t,activeGrid:n,lastMove:r,onCellClick:i})=>(0,H.jsxs)(`div`,{className:`relative p-3 sm:p-4 bg-white/90 rounded-2xl shadow-xl border-4 border-gray-800/10`,children:[(0,H.jsx)(`div`,{className:`grid grid-cols-3 gap-1 sm:gap-2 md:gap-3`,children:Array(9).fill(null).map((a,o)=>(0,H.jsx)(Kr,{gridIndex:o,gridData:e[o],macroWinner:t[o],isActive:n===null||n===o,isLastMoveGrid:r?.gridIndex===o,lastMoveSquare:r?.gridIndex===o?r?.squareIndex:null,onSquareClick:e=>i(o,e)},o))}),(0,H.jsx)(`div`,{className:`absolute top-1/3 left-0 w-full h-1 bg-gray-800/10`}),(0,H.jsx)(`div`,{className:`absolute top-2/3 left-0 w-full h-1 bg-gray-800/10`}),(0,H.jsx)(`div`,{className:`absolute left-1/3 top-0 h-full w-1 bg-gray-800/10`}),(0,H.jsx)(`div`,{className:`absolute left-2/3 top-0 h-full w-1 bg-gray-800/10`})]}),Jr=()=>{let{socket:e,playerName:t,roomId:n,setRoomId:r}=ir(),[i,a]=(0,_.useState)([]),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(`waiting`),[u,d]=(0,_.useState)(Array(9).fill(null).map(()=>Array(9).fill(null))),[f,p]=(0,_.useState)(Array(9).fill(null)),[m,h]=(0,_.useState)(null),[g,v]=(0,_.useState)({X:0,O:0}),[y,b]=(0,_.useState)(null),[x,S]=(0,_.useState)(null),C=He(),[w]=Vr(`/sounds/move.mp3`,{volume:.5}),[T]=Vr(`/sounds/win.mp3`,{volume:.7});return(0,_.useEffect)(()=>{if(e)return V.info(`UTTT`,`Socket connected: ${e.id}`),e.on(`uttt_roomInfo`,t=>{V.socket(`⬅️`,`uttt_roomInfo`,{roomId:t.id,gameState:t.gameState}),r(t.id),a(t.players),l(t.gameState),s(t.currentTurn),t.board&&d(t.board),t.macroBoard&&p(t.macroBoard),t.activeGrid!==void 0&&h(t.activeGrid),t.scores&&v(t.scores),t.lastMove&&b(t.lastMove);let n=t.players.findIndex(t=>t.id===e.id);n!==-1&&(S(n===0?`X`:`O`),V.info(`UTTT`,`You are player ${n+1} (${n===0?`X`:`O`})`))}),e.on(`uttt_gameState`,e=>{V.socket(`⬅️`,`uttt_gameState`,{gameState:e.gameState,currentTurn:e.currentTurn,activeGrid:e.activeGrid,scores:e.scores}),l(e.gameState),s(e.currentTurn),d(e.board),p(e.macroBoard),h(e.activeGrid),v(e.scores),b(e.lastMove)}),e.on(`uttt_gameStarted`,()=>{V.socket(`⬅️`,`uttt_gameStarted`,`Game started!`),l(`playing`),d(Array(9).fill(null).map(()=>Array(9).fill(null))),p(Array(9).fill(null)),h(null),v({X:0,O:0}),b(null),W.default.fire({title:`Game Started!`,text:`Ultimate Tic-Tac-Toe begins!`,timer:1500,showConfirmButton:!1,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`uttt_gameOver`,({winner:e,symbol:t,scores:n,reason:r})=>{V.socket(`⬅️`,`uttt_gameOver`,{winner:e,symbol:t,scores:n,reason:r}),T(),Ur({particleCount:200,spread:70,origin:{y:.6}});let a=i.find(t=>t.id===e)?.name||`Someone`,o=r===`macro_win`?` won the game!`:` won by points (${n.X} - ${n.O})!`;W.default.fire({title:`🎉 Victory!`,text:`${a}${o}`,icon:`success`,customClass:{popup:`glass rounded-3xl paper-font`}}),l(`ended`)}),e.on(`uttt_error`,({message:e})=>{V.socket(`⬅️`,`uttt_error`,{message:e}),W.default.fire({title:`Oops!`,text:e,icon:`error`,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`uttt_playerLeft`,({playerId:e})=>{V.socket(`⬅️`,`uttt_playerLeft`,{playerId:e}),W.default.fire({title:`Player Left`,text:`The opponent has left the party.`,icon:`warning`,customClass:{popup:`glass rounded-3xl paper-font`}}),l(`waiting`),d(Array(9).fill(null).map(()=>Array(9).fill(null))),p(Array(9).fill(null)),h(null)}),()=>{e.off(`uttt_roomInfo`),e.off(`uttt_gameState`),e.off(`uttt_gameStarted`),e.off(`uttt_gameOver`),e.off(`uttt_error`),e.off(`uttt_playerLeft`)}},[e,i,r,T]),(0,H.jsxs)(`div`,{className:`min-h-screen flex flex-col items-center justify-center p-2 sm:p-4`,children:[(0,H.jsxs)(U,{onClick:()=>C(`/`),variant:`secondary`,className:`absolute top-2 sm:top-8 left-2 sm:left-8 flex items-center gap-1 sm:gap-2 text-xs sm:text-base px-2 sm:px-4`,children:[(0,H.jsx)(_r,{size:14,className:`sm:w-[18px]`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Back`})]}),(0,H.jsxs)(`h1`,{className:`text-2xl sm:text-3xl md:text-5xl hand-drawn mb-2 sm:mb-4 text-blue-600 flex items-center gap-2 sm:gap-3 text-center`,children:[(0,H.jsx)(yr,{className:`w-6 h-6 sm:w-8 sm:h-8 text-blue-500`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Ultimate Tic-Tac-Toe`}),(0,H.jsx)(`span`,{className:`sm:hidden`,children:`UTTT`})]}),n?(0,H.jsxs)(`div`,{className:`w-full max-w-md sm:max-w-2xl`,children:[(0,H.jsxs)(`div`,{className:`glass p-2 sm:p-4 rounded-xl sm:rounded-2xl mb-3 sm:mb-6 flex flex-col sm:flex-row justify-between items-center gap-2 sm:gap-4`,children:[(0,H.jsxs)(`div`,{className:`paper-font text-gray-600 flex items-center gap-1 sm:gap-2 text-xs sm:text-base`,children:[(0,H.jsx)(yr,{size:14,className:`sm:w-[18px] text-blue-500`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Room:`}),` `,(0,H.jsx)(`span`,{className:`font-bold text-blue-600 uppercase`,children:n})]}),(0,H.jsx)(`div`,{className:`flex items-center gap-2 sm:gap-4`,children:(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2`,children:[(0,H.jsx)(Tr,{size:14,className:`sm:w-[18px] text-blue-500`}),(0,H.jsx)(`span`,{className:`font-bold text-blue-600 text-sm sm:text-base`,children:g.X}),(0,H.jsx)(`span`,{className:`text-gray-400`,children:`-`}),(0,H.jsx)(`span`,{className:`font-bold text-red-600 text-sm sm:text-base`,children:g.O})]})}),(0,H.jsx)(`div`,{className:`flex gap-2 sm:gap-4 text-xs sm:text-sm`,children:i.map((e,t)=>(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 transition-all duration-300 ${e.id===o?`scale-105`:`opacity-60`}`,children:[e.id===o?(0,H.jsx)(Ar,{size:12,className:`sm:w-4 text-blue-500 animate-pulse`}):(0,H.jsx)(`div`,{className:`w-2 h-2 sm:w-3 sm:h-3 rounded-full ${t===0?`bg-blue-500`:`bg-red-500`}`}),(0,H.jsxs)(`span`,{className:`font-bold paper-font text-xs sm:text-base`,children:[e.name.length>8?e.name.slice(0,8)+`...`:e.name,` (`,t===0?`X`:`O`,`)`]})]},e.id))})]}),(0,H.jsx)(`div`,{className:`mb-3 sm:mb-6 px-1`,children:(0,H.jsx)(qr,{board:u,macroBoard:f,activeGrid:m,lastMove:y,onCellClick:(t,r)=>{if(c===`playing`&&o===e?.id){if(m!==null&&m!==t||u[t][r]!==null||f[t]!==null&&f[t]!==`DEAD`)return;w(),V.socket(`➡️`,`uttt_makeMove`,{roomId:n,gridIndex:t,squareIndex:r}),e.emit(`uttt_makeMove`,{roomId:n,gridIndex:t,squareIndex:r})}}})}),(0,H.jsx)(`div`,{className:`text-center paper-font text-xs sm:text-lg text-gray-700 flex flex-col items-center gap-2`,children:c===`playing`?o===e?.id?(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 text-blue-600 animate-bounce`,children:[(0,H.jsx)(Or,{size:16,className:`sm:w-6`}),(0,H.jsx)(`span`,{children:`Your turn!`})]}):(0,H.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2`,children:[(0,H.jsx)(`div`,{className:`w-3 h-3 sm:w-4 sm:h-4 border-2 border-blue-600 border-t-transparent rounded-full animate-spin`}),(0,H.jsxs)(`span`,{className:`hidden sm:inline`,children:[`Waiting for `,i.find(e=>e.id===o)?.name,`...`]}),(0,H.jsx)(`span`,{className:`sm:hidden`,children:`Waiting...`})]}):c===`waiting`?(0,H.jsx)(`span`,{className:`text-xs sm:text-base`,children:`Waiting for opponent...`}):(0,H.jsx)(U,{onClick:()=>{V.socket(`➡️`,`uttt_restartGame`,{roomId:n}),e.emit(`uttt_restartGame`,n)},className:`text-xs sm:text-base px-3 sm:px-6 py-1 sm:py-2`,children:`Play Again`})})]}):(0,H.jsxs)(`div`,{className:`flex gap-2 sm:gap-4 flex-wrap justify-center`,children:[(0,H.jsx)(U,{onClick:()=>{V.socket(`➡️`,`uttt_createRoom`,{playerName:t}),e.emit(`uttt_createRoom`,t)},className:`text-sm sm:text-base px-3 sm:px-6 py-2`,children:`Create`}),(0,H.jsx)(U,{onClick:async()=>{let{value:n}=await W.default.fire({title:`Join Room`,input:`text`,inputPlaceholder:`Enter Room ID`,showCancelButton:!0,customClass:{popup:`glass rounded-3xl paper-font`}});n&&(V.socket(`➡️`,`uttt_joinRoom`,{roomId:n.toUpperCase(),playerName:t}),e.emit(`uttt_joinRoom`,{roomId:n.toUpperCase(),playerName:t}))},variant:`secondary`,className:`text-sm sm:text-base px-3 sm:px-6 py-2`,children:`Join`})]})]})},Yr=function(e,t){return Number(e.toFixed(t))},Xr=function(e,t){return typeof e==`number`?e:t},G=function(e,t,n){n&&typeof n==`function`&&n(e,t)},Zr={easeOut:function(e){return-Math.cos(e*Math.PI)/2+.5},linear:function(e){return e},easeInQuad:function(e){return e*e},easeOutQuad:function(e){return e*(2-e)},easeInOutQuad:function(e){return e<.5?2*e*e:-1+(4-2*e)*e},easeInCubic:function(e){return e*e*e},easeOutCubic:function(e){return--e*e*e+1},easeInOutCubic:function(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1},easeInQuart:function(e){return e*e*e*e},easeOutQuart:function(e){return 1- --e*e*e*e},easeInOutQuart:function(e){return e<.5?8*e*e*e*e:1-8*--e*e*e*e},easeInQuint:function(e){return e*e*e*e*e},easeOutQuint:function(e){return 1+--e*e*e*e*e},easeInOutQuint:function(e){return e<.5?16*e*e*e*e*e:1+16*--e*e*e*e*e}},Qr=function(e){typeof e==`number`&&cancelAnimationFrame(e)},$r=function(e){e.mounted&&(Qr(e.animation),e.isAnimating=!1,e.animation=null,e.velocity=null)};function ei(e,t,n,r){if(e.mounted){var i=new Date().getTime(),a=1;$r(e),e.animation=function(){if(!e.mounted)return Qr(e.animation);var o=new Date().getTime()-i,s=o/n,c=Zr[t],l=c(s);o>=n?(r(a),e.animation=null):e.animation&&(r(l),requestAnimationFrame(e.animation))},requestAnimationFrame(e.animation)}}function ti(e){var t=e.scale,n=e.positionX,r=e.positionY;return!(Number.isNaN(t)||Number.isNaN(n)||Number.isNaN(r))}function ni(e,t,n,r){var i=ti(t);if(!(!e.mounted||!i)){var a=e.setState,o=e.state,s=o.scale,c=o.positionX,l=o.positionY,u=t.scale-s,d=t.positionX-c,f=t.positionY-l;n===0?a(t.scale,t.positionX,t.positionY):ei(e,r,n,function(t){t===1?e.isAnimating=!1:e.isAnimating=!0,a(s+u*t,c+d*t,l+f*t)})}}function K(e,t,n){var r=e.offsetWidth,i=e.offsetHeight,a=t.offsetWidth,o=t.offsetHeight,s=a*n,c=o*n;return{wrapperWidth:r,wrapperHeight:i,newContentWidth:s,newDiffWidth:r-s,newContentHeight:c,newDiffHeight:i-c}}var ri=function(e,t,n,r,i,a,o){var s=e>t?n*(o?.5:1):0,c=r>i?a*(o?.5:1):0;return{minPositionX:e-t-s,maxPositionX:s,minPositionY:r-i-c,maxPositionY:c,scaleWidthFactor:s,scaleHeightFactor:c}},ii=function(e,t){var n=e.wrapperComponent,r=e.contentComponent,i=e.setup,a=i.centerZoomedOut,o=i.disablePadding;if(!n||!r)throw Error(`Components are not mounted`);var s=K(n,r,t),c=s.wrapperWidth,l=s.wrapperHeight,u=s.newContentWidth,d=s.newContentHeight,f=s.newDiffWidth,p=s.newDiffHeight,m=ri(c,u,f,l,d,p,!!a);o&&c>=u&&l>=d&&!a&&(m.minPositionX=0,m.maxPositionX=0,m.minPositionY=0,m.maxPositionY=0);var h=e.setup,g=h.minPositionX,_=h.maxPositionX,v=h.minPositionY,y=h.maxPositionY;return g!=null&&(m.minPositionX=c*(1-t)+g*t),_!=null&&(m.maxPositionX=_*t),v!=null&&(m.minPositionY=l*(1-t)+v*t),y!=null&&(m.maxPositionY=y*t),m},ai=function(e,t,n,r){return Yr(r?en?n:e:e,2)},oi=function(e,t){var n=ii(e,t);return e.bounds=n,n};function si(e,t,n,r,i,a,o){var s=n.minPositionX,c=n.minPositionY,l=n.maxPositionX,u=n.maxPositionY,d=0,f=0;return o&&(d=i,f=a),{x:ai(e,s-d,l+d,r),y:ai(t,c-f,u+f,r)}}function q(e,t,n,r,i,a){var o=e.state,s=o.scale,c=o.positionX,l=o.positionY,u=r-s;return typeof t!=`number`||typeof n!=`number`?(console.error(`Mouse X and Y position were not provided!`),{x:c,y:l}):si(c-t*u,l-n*u,i,a,0,0,null)}var ci=1e-7;function li(e,t,n,r,i){var a=i?r:0,o=Math.max(t-a,ci),s=n+a;return!Number.isNaN(n)&&e>=s?s:!Number.isNaN(t)&&e<=o?o:Math.max(e,ci)}var ui=function(e,t){var n=e.setup.panning.excluded,r=e.isInitialized,i=e.wrapperComponent,a=t.target,o=`shadowRoot`in a&&`composedPath`in t?t.composedPath().some(function(e){return e instanceof Element?i?.contains(e):!1}):i?.contains(a);return!(!(r&&a&&o)||ea(a,n)||a.getAttribute(`draggable`)===`true`||a.getAttribute(`contenteditable`)===`true`||a.isContentEditable)},di=function(e){var t=e.isInitialized,n=e.isPanning,r=e.setup.panning.disabled;return!!(t&&n&&!r)},fi=function(e,t){var n=e.state,r=n.positionX,i=n.positionY;e.isPanning=!0;var a=t.clientX,o=t.clientY;e.startCoords={x:a-r,y:o-i}},pi=function(e,t){var n=t.touches,r=e.state,i=r.positionX,a=r.positionY;if(e.isPanning=!0,n.length===1){var o=n[0].clientX,s=n[0].clientY;e.startCoords={x:o-i,y:s-a}}};function mi(e){var t=e.state,n=t.positionX,r=t.positionY,i=t.scale,a=e.setup,o=a.disabled,s=a.limitToBounds,c=a.centerZoomedOut,l=e.wrapperComponent;if(!(o||!l||!e.bounds)){var u=e.bounds,d=u.maxPositionX,f=u.minPositionX,p=u.maxPositionY,m=u.minPositionY,h=n>d||np||rd?l.offsetWidth:e.setup.minPositionX||0,r>p?l.offsetHeight:e.setup.minPositionY||0,i,e.bounds,s||c),v=_.x,y=_.y;return{scale:i,positionX:h?v:n,positionY:g?y:r}}}function hi(e,t,n,r,i){var a=e.setup.limitToBounds,o=e.wrapperComponent,s=e.bounds,c=e.state,l=c.scale,u=c.positionX,d=c.positionY;if(!(o===null||s===null||t===u&&n===d)){var f=si(t,n,s,a,r,i,o),p=f.x,m=f.y;e.setState(l,p,m)}}var gi=function(e,t,n){var r=e.startCoords,i=e.state,a=e.setup.panning,o=a.lockAxisX,s=a.lockAxisY,c=i.positionX,l=i.positionY;if(!r)return{x:c,y:l};var u=t-r.x,d=n-r.y;return{x:o?c:u,y:s?l:d}},_i=function(e,t,n){var r=e.setup,i=e.state,a=r.minScale,o=r.disablePadding,s=r.centerZoomedOut,c=n??i.scale;return t>0&&c>=a&&!o&&!s?t:0},vi;(function(e){e.TRACK_PAD=`track_pad`,e.MOUSE=`mouse`,e.TOUCH=`touch`})(vi||={});var yi=function(e){var t=e.mounted,n=e.wrapperComponent,r=e.contentComponent,i=e.setup,a=i.disabled,o=i.velocityAnimation,s=i.limitToBounds,c=e.state.scale;return o.disabled||a||!t||!n||!r?!1:s?n.offsetWidtho&&n>o){var u=o+(e-o)*l;return u>c?c:ua?a:u}}return r?t:ai(e,a,o,i)}function Ci(e){var t=1,n=e.offsetWidth/window.innerWidth;return Number.isNaN(n)?t:Math.min(t,n)}var wi=function(e,t,n){var r=0,i=e*n;return Number.isNaN(i)?r:e<0?Math.max(i,-t):Math.min(i,t)};function Ti(e,t,n){var r,i;if(yi(e)){var a=e.lastMousePosition,o=e.velocityTime,s=e.setup,c=e.wrapperComponent,l=s.velocityAnimation,u=l.maxStrengthMouse,d=l.maxStrengthTouch,f=l.sensitivityTouch,p=l.sensitivityMouse,m=Date.now();if(a&&o&&c){var h=Ci(c),g=(r={},r[vi.TOUCH]=f,r[vi.MOUSE]=p,r)[n],_=(i={},i[vi.TOUCH]=d,i[vi.MOUSE]=u,i)[n],v=t.x-a.x,y=t.y-a.y,b=wi(v/h,_,g),x=wi(y/h,_,g),S=m-o,C=v*v+y*y;e.velocity={velocityX:b,velocityY:x,total:wi(Math.sqrt(C)/S,_,g)}}e.lastMousePosition=t,e.velocityTime=m}}function Ei(e){var t=e.velocity,n=e.bounds,r=e.setup,i=e.wrapperComponent;if(!(!bi(e)||!t||!n||!i)){var a=t.velocityX,o=t.velocityY,s=t.total,c=n.maxPositionX,l=n.minPositionX,u=n.maxPositionY,d=n.minPositionY,f=r.limitToBounds,p=r.autoAlignment,m=r.zoomAnimation,h=r.panning,g=h.lockAxisY,_=h.lockAxisX,v=m.animationType,y=p.sizeX,b=p.sizeY,x=p.velocityAlignmentTime,S=xi(e,s),C=Math.max(S,x),w=_i(e,y),T=_i(e,b),E=w*i.offsetWidth/100,D=T*i.offsetHeight/100,ee=c+E,te=l-E,ne=u+D,re=d-D,ie=e.state,ae=new Date().getTime();ei(e,v,C,function(t){var n=e.state,r=n.scale,i=n.positionX,s=n.positionY,m=(new Date().getTime()-ae)/x,h=Zr[p.animationType],v=1-h(Math.min(1,m)),y=1-t,b=i+a*y,S=s+o*y,C=Si(b,ie.positionX,i,_,f,l,c,te,ee,v),w=Si(S,ie.positionY,s,g,f,d,u,re,ne,v);if(i!==b||s!==S){e.setState(r,C,w);var T=e.props.onPanning;T&&T(X(e),{})}})}}function Di(e,t){var n=e.state,r=n.scale;e.panStartPosition={x:n.positionX,y:n.positionY},$r(e),oi(e,r),window.TouchEvent!==void 0&&t instanceof TouchEvent?pi(e,t):fi(e,t)}function Oi(e,t){var n=e.state.scale,r=e.setup,i=r.minScale,a=r.autoAlignment,o=a.disabled,s=a.sizeX,c=a.sizeY,l=a.animationTime,u=a.animationType;if(!(o||n.1&&g?Ei(e):Oi(e)}}function ji(e,t,n,r){var i=e.setup,a=i.minScale,o=i.maxScale,s=i.limitToBounds,c=li(Yr(t,2),a,o,0,!1),l=q(e,n,r,c,oi(e,c),s);return{scale:c,positionX:l.x,positionY:l.y}}function Mi(e,t,n){var r=e.state.scale,i=e.wrapperComponent,a=e.setup,o=a.minScale,s=a.maxScale,c=a.limitToBounds,l=a.zoomAnimation,u=l.disabled,d=l.animationTime,f=l.animationType,p=u||r>=o&&r<=s;if((r>=1||c)&&Oi(e),!(p||!i||!e.mounted)){var m=t||i.offsetWidth/2,h=n||i.offsetHeight/2,g=ji(e,ro||Math.sign(n.deltaY)!==Math.sign(t.deltaY)||n.deltaY>0&&n.deltaYt.deltaY||Math.sign(n.deltaY)!==Math.sign(t.deltaY):!1},ma=function(e,t){var n=e.setup.pinch,r=n.disabled,i=n.excluded,a=e.isInitialized,o=t.target;return!(!(a&&!r&&o)||ea(o,i))},ha=function(e){var t=e.setup.pinch.disabled,n=e.isInitialized,r=e.pinchStartDistance;return!!(n&&!t&&r!==null)},ga=function(e,t,n){var r=n.getBoundingClientRect(),i=e.touches,a=i[0].clientX-r.left,o=i[0].clientY-r.top,s=i[1].clientX-r.left,c=i[1].clientY-r.top;return{x:(a+s)/2/t,y:(o+c)/2/t}},_a=function(e){return Math.sqrt((e.touches[0].pageX-e.touches[1].pageX)**2+(e.touches[0].pageY-e.touches[1].pageY)**2)},Z=5,va=function(e,t){var n=e.pinchStartScale,r=e.pinchStartDistance,i=e.setup,a=i.maxScale,o=i.minScale,s=i.zoomAnimation,c=i.disablePadding,l=i.pinch,u=s.size,d=s.disabled,f=l.step;if(!n||r===null)throw Error(`Pinch touches distance was not provided`);if(t<0)return e.state.scale;var p=n+(t/r*n-n)*(f/Z);return li(p===1/0?0:Yr(p,10),o,a,u,!d&&!c)},ya=160,ba=100,xa=function(e,t){var n=e.props,r=n.onWheelStart,i=n.onZoomStart;e.wheelStopEventTimer||($r(e),G(X(e),t,r),G(X(e),t,i))},Sa=function(e,t){var n=e.props,r=n.onWheel,i=n.onZoom,a=e.contentComponent,o=e.setup,s=e.state.scale,c=o.limitToBounds,l=o.centerZoomedOut,u=o.zoomAnimation,d=o.wheel,f=o.disablePadding,p=o.smooth,m=u.size,h=u.disabled,g=d.step;if(!a)throw Error(`Component not mounted`);t.preventDefault(),t.stopPropagation();var _=fa(e,ua(t,null),p?g*Math.abs(t.deltaY):g,!t.ctrlKey);if(s!==_){var v=oi(e,_),y=da(t,a,s),b=c&&(h||m===0||l||f),x=q(e,y.x,y.y,_,v,b),S=x.x,C=x.y;e.previousWheelEvent=t,e.setState(_,S,C),G(X(e),t,r),G(X(e),t,i)}},Ca=function(e,t){var n=e.props,r=n.onWheelStop,i=n.onZoomStop;ta(e.wheelAnimationTimer),e.wheelAnimationTimer=setTimeout(function(){e.mounted&&(Mi(e,t.x,t.y),e.wheelAnimationTimer=null)},ba),pa(e,t)&&(ta(e.wheelStopEventTimer),e.wheelStopEventTimer=setTimeout(function(){e.mounted&&(e.wheelStopEventTimer=null,G(X(e),t,r),G(X(e),t,i))},ya))},wa=function(e,t){var n=e.props,r=n.onWheelStart,i=n.onPanningStart;e.wheelStopEventTimer||($r(e),G(X(e),t,r),G(X(e),t,i))},Ta=function(e,t){var n=e.props,r=n.onWheelStop,i=n.onPanningStop;ta(e.wheelAnimationTimer),e.wheelAnimationTimer=setTimeout(function(){e.mounted&&(Mi(e,t.x,t.y),e.wheelAnimationTimer=null)},ba),pa(e,t)&&(ta(e.wheelStopEventTimer),e.wheelStopEventTimer=setTimeout(function(){e.mounted&&(e.wheelStopEventTimer=null,G(X(e),t,r),G(X(e),t,i))},ya))},Ea=function(e){for(var t=0,n=0,r=0;r<2;r+=1)t+=e.touches[r].clientX,n+=e.touches[r].clientY;return{x:t/2,y:n/2}},Da=function(e,t){var n=_a(t);e.pinchStartDistance=n,e.lastDistance=n,e.pinchStartScale=e.state.scale,e.isPanning=!1,e.isPinching=!0,e.pinchPreviousCenter=Ea(t),$r(e)},Oa=function(e,t){var n=e.contentComponent,r=e.pinchStartDistance,i=e.wrapperComponent,a=e.pinchPreviousCenter,o=e.state.scale,s=e.setup,c=s.limitToBounds,l=s.centerZoomedOut,u=s.zoomAnimation,d=s.autoAlignment,f=s.pinch,p=s.panning,m=u.disabled,h=u.size,g=f.allowPanning;if(!(r===null||!n)){var _=ga(t,o,n);if(!(!Number.isFinite(_.x)||!Number.isFinite(_.y))){var v=_a(t),y=va(e,v),b=Ea(t),x=o/y,S=(b.x-(a?.x||0))*x,C=(b.y-(a?.y||0))*x;if(!(y===o&&S===0&&C===0)){e.pinchPreviousCenter=b;var w=oi(e,y),T=c&&(m||h===0||l),E=q(e,_.x,_.y,y,w,T),D=E.x,ee=E.y;if(e.pinchMidpoint=_,e.lastDistance=v,p.disabled||!g)e.setState(y,D,ee);else{var te=d.sizeX,ne=d.sizeY,re=_i(e,te,y),ie=_i(e,ne,y),ae=si(D+S,ee+C,w,c,re,ie,i),O=ae.x,k=ae.y;e.setState(y,O,k)}}}}},ka=function(e){var t=e.pinchMidpoint;e.velocity=null,e.lastDistance=null,e.pinchMidpoint=null,e.pinchStartScale=null,e.pinchStartDistance=null,e.isPinching=!1,Mi(e,t?.x,t?.y)},Aa=function(e,t){var n=e.props.onZoomStop,r=e.setup.doubleClick.animationTime;ta(e.doubleClickStopEventTimer),e.doubleClickStopEventTimer=setTimeout(function(){e.doubleClickStopEventTimer=null,G(X(e),t,n)},r)},ja=function(e,t){var n=e.props,r=n.onZoomStart,i=n.onZoom,a=e.setup.doubleClick,o=a.animationTime,s=a.animationType;G(X(e),t,r),Y(e,o,s,function(){return G(X(e),t,i)}),Aa(e,t)};function Ma(e,t){return e===`toggle`?t===1?1:-1:e===`zoomOut`?-1:1}function Na(e,t){var n=e.setup,r=e.doubleClickStopEventTimer,i=e.state,a=e.contentComponent,o=i.scale,s=e.props,c=s.onZoomStart,l=s.onZoom,u=n.doubleClick,d=u.disabled,f=u.mode,p=u.step,m=u.animationTime,h=u.animationType;if(!d&&!r){if(f===`reset`)return ja(e,t);if(!a)return console.error(`No ContentComponent found`);var g=Bi(e,Ma(f,e.state.scale),p);if(o!==g){G(X(e),t,c);var _=da(t,a,o),v=ji(e,g,_.x,_.y);if(!v)return console.error(`Error during zoom event. New transformation state was not calculated.`);G(X(e),t,l),ni(e,v,m,h),Aa(e,t)}}}var Pa=function(e,t){var n=e.isInitialized,r=e.setup,i=e.wrapperComponent,a=r.doubleClick,o=a.disabled,s=a.excluded,c=t.target,l=i?.contains(c);return!(!(n&&c&&l&&!o)||ea(c,s))},Fa=function(){function e(e){var t=this;this.mounted=!0,this.onChangeCallbacks=new Set,this.onInitCallbacks=new Set,this.onTransformCallbacks=new Set,this.wrapperComponent=null,this.contentComponent=null,this.isInitialized=!1,this.bounds=null,this.previousWheelEvent=null,this.wheelStopEventTimer=null,this.wheelAnimationTimer=null,this.isPanning=!1,this.isWheelPanning=!1,this.startCoords=null,this.panStartPosition=null,this.lastTouch=null,this.isPinching=!1,this.distance=null,this.lastDistance=null,this.pinchStartDistance=null,this.pinchStartScale=null,this.pinchMidpoint=null,this.pinchPreviousCenter=null,this.doubleClickStopEventTimer=null,this.velocity=null,this.velocityTime=null,this.lastMousePosition=null,this.isAnimating=!1,this.animation=null,this.pressedKeys={},this.mount=function(){t.initializeWindowEvents()},this.unmount=function(){t.cleanupWindowEvents()},this.update=function(e){t.props=e,t.wrapperComponent&&t.contentComponent&&oi(t,t.state.scale),t.setup=zi(e)},this.initializeWindowEvents=function(){var e,n,r,i=Qi(),a=t.wrapperComponent?.ownerDocument,o=a?.defaultView;(e=t.wrapperComponent)==null||e.addEventListener(`wheel`,t.onWheelPanning,i),(n=t.wrapperComponent)==null||n.addEventListener(`keyup`,t.setKeyUnPressed,i),(r=t.wrapperComponent)==null||r.addEventListener(`keydown`,t.setKeyPressed,i),o?.addEventListener(`mousedown`,t.onPanningStart,i),o?.addEventListener(`mousemove`,t.onPanning,i),o?.addEventListener(`mouseup`,t.onPanningStop,i),a?.addEventListener(`mouseleave`,t.clearPanning,i),o?.addEventListener(`keyup`,t.setKeyUnPressed,i),o?.addEventListener(`keydown`,t.setKeyPressed,i),o?.addEventListener(`blur`,t.handleWindowBlur)},this.cleanupWindowEvents=function(){var e,n,r,i,a=Qi(),o=t.wrapperComponent?.ownerDocument,s=o?.defaultView;s?.removeEventListener(`mousedown`,t.onPanningStart,a),s?.removeEventListener(`mousemove`,t.onPanning,a),s?.removeEventListener(`mouseup`,t.onPanningStop,a),o?.removeEventListener(`mouseleave`,t.clearPanning,a),s?.removeEventListener(`keyup`,t.setKeyUnPressed,a),s?.removeEventListener(`keydown`,t.setKeyPressed,a),s?.removeEventListener(`blur`,t.handleWindowBlur),document.removeEventListener(`mouseleave`,t.clearPanning,a),(e=t.wrapperComponent)==null||e.removeEventListener(`wheel`,t.onWheelPanning,a),(n=t.wrapperComponent)==null||n.removeEventListener(`keyup`,t.setKeyUnPressed,a),(r=t.wrapperComponent)==null||r.removeEventListener(`keydown`,t.setKeyPressed,a),$r(t),(i=t.observer)==null||i.disconnect()},this.handleInitializeWrapperEvents=function(e){var n=Qi();e.addEventListener(`wheel`,t.onWheelZoom,n),e.addEventListener(`dblclick`,t.onDoubleClick,n),e.addEventListener(`touchstart`,t.onTouchPanningStart,n),e.addEventListener(`touchmove`,t.onTouchPanning,n),e.addEventListener(`touchend`,t.onTouchPanningStop,n)},this.handleInitialize=function(e){var n=t.setup.centerOnInit;t.applyTransformation(),t.onInitCallbacks.forEach(function(e){return e(X(t))}),n&&(t.setCenter(),t.observer=new ResizeObserver(function(){var n,r=e.offsetWidth,i=e.offsetHeight;(r>0||i>0)&&(t.onInitCallbacks.forEach(function(e){return e(X(t))}),t.setCenter(),(n=t.observer)==null||n.disconnect())}),setTimeout(function(){var e;(e=t.observer)==null||e.disconnect()},5e3),t.observer.observe(e))},this.onWheelZoom=function(e){t.setup.disabled||(t.syncModifierKeys(e),sa(t,e)&&(xa(t,e),Sa(t,e),Ca(t,e)))},this.onWheelPanning=function(e){var n=t.props.onPanning,r=t.setup.trackPadPanning,i=r.lockAxisX,a=r.lockAxisY;if(t.syncModifierKeys(e),ca(t,e)){e.preventDefault(),e.stopPropagation();var o=t.state,s=o.positionX,c=o.positionY,l=s-e.deltaX,u=c-e.deltaY,d=i?s:l,f=a?c:u,p=t.setup.autoAlignment,m=p.sizeX,h=p.sizeY,g=_i(t,m),_=_i(t,h);d===s&&f===c||(wa(t,e),hi(t,d,f,g,_),G(X(t),e,n),Ta(t,e))}},this.onPanningStart=function(e){var n=t.setup.disabled,r=t.props.onPanningStart;n||(t.syncModifierKeys(e),ui(t,e)&&t.isPressingKeys(t.setup.panning.activationKeys)&&(e.button===0&&!t.setup.panning.allowLeftClickPan||e.button===1&&!t.setup.panning.allowMiddleClickPan||e.button===2&&!t.setup.panning.allowRightClickPan||(e.preventDefault(),e.stopPropagation(),$r(t),Di(t,e),G(X(t),e,r))))},this.onPanning=function(e){var n=t.setup.disabled,r=t.props.onPanning;if(!n){if(t.syncModifierKeys(e),t.isPanning&&e.buttons===0){t.clearPanning(e);return}di(t)&&t.isPressingKeys(t.setup.panning.activationKeys)&&(e.preventDefault(),e.stopPropagation(),ki(t,e.clientX,e.clientY,vi.MOUSE),G(X(t),e,r))}},this.onPanningStop=function(e){var n=t.setup.panning.velocityDisabled,r=t.props.onPanningStop;t.isPanning&&(Ai(t,n),G(X(t),e,r))},this.onPinchStart=function(e){var n=t.setup.disabled,r=t.props.onPinchStart;n||ma(t,e)&&(Da(t,e),$r(t),G(X(t),e,r))},this.onPinch=function(e){var n=t.setup.disabled,r=t.props.onPinch;n||ha(t)&&(e.preventDefault(),e.stopPropagation(),Oa(t,e),G(X(t),e,r))},this.onPinchStop=function(e){var n=t.props.onPinchStop;t.pinchStartScale&&(ka(t),G(X(t),e,n))},this.onTouchPanningStart=function(e){var n=t.setup,r=n.disabled,i=n.doubleClick,a=t.props.onPanningStart;if(!r){var o=!i?.disabled,s=t.lastTouch&&+new Date-t.lastTouch<200;if(o&&s&&e.touches.length===1)t.onDoubleClick(e);else{t.lastTouch=+new Date,$r(t);var c=e.touches,l=c.length===1,u=c.length===2,d=ui(t,e);if(l){if(!d)return;$r(t),Di(t,e),G(X(t),e,a)}u&&t.onPinchStart(e)}}},this.onTouchPanning=function(e){var n=t.setup.disabled,r=t.props.onPanning;if(t.isPanning&&e.touches.length===1){if(n||!di(t))return;e.cancelable&&e.preventDefault(),e.stopPropagation();var i=e.touches[0];ki(t,i.clientX,i.clientY,vi.TOUCH),G(X(t),e,r)}else e.touches.length>1&&t.onPinch(e)},this.onTouchPanningStop=function(e){t.onPanningStop(e),t.onPinchStop(e)},this.onDoubleClick=function(e){t.setup.disabled||Pa(t,e)&&Na(t,e)},this.clearPanning=function(e){t.isPanning&&t.onPanningStop(e)},this.handleWindowBlur=function(){t.pressedKeys={},t.isPanning&&(t.isPanning=!1,t.startCoords=null)},this.syncModifierKeys=function(e){var n=e.ctrlKey,r=e.metaKey,i=e.shiftKey,a=e.altKey;typeof n==`boolean`&&(t.pressedKeys.Control=n),typeof r==`boolean`&&(t.pressedKeys.Meta=r),typeof i==`boolean`&&(t.pressedKeys.Shift=i),typeof a==`boolean`&&(t.pressedKeys.Alt=a)},this.setKeyPressed=function(e){t.pressedKeys[e.key]=!0},this.setKeyUnPressed=function(e){t.pressedKeys[e.key]=!1},this.isPressingKeys=function(e){return typeof e==`function`?e(Object.entries(t.pressedKeys).filter(function(e){return e[1]}).map(function(e){return e[0]})):e.length?!!e.every(function(e){return t.pressedKeys[e]}):!0},this.setCenter=function(){if(t.wrapperComponent&&t.contentComponent){var e=ia(t.state.scale,t.wrapperComponent,t.contentComponent);t.setState(e.scale,e.positionX,e.positionY)}},this.handleTransformStyles=function(e,n,r){return t.props.customTransform?t.props.customTransform(e,n,r):ra(e,n,r)},this.getContext=function(){return X(t)},this.applyTransformation=function(){if(!(!t.mounted||!t.contentComponent)){var e=t.state,n=e.scale,r=e.positionX,i=e.positionY,a=t.handleTransformStyles(r,i,n);t.props.detached||(t.contentComponent.style.transform=a),t.onTransformCallbacks.forEach(function(e){return e({scale:n,positionX:r,positionY:i,previousScale:t.state.previousScale,ref:X(t)})})}},this.setState=function(e,n,r){var i=t.props.onTransform;if(!Number.isNaN(e)&&!Number.isNaN(n)&&!Number.isNaN(r)){var a=Math.max(e,1e-7);a!==t.state.scale&&(t.state.previousScale=t.state.scale,t.state.scale=a),t.state.positionX=n,t.state.positionY=r,t.applyTransformation();var o=X(t);t.onChangeCallbacks.forEach(function(e){return e(o)}),G(o,{scale:t.state.scale,positionX:n,positionY:r},i)}else console.error(`Detected NaN set state values`)},this.onTransform=function(e){return t.onTransformCallbacks.has(e)||t.onTransformCallbacks.add(e),function(){t.onTransformCallbacks.delete(e)}},this.onChange=function(e){return t.onChangeCallbacks.has(e)||t.onChangeCallbacks.add(e),function(){t.onChangeCallbacks.delete(e)}},this.onInit=function(e){return t.onInitCallbacks.has(e)||t.onInitCallbacks.add(e),function(){t.onInitCallbacks.delete(e)}},this.init=function(e,n){t.cleanupWindowEvents(),t.wrapperComponent=e,t.contentComponent=n,oi(t,t.state.scale),t.handleInitializeWrapperEvents(e),t.handleInitialize(n),t.initializeWindowEvents(),t.isInitialized=!0;var r=X(t);G(r,void 0,t.props.onInit),aa(t.props.ref,r)},this.props=e,this.setup=zi(this.props),this.state=Ri(this.props)}return e}(),Ia=_.createContext(null),La=function(e,t){return typeof e==`function`?e(t):e},Ra=_.forwardRef(function(e,t){var n=(0,_.useRef)(new Fa(e)).current,r=La(e.children,Yi(n));return(0,_.useImperativeHandle)(t,function(){return Yi(n)},[n]),(0,_.useEffect)(function(){n.update(e)},[n,e]),(0,H.jsx)(Ia.Provider,Ni({value:n},{children:r}))});_.forwardRef(function(e,t){var n=(0,_.useRef)(null),r=(0,_.useContext)(Ia);return(0,_.useEffect)(function(){return r.onChange(function(e){if(n.current){var t=0,i=0;n.current.style.transform=r.handleTransformStyles(t,i,1/e.instance.state.scale)}})},[r]),(0,H.jsx)(`div`,Ni({},e,{ref:oa([n,t])}))});function za(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(!e||typeof document>`u`)){var r=document.head||document.getElementsByTagName(`head`)[0],i=document.createElement(`style`);i.type=`text/css`,n===`top`&&r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(document.createTextNode(e))}}var Ba=`.transform-component-module_wrapper__SPB86 { - position: relative; - width: -moz-fit-content; - width: fit-content; - height: -moz-fit-content; - height: fit-content; - overflow: hidden; - -webkit-touch-callout: none; /* iOS Safari */ - -webkit-user-select: none; /* Safari */ - -khtml-user-select: none; /* Konqueror HTML */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* Internet Explorer/Edge */ - user-select: none; - margin: 0; - padding: 0; - transform: translate3d(0, 0, 0); -} -.transform-component-module_content__FBWxo { - display: flex; - flex-wrap: wrap; - width: -moz-fit-content; - width: fit-content; - height: -moz-fit-content; - height: fit-content; - margin: 0; - padding: 0; - transform-origin: 0% 0%; -} -.transform-component-module_content__FBWxo img { - pointer-events: none; -} -.transform-component-module_infiniteGrid__Z-aP3 { - position: absolute; - inset: 0; - pointer-events: none; - background-image: radial-gradient( - circle, - rgba(0, 0, 0, 0.12) 1px, - transparent 1px - ); - background-size: 20px 20px; - background-position: 0 0; -} -`,Va={wrapper:`transform-component-module_wrapper__SPB86`,content:`transform-component-module_content__FBWxo`,infiniteGrid:`transform-component-module_infiniteGrid__Z-aP3`};za(Ba);var Ha=function(e){var t=e.children,n=e.wrapperClass,r=n===void 0?``:n,i=e.contentClass,a=i===void 0?``:i,o=e.wrapperStyle,s=e.contentStyle,c=e.wrapperProps,l=c===void 0?{}:c,u=e.contentProps,d=u===void 0?{}:u,f=e.infinite,p=f===void 0?!1:f,m=(0,_.useContext)(Ia),h=m.init,g=m.cleanupWindowEvents,v=(0,_.useRef)(null),y=(0,_.useRef)(null),b=(0,_.useRef)(null);return(0,_.useEffect)(function(){var e=v.current,t=y.current;return e!==null&&t!==null&&h&&h?.(e,t),function(){g?.()}},[]),(0,_.useEffect)(function(){if(p){var e=b.current;if(e){var t=function(){var t=m.state,n=t.positionX,r=t.positionY;e.style.backgroundPosition=`${n}px ${r}px`};return t(),m.onChange(t)}}},[p,m]),(0,H.jsxs)(`div`,Ni({},l,{ref:v,className:`${Li.wrapperClass} ${Va.wrapper} ${r}`,style:o},{children:[p&&(0,H.jsx)(`div`,{ref:b,className:Va.infiniteGrid,"aria-hidden":!0}),(0,H.jsx)(`div`,Ni({},d,{ref:y,className:`${Li.contentClass} ${Va.content} ${a}`,style:Ni(Ni({},s),{transform:ra(m.state.positionX,m.state.positionY,m.state.scale)})},{children:t}))]}))};function Ua(e,t){return Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x))*Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function Wa(e){var t=e.elementX,n=e.elementY,r=e.elementWidth,i=e.elementHeight,a=e.scale,o=e.positionX,s=e.positionY,c=e.viewportWidth,l=e.viewportHeight,u=e.margin,d=u===void 0?0:u,f=e.threshold,p=f===void 0?0:f,m={x:-d,y:-d,width:c+2*d,height:l+2*d},h={x:t*a+o,y:n*a+s,width:r*a,height:i*a};if(p<=0){var g=h.xm.x,_=h.ym.y;return g&&_}var v=h.width*h.height;return v<=0?!1:Ua(m,h)/v>=p}_.forwardRef(function(e,t){var n=e.x,r=e.y,i=e.width,a=e.height,o=e.margin,s=o===void 0?0:o,c=e.threshold,l=c===void 0?0:c,u=e.placeholder,d=u===void 0?null:u,f=e.onShow,p=e.onHide,m=e.children,h=e.className,g=e.style,v=(0,_.useContext)(Ia),y=(0,_.useState)(!1),b=y[0],x=y[1],S=(0,_.useRef)(!1),C=(0,_.useRef)(f),w=(0,_.useRef)(p);return C.current=f,w.current=p,(0,_.useEffect)(function(){var e=function(){var e,t,o=v.wrapperComponent;if(o){var c=Wa({elementX:n,elementY:r,elementWidth:i,elementHeight:a,scale:v.state.scale,positionX:v.state.positionX,positionY:v.state.positionY,viewportWidth:o.offsetWidth,viewportHeight:o.offsetHeight,margin:s,threshold:l});c!==S.current&&(S.current=c,x(c),c?(e=C.current)==null||e.call(C):(t=w.current)==null||t.call(w))}};e();var t=v.onChange(e),o;return v.wrapperComponent||(o=v.onInit(function(){return e()})),function(){t(),o?.()}},[v,n,r,i,a,s,l]),b?(0,H.jsx)(`div`,Ni({ref:t,className:h,style:g},{children:m})):d?(0,H.jsx)(H.Fragment,{children:d}):null});var Ga=[`#3B82F6`,`#EF4444`,`#22C55E`,`#F97316`],Ka=[`blue-500`,`red-500`,`green-500`,`orange-500`],qa=()=>{let{socket:e,playerName:t,roomId:n,setRoomId:r}=ir(),i=He(),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(`waiting`),[l,u]=(0,_.useState)(0),[d,f]=(0,_.useState)(9),[p,m]=(0,_.useState)(9),[h,g]=(0,_.useState)([]),[v,y]=(0,_.useState)([]),[b,x]=(0,_.useState)([]),[S,C]=(0,_.useState)([]),[w,T]=(0,_.useState)(null),[E,D]=(0,_.useState)(`classic`),[ee,te]=(0,_.useState)(5),[ne,re]=(0,_.useState)(5),[ie,ae]=(0,_.useState)(2),[O,k]=(0,_.useState)(-1),[oe,se]=(0,_.useState)(!1),[ce]=Vr(`/sounds/move.mp3`,{volume:.5}),[A]=Vr(`/sounds/win.mp3`,{volume:.7}),le=(0,_.useRef)(!1);(0,_.useEffect)(()=>{if(!e)return;let t=sessionStorage.getItem(`dab_reconnect`);if(t&&!le.current){le.current=!0;let{roomId:n,playerId:i}=JSON.parse(t);V.socket(`➡️`,`dab_reconnect`,{roomId:n,playerId:i}),e.emit(`dab_reconnect`,{roomId:n,playerId:i}),r(n);return}return e.on(`dab_roomInfo`,t=>{V.socket(`⬅️`,`dab_roomInfo`,{roomId:t.id,gameState:t.gameState}),r(t.id),o(t.players),c(t.gameState),u(t.currentTurn),f(t.rows),m(t.cols),g(t.horizontalLines),y(t.verticalLines),x(t.boxes),C(t.scores),T(t.lastMove),se(t.gameState===`paused`);let n=t.players.findIndex(t=>t.id===e.id);n!==-1&&(k(n),sessionStorage.setItem(`dab_reconnect`,JSON.stringify({roomId:t.id,playerId:t.players[n].id})))}),e.on(`dab_gameStarted`,({firstTurn:e})=>{V.socket(`⬅️`,`dab_gameStarted`,{firstTurn:e}),c(`playing`),se(!1),W.default.fire({title:`Game Started!`,text:`Draw lines to claim boxes!`,timer:1500,showConfirmButton:!1,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`dab_moveResult`,({lineType:e,r:t,c:n,claimedBoxes:r,scores:i,currentTurn:a,playerIndex:o})=>{V.socket(`⬅️`,`dab_moveResult`,{claimedBoxes:r,scores:i}),ce(),g(r=>{let i=r.map(e=>[...e]);return e===`h`&&(i[t][n]=o),i}),y(r=>{let i=r.map(e=>[...e]);return e===`v`&&(i[t][n]=o),i}),r.length>0&&(A(),x(e=>{let t=e.map(e=>[...e]);for(let e of r)t[e.r][e.c]=o;return t})),C(i),u(a)}),e.on(`dab_gameOver`,({winner:e,scores:t,winners:n})=>{if(V.socket(`⬅️`,`dab_gameOver`,{winner:e,winners:n}),c(`ended`),C(t),sessionStorage.removeItem(`dab_reconnect`),Ur({particleCount:150,spread:70,origin:{y:.6}}),e){let t=a.find(t=>t.id===e)?.name||`Player`;W.default.fire({title:`Victory!`,text:`${t} wins!`,icon:`success`,customClass:{popup:`glass rounded-3xl paper-font`}})}else W.default.fire({title:`It's a Tie!`,text:`Multiple players share the top score!`,icon:`info`,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`dab_playerLeft`,({playerId:e})=>{V.socket(`⬅️`,`dab_playerLeft`,{playerId:e}),o(t=>t.map(t=>t.id===e?{...t,connected:!1}:t))}),e.on(`dab_gamePaused`,({reason:e})=>{V.socket(`⬅️`,`dab_gamePaused`,{reason:e}),se(!0),W.default.fire({title:`Game Paused`,text:e,icon:`warning`,customClass:{popup:`glass rounded-3xl paper-font`}})}),e.on(`dab_alert`,({icon:e,title:t,text:n})=>{V.socket(`⬅️`,`dab_alert`,{icon:e,title:t,text:n}),W.default.fire({icon:e,title:t,text:n,customClass:{popup:`glass rounded-3xl paper-font`}})}),()=>{e.off(`dab_roomInfo`),e.off(`dab_gameStarted`),e.off(`dab_moveResult`),e.off(`dab_gameOver`),e.off(`dab_playerLeft`),e.off(`dab_gamePaused`),e.off(`dab_alert`)}},[e,a,r,ce,A]);let ue=()=>{let t=d,n=p,r=ie;E===`custom`&&(t=ee,n=ne,r=ie),V.socket(`➡️`,`dab_createRoom`,{mode:E,customRows:t,customCols:n,customPlayers:r}),e.emit(`dab_createRoom`,{mode:E,customRows:t,customCols:n,customPlayers:r})},de=async()=>{let{value:n}=await W.default.fire({title:`Join Room`,input:`text`,inputPlaceholder:`Enter Room ID`,showCancelButton:!0,customClass:{popup:`glass rounded-3xl paper-font`}});n&&(V.socket(`➡️`,`dab_joinRoom`,{roomId:n.toUpperCase(),playerName:t}),e.emit(`dab_joinRoom`,{roomId:n.toUpperCase(),playerName:t}))},fe=(0,_.useCallback)((t,r,i,a)=>{a.stopPropagation(),V.socket(`➡️`,`dab_makeMove`,{roomId:n,lineType:t,r,c:i,gameState:s,currentTurn:l,myPlayerIndex:O}),!(s!==`playing`||oe)&&l===O&&e.emit(`dab_makeMove`,{roomId:n,lineType:t,r,c:i})},[s,oe,l,O,n,e]),pe=()=>{sessionStorage.removeItem(`dab_reconnect`),r(null),o([]),c(`waiting`),x([]),g([]),y([]),C([]),k(-1),se(!1)},me=p*40,he=d*40;return(0,H.jsxs)(`div`,{className:`min-h-screen flex flex-col items-center justify-center p-2 sm:p-4`,children:[(0,H.jsxs)(U,{onClick:()=>i(`/`),variant:`secondary`,className:`absolute top-2 sm:top-8 left-2 sm:left-8 flex items-center gap-1 sm:gap-2 text-xs sm:text-base px-2 sm:px-4`,children:[(0,H.jsx)(_r,{size:14,className:`sm:w-[18px]`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Back`})]}),(0,H.jsx)(`h1`,{className:`text-3xl sm:text-5xl md:text-6xl hand-drawn mb-4 sm:mb-8 text-blue-600`,children:`Dots & Boxes`}),n?(0,H.jsxs)(`div`,{className:`w-full max-w-4xl`,children:[(0,H.jsxs)(`div`,{className:`glass p-2 sm:p-4 rounded-xl sm:rounded-2xl mb-3 sm:mb-6`,children:[(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 mb-3`,children:[(0,H.jsxs)(`div`,{className:`paper-font text-gray-600 flex items-center gap-2 text-xs sm:text-base`,children:[(0,H.jsx)(Er,{size:14,className:`sm:w-[18px] text-blue-500`}),(0,H.jsx)(`span`,{className:`hidden sm:inline`,children:`Room:`}),(0,H.jsx)(`span`,{className:`font-bold text-blue-600 uppercase`,children:n})]}),(0,H.jsx)(U,{onClick:pe,variant:`secondary`,className:`text-xs px-2 py-1`,children:`Leave`})]}),(0,H.jsx)(`div`,{className:`flex flex-wrap gap-2 sm:gap-4 mb-3`,children:a.map((e,t)=>(0,H.jsxs)(`div`,{className:`flex items-center gap-2 paper-font text-xs sm:text-sm px-3 py-1 rounded-full transition-all ${t===l&&s===`playing`&&!oe?`bg-${Ka[t]}/20 scale-105 ring-2 ring-${Ka[t]}`:`opacity-60`} ${e.connected?``:`grayscale`}`,children:[(0,H.jsx)(`div`,{className:`w-3 h-3 rounded-full`,style:{backgroundColor:Ga[t]}}),(0,H.jsx)(`span`,{className:`font-bold`,children:e.name.length>10?e.name.slice(0,10)+`...`:e.name}),(0,H.jsx)(`span`,{className:`font-mono text-sm`,children:S[t]||0}),!e.connected&&(0,H.jsx)(`span`,{className:`text-gray-400 text-xs`,children:`(DC)`}),t===l&&s===`playing`&&!oe&&e.connected&&(0,H.jsx)(`div`,{className:`w-2 h-2 rounded-full animate-pulse`,style:{backgroundColor:Ga[t]}})]},e.id))}),s===`playing`&&!oe&&(0,H.jsx)(`div`,{className:`text-center paper-font text-xs sm:text-sm text-gray-700`,children:l===O?(0,H.jsx)(`span`,{className:`text-blue-600 font-bold animate-pulse`,children:`Your turn!`}):(0,H.jsxs)(`span`,{children:[`Waiting for `,a[l]?.name,`...`]})}),oe&&(0,H.jsx)(`div`,{className:`text-center paper-font text-sm text-yellow-600 font-bold animate-pulse`,children:`Game Paused — Waiting for players to reconnect`}),s===`ended`&&(0,H.jsx)(`div`,{className:`text-center paper-font text-sm text-green-600 font-bold`,children:`Game Over!`})]}),(0,H.jsx)(`div`,{className:`glass p-2 sm:p-4 rounded-xl sm:rounded-2xl overflow-hidden`,children:(0,H.jsx)(Ra,{initialScale:Math.min(1,600/Math.max(me,he)),minScale:.3,maxScale:3,limitToBounds:!0,centerOnInit:!0,children:({zoomIn:e,zoomOut:t,resetTransform:n})=>(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(`div`,{className:`absolute top-2 right-2 z-10 flex gap-1`,children:[(0,H.jsx)(`button`,{onClick:()=>e(.2),className:`bg-white/80 rounded-full p-1 shadow hover:bg-white`,children:(0,H.jsx)(Sr,{size:16})}),(0,H.jsx)(`button`,{onClick:()=>t(.2),className:`bg-white/80 rounded-full p-1 shadow hover:bg-white`,children:(0,H.jsx)(xr,{size:16})}),(0,H.jsx)(`button`,{onClick:()=>n(),className:`bg-white/80 rounded-full p-1 shadow hover:bg-white`,children:(0,H.jsx)(Cr,{size:16})})]}),(0,H.jsx)(Ha,{children:(0,H.jsx)(`div`,{className:`select-none`,style:{touchAction:`none`},children:(0,H.jsxs)(`svg`,{viewBox:`-20 -20 ${me+40} ${he+40}`,className:`w-full h-auto`,style:{minWidth:`${me}px`},children:[b.map((e,t)=>e.map((e,n)=>e===null?null:(0,H.jsx)(`rect`,{x:n*40,y:t*40,width:40,height:40,fill:Ga[e],opacity:.3},`box-${t}-${n}`))),Array.from({length:d+1},(e,t)=>Array.from({length:p},(e,n)=>{let r=h[t]?.[n];return(0,H.jsxs)(`g`,{children:[r!==null&&(0,H.jsx)(`line`,{x1:n*40,y1:t*40,x2:(n+1)*40,y2:t*40,stroke:Ga[r],strokeWidth:3,vectorEffect:`non-scaling-stroke`}),(0,H.jsx)(`line`,{x1:n*40,y1:t*40,x2:(n+1)*40,y2:t*40,stroke:`transparent`,strokeWidth:16,style:{cursor:`pointer`,pointerEvents:`stroke`},onPointerDown:e=>fe(`h`,t,n,e)})]},`h-${t}-${n}`)})),Array.from({length:d},(e,t)=>Array.from({length:p+1},(e,n)=>{let r=v[t]?.[n];return(0,H.jsxs)(`g`,{children:[r!==null&&(0,H.jsx)(`line`,{x1:n*40,y1:t*40,x2:n*40,y2:(t+1)*40,stroke:Ga[r],strokeWidth:3,vectorEffect:`non-scaling-stroke`}),(0,H.jsx)(`line`,{x1:n*40,y1:t*40,x2:n*40,y2:(t+1)*40,stroke:`transparent`,strokeWidth:16,style:{cursor:`pointer`,pointerEvents:`stroke`},onPointerDown:e=>fe(`v`,t,n,e)})]},`v-${t}-${n}`)})),Array.from({length:d+1},(e,t)=>Array.from({length:p+1},(e,n)=>(0,H.jsx)(`circle`,{cx:n*40,cy:t*40,r:4,fill:`#333`,vectorEffect:`non-scaling-stroke`,style:{pointerEvents:`none`}},`dot-${t}-${n}`)))]})})})]})})})]}):(0,H.jsx)(`div`,{className:`w-full max-w-md`,children:(0,H.jsxs)(`div`,{className:`glass p-4 sm:p-6 rounded-xl sm:rounded-2xl mb-4 space-y-4`,children:[(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`label`,{className:`paper-font text-gray-600 text-sm mb-1 block`,children:`Mode`}),(0,H.jsxs)(`select`,{value:E,onChange:e=>D(e.target.value),className:`w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font`,children:[(0,H.jsx)(`option`,{value:`classic`,children:`Classic (9×9)`}),(0,H.jsx)(`option`,{value:`extended`,children:`Extended (14×14)`}),(0,H.jsx)(`option`,{value:`marathon`,children:`Marathon (19×19)`}),(0,H.jsx)(`option`,{value:`custom`,children:`Custom`})]})]}),E===`custom`&&(0,H.jsxs)(`div`,{className:`space-y-3`,children:[(0,H.jsxs)(`div`,{className:`flex gap-3`,children:[(0,H.jsxs)(`div`,{className:`flex-1`,children:[(0,H.jsx)(`label`,{className:`paper-font text-gray-600 text-sm mb-1 block`,children:`Rows (1-30)`}),(0,H.jsx)(`input`,{type:`number`,min:1,max:30,value:ee,onChange:e=>te(Math.max(1,Math.min(30,parseInt(e.target.value)||1))),className:`w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font`})]}),(0,H.jsxs)(`div`,{className:`flex-1`,children:[(0,H.jsx)(`label`,{className:`paper-font text-gray-600 text-sm mb-1 block`,children:`Cols (1-30)`}),(0,H.jsx)(`input`,{type:`number`,min:1,max:30,value:ne,onChange:e=>re(Math.max(1,Math.min(30,parseInt(e.target.value)||1))),className:`w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font`})]})]}),(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`label`,{className:`paper-font text-gray-600 text-sm mb-1 block`,children:`Players (2-4)`}),(0,H.jsx)(`input`,{type:`number`,min:2,max:4,value:ie,onChange:e=>ae(Math.max(2,Math.min(4,parseInt(e.target.value)||2))),className:`w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font`})]})]}),(0,H.jsxs)(`div`,{className:`flex gap-3 pt-2`,children:[(0,H.jsx)(U,{onClick:ue,className:`flex-1 text-sm sm:text-base px-3 py-2`,children:`Create Room`}),(0,H.jsx)(U,{onClick:de,variant:`secondary`,className:`flex-1 text-sm sm:text-base px-3 py-2`,children:`Join Room`})]})]})})]})},Ja=()=>{let e=He();return(0,H.jsxs)(`div`,{className:`min-h-screen flex flex-col items-center justify-center p-4`,children:[(0,H.jsx)(`h1`,{className:`text-9xl hand-drawn text-red-500 mb-4 animate-bounce`,children:`404`}),(0,H.jsx)(`p`,{className:`text-2xl paper-font text-gray-600 mb-8`,children:`Oops! This page got lost in the notebook.`}),(0,H.jsx)(U,{onClick:()=>e(`/`),children:`Take me Home`})]})};function Ya(){return(0,H.jsx)(mt,{children:(0,H.jsx)(`div`,{className:`min-h-screen`,children:(0,H.jsxs)(ut,{children:[(0,H.jsx)(ct,{path:`/`,element:(0,H.jsx)(Mr,{})}),(0,H.jsx)(ct,{path:`/bingo`,element:(0,H.jsx)(Wr,{})}),(0,H.jsx)(ct,{path:`/tictactoe`,element:(0,H.jsx)(Gr,{})}),(0,H.jsx)(ct,{path:`/uttt`,element:(0,H.jsx)(Jr,{})}),(0,H.jsx)(ct,{path:`/dab`,element:(0,H.jsx)(qa,{})}),(0,H.jsx)(ct,{path:`*`,element:(0,H.jsx)(Ja,{})})]})})})}v.createRoot(document.getElementById(`root`)).render((0,H.jsx)(_.StrictMode,{children:(0,H.jsx)(ar,{children:(0,H.jsx)(Ya,{})})}));export{o as t}; \ No newline at end of file diff --git a/pro/dist/assets/index-D8u_dQCt.css b/pro/dist/assets/index-D8u_dQCt.css new file mode 100644 index 0000000..6b2ed7f --- /dev/null +++ b/pro/dist/assets/index-D8u_dQCt.css @@ -0,0 +1,2587 @@ +/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */ +@layer properties { + @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or + ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) { + *, + :before, + :after, + ::backdrop { + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-translate-z: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-scale-z: 1; + --tw-rotate-x: initial; + --tw-rotate-y: initial; + --tw-rotate-z: initial; + --tw-skew-x: initial; + --tw-skew-y: initial; + --tw-space-y-reverse: 0; + --tw-border-style: solid; + --tw-gradient-position: initial; + --tw-gradient-from: #0000; + --tw-gradient-via: #0000; + --tw-gradient-to: #0000; + --tw-gradient-stops: initial; + --tw-gradient-via-stops: initial; + --tw-gradient-from-position: 0%; + --tw-gradient-via-position: 50%; + --tw-gradient-to-position: 100%; + --tw-leading: initial; + --tw-font-weight: initial; + --tw-tracking: initial; + --tw-shadow: 0 0 #0000; + --tw-shadow-color: initial; + --tw-shadow-alpha: 100%; + --tw-inset-shadow: 0 0 #0000; + --tw-inset-shadow-color: initial; + --tw-inset-shadow-alpha: 100%; + --tw-ring-color: initial; + --tw-ring-shadow: 0 0 #0000; + --tw-inset-ring-color: initial; + --tw-inset-ring-shadow: 0 0 #0000; + --tw-ring-inset: initial; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-offset-shadow: 0 0 #0000; + --tw-blur: initial; + --tw-brightness: initial; + --tw-contrast: initial; + --tw-grayscale: initial; + --tw-hue-rotate: initial; + --tw-invert: initial; + --tw-opacity: initial; + --tw-saturate: initial; + --tw-sepia: initial; + --tw-drop-shadow: initial; + --tw-drop-shadow-color: initial; + --tw-drop-shadow-alpha: 100%; + --tw-drop-shadow-size: initial; + --tw-duration: initial; + --tw-ease: initial; + } + } +} +@layer theme { + :root, + :host { + --font-sans: + ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; + --color-red-50: oklch(97.1% 0.013 17.38); + --color-red-100: oklch(93.6% 0.032 17.717); + --color-red-200: oklch(88.5% 0.062 18.334); + --color-red-400: oklch(70.4% 0.191 22.216); + --color-red-500: oklch(63.7% 0.237 25.331); + --color-red-600: oklch(57.7% 0.245 27.325); + --color-red-900: oklch(39.6% 0.141 25.723); + --color-orange-100: oklch(95.4% 0.038 75.164); + --color-orange-600: oklch(64.6% 0.222 41.116); + --color-yellow-50: oklch(98.7% 0.026 102.212); + --color-yellow-100: oklch(97.3% 0.071 103.193); + --color-yellow-200: oklch(94.5% 0.129 101.54); + --color-yellow-300: oklch(90.5% 0.182 98.111); + --color-yellow-400: oklch(85.2% 0.199 91.936); + --color-yellow-500: oklch(79.5% 0.184 86.047); + --color-yellow-600: oklch(68.1% 0.162 75.834); + --color-yellow-700: oklch(55.4% 0.135 66.442); + --color-green-50: oklch(98.2% 0.018 155.826); + --color-green-100: oklch(96.2% 0.044 156.743); + --color-green-200: oklch(92.5% 0.084 155.995); + --color-green-400: oklch(79.2% 0.209 151.711); + --color-green-500: oklch(72.3% 0.219 149.579); + --color-green-600: oklch(62.7% 0.194 149.214); + --color-green-700: oklch(52.7% 0.154 150.069); + --color-green-900: oklch(39.3% 0.095 152.535); + --color-sky-400: oklch(74.6% 0.16 232.661); + --color-blue-50: oklch(97% 0.014 254.604); + --color-blue-100: oklch(93.2% 0.032 255.585); + --color-blue-200: oklch(88.2% 0.059 254.128); + --color-blue-300: oklch(80.9% 0.105 251.813); + --color-blue-400: oklch(70.7% 0.165 254.624); + --color-blue-500: oklch(62.3% 0.214 259.815); + --color-blue-600: oklch(54.6% 0.245 262.881); + --color-blue-700: oklch(48.8% 0.243 264.376); + --color-blue-900: oklch(37.9% 0.146 265.522); + --color-purple-100: oklch(94.6% 0.033 307.174); + --color-purple-400: oklch(71.4% 0.203 305.504); + --color-purple-500: oklch(62.7% 0.265 303.9); + --color-purple-600: oklch(55.8% 0.288 302.321); + --color-purple-900: oklch(38.1% 0.176 304.987); + --color-gray-100: oklch(96.7% 0.003 264.542); + --color-gray-200: oklch(92.8% 0.006 264.531); + --color-gray-300: oklch(87.2% 0.01 258.338); + --color-gray-400: oklch(70.7% 0.022 261.325); + --color-gray-500: oklch(55.1% 0.027 264.364); + --color-gray-600: oklch(44.6% 0.03 256.802); + --color-gray-700: oklch(37.3% 0.034 259.733); + --color-gray-800: oklch(27.8% 0.033 256.848); + --color-white: #fff; + --spacing: 0.25rem; + --container-sm: 24rem; + --container-md: 28rem; + --container-2xl: 42rem; + --container-3xl: 48rem; + --container-4xl: 56rem; + --container-6xl: 72rem; + --text-xs: 0.75rem; + --text-xs--line-height: calc(1 / 0.75); + --text-sm: 0.875rem; + --text-sm--line-height: calc(1.25 / 0.875); + --text-base: 1rem; + --text-base--line-height: calc(1.5 / 1); + --text-lg: 1.125rem; + --text-lg--line-height: calc(1.75 / 1.125); + --text-xl: 1.25rem; + --text-xl--line-height: calc(1.75 / 1.25); + --text-2xl: 1.5rem; + --text-2xl--line-height: calc(2 / 1.5); + --text-3xl: 1.875rem; + --text-3xl--line-height: calc(2.25 / 1.875); + --text-4xl: 2.25rem; + --text-4xl--line-height: calc(2.5 / 2.25); + --text-5xl: 3rem; + --text-5xl--line-height: 1; + --text-6xl: 3.75rem; + --text-6xl--line-height: 1; + --text-7xl: 4.5rem; + --text-7xl--line-height: 1; + --text-8xl: 6rem; + --text-8xl--line-height: 1; + --text-9xl: 8rem; + --text-9xl--line-height: 1; + --font-weight-semibold: 600; + --font-weight-bold: 700; + --tracking-wider: 0.05em; + --tracking-widest: 0.1em; + --leading-relaxed: 1.625; + --radius-lg: 0.5rem; + --radius-xl: 0.75rem; + --radius-2xl: 1rem; + --radius-3xl: 1.5rem; + --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); + --animate-spin: spin 1s linear infinite; + --animate-ping: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite; + --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; + --animate-bounce: bounce 1s infinite; + --default-transition-duration: 0.15s; + --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + --default-font-family: var(--font-sans); + --default-mono-font-family: var(--font-mono); + --font-hand-drawn: 'Permanent Marker', cursive; + --font-paper: 'Schoolbell', cursive; + } +} +@layer base { + *, + :after, + :before, + ::backdrop { + box-sizing: border-box; + border: 0 solid; + margin: 0; + padding: 0; + } + ::file-selector-button { + box-sizing: border-box; + border: 0 solid; + margin: 0; + padding: 0; + } + html, + :host { + -webkit-text-size-adjust: 100%; + tab-size: 4; + line-height: 1.5; + font-family: var( + --default-font-family, + ui-sans-serif, + system-ui, + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji' + ); + font-feature-settings: var(--default-font-feature-settings, normal); + font-variation-settings: var(--default-font-variation-settings, normal); + -webkit-tap-highlight-color: transparent; + } + hr { + height: 0; + color: inherit; + border-top-width: 1px; + } + abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + } + h1, + h2, + h3, + h4, + h5, + h6 { + font-size: inherit; + font-weight: inherit; + } + a { + color: inherit; + -webkit-text-decoration: inherit; + -webkit-text-decoration: inherit; + -webkit-text-decoration: inherit; + -webkit-text-decoration: inherit; + text-decoration: inherit; + } + b, + strong { + font-weight: bolder; + } + code, + kbd, + samp, + pre { + font-family: var( + --default-mono-font-family, + ui-monospace, + SFMono-Regular, + Menlo, + Monaco, + Consolas, + 'Liberation Mono', + 'Courier New', + monospace + ); + font-feature-settings: var(--default-mono-font-feature-settings, normal); + font-variation-settings: var(--default-mono-font-variation-settings, normal); + font-size: 1em; + } + small { + font-size: 80%; + } + sub, + sup { + vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + } + sub { + bottom: -0.25em; + } + sup { + top: -0.5em; + } + table { + text-indent: 0; + border-color: inherit; + border-collapse: collapse; + } + :-moz-focusring { + outline: auto; + } + progress { + vertical-align: baseline; + } + summary { + display: list-item; + } + ol, + ul, + menu { + list-style: none; + } + img, + svg, + video, + canvas, + audio, + iframe, + embed, + object { + vertical-align: middle; + display: block; + } + img, + video { + max-width: 100%; + height: auto; + } + button, + input, + select, + optgroup, + textarea { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + opacity: 1; + background-color: #0000; + border-radius: 0; + } + ::file-selector-button { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + opacity: 1; + background-color: #0000; + border-radius: 0; + } + :where(select:is([multiple], [size])) optgroup { + font-weight: bolder; + } + :where(select:is([multiple], [size])) optgroup option { + padding-inline-start: 20px; + } + ::file-selector-button { + margin-inline-end: 4px; + } + ::placeholder { + opacity: 1; + } + @supports (not ((-webkit-appearance: -apple-pay-button))) or (contain-intrinsic-size: 1px) { + ::placeholder { + color: currentColor; + } + @supports (color: color-mix(in lab, red, red)) { + ::placeholder { + color: color-mix(in oklab, currentcolor 50%, transparent); + } + } + } + textarea { + resize: vertical; + } + ::-webkit-search-decoration { + -webkit-appearance: none; + } + ::-webkit-date-and-time-value { + min-height: 1lh; + text-align: inherit; + } + ::-webkit-datetime-edit { + display: inline-flex; + } + ::-webkit-datetime-edit-fields-wrapper { + padding: 0; + } + ::-webkit-datetime-edit { + padding-block: 0; + } + ::-webkit-datetime-edit-year-field { + padding-block: 0; + } + ::-webkit-datetime-edit-month-field { + padding-block: 0; + } + ::-webkit-datetime-edit-day-field { + padding-block: 0; + } + ::-webkit-datetime-edit-hour-field { + padding-block: 0; + } + ::-webkit-datetime-edit-minute-field { + padding-block: 0; + } + ::-webkit-datetime-edit-second-field { + padding-block: 0; + } + ::-webkit-datetime-edit-millisecond-field { + padding-block: 0; + } + ::-webkit-datetime-edit-meridiem-field { + padding-block: 0; + } + ::-webkit-calendar-picker-indicator { + line-height: 1; + } + :-moz-ui-invalid { + box-shadow: none; + } + button, + input:where([type='button'], [type='reset'], [type='submit']) { + appearance: button; + } + ::file-selector-button { + appearance: button; + } + ::-webkit-inner-spin-button { + height: auto; + } + ::-webkit-outer-spin-button { + height: auto; + } + [hidden]:where(:not([hidden='until-found'])) { + display: none !important; + } +} +@layer components; +@layer utilities { + .\@container { + container-type: inline-size; + } + .pointer-events-auto { + pointer-events: auto; + } + .pointer-events-none { + pointer-events: none; + } + .visible { + visibility: visible; + } + .absolute { + position: absolute; + } + .fixed { + position: fixed; + } + .relative { + position: relative; + } + .static { + position: static; + } + .-inset-1 { + inset: calc(var(--spacing) * -1); + } + .inset-0 { + inset: calc(var(--spacing) * 0); + } + .top-0 { + top: calc(var(--spacing) * 0); + } + .top-1\/4 { + top: 25%; + } + .top-2 { + top: calc(var(--spacing) * 2); + } + .top-4 { + top: calc(var(--spacing) * 4); + } + .-right-2 { + right: calc(var(--spacing) * -2); + } + .right-2 { + right: calc(var(--spacing) * 2); + } + .right-4 { + right: calc(var(--spacing) * 4); + } + .right-8 { + right: calc(var(--spacing) * 8); + } + .-bottom-2 { + bottom: calc(var(--spacing) * -2); + } + .bottom-1\/4 { + bottom: 25%; + } + .bottom-4 { + bottom: calc(var(--spacing) * 4); + } + .bottom-full { + bottom: 100%; + } + .-left-3 { + left: calc(var(--spacing) * -3); + } + .left-0 { + left: calc(var(--spacing) * 0); + } + .left-1\/2 { + left: 50%; + } + .left-4 { + left: calc(var(--spacing) * 4); + } + .left-8 { + left: calc(var(--spacing) * 8); + } + .z-10 { + z-index: 10; + } + .z-50 { + z-index: 50; + } + .container { + width: 100%; + } + @media (width>=40rem) { + .container { + max-width: 40rem; + } + } + @media (width>=48rem) { + .container { + max-width: 48rem; + } + } + @media (width>=64rem) { + .container { + max-width: 64rem; + } + } + @media (width>=80rem) { + .container { + max-width: 80rem; + } + } + @media (width>=96rem) { + .container { + max-width: 96rem; + } + } + .mx-auto { + margin-inline: auto; + } + .mt-1 { + margin-top: calc(var(--spacing) * 1); + } + .mt-2 { + margin-top: calc(var(--spacing) * 2); + } + .mt-3 { + margin-top: calc(var(--spacing) * 3); + } + .mt-4 { + margin-top: calc(var(--spacing) * 4); + } + .mt-8 { + margin-top: calc(var(--spacing) * 8); + } + .mr-1 { + margin-right: calc(var(--spacing) * 1); + } + .mb-1 { + margin-bottom: calc(var(--spacing) * 1); + } + .mb-2 { + margin-bottom: calc(var(--spacing) * 2); + } + .mb-3 { + margin-bottom: calc(var(--spacing) * 3); + } + .mb-4 { + margin-bottom: calc(var(--spacing) * 4); + } + .mb-6 { + margin-bottom: calc(var(--spacing) * 6); + } + .mb-8 { + margin-bottom: calc(var(--spacing) * 8); + } + .ml-1 { + margin-left: calc(var(--spacing) * 1); + } + .ml-auto { + margin-left: auto; + } + .block { + display: block; + } + .flex { + display: flex; + } + .grid { + display: grid; + } + .hidden { + display: none; + } + .inline { + display: inline; + } + .inline-block { + display: inline-block; + } + .aspect-square { + aspect-ratio: 1; + } + .h-1\.5 { + height: calc(var(--spacing) * 1.5); + } + .h-2 { + height: calc(var(--spacing) * 2); + } + .h-3 { + height: calc(var(--spacing) * 3); + } + .h-4 { + height: calc(var(--spacing) * 4); + } + .h-6 { + height: calc(var(--spacing) * 6); + } + .h-8 { + height: calc(var(--spacing) * 8); + } + .h-10 { + height: calc(var(--spacing) * 10); + } + .h-12 { + height: calc(var(--spacing) * 12); + } + .h-16 { + height: calc(var(--spacing) * 16); + } + .h-24 { + height: calc(var(--spacing) * 24); + } + .h-32 { + height: calc(var(--spacing) * 32); + } + .h-full { + height: 100%; + } + .h-px { + height: 1px; + } + .min-h-screen { + min-height: 100vh; + } + .w-1\.5 { + width: calc(var(--spacing) * 1.5); + } + .w-2 { + width: calc(var(--spacing) * 2); + } + .w-3 { + width: calc(var(--spacing) * 3); + } + .w-4 { + width: calc(var(--spacing) * 4); + } + .w-6 { + width: calc(var(--spacing) * 6); + } + .w-8 { + width: calc(var(--spacing) * 8); + } + .w-10 { + width: calc(var(--spacing) * 10); + } + .w-12 { + width: calc(var(--spacing) * 12); + } + .w-16 { + width: calc(var(--spacing) * 16); + } + .w-24 { + width: calc(var(--spacing) * 24); + } + .w-32 { + width: calc(var(--spacing) * 32); + } + .w-48 { + width: calc(var(--spacing) * 48); + } + .w-64 { + width: calc(var(--spacing) * 64); + } + .w-full { + width: 100%; + } + .w-px { + width: 1px; + } + .max-w-2xl { + max-width: var(--container-2xl); + } + .max-w-3xl { + max-width: var(--container-3xl); + } + .max-w-4xl { + max-width: var(--container-4xl); + } + .max-w-6xl { + max-width: var(--container-6xl); + } + .max-w-\[7rem\] { + max-width: 7rem; + } + .max-w-md { + max-width: var(--container-md); + } + .max-w-sm { + max-width: var(--container-sm); + } + .min-w-0 { + min-width: calc(var(--spacing) * 0); + } + .flex-1 { + flex: 1; + } + .flex-shrink-0 { + flex-shrink: 0; + } + .grow { + flex-grow: 1; + } + .-translate-x-1\/2 { + --tw-translate-x: calc(calc(1 / 2 * 100%) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } + .translate-y-0 { + --tw-translate-y: calc(var(--spacing) * 0); + translate: var(--tw-translate-x) var(--tw-translate-y); + } + .translate-y-2 { + --tw-translate-y: calc(var(--spacing) * 2); + translate: var(--tw-translate-x) var(--tw-translate-y); + } + .scale-105 { + --tw-scale-x: 105%; + --tw-scale-y: 105%; + --tw-scale-z: 105%; + scale: var(--tw-scale-x) var(--tw-scale-y); + } + .scale-110 { + --tw-scale-x: 110%; + --tw-scale-y: 110%; + --tw-scale-z: 110%; + scale: var(--tw-scale-x) var(--tw-scale-y); + } + .scale-\[1\.02\] { + scale: 1.02; + } + .-rotate-2 { + rotate: -2deg; + } + .-rotate-12 { + rotate: -12deg; + } + .-rotate-30 { + rotate: -30deg; + } + .rotate-1 { + rotate: 1deg; + } + .rotate-12 { + rotate: 12deg; + } + .rotate-45 { + rotate: 45deg; + } + .transform { + transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); + } + .animate-bounce { + animation: var(--animate-bounce); + } + .animate-ping { + animation: var(--animate-ping); + } + .animate-pulse { + animation: var(--animate-pulse); + } + .animate-spin { + animation: var(--animate-spin); + } + .cursor-default { + cursor: default; + } + .cursor-not-allowed { + cursor: not-allowed; + } + .cursor-pointer { + cursor: pointer; + } + .resize { + resize: both; + } + .grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); + } + .grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + .grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); + } + .flex-col { + flex-direction: column; + } + .flex-wrap { + flex-wrap: wrap; + } + .items-center { + align-items: center; + } + .items-start { + align-items: flex-start; + } + .justify-between { + justify-content: space-between; + } + .justify-center { + justify-content: center; + } + .justify-items-center { + justify-items: center; + } + .gap-0 { + gap: calc(var(--spacing) * 0); + } + .gap-0\.5 { + gap: calc(var(--spacing) * 0.5); + } + .gap-1 { + gap: calc(var(--spacing) * 1); + } + .gap-1\.5 { + gap: calc(var(--spacing) * 1.5); + } + .gap-2 { + gap: calc(var(--spacing) * 2); + } + .gap-3 { + gap: calc(var(--spacing) * 3); + } + .gap-4 { + gap: calc(var(--spacing) * 4); + } + .gap-6 { + gap: calc(var(--spacing) * 6); + } + .gap-8 { + gap: calc(var(--spacing) * 8); + } + :where(.space-y-1 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse))); + } + :where(.space-y-2 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse))); + } + :where(.space-y-3 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse))); + } + :where(.space-y-4 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse))); + } + :where(.space-y-6 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse))); + } + .truncate { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + .overflow-hidden { + overflow: hidden; + } + .rounded { + border-radius: 0.25rem; + } + .rounded-2xl { + border-radius: var(--radius-2xl); + } + .rounded-3xl { + border-radius: var(--radius-3xl); + } + .rounded-full { + border-radius: 3.40282e38px; + } + .rounded-lg { + border-radius: var(--radius-lg); + } + .rounded-xl { + border-radius: var(--radius-xl); + } + .border { + border-style: var(--tw-border-style); + border-width: 1px; + } + .border-2 { + border-style: var(--tw-border-style); + border-width: 2px; + } + .border-4 { + border-style: var(--tw-border-style); + border-width: 4px; + } + .border-t { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + } + .border-t-2 { + border-top-style: var(--tw-border-style); + border-top-width: 2px; + } + .border-b { + border-bottom-style: var(--tw-border-style); + border-bottom-width: 1px; + } + .border-dashed { + --tw-border-style: dashed; + border-style: dashed; + } + .border-blue-200 { + border-color: var(--color-blue-200); + } + .border-blue-200\/50 { + border-color: #bedbff80; + } + @supports (color: color-mix(in lab, red, red)) { + .border-blue-200\/50 { + border-color: color-mix(in oklab, var(--color-blue-200) 50%, transparent); + } + } + .border-blue-300 { + border-color: var(--color-blue-300); + } + .border-blue-400\/50 { + border-color: #54a2ff80; + } + @supports (color: color-mix(in lab, red, red)) { + .border-blue-400\/50 { + border-color: color-mix(in oklab, var(--color-blue-400) 50%, transparent); + } + } + .border-current { + border-color: currentColor; + } + .border-gray-200\/70 { + border-color: #e5e7ebb3; + } + @supports (color: color-mix(in lab, red, red)) { + .border-gray-200\/70 { + border-color: color-mix(in oklab, var(--color-gray-200) 70%, transparent); + } + } + .border-gray-300 { + border-color: var(--color-gray-300); + } + .border-gray-300\/30 { + border-color: #d1d5dc4d; + } + @supports (color: color-mix(in lab, red, red)) { + .border-gray-300\/30 { + border-color: color-mix(in oklab, var(--color-gray-300) 30%, transparent); + } + } + .border-gray-300\/50 { + border-color: #d1d5dc80; + } + @supports (color: color-mix(in lab, red, red)) { + .border-gray-300\/50 { + border-color: color-mix(in oklab, var(--color-gray-300) 50%, transparent); + } + } + .border-gray-800\/10 { + border-color: #1e29391a; + } + @supports (color: color-mix(in lab, red, red)) { + .border-gray-800\/10 { + border-color: color-mix(in oklab, var(--color-gray-800) 10%, transparent); + } + } + .border-green-400\/50 { + border-color: #05df7280; + } + @supports (color: color-mix(in lab, red, red)) { + .border-green-400\/50 { + border-color: color-mix(in oklab, var(--color-green-400) 50%, transparent); + } + } + .border-purple-400\/50 { + border-color: #c07eff80; + } + @supports (color: color-mix(in lab, red, red)) { + .border-purple-400\/50 { + border-color: color-mix(in oklab, var(--color-purple-400) 50%, transparent); + } + } + .border-red-200 { + border-color: var(--color-red-200); + } + .border-red-200\/50 { + border-color: #ffcaca80; + } + @supports (color: color-mix(in lab, red, red)) { + .border-red-200\/50 { + border-color: color-mix(in oklab, var(--color-red-200) 50%, transparent); + } + } + .border-red-400\/50 { + border-color: #ff656880; + } + @supports (color: color-mix(in lab, red, red)) { + .border-red-400\/50 { + border-color: color-mix(in oklab, var(--color-red-400) 50%, transparent); + } + } + .border-transparent { + border-color: #0000; + } + .border-yellow-400 { + border-color: var(--color-yellow-400); + } + .border-yellow-400\/70 { + border-color: #fac800b3; + } + @supports (color: color-mix(in lab, red, red)) { + .border-yellow-400\/70 { + border-color: color-mix(in oklab, var(--color-yellow-400) 70%, transparent); + } + } + .border-t-transparent { + border-top-color: #0000; + } + .bg-blue-50 { + background-color: var(--color-blue-50); + } + .bg-blue-50\/80 { + background-color: #eff6ffcc; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-blue-50\/80 { + background-color: color-mix(in oklab, var(--color-blue-50) 80%, transparent); + } + } + .bg-blue-100 { + background-color: var(--color-blue-100); + } + .bg-blue-500 { + background-color: var(--color-blue-500); + } + .bg-blue-500\/40 { + background-color: #3080ff66; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-blue-500\/40 { + background-color: color-mix(in oklab, var(--color-blue-500) 40%, transparent); + } + } + .bg-blue-500\/80 { + background-color: #3080ffcc; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-blue-500\/80 { + background-color: color-mix(in oklab, var(--color-blue-500) 80%, transparent); + } + } + .bg-gray-100\/90 { + background-color: #f3f4f6e6; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-gray-100\/90 { + background-color: color-mix(in oklab, var(--color-gray-100) 90%, transparent); + } + } + .bg-gray-200 { + background-color: var(--color-gray-200); + } + .bg-gray-300 { + background-color: var(--color-gray-300); + } + .bg-gray-500 { + background-color: var(--color-gray-500); + } + .bg-green-50 { + background-color: var(--color-green-50); + } + .bg-green-100 { + background-color: var(--color-green-100); + } + .bg-green-500 { + background-color: var(--color-green-500); + } + .bg-green-500\/40 { + background-color: #00c75866; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-green-500\/40 { + background-color: color-mix(in oklab, var(--color-green-500) 40%, transparent); + } + } + .bg-orange-100 { + background-color: var(--color-orange-100); + } + .bg-purple-500\/40 { + background-color: #ac4bff66; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-purple-500\/40 { + background-color: color-mix(in oklab, var(--color-purple-500) 40%, transparent); + } + } + .bg-red-50 { + background-color: var(--color-red-50); + } + .bg-red-50\/80 { + background-color: #fef2f2cc; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-red-50\/80 { + background-color: color-mix(in oklab, var(--color-red-50) 80%, transparent); + } + } + .bg-red-500 { + background-color: var(--color-red-500); + } + .bg-red-500\/30 { + background-color: #fb2c364d; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-red-500\/30 { + background-color: color-mix(in oklab, var(--color-red-500) 30%, transparent); + } + } + .bg-red-500\/40 { + background-color: #fb2c3666; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-red-500\/40 { + background-color: color-mix(in oklab, var(--color-red-500) 40%, transparent); + } + } + .bg-white { + background-color: var(--color-white); + } + .bg-white\/30 { + background-color: #ffffff4d; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/30 { + background-color: color-mix(in oklab, var(--color-white) 30%, transparent); + } + } + .bg-white\/50 { + background-color: #ffffff80; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/50 { + background-color: color-mix(in oklab, var(--color-white) 50%, transparent); + } + } + .bg-white\/60 { + background-color: #fff9; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/60 { + background-color: color-mix(in oklab, var(--color-white) 60%, transparent); + } + } + .bg-white\/80 { + background-color: #fffc; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/80 { + background-color: color-mix(in oklab, var(--color-white) 80%, transparent); + } + } + .bg-white\/95 { + background-color: #fffffff2; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/95 { + background-color: color-mix(in oklab, var(--color-white) 95%, transparent); + } + } + .bg-yellow-50 { + background-color: var(--color-yellow-50); + } + .bg-yellow-50\/60 { + background-color: #fefce899; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-yellow-50\/60 { + background-color: color-mix(in oklab, var(--color-yellow-50) 60%, transparent); + } + } + .bg-yellow-100 { + background-color: var(--color-yellow-100); + } + .bg-yellow-200 { + background-color: var(--color-yellow-200); + } + .bg-yellow-200\/70 { + background-color: #fff085b3; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-yellow-200\/70 { + background-color: color-mix(in oklab, var(--color-yellow-200) 70%, transparent); + } + } + .bg-yellow-300\/50 { + background-color: #ffe02a80; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-yellow-300\/50 { + background-color: color-mix(in oklab, var(--color-yellow-300) 50%, transparent); + } + } + .bg-yellow-400 { + background-color: var(--color-yellow-400); + } + .bg-yellow-500 { + background-color: var(--color-yellow-500); + } + .bg-yellow-500\/30 { + background-color: #edb2004d; + } + @supports (color: color-mix(in lab, red, red)) { + .bg-yellow-500\/30 { + background-color: color-mix(in oklab, var(--color-yellow-500) 30%, transparent); + } + } + .bg-gradient-to-b { + --tw-gradient-position: to bottom in oklab; + background-image: linear-gradient(var(--tw-gradient-stops)); + } + .bg-gradient-to-r { + --tw-gradient-position: to right in oklab; + background-image: linear-gradient(var(--tw-gradient-stops)); + } + .from-blue-600 { + --tw-gradient-from: var(--color-blue-600); + --tw-gradient-stops: var( + --tw-gradient-via-stops, + var(--tw-gradient-position), + var(--tw-gradient-from) var(--tw-gradient-from-position), + var(--tw-gradient-to) var(--tw-gradient-to-position) + ); + } + .from-transparent { + --tw-gradient-from: transparent; + --tw-gradient-stops: var( + --tw-gradient-via-stops, + var(--tw-gradient-position), + var(--tw-gradient-from) var(--tw-gradient-from-position), + var(--tw-gradient-to) var(--tw-gradient-to-position) + ); + } + .via-gray-300 { + --tw-gradient-via: var(--color-gray-300); + --tw-gradient-via-stops: + var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), + var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + .via-gray-400\/40 { + --tw-gradient-via: #99a1af66; + } + @supports (color: color-mix(in lab, red, red)) { + .via-gray-400\/40 { + --tw-gradient-via: color-mix(in oklab, var(--color-gray-400) 40%, transparent); + } + } + .via-gray-400\/40 { + --tw-gradient-via-stops: + var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), + var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + .to-purple-600 { + --tw-gradient-to: var(--color-purple-600); + --tw-gradient-stops: var( + --tw-gradient-via-stops, + var(--tw-gradient-position), + var(--tw-gradient-from) var(--tw-gradient-from-position), + var(--tw-gradient-to) var(--tw-gradient-to-position) + ); + } + .to-transparent { + --tw-gradient-to: transparent; + --tw-gradient-stops: var( + --tw-gradient-via-stops, + var(--tw-gradient-position), + var(--tw-gradient-from) var(--tw-gradient-from-position), + var(--tw-gradient-to) var(--tw-gradient-to-position) + ); + } + .bg-clip-text { + -webkit-background-clip: text; + background-clip: text; + } + .object-cover { + object-fit: cover; + } + .p-0\.5 { + padding: calc(var(--spacing) * 0.5); + } + .p-1\.5 { + padding: calc(var(--spacing) * 1.5); + } + .p-2 { + padding: calc(var(--spacing) * 2); + } + .p-3 { + padding: calc(var(--spacing) * 3); + } + .p-4 { + padding: calc(var(--spacing) * 4); + } + .p-6 { + padding: calc(var(--spacing) * 6); + } + .p-8 { + padding: calc(var(--spacing) * 8); + } + .px-1\.5 { + padding-inline: calc(var(--spacing) * 1.5); + } + .px-2 { + padding-inline: calc(var(--spacing) * 2); + } + .px-3 { + padding-inline: calc(var(--spacing) * 3); + } + .px-4 { + padding-inline: calc(var(--spacing) * 4); + } + .px-6 { + padding-inline: calc(var(--spacing) * 6); + } + .px-8 { + padding-inline: calc(var(--spacing) * 8); + } + .py-0\.5 { + padding-block: calc(var(--spacing) * 0.5); + } + .py-1 { + padding-block: calc(var(--spacing) * 1); + } + .py-1\.5 { + padding-block: calc(var(--spacing) * 1.5); + } + .py-2 { + padding-block: calc(var(--spacing) * 2); + } + .py-3 { + padding-block: calc(var(--spacing) * 3); + } + .py-4 { + padding-block: calc(var(--spacing) * 4); + } + .pt-2 { + padding-top: calc(var(--spacing) * 2); + } + .pt-3 { + padding-top: calc(var(--spacing) * 3); + } + .pt-4 { + padding-top: calc(var(--spacing) * 4); + } + .text-center { + text-align: center; + } + .text-left { + text-align: left; + } + .font-hand-drawn { + font-family: var(--font-hand-drawn); + } + .text-2xl { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + .text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } + .text-4xl { + font-size: var(--text-4xl); + line-height: var(--tw-leading, var(--text-4xl--line-height)); + } + .text-5xl { + font-size: var(--text-5xl); + line-height: var(--tw-leading, var(--text-5xl--line-height)); + } + .text-6xl { + font-size: var(--text-6xl); + line-height: var(--tw-leading, var(--text-6xl--line-height)); + } + .text-9xl { + font-size: var(--text-9xl); + line-height: var(--tw-leading, var(--text-9xl--line-height)); + } + .text-base { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + } + .text-lg { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + .text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + .text-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + .text-xs { + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + } + .text-\[6px\] { + font-size: 6px; + } + .text-\[10px\] { + font-size: 10px; + } + .leading-relaxed { + --tw-leading: var(--leading-relaxed); + line-height: var(--leading-relaxed); + } + .font-bold { + --tw-font-weight: var(--font-weight-bold); + font-weight: var(--font-weight-bold); + } + .font-semibold { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } + .tracking-wider { + --tw-tracking: var(--tracking-wider); + letter-spacing: var(--tracking-wider); + } + .tracking-widest { + --tw-tracking: var(--tracking-widest); + letter-spacing: var(--tracking-widest); + } + .whitespace-pre-wrap { + white-space: pre-wrap; + } + .text-\[\#1a1a2e\] { + color: #1a1a2e; + } + .text-\[\#c73e1d\] { + color: #c73e1d; + } + .text-blue-500 { + color: var(--color-blue-500); + } + .text-blue-600 { + color: var(--color-blue-600); + } + .text-blue-700 { + color: var(--color-blue-700); + } + .text-blue-900 { + color: var(--color-blue-900); + } + .text-gray-200 { + color: var(--color-gray-200); + } + .text-gray-300 { + color: var(--color-gray-300); + } + .text-gray-400 { + color: var(--color-gray-400); + } + .text-gray-500 { + color: var(--color-gray-500); + } + .text-gray-600 { + color: var(--color-gray-600); + } + .text-gray-700 { + color: var(--color-gray-700); + } + .text-gray-800 { + color: var(--color-gray-800); + } + .text-green-600 { + color: var(--color-green-600); + } + .text-green-700 { + color: var(--color-green-700); + } + .text-green-900 { + color: var(--color-green-900); + } + .text-orange-600 { + color: var(--color-orange-600); + } + .text-purple-900 { + color: var(--color-purple-900); + } + .text-red-500 { + color: var(--color-red-500); + } + .text-red-600 { + color: var(--color-red-600); + } + .text-red-900 { + color: var(--color-red-900); + } + .text-transparent { + color: #0000; + } + .text-white { + color: var(--color-white); + } + .text-white\/90 { + color: #ffffffe6; + } + @supports (color: color-mix(in lab, red, red)) { + .text-white\/90 { + color: color-mix(in oklab, var(--color-white) 90%, transparent); + } + } + .text-yellow-500 { + color: var(--color-yellow-500); + } + .text-yellow-600 { + color: var(--color-yellow-600); + } + .text-yellow-700 { + color: var(--color-yellow-700); + } + .capitalize { + text-transform: capitalize; + } + .uppercase { + text-transform: uppercase; + } + .italic { + font-style: italic; + } + .opacity-0 { + opacity: 0; + } + .opacity-5 { + opacity: 0.05; + } + .opacity-10 { + opacity: 0.1; + } + .opacity-20 { + opacity: 0.2; + } + .opacity-30 { + opacity: 0.3; + } + .opacity-40 { + opacity: 0.4; + } + .opacity-50 { + opacity: 0.5; + } + .opacity-60 { + opacity: 0.6; + } + .opacity-70 { + opacity: 0.7; + } + .opacity-100 { + opacity: 1; + } + .opacity-\[0\.03\] { + opacity: 0.03; + } + .mix-blend-multiply { + mix-blend-mode: multiply; + } + .shadow-lg { + --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, #0000001a), 0 4px 6px -4px var(--tw-shadow-color, #0000001a); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .shadow-md { + --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, #0000001a), 0 2px 4px -2px var(--tw-shadow-color, #0000001a); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .shadow-sm { + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .ring-1 { + --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) + var(--tw-ring-color, currentcolor); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .ring-2 { + --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) + var(--tw-ring-color, currentcolor); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .ring-4 { + --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) + var(--tw-ring-color, currentcolor); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .ring-blue-400 { + --tw-ring-color: var(--color-blue-400); + } + .ring-sky-400 { + --tw-ring-color: var(--color-sky-400); + } + .ring-yellow-400 { + --tw-ring-color: var(--color-yellow-400); + } + .ring-yellow-500 { + --tw-ring-color: var(--color-yellow-500); + } + .ring-offset-1 { + --tw-ring-offset-width: 1px; + --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + } + .ring-offset-2 { + --tw-ring-offset-width: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + } + .blur { + --tw-blur: blur(8px); + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) + var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); + } + .filter { + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) + var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); + } + .transition { + transition-property: + color, + background-color, + border-color, + outline-color, + text-decoration-color, + fill, + stroke, + --tw-gradient-from, + --tw-gradient-via, + --tw-gradient-to, + opacity, + box-shadow, + transform, + translate, + scale, + rotate, + filter, + -webkit-backdrop-filter, + backdrop-filter, + display, + content-visibility, + overlay, + pointer-events; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .transition-all { + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .transition-colors { + transition-property: + color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, + --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .transition-opacity { + transition-property: opacity; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .transition-transform { + transition-property: transform, translate, scale, rotate; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .duration-200 { + --tw-duration: 0.2s; + transition-duration: 0.2s; + } + .duration-300 { + --tw-duration: 0.3s; + transition-duration: 0.3s; + } + .duration-500 { + --tw-duration: 0.5s; + transition-duration: 0.5s; + } + .ease-in-out { + --tw-ease: var(--ease-in-out); + transition-timing-function: var(--ease-in-out); + } + .select-none { + -webkit-user-select: none; + user-select: none; + } + @media (hover: hover) { + .group-hover\:translate-x-1:is(:where(.group):hover *) { + --tw-translate-x: calc(var(--spacing) * 1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } + .group-hover\:text-gray-600:is(:where(.group):hover *) { + color: var(--color-gray-600); + } + .group-hover\:opacity-100:is(:where(.group):hover *) { + opacity: 1; + } + .hover\:-translate-y-1:hover { + --tw-translate-y: calc(var(--spacing) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } + .hover\:scale-105:hover { + --tw-scale-x: 105%; + --tw-scale-y: 105%; + --tw-scale-z: 105%; + scale: var(--tw-scale-x) var(--tw-scale-y); + } + .hover\:border-gray-400:hover { + border-color: var(--color-gray-400); + } + .hover\:bg-blue-100\/40:hover { + background-color: #dbeafe66; + } + @supports (color: color-mix(in lab, red, red)) { + .hover\:bg-blue-100\/40:hover { + background-color: color-mix(in oklab, var(--color-blue-100) 40%, transparent); + } + } + .hover\:bg-blue-500:hover { + background-color: var(--color-blue-500); + } + .hover\:bg-blue-500\/60:hover { + background-color: #3080ff99; + } + @supports (color: color-mix(in lab, red, red)) { + .hover\:bg-blue-500\/60:hover { + background-color: color-mix(in oklab, var(--color-blue-500) 60%, transparent); + } + } + .hover\:bg-blue-600:hover { + background-color: var(--color-blue-600); + } + .hover\:bg-gray-100:hover { + background-color: var(--color-gray-100); + } + .hover\:bg-gray-600:hover { + background-color: var(--color-gray-600); + } + .hover\:bg-green-100:hover { + background-color: var(--color-green-100); + } + .hover\:bg-green-200:hover { + background-color: var(--color-green-200); + } + .hover\:bg-green-500\/60:hover { + background-color: #00c75899; + } + @supports (color: color-mix(in lab, red, red)) { + .hover\:bg-green-500\/60:hover { + background-color: color-mix(in oklab, var(--color-green-500) 60%, transparent); + } + } + .hover\:bg-green-600:hover { + background-color: var(--color-green-600); + } + .hover\:bg-purple-500\/60:hover { + background-color: #ac4bff99; + } + @supports (color: color-mix(in lab, red, red)) { + .hover\:bg-purple-500\/60:hover { + background-color: color-mix(in oklab, var(--color-purple-500) 60%, transparent); + } + } + .hover\:bg-red-50:hover { + background-color: var(--color-red-50); + } + .hover\:bg-red-100:hover { + background-color: var(--color-red-100); + } + .hover\:bg-red-500\/60:hover { + background-color: #fb2c3699; + } + @supports (color: color-mix(in lab, red, red)) { + .hover\:bg-red-500\/60:hover { + background-color: color-mix(in oklab, var(--color-red-500) 60%, transparent); + } + } + .hover\:bg-red-600:hover { + background-color: var(--color-red-600); + } + .hover\:opacity-100:hover { + opacity: 1; + } + } + .focus\:border-transparent:focus { + border-color: #0000; + } + .focus\:ring-2:focus { + --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) + var(--tw-ring-color, currentcolor); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); + } + .focus\:ring-blue-400:focus { + --tw-ring-color: var(--color-blue-400); + } + .focus\:outline-none:focus { + --tw-outline-style: none; + outline-style: none; + } + .active\:scale-95:active { + --tw-scale-x: 95%; + --tw-scale-y: 95%; + --tw-scale-z: 95%; + scale: var(--tw-scale-x) var(--tw-scale-y); + } + .disabled\:transform-none:disabled { + transform: none; + } + .disabled\:cursor-not-allowed:disabled { + cursor: not-allowed; + } + .disabled\:opacity-50:disabled { + opacity: 0.5; + } + @media (width>=40rem) { + .sm\:col-span-2 { + grid-column: span 2 / span 2; + } + .sm\:mt-4 { + margin-top: calc(var(--spacing) * 4); + } + .sm\:mt-12 { + margin-top: calc(var(--spacing) * 12); + } + .sm\:mb-2 { + margin-bottom: calc(var(--spacing) * 2); + } + .sm\:mb-4 { + margin-bottom: calc(var(--spacing) * 4); + } + .sm\:mb-6 { + margin-bottom: calc(var(--spacing) * 6); + } + .sm\:mb-8 { + margin-bottom: calc(var(--spacing) * 8); + } + .sm\:mb-16 { + margin-bottom: calc(var(--spacing) * 16); + } + .sm\:block { + display: block; + } + .sm\:hidden { + display: none; + } + .sm\:inline { + display: inline; + } + .sm\:h-3 { + height: calc(var(--spacing) * 3); + } + .sm\:h-4 { + height: calc(var(--spacing) * 4); + } + .sm\:h-8 { + height: calc(var(--spacing) * 8); + } + .sm\:h-12 { + height: calc(var(--spacing) * 12); + } + .sm\:h-20 { + height: calc(var(--spacing) * 20); + } + .sm\:w-3 { + width: calc(var(--spacing) * 3); + } + .sm\:w-4 { + width: calc(var(--spacing) * 4); + } + .sm\:w-6 { + width: calc(var(--spacing) * 6); + } + .sm\:w-8 { + width: calc(var(--spacing) * 8); + } + .sm\:w-12 { + width: calc(var(--spacing) * 12); + } + .sm\:w-20 { + width: calc(var(--spacing) * 20); + } + .sm\:w-64 { + width: calc(var(--spacing) * 64); + } + .sm\:w-72 { + width: calc(var(--spacing) * 72); + } + .sm\:w-\[18px\] { + width: 18px; + } + .sm\:max-w-2xl { + max-width: var(--container-2xl); + } + .sm\:max-w-md { + max-width: var(--container-md); + } + .sm\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .sm\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .sm\:flex-row { + flex-direction: row; + } + .sm\:gap-1\.5 { + gap: calc(var(--spacing) * 1.5); + } + .sm\:gap-2 { + gap: calc(var(--spacing) * 2); + } + .sm\:gap-3 { + gap: calc(var(--spacing) * 3); + } + .sm\:gap-4 { + gap: calc(var(--spacing) * 4); + } + .sm\:gap-6 { + gap: calc(var(--spacing) * 6); + } + .sm\:p-1 { + padding: calc(var(--spacing) * 1); + } + .sm\:p-2 { + padding: calc(var(--spacing) * 2); + } + .sm\:p-4 { + padding: calc(var(--spacing) * 4); + } + .sm\:p-6 { + padding: calc(var(--spacing) * 6); + } + .sm\:p-8 { + padding: calc(var(--spacing) * 8); + } + .sm\:px-5 { + padding-inline: calc(var(--spacing) * 5); + } + .sm\:px-6 { + padding-inline: calc(var(--spacing) * 6); + } + .sm\:py-2 { + padding-block: calc(var(--spacing) * 2); + } + .sm\:py-3 { + padding-block: calc(var(--spacing) * 3); + } + .sm\:text-2xl { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + .sm\:text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } + .sm\:text-5xl { + font-size: var(--text-5xl); + line-height: var(--tw-leading, var(--text-5xl--line-height)); + } + .sm\:text-6xl { + font-size: var(--text-6xl); + line-height: var(--tw-leading, var(--text-6xl--line-height)); + } + .sm\:text-base { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + } + .sm\:text-lg { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + .sm\:text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + .sm\:text-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + .sm\:text-xs { + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + } + .sm\:text-\[8px\] { + font-size: 8px; + } + } + @media (width>=48rem) { + .md\:w-64 { + width: calc(var(--spacing) * 64); + } + .md\:w-80 { + width: calc(var(--spacing) * 80); + } + .md\:max-w-3xl { + max-width: var(--container-3xl); + } + .md\:flex-row { + flex-direction: row; + } + .md\:gap-2 { + gap: calc(var(--spacing) * 2); + } + .md\:gap-4 { + gap: calc(var(--spacing) * 4); + } + .md\:p-3 { + padding: calc(var(--spacing) * 3); + } + .md\:text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } + .md\:text-5xl { + font-size: var(--text-5xl); + line-height: var(--tw-leading, var(--text-5xl--line-height)); + } + .md\:text-6xl { + font-size: var(--text-6xl); + line-height: var(--tw-leading, var(--text-6xl--line-height)); + } + .md\:text-7xl { + font-size: var(--text-7xl); + line-height: var(--tw-leading, var(--text-7xl--line-height)); + } + .md\:text-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + .md\:text-xs { + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + } + } + @media (width>=64rem) { + .lg\:col-span-1 { + grid-column: span 1 / span 1; + } + .lg\:col-span-2 { + grid-column: span 2 / span 2; + } + .lg\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .lg\:text-2xl { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + .lg\:text-6xl { + font-size: var(--text-6xl); + line-height: var(--tw-leading, var(--text-6xl--line-height)); + } + .lg\:text-8xl { + font-size: var(--text-8xl); + line-height: var(--tw-leading, var(--text-8xl--line-height)); + } + } +} +.hand-drawn { + font-family: var(--font-hand-drawn); +} +.paper-font { + font-family: var(--font-paper); +} +.font-sketch { + letter-spacing: 0.5px; + font-family: Caveat, cursive; +} +.font-handwriting { + font-family: + Patrick Hand, + cursive; +} +.text-ink { + color: #2a2a3e; +} +.bg-paper { + background-color: #f5f1e8; + background-image: repeating-linear-gradient(0deg, #0000, #0000 30px, #8b634c0d 30px 31px); + position: relative; +} +.bg-paper:before { + content: ''; + pointer-events: none; + z-index: 0; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E"); + position: fixed; + inset: 0; +} +.sketch-card { + background: #fffef9; + border: 2px solid #2a2a3e; + border-radius: 3px; + position: relative; + transform: rotate(-0.5deg); + box-shadow: + 3px 3px #0000001a, + inset 0 0 0 1px #ffffff80; +} +.sketch-card:before { + content: ''; + opacity: 0.3; + pointer-events: none; + border: 2px solid #2a2a3e; + border-radius: 3px; + position: absolute; + inset: -2px; + transform: translate(1px, 1px); +} +.sketch-border { + background: #fffef999; + border: 2px dashed #8b7355; + border-radius: 2px; + padding: 1rem; +} +.sketch-button { + cursor: pointer; + background: #fffef9; + border: 2px solid #2a2a3e; + border-radius: 2px; + padding: 0.5rem 1rem; + font-family: + Patrick Hand, + cursive; + transition: all 0.2s; + position: relative; + transform: rotate(-0.3deg); + box-shadow: 2px 2px #0003; +} +.sketch-button:hover { + transform: rotate(0) translateY(-2px); + box-shadow: 3px 3px #0003; +} +.sketch-button:active { + transform: rotate(0) translateY(0); + box-shadow: 1px 1px #0003; +} +.player-badge { + border: 2px solid; + border-radius: 20px; + padding: 0.25rem 0.75rem; + font-family: + Patrick Hand, + cursive; + display: inline-block; + position: relative; + transform: rotate(-1deg); +} +.player-badge:after { + content: ''; + opacity: 0.3; + border: 2px solid; + border-radius: 20px; + position: absolute; + inset: 0; + transform: translate(1px, 1px); +} +.sketch-popup { + background: #fffef9 !important; + border: 3px solid #2a2a3e !important; + border-radius: 5px !important; + font-family: + Patrick Hand, + cursive !important; +} +.sketch-dot { + animation: 3s ease-in-out infinite sketch-wiggle; +} +@keyframes sketch-wiggle { + 0%, + to { + transform: rotate(0) translateY(0); + } + 25% { + transform: rotate(0.5deg) translateY(-1px); + } + 75% { + transform: rotate(-0.5deg) translateY(1px); + } +} +@keyframes wiggle { + 0%, + to { + transform: rotate(-1deg); + } + 50% { + transform: rotate(1deg); + } +} +@keyframes pencil-scribble { + 0% { + filter: brightness(); + } + 50% { + filter: brightness(1.2) contrast(1.1); + } + to { + filter: brightness(); + } +} +@keyframes screen-shake { + 0%, + to { + transform: translate(0); + } + 25% { + transform: translate(-2px, 2px); + } + 75% { + transform: translate(2px, -2px); + } +} +.glass { + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); + background: #ffffffb3; + border: 1px solid #ffffff4d; + box-shadow: 0 8px 32px #1f268726; +} +body { + background-color: #0000; + background-image: + linear-gradient(#ffffffe6, #ffffffe6), repeating-linear-gradient(0deg, #0000, #0000 19px, #e5e7eb 19px 20px), + repeating-linear-gradient(90deg, #0000, #0000 19px, #e5e7eb 19px 20px); + background-position: + 0 0, + 0 0, + 0 0; + background-repeat: repeat, repeat, repeat; + background-size: 20px 20px; + background-attachment: scroll, scroll, scroll; + background-origin: padding-box, padding-box, padding-box; + background-clip: border-box, border-box, border-box; + min-height: 100vh; +} +[data-theme='dark'] .text-ink { + color: #e5e7eb; +} +[data-theme='dark'] .bg-paper { + background-color: #1a1a2e; + background-image: repeating-linear-gradient(0deg, #0000, #0000 30px, #e5e7eb08 30px 31px); +} +[data-theme='dark'] .sketch-card { + background: #252542; + border: 2px solid #e5e7eb; +} +[data-theme='dark'] .sketch-card:before { + border: 2px solid #e5e7eb; +} +[data-theme='dark'] .sketch-button { + color: #e5e7eb; + background: #252542; + border: 2px solid #e5e7eb; +} +[data-theme='dark'] .glass { + background: #252542b3; + border: 1px solid #e5e7eb33; +} +[data-theme='dark'] .player-badge, +[data-theme='dark'] .font-sketch { + color: #e5e7eb; +} +[data-theme='dark'] .font-handwriting { + color: #d1d5e0; +} +@property --tw-translate-x { + syntax: '*'; + inherits: false; + initial-value: 0; +} +@property --tw-translate-y { + syntax: '*'; + inherits: false; + initial-value: 0; +} +@property --tw-translate-z { + syntax: '*'; + inherits: false; + initial-value: 0; +} +@property --tw-scale-x { + syntax: '*'; + inherits: false; + initial-value: 1; +} +@property --tw-scale-y { + syntax: '*'; + inherits: false; + initial-value: 1; +} +@property --tw-scale-z { + syntax: '*'; + inherits: false; + initial-value: 1; +} +@property --tw-rotate-x { + syntax: '*'; + inherits: false; +} +@property --tw-rotate-y { + syntax: '*'; + inherits: false; +} +@property --tw-rotate-z { + syntax: '*'; + inherits: false; +} +@property --tw-skew-x { + syntax: '*'; + inherits: false; +} +@property --tw-skew-y { + syntax: '*'; + inherits: false; +} +@property --tw-space-y-reverse { + syntax: '*'; + inherits: false; + initial-value: 0; +} +@property --tw-border-style { + syntax: '*'; + inherits: false; + initial-value: solid; +} +@property --tw-gradient-position { + syntax: '*'; + inherits: false; +} +@property --tw-gradient-from { + syntax: ''; + inherits: false; + initial-value: #0000; +} +@property --tw-gradient-via { + syntax: ''; + inherits: false; + initial-value: #0000; +} +@property --tw-gradient-to { + syntax: ''; + inherits: false; + initial-value: #0000; +} +@property --tw-gradient-stops { + syntax: '*'; + inherits: false; +} +@property --tw-gradient-via-stops { + syntax: '*'; + inherits: false; +} +@property --tw-gradient-from-position { + syntax: ''; + inherits: false; + initial-value: 0%; +} +@property --tw-gradient-via-position { + syntax: ''; + inherits: false; + initial-value: 50%; +} +@property --tw-gradient-to-position { + syntax: ''; + inherits: false; + initial-value: 100%; +} +@property --tw-leading { + syntax: '*'; + inherits: false; +} +@property --tw-font-weight { + syntax: '*'; + inherits: false; +} +@property --tw-tracking { + syntax: '*'; + inherits: false; +} +@property --tw-shadow { + syntax: '*'; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-shadow-color { + syntax: '*'; + inherits: false; +} +@property --tw-shadow-alpha { + syntax: ''; + inherits: false; + initial-value: 100%; +} +@property --tw-inset-shadow { + syntax: '*'; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-inset-shadow-color { + syntax: '*'; + inherits: false; +} +@property --tw-inset-shadow-alpha { + syntax: ''; + inherits: false; + initial-value: 100%; +} +@property --tw-ring-color { + syntax: '*'; + inherits: false; +} +@property --tw-ring-shadow { + syntax: '*'; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-inset-ring-color { + syntax: '*'; + inherits: false; +} +@property --tw-inset-ring-shadow { + syntax: '*'; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-ring-inset { + syntax: '*'; + inherits: false; +} +@property --tw-ring-offset-width { + syntax: ''; + inherits: false; + initial-value: 0; +} +@property --tw-ring-offset-color { + syntax: '*'; + inherits: false; + initial-value: #fff; +} +@property --tw-ring-offset-shadow { + syntax: '*'; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-blur { + syntax: '*'; + inherits: false; +} +@property --tw-brightness { + syntax: '*'; + inherits: false; +} +@property --tw-contrast { + syntax: '*'; + inherits: false; +} +@property --tw-grayscale { + syntax: '*'; + inherits: false; +} +@property --tw-hue-rotate { + syntax: '*'; + inherits: false; +} +@property --tw-invert { + syntax: '*'; + inherits: false; +} +@property --tw-opacity { + syntax: '*'; + inherits: false; +} +@property --tw-saturate { + syntax: '*'; + inherits: false; +} +@property --tw-sepia { + syntax: '*'; + inherits: false; +} +@property --tw-drop-shadow { + syntax: '*'; + inherits: false; +} +@property --tw-drop-shadow-color { + syntax: '*'; + inherits: false; +} +@property --tw-drop-shadow-alpha { + syntax: ''; + inherits: false; + initial-value: 100%; +} +@property --tw-drop-shadow-size { + syntax: '*'; + inherits: false; +} +@property --tw-duration { + syntax: '*'; + inherits: false; +} +@property --tw-ease { + syntax: '*'; + inherits: false; +} +@keyframes spin { + to { + transform: rotate(360deg); + } +} +@keyframes ping { + 75%, + to { + opacity: 0; + transform: scale(2); + } +} +@keyframes pulse { + 50% { + opacity: 0.5; + } +} +@keyframes bounce { + 0%, + to { + animation-timing-function: cubic-bezier(0.8, 0, 1, 1); + transform: translateY(-25%); + } + 50% { + animation-timing-function: cubic-bezier(0, 0, 0.2, 1); + transform: none; + } +} diff --git a/pro/dist/assets/index-DlQ4Zh9O.js b/pro/dist/assets/index-DlQ4Zh9O.js new file mode 100644 index 0000000..3eaa545 --- /dev/null +++ b/pro/dist/assets/index-DlQ4Zh9O.js @@ -0,0 +1,20904 @@ +var e = Object.create, + t = Object.defineProperty, + n = Object.getOwnPropertyDescriptor, + r = Object.getOwnPropertyNames, + i = Object.getPrototypeOf, + a = Object.prototype.hasOwnProperty, + o = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), (e = null)), t.exports), + s = (e, n) => { + let r = {}; + for (var i in e) t(r, i, { get: e[i], enumerable: !0 }); + return (n || t(r, Symbol.toStringTag, { value: `Module` }), r); + }, + c = (e, i, o, s) => { + if ((i && typeof i == `object`) || typeof i == `function`) + for (var c = r(i), l = 0, u = c.length, d; l < u; l++) + ((d = c[l]), + !a.call(e, d) && + d !== o && + t(e, d, { get: ((e) => i[e]).bind(null, d), enumerable: !(s = n(i, d)) || s.enumerable })); + return e; + }, + l = (n, r, a) => ( + (a = n == null ? {} : e(i(n))), + c(r || !n || !n.__esModule ? t(a, `default`, { value: n, enumerable: !0 }) : a, n) + ); +(function () { + let e = document.createElement(`link`).relList; + if (e && e.supports && e.supports(`modulepreload`)) return; + for (let e of document.querySelectorAll(`link[rel="modulepreload"]`)) n(e); + new MutationObserver((e) => { + for (let t of e) + if (t.type === `childList`) for (let e of t.addedNodes) e.tagName === `LINK` && e.rel === `modulepreload` && n(e); + }).observe(document, { childList: !0, subtree: !0 }); + function t(e) { + let t = {}; + return ( + e.integrity && (t.integrity = e.integrity), + e.referrerPolicy && (t.referrerPolicy = e.referrerPolicy), + e.crossOrigin === `use-credentials` + ? (t.credentials = `include`) + : e.crossOrigin === `anonymous` + ? (t.credentials = `omit`) + : (t.credentials = `same-origin`), + t + ); + } + function n(e) { + if (e.ep) return; + e.ep = !0; + let n = t(e); + fetch(e.href, n); + } +})(); +var u = o((e) => { + var t = Symbol.for(`react.element`), + n = Symbol.for(`react.portal`), + r = Symbol.for(`react.fragment`), + i = Symbol.for(`react.strict_mode`), + a = Symbol.for(`react.profiler`), + o = Symbol.for(`react.provider`), + s = Symbol.for(`react.context`), + c = Symbol.for(`react.forward_ref`), + l = Symbol.for(`react.suspense`), + u = Symbol.for(`react.memo`), + d = Symbol.for(`react.lazy`), + f = Symbol.iterator; + function p(e) { + return typeof e != `object` || !e + ? null + : ((e = (f && e[f]) || e[`@@iterator`]), typeof e == `function` ? e : null); + } + var m = { + isMounted: function () { + return !1; + }, + enqueueForceUpdate: function () {}, + enqueueReplaceState: function () {}, + enqueueSetState: function () {}, + }, + h = Object.assign, + g = {}; + function _(e, t, n) { + ((this.props = e), (this.context = t), (this.refs = g), (this.updater = n || m)); + } + ((_.prototype.isReactComponent = {}), + (_.prototype.setState = function (e, t) { + if (typeof e != `object` && typeof e != `function` && e != null) + throw Error( + `setState(...): takes an object of state variables to update or a function which returns an object of state variables.`, + ); + this.updater.enqueueSetState(this, e, t, `setState`); + }), + (_.prototype.forceUpdate = function (e) { + this.updater.enqueueForceUpdate(this, e, `forceUpdate`); + })); + function v() {} + v.prototype = _.prototype; + function y(e, t, n) { + ((this.props = e), (this.context = t), (this.refs = g), (this.updater = n || m)); + } + var b = (y.prototype = new v()); + ((b.constructor = y), h(b, _.prototype), (b.isPureReactComponent = !0)); + var x = Array.isArray, + S = Object.prototype.hasOwnProperty, + C = { current: null }, + w = { key: !0, ref: !0, __self: !0, __source: !0 }; + function T(e, n, r) { + var i, + a = {}, + o = null, + s = null; + if (n != null) + for (i in (n.ref !== void 0 && (s = n.ref), n.key !== void 0 && (o = `` + n.key), n)) + S.call(n, i) && !w.hasOwnProperty(i) && (a[i] = n[i]); + var c = arguments.length - 2; + if (c === 1) a.children = r; + else if (1 < c) { + for (var l = Array(c), u = 0; u < c; u++) l[u] = arguments[u + 2]; + a.children = l; + } + if (e && e.defaultProps) for (i in ((c = e.defaultProps), c)) a[i] === void 0 && (a[i] = c[i]); + return { $$typeof: t, type: e, key: o, ref: s, props: a, _owner: C.current }; + } + function E(e, n) { + return { $$typeof: t, type: e.type, key: n, ref: e.ref, props: e.props, _owner: e._owner }; + } + function D(e) { + return typeof e == `object` && !!e && e.$$typeof === t; + } + function O(e) { + var t = { '=': `=0`, ':': `=2` }; + return ( + `$` + + e.replace(/[=:]/g, function (e) { + return t[e]; + }) + ); + } + var k = /\/+/g; + function A(e, t) { + return typeof e == `object` && e && e.key != null ? O(`` + e.key) : t.toString(36); + } + function j(e, r, i, a, o) { + var s = typeof e; + (s === `undefined` || s === `boolean`) && (e = null); + var c = !1; + if (e === null) c = !0; + else + switch (s) { + case `string`: + case `number`: + c = !0; + break; + case `object`: + switch (e.$$typeof) { + case t: + case n: + c = !0; + } + } + if (c) + return ( + (c = e), + (o = o(c)), + (e = a === `` ? `.` + A(c, 0) : a), + x(o) + ? ((i = ``), + e != null && (i = e.replace(k, `$&/`) + `/`), + j(o, r, i, ``, function (e) { + return e; + })) + : o != null && + (D(o) && + (o = E(o, i + (!o.key || (c && c.key === o.key) ? `` : (`` + o.key).replace(k, `$&/`) + `/`) + e)), + r.push(o)), + 1 + ); + if (((c = 0), (a = a === `` ? `.` : a + `:`), x(e))) + for (var l = 0; l < e.length; l++) { + s = e[l]; + var u = a + A(s, l); + c += j(s, r, i, u, o); + } + else if (((u = p(e)), typeof u == `function`)) + for (e = u.call(e), l = 0; !(s = e.next()).done; ) + ((s = s.value), (u = a + A(s, l++)), (c += j(s, r, i, u, o))); + else if (s === `object`) + throw ( + (r = String(e)), + Error( + `Objects are not valid as a React child (found: ` + + (r === `[object Object]` ? `object with keys {` + Object.keys(e).join(`, `) + `}` : r) + + `). If you meant to render a collection of children, use an array instead.`, + ) + ); + return c; + } + function M(e, t, n) { + if (e == null) return e; + var r = [], + i = 0; + return ( + j(e, r, ``, ``, function (e) { + return t.call(n, e, i++); + }), + r + ); + } + function ee(e) { + if (e._status === -1) { + var t = e._result; + ((t = t()), + t.then( + function (t) { + (e._status === 0 || e._status === -1) && ((e._status = 1), (e._result = t)); + }, + function (t) { + (e._status === 0 || e._status === -1) && ((e._status = 2), (e._result = t)); + }, + ), + e._status === -1 && ((e._status = 0), (e._result = t))); + } + if (e._status === 1) return e._result.default; + throw e._result; + } + var N = { current: null }, + P = { transition: null }, + te = { ReactCurrentDispatcher: N, ReactCurrentBatchConfig: P, ReactCurrentOwner: C }; + function ne() { + throw Error(`act(...) is not supported in production builds of React.`); + } + ((e.Children = { + map: M, + forEach: function (e, t, n) { + M( + e, + function () { + t.apply(this, arguments); + }, + n, + ); + }, + count: function (e) { + var t = 0; + return ( + M(e, function () { + t++; + }), + t + ); + }, + toArray: function (e) { + return ( + M(e, function (e) { + return e; + }) || [] + ); + }, + only: function (e) { + if (!D(e)) throw Error(`React.Children.only expected to receive a single React element child.`); + return e; + }, + }), + (e.Component = _), + (e.Fragment = r), + (e.Profiler = a), + (e.PureComponent = y), + (e.StrictMode = i), + (e.Suspense = l), + (e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = te), + (e.act = ne), + (e.cloneElement = function (e, n, r) { + if (e == null) + throw Error(`React.cloneElement(...): The argument must be a React element, but you passed ` + e + `.`); + var i = h({}, e.props), + a = e.key, + o = e.ref, + s = e._owner; + if (n != null) { + if ( + (n.ref !== void 0 && ((o = n.ref), (s = C.current)), + n.key !== void 0 && (a = `` + n.key), + e.type && e.type.defaultProps) + ) + var c = e.type.defaultProps; + for (l in n) S.call(n, l) && !w.hasOwnProperty(l) && (i[l] = n[l] === void 0 && c !== void 0 ? c[l] : n[l]); + } + var l = arguments.length - 2; + if (l === 1) i.children = r; + else if (1 < l) { + c = Array(l); + for (var u = 0; u < l; u++) c[u] = arguments[u + 2]; + i.children = c; + } + return { $$typeof: t, type: e.type, key: a, ref: o, props: i, _owner: s }; + }), + (e.createContext = function (e) { + return ( + (e = { + $$typeof: s, + _currentValue: e, + _currentValue2: e, + _threadCount: 0, + Provider: null, + Consumer: null, + _defaultValue: null, + _globalName: null, + }), + (e.Provider = { $$typeof: o, _context: e }), + (e.Consumer = e) + ); + }), + (e.createElement = T), + (e.createFactory = function (e) { + var t = T.bind(null, e); + return ((t.type = e), t); + }), + (e.createRef = function () { + return { current: null }; + }), + (e.forwardRef = function (e) { + return { $$typeof: c, render: e }; + }), + (e.isValidElement = D), + (e.lazy = function (e) { + return { $$typeof: d, _payload: { _status: -1, _result: e }, _init: ee }; + }), + (e.memo = function (e, t) { + return { $$typeof: u, type: e, compare: t === void 0 ? null : t }; + }), + (e.startTransition = function (e) { + var t = P.transition; + P.transition = {}; + try { + e(); + } finally { + P.transition = t; + } + }), + (e.unstable_act = ne), + (e.useCallback = function (e, t) { + return N.current.useCallback(e, t); + }), + (e.useContext = function (e) { + return N.current.useContext(e); + }), + (e.useDebugValue = function () {}), + (e.useDeferredValue = function (e) { + return N.current.useDeferredValue(e); + }), + (e.useEffect = function (e, t) { + return N.current.useEffect(e, t); + }), + (e.useId = function () { + return N.current.useId(); + }), + (e.useImperativeHandle = function (e, t, n) { + return N.current.useImperativeHandle(e, t, n); + }), + (e.useInsertionEffect = function (e, t) { + return N.current.useInsertionEffect(e, t); + }), + (e.useLayoutEffect = function (e, t) { + return N.current.useLayoutEffect(e, t); + }), + (e.useMemo = function (e, t) { + return N.current.useMemo(e, t); + }), + (e.useReducer = function (e, t, n) { + return N.current.useReducer(e, t, n); + }), + (e.useRef = function (e) { + return N.current.useRef(e); + }), + (e.useState = function (e) { + return N.current.useState(e); + }), + (e.useSyncExternalStore = function (e, t, n) { + return N.current.useSyncExternalStore(e, t, n); + }), + (e.useTransition = function () { + return N.current.useTransition(); + }), + (e.version = `18.3.1`)); + }), + d = o((e, t) => { + t.exports = u(); + }), + f = o((e) => { + function t(e, t) { + var n = e.length; + e.push(t); + a: for (; 0 < n; ) { + var r = (n - 1) >>> 1, + a = e[r]; + if (0 < i(a, t)) ((e[r] = t), (e[n] = a), (n = r)); + else break a; + } + } + function n(e) { + return e.length === 0 ? null : e[0]; + } + function r(e) { + if (e.length === 0) return null; + var t = e[0], + n = e.pop(); + if (n !== t) { + e[0] = n; + a: for (var r = 0, a = e.length, o = a >>> 1; r < o; ) { + var s = 2 * (r + 1) - 1, + c = e[s], + l = s + 1, + u = e[l]; + if (0 > i(c, n)) l < a && 0 > i(u, c) ? ((e[r] = u), (e[l] = n), (r = l)) : ((e[r] = c), (e[s] = n), (r = s)); + else if (l < a && 0 > i(u, n)) ((e[r] = u), (e[l] = n), (r = l)); + else break a; + } + } + return t; + } + function i(e, t) { + var n = e.sortIndex - t.sortIndex; + return n === 0 ? e.id - t.id : n; + } + if (typeof performance == `object` && typeof performance.now == `function`) { + var a = performance; + e.unstable_now = function () { + return a.now(); + }; + } else { + var o = Date, + s = o.now(); + e.unstable_now = function () { + return o.now() - s; + }; + } + var c = [], + l = [], + u = 1, + d = null, + f = 3, + p = !1, + m = !1, + h = !1, + g = typeof setTimeout == `function` ? setTimeout : null, + _ = typeof clearTimeout == `function` ? clearTimeout : null, + v = typeof setImmediate < `u` ? setImmediate : null; + typeof navigator < `u` && + navigator.scheduling !== void 0 && + navigator.scheduling.isInputPending !== void 0 && + navigator.scheduling.isInputPending.bind(navigator.scheduling); + function y(e) { + for (var i = n(l); i !== null; ) { + if (i.callback === null) r(l); + else if (i.startTime <= e) (r(l), (i.sortIndex = i.expirationTime), t(c, i)); + else break; + i = n(l); + } + } + function b(e) { + if (((h = !1), y(e), !m)) + if (n(c) !== null) ((m = !0), M(x)); + else { + var t = n(l); + t !== null && ee(b, t.startTime - e); + } + } + function x(t, i) { + ((m = !1), h && ((h = !1), _(w), (w = -1)), (p = !0)); + var a = f; + try { + for (y(i), d = n(c); d !== null && (!(d.expirationTime > i) || (t && !D())); ) { + var o = d.callback; + if (typeof o == `function`) { + ((d.callback = null), (f = d.priorityLevel)); + var s = o(d.expirationTime <= i); + ((i = e.unstable_now()), typeof s == `function` ? (d.callback = s) : d === n(c) && r(c), y(i)); + } else r(c); + d = n(c); + } + if (d !== null) var u = !0; + else { + var g = n(l); + (g !== null && ee(b, g.startTime - i), (u = !1)); + } + return u; + } finally { + ((d = null), (f = a), (p = !1)); + } + } + var S = !1, + C = null, + w = -1, + T = 5, + E = -1; + function D() { + return !(e.unstable_now() - E < T); + } + function O() { + if (C !== null) { + var t = e.unstable_now(); + E = t; + var n = !0; + try { + n = C(!0, t); + } finally { + n ? k() : ((S = !1), (C = null)); + } + } else S = !1; + } + var k; + if (typeof v == `function`) + k = function () { + v(O); + }; + else if (typeof MessageChannel < `u`) { + var A = new MessageChannel(), + j = A.port2; + ((A.port1.onmessage = O), + (k = function () { + j.postMessage(null); + })); + } else + k = function () { + g(O, 0); + }; + function M(e) { + ((C = e), S || ((S = !0), k())); + } + function ee(t, n) { + w = g(function () { + t(e.unstable_now()); + }, n); + } + ((e.unstable_IdlePriority = 5), + (e.unstable_ImmediatePriority = 1), + (e.unstable_LowPriority = 4), + (e.unstable_NormalPriority = 3), + (e.unstable_Profiling = null), + (e.unstable_UserBlockingPriority = 2), + (e.unstable_cancelCallback = function (e) { + e.callback = null; + }), + (e.unstable_continueExecution = function () { + m || p || ((m = !0), M(x)); + }), + (e.unstable_forceFrameRate = function (e) { + 0 > e || 125 < e + ? console.error( + `forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`, + ) + : (T = 0 < e ? Math.floor(1e3 / e) : 5); + }), + (e.unstable_getCurrentPriorityLevel = function () { + return f; + }), + (e.unstable_getFirstCallbackNode = function () { + return n(c); + }), + (e.unstable_next = function (e) { + switch (f) { + case 1: + case 2: + case 3: + var t = 3; + break; + default: + t = f; + } + var n = f; + f = t; + try { + return e(); + } finally { + f = n; + } + }), + (e.unstable_pauseExecution = function () {}), + (e.unstable_requestPaint = function () {}), + (e.unstable_runWithPriority = function (e, t) { + switch (e) { + case 1: + case 2: + case 3: + case 4: + case 5: + break; + default: + e = 3; + } + var n = f; + f = e; + try { + return t(); + } finally { + f = n; + } + }), + (e.unstable_scheduleCallback = function (r, i, a) { + var o = e.unstable_now(); + switch ( + (typeof a == `object` && a ? ((a = a.delay), (a = typeof a == `number` && 0 < a ? o + a : o)) : (a = o), r) + ) { + case 1: + var s = -1; + break; + case 2: + s = 250; + break; + case 5: + s = 1073741823; + break; + case 4: + s = 1e4; + break; + default: + s = 5e3; + } + return ( + (s = a + s), + (r = { id: u++, callback: i, priorityLevel: r, startTime: a, expirationTime: s, sortIndex: -1 }), + a > o + ? ((r.sortIndex = a), + t(l, r), + n(c) === null && r === n(l) && (h ? (_(w), (w = -1)) : (h = !0), ee(b, a - o))) + : ((r.sortIndex = s), t(c, r), m || p || ((m = !0), M(x))), + r + ); + }), + (e.unstable_shouldYield = D), + (e.unstable_wrapCallback = function (e) { + var t = f; + return function () { + var n = f; + f = t; + try { + return e.apply(this, arguments); + } finally { + f = n; + } + }; + })); + }), + p = o((e, t) => { + t.exports = f(); + }), + m = o((e) => { + var t = d(), + n = p(); + function r(e) { + for (var t = `https://reactjs.org/docs/error-decoder.html?invariant=` + e, n = 1; n < arguments.length; n++) + t += `&args[]=` + encodeURIComponent(arguments[n]); + return ( + `Minified React error #` + + e + + `; visit ` + + t + + ` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` + ); + } + var i = new Set(), + a = {}; + function o(e, t) { + (s(e, t), s(e + `Capture`, t)); + } + function s(e, t) { + for (a[e] = t, e = 0; e < t.length; e++) i.add(t[e]); + } + var c = !(typeof window > `u` || window.document === void 0 || window.document.createElement === void 0), + l = Object.prototype.hasOwnProperty, + u = + /^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/, + f = {}, + m = {}; + function h(e) { + return l.call(m, e) ? !0 : l.call(f, e) ? !1 : u.test(e) ? (m[e] = !0) : ((f[e] = !0), !1); + } + function g(e, t, n, r) { + if (n !== null && n.type === 0) return !1; + switch (typeof t) { + case `function`: + case `symbol`: + return !0; + case `boolean`: + return r + ? !1 + : n === null + ? ((e = e.toLowerCase().slice(0, 5)), e !== `data-` && e !== `aria-`) + : !n.acceptsBooleans; + default: + return !1; + } + } + function _(e, t, n, r) { + if (t == null || g(e, t, n, r)) return !0; + if (r) return !1; + if (n !== null) + switch (n.type) { + case 3: + return !t; + case 4: + return !1 === t; + case 5: + return isNaN(t); + case 6: + return isNaN(t) || 1 > t; + } + return !1; + } + function v(e, t, n, r, i, a, o) { + ((this.acceptsBooleans = t === 2 || t === 3 || t === 4), + (this.attributeName = r), + (this.attributeNamespace = i), + (this.mustUseProperty = n), + (this.propertyName = e), + (this.type = t), + (this.sanitizeURL = a), + (this.removeEmptyString = o)); + } + var y = {}; + (`children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style` + .split(` `) + .forEach(function (e) { + y[e] = new v(e, 0, !1, e, null, !1, !1); + }), + [ + [`acceptCharset`, `accept-charset`], + [`className`, `class`], + [`htmlFor`, `for`], + [`httpEquiv`, `http-equiv`], + ].forEach(function (e) { + var t = e[0]; + y[t] = new v(t, 1, !1, e[1], null, !1, !1); + }), + [`contentEditable`, `draggable`, `spellCheck`, `value`].forEach(function (e) { + y[e] = new v(e, 2, !1, e.toLowerCase(), null, !1, !1); + }), + [`autoReverse`, `externalResourcesRequired`, `focusable`, `preserveAlpha`].forEach(function (e) { + y[e] = new v(e, 2, !1, e, null, !1, !1); + }), + `allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope` + .split(` `) + .forEach(function (e) { + y[e] = new v(e, 3, !1, e.toLowerCase(), null, !1, !1); + }), + [`checked`, `multiple`, `muted`, `selected`].forEach(function (e) { + y[e] = new v(e, 3, !0, e, null, !1, !1); + }), + [`capture`, `download`].forEach(function (e) { + y[e] = new v(e, 4, !1, e, null, !1, !1); + }), + [`cols`, `rows`, `size`, `span`].forEach(function (e) { + y[e] = new v(e, 6, !1, e, null, !1, !1); + }), + [`rowSpan`, `start`].forEach(function (e) { + y[e] = new v(e, 5, !1, e.toLowerCase(), null, !1, !1); + })); + var b = /[\-:]([a-z])/g; + function x(e) { + return e[1].toUpperCase(); + } + (`accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height` + .split(` `) + .forEach(function (e) { + var t = e.replace(b, x); + y[t] = new v(t, 1, !1, e, null, !1, !1); + }), + `xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type`.split(` `).forEach(function (e) { + var t = e.replace(b, x); + y[t] = new v(t, 1, !1, e, `http://www.w3.org/1999/xlink`, !1, !1); + }), + [`xml:base`, `xml:lang`, `xml:space`].forEach(function (e) { + var t = e.replace(b, x); + y[t] = new v(t, 1, !1, e, `http://www.w3.org/XML/1998/namespace`, !1, !1); + }), + [`tabIndex`, `crossOrigin`].forEach(function (e) { + y[e] = new v(e, 1, !1, e.toLowerCase(), null, !1, !1); + }), + (y.xlinkHref = new v(`xlinkHref`, 1, !1, `xlink:href`, `http://www.w3.org/1999/xlink`, !0, !1)), + [`src`, `href`, `action`, `formAction`].forEach(function (e) { + y[e] = new v(e, 1, !1, e.toLowerCase(), null, !0, !0); + })); + function S(e, t, n, r) { + var i = y.hasOwnProperty(t) ? y[t] : null; + (i === null + ? r || !(2 < t.length) || (t[0] !== `o` && t[0] !== `O`) || (t[1] !== `n` && t[1] !== `N`) + : i.type !== 0) && + (_(t, n, i, r) && (n = null), + r || i === null + ? h(t) && (n === null ? e.removeAttribute(t) : e.setAttribute(t, `` + n)) + : i.mustUseProperty + ? (e[i.propertyName] = n === null ? (i.type === 3 ? !1 : ``) : n) + : ((t = i.attributeName), + (r = i.attributeNamespace), + n === null + ? e.removeAttribute(t) + : ((i = i.type), + (n = i === 3 || (i === 4 && !0 === n) ? `` : `` + n), + r ? e.setAttributeNS(r, t, n) : e.setAttribute(t, n)))); + } + var C = t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, + w = Symbol.for(`react.element`), + T = Symbol.for(`react.portal`), + E = Symbol.for(`react.fragment`), + D = Symbol.for(`react.strict_mode`), + O = Symbol.for(`react.profiler`), + k = Symbol.for(`react.provider`), + A = Symbol.for(`react.context`), + j = Symbol.for(`react.forward_ref`), + M = Symbol.for(`react.suspense`), + ee = Symbol.for(`react.suspense_list`), + N = Symbol.for(`react.memo`), + P = Symbol.for(`react.lazy`), + te = Symbol.for(`react.offscreen`), + ne = Symbol.iterator; + function re(e) { + return typeof e != `object` || !e + ? null + : ((e = (ne && e[ne]) || e[`@@iterator`]), typeof e == `function` ? e : null); + } + var F = Object.assign, + ie; + function ae(e) { + if (ie === void 0) + try { + throw Error(); + } catch (e) { + var t = e.stack.trim().match(/\n( *(at )?)/); + ie = (t && t[1]) || ``; + } + return ( + ` +` + + ie + + e + ); + } + var oe = !1; + function se(e, t) { + if (!e || oe) return ``; + oe = !0; + var n = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + try { + if (t) + if ( + ((t = function () { + throw Error(); + }), + Object.defineProperty(t.prototype, `props`, { + set: function () { + throw Error(); + }, + }), + typeof Reflect == `object` && Reflect.construct) + ) { + try { + Reflect.construct(t, []); + } catch (e) { + var r = e; + } + Reflect.construct(e, [], t); + } else { + try { + t.call(); + } catch (e) { + r = e; + } + e.call(t.prototype); + } + else { + try { + throw Error(); + } catch (e) { + r = e; + } + e(); + } + } catch (t) { + if (t && r && typeof t.stack == `string`) { + for ( + var i = t.stack.split(` +`), + a = r.stack.split(` +`), + o = i.length - 1, + s = a.length - 1; + 1 <= o && 0 <= s && i[o] !== a[s]; + ) + s--; + for (; 1 <= o && 0 <= s; o--, s--) + if (i[o] !== a[s]) { + if (o !== 1 || s !== 1) + do + if ((o--, s--, 0 > s || i[o] !== a[s])) { + var c = + ` +` + i[o].replace(` at new `, ` at `); + return ( + e.displayName && c.includes(``) && (c = c.replace(``, e.displayName)), + c + ); + } + while (1 <= o && 0 <= s); + break; + } + } + } finally { + ((oe = !1), (Error.prepareStackTrace = n)); + } + return (e = e ? e.displayName || e.name : ``) ? ae(e) : ``; + } + function ce(e) { + switch (e.tag) { + case 5: + return ae(e.type); + case 16: + return ae(`Lazy`); + case 13: + return ae(`Suspense`); + case 19: + return ae(`SuspenseList`); + case 0: + case 2: + case 15: + return ((e = se(e.type, !1)), e); + case 11: + return ((e = se(e.type.render, !1)), e); + case 1: + return ((e = se(e.type, !0)), e); + default: + return ``; + } + } + function le(e) { + if (e == null) return null; + if (typeof e == `function`) return e.displayName || e.name || null; + if (typeof e == `string`) return e; + switch (e) { + case E: + return `Fragment`; + case T: + return `Portal`; + case O: + return `Profiler`; + case D: + return `StrictMode`; + case M: + return `Suspense`; + case ee: + return `SuspenseList`; + } + if (typeof e == `object`) + switch (e.$$typeof) { + case A: + return (e.displayName || `Context`) + `.Consumer`; + case k: + return (e._context.displayName || `Context`) + `.Provider`; + case j: + var t = e.render; + return ( + (e = e.displayName), + (e ||= ((e = t.displayName || t.name || ``), e === `` ? `ForwardRef` : `ForwardRef(` + e + `)`)), + e + ); + case N: + return ((t = e.displayName || null), t === null ? le(e.type) || `Memo` : t); + case P: + ((t = e._payload), (e = e._init)); + try { + return le(e(t)); + } catch {} + } + return null; + } + function ue(e) { + var t = e.type; + switch (e.tag) { + case 24: + return `Cache`; + case 9: + return (t.displayName || `Context`) + `.Consumer`; + case 10: + return (t._context.displayName || `Context`) + `.Provider`; + case 18: + return `DehydratedFragment`; + case 11: + return ( + (e = t.render), + (e = e.displayName || e.name || ``), + t.displayName || (e === `` ? `ForwardRef` : `ForwardRef(` + e + `)`) + ); + case 7: + return `Fragment`; + case 5: + return t; + case 4: + return `Portal`; + case 3: + return `Root`; + case 6: + return `Text`; + case 16: + return le(t); + case 8: + return t === D ? `StrictMode` : `Mode`; + case 22: + return `Offscreen`; + case 12: + return `Profiler`; + case 21: + return `Scope`; + case 13: + return `Suspense`; + case 19: + return `SuspenseList`; + case 25: + return `TracingMarker`; + case 1: + case 0: + case 17: + case 2: + case 14: + case 15: + if (typeof t == `function`) return t.displayName || t.name || null; + if (typeof t == `string`) return t; + } + return null; + } + function I(e) { + switch (typeof e) { + case `boolean`: + case `number`: + case `string`: + case `undefined`: + return e; + case `object`: + return e; + default: + return ``; + } + } + function de(e) { + var t = e.type; + return (e = e.nodeName) && e.toLowerCase() === `input` && (t === `checkbox` || t === `radio`); + } + function fe(e) { + var t = de(e) ? `checked` : `value`, + n = Object.getOwnPropertyDescriptor(e.constructor.prototype, t), + r = `` + e[t]; + if (!e.hasOwnProperty(t) && n !== void 0 && typeof n.get == `function` && typeof n.set == `function`) { + var i = n.get, + a = n.set; + return ( + Object.defineProperty(e, t, { + configurable: !0, + get: function () { + return i.call(this); + }, + set: function (e) { + ((r = `` + e), a.call(this, e)); + }, + }), + Object.defineProperty(e, t, { enumerable: n.enumerable }), + { + getValue: function () { + return r; + }, + setValue: function (e) { + r = `` + e; + }, + stopTracking: function () { + ((e._valueTracker = null), delete e[t]); + }, + } + ); + } + } + function L(e) { + e._valueTracker ||= fe(e); + } + function pe(e) { + if (!e) return !1; + var t = e._valueTracker; + if (!t) return !0; + var n = t.getValue(), + r = ``; + return (e && (r = de(e) ? (e.checked ? `true` : `false`) : e.value), (e = r), e === n ? !1 : (t.setValue(e), !0)); + } + function me(e) { + if (((e ||= typeof document < `u` ? document : void 0), e === void 0)) return null; + try { + return e.activeElement || e.body; + } catch { + return e.body; + } + } + function he(e, t) { + var n = t.checked; + return F({}, t, { + defaultChecked: void 0, + defaultValue: void 0, + value: void 0, + checked: n ?? e._wrapperState.initialChecked, + }); + } + function R(e, t) { + var n = t.defaultValue == null ? `` : t.defaultValue, + r = t.checked == null ? t.defaultChecked : t.checked; + ((n = I(t.value == null ? n : t.value)), + (e._wrapperState = { + initialChecked: r, + initialValue: n, + controlled: t.type === `checkbox` || t.type === `radio` ? t.checked != null : t.value != null, + })); + } + function ge(e, t) { + ((t = t.checked), t != null && S(e, `checked`, t, !1)); + } + function _e(e, t) { + ge(e, t); + var n = I(t.value), + r = t.type; + if (n != null) + r === `number` + ? ((n === 0 && e.value === ``) || e.value != n) && (e.value = `` + n) + : e.value !== `` + n && (e.value = `` + n); + else if (r === `submit` || r === `reset`) { + e.removeAttribute(`value`); + return; + } + (t.hasOwnProperty(`value`) + ? ye(e, t.type, n) + : t.hasOwnProperty(`defaultValue`) && ye(e, t.type, I(t.defaultValue)), + t.checked == null && t.defaultChecked != null && (e.defaultChecked = !!t.defaultChecked)); + } + function ve(e, t, n) { + if (t.hasOwnProperty(`value`) || t.hasOwnProperty(`defaultValue`)) { + var r = t.type; + if (!((r !== `submit` && r !== `reset`) || (t.value !== void 0 && t.value !== null))) return; + ((t = `` + e._wrapperState.initialValue), n || t === e.value || (e.value = t), (e.defaultValue = t)); + } + ((n = e.name), + n !== `` && (e.name = ``), + (e.defaultChecked = !!e._wrapperState.initialChecked), + n !== `` && (e.name = n)); + } + function ye(e, t, n) { + (t !== `number` || me(e.ownerDocument) !== e) && + (n == null + ? (e.defaultValue = `` + e._wrapperState.initialValue) + : e.defaultValue !== `` + n && (e.defaultValue = `` + n)); + } + var be = Array.isArray; + function xe(e, t, n, r) { + if (((e = e.options), t)) { + t = {}; + for (var i = 0; i < n.length; i++) t[`$` + n[i]] = !0; + for (n = 0; n < e.length; n++) + ((i = t.hasOwnProperty(`$` + e[n].value)), + e[n].selected !== i && (e[n].selected = i), + i && r && (e[n].defaultSelected = !0)); + } else { + for (n = `` + I(n), t = null, i = 0; i < e.length; i++) { + if (e[i].value === n) { + ((e[i].selected = !0), r && (e[i].defaultSelected = !0)); + return; + } + t !== null || e[i].disabled || (t = e[i]); + } + t !== null && (t.selected = !0); + } + } + function Se(e, t) { + if (t.dangerouslySetInnerHTML != null) throw Error(r(91)); + return F({}, t, { value: void 0, defaultValue: void 0, children: `` + e._wrapperState.initialValue }); + } + function Ce(e, t) { + var n = t.value; + if (n == null) { + if (((n = t.children), (t = t.defaultValue), n != null)) { + if (t != null) throw Error(r(92)); + if (be(n)) { + if (1 < n.length) throw Error(r(93)); + n = n[0]; + } + t = n; + } + ((t ??= ``), (n = t)); + } + e._wrapperState = { initialValue: I(n) }; + } + function we(e, t) { + var n = I(t.value), + r = I(t.defaultValue); + (n != null && + ((n = `` + n), + n !== e.value && (e.value = n), + t.defaultValue == null && e.defaultValue !== n && (e.defaultValue = n)), + r != null && (e.defaultValue = `` + r)); + } + function Te(e) { + var t = e.textContent; + t === e._wrapperState.initialValue && t !== `` && t !== null && (e.value = t); + } + function Ee(e) { + switch (e) { + case `svg`: + return `http://www.w3.org/2000/svg`; + case `math`: + return `http://www.w3.org/1998/Math/MathML`; + default: + return `http://www.w3.org/1999/xhtml`; + } + } + function De(e, t) { + return e == null || e === `http://www.w3.org/1999/xhtml` + ? Ee(t) + : e === `http://www.w3.org/2000/svg` && t === `foreignObject` + ? `http://www.w3.org/1999/xhtml` + : e; + } + var Oe, + ke = (function (e) { + return typeof MSApp < `u` && MSApp.execUnsafeLocalFunction + ? function (t, n, r, i) { + MSApp.execUnsafeLocalFunction(function () { + return e(t, n, r, i); + }); + } + : e; + })(function (e, t) { + if (e.namespaceURI !== `http://www.w3.org/2000/svg` || `innerHTML` in e) e.innerHTML = t; + else { + for ( + Oe ||= document.createElement(`div`), + Oe.innerHTML = `` + t.valueOf().toString() + ``, + t = Oe.firstChild; + e.firstChild; + ) + e.removeChild(e.firstChild); + for (; t.firstChild; ) e.appendChild(t.firstChild); + } + }); + function Ae(e, t) { + if (t) { + var n = e.firstChild; + if (n && n === e.lastChild && n.nodeType === 3) { + n.nodeValue = t; + return; + } + } + e.textContent = t; + } + var je = { + animationIterationCount: !0, + aspectRatio: !0, + borderImageOutset: !0, + borderImageSlice: !0, + borderImageWidth: !0, + boxFlex: !0, + boxFlexGroup: !0, + boxOrdinalGroup: !0, + columnCount: !0, + columns: !0, + flex: !0, + flexGrow: !0, + flexPositive: !0, + flexShrink: !0, + flexNegative: !0, + flexOrder: !0, + gridArea: !0, + gridRow: !0, + gridRowEnd: !0, + gridRowSpan: !0, + gridRowStart: !0, + gridColumn: !0, + gridColumnEnd: !0, + gridColumnSpan: !0, + gridColumnStart: !0, + fontWeight: !0, + lineClamp: !0, + lineHeight: !0, + opacity: !0, + order: !0, + orphans: !0, + tabSize: !0, + widows: !0, + zIndex: !0, + zoom: !0, + fillOpacity: !0, + floodOpacity: !0, + stopOpacity: !0, + strokeDasharray: !0, + strokeDashoffset: !0, + strokeMiterlimit: !0, + strokeOpacity: !0, + strokeWidth: !0, + }, + Me = [`Webkit`, `ms`, `Moz`, `O`]; + Object.keys(je).forEach(function (e) { + Me.forEach(function (t) { + ((t = t + e.charAt(0).toUpperCase() + e.substring(1)), (je[t] = je[e])); + }); + }); + function Ne(e, t, n) { + return t == null || typeof t == `boolean` || t === `` + ? `` + : n || typeof t != `number` || t === 0 || (je.hasOwnProperty(e) && je[e]) + ? (`` + t).trim() + : t + `px`; + } + function Pe(e, t) { + for (var n in ((e = e.style), t)) + if (t.hasOwnProperty(n)) { + var r = n.indexOf(`--`) === 0, + i = Ne(n, t[n], r); + (n === `float` && (n = `cssFloat`), r ? e.setProperty(n, i) : (e[n] = i)); + } + } + var Fe = F( + { menuitem: !0 }, + { + area: !0, + base: !0, + br: !0, + col: !0, + embed: !0, + hr: !0, + img: !0, + input: !0, + keygen: !0, + link: !0, + meta: !0, + param: !0, + source: !0, + track: !0, + wbr: !0, + }, + ); + function Ie(e, t) { + if (t) { + if (Fe[e] && (t.children != null || t.dangerouslySetInnerHTML != null)) throw Error(r(137, e)); + if (t.dangerouslySetInnerHTML != null) { + if (t.children != null) throw Error(r(60)); + if (typeof t.dangerouslySetInnerHTML != `object` || !(`__html` in t.dangerouslySetInnerHTML)) + throw Error(r(61)); + } + if (t.style != null && typeof t.style != `object`) throw Error(r(62)); + } + } + function Le(e, t) { + if (e.indexOf(`-`) === -1) return typeof t.is == `string`; + switch (e) { + case `annotation-xml`: + case `color-profile`: + case `font-face`: + case `font-face-src`: + case `font-face-uri`: + case `font-face-format`: + case `font-face-name`: + case `missing-glyph`: + return !1; + default: + return !0; + } + } + var Re = null; + function ze(e) { + return ( + (e = e.target || e.srcElement || window), + e.correspondingUseElement && (e = e.correspondingUseElement), + e.nodeType === 3 ? e.parentNode : e + ); + } + var Be = null, + Ve = null, + He = null; + function Ue(e) { + if ((e = q(e))) { + if (typeof Be != `function`) throw Error(r(280)); + var t = e.stateNode; + t && ((t = J(t)), Be(e.stateNode, e.type, t)); + } + } + function We(e) { + Ve ? (He ? He.push(e) : (He = [e])) : (Ve = e); + } + function Ge() { + if (Ve) { + var e = Ve, + t = He; + if (((He = Ve = null), Ue(e), t)) for (e = 0; e < t.length; e++) Ue(t[e]); + } + } + function Ke(e, t) { + return e(t); + } + function qe() {} + var Je = !1; + function Ye(e, t, n) { + if (Je) return e(t, n); + Je = !0; + try { + return Ke(e, t, n); + } finally { + ((Je = !1), (Ve !== null || He !== null) && (qe(), Ge())); + } + } + function Xe(e, t) { + var n = e.stateNode; + if (n === null) return null; + var i = J(n); + if (i === null) return null; + n = i[t]; + a: switch (t) { + case `onClick`: + case `onClickCapture`: + case `onDoubleClick`: + case `onDoubleClickCapture`: + case `onMouseDown`: + case `onMouseDownCapture`: + case `onMouseMove`: + case `onMouseMoveCapture`: + case `onMouseUp`: + case `onMouseUpCapture`: + case `onMouseEnter`: + ((i = !i.disabled) || + ((e = e.type), (i = !(e === `button` || e === `input` || e === `select` || e === `textarea`))), + (e = !i)); + break a; + default: + e = !1; + } + if (e) return null; + if (n && typeof n != `function`) throw Error(r(231, t, typeof n)); + return n; + } + var Ze = !1; + if (c) + try { + var Qe = {}; + (Object.defineProperty(Qe, `passive`, { + get: function () { + Ze = !0; + }, + }), + window.addEventListener(`test`, Qe, Qe), + window.removeEventListener(`test`, Qe, Qe)); + } catch { + Ze = !1; + } + function z(e, t, n, r, i, a, o, s, c) { + var l = Array.prototype.slice.call(arguments, 3); + try { + t.apply(n, l); + } catch (e) { + this.onError(e); + } + } + var $e = !1, + et = null, + tt = !1, + nt = null, + rt = { + onError: function (e) { + (($e = !0), (et = e)); + }, + }; + function it(e, t, n, r, i, a, o, s, c) { + (($e = !1), (et = null), z.apply(rt, arguments)); + } + function at(e, t, n, i, a, o, s, c, l) { + if ((it.apply(this, arguments), $e)) { + if ($e) { + var u = et; + (($e = !1), (et = null)); + } else throw Error(r(198)); + tt || ((tt = !0), (nt = u)); + } + } + function ot(e) { + var t = e, + n = e; + if (e.alternate) for (; t.return; ) t = t.return; + else { + e = t; + do ((t = e), t.flags & 4098 && (n = t.return), (e = t.return)); + while (e); + } + return t.tag === 3 ? n : null; + } + function st(e) { + if (e.tag === 13) { + var t = e.memoizedState; + if ((t === null && ((e = e.alternate), e !== null && (t = e.memoizedState)), t !== null)) return t.dehydrated; + } + return null; + } + function ct(e) { + if (ot(e) !== e) throw Error(r(188)); + } + function lt(e) { + var t = e.alternate; + if (!t) { + if (((t = ot(e)), t === null)) throw Error(r(188)); + return t === e ? e : null; + } + for (var n = e, i = t; ; ) { + var a = n.return; + if (a === null) break; + var o = a.alternate; + if (o === null) { + if (((i = a.return), i !== null)) { + n = i; + continue; + } + break; + } + if (a.child === o.child) { + for (o = a.child; o; ) { + if (o === n) return (ct(a), e); + if (o === i) return (ct(a), t); + o = o.sibling; + } + throw Error(r(188)); + } + if (n.return !== i.return) ((n = a), (i = o)); + else { + for (var s = !1, c = a.child; c; ) { + if (c === n) { + ((s = !0), (n = a), (i = o)); + break; + } + if (c === i) { + ((s = !0), (i = a), (n = o)); + break; + } + c = c.sibling; + } + if (!s) { + for (c = o.child; c; ) { + if (c === n) { + ((s = !0), (n = o), (i = a)); + break; + } + if (c === i) { + ((s = !0), (i = o), (n = a)); + break; + } + c = c.sibling; + } + if (!s) throw Error(r(189)); + } + } + if (n.alternate !== i) throw Error(r(190)); + } + if (n.tag !== 3) throw Error(r(188)); + return n.stateNode.current === n ? e : t; + } + function ut(e) { + return ((e = lt(e)), e === null ? null : dt(e)); + } + function dt(e) { + if (e.tag === 5 || e.tag === 6) return e; + for (e = e.child; e !== null; ) { + var t = dt(e); + if (t !== null) return t; + e = e.sibling; + } + return null; + } + var ft = n.unstable_scheduleCallback, + pt = n.unstable_cancelCallback, + mt = n.unstable_shouldYield, + ht = n.unstable_requestPaint, + gt = n.unstable_now, + _t = n.unstable_getCurrentPriorityLevel, + vt = n.unstable_ImmediatePriority, + yt = n.unstable_UserBlockingPriority, + bt = n.unstable_NormalPriority, + xt = n.unstable_LowPriority, + St = n.unstable_IdlePriority, + Ct = null, + wt = null; + function Tt(e) { + if (wt && typeof wt.onCommitFiberRoot == `function`) + try { + wt.onCommitFiberRoot(Ct, e, void 0, (e.current.flags & 128) == 128); + } catch {} + } + var Et = Math.clz32 ? Math.clz32 : kt, + Dt = Math.log, + Ot = Math.LN2; + function kt(e) { + return ((e >>>= 0), e === 0 ? 32 : (31 - ((Dt(e) / Ot) | 0)) | 0); + } + var At = 64, + jt = 4194304; + function Mt(e) { + switch (e & -e) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return e & 4194240; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return e & 130023424; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 1073741824; + default: + return e; + } + } + function Nt(e, t) { + var n = e.pendingLanes; + if (n === 0) return 0; + var r = 0, + i = e.suspendedLanes, + a = e.pingedLanes, + o = n & 268435455; + if (o !== 0) { + var s = o & ~i; + s === 0 ? ((a &= o), a !== 0 && (r = Mt(a))) : (r = Mt(s)); + } else ((o = n & ~i), o === 0 ? a !== 0 && (r = Mt(a)) : (r = Mt(o))); + if (r === 0) return 0; + if (t !== 0 && t !== r && (t & i) === 0 && ((i = r & -r), (a = t & -t), i >= a || (i === 16 && a & 4194240))) + return t; + if ((r & 4 && (r |= n & 16), (t = e.entangledLanes), t !== 0)) + for (e = e.entanglements, t &= r; 0 < t; ) ((n = 31 - Et(t)), (i = 1 << n), (r |= e[n]), (t &= ~i)); + return r; + } + function Pt(e, t) { + switch (e) { + case 1: + case 2: + case 4: + return t + 250; + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return t + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return -1; + case 134217728: + case 268435456: + case 536870912: + case 1073741824: + return -1; + default: + return -1; + } + } + function Ft(e, t) { + for (var n = e.suspendedLanes, r = e.pingedLanes, i = e.expirationTimes, a = e.pendingLanes; 0 < a; ) { + var o = 31 - Et(a), + s = 1 << o, + c = i[o]; + (c === -1 ? ((s & n) === 0 || (s & r) !== 0) && (i[o] = Pt(s, t)) : c <= t && (e.expiredLanes |= s), (a &= ~s)); + } + } + function It(e) { + return ((e = e.pendingLanes & -1073741825), e === 0 ? (e & 1073741824 ? 1073741824 : 0) : e); + } + function Lt() { + var e = At; + return ((At <<= 1), !(At & 4194240) && (At = 64), e); + } + function Rt(e) { + for (var t = [], n = 0; 31 > n; n++) t.push(e); + return t; + } + function zt(e, t, n) { + ((e.pendingLanes |= t), + t !== 536870912 && ((e.suspendedLanes = 0), (e.pingedLanes = 0)), + (e = e.eventTimes), + (t = 31 - Et(t)), + (e[t] = n)); + } + function Bt(e, t) { + var n = e.pendingLanes & ~t; + ((e.pendingLanes = t), + (e.suspendedLanes = 0), + (e.pingedLanes = 0), + (e.expiredLanes &= t), + (e.mutableReadLanes &= t), + (e.entangledLanes &= t), + (t = e.entanglements)); + var r = e.eventTimes; + for (e = e.expirationTimes; 0 < n; ) { + var i = 31 - Et(n), + a = 1 << i; + ((t[i] = 0), (r[i] = -1), (e[i] = -1), (n &= ~a)); + } + } + function Vt(e, t) { + var n = (e.entangledLanes |= t); + for (e = e.entanglements; n; ) { + var r = 31 - Et(n), + i = 1 << r; + ((i & t) | (e[r] & t) && (e[r] |= t), (n &= ~i)); + } + } + var B = 0; + function Ht(e) { + return ((e &= -e), 1 < e ? (4 < e ? (e & 268435455 ? 16 : 536870912) : 4) : 1); + } + var Ut, + Wt, + Gt, + Kt, + qt, + Jt = !1, + Yt = [], + Xt = null, + Zt = null, + Qt = null, + $t = new Map(), + en = new Map(), + tn = [], + nn = + `mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit`.split( + ` `, + ); + function rn(e, t) { + switch (e) { + case `focusin`: + case `focusout`: + Xt = null; + break; + case `dragenter`: + case `dragleave`: + Zt = null; + break; + case `mouseover`: + case `mouseout`: + Qt = null; + break; + case `pointerover`: + case `pointerout`: + $t.delete(t.pointerId); + break; + case `gotpointercapture`: + case `lostpointercapture`: + en.delete(t.pointerId); + } + } + function an(e, t, n, r, i, a) { + return e === null || e.nativeEvent !== a + ? ((e = { blockedOn: t, domEventName: n, eventSystemFlags: r, nativeEvent: a, targetContainers: [i] }), + t !== null && ((t = q(t)), t !== null && Wt(t)), + e) + : ((e.eventSystemFlags |= r), (t = e.targetContainers), i !== null && t.indexOf(i) === -1 && t.push(i), e); + } + function on(e, t, n, r, i) { + switch (t) { + case `focusin`: + return ((Xt = an(Xt, e, t, n, r, i)), !0); + case `dragenter`: + return ((Zt = an(Zt, e, t, n, r, i)), !0); + case `mouseover`: + return ((Qt = an(Qt, e, t, n, r, i)), !0); + case `pointerover`: + var a = i.pointerId; + return ($t.set(a, an($t.get(a) || null, e, t, n, r, i)), !0); + case `gotpointercapture`: + return ((a = i.pointerId), en.set(a, an(en.get(a) || null, e, t, n, r, i)), !0); + } + return !1; + } + function sn(e) { + var t = Fi(e.target); + if (t !== null) { + var n = ot(t); + if (n !== null) { + if (((t = n.tag), t === 13)) { + if (((t = st(n)), t !== null)) { + ((e.blockedOn = t), + qt(e.priority, function () { + Gt(n); + })); + return; + } + } else if (t === 3 && n.stateNode.current.memoizedState.isDehydrated) { + e.blockedOn = n.tag === 3 ? n.stateNode.containerInfo : null; + return; + } + } + } + e.blockedOn = null; + } + function cn(e) { + if (e.blockedOn !== null) return !1; + for (var t = e.targetContainers; 0 < t.length; ) { + var n = yn(e.domEventName, e.eventSystemFlags, t[0], e.nativeEvent); + if (n === null) { + n = e.nativeEvent; + var r = new n.constructor(n.type, n); + ((Re = r), n.target.dispatchEvent(r), (Re = null)); + } else return ((t = q(n)), t !== null && Wt(t), (e.blockedOn = n), !1); + t.shift(); + } + return !0; + } + function ln(e, t, n) { + cn(e) && n.delete(t); + } + function un() { + ((Jt = !1), + Xt !== null && cn(Xt) && (Xt = null), + Zt !== null && cn(Zt) && (Zt = null), + Qt !== null && cn(Qt) && (Qt = null), + $t.forEach(ln), + en.forEach(ln)); + } + function dn(e, t) { + e.blockedOn === t && + ((e.blockedOn = null), Jt || ((Jt = !0), n.unstable_scheduleCallback(n.unstable_NormalPriority, un))); + } + function fn(e) { + function t(t) { + return dn(t, e); + } + if (0 < Yt.length) { + dn(Yt[0], e); + for (var n = 1; n < Yt.length; n++) { + var r = Yt[n]; + r.blockedOn === e && (r.blockedOn = null); + } + } + for ( + Xt !== null && dn(Xt, e), + Zt !== null && dn(Zt, e), + Qt !== null && dn(Qt, e), + $t.forEach(t), + en.forEach(t), + n = 0; + n < tn.length; + n++ + ) + ((r = tn[n]), r.blockedOn === e && (r.blockedOn = null)); + for (; 0 < tn.length && ((n = tn[0]), n.blockedOn === null); ) (sn(n), n.blockedOn === null && tn.shift()); + } + var pn = C.ReactCurrentBatchConfig, + mn = !0; + function hn(e, t, n, r) { + var i = B, + a = pn.transition; + pn.transition = null; + try { + ((B = 1), _n(e, t, n, r)); + } finally { + ((B = i), (pn.transition = a)); + } + } + function gn(e, t, n, r) { + var i = B, + a = pn.transition; + pn.transition = null; + try { + ((B = 4), _n(e, t, n, r)); + } finally { + ((B = i), (pn.transition = a)); + } + } + function _n(e, t, n, r) { + if (mn) { + var i = yn(e, t, n, r); + if (i === null) (ci(e, t, r, vn, n), rn(e, r)); + else if (on(i, e, t, n, r)) r.stopPropagation(); + else if ((rn(e, r), t & 4 && -1 < nn.indexOf(e))) { + for (; i !== null; ) { + var a = q(i); + if ((a !== null && Ut(a), (a = yn(e, t, n, r)), a === null && ci(e, t, r, vn, n), a === i)) break; + i = a; + } + i !== null && r.stopPropagation(); + } else ci(e, t, r, null, n); + } + } + var vn = null; + function yn(e, t, n, r) { + if (((vn = null), (e = ze(r)), (e = Fi(e)), e !== null)) + if (((t = ot(e)), t === null)) e = null; + else if (((n = t.tag), n === 13)) { + if (((e = st(t)), e !== null)) return e; + e = null; + } else if (n === 3) { + if (t.stateNode.current.memoizedState.isDehydrated) return t.tag === 3 ? t.stateNode.containerInfo : null; + e = null; + } else t !== e && (e = null); + return ((vn = e), null); + } + function bn(e) { + switch (e) { + case `cancel`: + case `click`: + case `close`: + case `contextmenu`: + case `copy`: + case `cut`: + case `auxclick`: + case `dblclick`: + case `dragend`: + case `dragstart`: + case `drop`: + case `focusin`: + case `focusout`: + case `input`: + case `invalid`: + case `keydown`: + case `keypress`: + case `keyup`: + case `mousedown`: + case `mouseup`: + case `paste`: + case `pause`: + case `play`: + case `pointercancel`: + case `pointerdown`: + case `pointerup`: + case `ratechange`: + case `reset`: + case `resize`: + case `seeked`: + case `submit`: + case `touchcancel`: + case `touchend`: + case `touchstart`: + case `volumechange`: + case `change`: + case `selectionchange`: + case `textInput`: + case `compositionstart`: + case `compositionend`: + case `compositionupdate`: + case `beforeblur`: + case `afterblur`: + case `beforeinput`: + case `blur`: + case `fullscreenchange`: + case `focus`: + case `hashchange`: + case `popstate`: + case `select`: + case `selectstart`: + return 1; + case `drag`: + case `dragenter`: + case `dragexit`: + case `dragleave`: + case `dragover`: + case `mousemove`: + case `mouseout`: + case `mouseover`: + case `pointermove`: + case `pointerout`: + case `pointerover`: + case `scroll`: + case `toggle`: + case `touchmove`: + case `wheel`: + case `mouseenter`: + case `mouseleave`: + case `pointerenter`: + case `pointerleave`: + return 4; + case `message`: + switch (_t()) { + case vt: + return 1; + case yt: + return 4; + case bt: + case xt: + return 16; + case St: + return 536870912; + default: + return 16; + } + default: + return 16; + } + } + var xn = null, + Sn = null, + Cn = null; + function wn() { + if (Cn) return Cn; + var e, + t = Sn, + n = t.length, + r, + i = `value` in xn ? xn.value : xn.textContent, + a = i.length; + for (e = 0; e < n && t[e] === i[e]; e++); + var o = n - e; + for (r = 1; r <= o && t[n - r] === i[a - r]; r++); + return (Cn = i.slice(e, 1 < r ? 1 - r : void 0)); + } + function Tn(e) { + var t = e.keyCode; + return ( + `charCode` in e ? ((e = e.charCode), e === 0 && t === 13 && (e = 13)) : (e = t), + e === 10 && (e = 13), + 32 <= e || e === 13 ? e : 0 + ); + } + function En() { + return !0; + } + function Dn() { + return !1; + } + function On(e) { + function t(t, n, r, i, a) { + for (var o in ((this._reactName = t), + (this._targetInst = r), + (this.type = n), + (this.nativeEvent = i), + (this.target = a), + (this.currentTarget = null), + e)) + e.hasOwnProperty(o) && ((t = e[o]), (this[o] = t ? t(i) : i[o])); + return ( + (this.isDefaultPrevented = (i.defaultPrevented == null ? !1 === i.returnValue : i.defaultPrevented) + ? En + : Dn), + (this.isPropagationStopped = Dn), + this + ); + } + return ( + F(t.prototype, { + preventDefault: function () { + this.defaultPrevented = !0; + var e = this.nativeEvent; + e && + (e.preventDefault ? e.preventDefault() : typeof e.returnValue != `unknown` && (e.returnValue = !1), + (this.isDefaultPrevented = En)); + }, + stopPropagation: function () { + var e = this.nativeEvent; + e && + (e.stopPropagation ? e.stopPropagation() : typeof e.cancelBubble != `unknown` && (e.cancelBubble = !0), + (this.isPropagationStopped = En)); + }, + persist: function () {}, + isPersistent: En, + }), + t + ); + } + var kn = { + eventPhase: 0, + bubbles: 0, + cancelable: 0, + timeStamp: function (e) { + return e.timeStamp || Date.now(); + }, + defaultPrevented: 0, + isTrusted: 0, + }, + An = On(kn), + jn = F({}, kn, { view: 0, detail: 0 }), + Mn = On(jn), + Nn, + Pn, + Fn, + In = F({}, jn, { + screenX: 0, + screenY: 0, + clientX: 0, + clientY: 0, + pageX: 0, + pageY: 0, + ctrlKey: 0, + shiftKey: 0, + altKey: 0, + metaKey: 0, + getModifierState: Kn, + button: 0, + buttons: 0, + relatedTarget: function (e) { + return e.relatedTarget === void 0 + ? e.fromElement === e.srcElement + ? e.toElement + : e.fromElement + : e.relatedTarget; + }, + movementX: function (e) { + return `movementX` in e + ? e.movementX + : (e !== Fn && + (Fn && e.type === `mousemove` + ? ((Nn = e.screenX - Fn.screenX), (Pn = e.screenY - Fn.screenY)) + : (Pn = Nn = 0), + (Fn = e)), + Nn); + }, + movementY: function (e) { + return `movementY` in e ? e.movementY : Pn; + }, + }), + Ln = On(In), + Rn = On(F({}, In, { dataTransfer: 0 })), + zn = On(F({}, jn, { relatedTarget: 0 })), + Bn = On(F({}, kn, { animationName: 0, elapsedTime: 0, pseudoElement: 0 })), + V = On( + F({}, kn, { + clipboardData: function (e) { + return `clipboardData` in e ? e.clipboardData : window.clipboardData; + }, + }), + ), + Vn = On(F({}, kn, { data: 0 })), + Hn = { + Esc: `Escape`, + Spacebar: ` `, + Left: `ArrowLeft`, + Up: `ArrowUp`, + Right: `ArrowRight`, + Down: `ArrowDown`, + Del: `Delete`, + Win: `OS`, + Menu: `ContextMenu`, + Apps: `ContextMenu`, + Scroll: `ScrollLock`, + MozPrintableKey: `Unidentified`, + }, + Un = { + 8: `Backspace`, + 9: `Tab`, + 12: `Clear`, + 13: `Enter`, + 16: `Shift`, + 17: `Control`, + 18: `Alt`, + 19: `Pause`, + 20: `CapsLock`, + 27: `Escape`, + 32: ` `, + 33: `PageUp`, + 34: `PageDown`, + 35: `End`, + 36: `Home`, + 37: `ArrowLeft`, + 38: `ArrowUp`, + 39: `ArrowRight`, + 40: `ArrowDown`, + 45: `Insert`, + 46: `Delete`, + 112: `F1`, + 113: `F2`, + 114: `F3`, + 115: `F4`, + 116: `F5`, + 117: `F6`, + 118: `F7`, + 119: `F8`, + 120: `F9`, + 121: `F10`, + 122: `F11`, + 123: `F12`, + 144: `NumLock`, + 145: `ScrollLock`, + 224: `Meta`, + }, + Wn = { Alt: `altKey`, Control: `ctrlKey`, Meta: `metaKey`, Shift: `shiftKey` }; + function Gn(e) { + var t = this.nativeEvent; + return t.getModifierState ? t.getModifierState(e) : (e = Wn[e]) ? !!t[e] : !1; + } + function Kn() { + return Gn; + } + var qn = On( + F({}, jn, { + key: function (e) { + if (e.key) { + var t = Hn[e.key] || e.key; + if (t !== `Unidentified`) return t; + } + return e.type === `keypress` + ? ((e = Tn(e)), e === 13 ? `Enter` : String.fromCharCode(e)) + : e.type === `keydown` || e.type === `keyup` + ? Un[e.keyCode] || `Unidentified` + : ``; + }, + code: 0, + location: 0, + ctrlKey: 0, + shiftKey: 0, + altKey: 0, + metaKey: 0, + repeat: 0, + locale: 0, + getModifierState: Kn, + charCode: function (e) { + return e.type === `keypress` ? Tn(e) : 0; + }, + keyCode: function (e) { + return e.type === `keydown` || e.type === `keyup` ? e.keyCode : 0; + }, + which: function (e) { + return e.type === `keypress` ? Tn(e) : e.type === `keydown` || e.type === `keyup` ? e.keyCode : 0; + }, + }), + ), + Jn = On( + F({}, In, { + pointerId: 0, + width: 0, + height: 0, + pressure: 0, + tangentialPressure: 0, + tiltX: 0, + tiltY: 0, + twist: 0, + pointerType: 0, + isPrimary: 0, + }), + ), + Yn = On( + F({}, jn, { + touches: 0, + targetTouches: 0, + changedTouches: 0, + altKey: 0, + metaKey: 0, + ctrlKey: 0, + shiftKey: 0, + getModifierState: Kn, + }), + ), + Xn = On(F({}, kn, { propertyName: 0, elapsedTime: 0, pseudoElement: 0 })), + Zn = On( + F({}, In, { + deltaX: function (e) { + return `deltaX` in e ? e.deltaX : `wheelDeltaX` in e ? -e.wheelDeltaX : 0; + }, + deltaY: function (e) { + return `deltaY` in e + ? e.deltaY + : `wheelDeltaY` in e + ? -e.wheelDeltaY + : `wheelDelta` in e + ? -e.wheelDelta + : 0; + }, + deltaZ: 0, + deltaMode: 0, + }), + ), + Qn = [9, 13, 27, 32], + $n = c && `CompositionEvent` in window, + er = null; + c && `documentMode` in document && (er = document.documentMode); + var tr = c && `TextEvent` in window && !er, + H = c && (!$n || (er && 8 < er && 11 >= er)), + nr = ` `, + rr = !1; + function ir(e, t) { + switch (e) { + case `keyup`: + return Qn.indexOf(t.keyCode) !== -1; + case `keydown`: + return t.keyCode !== 229; + case `keypress`: + case `mousedown`: + case `focusout`: + return !0; + default: + return !1; + } + } + function ar(e) { + return ((e = e.detail), typeof e == `object` && `data` in e ? e.data : null); + } + var or = !1; + function sr(e, t) { + switch (e) { + case `compositionend`: + return ar(t); + case `keypress`: + return t.which === 32 ? ((rr = !0), nr) : null; + case `textInput`: + return ((e = t.data), e === nr && rr ? null : e); + default: + return null; + } + } + function cr(e, t) { + if (or) + return e === `compositionend` || (!$n && ir(e, t)) ? ((e = wn()), (Cn = Sn = xn = null), (or = !1), e) : null; + switch (e) { + case `paste`: + return null; + case `keypress`: + if (!(t.ctrlKey || t.altKey || t.metaKey) || (t.ctrlKey && t.altKey)) { + if (t.char && 1 < t.char.length) return t.char; + if (t.which) return String.fromCharCode(t.which); + } + return null; + case `compositionend`: + return H && t.locale !== `ko` ? null : t.data; + default: + return null; + } + } + var lr = { + color: !0, + date: !0, + datetime: !0, + 'datetime-local': !0, + email: !0, + month: !0, + number: !0, + password: !0, + range: !0, + search: !0, + tel: !0, + text: !0, + time: !0, + url: !0, + week: !0, + }; + function ur(e) { + var t = e && e.nodeName && e.nodeName.toLowerCase(); + return t === `input` ? !!lr[e.type] : t === `textarea`; + } + function dr(e, t, n, r) { + (We(r), + (t = ui(t, `onChange`)), + 0 < t.length && ((n = new An(`onChange`, `change`, null, n, r)), e.push({ event: n, listeners: t }))); + } + var fr = null, + pr = null; + function mr(e) { + ri(e, 0); + } + function hr(e) { + if (pe(Ii(e))) return e; + } + function gr(e, t) { + if (e === `change`) return t; + } + var _r = !1; + if (c) { + var vr; + if (c) { + var yr = `oninput` in document; + if (!yr) { + var br = document.createElement(`div`); + (br.setAttribute(`oninput`, `return;`), (yr = typeof br.oninput == `function`)); + } + vr = yr; + } else vr = !1; + _r = vr && (!document.documentMode || 9 < document.documentMode); + } + function xr() { + fr && (fr.detachEvent(`onpropertychange`, Sr), (pr = fr = null)); + } + function Sr(e) { + if (e.propertyName === `value` && hr(pr)) { + var t = []; + (dr(t, pr, e, ze(e)), Ye(mr, t)); + } + } + function Cr(e, t, n) { + e === `focusin` ? (xr(), (fr = t), (pr = n), fr.attachEvent(`onpropertychange`, Sr)) : e === `focusout` && xr(); + } + function wr(e) { + if (e === `selectionchange` || e === `keyup` || e === `keydown`) return hr(pr); + } + function Tr(e, t) { + if (e === `click`) return hr(t); + } + function Er(e, t) { + if (e === `input` || e === `change`) return hr(t); + } + function Dr(e, t) { + return (e === t && (e !== 0 || 1 / e == 1 / t)) || (e !== e && t !== t); + } + var Or = typeof Object.is == `function` ? Object.is : Dr; + function kr(e, t) { + if (Or(e, t)) return !0; + if (typeof e != `object` || !e || typeof t != `object` || !t) return !1; + var n = Object.keys(e), + r = Object.keys(t); + if (n.length !== r.length) return !1; + for (r = 0; r < n.length; r++) { + var i = n[r]; + if (!l.call(t, i) || !Or(e[i], t[i])) return !1; + } + return !0; + } + function Ar(e) { + for (; e && e.firstChild; ) e = e.firstChild; + return e; + } + function jr(e, t) { + var n = Ar(e); + e = 0; + for (var r; n; ) { + if (n.nodeType === 3) { + if (((r = e + n.textContent.length), e <= t && r >= t)) return { node: n, offset: t - e }; + e = r; + } + a: { + for (; n; ) { + if (n.nextSibling) { + n = n.nextSibling; + break a; + } + n = n.parentNode; + } + n = void 0; + } + n = Ar(n); + } + } + function Mr(e, t) { + return e && t + ? e === t + ? !0 + : e && e.nodeType === 3 + ? !1 + : t && t.nodeType === 3 + ? Mr(e, t.parentNode) + : `contains` in e + ? e.contains(t) + : e.compareDocumentPosition + ? !!(e.compareDocumentPosition(t) & 16) + : !1 + : !1; + } + function Nr() { + for (var e = window, t = me(); t instanceof e.HTMLIFrameElement; ) { + try { + var n = typeof t.contentWindow.location.href == `string`; + } catch { + n = !1; + } + if (n) e = t.contentWindow; + else break; + t = me(e.document); + } + return t; + } + function Pr(e) { + var t = e && e.nodeName && e.nodeName.toLowerCase(); + return ( + t && + ((t === `input` && + (e.type === `text` || + e.type === `search` || + e.type === `tel` || + e.type === `url` || + e.type === `password`)) || + t === `textarea` || + e.contentEditable === `true`) + ); + } + function Fr(e) { + var t = Nr(), + n = e.focusedElem, + r = e.selectionRange; + if (t !== n && n && n.ownerDocument && Mr(n.ownerDocument.documentElement, n)) { + if (r !== null && Pr(n)) { + if (((t = r.start), (e = r.end), e === void 0 && (e = t), `selectionStart` in n)) + ((n.selectionStart = t), (n.selectionEnd = Math.min(e, n.value.length))); + else if (((e = ((t = n.ownerDocument || document) && t.defaultView) || window), e.getSelection)) { + e = e.getSelection(); + var i = n.textContent.length, + a = Math.min(r.start, i); + ((r = r.end === void 0 ? a : Math.min(r.end, i)), + !e.extend && a > r && ((i = r), (r = a), (a = i)), + (i = jr(n, a))); + var o = jr(n, r); + i && + o && + (e.rangeCount !== 1 || + e.anchorNode !== i.node || + e.anchorOffset !== i.offset || + e.focusNode !== o.node || + e.focusOffset !== o.offset) && + ((t = t.createRange()), + t.setStart(i.node, i.offset), + e.removeAllRanges(), + a > r ? (e.addRange(t), e.extend(o.node, o.offset)) : (t.setEnd(o.node, o.offset), e.addRange(t))); + } + } + for (t = [], e = n; (e = e.parentNode); ) + e.nodeType === 1 && t.push({ element: e, left: e.scrollLeft, top: e.scrollTop }); + for (typeof n.focus == `function` && n.focus(), n = 0; n < t.length; n++) + ((e = t[n]), (e.element.scrollLeft = e.left), (e.element.scrollTop = e.top)); + } + } + var U = c && `documentMode` in document && 11 >= document.documentMode, + Ir = null, + Lr = null, + Rr = null, + zr = !1; + function Br(e, t, n) { + var r = n.window === n ? n.document : n.nodeType === 9 ? n : n.ownerDocument; + zr || + Ir == null || + Ir !== me(r) || + ((r = Ir), + `selectionStart` in r && Pr(r) + ? (r = { start: r.selectionStart, end: r.selectionEnd }) + : ((r = ((r.ownerDocument && r.ownerDocument.defaultView) || window).getSelection()), + (r = { + anchorNode: r.anchorNode, + anchorOffset: r.anchorOffset, + focusNode: r.focusNode, + focusOffset: r.focusOffset, + })), + (Rr && kr(Rr, r)) || + ((Rr = r), + (r = ui(Lr, `onSelect`)), + 0 < r.length && + ((t = new An(`onSelect`, `select`, null, t, n)), e.push({ event: t, listeners: r }), (t.target = Ir)))); + } + function Vr(e, t) { + var n = {}; + return ((n[e.toLowerCase()] = t.toLowerCase()), (n[`Webkit` + e] = `webkit` + t), (n[`Moz` + e] = `moz` + t), n); + } + var Hr = { + animationend: Vr(`Animation`, `AnimationEnd`), + animationiteration: Vr(`Animation`, `AnimationIteration`), + animationstart: Vr(`Animation`, `AnimationStart`), + transitionend: Vr(`Transition`, `TransitionEnd`), + }, + Ur = {}, + Wr = {}; + c && + ((Wr = document.createElement(`div`).style), + `AnimationEvent` in window || + (delete Hr.animationend.animation, delete Hr.animationiteration.animation, delete Hr.animationstart.animation), + `TransitionEvent` in window || delete Hr.transitionend.transition); + function Gr(e) { + if (Ur[e]) return Ur[e]; + if (!Hr[e]) return e; + var t = Hr[e], + n; + for (n in t) if (t.hasOwnProperty(n) && n in Wr) return (Ur[e] = t[n]); + return e; + } + var Kr = Gr(`animationend`), + qr = Gr(`animationiteration`), + Jr = Gr(`animationstart`), + W = Gr(`transitionend`), + Yr = new Map(), + Xr = + `abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel`.split( + ` `, + ); + function Zr(e, t) { + (Yr.set(e, t), o(t, [e])); + } + for (var Qr = 0; Qr < Xr.length; Qr++) { + var $r = Xr[Qr]; + Zr($r.toLowerCase(), `on` + ($r[0].toUpperCase() + $r.slice(1))); + } + (Zr(Kr, `onAnimationEnd`), + Zr(qr, `onAnimationIteration`), + Zr(Jr, `onAnimationStart`), + Zr(`dblclick`, `onDoubleClick`), + Zr(`focusin`, `onFocus`), + Zr(`focusout`, `onBlur`), + Zr(W, `onTransitionEnd`), + s(`onMouseEnter`, [`mouseout`, `mouseover`]), + s(`onMouseLeave`, [`mouseout`, `mouseover`]), + s(`onPointerEnter`, [`pointerout`, `pointerover`]), + s(`onPointerLeave`, [`pointerout`, `pointerover`]), + o(`onChange`, `change click focusin focusout input keydown keyup selectionchange`.split(` `)), + o(`onSelect`, `focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange`.split(` `)), + o(`onBeforeInput`, [`compositionend`, `keypress`, `textInput`, `paste`]), + o(`onCompositionEnd`, `compositionend focusout keydown keypress keyup mousedown`.split(` `)), + o(`onCompositionStart`, `compositionstart focusout keydown keypress keyup mousedown`.split(` `)), + o(`onCompositionUpdate`, `compositionupdate focusout keydown keypress keyup mousedown`.split(` `))); + var ei = + `abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting`.split( + ` `, + ), + ti = new Set(`cancel close invalid load scroll toggle`.split(` `).concat(ei)); + function ni(e, t, n) { + var r = e.type || `unknown-event`; + ((e.currentTarget = n), at(r, t, void 0, e), (e.currentTarget = null)); + } + function ri(e, t) { + t = (t & 4) != 0; + for (var n = 0; n < e.length; n++) { + var r = e[n], + i = r.event; + r = r.listeners; + a: { + var a = void 0; + if (t) + for (var o = r.length - 1; 0 <= o; o--) { + var s = r[o], + c = s.instance, + l = s.currentTarget; + if (((s = s.listener), c !== a && i.isPropagationStopped())) break a; + (ni(i, s, l), (a = c)); + } + else + for (o = 0; o < r.length; o++) { + if ( + ((s = r[o]), + (c = s.instance), + (l = s.currentTarget), + (s = s.listener), + c !== a && i.isPropagationStopped()) + ) + break a; + (ni(i, s, l), (a = c)); + } + } + } + if (tt) throw ((e = nt), (tt = !1), (nt = null), e); + } + function G(e, t) { + var n = t[Mi]; + n === void 0 && (n = t[Mi] = new Set()); + var r = e + `__bubble`; + n.has(r) || (si(t, e, 2, !1), n.add(r)); + } + function ii(e, t, n) { + var r = 0; + (t && (r |= 4), si(n, e, r, t)); + } + var ai = `_reactListening` + Math.random().toString(36).slice(2); + function oi(e) { + if (!e[ai]) { + ((e[ai] = !0), + i.forEach(function (t) { + t !== `selectionchange` && (ti.has(t) || ii(t, !1, e), ii(t, !0, e)); + })); + var t = e.nodeType === 9 ? e : e.ownerDocument; + t === null || t[ai] || ((t[ai] = !0), ii(`selectionchange`, !1, t)); + } + } + function si(e, t, n, r) { + switch (bn(t)) { + case 1: + var i = hn; + break; + case 4: + i = gn; + break; + default: + i = _n; + } + ((n = i.bind(null, t, n, e)), + (i = void 0), + !Ze || (t !== `touchstart` && t !== `touchmove` && t !== `wheel`) || (i = !0), + r + ? i === void 0 + ? e.addEventListener(t, n, !0) + : e.addEventListener(t, n, { capture: !0, passive: i }) + : i === void 0 + ? e.addEventListener(t, n, !1) + : e.addEventListener(t, n, { passive: i })); + } + function ci(e, t, n, r, i) { + var a = r; + if (!(t & 1) && !(t & 2) && r !== null) + a: for (;;) { + if (r === null) return; + var o = r.tag; + if (o === 3 || o === 4) { + var s = r.stateNode.containerInfo; + if (s === i || (s.nodeType === 8 && s.parentNode === i)) break; + if (o === 4) + for (o = r.return; o !== null; ) { + var c = o.tag; + if ( + (c === 3 || c === 4) && + ((c = o.stateNode.containerInfo), c === i || (c.nodeType === 8 && c.parentNode === i)) + ) + return; + o = o.return; + } + for (; s !== null; ) { + if (((o = Fi(s)), o === null)) return; + if (((c = o.tag), c === 5 || c === 6)) { + r = a = o; + continue a; + } + s = s.parentNode; + } + } + r = r.return; + } + Ye(function () { + var r = a, + i = ze(n), + o = []; + a: { + var s = Yr.get(e); + if (s !== void 0) { + var c = An, + l = e; + switch (e) { + case `keypress`: + if (Tn(n) === 0) break a; + case `keydown`: + case `keyup`: + c = qn; + break; + case `focusin`: + ((l = `focus`), (c = zn)); + break; + case `focusout`: + ((l = `blur`), (c = zn)); + break; + case `beforeblur`: + case `afterblur`: + c = zn; + break; + case `click`: + if (n.button === 2) break a; + case `auxclick`: + case `dblclick`: + case `mousedown`: + case `mousemove`: + case `mouseup`: + case `mouseout`: + case `mouseover`: + case `contextmenu`: + c = Ln; + break; + case `drag`: + case `dragend`: + case `dragenter`: + case `dragexit`: + case `dragleave`: + case `dragover`: + case `dragstart`: + case `drop`: + c = Rn; + break; + case `touchcancel`: + case `touchend`: + case `touchmove`: + case `touchstart`: + c = Yn; + break; + case Kr: + case qr: + case Jr: + c = Bn; + break; + case W: + c = Xn; + break; + case `scroll`: + c = Mn; + break; + case `wheel`: + c = Zn; + break; + case `copy`: + case `cut`: + case `paste`: + c = V; + break; + case `gotpointercapture`: + case `lostpointercapture`: + case `pointercancel`: + case `pointerdown`: + case `pointermove`: + case `pointerout`: + case `pointerover`: + case `pointerup`: + c = Jn; + } + var u = (t & 4) != 0, + d = !u && e === `scroll`, + f = u ? (s === null ? null : s + `Capture`) : s; + u = []; + for (var p = r, m; p !== null; ) { + m = p; + var h = m.stateNode; + if ( + (m.tag === 5 && + h !== null && + ((m = h), f !== null && ((h = Xe(p, f)), h != null && u.push(li(p, h, m)))), + d) + ) + break; + p = p.return; + } + 0 < u.length && ((s = new c(s, l, null, n, i)), o.push({ event: s, listeners: u })); + } + } + if (!(t & 7)) { + a: { + if ( + ((s = e === `mouseover` || e === `pointerover`), + (c = e === `mouseout` || e === `pointerout`), + s && n !== Re && (l = n.relatedTarget || n.fromElement) && (Fi(l) || l[ji])) + ) + break a; + if ( + (c || s) && + ((s = i.window === i ? i : (s = i.ownerDocument) ? s.defaultView || s.parentWindow : window), + c + ? ((l = n.relatedTarget || n.toElement), + (c = r), + (l = l ? Fi(l) : null), + l !== null && ((d = ot(l)), l !== d || (l.tag !== 5 && l.tag !== 6)) && (l = null)) + : ((c = null), (l = r)), + c !== l) + ) { + if ( + ((u = Ln), + (h = `onMouseLeave`), + (f = `onMouseEnter`), + (p = `mouse`), + (e === `pointerout` || e === `pointerover`) && + ((u = Jn), (h = `onPointerLeave`), (f = `onPointerEnter`), (p = `pointer`)), + (d = c == null ? s : Ii(c)), + (m = l == null ? s : Ii(l)), + (s = new u(h, p + `leave`, c, n, i)), + (s.target = d), + (s.relatedTarget = m), + (h = null), + Fi(i) === r && ((u = new u(f, p + `enter`, l, n, i)), (u.target = m), (u.relatedTarget = d), (h = u)), + (d = h), + c && l) + ) + b: { + for (u = c, f = l, p = 0, m = u; m; m = di(m)) p++; + for (m = 0, h = f; h; h = di(h)) m++; + for (; 0 < p - m; ) ((u = di(u)), p--); + for (; 0 < m - p; ) ((f = di(f)), m--); + for (; p--; ) { + if (u === f || (f !== null && u === f.alternate)) break b; + ((u = di(u)), (f = di(f))); + } + u = null; + } + else u = null; + (c !== null && fi(o, s, c, u, !1), l !== null && d !== null && fi(o, d, l, u, !0)); + } + } + a: { + if ( + ((s = r ? Ii(r) : window), + (c = s.nodeName && s.nodeName.toLowerCase()), + c === `select` || (c === `input` && s.type === `file`)) + ) + var g = gr; + else if (ur(s)) + if (_r) g = Er; + else { + g = wr; + var _ = Cr; + } + else + (c = s.nodeName) && + c.toLowerCase() === `input` && + (s.type === `checkbox` || s.type === `radio`) && + (g = Tr); + if ((g &&= g(e, r))) { + dr(o, g, n, i); + break a; + } + (_ && _(e, s, r), + e === `focusout` && + (_ = s._wrapperState) && + _.controlled && + s.type === `number` && + ye(s, `number`, s.value)); + } + switch (((_ = r ? Ii(r) : window), e)) { + case `focusin`: + (ur(_) || _.contentEditable === `true`) && ((Ir = _), (Lr = r), (Rr = null)); + break; + case `focusout`: + Rr = Lr = Ir = null; + break; + case `mousedown`: + zr = !0; + break; + case `contextmenu`: + case `mouseup`: + case `dragend`: + ((zr = !1), Br(o, n, i)); + break; + case `selectionchange`: + if (U) break; + case `keydown`: + case `keyup`: + Br(o, n, i); + } + var v; + if ($n) + b: { + switch (e) { + case `compositionstart`: + var y = `onCompositionStart`; + break b; + case `compositionend`: + y = `onCompositionEnd`; + break b; + case `compositionupdate`: + y = `onCompositionUpdate`; + break b; + } + y = void 0; + } + else + or + ? ir(e, n) && (y = `onCompositionEnd`) + : e === `keydown` && n.keyCode === 229 && (y = `onCompositionStart`); + (y && + (H && + n.locale !== `ko` && + (or || y !== `onCompositionStart` + ? y === `onCompositionEnd` && or && (v = wn()) + : ((xn = i), (Sn = `value` in xn ? xn.value : xn.textContent), (or = !0))), + (_ = ui(r, y)), + 0 < _.length && + ((y = new Vn(y, e, null, n, i)), + o.push({ event: y, listeners: _ }), + v ? (y.data = v) : ((v = ar(n)), v !== null && (y.data = v)))), + (v = tr ? sr(e, n) : cr(e, n)) && + ((r = ui(r, `onBeforeInput`)), + 0 < r.length && + ((i = new Vn(`onBeforeInput`, `beforeinput`, null, n, i)), + o.push({ event: i, listeners: r }), + (i.data = v)))); + } + ri(o, t); + }); + } + function li(e, t, n) { + return { instance: e, listener: t, currentTarget: n }; + } + function ui(e, t) { + for (var n = t + `Capture`, r = []; e !== null; ) { + var i = e, + a = i.stateNode; + (i.tag === 5 && + a !== null && + ((i = a), + (a = Xe(e, n)), + a != null && r.unshift(li(e, a, i)), + (a = Xe(e, t)), + a != null && r.push(li(e, a, i))), + (e = e.return)); + } + return r; + } + function di(e) { + if (e === null) return null; + do e = e.return; + while (e && e.tag !== 5); + return e || null; + } + function fi(e, t, n, r, i) { + for (var a = t._reactName, o = []; n !== null && n !== r; ) { + var s = n, + c = s.alternate, + l = s.stateNode; + if (c !== null && c === r) break; + (s.tag === 5 && + l !== null && + ((s = l), + i + ? ((c = Xe(n, a)), c != null && o.unshift(li(n, c, s))) + : i || ((c = Xe(n, a)), c != null && o.push(li(n, c, s)))), + (n = n.return)); + } + o.length !== 0 && e.push({ event: t, listeners: o }); + } + var pi = /\r\n?/g, + mi = /\u0000|\uFFFD/g; + function hi(e) { + return (typeof e == `string` ? e : `` + e) + .replace( + pi, + ` +`, + ) + .replace(mi, ``); + } + function gi(e, t, n) { + if (((t = hi(t)), hi(e) !== t && n)) throw Error(r(425)); + } + function _i() {} + var vi = null, + yi = null; + function bi(e, t) { + return ( + e === `textarea` || + e === `noscript` || + typeof t.children == `string` || + typeof t.children == `number` || + (typeof t.dangerouslySetInnerHTML == `object` && + t.dangerouslySetInnerHTML !== null && + t.dangerouslySetInnerHTML.__html != null) + ); + } + var xi = typeof setTimeout == `function` ? setTimeout : void 0, + Si = typeof clearTimeout == `function` ? clearTimeout : void 0, + Ci = typeof Promise == `function` ? Promise : void 0, + wi = + typeof queueMicrotask == `function` + ? queueMicrotask + : Ci === void 0 + ? xi + : function (e) { + return Ci.resolve(null).then(e).catch(Ti); + }; + function Ti(e) { + setTimeout(function () { + throw e; + }); + } + function Ei(e, t) { + var n = t, + r = 0; + do { + var i = n.nextSibling; + if ((e.removeChild(n), i && i.nodeType === 8)) + if (((n = i.data), n === `/$`)) { + if (r === 0) { + (e.removeChild(i), fn(t)); + return; + } + r--; + } else (n !== `$` && n !== `$?` && n !== `$!`) || r++; + n = i; + } while (n); + fn(t); + } + function Di(e) { + for (; e != null; e = e.nextSibling) { + var t = e.nodeType; + if (t === 1 || t === 3) break; + if (t === 8) { + if (((t = e.data), t === `$` || t === `$!` || t === `$?`)) break; + if (t === `/$`) return null; + } + } + return e; + } + function K(e) { + e = e.previousSibling; + for (var t = 0; e; ) { + if (e.nodeType === 8) { + var n = e.data; + if (n === `$` || n === `$!` || n === `$?`) { + if (t === 0) return e; + t--; + } else n === `/$` && t++; + } + e = e.previousSibling; + } + return null; + } + var Oi = Math.random().toString(36).slice(2), + ki = `__reactFiber$` + Oi, + Ai = `__reactProps$` + Oi, + ji = `__reactContainer$` + Oi, + Mi = `__reactEvents$` + Oi, + Ni = `__reactListeners$` + Oi, + Pi = `__reactHandles$` + Oi; + function Fi(e) { + var t = e[ki]; + if (t) return t; + for (var n = e.parentNode; n; ) { + if ((t = n[ji] || n[ki])) { + if (((n = t.alternate), t.child !== null || (n !== null && n.child !== null))) + for (e = K(e); e !== null; ) { + if ((n = e[ki])) return n; + e = K(e); + } + return t; + } + ((e = n), (n = e.parentNode)); + } + return null; + } + function q(e) { + return ((e = e[ki] || e[ji]), !e || (e.tag !== 5 && e.tag !== 6 && e.tag !== 13 && e.tag !== 3) ? null : e); + } + function Ii(e) { + if (e.tag === 5 || e.tag === 6) return e.stateNode; + throw Error(r(33)); + } + function J(e) { + return e[Ai] || null; + } + var Li = [], + Ri = -1; + function zi(e) { + return { current: e }; + } + function Bi(e) { + 0 > Ri || ((e.current = Li[Ri]), (Li[Ri] = null), Ri--); + } + function Y(e, t) { + (Ri++, (Li[Ri] = e.current), (e.current = t)); + } + var Vi = {}, + Hi = zi(Vi), + Ui = zi(!1), + Wi = Vi; + function Gi(e, t) { + var n = e.type.contextTypes; + if (!n) return Vi; + var r = e.stateNode; + if (r && r.__reactInternalMemoizedUnmaskedChildContext === t) return r.__reactInternalMemoizedMaskedChildContext; + var i = {}, + a; + for (a in n) i[a] = t[a]; + return ( + r && + ((e = e.stateNode), + (e.__reactInternalMemoizedUnmaskedChildContext = t), + (e.__reactInternalMemoizedMaskedChildContext = i)), + i + ); + } + function Ki(e) { + return ((e = e.childContextTypes), e != null); + } + function qi() { + (Bi(Ui), Bi(Hi)); + } + function Ji(e, t, n) { + if (Hi.current !== Vi) throw Error(r(168)); + (Y(Hi, t), Y(Ui, n)); + } + function Yi(e, t, n) { + var i = e.stateNode; + if (((t = t.childContextTypes), typeof i.getChildContext != `function`)) return n; + for (var a in ((i = i.getChildContext()), i)) if (!(a in t)) throw Error(r(108, ue(e) || `Unknown`, a)); + return F({}, n, i); + } + function Xi(e) { + return ( + (e = ((e = e.stateNode) && e.__reactInternalMemoizedMergedChildContext) || Vi), + (Wi = Hi.current), + Y(Hi, e), + Y(Ui, Ui.current), + !0 + ); + } + function Zi(e, t, n) { + var i = e.stateNode; + if (!i) throw Error(r(169)); + (n ? ((e = Yi(e, t, Wi)), (i.__reactInternalMemoizedMergedChildContext = e), Bi(Ui), Bi(Hi), Y(Hi, e)) : Bi(Ui), + Y(Ui, n)); + } + var Qi = null, + $i = !1, + ea = !1; + function ta(e) { + Qi === null ? (Qi = [e]) : Qi.push(e); + } + function na(e) { + (($i = !0), ta(e)); + } + function ra() { + if (!ea && Qi !== null) { + ea = !0; + var e = 0, + t = B; + try { + var n = Qi; + for (B = 1; e < n.length; e++) { + var r = n[e]; + do r = r(!0); + while (r !== null); + } + ((Qi = null), ($i = !1)); + } catch (t) { + throw (Qi !== null && (Qi = Qi.slice(e + 1)), ft(vt, ra), t); + } finally { + ((B = t), (ea = !1)); + } + } + return null; + } + var ia = [], + aa = 0, + oa = null, + sa = 0, + ca = [], + la = 0, + ua = null, + da = 1, + fa = ``; + function pa(e, t) { + ((ia[aa++] = sa), (ia[aa++] = oa), (oa = e), (sa = t)); + } + function ma(e, t, n) { + ((ca[la++] = da), (ca[la++] = fa), (ca[la++] = ua), (ua = e)); + var r = da; + e = fa; + var i = 32 - Et(r) - 1; + ((r &= ~(1 << i)), (n += 1)); + var a = 32 - Et(t) + i; + if (30 < a) { + var o = i - (i % 5); + ((a = (r & ((1 << o) - 1)).toString(32)), + (r >>= o), + (i -= o), + (da = (1 << (32 - Et(t) + i)) | (n << i) | r), + (fa = a + e)); + } else ((da = (1 << a) | (n << i) | r), (fa = e)); + } + function ha(e) { + e.return !== null && (pa(e, 1), ma(e, 1, 0)); + } + function ga(e) { + for (; e === oa; ) ((oa = ia[--aa]), (ia[aa] = null), (sa = ia[--aa]), (ia[aa] = null)); + for (; e === ua; ) + ((ua = ca[--la]), (ca[la] = null), (fa = ca[--la]), (ca[la] = null), (da = ca[--la]), (ca[la] = null)); + } + var _a = null, + va = null, + ya = !1, + ba = null; + function xa(e, t) { + var n = Kl(5, null, null, 0); + ((n.elementType = `DELETED`), + (n.stateNode = t), + (n.return = e), + (t = e.deletions), + t === null ? ((e.deletions = [n]), (e.flags |= 16)) : t.push(n)); + } + function Sa(e, t) { + switch (e.tag) { + case 5: + var n = e.type; + return ( + (t = t.nodeType !== 1 || n.toLowerCase() !== t.nodeName.toLowerCase() ? null : t), + t === null ? !1 : ((e.stateNode = t), (_a = e), (va = Di(t.firstChild)), !0) + ); + case 6: + return ( + (t = e.pendingProps === `` || t.nodeType !== 3 ? null : t), + t === null ? !1 : ((e.stateNode = t), (_a = e), (va = null), !0) + ); + case 13: + return ( + (t = t.nodeType === 8 ? t : null), + t === null + ? !1 + : ((n = ua === null ? null : { id: da, overflow: fa }), + (e.memoizedState = { dehydrated: t, treeContext: n, retryLane: 1073741824 }), + (n = Kl(18, null, null, 0)), + (n.stateNode = t), + (n.return = e), + (e.child = n), + (_a = e), + (va = null), + !0) + ); + default: + return !1; + } + } + function Ca(e) { + return (e.mode & 1) != 0 && (e.flags & 128) == 0; + } + function wa(e) { + if (ya) { + var t = va; + if (t) { + var n = t; + if (!Sa(e, t)) { + if (Ca(e)) throw Error(r(418)); + t = Di(n.nextSibling); + var i = _a; + t && Sa(e, t) ? xa(i, n) : ((e.flags = (e.flags & -4097) | 2), (ya = !1), (_a = e)); + } + } else { + if (Ca(e)) throw Error(r(418)); + ((e.flags = (e.flags & -4097) | 2), (ya = !1), (_a = e)); + } + } + } + function Ta(e) { + for (e = e.return; e !== null && e.tag !== 5 && e.tag !== 3 && e.tag !== 13; ) e = e.return; + _a = e; + } + function Ea(e) { + if (e !== _a) return !1; + if (!ya) return (Ta(e), (ya = !0), !1); + var t; + if ( + ((t = e.tag !== 3) && + !(t = e.tag !== 5) && + ((t = e.type), (t = t !== `head` && t !== `body` && !bi(e.type, e.memoizedProps))), + (t &&= va)) + ) { + if (Ca(e)) throw (X(), Error(r(418))); + for (; t; ) (xa(e, t), (t = Di(t.nextSibling))); + } + if ((Ta(e), e.tag === 13)) { + if (((e = e.memoizedState), (e = e === null ? null : e.dehydrated), !e)) throw Error(r(317)); + a: { + for (e = e.nextSibling, t = 0; e; ) { + if (e.nodeType === 8) { + var n = e.data; + if (n === `/$`) { + if (t === 0) { + va = Di(e.nextSibling); + break a; + } + t--; + } else (n !== `$` && n !== `$!` && n !== `$?`) || t++; + } + e = e.nextSibling; + } + va = null; + } + } else va = _a ? Di(e.stateNode.nextSibling) : null; + return !0; + } + function X() { + for (var e = va; e; ) e = Di(e.nextSibling); + } + function Da() { + ((va = _a = null), (ya = !1)); + } + function Oa(e) { + ba === null ? (ba = [e]) : ba.push(e); + } + var ka = C.ReactCurrentBatchConfig; + function Aa(e, t, n) { + if (((e = n.ref), e !== null && typeof e != `function` && typeof e != `object`)) { + if (n._owner) { + if (((n = n._owner), n)) { + if (n.tag !== 1) throw Error(r(309)); + var i = n.stateNode; + } + if (!i) throw Error(r(147, e)); + var a = i, + o = `` + e; + return t !== null && t.ref !== null && typeof t.ref == `function` && t.ref._stringRef === o + ? t.ref + : ((t = function (e) { + var t = a.refs; + e === null ? delete t[o] : (t[o] = e); + }), + (t._stringRef = o), + t); + } + if (typeof e != `string`) throw Error(r(284)); + if (!n._owner) throw Error(r(290, e)); + } + return e; + } + function ja(e, t) { + throw ( + (e = Object.prototype.toString.call(t)), + Error(r(31, e === `[object Object]` ? `object with keys {` + Object.keys(t).join(`, `) + `}` : e)) + ); + } + function Ma(e) { + var t = e._init; + return t(e._payload); + } + function Na(e) { + function t(t, n) { + if (e) { + var r = t.deletions; + r === null ? ((t.deletions = [n]), (t.flags |= 16)) : r.push(n); + } + } + function n(n, r) { + if (!e) return null; + for (; r !== null; ) (t(n, r), (r = r.sibling)); + return null; + } + function i(e, t) { + for (e = new Map(); t !== null; ) (t.key === null ? e.set(t.index, t) : e.set(t.key, t), (t = t.sibling)); + return e; + } + function a(e, t) { + return ((e = Yl(e, t)), (e.index = 0), (e.sibling = null), e); + } + function o(t, n, r) { + return ( + (t.index = r), + e + ? ((r = t.alternate), r === null ? ((t.flags |= 2), n) : ((r = r.index), r < n ? ((t.flags |= 2), n) : r)) + : ((t.flags |= 1048576), n) + ); + } + function s(t) { + return (e && t.alternate === null && (t.flags |= 2), t); + } + function c(e, t, n, r) { + return t === null || t.tag !== 6 + ? ((t = $l(n, e.mode, r)), (t.return = e), t) + : ((t = a(t, n)), (t.return = e), t); + } + function l(e, t, n, r) { + var i = n.type; + return i === E + ? d(e, t, n.props.children, r, n.key) + : t !== null && (t.elementType === i || (typeof i == `object` && i && i.$$typeof === P && Ma(i) === t.type)) + ? ((r = a(t, n.props)), (r.ref = Aa(e, t, n)), (r.return = e), r) + : ((r = Xl(n.type, n.key, n.props, null, e.mode, r)), (r.ref = Aa(e, t, n)), (r.return = e), r); + } + function u(e, t, n, r) { + return t === null || + t.tag !== 4 || + t.stateNode.containerInfo !== n.containerInfo || + t.stateNode.implementation !== n.implementation + ? ((t = eu(n, e.mode, r)), (t.return = e), t) + : ((t = a(t, n.children || [])), (t.return = e), t); + } + function d(e, t, n, r, i) { + return t === null || t.tag !== 7 + ? ((t = Zl(n, e.mode, r, i)), (t.return = e), t) + : ((t = a(t, n)), (t.return = e), t); + } + function f(e, t, n) { + if ((typeof t == `string` && t !== ``) || typeof t == `number`) + return ((t = $l(`` + t, e.mode, n)), (t.return = e), t); + if (typeof t == `object` && t) { + switch (t.$$typeof) { + case w: + return ((n = Xl(t.type, t.key, t.props, null, e.mode, n)), (n.ref = Aa(e, null, t)), (n.return = e), n); + case T: + return ((t = eu(t, e.mode, n)), (t.return = e), t); + case P: + var r = t._init; + return f(e, r(t._payload), n); + } + if (be(t) || re(t)) return ((t = Zl(t, e.mode, n, null)), (t.return = e), t); + ja(e, t); + } + return null; + } + function p(e, t, n, r) { + var i = t === null ? null : t.key; + if ((typeof n == `string` && n !== ``) || typeof n == `number`) return i === null ? c(e, t, `` + n, r) : null; + if (typeof n == `object` && n) { + switch (n.$$typeof) { + case w: + return n.key === i ? l(e, t, n, r) : null; + case T: + return n.key === i ? u(e, t, n, r) : null; + case P: + return ((i = n._init), p(e, t, i(n._payload), r)); + } + if (be(n) || re(n)) return i === null ? d(e, t, n, r, null) : null; + ja(e, n); + } + return null; + } + function m(e, t, n, r, i) { + if ((typeof r == `string` && r !== ``) || typeof r == `number`) + return ((e = e.get(n) || null), c(t, e, `` + r, i)); + if (typeof r == `object` && r) { + switch (r.$$typeof) { + case w: + return ((e = e.get(r.key === null ? n : r.key) || null), l(t, e, r, i)); + case T: + return ((e = e.get(r.key === null ? n : r.key) || null), u(t, e, r, i)); + case P: + var a = r._init; + return m(e, t, n, a(r._payload), i); + } + if (be(r) || re(r)) return ((e = e.get(n) || null), d(t, e, r, i, null)); + ja(t, r); + } + return null; + } + function h(r, a, s, c) { + for (var l = null, u = null, d = a, h = (a = 0), g = null; d !== null && h < s.length; h++) { + d.index > h ? ((g = d), (d = null)) : (g = d.sibling); + var _ = p(r, d, s[h], c); + if (_ === null) { + d === null && (d = g); + break; + } + (e && d && _.alternate === null && t(r, d), + (a = o(_, a, h)), + u === null ? (l = _) : (u.sibling = _), + (u = _), + (d = g)); + } + if (h === s.length) return (n(r, d), ya && pa(r, h), l); + if (d === null) { + for (; h < s.length; h++) + ((d = f(r, s[h], c)), d !== null && ((a = o(d, a, h)), u === null ? (l = d) : (u.sibling = d), (u = d))); + return (ya && pa(r, h), l); + } + for (d = i(r, d); h < s.length; h++) + ((g = m(d, r, h, s[h], c)), + g !== null && + (e && g.alternate !== null && d.delete(g.key === null ? h : g.key), + (a = o(g, a, h)), + u === null ? (l = g) : (u.sibling = g), + (u = g))); + return ( + e && + d.forEach(function (e) { + return t(r, e); + }), + ya && pa(r, h), + l + ); + } + function g(a, s, c, l) { + var u = re(c); + if (typeof u != `function`) throw Error(r(150)); + if (((c = u.call(c)), c == null)) throw Error(r(151)); + for (var d = (u = null), h = s, g = (s = 0), _ = null, v = c.next(); h !== null && !v.done; g++, v = c.next()) { + h.index > g ? ((_ = h), (h = null)) : (_ = h.sibling); + var y = p(a, h, v.value, l); + if (y === null) { + h === null && (h = _); + break; + } + (e && h && y.alternate === null && t(a, h), + (s = o(y, s, g)), + d === null ? (u = y) : (d.sibling = y), + (d = y), + (h = _)); + } + if (v.done) return (n(a, h), ya && pa(a, g), u); + if (h === null) { + for (; !v.done; g++, v = c.next()) + ((v = f(a, v.value, l)), v !== null && ((s = o(v, s, g)), d === null ? (u = v) : (d.sibling = v), (d = v))); + return (ya && pa(a, g), u); + } + for (h = i(a, h); !v.done; g++, v = c.next()) + ((v = m(h, a, g, v.value, l)), + v !== null && + (e && v.alternate !== null && h.delete(v.key === null ? g : v.key), + (s = o(v, s, g)), + d === null ? (u = v) : (d.sibling = v), + (d = v))); + return ( + e && + h.forEach(function (e) { + return t(a, e); + }), + ya && pa(a, g), + u + ); + } + function _(e, r, i, o) { + if ( + (typeof i == `object` && i && i.type === E && i.key === null && (i = i.props.children), + typeof i == `object` && i) + ) { + switch (i.$$typeof) { + case w: + a: { + for (var c = i.key, l = r; l !== null; ) { + if (l.key === c) { + if (((c = i.type), c === E)) { + if (l.tag === 7) { + (n(e, l.sibling), (r = a(l, i.props.children)), (r.return = e), (e = r)); + break a; + } + } else if ( + l.elementType === c || + (typeof c == `object` && c && c.$$typeof === P && Ma(c) === l.type) + ) { + (n(e, l.sibling), (r = a(l, i.props)), (r.ref = Aa(e, l, i)), (r.return = e), (e = r)); + break a; + } + n(e, l); + break; + } else t(e, l); + l = l.sibling; + } + i.type === E + ? ((r = Zl(i.props.children, e.mode, o, i.key)), (r.return = e), (e = r)) + : ((o = Xl(i.type, i.key, i.props, null, e.mode, o)), (o.ref = Aa(e, r, i)), (o.return = e), (e = o)); + } + return s(e); + case T: + a: { + for (l = i.key; r !== null; ) { + if (r.key === l) + if ( + r.tag === 4 && + r.stateNode.containerInfo === i.containerInfo && + r.stateNode.implementation === i.implementation + ) { + (n(e, r.sibling), (r = a(r, i.children || [])), (r.return = e), (e = r)); + break a; + } else { + n(e, r); + break; + } + else t(e, r); + r = r.sibling; + } + ((r = eu(i, e.mode, o)), (r.return = e), (e = r)); + } + return s(e); + case P: + return ((l = i._init), _(e, r, l(i._payload), o)); + } + if (be(i)) return h(e, r, i, o); + if (re(i)) return g(e, r, i, o); + ja(e, i); + } + return (typeof i == `string` && i !== ``) || typeof i == `number` + ? ((i = `` + i), + r !== null && r.tag === 6 + ? (n(e, r.sibling), (r = a(r, i)), (r.return = e), (e = r)) + : (n(e, r), (r = $l(i, e.mode, o)), (r.return = e), (e = r)), + s(e)) + : n(e, r); + } + return _; + } + var Pa = Na(!0), + Fa = Na(!1), + Ia = zi(null), + La = null, + Ra = null, + za = null; + function Ba() { + za = Ra = La = null; + } + function Va(e) { + var t = Ia.current; + (Bi(Ia), (e._currentValue = t)); + } + function Ha(e, t, n) { + for (; e !== null; ) { + var r = e.alternate; + if ( + ((e.childLanes & t) === t + ? r !== null && (r.childLanes & t) !== t && (r.childLanes |= t) + : ((e.childLanes |= t), r !== null && (r.childLanes |= t)), + e === n) + ) + break; + e = e.return; + } + } + function Ua(e, t) { + ((La = e), + (za = Ra = null), + (e = e.dependencies), + e !== null && e.firstContext !== null && ((e.lanes & t) !== 0 && (Ms = !0), (e.firstContext = null))); + } + function Wa(e) { + var t = e._currentValue; + if (za !== e) + if (((e = { context: e, memoizedValue: t, next: null }), Ra === null)) { + if (La === null) throw Error(r(308)); + ((Ra = e), (La.dependencies = { lanes: 0, firstContext: e })); + } else Ra = Ra.next = e; + return t; + } + var Ga = null; + function Ka(e) { + Ga === null ? (Ga = [e]) : Ga.push(e); + } + function qa(e, t, n, r) { + var i = t.interleaved; + return (i === null ? ((n.next = n), Ka(t)) : ((n.next = i.next), (i.next = n)), (t.interleaved = n), Ja(e, r)); + } + function Ja(e, t) { + e.lanes |= t; + var n = e.alternate; + for (n !== null && (n.lanes |= t), n = e, e = e.return; e !== null; ) + ((e.childLanes |= t), (n = e.alternate), n !== null && (n.childLanes |= t), (n = e), (e = e.return)); + return n.tag === 3 ? n.stateNode : null; + } + var Ya = !1; + function Xa(e) { + e.updateQueue = { + baseState: e.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { pending: null, interleaved: null, lanes: 0 }, + effects: null, + }; + } + function Za(e, t) { + ((e = e.updateQueue), + t.updateQueue === e && + (t.updateQueue = { + baseState: e.baseState, + firstBaseUpdate: e.firstBaseUpdate, + lastBaseUpdate: e.lastBaseUpdate, + shared: e.shared, + effects: e.effects, + })); + } + function Qa(e, t) { + return { eventTime: e, lane: t, tag: 0, payload: null, callback: null, next: null }; + } + function $a(e, t, n) { + var r = e.updateQueue; + if (r === null) return null; + if (((r = r.shared), $ & 2)) { + var i = r.pending; + return (i === null ? (t.next = t) : ((t.next = i.next), (i.next = t)), (r.pending = t), Ja(e, n)); + } + return ( + (i = r.interleaved), + i === null ? ((t.next = t), Ka(r)) : ((t.next = i.next), (i.next = t)), + (r.interleaved = t), + Ja(e, n) + ); + } + function eo(e, t, n) { + if (((t = t.updateQueue), t !== null && ((t = t.shared), n & 4194240))) { + var r = t.lanes; + ((r &= e.pendingLanes), (n |= r), (t.lanes = n), Vt(e, n)); + } + } + function to(e, t) { + var n = e.updateQueue, + r = e.alternate; + if (r !== null && ((r = r.updateQueue), n === r)) { + var i = null, + a = null; + if (((n = n.firstBaseUpdate), n !== null)) { + do { + var o = { + eventTime: n.eventTime, + lane: n.lane, + tag: n.tag, + payload: n.payload, + callback: n.callback, + next: null, + }; + (a === null ? (i = a = o) : (a = a.next = o), (n = n.next)); + } while (n !== null); + a === null ? (i = a = t) : (a = a.next = t); + } else i = a = t; + ((n = { baseState: r.baseState, firstBaseUpdate: i, lastBaseUpdate: a, shared: r.shared, effects: r.effects }), + (e.updateQueue = n)); + return; + } + ((e = n.lastBaseUpdate), e === null ? (n.firstBaseUpdate = t) : (e.next = t), (n.lastBaseUpdate = t)); + } + function no(e, t, n, r) { + var i = e.updateQueue; + Ya = !1; + var a = i.firstBaseUpdate, + o = i.lastBaseUpdate, + s = i.shared.pending; + if (s !== null) { + i.shared.pending = null; + var c = s, + l = c.next; + ((c.next = null), o === null ? (a = l) : (o.next = l), (o = c)); + var u = e.alternate; + u !== null && + ((u = u.updateQueue), + (s = u.lastBaseUpdate), + s !== o && (s === null ? (u.firstBaseUpdate = l) : (s.next = l), (u.lastBaseUpdate = c))); + } + if (a !== null) { + var d = i.baseState; + ((o = 0), (u = l = c = null), (s = a)); + do { + var f = s.lane, + p = s.eventTime; + if ((r & f) === f) { + u !== null && + (u = u.next = + { eventTime: p, lane: 0, tag: s.tag, payload: s.payload, callback: s.callback, next: null }); + a: { + var m = e, + h = s; + switch (((f = t), (p = n), h.tag)) { + case 1: + if (((m = h.payload), typeof m == `function`)) { + d = m.call(p, d, f); + break a; + } + d = m; + break a; + case 3: + m.flags = (m.flags & -65537) | 128; + case 0: + if (((m = h.payload), (f = typeof m == `function` ? m.call(p, d, f) : m), f == null)) break a; + d = F({}, d, f); + break a; + case 2: + Ya = !0; + } + } + s.callback !== null && + s.lane !== 0 && + ((e.flags |= 64), (f = i.effects), f === null ? (i.effects = [s]) : f.push(s)); + } else + ((p = { eventTime: p, lane: f, tag: s.tag, payload: s.payload, callback: s.callback, next: null }), + u === null ? ((l = u = p), (c = d)) : (u = u.next = p), + (o |= f)); + if (((s = s.next), s === null)) { + if (((s = i.shared.pending), s === null)) break; + ((f = s), (s = f.next), (f.next = null), (i.lastBaseUpdate = f), (i.shared.pending = null)); + } + } while (1); + if ( + (u === null && (c = d), + (i.baseState = c), + (i.firstBaseUpdate = l), + (i.lastBaseUpdate = u), + (t = i.shared.interleaved), + t !== null) + ) { + i = t; + do ((o |= i.lane), (i = i.next)); + while (i !== t); + } else a === null && (i.shared.lanes = 0); + ((Jc |= o), (e.lanes = o), (e.memoizedState = d)); + } + } + function ro(e, t, n) { + if (((e = t.effects), (t.effects = null), e !== null)) + for (t = 0; t < e.length; t++) { + var i = e[t], + a = i.callback; + if (a !== null) { + if (((i.callback = null), (i = n), typeof a != `function`)) throw Error(r(191, a)); + a.call(i); + } + } + } + var io = {}, + ao = zi(io), + oo = zi(io), + so = zi(io); + function co(e) { + if (e === io) throw Error(r(174)); + return e; + } + function lo(e, t) { + switch ((Y(so, t), Y(oo, e), Y(ao, io), (e = t.nodeType), e)) { + case 9: + case 11: + t = (t = t.documentElement) ? t.namespaceURI : De(null, ``); + break; + default: + ((e = e === 8 ? t.parentNode : t), (t = e.namespaceURI || null), (e = e.tagName), (t = De(t, e))); + } + (Bi(ao), Y(ao, t)); + } + function uo() { + (Bi(ao), Bi(oo), Bi(so)); + } + function fo(e) { + co(so.current); + var t = co(ao.current), + n = De(t, e.type); + t !== n && (Y(oo, e), Y(ao, n)); + } + function po(e) { + oo.current === e && (Bi(ao), Bi(oo)); + } + var mo = zi(0); + function ho(e) { + for (var t = e; t !== null; ) { + if (t.tag === 13) { + var n = t.memoizedState; + if (n !== null && ((n = n.dehydrated), n === null || n.data === `$?` || n.data === `$!`)) return t; + } else if (t.tag === 19 && t.memoizedProps.revealOrder !== void 0) { + if (t.flags & 128) return t; + } else if (t.child !== null) { + ((t.child.return = t), (t = t.child)); + continue; + } + if (t === e) break; + for (; t.sibling === null; ) { + if (t.return === null || t.return === e) return null; + t = t.return; + } + ((t.sibling.return = t.return), (t = t.sibling)); + } + return null; + } + var go = []; + function _o() { + for (var e = 0; e < go.length; e++) go[e]._workInProgressVersionPrimary = null; + go.length = 0; + } + var vo = C.ReactCurrentDispatcher, + yo = C.ReactCurrentBatchConfig, + bo = 0, + xo = null, + So = null, + Co = null, + wo = !1, + To = !1, + Eo = 0, + Do = 0; + function Oo() { + throw Error(r(321)); + } + function ko(e, t) { + if (t === null) return !1; + for (var n = 0; n < t.length && n < e.length; n++) if (!Or(e[n], t[n])) return !1; + return !0; + } + function Ao(e, t, n, i, a, o) { + if ( + ((bo = o), + (xo = t), + (t.memoizedState = null), + (t.updateQueue = null), + (t.lanes = 0), + (vo.current = e === null || e.memoizedState === null ? fs : ps), + (e = n(i, a)), + To) + ) { + o = 0; + do { + if (((To = !1), (Eo = 0), 25 <= o)) throw Error(r(301)); + ((o += 1), (Co = So = null), (t.updateQueue = null), (vo.current = ms), (e = n(i, a))); + } while (To); + } + if (((vo.current = ds), (t = So !== null && So.next !== null), (bo = 0), (Co = So = xo = null), (wo = !1), t)) + throw Error(r(300)); + return e; + } + function jo() { + var e = Eo !== 0; + return ((Eo = 0), e); + } + function Z() { + var e = { memoizedState: null, baseState: null, baseQueue: null, queue: null, next: null }; + return (Co === null ? (xo.memoizedState = Co = e) : (Co = Co.next = e), Co); + } + function Mo() { + if (So === null) { + var e = xo.alternate; + e = e === null ? null : e.memoizedState; + } else e = So.next; + var t = Co === null ? xo.memoizedState : Co.next; + if (t !== null) ((Co = t), (So = e)); + else { + if (e === null) throw Error(r(310)); + ((So = e), + (e = { + memoizedState: So.memoizedState, + baseState: So.baseState, + baseQueue: So.baseQueue, + queue: So.queue, + next: null, + }), + Co === null ? (xo.memoizedState = Co = e) : (Co = Co.next = e)); + } + return Co; + } + function No(e, t) { + return typeof t == `function` ? t(e) : t; + } + function Po(e) { + var t = Mo(), + n = t.queue; + if (n === null) throw Error(r(311)); + n.lastRenderedReducer = e; + var i = So, + a = i.baseQueue, + o = n.pending; + if (o !== null) { + if (a !== null) { + var s = a.next; + ((a.next = o.next), (o.next = s)); + } + ((i.baseQueue = a = o), (n.pending = null)); + } + if (a !== null) { + ((o = a.next), (i = i.baseState)); + var c = (s = null), + l = null, + u = o; + do { + var d = u.lane; + if ((bo & d) === d) + (l !== null && + (l = l.next = + { lane: 0, action: u.action, hasEagerState: u.hasEagerState, eagerState: u.eagerState, next: null }), + (i = u.hasEagerState ? u.eagerState : e(i, u.action))); + else { + var f = { lane: d, action: u.action, hasEagerState: u.hasEagerState, eagerState: u.eagerState, next: null }; + (l === null ? ((c = l = f), (s = i)) : (l = l.next = f), (xo.lanes |= d), (Jc |= d)); + } + u = u.next; + } while (u !== null && u !== o); + (l === null ? (s = i) : (l.next = c), + Or(i, t.memoizedState) || (Ms = !0), + (t.memoizedState = i), + (t.baseState = s), + (t.baseQueue = l), + (n.lastRenderedState = i)); + } + if (((e = n.interleaved), e !== null)) { + a = e; + do ((o = a.lane), (xo.lanes |= o), (Jc |= o), (a = a.next)); + while (a !== e); + } else a === null && (n.lanes = 0); + return [t.memoizedState, n.dispatch]; + } + function Fo(e) { + var t = Mo(), + n = t.queue; + if (n === null) throw Error(r(311)); + n.lastRenderedReducer = e; + var i = n.dispatch, + a = n.pending, + o = t.memoizedState; + if (a !== null) { + n.pending = null; + var s = (a = a.next); + do ((o = e(o, s.action)), (s = s.next)); + while (s !== a); + (Or(o, t.memoizedState) || (Ms = !0), + (t.memoizedState = o), + t.baseQueue === null && (t.baseState = o), + (n.lastRenderedState = o)); + } + return [o, i]; + } + function Io() {} + function Lo(e, t) { + var n = xo, + i = Mo(), + a = t(), + o = !Or(i.memoizedState, a); + if ( + (o && ((i.memoizedState = a), (Ms = !0)), + (i = i.queue), + Yo(Bo.bind(null, n, i, e), [e]), + i.getSnapshot !== t || o || (Co !== null && Co.memoizedState.tag & 1)) + ) { + if (((n.flags |= 2048), Wo(9, zo.bind(null, n, i, a, t), void 0, null), Vc === null)) throw Error(r(349)); + bo & 30 || Ro(n, t, a); + } + return a; + } + function Ro(e, t, n) { + ((e.flags |= 16384), + (e = { getSnapshot: t, value: n }), + (t = xo.updateQueue), + t === null + ? ((t = { lastEffect: null, stores: null }), (xo.updateQueue = t), (t.stores = [e])) + : ((n = t.stores), n === null ? (t.stores = [e]) : n.push(e))); + } + function zo(e, t, n, r) { + ((t.value = n), (t.getSnapshot = r), Vo(t) && Ho(e)); + } + function Bo(e, t, n) { + return n(function () { + Vo(t) && Ho(e); + }); + } + function Vo(e) { + var t = e.getSnapshot; + e = e.value; + try { + var n = t(); + return !Or(e, n); + } catch { + return !0; + } + } + function Ho(e) { + var t = Ja(e, 1); + t !== null && ml(t, e, 1, -1); + } + function Uo(e) { + var t = Z(); + return ( + typeof e == `function` && (e = e()), + (t.memoizedState = t.baseState = e), + (e = { + pending: null, + interleaved: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: No, + lastRenderedState: e, + }), + (t.queue = e), + (e = e.dispatch = ss.bind(null, xo, e)), + [t.memoizedState, e] + ); + } + function Wo(e, t, n, r) { + return ( + (e = { tag: e, create: t, destroy: n, deps: r, next: null }), + (t = xo.updateQueue), + t === null + ? ((t = { lastEffect: null, stores: null }), (xo.updateQueue = t), (t.lastEffect = e.next = e)) + : ((n = t.lastEffect), + n === null ? (t.lastEffect = e.next = e) : ((r = n.next), (n.next = e), (e.next = r), (t.lastEffect = e))), + e + ); + } + function Go() { + return Mo().memoizedState; + } + function Ko(e, t, n, r) { + var i = Z(); + ((xo.flags |= e), (i.memoizedState = Wo(1 | t, n, void 0, r === void 0 ? null : r))); + } + function qo(e, t, n, r) { + var i = Mo(); + r = r === void 0 ? null : r; + var a = void 0; + if (So !== null) { + var o = So.memoizedState; + if (((a = o.destroy), r !== null && ko(r, o.deps))) { + i.memoizedState = Wo(t, n, a, r); + return; + } + } + ((xo.flags |= e), (i.memoizedState = Wo(1 | t, n, a, r))); + } + function Jo(e, t) { + return Ko(8390656, 8, e, t); + } + function Yo(e, t) { + return qo(2048, 8, e, t); + } + function Xo(e, t) { + return qo(4, 2, e, t); + } + function Zo(e, t) { + return qo(4, 4, e, t); + } + function Qo(e, t) { + if (typeof t == `function`) + return ( + (e = e()), + t(e), + function () { + t(null); + } + ); + if (t != null) + return ( + (e = e()), + (t.current = e), + function () { + t.current = null; + } + ); + } + function $o(e, t, n) { + return ((n = n == null ? null : n.concat([e])), qo(4, 4, Qo.bind(null, t, e), n)); + } + function es() {} + function ts(e, t) { + var n = Mo(); + t = t === void 0 ? null : t; + var r = n.memoizedState; + return r !== null && t !== null && ko(t, r[1]) ? r[0] : ((n.memoizedState = [e, t]), e); + } + function ns(e, t) { + var n = Mo(); + t = t === void 0 ? null : t; + var r = n.memoizedState; + return r !== null && t !== null && ko(t, r[1]) ? r[0] : ((e = e()), (n.memoizedState = [e, t]), e); + } + function rs(e, t, n) { + return bo & 21 + ? (Or(n, t) || ((n = Lt()), (xo.lanes |= n), (Jc |= n), (e.baseState = !0)), t) + : (e.baseState && ((e.baseState = !1), (Ms = !0)), (e.memoizedState = n)); + } + function is(e, t) { + var n = B; + ((B = n !== 0 && 4 > n ? n : 4), e(!0)); + var r = yo.transition; + yo.transition = {}; + try { + (e(!1), t()); + } finally { + ((B = n), (yo.transition = r)); + } + } + function as() { + return Mo().memoizedState; + } + function os(e, t, n) { + var r = pl(e); + if (((n = { lane: r, action: n, hasEagerState: !1, eagerState: null, next: null }), cs(e))) ls(t, n); + else if (((n = qa(e, t, n, r)), n !== null)) { + var i = fl(); + (ml(n, e, r, i), us(n, t, r)); + } + } + function ss(e, t, n) { + var r = pl(e), + i = { lane: r, action: n, hasEagerState: !1, eagerState: null, next: null }; + if (cs(e)) ls(t, i); + else { + var a = e.alternate; + if (e.lanes === 0 && (a === null || a.lanes === 0) && ((a = t.lastRenderedReducer), a !== null)) + try { + var o = t.lastRenderedState, + s = a(o, n); + if (((i.hasEagerState = !0), (i.eagerState = s), Or(s, o))) { + var c = t.interleaved; + (c === null ? ((i.next = i), Ka(t)) : ((i.next = c.next), (c.next = i)), (t.interleaved = i)); + return; + } + } catch {} + ((n = qa(e, t, i, r)), n !== null && ((i = fl()), ml(n, e, r, i), us(n, t, r))); + } + } + function cs(e) { + var t = e.alternate; + return e === xo || (t !== null && t === xo); + } + function ls(e, t) { + To = wo = !0; + var n = e.pending; + (n === null ? (t.next = t) : ((t.next = n.next), (n.next = t)), (e.pending = t)); + } + function us(e, t, n) { + if (n & 4194240) { + var r = t.lanes; + ((r &= e.pendingLanes), (n |= r), (t.lanes = n), Vt(e, n)); + } + } + var ds = { + readContext: Wa, + useCallback: Oo, + useContext: Oo, + useEffect: Oo, + useImperativeHandle: Oo, + useInsertionEffect: Oo, + useLayoutEffect: Oo, + useMemo: Oo, + useReducer: Oo, + useRef: Oo, + useState: Oo, + useDebugValue: Oo, + useDeferredValue: Oo, + useTransition: Oo, + useMutableSource: Oo, + useSyncExternalStore: Oo, + useId: Oo, + unstable_isNewReconciler: !1, + }, + fs = { + readContext: Wa, + useCallback: function (e, t) { + return ((Z().memoizedState = [e, t === void 0 ? null : t]), e); + }, + useContext: Wa, + useEffect: Jo, + useImperativeHandle: function (e, t, n) { + return ((n = n == null ? null : n.concat([e])), Ko(4194308, 4, Qo.bind(null, t, e), n)); + }, + useLayoutEffect: function (e, t) { + return Ko(4194308, 4, e, t); + }, + useInsertionEffect: function (e, t) { + return Ko(4, 2, e, t); + }, + useMemo: function (e, t) { + var n = Z(); + return ((t = t === void 0 ? null : t), (e = e()), (n.memoizedState = [e, t]), e); + }, + useReducer: function (e, t, n) { + var r = Z(); + return ( + (t = n === void 0 ? t : n(t)), + (r.memoizedState = r.baseState = t), + (e = { + pending: null, + interleaved: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: e, + lastRenderedState: t, + }), + (r.queue = e), + (e = e.dispatch = os.bind(null, xo, e)), + [r.memoizedState, e] + ); + }, + useRef: function (e) { + var t = Z(); + return ((e = { current: e }), (t.memoizedState = e)); + }, + useState: Uo, + useDebugValue: es, + useDeferredValue: function (e) { + return (Z().memoizedState = e); + }, + useTransition: function () { + var e = Uo(!1), + t = e[0]; + return ((e = is.bind(null, e[1])), (Z().memoizedState = e), [t, e]); + }, + useMutableSource: function () {}, + useSyncExternalStore: function (e, t, n) { + var i = xo, + a = Z(); + if (ya) { + if (n === void 0) throw Error(r(407)); + n = n(); + } else { + if (((n = t()), Vc === null)) throw Error(r(349)); + bo & 30 || Ro(i, t, n); + } + a.memoizedState = n; + var o = { value: n, getSnapshot: t }; + return ( + (a.queue = o), + Jo(Bo.bind(null, i, o, e), [e]), + (i.flags |= 2048), + Wo(9, zo.bind(null, i, o, n, t), void 0, null), + n + ); + }, + useId: function () { + var e = Z(), + t = Vc.identifierPrefix; + if (ya) { + var n = fa, + r = da; + ((n = (r & ~(1 << (32 - Et(r) - 1))).toString(32) + n), + (t = `:` + t + `R` + n), + (n = Eo++), + 0 < n && (t += `H` + n.toString(32)), + (t += `:`)); + } else ((n = Do++), (t = `:` + t + `r` + n.toString(32) + `:`)); + return (e.memoizedState = t); + }, + unstable_isNewReconciler: !1, + }, + ps = { + readContext: Wa, + useCallback: ts, + useContext: Wa, + useEffect: Yo, + useImperativeHandle: $o, + useInsertionEffect: Xo, + useLayoutEffect: Zo, + useMemo: ns, + useReducer: Po, + useRef: Go, + useState: function () { + return Po(No); + }, + useDebugValue: es, + useDeferredValue: function (e) { + return rs(Mo(), So.memoizedState, e); + }, + useTransition: function () { + return [Po(No)[0], Mo().memoizedState]; + }, + useMutableSource: Io, + useSyncExternalStore: Lo, + useId: as, + unstable_isNewReconciler: !1, + }, + ms = { + readContext: Wa, + useCallback: ts, + useContext: Wa, + useEffect: Yo, + useImperativeHandle: $o, + useInsertionEffect: Xo, + useLayoutEffect: Zo, + useMemo: ns, + useReducer: Fo, + useRef: Go, + useState: function () { + return Fo(No); + }, + useDebugValue: es, + useDeferredValue: function (e) { + var t = Mo(); + return So === null ? (t.memoizedState = e) : rs(t, So.memoizedState, e); + }, + useTransition: function () { + return [Fo(No)[0], Mo().memoizedState]; + }, + useMutableSource: Io, + useSyncExternalStore: Lo, + useId: as, + unstable_isNewReconciler: !1, + }; + function hs(e, t) { + if (e && e.defaultProps) { + for (var n in ((t = F({}, t)), (e = e.defaultProps), e)) t[n] === void 0 && (t[n] = e[n]); + return t; + } + return t; + } + function gs(e, t, n, r) { + ((t = e.memoizedState), + (n = n(r, t)), + (n = n == null ? t : F({}, t, n)), + (e.memoizedState = n), + e.lanes === 0 && (e.updateQueue.baseState = n)); + } + var _s = { + isMounted: function (e) { + return (e = e._reactInternals) ? ot(e) === e : !1; + }, + enqueueSetState: function (e, t, n) { + e = e._reactInternals; + var r = fl(), + i = pl(e), + a = Qa(r, i); + ((a.payload = t), + n != null && (a.callback = n), + (t = $a(e, a, i)), + t !== null && (ml(t, e, i, r), eo(t, e, i))); + }, + enqueueReplaceState: function (e, t, n) { + e = e._reactInternals; + var r = fl(), + i = pl(e), + a = Qa(r, i); + ((a.tag = 1), + (a.payload = t), + n != null && (a.callback = n), + (t = $a(e, a, i)), + t !== null && (ml(t, e, i, r), eo(t, e, i))); + }, + enqueueForceUpdate: function (e, t) { + e = e._reactInternals; + var n = fl(), + r = pl(e), + i = Qa(n, r); + ((i.tag = 2), t != null && (i.callback = t), (t = $a(e, i, r)), t !== null && (ml(t, e, r, n), eo(t, e, r))); + }, + }; + function vs(e, t, n, r, i, a, o) { + return ( + (e = e.stateNode), + typeof e.shouldComponentUpdate == `function` + ? e.shouldComponentUpdate(r, a, o) + : t.prototype && t.prototype.isPureReactComponent + ? !kr(n, r) || !kr(i, a) + : !0 + ); + } + function ys(e, t, n) { + var r = !1, + i = Vi, + a = t.contextType; + return ( + typeof a == `object` && a + ? (a = Wa(a)) + : ((i = Ki(t) ? Wi : Hi.current), (r = t.contextTypes), (a = (r = r != null) ? Gi(e, i) : Vi)), + (t = new t(n, a)), + (e.memoizedState = t.state !== null && t.state !== void 0 ? t.state : null), + (t.updater = _s), + (e.stateNode = t), + (t._reactInternals = e), + r && + ((e = e.stateNode), + (e.__reactInternalMemoizedUnmaskedChildContext = i), + (e.__reactInternalMemoizedMaskedChildContext = a)), + t + ); + } + function bs(e, t, n, r) { + ((e = t.state), + typeof t.componentWillReceiveProps == `function` && t.componentWillReceiveProps(n, r), + typeof t.UNSAFE_componentWillReceiveProps == `function` && t.UNSAFE_componentWillReceiveProps(n, r), + t.state !== e && _s.enqueueReplaceState(t, t.state, null)); + } + function xs(e, t, n, r) { + var i = e.stateNode; + ((i.props = n), (i.state = e.memoizedState), (i.refs = {}), Xa(e)); + var a = t.contextType; + (typeof a == `object` && a ? (i.context = Wa(a)) : ((a = Ki(t) ? Wi : Hi.current), (i.context = Gi(e, a))), + (i.state = e.memoizedState), + (a = t.getDerivedStateFromProps), + typeof a == `function` && (gs(e, t, a, n), (i.state = e.memoizedState)), + typeof t.getDerivedStateFromProps == `function` || + typeof i.getSnapshotBeforeUpdate == `function` || + (typeof i.UNSAFE_componentWillMount != `function` && typeof i.componentWillMount != `function`) || + ((t = i.state), + typeof i.componentWillMount == `function` && i.componentWillMount(), + typeof i.UNSAFE_componentWillMount == `function` && i.UNSAFE_componentWillMount(), + t !== i.state && _s.enqueueReplaceState(i, i.state, null), + no(e, n, i, r), + (i.state = e.memoizedState)), + typeof i.componentDidMount == `function` && (e.flags |= 4194308)); + } + function Ss(e, t) { + try { + var n = ``, + r = t; + do ((n += ce(r)), (r = r.return)); + while (r); + var i = n; + } catch (e) { + i = + ` +Error generating stack: ` + + e.message + + ` +` + + e.stack; + } + return { value: e, source: t, stack: i, digest: null }; + } + function Cs(e, t, n) { + return { value: e, source: null, stack: n ?? null, digest: t ?? null }; + } + function ws(e, t) { + try { + console.error(t.value); + } catch (e) { + setTimeout(function () { + throw e; + }); + } + } + var Ts = typeof WeakMap == `function` ? WeakMap : Map; + function Es(e, t, n) { + ((n = Qa(-1, n)), (n.tag = 3), (n.payload = { element: null })); + var r = t.value; + return ( + (n.callback = function () { + (nl || ((nl = !0), (rl = r)), ws(e, t)); + }), + n + ); + } + function Ds(e, t, n) { + ((n = Qa(-1, n)), (n.tag = 3)); + var r = e.type.getDerivedStateFromError; + if (typeof r == `function`) { + var i = t.value; + ((n.payload = function () { + return r(i); + }), + (n.callback = function () { + ws(e, t); + })); + } + var a = e.stateNode; + return ( + a !== null && + typeof a.componentDidCatch == `function` && + (n.callback = function () { + (ws(e, t), typeof r != `function` && (il === null ? (il = new Set([this])) : il.add(this))); + var n = t.stack; + this.componentDidCatch(t.value, { componentStack: n === null ? `` : n }); + }), + n + ); + } + function Os(e, t, n) { + var r = e.pingCache; + if (r === null) { + r = e.pingCache = new Ts(); + var i = new Set(); + r.set(t, i); + } else ((i = r.get(t)), i === void 0 && ((i = new Set()), r.set(t, i))); + i.has(n) || (i.add(n), (e = zl.bind(null, e, t, n)), t.then(e, e)); + } + function ks(e) { + do { + var t; + if (((t = e.tag === 13) && ((t = e.memoizedState), (t = t === null ? !0 : t.dehydrated !== null)), t)) return e; + e = e.return; + } while (e !== null); + return null; + } + function As(e, t, n, r, i) { + return e.mode & 1 + ? ((e.flags |= 65536), (e.lanes = i), e) + : (e === t + ? (e.flags |= 65536) + : ((e.flags |= 128), + (n.flags |= 131072), + (n.flags &= -52805), + n.tag === 1 && (n.alternate === null ? (n.tag = 17) : ((t = Qa(-1, 1)), (t.tag = 2), $a(n, t, 1))), + (n.lanes |= 1)), + e); + } + var js = C.ReactCurrentOwner, + Ms = !1; + function Ns(e, t, n, r) { + t.child = e === null ? Fa(t, null, n, r) : Pa(t, e.child, n, r); + } + function Ps(e, t, n, r, i) { + n = n.render; + var a = t.ref; + return ( + Ua(t, i), + (r = Ao(e, t, n, r, a, i)), + (n = jo()), + e !== null && !Ms + ? ((t.updateQueue = e.updateQueue), (t.flags &= -2053), (e.lanes &= ~i), ec(e, t, i)) + : (ya && n && ha(t), (t.flags |= 1), Ns(e, t, r, i), t.child) + ); + } + function Fs(e, t, n, r, i) { + if (e === null) { + var a = n.type; + return typeof a == `function` && + !ql(a) && + a.defaultProps === void 0 && + n.compare === null && + n.defaultProps === void 0 + ? ((t.tag = 15), (t.type = a), Is(e, t, a, r, i)) + : ((e = Xl(n.type, null, r, t, t.mode, i)), (e.ref = t.ref), (e.return = t), (t.child = e)); + } + if (((a = e.child), (e.lanes & i) === 0)) { + var o = a.memoizedProps; + if (((n = n.compare), (n = n === null ? kr : n), n(o, r) && e.ref === t.ref)) return ec(e, t, i); + } + return ((t.flags |= 1), (e = Yl(a, r)), (e.ref = t.ref), (e.return = t), (t.child = e)); + } + function Is(e, t, n, r, i) { + if (e !== null) { + var a = e.memoizedProps; + if (kr(a, r) && e.ref === t.ref) + if (((Ms = !1), (t.pendingProps = r = a), (e.lanes & i) !== 0)) e.flags & 131072 && (Ms = !0); + else return ((t.lanes = e.lanes), ec(e, t, i)); + } + return zs(e, t, n, r, i); + } + function Ls(e, t, n) { + var r = t.pendingProps, + i = r.children, + a = e === null ? null : e.memoizedState; + if (r.mode === `hidden`) + if (!(t.mode & 1)) + ((t.memoizedState = { baseLanes: 0, cachePool: null, transitions: null }), Y(Gc, Wc), (Wc |= n)); + else { + if (!(n & 1073741824)) + return ( + (e = a === null ? n : a.baseLanes | n), + (t.lanes = t.childLanes = 1073741824), + (t.memoizedState = { baseLanes: e, cachePool: null, transitions: null }), + (t.updateQueue = null), + Y(Gc, Wc), + (Wc |= e), + null + ); + ((t.memoizedState = { baseLanes: 0, cachePool: null, transitions: null }), + (r = a === null ? n : a.baseLanes), + Y(Gc, Wc), + (Wc |= r)); + } + else (a === null ? (r = n) : ((r = a.baseLanes | n), (t.memoizedState = null)), Y(Gc, Wc), (Wc |= r)); + return (Ns(e, t, i, n), t.child); + } + function Rs(e, t) { + var n = t.ref; + ((e === null && n !== null) || (e !== null && e.ref !== n)) && ((t.flags |= 512), (t.flags |= 2097152)); + } + function zs(e, t, n, r, i) { + var a = Ki(n) ? Wi : Hi.current; + return ( + (a = Gi(t, a)), + Ua(t, i), + (n = Ao(e, t, n, r, a, i)), + (r = jo()), + e !== null && !Ms + ? ((t.updateQueue = e.updateQueue), (t.flags &= -2053), (e.lanes &= ~i), ec(e, t, i)) + : (ya && r && ha(t), (t.flags |= 1), Ns(e, t, n, i), t.child) + ); + } + function Bs(e, t, n, r, i) { + if (Ki(n)) { + var a = !0; + Xi(t); + } else a = !1; + if ((Ua(t, i), t.stateNode === null)) ($s(e, t), ys(t, n, r), xs(t, n, r, i), (r = !0)); + else if (e === null) { + var o = t.stateNode, + s = t.memoizedProps; + o.props = s; + var c = o.context, + l = n.contextType; + typeof l == `object` && l ? (l = Wa(l)) : ((l = Ki(n) ? Wi : Hi.current), (l = Gi(t, l))); + var u = n.getDerivedStateFromProps, + d = typeof u == `function` || typeof o.getSnapshotBeforeUpdate == `function`; + (d || + (typeof o.UNSAFE_componentWillReceiveProps != `function` && + typeof o.componentWillReceiveProps != `function`) || + ((s !== r || c !== l) && bs(t, o, r, l)), + (Ya = !1)); + var f = t.memoizedState; + ((o.state = f), + no(t, r, o, i), + (c = t.memoizedState), + s !== r || f !== c || Ui.current || Ya + ? (typeof u == `function` && (gs(t, n, u, r), (c = t.memoizedState)), + (s = Ya || vs(t, n, s, r, f, c, l)) + ? (d || + (typeof o.UNSAFE_componentWillMount != `function` && typeof o.componentWillMount != `function`) || + (typeof o.componentWillMount == `function` && o.componentWillMount(), + typeof o.UNSAFE_componentWillMount == `function` && o.UNSAFE_componentWillMount()), + typeof o.componentDidMount == `function` && (t.flags |= 4194308)) + : (typeof o.componentDidMount == `function` && (t.flags |= 4194308), + (t.memoizedProps = r), + (t.memoizedState = c)), + (o.props = r), + (o.state = c), + (o.context = l), + (r = s)) + : (typeof o.componentDidMount == `function` && (t.flags |= 4194308), (r = !1))); + } else { + ((o = t.stateNode), + Za(e, t), + (s = t.memoizedProps), + (l = t.type === t.elementType ? s : hs(t.type, s)), + (o.props = l), + (d = t.pendingProps), + (f = o.context), + (c = n.contextType), + typeof c == `object` && c ? (c = Wa(c)) : ((c = Ki(n) ? Wi : Hi.current), (c = Gi(t, c)))); + var p = n.getDerivedStateFromProps; + ((u = typeof p == `function` || typeof o.getSnapshotBeforeUpdate == `function`) || + (typeof o.UNSAFE_componentWillReceiveProps != `function` && + typeof o.componentWillReceiveProps != `function`) || + ((s !== d || f !== c) && bs(t, o, r, c)), + (Ya = !1), + (f = t.memoizedState), + (o.state = f), + no(t, r, o, i)); + var m = t.memoizedState; + s !== d || f !== m || Ui.current || Ya + ? (typeof p == `function` && (gs(t, n, p, r), (m = t.memoizedState)), + (l = Ya || vs(t, n, l, r, f, m, c) || !1) + ? (u || + (typeof o.UNSAFE_componentWillUpdate != `function` && typeof o.componentWillUpdate != `function`) || + (typeof o.componentWillUpdate == `function` && o.componentWillUpdate(r, m, c), + typeof o.UNSAFE_componentWillUpdate == `function` && o.UNSAFE_componentWillUpdate(r, m, c)), + typeof o.componentDidUpdate == `function` && (t.flags |= 4), + typeof o.getSnapshotBeforeUpdate == `function` && (t.flags |= 1024)) + : (typeof o.componentDidUpdate != `function` || + (s === e.memoizedProps && f === e.memoizedState) || + (t.flags |= 4), + typeof o.getSnapshotBeforeUpdate != `function` || + (s === e.memoizedProps && f === e.memoizedState) || + (t.flags |= 1024), + (t.memoizedProps = r), + (t.memoizedState = m)), + (o.props = r), + (o.state = m), + (o.context = c), + (r = l)) + : (typeof o.componentDidUpdate != `function` || + (s === e.memoizedProps && f === e.memoizedState) || + (t.flags |= 4), + typeof o.getSnapshotBeforeUpdate != `function` || + (s === e.memoizedProps && f === e.memoizedState) || + (t.flags |= 1024), + (r = !1)); + } + return Vs(e, t, n, r, a, i); + } + function Vs(e, t, n, r, i, a) { + Rs(e, t); + var o = (t.flags & 128) != 0; + if (!r && !o) return (i && Zi(t, n, !1), ec(e, t, a)); + ((r = t.stateNode), (js.current = t)); + var s = o && typeof n.getDerivedStateFromError != `function` ? null : r.render(); + return ( + (t.flags |= 1), + e !== null && o ? ((t.child = Pa(t, e.child, null, a)), (t.child = Pa(t, null, s, a))) : Ns(e, t, s, a), + (t.memoizedState = r.state), + i && Zi(t, n, !0), + t.child + ); + } + function Hs(e) { + var t = e.stateNode; + (t.pendingContext ? Ji(e, t.pendingContext, t.pendingContext !== t.context) : t.context && Ji(e, t.context, !1), + lo(e, t.containerInfo)); + } + function Us(e, t, n, r, i) { + return (Da(), Oa(i), (t.flags |= 256), Ns(e, t, n, r), t.child); + } + var Ws = { dehydrated: null, treeContext: null, retryLane: 0 }; + function Gs(e) { + return { baseLanes: e, cachePool: null, transitions: null }; + } + function Ks(e, t, n) { + var r = t.pendingProps, + i = mo.current, + a = !1, + o = (t.flags & 128) != 0, + s; + if ( + ((s = o) || (s = e !== null && e.memoizedState === null ? !1 : (i & 2) != 0), + s ? ((a = !0), (t.flags &= -129)) : (e === null || e.memoizedState !== null) && (i |= 1), + Y(mo, i & 1), + e === null) + ) + return ( + wa(t), + (e = t.memoizedState), + e !== null && ((e = e.dehydrated), e !== null) + ? (t.mode & 1 ? (e.data === `$!` ? (t.lanes = 8) : (t.lanes = 1073741824)) : (t.lanes = 1), null) + : ((o = r.children), + (e = r.fallback), + a + ? ((r = t.mode), + (a = t.child), + (o = { mode: `hidden`, children: o }), + !(r & 1) && a !== null ? ((a.childLanes = 0), (a.pendingProps = o)) : (a = Ql(o, r, 0, null)), + (e = Zl(e, r, n, null)), + (a.return = t), + (e.return = t), + (a.sibling = e), + (t.child = a), + (t.child.memoizedState = Gs(n)), + (t.memoizedState = Ws), + e) + : qs(t, o)) + ); + if (((i = e.memoizedState), i !== null && ((s = i.dehydrated), s !== null))) return Ys(e, t, o, r, s, i, n); + if (a) { + ((a = r.fallback), (o = t.mode), (i = e.child), (s = i.sibling)); + var c = { mode: `hidden`, children: r.children }; + return ( + !(o & 1) && t.child !== i + ? ((r = t.child), (r.childLanes = 0), (r.pendingProps = c), (t.deletions = null)) + : ((r = Yl(i, c)), (r.subtreeFlags = i.subtreeFlags & 14680064)), + s === null ? ((a = Zl(a, o, n, null)), (a.flags |= 2)) : (a = Yl(s, a)), + (a.return = t), + (r.return = t), + (r.sibling = a), + (t.child = r), + (r = a), + (a = t.child), + (o = e.child.memoizedState), + (o = o === null ? Gs(n) : { baseLanes: o.baseLanes | n, cachePool: null, transitions: o.transitions }), + (a.memoizedState = o), + (a.childLanes = e.childLanes & ~n), + (t.memoizedState = Ws), + r + ); + } + return ( + (a = e.child), + (e = a.sibling), + (r = Yl(a, { mode: `visible`, children: r.children })), + !(t.mode & 1) && (r.lanes = n), + (r.return = t), + (r.sibling = null), + e !== null && ((n = t.deletions), n === null ? ((t.deletions = [e]), (t.flags |= 16)) : n.push(e)), + (t.child = r), + (t.memoizedState = null), + r + ); + } + function qs(e, t) { + return ((t = Ql({ mode: `visible`, children: t }, e.mode, 0, null)), (t.return = e), (e.child = t)); + } + function Js(e, t, n, r) { + return ( + r !== null && Oa(r), + Pa(t, e.child, null, n), + (e = qs(t, t.pendingProps.children)), + (e.flags |= 2), + (t.memoizedState = null), + e + ); + } + function Ys(e, t, n, i, a, o, s) { + if (n) + return t.flags & 256 + ? ((t.flags &= -257), (i = Cs(Error(r(422)))), Js(e, t, s, i)) + : t.memoizedState === null + ? ((o = i.fallback), + (a = t.mode), + (i = Ql({ mode: `visible`, children: i.children }, a, 0, null)), + (o = Zl(o, a, s, null)), + (o.flags |= 2), + (i.return = t), + (o.return = t), + (i.sibling = o), + (t.child = i), + t.mode & 1 && Pa(t, e.child, null, s), + (t.child.memoizedState = Gs(s)), + (t.memoizedState = Ws), + o) + : ((t.child = e.child), (t.flags |= 128), null); + if (!(t.mode & 1)) return Js(e, t, s, null); + if (a.data === `$!`) { + if (((i = a.nextSibling && a.nextSibling.dataset), i)) var c = i.dgst; + return ((i = c), (o = Error(r(419))), (i = Cs(o, i, void 0)), Js(e, t, s, i)); + } + if (((c = (s & e.childLanes) !== 0), Ms || c)) { + if (((i = Vc), i !== null)) { + switch (s & -s) { + case 4: + a = 2; + break; + case 16: + a = 8; + break; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + a = 32; + break; + case 536870912: + a = 268435456; + break; + default: + a = 0; + } + ((a = (a & (i.suspendedLanes | s)) === 0 ? a : 0), + a !== 0 && a !== o.retryLane && ((o.retryLane = a), Ja(e, a), ml(i, e, a, -1))); + } + return (Ol(), (i = Cs(Error(r(421)))), Js(e, t, s, i)); + } + return a.data === `$?` + ? ((t.flags |= 128), (t.child = e.child), (t = Vl.bind(null, e)), (a._reactRetry = t), null) + : ((e = o.treeContext), + (va = Di(a.nextSibling)), + (_a = t), + (ya = !0), + (ba = null), + e !== null && ((ca[la++] = da), (ca[la++] = fa), (ca[la++] = ua), (da = e.id), (fa = e.overflow), (ua = t)), + (t = qs(t, i.children)), + (t.flags |= 4096), + t); + } + function Xs(e, t, n) { + e.lanes |= t; + var r = e.alternate; + (r !== null && (r.lanes |= t), Ha(e.return, t, n)); + } + function Zs(e, t, n, r, i) { + var a = e.memoizedState; + a === null + ? (e.memoizedState = { isBackwards: t, rendering: null, renderingStartTime: 0, last: r, tail: n, tailMode: i }) + : ((a.isBackwards = t), + (a.rendering = null), + (a.renderingStartTime = 0), + (a.last = r), + (a.tail = n), + (a.tailMode = i)); + } + function Qs(e, t, n) { + var r = t.pendingProps, + i = r.revealOrder, + a = r.tail; + if ((Ns(e, t, r.children, n), (r = mo.current), r & 2)) ((r = (r & 1) | 2), (t.flags |= 128)); + else { + if (e !== null && e.flags & 128) + a: for (e = t.child; e !== null; ) { + if (e.tag === 13) e.memoizedState !== null && Xs(e, n, t); + else if (e.tag === 19) Xs(e, n, t); + else if (e.child !== null) { + ((e.child.return = e), (e = e.child)); + continue; + } + if (e === t) break a; + for (; e.sibling === null; ) { + if (e.return === null || e.return === t) break a; + e = e.return; + } + ((e.sibling.return = e.return), (e = e.sibling)); + } + r &= 1; + } + if ((Y(mo, r), !(t.mode & 1))) t.memoizedState = null; + else + switch (i) { + case `forwards`: + for (n = t.child, i = null; n !== null; ) + ((e = n.alternate), e !== null && ho(e) === null && (i = n), (n = n.sibling)); + ((n = i), + n === null ? ((i = t.child), (t.child = null)) : ((i = n.sibling), (n.sibling = null)), + Zs(t, !1, i, n, a)); + break; + case `backwards`: + for (n = null, i = t.child, t.child = null; i !== null; ) { + if (((e = i.alternate), e !== null && ho(e) === null)) { + t.child = i; + break; + } + ((e = i.sibling), (i.sibling = n), (n = i), (i = e)); + } + Zs(t, !0, n, null, a); + break; + case `together`: + Zs(t, !1, null, null, void 0); + break; + default: + t.memoizedState = null; + } + return t.child; + } + function $s(e, t) { + !(t.mode & 1) && e !== null && ((e.alternate = null), (t.alternate = null), (t.flags |= 2)); + } + function ec(e, t, n) { + if ((e !== null && (t.dependencies = e.dependencies), (Jc |= t.lanes), (n & t.childLanes) === 0)) return null; + if (e !== null && t.child !== e.child) throw Error(r(153)); + if (t.child !== null) { + for (e = t.child, n = Yl(e, e.pendingProps), t.child = n, n.return = t; e.sibling !== null; ) + ((e = e.sibling), (n = n.sibling = Yl(e, e.pendingProps)), (n.return = t)); + n.sibling = null; + } + return t.child; + } + function tc(e, t, n) { + switch (t.tag) { + case 3: + (Hs(t), Da()); + break; + case 5: + fo(t); + break; + case 1: + Ki(t.type) && Xi(t); + break; + case 4: + lo(t, t.stateNode.containerInfo); + break; + case 10: + var r = t.type._context, + i = t.memoizedProps.value; + (Y(Ia, r._currentValue), (r._currentValue = i)); + break; + case 13: + if (((r = t.memoizedState), r !== null)) + return r.dehydrated === null + ? (n & t.child.childLanes) === 0 + ? (Y(mo, mo.current & 1), (e = ec(e, t, n)), e === null ? null : e.sibling) + : Ks(e, t, n) + : (Y(mo, mo.current & 1), (t.flags |= 128), null); + Y(mo, mo.current & 1); + break; + case 19: + if (((r = (n & t.childLanes) !== 0), e.flags & 128)) { + if (r) return Qs(e, t, n); + t.flags |= 128; + } + if ( + ((i = t.memoizedState), + i !== null && ((i.rendering = null), (i.tail = null), (i.lastEffect = null)), + Y(mo, mo.current), + r) + ) + break; + return null; + case 22: + case 23: + return ((t.lanes = 0), Ls(e, t, n)); + } + return ec(e, t, n); + } + var nc = function (e, t) { + for (var n = t.child; n !== null; ) { + if (n.tag === 5 || n.tag === 6) e.appendChild(n.stateNode); + else if (n.tag !== 4 && n.child !== null) { + ((n.child.return = n), (n = n.child)); + continue; + } + if (n === t) break; + for (; n.sibling === null; ) { + if (n.return === null || n.return === t) return; + n = n.return; + } + ((n.sibling.return = n.return), (n = n.sibling)); + } + }, + rc = function (e, t, n, r) { + var i = e.memoizedProps; + if (i !== r) { + ((e = t.stateNode), co(ao.current)); + var o = null; + switch (n) { + case `input`: + ((i = he(e, i)), (r = he(e, r)), (o = [])); + break; + case `select`: + ((i = F({}, i, { value: void 0 })), (r = F({}, r, { value: void 0 })), (o = [])); + break; + case `textarea`: + ((i = Se(e, i)), (r = Se(e, r)), (o = [])); + break; + default: + typeof i.onClick != `function` && typeof r.onClick == `function` && (e.onclick = _i); + } + Ie(n, r); + var s; + for (u in ((n = null), i)) + if (!r.hasOwnProperty(u) && i.hasOwnProperty(u) && i[u] != null) + if (u === `style`) { + var c = i[u]; + for (s in c) c.hasOwnProperty(s) && ((n ||= {}), (n[s] = ``)); + } else + u !== `dangerouslySetInnerHTML` && + u !== `children` && + u !== `suppressContentEditableWarning` && + u !== `suppressHydrationWarning` && + u !== `autoFocus` && + (a.hasOwnProperty(u) ? (o ||= []) : (o ||= []).push(u, null)); + for (u in r) { + var l = r[u]; + if (((c = i?.[u]), r.hasOwnProperty(u) && l !== c && (l != null || c != null))) + if (u === `style`) + if (c) { + for (s in c) !c.hasOwnProperty(s) || (l && l.hasOwnProperty(s)) || ((n ||= {}), (n[s] = ``)); + for (s in l) l.hasOwnProperty(s) && c[s] !== l[s] && ((n ||= {}), (n[s] = l[s])); + } else (n || ((o ||= []), o.push(u, n)), (n = l)); + else + u === `dangerouslySetInnerHTML` + ? ((l = l ? l.__html : void 0), + (c = c ? c.__html : void 0), + l != null && c !== l && (o ||= []).push(u, l)) + : u === `children` + ? (typeof l != `string` && typeof l != `number`) || (o ||= []).push(u, `` + l) + : u !== `suppressContentEditableWarning` && + u !== `suppressHydrationWarning` && + (a.hasOwnProperty(u) + ? (l != null && u === `onScroll` && G(`scroll`, e), o || c === l || (o = [])) + : (o ||= []).push(u, l)); + } + n && (o ||= []).push(`style`, n); + var u = o; + (t.updateQueue = u) && (t.flags |= 4); + } + }, + ic = function (e, t, n, r) { + n !== r && (t.flags |= 4); + }; + function ac(e, t) { + if (!ya) + switch (e.tailMode) { + case `hidden`: + t = e.tail; + for (var n = null; t !== null; ) (t.alternate !== null && (n = t), (t = t.sibling)); + n === null ? (e.tail = null) : (n.sibling = null); + break; + case `collapsed`: + n = e.tail; + for (var r = null; n !== null; ) (n.alternate !== null && (r = n), (n = n.sibling)); + r === null ? (t || e.tail === null ? (e.tail = null) : (e.tail.sibling = null)) : (r.sibling = null); + } + } + function oc(e) { + var t = e.alternate !== null && e.alternate.child === e.child, + n = 0, + r = 0; + if (t) + for (var i = e.child; i !== null; ) + ((n |= i.lanes | i.childLanes), + (r |= i.subtreeFlags & 14680064), + (r |= i.flags & 14680064), + (i.return = e), + (i = i.sibling)); + else + for (i = e.child; i !== null; ) + ((n |= i.lanes | i.childLanes), (r |= i.subtreeFlags), (r |= i.flags), (i.return = e), (i = i.sibling)); + return ((e.subtreeFlags |= r), (e.childLanes = n), t); + } + function sc(e, t, n) { + var i = t.pendingProps; + switch ((ga(t), t.tag)) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return (oc(t), null); + case 1: + return (Ki(t.type) && qi(), oc(t), null); + case 3: + return ( + (i = t.stateNode), + uo(), + Bi(Ui), + Bi(Hi), + _o(), + i.pendingContext && ((i.context = i.pendingContext), (i.pendingContext = null)), + (e === null || e.child === null) && + (Ea(t) + ? (t.flags |= 4) + : e === null || + (e.memoizedState.isDehydrated && !(t.flags & 256)) || + ((t.flags |= 1024), ba !== null && (vl(ba), (ba = null)))), + oc(t), + null + ); + case 5: + po(t); + var o = co(so.current); + if (((n = t.type), e !== null && t.stateNode != null)) + (rc(e, t, n, i, o), e.ref !== t.ref && ((t.flags |= 512), (t.flags |= 2097152))); + else { + if (!i) { + if (t.stateNode === null) throw Error(r(166)); + return (oc(t), null); + } + if (((e = co(ao.current)), Ea(t))) { + ((i = t.stateNode), (n = t.type)); + var s = t.memoizedProps; + switch (((i[ki] = t), (i[Ai] = s), (e = (t.mode & 1) != 0), n)) { + case `dialog`: + (G(`cancel`, i), G(`close`, i)); + break; + case `iframe`: + case `object`: + case `embed`: + G(`load`, i); + break; + case `video`: + case `audio`: + for (o = 0; o < ei.length; o++) G(ei[o], i); + break; + case `source`: + G(`error`, i); + break; + case `img`: + case `image`: + case `link`: + (G(`error`, i), G(`load`, i)); + break; + case `details`: + G(`toggle`, i); + break; + case `input`: + (R(i, s), G(`invalid`, i)); + break; + case `select`: + ((i._wrapperState = { wasMultiple: !!s.multiple }), G(`invalid`, i)); + break; + case `textarea`: + (Ce(i, s), G(`invalid`, i)); + } + for (var c in (Ie(n, s), (o = null), s)) + if (s.hasOwnProperty(c)) { + var l = s[c]; + c === `children` + ? typeof l == `string` + ? i.textContent !== l && + (!0 !== s.suppressHydrationWarning && gi(i.textContent, l, e), (o = [`children`, l])) + : typeof l == `number` && + i.textContent !== `` + l && + (!0 !== s.suppressHydrationWarning && gi(i.textContent, l, e), (o = [`children`, `` + l])) + : a.hasOwnProperty(c) && l != null && c === `onScroll` && G(`scroll`, i); + } + switch (n) { + case `input`: + (L(i), ve(i, s, !0)); + break; + case `textarea`: + (L(i), Te(i)); + break; + case `select`: + case `option`: + break; + default: + typeof s.onClick == `function` && (i.onclick = _i); + } + ((i = o), (t.updateQueue = i), i !== null && (t.flags |= 4)); + } else { + ((c = o.nodeType === 9 ? o : o.ownerDocument), + e === `http://www.w3.org/1999/xhtml` && (e = Ee(n)), + e === `http://www.w3.org/1999/xhtml` + ? n === `script` + ? ((e = c.createElement(`div`)), + (e.innerHTML = ` - - - - -
- - + + + + + + + + + + + + + + PaperParty + + + + + +
+ + diff --git a/pro/index.html b/pro/index.html index 81c6b4e..abf3e9e 100644 --- a/pro/index.html +++ b/pro/index.html @@ -1,19 +1,19 @@ - + - + - - - + + + PaperParty diff --git a/pro/package-lock.json b/pro/package-lock.json index 1e1be5b..64bb2c1 100644 --- a/pro/package-lock.json +++ b/pro/package-lock.json @@ -9,14 +9,15 @@ "version": "0.1.0", "dependencies": { "canvas-confetti": "^1.9.4", + "framer-motion": "^12.40.0", "lucide-react": "^1.16.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.30.3", + "react-zoom-pan-pinch": "^4.0.3", "socket.io-client": "^4.8.3", "sweetalert2": "^11.26.24", - "use-sound": "^5.0.0", - "web-vitals": "^2.1.4" + "use-sound": "^5.0.0" }, "devDependencies": { "@tailwindcss/vite": "^4.3.0", @@ -1649,6 +1650,33 @@ } } }, + "node_modules/framer-motion": { + "version": "12.40.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.40.0.tgz", + "integrity": "sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.40.0", + "motion-utils": "^12.39.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2099,6 +2127,21 @@ "node": ">=4" } }, + "node_modules/motion-dom": { + "version": "12.40.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.40.0.tgz", + "integrity": "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.39.0" + } + }, + "node_modules/motion-utils": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz", + "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2305,6 +2348,20 @@ "react-dom": ">=16.8" } }, + "node_modules/react-zoom-pan-pinch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-4.0.3.tgz", + "integrity": "sha512-N2Hi6L78fFmhRra+ORpFSW7WST5x6kxpOPplIvtB0b7b+U2anpo1z1wLgaWRPS2kUSqcraRG+JgBCIlDJnqqAg==", + "license": "MIT", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -2628,9 +2685,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true + "license": "0BSD" }, "node_modules/undici": { "version": "7.25.0", @@ -2835,11 +2890,6 @@ "node": ">=18" } }, - "node_modules/web-vitals": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" - }, "node_modules/webidl-conversions": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", diff --git a/pro/package.json b/pro/package.json index 601dd7c..4f643f0 100644 --- a/pro/package.json +++ b/pro/package.json @@ -4,14 +4,15 @@ "private": true, "dependencies": { "canvas-confetti": "^1.9.4", + "framer-motion": "^12.40.0", "lucide-react": "^1.16.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.30.3", + "react-zoom-pan-pinch": "^4.0.3", "socket.io-client": "^4.8.3", "sweetalert2": "^11.26.24", - "use-sound": "^5.0.0", - "web-vitals": "^2.1.4" + "use-sound": "^5.0.0" }, "scripts": { "dev": "vite", @@ -19,12 +20,6 @@ "preview": "vite preview", "test": "vitest" }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, "browserslist": { "production": [ ">0.2%", diff --git a/pro/src/App.jsx b/pro/src/App.jsx index 351e4cc..14ade13 100644 --- a/pro/src/App.jsx +++ b/pro/src/App.jsx @@ -5,6 +5,8 @@ import Bingo from './bingo/Bingo'; import TicTacToe from './tictactoe/TicTacToe'; import UTTTGame from './uttt/UTTTGame'; import DabGame from './dab/DabGame'; +import SOSGame from './sos/SOSGame'; +import Connect4Game from './connect4/Connect4Game'; import NotFound from './components/NotFound'; function App() { @@ -17,6 +19,8 @@ function App() { } /> } /> } /> + } /> + } /> } /> diff --git a/pro/src/bingo/Bingo.css b/pro/src/bingo/Bingo.css deleted file mode 100644 index 91460fa..0000000 --- a/pro/src/bingo/Bingo.css +++ /dev/null @@ -1,19 +0,0 @@ -/* Bingo.css */ -.bingo { - text-align: center; -} - -.bingo-grid { - display: grid; - grid-template-columns: repeat(5, 1fr); - grid-gap: 5px; -} - -.bingo-cell { - display: flex; - justify-content: center; - align-items: center; - width: 50px; - height: 50px; - border: 1px solid #ccc; -} \ No newline at end of file diff --git a/pro/src/bingo/Bingo.jsx b/pro/src/bingo/Bingo.jsx index d62d43e..22d8ae0 100644 --- a/pro/src/bingo/Bingo.jsx +++ b/pro/src/bingo/Bingo.jsx @@ -1,18 +1,26 @@ -import React, { useState, useEffect, useCallback } from 'react'; +import React, { useState, useEffect, useCallback, useRef } from 'react'; import { useGameContext } from '../context/GameContext'; -import RetroButton from '../components/ui/RetroButton'; +import { + SketchButton, + SketchCard, + sketchPopupClass, + GameLayout, + AvatarSelector, + AvatarReactionBar, +} from '../components/ui'; import useSound from 'use-sound'; import confetti from 'canvas-confetti'; import Swal from 'sweetalert2'; import { useNavigate } from 'react-router-dom'; -import { ArrowLeft, Users, Trophy, SwatchBook, Timer } from 'lucide-react'; +import { Users, Trophy, SwatchBook, Timer } from 'lucide-react'; +import useSocketListeners from '../hooks/useSocketListeners'; +import useReconnection from '../hooks/useReconnection'; + +const PLAYER_COLORS = ['#2a2a3e', '#c73e1d', '#2d4a8f', '#2f5233']; const Bingo = () => { - const { socket, playerName, roomId, setRoomId } = useGameContext(); - const [numbers, setNumbers] = useState(() => { - const nums = Array.from({ length: 25 }, (_, i) => i + 1); - return nums.sort(() => Math.random() - 0.5); - }); + const { socket, roomId, setRoomId, clearRoomId, profile, setProfile, setGamePrefix } = useGameContext(); + const [numbers, setNumbers] = useState(Array.from({ length: 25 }, (_, i) => i + 1)); const [players, setPlayers] = useState([]); const [gameState, setGameState] = useState('waiting'); const [currentTurn, setCurrentTurn] = useState(null); @@ -21,274 +29,446 @@ const Bingo = () => { const [turnTimer, setTurnTimer] = useState(30); const navigate = useNavigate(); + const strikedNumbersRef = useRef([]); + const timerRef = useRef(null); const [playPop] = useSound('/sounds/pop.mp3', { volume: 0.5 }); - const [playWin] = useSound('/sounds/win.mp3', { volume: 0.7 }); const [playTurn] = useSound('/sounds/turn.mp3', { volume: 0.6 }); - useEffect(() => { - let timerInterval; - if (gameState === 'playing' && currentTurn === socket?.id && turnTimer > 0) { - timerInterval = setInterval(() => { - setTurnTimer(prev => prev - 1); - }, 1000); + const calculateBingoProgress = useCallback((boardNumbers) => { + const size = 5; + const lines = []; + for (let i = 0; i < size; i++) { + lines.push(Array.from({ length: size }, (_, j) => i * size + j)); } - return () => clearInterval(timerInterval); - }, [gameState, currentTurn, socket?.id, turnTimer]); - - useEffect(() => { - if (!socket) return; + for (let i = 0; i < size; i++) { + lines.push(Array.from({ length: size }, (_, j) => i + j * size)); + } + lines.push(Array.from({ length: size }, (_, i) => i * size + i)); + lines.push(Array.from({ length: size }, (_, i) => (i + 1) * size - (i + 1))); - socket.on('bingo_roomInfo', ({ id, creator, players, gameState, currentTurn }) => { - setRoomId(id); - setPlayers(players); - setGameState(gameState); - setCurrentTurn(currentTurn); - setIsCreator(creator === socket.id); - }); + const completedLinesCount = lines.filter((line) => + line.every((idx) => typeof boardNumbers[idx] === 'string'), + ).length; - socket.on('bingo_gameStarted', (firstPlayerId) => { - setGameState('playing'); - setCurrentTurn(firstPlayerId); - setTurnTimer(30); - Swal.fire({ - title: 'Eyes Down!', - text: 'Bingo has started!', - timer: 1500, - showConfirmButton: false, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); + return 'BINGO'.slice(0, Math.min(completedLinesCount, 5)); + }, []); - socket.on('bingo_gameRestarted', () => { - setNumbers(Array.from({ length: 25 }, (_, i) => i + 1).sort(() => Math.random() - 0.5)); - setStrikedOut(''); - setGameState('ready'); - Swal.fire({ - title: 'Game Restarted', - text: 'New card generated!', - timer: 1500, - showConfirmButton: false, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); + const { clearReconnect } = useReconnection({ + socket, + gamePrefix: 'bingo', + roomId, + onRestore: (room) => { + if (!room) return; + setRoomId(room.id); + setPlayers(room.players || []); + setGameState(room.gameState || 'waiting'); + setCurrentTurn(room.currentTurn); + setIsCreator(room.creator === socket.id); + }, + }); - socket.on('bingo_numberMarked', ({ number, playerId }) => { - setNumbers(prev => prev.map(n => n === number ? 'X' : n)); - playPop(); - }); + useSocketListeners( + socket, + { + bingo_roomInfo: ({ id, creator, players, gameState, currentTurn, strikedNumbers }) => { + setRoomId(id); + setPlayers(players); + setGameState(gameState); + setCurrentTurn(currentTurn); + setIsCreator(creator === socket.id); - socket.on('bingo_nextTurn', (nextPlayerId) => { - setCurrentTurn(nextPlayerId); - setTurnTimer(30); - if (nextPlayerId === socket.id) { - playTurn(); - } - }); + try { + const savedBoard = localStorage.getItem(`bingo_board_${id}`); + if (savedBoard) { + setNumbers(JSON.parse(savedBoard)); + } + } catch { + localStorage.removeItem(`bingo_board_${id}`); + } - socket.on('bingo_playerWon', (winnerId) => { - playWin(); - confetti({ - particleCount: 150, - spread: 70, - origin: { y: 0.6 } - }); - const winnerName = players.find(p => p.id === winnerId)?.name || 'Someone'; - Swal.fire({ - title: 'BINGO!', - text: `${winnerName} has achieved Bingo!`, - icon: 'success', - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - setGameState('ended'); - }); + if (strikedNumbers) { + strikedNumbersRef.current = strikedNumbers; + } + }, + bingo_playerBoard: ({ board }) => { + const sn = strikedNumbersRef.current; + const updatedBoard = sn.length > 0 ? board.map((n) => (sn.includes(n) ? 'X' : n)) : board; + setNumbers(updatedBoard); + }, + bingo_gamePaused: ({ reason }) => { + Swal.fire({ + title: 'Game Paused', + text: reason, + icon: 'warning', + customClass: { popup: sketchPopupClass }, + }); + }, + bingo_gameStarted: ({ firstPlayerId, playerBoards }) => { + setGameState('playing'); + setCurrentTurn(firstPlayerId); + setTurnTimer(30); + setStrikedOut(''); - socket.on('bingo_playerLeft', (playerId) => { - Swal.fire({ - title: 'Player Left', - text: 'A player has left the game.', - icon: 'warning', - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); + if (playerBoards?.[socket.id]) { + setNumbers(playerBoards[socket.id]); + } - socket.on('bingo_alert', ({ icon, title, text }) => { - Swal.fire({ icon, title, text, customClass: { popup: 'glass rounded-3xl paper-font' } }); - }); + Swal.fire({ + title: 'Eyes Down!', + text: 'Bingo has started!', + timer: 1500, + showConfirmButton: false, + customClass: { popup: sketchPopupClass }, + }); + }, + bingo_gameRestarted: () => { + setGameState('ready'); + setStrikedOut(''); + setNumbers(Array.from({ length: 25 }, (_, i) => i + 1)); + }, + bingo_numberMarked: ({ nextTurn, strikedNumbers }) => { + setNumbers((prev) => prev.map((n) => (strikedNumbers.includes(n) ? 'X' : n))); + setCurrentTurn(nextTurn); + playPop(); + }, + bingo_nextTurn: ({ nextPlayerId, timestamp }) => { + setCurrentTurn(nextPlayerId); + const elapsed = Math.floor((Date.now() - timestamp) / 1000); + setTurnTimer(Math.max(0, 30 - elapsed)); + if (nextPlayerId === socket.id) { + playTurn(); + } + }, + bingo_playerWon: ({ winner }) => { + const playerColor = players.find((p) => p.id === winner)?.color || '#2a2a3e'; + confetti({ + particleCount: 150, + spread: 70, + origin: { y: 0.6 }, + colors: [playerColor], + }); + const winnerName = players.find((p) => p.id === winner)?.name || 'Someone'; + Swal.fire({ + title: 'BINGO!', + text: `${winnerName} has achieved Bingo!`, + icon: 'success', + customClass: { popup: sketchPopupClass }, + }); + setGameState('ended'); + clearReconnect(); + }, + bingo_playerLeft: (_playerId) => { + Swal.fire({ + title: 'Player Left', + text: 'A player has left the game.', + icon: 'warning', + customClass: { popup: sketchPopupClass }, + }); + }, + bingo_alert: ({ icon, title, text }) => { + if (title === 'Room Created') { + Swal.fire({ + icon, + title, + text, + timer: 2000, + showConfirmButton: false, + customClass: { popup: sketchPopupClass }, + }); + } else { + Swal.fire({ + icon, + title, + text, + customClass: { popup: sketchPopupClass }, + }); + } + }, + bingo_reconnectFailed: ({ reason, roomId: failedRoomId }) => { + Swal.fire({ + title: 'Reconnection Failed', + text: + reason === 'room_not_found' + ? 'The room no longer exists.' + : reason === 'player_not_found' + ? 'Your player session was not found.' + : reason === 'game_already_ended' + ? 'The game has ended.' + : 'Could not reconnect to the game.', + icon: 'error', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(failedRoomId); + navigate('/'); + }); + }, + server_shutdown: ({ message }) => { + Swal.fire({ + title: 'Server Shutting Down', + text: message || 'The server is going down for maintenance.', + icon: 'info', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(roomId); + navigate('/'); + }); + }, + }, + [roomId, players, playPop, playTurn, setRoomId, clearReconnect, clearRoomId, navigate], + ); - return () => { - socket.off('bingo_roomInfo'); - socket.off('bingo_gameStarted'); - socket.off('bingo_gameRestarted'); - socket.off('bingo_numberMarked'); - socket.off('bingo_nextTurn'); - socket.off('bingo_playerWon'); - socket.off('bingo_playerLeft'); - socket.off('bingo_alert'); - }; - }, [socket, players, setRoomId, playPop, playWin, playTurn]); + useEffect(() => { + if (!socket) return; - const checkForWin = useCallback(() => { - const size = 5; - const lines = []; + setGamePrefix('bingo'); - // Horizontal - for (let i = 0; i < size; i++) { - lines.push(Array.from({ length: size }, (_, j) => i * size + j)); + const saved = sessionStorage.getItem('bingo_reconnect'); + const hasSavedReconnect = saved && !roomId; + if (hasSavedReconnect) { + const { roomId: savedRoomId, playerId } = JSON.parse(saved); + socket.emit('bingo_reconnect', { roomId: savedRoomId, playerId }); + setRoomId(savedRoomId); } - // Vertical - for (let i = 0; i < size; i++) { - lines.push(Array.from({ length: size }, (_, j) => i + j * size)); + + // recovery: emit requestRoomInfo if roomId exists but we haven't received roomInfo yet + if (roomId && !hasSavedReconnect) { + socket.emit('bingo_requestRoomInfo', roomId); } - // Diagonals - lines.push(Array.from({ length: size }, (_, i) => i * size + i)); - lines.push(Array.from({ length: size }, (_, i) => (i + 1) * size - (i + 1))); + }, [socket, roomId, setGamePrefix, setRoomId]); - const completedLinesCount = lines.filter(line => line.every(cell => numbers[cell] === 'X')).length; - const newStrikedOut = 'BINGO'.slice(0, Math.min(completedLinesCount, 5)); + useEffect(() => { + if (gameState !== 'playing' || numbers.length !== 25) return; - if (newStrikedOut.length > strikedOut.length) { - setStrikedOut(newStrikedOut); - if (newStrikedOut === 'BINGO') { + const progress = calculateBingoProgress(numbers); + if (progress.length > strikedOut.length) { + setStrikedOut(progress); + if (progress === 'BINGO') { socket.emit('bingo_achieved', roomId); } } - }, [numbers, strikedOut, roomId, socket]); + }, [socket, numbers, gameState, strikedOut, calculateBingoProgress, roomId]); useEffect(() => { - checkForWin(); - }, [numbers, checkForWin]); + if (timerRef.current) clearInterval(timerRef.current); + if (gameState === 'playing' && currentTurn === socket?.id && turnTimer > 0) { + timerRef.current = setInterval(() => { + setTurnTimer((prev) => prev - 1); + }, 1000); + } + return () => { + if (timerRef.current) clearInterval(timerRef.current); + }; + }, [gameState, currentTurn, socket?.id]); // eslint-disable-line react-hooks/exhaustive-deps + + const handleCellClick = useCallback( + (number) => { + if (gameState !== 'playing') return; + if (currentTurn !== socket?.id) return; + if (typeof number === 'string') return; - const handleCellClick = (number) => { - if (gameState === 'playing' && currentTurn === socket?.id && number !== 'X') { socket.emit('bingo_markNumber', { roomId, number }); - } - }; + }, + [gameState, currentTurn, roomId, socket], + ); - const handleCreateRoom = () => { - socket.emit('bingo_createRoom', playerName); - }; + const handleCreateRoom = useCallback(() => { + socket.emit('bingo_createRoom', { + creatorName: profile.name, + avatarIcon: profile.avatarIcon, + color: profile.color, + }); + }, [socket, profile]); - const handleJoinRoom = async () => { + const handleJoinRoom = useCallback(async () => { const { value: joinRoomId } = await Swal.fire({ title: 'Join Bingo Room', input: 'text', inputPlaceholder: 'Enter Room ID', showCancelButton: true, - customClass: { popup: 'glass rounded-3xl paper-font' } + customClass: { popup: sketchPopupClass }, }); if (joinRoomId) { - socket.emit('bingo_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); + socket.emit('bingo_joinRoom', { + roomId: joinRoomId.toUpperCase(), + playerName: profile.name, + avatarIcon: profile.avatarIcon, + color: profile.color, + }); } - }; + }, [socket, profile]); - const handleStartGame = () => { + const handleStartGame = useCallback(() => { if (players.length < 2) { - Swal.fire({ title: 'Wait!', text: 'Need at least 2 players!', icon: 'info' }); + Swal.fire({ + title: 'Wait!', + text: 'Need at least 2 players!', + icon: 'info', + }); return; } socket.emit('bingo_startGame', roomId); - }; + }, [socket, roomId, players.length]); - const handleRestartGame = () => { - socket.emit('bingo_restartGame', roomId); - }; + const handleLeaveRoom = useCallback(async () => { + const result = await Swal.fire({ + title: 'Leave Game?', + text: 'Are you sure you want to leave?', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Yes, leave', + customClass: { popup: sketchPopupClass }, + }); + if (result.isConfirmed) { + socket.emit('bingo_leaveRoom', roomId); + clearReconnect(); + clearRoomId(roomId); + navigate('/'); + } + }, [socket, roomId, clearReconnect, clearRoomId, navigate]); return ( -
- navigate('/')} - variant="secondary" - className="absolute top-8 left-8 flex items-center gap-2" - > - - Back - - -

Bingo Party

- - {!roomId ? ( -
- Create Room - Join Room -
- ) : ( -
-
-
-
- - Room: {roomId} -
-
- {'BINGO'.split('').map((l, i) => ( - - {l} - - ))} -
-
+ +
+

Bingo Party

-
- {numbers.map((n, i) => ( - - ))} + {!roomId ? ( + + setProfile((prev) => ({ ...prev, name: e.target.value }))} + placeholder="Enter your name" + className="w-full sketch-border font-handwriting text-ink px-3 py-2 rounded mb-4" + /> + setProfile((prev) => ({ ...prev, avatarIcon: icon }))} + onColorChange={(c) => setProfile((prev) => ({ ...prev, color: c }))} + /> +
+ Create Room + Join Room
-
+ + ) : ( +
+
+ +
+ + Room: {roomId} +
+
+ {'BINGO'.split('').map((l, i) => ( + + {l} + + ))} +
+
-
-
-

- - Players -

-
- {players.map(p => ( -
- {p.name} - {p.id === currentTurn && } -
+
+ {numbers.map((n, i) => ( + ))}
- {isCreator && gameState === 'ready' && ( - - 🚀 Start Party! - - )} - - {gameState === 'playing' && ( -
-
- - Time Remaining -
-
- {turnTimer}s +
+ +

+ + Players +

+
+ {players.map((p, i) => ( +
+
+ + {p.name} + {p.id === socket?.id && ' (You)'} + +
+
+ ))}
- {currentTurn === socket?.id && ( -
- - Your Turn! + + + {isCreator && gameState === 'ready' && ( + + Start Party! + + )} + + {(gameState === 'ready' || gameState === 'playing') && ( + + Leave Room + + )} + + {gameState === 'playing' && ( + +
+ + Time Remaining
- )} -
- )} +
+ {turnTimer}s +
+ {currentTurn === socket?.id && ( +
+ + Your Turn! +
+ )} +
+ )} +
-
+ )} +
+ + {gameState === 'playing' && ( + )} -
+ ); }; diff --git a/pro/src/bingo/Bingo.test.jsx b/pro/src/bingo/Bingo.test.jsx index b60a8f9..8bd4f96 100644 --- a/pro/src/bingo/Bingo.test.jsx +++ b/pro/src/bingo/Bingo.test.jsx @@ -3,9 +3,9 @@ import { render, screen, fireEvent, act } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import Bingo from './Bingo'; import { GameProvider } from '../context/GameContext'; +import { ThemeProvider } from '../context/ThemeContext'; import { BrowserRouter } from 'react-router-dom'; -// Mock Socket.io const mockSocket = { id: 'mock-id', on: vi.fn(), @@ -14,57 +14,182 @@ const mockSocket = { disconnect: vi.fn(), }; -vi.mock('socket.io-client', () => ({ - default: () => mockSocket -})); +vi.mock('socket.io-client', () => ({ default: () => mockSocket })); +vi.mock('use-sound', () => ({ default: () => [vi.fn()] })); +vi.mock('canvas-confetti', () => ({ default: vi.fn() })); +vi.mock('sweetalert2', () => ({ default: { fire: vi.fn().mockResolvedValue({ isConfirmed: true }) } })); + +const Wrapper = ({ children }) => ( + + + {children} + + +); + +const findEventCb = (event) => { + const call = mockSocket.on.mock.calls.find((c) => c[0] === event); + return call?.[1]; +}; describe('Bingo', () => { beforeEach(() => { vi.clearAllMocks(); + localStorage.clear(); + sessionStorage.clear(); + }); + + describe('Board Rendering', () => { + it('shows Create Room and Join Room buttons in waiting state', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText('Create Room')).toBeTruthy(); + expect(screen.getByText('Join Room')).toBeTruthy(); + }); + + it('renders 25 number cells when playing', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('bingo_roomInfo'); + await act(async () => { + cb({ + id: 'BINGO1', + creator: 'mock-id', + players: [ + { id: 'mock-id', name: 'Alice', connected: true }, + { id: 'bob-id', name: 'Bob', connected: true }, + ], + gameState: 'playing', + currentTurn: 'mock-id', + turnOrder: ['mock-id', 'bob-id'], + }); + }); + + const buttons = screen.getAllByRole('button'); + const numberCells = buttons.filter((b) => { + const n = parseInt(b.textContent); + return n >= 1 && n <= 25; + }); + expect(numberCells.length).toBe(25); + }); + + it('shows BINGO progress display', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('bingo_roomInfo'); + await act(async () => { + cb({ + id: 'BINGO1', + creator: 'mock-id', + players: [ + { id: 'mock-id', name: 'Alice', connected: true }, + { id: 'bob-id', name: 'Bob', connected: true }, + ], + gameState: 'playing', + currentTurn: 'mock-id', + turnOrder: ['mock-id', 'bob-id'], + }); + }); + + for (const letter of 'BINGO') { + expect(screen.getByText(letter)).toBeTruthy(); + } + }); }); - it('emits markNumber when a cell is clicked', async () => { - render( - - - - - - ); - - // Simulate being in a game and it being our turn - const roomInfoCall = mockSocket.on.mock.calls.find(call => call[0] === 'bingo_roomInfo'); - if (!roomInfoCall) throw new Error('bingo_roomInfo listener not registered'); - - const roomInfoCallback = roomInfoCall[1]; - - await act(async () => { - roomInfoCallback({ - id: '123456', - creator: 'mock-id', - players: [{ id: 'mock-id', name: 'Alice' }, { id: 'bob-id', name: 'Bob' }], - gameState: 'playing', - currentTurn: 'mock-id', - turnOrder: ['mock-id', 'bob-id'] + describe('Mark Numbers', () => { + it('emits bingo_markNumber when a cell is clicked on my turn', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('bingo_roomInfo'); + await act(async () => { + cb({ + id: 'BINGO1', + creator: 'mock-id', + players: [ + { id: 'mock-id', name: 'Alice', connected: true }, + { id: 'bob-id', name: 'Bob', connected: true }, + ], + gameState: 'playing', + currentTurn: 'mock-id', + turnOrder: ['mock-id', 'bob-id'], + }); + }); + + const buttons = screen.getAllByRole('button'); + const numberCell = buttons.find((b) => { + const n = parseInt(b.textContent); + return n >= 1 && n <= 25; + }); + expect(numberCell).toBeDefined(); + const number = parseInt(numberCell.textContent); + + await act(async () => { + fireEvent.click(numberCell); }); + + expect(mockSocket.emit).toHaveBeenCalledWith('bingo_markNumber', expect.objectContaining({ number })); }); - // Our Bingo cells are buttons. - // There are 25 cells + navigation buttons. - const cells = screen.getAllByRole('button'); - - // Find a cell with a number (not navigation) - const gameCell = cells.find(c => !isNaN(parseInt(c.textContent))); - if (!gameCell) throw new Error('Bingo cell not found'); + it('does not emit when it is not my turn', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('bingo_roomInfo'); + await act(async () => { + cb({ + id: 'BINGO1', + creator: 'other-id', + players: [ + { id: 'mock-id', name: 'Alice', connected: true }, + { id: 'bob-id', name: 'Bob', connected: true }, + ], + gameState: 'playing', + currentTurn: 'bob-id', + turnOrder: ['mock-id', 'bob-id'], + }); + }); - const number = parseInt(gameCell.textContent); + const buttons = screen.getAllByRole('button'); + const numberCell = buttons.find((b) => { + const n = parseInt(b.textContent); + return n >= 1 && n <= 25; + }); - await act(async () => { - fireEvent.click(gameCell); + await act(async () => { + fireEvent.click(numberCell); + }); + + expect(mockSocket.emit).not.toHaveBeenCalledWith('bingo_markNumber', expect.any(Object)); }); - expect(mockSocket.emit).toHaveBeenCalledWith('bingo_markNumber', expect.objectContaining({ - number: number - })); + it('shows striked cells as stars after bingo_numberMarked', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('bingo_roomInfo'); + await act(async () => { + cb({ + id: 'BINGO1', + creator: 'mock-id', + players: [ + { id: 'mock-id', name: 'Alice', connected: true }, + { id: 'bob-id', name: 'Bob', connected: true }, + ], + gameState: 'playing', + currentTurn: 'mock-id', + turnOrder: ['mock-id', 'bob-id'], + }); + }); + + const numberMarkedCb = findEventCb('bingo_numberMarked'); + await act(async () => { + numberMarkedCb({ + number: 5, + nextTurn: 'bob-id', + strikedNumbers: [5], + }); + }); + + const stars = screen.getAllByText('★'); + expect(stars.length).toBeGreaterThanOrEqual(1); + }); }); }); diff --git a/pro/src/components/ErrorBoundary.jsx b/pro/src/components/ErrorBoundary.jsx index 640c0a0..70e245f 100644 --- a/pro/src/components/ErrorBoundary.jsx +++ b/pro/src/components/ErrorBoundary.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Typography, Button } from '@mui/material'; +import { reportRuntimeError } from '../utils/runtimeError'; class ErrorBoundary extends React.Component { constructor(props) { @@ -7,16 +7,13 @@ class ErrorBoundary extends React.Component { this.state = { hasError: false, error: null, errorInfo: null }; } - static getDerivedStateFromError(error) { + static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error, errorInfo) { - this.setState({ - error: error, - errorInfo: errorInfo - }); - // You can also log the error to an error reporting service here + this.setState({ error, errorInfo }); + reportRuntimeError('React error boundary', error); console.error('Error caught by ErrorBoundary:', error, errorInfo); } @@ -27,49 +24,24 @@ class ErrorBoundary extends React.Component { render() { if (this.state.hasError) { return ( - - - Oops! Something went wrong - - - We're sorry for the inconvenience. Please try refreshing the page. - - - {process.env.NODE_ENV === 'development' && ( - - - Error Details: - -
+          
+          {import.meta.env.DEV && (
+            
+

Error Details:

+
                 {this.state.error && this.state.error.toString()}
                 {this.state.errorInfo && this.state.errorInfo.componentStack}
               
- +
)} - +
); } @@ -77,4 +49,4 @@ class ErrorBoundary extends React.Component { } } -export default ErrorBoundary; \ No newline at end of file +export default ErrorBoundary; diff --git a/pro/src/components/NotificationProvider.jsx b/pro/src/components/NotificationProvider.jsx new file mode 100644 index 0000000..0b09121 --- /dev/null +++ b/pro/src/components/NotificationProvider.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { Toaster } from 'sonner'; +import { useTheme } from '../context/ThemeContext'; + +export default function NotificationProvider() { + const { theme } = useTheme(); + + return ( + + ); +} diff --git a/pro/src/components/PageTransition.jsx b/pro/src/components/PageTransition.jsx new file mode 100644 index 0000000..4df639c --- /dev/null +++ b/pro/src/components/PageTransition.jsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { motion } from 'framer-motion'; + +const pageVariants = { + initial: { + opacity: 0, + y: 20, + }, + animate: { + opacity: 1, + y: 0, + transition: { + duration: 0.4, + ease: 'easeOut', + }, + }, + exit: { + opacity: 0, + y: -20, + transition: { + duration: 0.3, + ease: 'easeIn', + }, + }, +}; + +export default function PageTransition({ children }) { + return ( + + {children} + + ); +} diff --git a/pro/src/components/PaperPartyLanding.jsx b/pro/src/components/PaperPartyLanding.jsx index 1da9aa6..cff6d50 100644 --- a/pro/src/components/PaperPartyLanding.jsx +++ b/pro/src/components/PaperPartyLanding.jsx @@ -1,21 +1,137 @@ import React, { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useGameContext } from '../context/GameContext'; -import RetroButton from './ui/RetroButton'; import Swal from 'sweetalert2'; -import { Dices, Hash, User, Grid3X3, Square } from 'lucide-react'; - -const GameCard = ({ title, description, onClick, icon: Icon }) => ( -
-
-
- +import { User, BookOpen, PenTool, Share2, Zap, Circle } from 'lucide-react'; + +const BingoIcon = () => ( + + + + B + + +); + +const TicTacToeIcon = () => ( + + + + + + + X + + + O + + +); + +const UTTTIcon = () => ( + + + + + + + X + + + O + + +); + +const DotsAndBoxesIcon = () => ( + + + + + + + + + + + + + + + + +); + +const SOSIcon = () => ( + + + + S + + + O + + + S + + +); + +const Connect4Icon = () => ( + + + + + + + + + +); + +const GameCard = ({ title, description, onClick, icon: Icon, accentColor, badge }) => ( +
+
+
+
+
+ +
+
+
+

{title}

+ {badge && ( + + {badge} + + )} +
+

{description}

+
+
+
+ + Click to play + + + +
-

{title}

-

{description}

); @@ -31,68 +147,124 @@ const PaperPartyLanding = () => { input: 'text', inputPlaceholder: 'Enter your name...', allowOutsideClick: false, - confirmButtonText: 'Let\'s Play!', + confirmButtonText: "Let's Play!", customClass: { popup: 'glass rounded-3xl paper-font', title: 'hand-drawn text-3xl', - confirmButton: 'bg-blue-500/80 hover:bg-blue-500 px-8 py-3 rounded-xl font-bold transition-all' + confirmButton: 'bg-blue-500/80 hover:bg-blue-500 px-8 py-3 rounded-xl font-bold transition-all', }, buttonsStyling: false, inputValidator: (value) => { - if (!value) return 'We need a name to start the party!'; - } + if (!value || !value.trim()) return 'We need a name to start the party!'; + }, }).then((result) => { if (result.isConfirmed) { - setPlayerName(result.value); + setPlayerName(result.value.trim()); } }); } }, [playerName, setPlayerName]); return ( -
-
-

+
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+ +
+

PaperParty

-

- Multiplayer games that feel like the back of your notebook. -

+
+ +

+ Multiplayer games that feel like the back of your notebook. +

+
+
+ {[...Array(5)].map((_, i) => ( +
+ ))} +
-
- + navigate('/bingo')} /> - navigate('/tictactoe')} /> - navigate('/uttt')} /> - navigate('/dab')} /> + navigate('/sos')} + /> + navigate('/connect4')} + />
{playerName && ( -
- - Playing as {playerName} +
+
+ +
+ Playing as + {playerName}
)} + +
+ + + +
); }; diff --git a/pro/src/components/PaperPartyLanding.test.jsx b/pro/src/components/PaperPartyLanding.test.jsx index 1fc454c..4f90e71 100644 --- a/pro/src/components/PaperPartyLanding.test.jsx +++ b/pro/src/components/PaperPartyLanding.test.jsx @@ -1,6 +1,6 @@ import React from 'react'; -import { render, screen, fireEvent } from '@testing-library/react'; -import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import { describe, it, expect, vi } from 'vitest'; import PaperPartyLanding from './PaperPartyLanding'; import { GameProvider } from '../context/GameContext'; import { BrowserRouter } from 'react-router-dom'; @@ -8,8 +8,8 @@ import { BrowserRouter } from 'react-router-dom'; // Mock SweetAlert2 vi.mock('sweetalert2', () => ({ default: { - fire: vi.fn().mockResolvedValue({ isConfirmed: true, value: 'Alice' }) - } + fire: vi.fn().mockResolvedValue({ isConfirmed: true, value: 'Alice' }), + }, })); describe('PaperPartyLanding', () => { @@ -19,7 +19,7 @@ describe('PaperPartyLanding', () => { - + , ); expect(screen.getByText('Bingo')).toBeDefined(); diff --git a/pro/src/components/RuntimeErrorProvider.jsx b/pro/src/components/RuntimeErrorProvider.jsx new file mode 100644 index 0000000..ad1783f --- /dev/null +++ b/pro/src/components/RuntimeErrorProvider.jsx @@ -0,0 +1,24 @@ +import { useEffect } from 'react'; +import { reportRuntimeError } from '../utils/runtimeError'; + +export default function RuntimeErrorProvider({ children }) { + useEffect(() => { + const handleWindowError = (event) => { + reportRuntimeError('Window error', event.error || event.message || 'Unknown browser error'); + }; + + const handleUnhandledRejection = (event) => { + reportRuntimeError('Unhandled promise rejection', event.reason || 'Unknown promise rejection'); + }; + + window.addEventListener('error', handleWindowError); + window.addEventListener('unhandledrejection', handleUnhandledRejection); + + return () => { + window.removeEventListener('error', handleWindowError); + window.removeEventListener('unhandledrejection', handleUnhandledRejection); + }; + }, []); + + return children; +} diff --git a/pro/src/components/ui/AvatarReactionBar.jsx b/pro/src/components/ui/AvatarReactionBar.jsx new file mode 100644 index 0000000..d101c90 --- /dev/null +++ b/pro/src/components/ui/AvatarReactionBar.jsx @@ -0,0 +1,101 @@ +import React, { useState, useEffect } from 'react'; +import { ThumbsUp, Sparkles, Flame, Heart, Zap, PartyPopper } from 'lucide-react'; +import { PlayerAvatar } from './AvatarSelector'; + +const REACTION_ICONS = [ + { id: 'thumbsup', Icon: ThumbsUp, label: 'Like' }, + { id: 'sparkles', Icon: Sparkles, label: 'Nice' }, + { id: 'flame', Icon: Flame, label: 'Fire' }, + { id: 'heart', Icon: Heart, label: 'Love' }, + { id: 'zap', Icon: Zap, label: 'Wow' }, + { id: 'party', Icon: PartyPopper, label: 'Party' }, +]; + +const AvatarReactionBar = ({ socket, roomId, gamePrefix, players }) => { + const [visible, setVisible] = useState(false); + const [recentReactions, setRecentReactions] = useState([]); + const [myProfile, setMyProfile] = useState(null); + + useEffect(() => { + const saved = localStorage.getItem('playerProfile'); + if (saved) { + setMyProfile(JSON.parse(saved)); + } + }, []); + + useEffect(() => { + if (!socket) return; + + const handler = (data) => { + const player = players.find((p) => p.id === data.playerId); + setRecentReactions((prev) => [ + ...prev, + { ...data, playerName: player?.name || 'Someone', avatarIcon: player?.avatarIcon, color: player?.color }, + ]); + }; + + socket.on(`${gamePrefix}_reaction`, handler); + return () => socket.off(`${gamePrefix}_reaction`, handler); + }, [socket, gamePrefix, players]); + + useEffect(() => { + if (recentReactions.length === 0) return; + + const timer = setTimeout(() => { + setRecentReactions((prev) => prev.slice(1)); + }, 3000); + + return () => clearTimeout(timer); + }, [recentReactions]); + + const handleReaction = (reactionId) => { + if (!socket || !roomId) return; + socket.emit('game_reaction', { roomId, reaction: reactionId, gamePrefix }); + }; + + return ( +
setVisible(true)} + onMouseLeave={() => setVisible(false)} + onTouchStart={() => setVisible(true)} + > +
+ {REACTION_ICONS.map((r) => ( + + ))} +
+ + {/* Recent reactions popups */} +
+ {recentReactions.map((r, i) => { + const ReactionIcon = REACTION_ICONS.find((icon) => icon.id === r.reaction)?.Icon; + return ( +
+
+ {r.avatarIcon && r.color ? : null} + {r.playerName} + {ReactionIcon && } +
+
+ ); + })} +
+
+ ); +}; + +export default AvatarReactionBar; diff --git a/pro/src/components/ui/AvatarSelector.jsx b/pro/src/components/ui/AvatarSelector.jsx new file mode 100644 index 0000000..ed4971f --- /dev/null +++ b/pro/src/components/ui/AvatarSelector.jsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { Cat, Dog, Bird, Fish, PawPrint, Mouse, Rabbit, Turtle, Squirrel } from 'lucide-react'; + +const AVATAR_ICON_MAP = { + cat: Cat, + dog: Dog, + bird: Bird, + fish: Fish, + monkey: Mouse, + panda: PawPrint, + frog: Rabbit, + tiger: Squirrel, + lion: Cat, + bear: Dog, + koala: Fish, + fox: Turtle, +}; + +const AVATAR_IDS = Object.keys(AVATAR_ICON_MAP); + +const COLORS = ['#2a2a3e', '#c73e1d', '#2d4a8f', '#2f5233', '#7b2d8f', '#b5651d']; + +const AvatarSelector = ({ avatarIcon, color, onAvatarChange, onColorChange }) => { + return ( +
+
+ {AVATAR_IDS.map((id) => { + const Icon = AVATAR_ICON_MAP[id]; + return ( + + ); + })} +
+
+ {COLORS.map((c) => ( +
+
+ ); +}; + +export default AvatarSelector; + +export const PlayerAvatar = ({ avatarIcon, color, size = 20 }) => { + const Icon = AVATAR_ICON_MAP[avatarIcon] || Cat; + + return ( +
+ +
+ ); +}; diff --git a/pro/src/components/ui/AvatarSelector.test.jsx b/pro/src/components/ui/AvatarSelector.test.jsx new file mode 100644 index 0000000..b8c52df --- /dev/null +++ b/pro/src/components/ui/AvatarSelector.test.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { describe, it, expect, vi } from 'vitest'; +import AvatarSelector from './AvatarSelector'; +import { render, screen, fireEvent } from '@testing-library/react'; + +vi.mock('lucide-react', () => ({ + Cat: () => 🐱, + Dog: () => 🐶, + Bird: () => 🐦, + Fish: () => 🐟, + Mouse: () => 🐵, + PawPrint: () => 🐼, + Rabbit: () => 🐸, + Turtle: () => 🐯, + Squirrel: () => 🐯, +})); + +describe('AvatarSelector', () => { + it('renders all 12 avatar icon options', () => { + render(); + const avatarButtons = screen.getAllByRole('button'); + expect(avatarButtons.length).toBeGreaterThanOrEqual(12); + }); + + it('calls onAvatarChange with clicked avatar id', () => { + const onAvatarChange = vi.fn(); + render(); + const avatarButtons = screen.getAllByRole('button').slice(0, 12); + fireEvent.click(avatarButtons[1]); + expect(onAvatarChange).toHaveBeenCalledWith('dog'); + }); + + it('calls onColorChange with clicked color', () => { + const onColorChange = vi.fn(); + render(); + const colorButtons = screen.getAllByRole('button').slice(12); + fireEvent.click(colorButtons[1]); + expect(onColorChange).toHaveBeenCalled(); + }); + + it('highlights the selected avatar', () => { + render(); + const avatarButtons = screen.getAllByRole('button'); + const frogButton = avatarButtons.find((b) => b.className.includes('border-ink')); + expect(frogButton).toBeTruthy(); + }); +}); diff --git a/pro/src/components/ui/AvatarSelectorNew.jsx b/pro/src/components/ui/AvatarSelectorNew.jsx new file mode 100644 index 0000000..84712fc --- /dev/null +++ b/pro/src/components/ui/AvatarSelectorNew.jsx @@ -0,0 +1,148 @@ +import React, { useState } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { ChevronLeft, ChevronRight, RotateCw } from 'lucide-react'; +import { useAvatarStore, AVATAR_STYLES, AVATAR_COLORS } from '../../store/avatarStore'; + +export default function AvatarSelector() { + const { avatar, setAvatar, generateNewAvatar, getAvatarUrl } = useAvatarStore(); + const [showStylePicker, setShowStylePicker] = useState(false); + + const containerVariants = { + hidden: { opacity: 0, scale: 0.95 }, + visible: { + opacity: 1, + scale: 1, + transition: { duration: 0.3, ease: 'easeOut' }, + }, + exit: { opacity: 0, scale: 0.95, transition: { duration: 0.2 } }, + }; + + const avatarVariants = { + hidden: { opacity: 0, scale: 0.8 }, + visible: { + opacity: 1, + scale: 1, + transition: { duration: 0.4, ease: 'easeOut' }, + }, + }; + + const colorGridVariants = { + hidden: { opacity: 0, height: 0 }, + visible: { + opacity: 1, + height: 'auto', + transition: { duration: 0.3, ease: 'easeOut' }, + }, + exit: { opacity: 0, height: 0, transition: { duration: 0.2 } }, + }; + + const colorItemVariants = { + hidden: { opacity: 0, scale: 0.6 }, + visible: (i) => ({ + opacity: 1, + scale: 1, + transition: { delay: i * 0.05, duration: 0.3, ease: 'easeOut' }, + }), + hover: { scale: 1.1, transition: { duration: 0.2 } }, + }; + + const currentStyleIndex = AVATAR_STYLES.indexOf(avatar.style); + const prevStyle = AVATAR_STYLES[(currentStyleIndex - 1 + AVATAR_STYLES.length) % AVATAR_STYLES.length]; + const nextStyle = AVATAR_STYLES[(currentStyleIndex + 1) % AVATAR_STYLES.length]; + + return ( + + {/* Avatar Display */} + +
+ Your Avatar +
+ + + +
+ + {/* Avatar Style Navigation */} +
+ setAvatar(prevStyle, undefined, avatar.backgroundColor)} + className="sketch-button p-2" + title="Previous style" + > + + + +
+

Style

+

{avatar.style.replace(/-/g, ' ')}

+
+ + setAvatar(nextStyle, undefined, avatar.backgroundColor)} + className="sketch-button p-2" + title="Next style" + > + + +
+ + {/* Color Picker Toggle */} + setShowStylePicker(!showStylePicker)} + className="sketch-button w-full font-sketch" + > + {showStylePicker ? 'Hide' : 'Show'} Colors + + + {/* Color Grid */} + + {showStylePicker && ( + +
+ {AVATAR_COLORS.map((color, i) => ( + setAvatar(avatar.style, undefined, color)} + className={`w-full aspect-square rounded-lg transition-all ${ + avatar.backgroundColor === color ? 'ring-4 ring-ink/50' : 'ring-1 ring-ink/10' + }`} + style={{ backgroundColor: color }} + title={`Select color ${color}`} + /> + ))} +
+
+ )} +
+ + {/* Info Text */} +

+ Your avatar is saved automatically. Choose a style and color you like! +

+
+ ); +} diff --git a/pro/src/components/ui/CountdownOverlay.jsx b/pro/src/components/ui/CountdownOverlay.jsx new file mode 100644 index 0000000..5771d1c --- /dev/null +++ b/pro/src/components/ui/CountdownOverlay.jsx @@ -0,0 +1,37 @@ +import React, { useState, useEffect, useRef } from 'react'; + +const CountdownOverlay = ({ onComplete }) => { + const [count, setCount] = useState(3); + const mountedRef = useRef(true); + + useEffect(() => { + return () => { + mountedRef.current = false; + }; + }, []); + + useEffect(() => { + if (count === 0) { + if (mountedRef.current) onComplete?.(); + return; + } + const t = setTimeout(() => setCount((c) => c - 1), 1000); + return () => clearTimeout(t); + }, [count, onComplete]); + + if (count === 0) return null; + + return ( +
+ + {count} + +
+ ); +}; + +export default CountdownOverlay; diff --git a/pro/src/components/ui/CountdownOverlay.test.jsx b/pro/src/components/ui/CountdownOverlay.test.jsx new file mode 100644 index 0000000..98feec9 --- /dev/null +++ b/pro/src/components/ui/CountdownOverlay.test.jsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { render, screen, act } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import CountdownOverlay from './CountdownOverlay'; + +describe('CountdownOverlay', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + afterEach(() => { + vi.useRealTimers(); + }); + + it('starts at 3', () => { + render(); + expect(screen.getByText('3')).toBeTruthy(); + }); + + it('counts down to 2 after 1 second', () => { + render(); + act(() => { + vi.advanceTimersByTime(1000); + }); + expect(screen.getByText('2')).toBeTruthy(); + }); + + it('counts down to 1 after 2 seconds', () => { + render(); + act(() => { + vi.advanceTimersByTime(1000); + }); + act(() => { + vi.advanceTimersByTime(1000); + }); + expect(screen.getByText('1')).toBeTruthy(); + }); + + it('calls onComplete and renders nothing after 3 ticks', () => { + const onComplete = vi.fn(); + const { container } = render(); + act(() => { + vi.advanceTimersByTime(1000); + }); + act(() => { + vi.advanceTimersByTime(1000); + }); + act(() => { + vi.advanceTimersByTime(1000); + }); + expect(onComplete).toHaveBeenCalledTimes(1); + expect(container.firstChild).toBeNull(); + }); +}); diff --git a/pro/src/components/ui/GameLayout.jsx b/pro/src/components/ui/GameLayout.jsx new file mode 100644 index 0000000..87ff03f --- /dev/null +++ b/pro/src/components/ui/GameLayout.jsx @@ -0,0 +1,81 @@ +import React, { useState } from 'react'; +import { ArrowLeft } from 'lucide-react'; +import Swal from 'sweetalert2'; +import { useNavigate } from 'react-router-dom'; +import { sketchPopupClass } from './SketchPopup'; +import { useGameContext } from '../../context/GameContext'; +import ThemeToggle from './ThemeToggle'; + +const GameLayout = ({ players = [], children }) => { + const navigate = useNavigate(); + const { socket, roomId, clearRoomId, gamePrefix } = useGameContext(); + const [copiedLabel, setCopiedLabel] = useState(''); + + const handleLeave = async () => { + const result = await Swal.fire({ + title: 'Leave Game?', + text: 'Your progress will be lost.', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Leave', + cancelButtonText: 'Stay', + customClass: { popup: sketchPopupClass }, + }); + if (!result.isConfirmed) return; + if (gamePrefix && roomId) { + socket?.emit(`${gamePrefix}_leaveRoom`, roomId); + } + clearRoomId(roomId); + navigate('/'); + }; + + const handleCopyRoomId = async () => { + try { + await navigator.clipboard.writeText(roomId); + setCopiedLabel('Copied!'); + setTimeout(() => setCopiedLabel(''), 1500); + } catch { + setCopiedLabel('Copy failed'); + setTimeout(() => setCopiedLabel(''), 1500); + } + }; + + return ( +
+ {/* Info Zone */} + + + {/* Canvas Zone */} +
{children}
+
+ ); +}; + +export default GameLayout; diff --git a/pro/src/components/ui/GameLayout.test.jsx b/pro/src/components/ui/GameLayout.test.jsx new file mode 100644 index 0000000..0db8238 --- /dev/null +++ b/pro/src/components/ui/GameLayout.test.jsx @@ -0,0 +1,111 @@ +import React from 'react'; +import { render, screen, fireEvent, act } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import GameLayout from './GameLayout'; +import { GameContext } from '../../context/GameContext'; +import { ThemeProvider } from '../../context/ThemeContext'; +import { BrowserRouter } from 'react-router-dom'; + +vi.mock('sweetalert2', () => ({ + default: { + fire: vi.fn().mockResolvedValue({ isConfirmed: true }), + }, +})); + +const mockSocket = { emit: vi.fn(), on: vi.fn(), off: vi.fn(), disconnect: vi.fn() }; +const mockNavigate = vi.fn(); +const mockClearRoomId = vi.fn(); + +vi.mock('react-router-dom', async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, useNavigate: () => mockNavigate }; +}); + +const baseContextValue = { + socket: mockSocket, + roomId: 'ABC123', + gamePrefix: 'ttt', + clearRoomId: mockClearRoomId, + setRoomId: vi.fn(), + setGamePrefix: vi.fn(), + leaveRoom: vi.fn(), + clearReconnect: vi.fn(), + playerName: 'Test', + profile: { name: 'Test', avatarIcon: 'cat', color: '#2a2a3e' }, + setPlayerName: vi.fn(), + setProfile: vi.fn(), +}; + +const renderLayout = (overrides = {}) => + render( + + + + +
Board
+
+
+
+
, + ); + +describe('GameLayout', () => { + beforeEach(() => vi.clearAllMocks()); + + it('renders children in the canvas zone', () => { + renderLayout(); + expect(screen.getByTestId('game-content')).toBeInTheDocument(); + }); + + it('displays the roomId badge', () => { + renderLayout(); + expect(screen.getByText('ABC123')).toBeInTheDocument(); + }); + + it('renders player avatars when players prop is provided', () => { + renderLayout(); + const { rerender } = render( + + + + +
Board
+
+
+
+
, + ); + expect(screen.getByText('Al')).toBeInTheDocument(); + expect(screen.getByText('Bo')).toBeInTheDocument(); + }); + + it('back button triggers leave confirmation', async () => { + const Swal = (await import('sweetalert2')).default; + renderLayout(); + const backBtn = screen.getByRole('button', { name: /back|leave/i }); + await act(async () => fireEvent.click(backBtn)); + expect(Swal.fire).toHaveBeenCalled(); + }); + + it('disconnects and navigates to / on confirmed leave', async () => { + renderLayout(); + const backBtn = screen.getByRole('button', { name: /back|leave/i }); + await act(async () => fireEvent.click(backBtn)); + expect(mockSocket.emit).toHaveBeenCalledWith('ttt_leaveRoom', 'ABC123'); + expect(mockClearRoomId).toHaveBeenCalled(); + expect(mockNavigate).toHaveBeenCalledWith('/'); + }); + + it('copies roomId to clipboard when badge is clicked', async () => { + const writeText = vi.fn().mockResolvedValue(undefined); + Object.assign(navigator, { clipboard: { writeText } }); + renderLayout(); + await act(async () => fireEvent.click(screen.getByText('ABC123'))); + expect(writeText).toHaveBeenCalledWith('ABC123'); + }); +}); diff --git a/pro/src/components/ui/GameLobby.jsx b/pro/src/components/ui/GameLobby.jsx new file mode 100644 index 0000000..6ddc0ae --- /dev/null +++ b/pro/src/components/ui/GameLobby.jsx @@ -0,0 +1,209 @@ +import React, { useState, useEffect, useRef } from 'react'; +import SketchButton from './SketchButton'; +import AvatarSelector from './AvatarSelector'; +import CountdownOverlay from './CountdownOverlay'; + +const GameLobby = ({ + gameName = 'Game', + roomId, + players = [], + spectators = [], + isHost, + minPlayers = 2, + canStart, + onStart, + onLeave, + onJoinSubmit, + showJoinInput = false, + customizationSlot, + startLabel = 'Start Game', + waitingLabel = 'Waiting for players…', + showCountdown = false, + onCountdownComplete, + profile = { name: '', avatarIcon: 'cat', color: '#2a2a3e' }, + onProfileChange, +}) => { + const [dots, setDots] = useState(''); + const [shareSupported] = useState(() => !!navigator.share); + const [copied, setCopied] = useState(false); + const joinInputRef = useRef(null); + + const actuallyCanStart = canStart ?? players.length >= minPlayers; + + useEffect(() => { + if (players.length >= minPlayers) return; + const id = setInterval(() => { + setDots((d) => (d.length >= 3 ? '' : d + '.')); + }, 500); + return () => clearInterval(id); + }, [players.length, minPlayers]); + + const handleShare = async () => { + try { + await navigator.share({ + title: `Join my ${gameName} room!`, + text: `Use room code: ${roomId}`, + url: window.location.href, + }); + } catch { + // user cancelled or not supported + } + }; + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(roomId); + setCopied(true); + setTimeout(() => setCopied(false), 1500); + } catch { + // fallback or error + } + }; + + const handleProfileChange = (field, value) => { + if (onProfileChange) { + onProfileChange({ ...profile, [field]: value }); + } + }; + + return ( +
+ {showCountdown && } + +
+

{gameName}

+ +
+

Room Code

+

{roomId}

+ + {copied ? '✓ Copied!' : '📋 Copy Room Code'} + +
+ + {customizationSlot &&
{customizationSlot}
} + +
+

Player Name (optional)

+ handleProfileChange('name', e.target.value)} + placeholder="Enter your name" + className="w-full px-3 py-2 border border-ink/30 rounded sketch-font text-ink bg-white/80" + /> +
+ + handleProfileChange('avatarIcon', icon)} + onColorChange={(color) => handleProfileChange('color', color)} + /> + +
+ {actuallyCanStart ? ( + ✅ Ready to start! + ) : ( + + {waitingLabel || 'Waiting for players'} + {dots} + + )} +
+ +
+

+ Players ({players.length}/{minPlayers} min) +

+ {players.map((p, i) => ( +
+ {p.connected !== false ? '☑️' : '☐'} + {p.name} + {i === 0 && host} +
+ ))} + {Array.from({ length: Math.max(0, minPlayers - players.length) }).map((_, i) => ( +
+ ☐ + Waiting... +
+ ))} +
+ + {spectators.length > 0 && ( +
+

Spectators ({spectators.length})

+ {spectators.map((s, i) => ( +
+ 👁️ + {s.name} +
+ ))} +
+ )} + + {showJoinInput && onJoinSubmit && ( +
+

Join Existing Room

+
+ + { + if (joinInputRef.current?.value) onJoinSubmit(joinInputRef.current.value.trim().toUpperCase()); + }} + className="text-sm" + > + Join + +
+
+ )} + +
+ {shareSupported && ( + + 📤 Invite Friends + + )} + + {showJoinInput &&

Enter room ID above to join

} + + {isHost && onStart && ( + + {actuallyCanStart ? `🚀 ${startLabel}` : `Need ${minPlayers - players.length} more player(s)`} + + )} + + {!isHost && onStart && ( +

Waiting for host to start…

+ )} + + + Leave Room + +
+
+
+ ); +}; + +export default GameLobby; diff --git a/pro/src/components/ui/LeaveButton.jsx b/pro/src/components/ui/LeaveButton.jsx new file mode 100644 index 0000000..08a1ee3 --- /dev/null +++ b/pro/src/components/ui/LeaveButton.jsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { ArrowLeft } from 'lucide-react'; +import Swal from 'sweetalert2'; +import { sketchPopupClass } from './SketchPopup'; + +const LeaveButton = ({ onLeave, className = '' }) => { + const handleClick = async () => { + const result = await Swal.fire({ + title: 'Leave Game?', + text: 'Are you sure you want to leave?', + showCancelButton: true, + confirmButtonText: 'Yes, Leave', + cancelButtonText: 'Stay', + customClass: { popup: sketchPopupClass }, + }); + if (result.isConfirmed) { + onLeave(); + } + }; + + return ( + + ); +}; + +export default LeaveButton; diff --git a/pro/src/components/ui/LeaveButton.test.jsx b/pro/src/components/ui/LeaveButton.test.jsx new file mode 100644 index 0000000..b06c1c0 --- /dev/null +++ b/pro/src/components/ui/LeaveButton.test.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import LeaveButton from './LeaveButton'; + +vi.mock('sweetalert2', () => ({ + default: { fire: vi.fn().mockResolvedValue({ isConfirmed: true }) }, +})); + +describe('LeaveButton', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('renders a button', () => { + render(); + expect(screen.getByRole('button')).toBeTruthy(); + }); + + it('calls onLeave when confirmed', async () => { + const onLeave = vi.fn(); + render(); + await fireEvent.click(screen.getByRole('button')); + await vi.waitFor(() => expect(onLeave).toHaveBeenCalledTimes(1)); + }); + + it('does not call onLeave when cancelled', async () => { + const Swal = (await import('sweetalert2')).default; + Swal.fire.mockResolvedValueOnce({ isConfirmed: false }); + const onLeave = vi.fn(); + render(); + await fireEvent.click(screen.getByRole('button')); + await vi.waitFor(() => expect(Swal.fire).toHaveBeenCalled()); + expect(onLeave).not.toHaveBeenCalled(); + }); +}); diff --git a/pro/src/components/ui/MatchReport.jsx b/pro/src/components/ui/MatchReport.jsx new file mode 100644 index 0000000..bb07053 --- /dev/null +++ b/pro/src/components/ui/MatchReport.jsx @@ -0,0 +1,156 @@ +import React from 'react'; +import { Trophy, Frown, Award, Users } from 'lucide-react'; +import SketchButton from './SketchButton'; +import SketchCard from './SketchCard'; + +const normalizeScores = (scores, players = []) => { + if (!scores) return []; + if (Array.isArray(scores)) { + return scores.map((score, idx) => { + const raw = score; + let value = typeof raw === 'number' ? raw : (raw?.value ?? raw?.score ?? 0); + const name = (typeof raw === 'object' && raw?.name) || players[idx]?.name || `Player ${idx + 1}`; + return { name, score: value }; + }); + } + return Object.entries(scores).map(([name, value], idx) => ({ + name, + score: typeof value === 'number' ? value : (value?.value ?? 0), + ...(players[idx] ? { profileName: players[idx].name } : {}), + })); +}; + +const MatchReport = ({ winner, isWinner, stats = {}, scores, onRematch, onNewRoom, players = [] }) => { + const scoreList = normalizeScores(scores, players); + + const getScoreDisplay = () => { + if (!scoreList.length) return null; + + if (scoreList.length === 2) { + const [p1, p2] = scoreList; + return ( +
+
+ {p1.name} + p2.score ? 'text-yellow-600' : ''}`}>{p1.score} +
+ +
+ {p2.name} + p1.score ? 'text-yellow-600' : ''}`}>{p2.score} +
+
+ ); + } + + return ( +
+
+ + Standings +
+
+ {scoreList.map((entry, idx) => { + const maxScore = Math.max(...scoreList.map((item) => item.score)); + const isTop = scoreList.length > 1 && entry.score === maxScore; + return ( +
+ {entry.name} + {entry.score} +
+ ); + })} +
+
+ ); + }; + + const getWinnerDisplay = () => { + if (!winner && !isWinner && scoreList.length > 1) { + const topScore = Math.max(...scoreList.map((item) => item.score)); + const winners = scoreList.filter((item) => item.score === topScore); + if (winners.length > 1) { + return ( + <> +
+ +
+

It's a Tie!

+

{winners.map((w) => w.name).join(' & ')}

+ + ); + } + } + + if (scores && scoreList.length > 1) { + const topScore = Math.max(...scoreList.map((item) => item.score)); + const winnerEntry = scoreList.find((item) => item.score === topScore); + if (winnerEntry) { + const displayName = winnerEntry.profileName || winnerEntry.name; + return ( + <> +
+ +
+

{displayName} Wins!

+ + ); + } + } + + if (!winner && !isWinner) { + return ( + <> +
+ +
+

It's a Tie!

+ + ); + } + + if (isWinner) { + return ( + <> +
+ +
+

You Win!

+ + ); + } + + return ( + <> +
+ +
+

{winner} Wins!

+ + ); + }; + + return ( + + {getScoreDisplay()} + {getWinnerDisplay()} + {(stats.moves || stats.time) && ( +
+ {stats.moves &&
Moves: {stats.moves}
} + {stats.time &&
Time: {stats.time}
} +
+ )} +
+ {onRematch && Rematch} + {onNewRoom && New Room} +
+
+ ); +}; + +export default MatchReport; diff --git a/pro/src/components/ui/MatchReport.test.jsx b/pro/src/components/ui/MatchReport.test.jsx new file mode 100644 index 0000000..e6da6a3 --- /dev/null +++ b/pro/src/components/ui/MatchReport.test.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { describe, it, expect, vi } from 'vitest'; +import MatchReport from './MatchReport'; + +describe('MatchReport', () => { + it('shows "You Win!" when isWinner is true', () => { + render(); + expect(screen.getByText('You Win!')).toBeTruthy(); + }); + + it('shows winner name when isWinner is false', () => { + render(); + expect(screen.getByText('Bob Wins!')).toBeTruthy(); + }); + + it('shows stats when provided', () => { + render(); + expect(screen.getByText('Moves: 12')).toBeTruthy(); + expect(screen.getByText('Time: 1m 23s')).toBeTruthy(); + }); + + it('calls onRematch when Rematch is clicked', () => { + const onRematch = vi.fn(); + render(); + fireEvent.click(screen.getByText('Rematch')); + expect(onRematch).toHaveBeenCalledTimes(1); + }); + + it('calls onNewRoom when New Room is clicked', () => { + const onNewRoom = vi.fn(); + render(); + fireEvent.click(screen.getByText('New Room')); + expect(onNewRoom).toHaveBeenCalledTimes(1); + }); + + it('does not render Rematch button when onRematch is not provided', () => { + render(); + expect(screen.queryByText('Rematch')).toBeNull(); + }); +}); diff --git a/pro/src/components/ui/ModeSelector.jsx b/pro/src/components/ui/ModeSelector.jsx new file mode 100644 index 0000000..9cfd41c --- /dev/null +++ b/pro/src/components/ui/ModeSelector.jsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { SwatchBook } from 'lucide-react'; + +const ModeSelector = ({ mode, onModeChange, customRows, customCols, onRowsChange, onColsChange }) => { + return ( +
+
+ + Game Mode +
+
+ + +
+ {mode === 'custom' && ( +
+
+ + onRowsChange(Number(e.target.value))} + className="w-full" + /> +
+
+ + onColsChange(Number(e.target.value))} + className="w-full" + /> +
+
+ )} +
+ ); +}; + +export default ModeSelector; diff --git a/pro/src/components/ui/ModeSelector.test.jsx b/pro/src/components/ui/ModeSelector.test.jsx new file mode 100644 index 0000000..8184274 --- /dev/null +++ b/pro/src/components/ui/ModeSelector.test.jsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { describe, it, expect, vi } from 'vitest'; +import ModeSelector from './ModeSelector'; + +const defaults = { + mode: 'classic', + onModeChange: vi.fn(), + customRows: 5, + customCols: 5, + onRowsChange: vi.fn(), + onColsChange: vi.fn(), +}; + +describe('ModeSelector', () => { + it('renders Classic and Custom buttons', () => { + render(); + expect(screen.getByText('Classic (9×9)')).toBeTruthy(); + expect(screen.getByText('Custom Size')).toBeTruthy(); + }); + + it('calls onModeChange with "custom" when Custom is clicked', () => { + const onModeChange = vi.fn(); + render(); + fireEvent.click(screen.getByText('Custom Size')); + expect(onModeChange).toHaveBeenCalledWith('custom'); + }); + + it('calls onModeChange with "classic" when Classic is clicked', () => { + const onModeChange = vi.fn(); + render(); + fireEvent.click(screen.getByText('Classic (9×9)')); + expect(onModeChange).toHaveBeenCalledWith('classic'); + }); + + it('shows row/col sliders only in custom mode', () => { + render(); + expect(screen.getByText(/Rows:/)).toBeTruthy(); + expect(screen.getByText(/Columns:/)).toBeTruthy(); + }); + + it('does not show sliders in classic mode', () => { + render(); + expect(screen.queryByText(/Rows:/)).toBeNull(); + }); + + it('calls onRowsChange when row slider changes', () => { + const onRowsChange = vi.fn(); + render(); + const sliders = screen.getAllByRole('slider'); + fireEvent.change(sliders[0], { target: { value: '7' } }); + expect(onRowsChange).toHaveBeenCalledWith(7); + }); +}); diff --git a/pro/src/components/ui/PlayerAvatar.jsx b/pro/src/components/ui/PlayerAvatar.jsx new file mode 100644 index 0000000..35465fa --- /dev/null +++ b/pro/src/components/ui/PlayerAvatar.jsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { User, Smile, Star, Heart, Sun, Zap } from 'lucide-react'; + +const ICON_MAP = { + User, + Smile, + Star, + Heart, + Sun, + Zap, +}; + +const PlayerAvatar = ({ avatar, color, size = 20 }) => { + const IconComp = ICON_MAP[avatar] || User; + return ; +}; + +export default PlayerAvatar; diff --git a/pro/src/components/ui/PlayerBadge.jsx b/pro/src/components/ui/PlayerBadge.jsx new file mode 100644 index 0000000..78a6635 --- /dev/null +++ b/pro/src/components/ui/PlayerBadge.jsx @@ -0,0 +1,19 @@ +import React from 'react'; + +const PLAYER_COLORS = ['#1a1a2e', '#c73e1d', '#2d4a8f', '#2f5233']; + +const PlayerBadge = ({ player, index, isConnected }) => { + return ( +
+ {player.name} {!isConnected && '(disconnected)'} +
+ ); +}; + +export default PlayerBadge; diff --git a/pro/src/components/ui/PlayerBadge.test.jsx b/pro/src/components/ui/PlayerBadge.test.jsx new file mode 100644 index 0000000..775303b --- /dev/null +++ b/pro/src/components/ui/PlayerBadge.test.jsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { describe, it, expect } from 'vitest'; +import PlayerBadge from './PlayerBadge'; + +describe('PlayerBadge', () => { + it('renders player name', () => { + render(); + expect(screen.getByText(/Alice/)).toBeTruthy(); + }); + + it('shows disconnected label when isConnected is false', () => { + render(); + expect(screen.getByText(/disconnected/)).toBeTruthy(); + }); + + it('does not show disconnected label when connected', () => { + render(); + expect(screen.queryByText(/disconnected/)).toBeNull(); + }); + + it('applies reduced opacity when disconnected', () => { + const { container } = render(); + expect(container.firstChild.style.opacity).toBe('0.4'); + }); + + it('applies full opacity when connected', () => { + const { container } = render(); + expect(container.firstChild.style.opacity).toBe('1'); + }); +}); diff --git a/pro/src/components/ui/RetroButton.jsx b/pro/src/components/ui/RetroButton.jsx index 3639c55..27663ff 100644 --- a/pro/src/components/ui/RetroButton.jsx +++ b/pro/src/components/ui/RetroButton.jsx @@ -1,21 +1,18 @@ import React from 'react'; const RetroButton = ({ children, onClick, disabled, className = '', variant = 'primary' }) => { - const baseStyles = "px-6 py-2 rounded-lg font-bold transition-all duration-300 transform active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none glass"; - + const baseStyles = + 'px-6 py-2 rounded-lg font-bold transition-all duration-300 transform active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none glass'; + const variants = { - primary: "bg-blue-500/40 hover:bg-blue-500/60 text-blue-900 border-blue-400/50", - secondary: "bg-purple-500/40 hover:bg-purple-500/60 text-purple-900 border-purple-400/50", - success: "bg-green-500/40 hover:bg-green-500/60 text-green-900 border-green-400/50", - danger: "bg-red-500/40 hover:bg-red-500/60 text-red-900 border-red-400/50", + primary: 'bg-blue-500/40 hover:bg-blue-500/60 text-blue-900 border-blue-400/50', + secondary: 'bg-purple-500/40 hover:bg-purple-500/60 text-purple-900 border-purple-400/50', + success: 'bg-green-500/40 hover:bg-green-500/60 text-green-900 border-green-400/50', + danger: 'bg-red-500/40 hover:bg-red-500/60 text-red-900 border-red-400/50', }; return ( - ); diff --git a/pro/src/components/ui/RetroButton.test.jsx b/pro/src/components/ui/RetroButton.test.jsx index 79e06cb..c70c6ad 100644 --- a/pro/src/components/ui/RetroButton.test.jsx +++ b/pro/src/components/ui/RetroButton.test.jsx @@ -17,7 +17,11 @@ describe('RetroButton', () => { it('can be disabled', () => { const handleClick = vi.fn(); - render(Disabled); + render( + + Disabled + , + ); const button = screen.getByText('Disabled'); expect(button).toBeDisabled(); diff --git a/pro/src/components/ui/RoomActionButtons.jsx b/pro/src/components/ui/RoomActionButtons.jsx new file mode 100644 index 0000000..199bdf0 --- /dev/null +++ b/pro/src/components/ui/RoomActionButtons.jsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { SketchButton, SketchCard, AvatarSelector } from '.'; + +const RoomActionButtons = ({ onCreateRoom, onJoinRoom, profile, onProfileChange, children }) => { + const { name, avatarIcon, color } = profile; + + return ( +
+ + onProfileChange({ ...profile, avatarIcon: icon })} + onColorChange={(c) => onProfileChange({ ...profile, color: c })} + /> + + + +
+ onProfileChange({ ...profile, name: e.target.value })} + placeholder="Enter your name" + className="flex-1 sketch-border font-handwriting text-ink px-3 py-2 rounded" + /> +
+ +
+ + Create Room + + + Join Room + +
+ + {children &&
{children}
} +
+
+ ); +}; + +export default RoomActionButtons; diff --git a/pro/src/components/ui/RoomLobby.jsx b/pro/src/components/ui/RoomLobby.jsx new file mode 100644 index 0000000..2884207 --- /dev/null +++ b/pro/src/components/ui/RoomLobby.jsx @@ -0,0 +1,135 @@ +import React, { useState, useEffect } from 'react'; +import SketchButton from './SketchButton'; +import CountdownOverlay from './CountdownOverlay'; + +const RoomLobby = ({ + roomId, + players = [], + spectators = [], + isHost, + minPlayers = 2, + onStart, + onLeave, + gameName = 'Game', + showCountdown = false, + onCountdownComplete, +}) => { + const [dots, setDots] = useState(''); + const [shareSupported] = useState(() => !!navigator.share); + + // Animated "Waiting..." dots + useEffect(() => { + if (players.length >= minPlayers) return; + const id = setInterval(() => { + setDots((d) => (d.length >= 3 ? '' : d + '.')); + }, 500); + return () => clearInterval(id); + }, [players.length, minPlayers]); + + const handleShare = async () => { + try { + await navigator.share({ + title: `Join my ${gameName} room!`, + text: `Use room code: ${roomId}`, + url: window.location.href, + }); + } catch { + // user cancelled or not supported + } + }; + + const canStart = players.length >= minPlayers; + + return ( +
+ {showCountdown && } + +
+ {/* Room ID */} +
+

Room Code

+

{roomId}

+
+ + {/* Animated status banner */} +
+ {canStart ? ( + ✅ Ready to start! + ) : ( + Waiting for players{dots} + )} +
+ + {/* Player ready checklist */} +
+

+ Players ({players.length}/{minPlayers} min) +

+ {players.map((p, i) => ( +
+ {p.connected !== false ? '☑️' : '☐'} + {p.name} + {i === 0 && host} +
+ ))} + {/* Empty slots */} + {Array.from({ length: Math.max(0, minPlayers - players.length) }).map((_, i) => ( +
+ ☐ + Waiting... +
+ ))} +
+ + {/* Spectators */} + {spectators.length > 0 && ( +
+

Spectators ({spectators.length})

+ {spectators.map((s, i) => ( +
+ 👁️ + {s.name} +
+ ))} +
+ )} + + {/* Actions */} +
+ {/* Web Share API invite */} + {shareSupported && ( + + 📤 Invite Friends + + )} + + {isHost && ( + + {canStart ? '🚀 Start Game' : `Need ${minPlayers - players.length} more player(s)`} + + )} + + {!isHost &&

Waiting for host to start…

} + + + Leave Room + +
+
+
+ ); +}; + +export default RoomLobby; diff --git a/pro/src/components/ui/RoomLobby.test.jsx b/pro/src/components/ui/RoomLobby.test.jsx new file mode 100644 index 0000000..565ae4e --- /dev/null +++ b/pro/src/components/ui/RoomLobby.test.jsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import RoomLobby from './RoomLobby'; + +const players2 = [ + { id: '1', name: 'Alice', connected: true }, + { id: '2', name: 'Bob', connected: true }, +]; + +describe('RoomLobby', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + afterEach(() => { + vi.useRealTimers(); + }); + + it('displays the room code', () => { + render(); + expect(screen.getByText('ABC123')).toBeTruthy(); + }); + + it('shows "Waiting for players" when below minPlayers', () => { + render( + , + ); + expect(screen.getByText(/Waiting for players/)).toBeTruthy(); + }); + + it('shows "Ready to start!" when minPlayers met', () => { + render(); + expect(screen.getByText('✅ Ready to start!')).toBeTruthy(); + }); + + it('renders player names in checklist', () => { + render(); + expect(screen.getByText('Alice')).toBeTruthy(); + expect(screen.getByText('Bob')).toBeTruthy(); + }); + + it('shows Start Game button for host when ready', () => { + render(); + expect(screen.getByText('🚀 Start Game')).toBeTruthy(); + }); + + it('calls onStart when Start Game is clicked', () => { + const onStart = vi.fn(); + render(); + fireEvent.click(screen.getByText('🚀 Start Game')); + expect(onStart).toHaveBeenCalledTimes(1); + }); + + it('shows "Waiting for host" message for non-host', () => { + render(); + expect(screen.getByText(/Waiting for host/)).toBeTruthy(); + }); + + it('calls onLeave when Leave Room is clicked', () => { + const onLeave = vi.fn(); + render(); + fireEvent.click(screen.getByText('Leave Room')); + expect(onLeave).toHaveBeenCalledTimes(1); + }); + + it('shows CountdownOverlay when showCountdown is true', () => { + render( + , + ); + expect(screen.getByText('3')).toBeTruthy(); + }); +}); diff --git a/pro/src/components/ui/ScoreBoard.jsx b/pro/src/components/ui/ScoreBoard.jsx new file mode 100644 index 0000000..1b29ac7 --- /dev/null +++ b/pro/src/components/ui/ScoreBoard.jsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { Trophy } from 'lucide-react'; +import { PlayerAvatar } from './AvatarSelector'; + +const PLAYER_COLORS = ['#2a2a3e', '#c73e1d', '#2d4a8f', '#2f5233', '#7b2d8f', '#b5651d']; + +const ScoreBoard = ({ players, scores, currentTurn, myPlayerIndex, lastMove, orientation = 'horizontal' }) => { + if (!players || players.length === 0) return null; + + const containerClass = orientation === 'vertical' ? 'flex flex-col gap-3' : 'flex gap-3'; + + // Normalize scores to array format if object (X/O) format + const normalizedScores = Array.isArray(scores) + ? scores + : players.map((_, idx) => { + if (scores && typeof scores === 'object') { + if (idx === 0 && scores.X !== undefined) return scores.X; + if (idx === 1 && scores.O !== undefined) return scores.O; + } + return scores?.[idx] || 0; + }); + + return ( +
+ {players.map((p, idx) => { + const isCurrentTurn = currentTurn === p.id; + const isLastMovePlayer = lastMove && lastMove.playerIndex === idx; + const playerColor = p.color || PLAYER_COLORS[idx % PLAYER_COLORS.length]; + + return ( +
+ + + {p.name} + {idx === myPlayerIndex && (You)} + + {normalizedScores && ( + + {normalizedScores[idx] || 0} + + )} + {isCurrentTurn && } + {isLastMovePlayer && !isCurrentTurn && ( + + )} +
+ ); + })} +
+ ); +}; + +export default ScoreBoard; diff --git a/pro/src/components/ui/SketchBorder.jsx b/pro/src/components/ui/SketchBorder.jsx new file mode 100644 index 0000000..0429879 --- /dev/null +++ b/pro/src/components/ui/SketchBorder.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const SketchBorder = ({ children, className = '' }) => { + return
{children}
; +}; + +export default SketchBorder; diff --git a/pro/src/components/ui/SketchButton.jsx b/pro/src/components/ui/SketchButton.jsx new file mode 100644 index 0000000..b4c8037 --- /dev/null +++ b/pro/src/components/ui/SketchButton.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +const SketchButton = ({ children, onClick, disabled, className = '', type = 'button' }) => { + return ( + + ); +}; + +export default SketchButton; diff --git a/pro/src/components/ui/SketchCard.jsx b/pro/src/components/ui/SketchCard.jsx new file mode 100644 index 0000000..0bc7304 --- /dev/null +++ b/pro/src/components/ui/SketchCard.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const SketchCard = ({ children, className = '' }) => { + return
{children}
; +}; + +export default SketchCard; diff --git a/pro/src/components/ui/SketchPopup.jsx b/pro/src/components/ui/SketchPopup.jsx new file mode 100644 index 0000000..0d4c955 --- /dev/null +++ b/pro/src/components/ui/SketchPopup.jsx @@ -0,0 +1 @@ +export const sketchPopupClass = 'sketch-popup'; diff --git a/pro/src/components/ui/TextInput.test.jsx b/pro/src/components/ui/TextInput.test.jsx index 79e24f3..4f87058 100644 --- a/pro/src/components/ui/TextInput.test.jsx +++ b/pro/src/components/ui/TextInput.test.jsx @@ -16,7 +16,7 @@ describe('TextInput', () => { it('renders label and placeholder', () => { render(); - + expect(screen.getByText('Room ID')).toBeDefined(); expect(screen.getByPlaceholderText('Enter code')).toBeDefined(); }); diff --git a/pro/src/components/ui/ThemeToggle.jsx b/pro/src/components/ui/ThemeToggle.jsx new file mode 100644 index 0000000..112eecd --- /dev/null +++ b/pro/src/components/ui/ThemeToggle.jsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Moon, Sun } from 'lucide-react'; +import { useTheme } from '../../context/ThemeContext'; + +const ThemeToggle = () => { + const { theme, toggleTheme } = useTheme(); + + return ( + + ); +}; + +export default ThemeToggle; diff --git a/pro/src/components/ui/TurnIndicator.jsx b/pro/src/components/ui/TurnIndicator.jsx new file mode 100644 index 0000000..684ef76 --- /dev/null +++ b/pro/src/components/ui/TurnIndicator.jsx @@ -0,0 +1,51 @@ +import React from 'react'; + +const PlayerAvatar = ({ playerName, isActive, isMyTurn, turnTimer, isCurrentPlayer = false }) => { + if (!playerName) return null; + const initials = playerName.slice(0, 2); + const timerProgress = turnTimer !== null ? turnTimer / 30 : undefined; + + return ( +
+
+ {initials} +
+ {playerName} + {isCurrentPlayer && (You)} +
+ ); +}; + +const TurnIndicator = ({ playerName, isActive, isMyTurn, turnTimer, players, currentTurn }) => { + if (players && Array.isArray(players)) { + return ( +
+ {players.map((player, index) => { + const isActiveTurn = typeof currentTurn === 'number' ? index === currentTurn : player.id === currentTurn; + return ( + + ); + })} +
+ ); + } + + return ; +}; + +export default TurnIndicator; diff --git a/pro/src/components/ui/TurnIndicator.test.jsx b/pro/src/components/ui/TurnIndicator.test.jsx new file mode 100644 index 0000000..173da24 --- /dev/null +++ b/pro/src/components/ui/TurnIndicator.test.jsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { describe, it, expect } from 'vitest'; +import TurnIndicator from './TurnIndicator'; + +describe('TurnIndicator', () => { + it('renders player avatar with initials', () => { + render(); + expect(screen.getByText('Al')).toBeInTheDocument(); + }); + + it('shows pulse animation when it is my turn', () => { + render(); + const avatar = screen.getByText('Bo'); + expect(avatar).toHaveClass('animate-pulse'); + }); + + it('does not show pulse when not my turn', () => { + render(); + const avatar = screen.getByText('Ch'); + expect(avatar).not.toHaveClass('animate-pulse'); + }); + + it('dims when not active', () => { + render(); + const avatar = screen.getByText('Da'); + expect(avatar).toHaveClass('opacity-50'); + }); + + it('shows timer progress when turnTimer is provided', () => { + render(); + const avatar = screen.getByText('Ev'); + expect(avatar).toHaveAttribute('data-timer', '0.5'); + }); +}); diff --git a/pro/src/components/ui/UndoUI.jsx b/pro/src/components/ui/UndoUI.jsx new file mode 100644 index 0000000..322ddef --- /dev/null +++ b/pro/src/components/ui/UndoUI.jsx @@ -0,0 +1,55 @@ +import React, { useState, useEffect } from 'react'; +import SketchButton from './SketchButton'; +import SketchCard from './SketchCard'; + +const UndoUI = ({ requesterId, players = [], currentTurn, myPlayerIndex, onRequest, onAllow, onDeny }) => { + const requester = players.find((p) => p.id === requesterId); + const requesterName = requester?.name || 'Someone'; + const [timeRemaining, setTimeRemaining] = useState(15); + + useEffect(() => { + if (!requesterId) { + setTimeRemaining(0); + return; + } + setTimeRemaining(15); + const timer = setInterval(() => { + setTimeRemaining((prev) => { + if (prev <= 1) { + clearInterval(timer); + return 0; + } + return prev - 1; + }); + }, 1000); + return () => clearInterval(timer); + }, [requesterId]); + + if (!requesterId) return null; + + const isTargetPlayer = myPlayerIndex === currentTurn; + const progressPercent = (timeRemaining / 15) * 100; + + return ( + +

+ {requesterName} wants to undo the last move +

+
+
+
+ {isTargetPlayer && ( +
+ + Allow + + + Deny + +
+ )} + + ); +}; + +export default UndoUI; diff --git a/pro/src/components/ui/WaitingLobby.jsx b/pro/src/components/ui/WaitingLobby.jsx new file mode 100644 index 0000000..5391b38 --- /dev/null +++ b/pro/src/components/ui/WaitingLobby.jsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { Users, Copy, Share2 } from 'lucide-react'; +import { SketchButton, PlayerAvatar } from './index'; + +const WaitingLobby = ({ roomId, players, isHost, minPlayers, onStart, onLeave, onProfileChange, gameSettings }) => { + const handleCopyRoomId = async () => { + await navigator.clipboard.writeText(roomId); + }; + + const handleShare = async () => { + if (navigator.share) { + await navigator.share({ + title: 'Join my game room!', + text: `Use room code: ${roomId}`, + url: window.location.href, + }); + } + }; + + const canStart = players.length >= minPlayers; + + return ( +
+
+
+

Room Code

+

{roomId}

+
+ + {navigator.share && ( + + )} +
+
+ +
+ + Players ({players.length}/{minPlayers} min) + + {isHost && Host} +
+ +
+ {players.map((p, i) => ( +
+ + {p.name} + {p.connected !== false ? ( + ✓ + ) : ( + disconnected + )} +
+ ))} +
+ + {gameSettings &&
{gameSettings}
} + + {isHost && ( + + {canStart ? 'Start Game' : `Need ${minPlayers - players.length} more player(s)`} + + )} + + {!isHost &&

Waiting for host to start...

} + + + Leave Room + +
+
+ ); +}; + +export default WaitingLobby; diff --git a/pro/src/components/ui/index.js b/pro/src/components/ui/index.js new file mode 100644 index 0000000..436466e --- /dev/null +++ b/pro/src/components/ui/index.js @@ -0,0 +1,20 @@ +export { default as SketchButton } from './SketchButton'; +export { default as SketchCard } from './SketchCard'; +export { default as SketchBorder } from './SketchBorder'; +export { default as PlayerBadge } from './PlayerBadge'; +export { default as ModeSelector } from './ModeSelector'; +export { default as LeaveButton } from './LeaveButton'; +export { default as RoomLobby } from './RoomLobby'; +export { default as GameLobby } from './GameLobby'; +export { default as WaitingLobby } from './WaitingLobby'; +export { default as RoomActionButtons } from './RoomActionButtons'; +export { default as ScoreBoard } from './ScoreBoard'; +export { default as ThemeToggle } from './ThemeToggle'; +export { default as AvatarReactionBar } from './AvatarReactionBar'; +export { sketchPopupClass } from './SketchPopup'; +export { default as GameLayout } from './GameLayout'; +export { default as TurnIndicator } from './TurnIndicator'; +export { default as MatchReport } from './MatchReport'; +export { default as AvatarSelector, PlayerAvatar } from './AvatarSelector'; +export { default as CountdownOverlay } from './CountdownOverlay'; +export { default as UndoUI } from './UndoUI'; diff --git a/pro/src/connect4/Connect4Game.jsx b/pro/src/connect4/Connect4Game.jsx new file mode 100644 index 0000000..09488e7 --- /dev/null +++ b/pro/src/connect4/Connect4Game.jsx @@ -0,0 +1,358 @@ +import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { useGameContext } from '../context/GameContext'; +import { useNavigate } from 'react-router-dom'; +import GameLayout from '../components/ui/GameLayout'; +import GameLobby from '../components/ui/GameLobby'; +import MatchReport from '../components/ui/MatchReport'; +import SketchButton from '../components/ui/SketchButton'; +import TurnIndicator from '../components/ui/TurnIndicator'; +import { AvatarSelector, AvatarReactionBar, sketchPopupClass } from '../components/ui'; +import useSocketListeners from '../hooks/useSocketListeners'; +import useReconnection from '../hooks/useReconnection'; +import Swal from 'sweetalert2'; +import useSound from 'use-sound'; + +const Connect4Game = () => { + const { socket, roomId, setRoomId, clearRoomId, setGamePrefix, profile, setProfile } = useGameContext(); + const navigate = useNavigate(); + const [gameState, setGameState] = useState('lobby'); + const [players, setPlayers] = useState([]); + const [spectators, setSpectators] = useState([]); + const [currentTurn, setCurrentTurn] = useState(null); + const [myPlayerIndex, setMyPlayerIndex] = useState(-1); + const [hoverCol, setHoverCol] = useState(null); + const [winLine, setWinLine] = useState(null); + const [lastMove, setLastMove] = useState(null); + const [board, setBoard] = useState([]); + const joinRoomIdRef = useRef(null); + + const [playMove] = useSound('/sounds/move.mp3', { volume: 0.5 }); + const [playWin] = useSound('/sounds/win.mp3', { volume: 0.7 }); + + const handleCreateRoom = useCallback(() => { + if (!socket) return; + socket.emit('c4_createRoom', { + playerName: profile.name, + avatarIcon: profile.avatarIcon, + color: profile.color, + }); + }, [socket, profile]); + + const handleJoinRoom = useCallback( + (roomIdToJoin, asSpectator) => { + if (!socket) return; + socket.emit('c4_joinRoom', { + roomId: roomIdToJoin, + playerName: profile.name, + avatarIcon: profile.avatarIcon, + color: profile.color, + asSpectator, + }); + }, + [socket, profile], + ); + + const { clearReconnect } = useReconnection({ + socket, + gamePrefix: 'c4', + roomId, + onRestore: (room) => { + if (!room) return; + setRoomId(room.id); + setPlayers(room.players || []); + setSpectators(room.spectators || []); + setGameState(room.gameState || 'lobby'); + setCurrentTurn(room.currentTurn); + setBoard(room.board || []); + }, + }); + + useSocketListeners( + socket, + { + c4_roomInfo: (data) => { + setRoomId(data.id); + setPlayers(data.players || []); + setSpectators(data.spectators || []); + setGameState(data.gameState); + setCurrentTurn(data.currentTurn); + setBoard(data.board || []); + const myPlayer = data.players?.find((p) => p.id === socket.id); + setMyPlayerIndex(myPlayer ? data.players.findIndex((p) => p.id === myPlayer.id) : -1); + }, + c4_gameStarted: () => { + setGameState('playing'); + }, + c4_moveMade: (data) => { + setBoard(data.board || []); + if (data.lastMove) { + setLastMove(data.lastMove); + playMove(); + } + }, + c4_gameOver: (data) => { + setGameState('ended'); + if (data.winLine) { + setWinLine(data.winLine.map((c) => `${c.row}-${c.col}`)); + playWin(); + } + }, + c4_gamePaused: () => { + setGameState('paused'); + }, + c4_gameRestarted: () => { + setGameState('waiting'); + setWinLine(null); + }, + c4_alert: ({ icon, title, text }) => { + Swal.fire({ icon, title, text }); + }, + c4_reconnectFailed: ({ reason, roomId: failedRoomId }) => { + Swal.fire({ + title: 'Reconnection Failed', + text: + reason === 'room_not_found' + ? 'The room no longer exists.' + : reason === 'player_not_found' + ? 'Your player session was not found.' + : reason === 'game_already_ended' + ? 'The game has ended.' + : 'Could not reconnect to the game.', + icon: 'error', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(); + setGameState('lobby'); + navigate('/'); + }); + }, + server_shutdown: ({ message }) => { + Swal.fire({ + title: 'Server Shutting Down', + text: message || 'The server is going down for maintenance.', + icon: 'info', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(); + setGameState('lobby'); + navigate('/'); + }); + }, + }, + [clearRoomId, navigate, playMove, playWin, setRoomId], + ); + + useEffect(() => { + if (!socket) return; + setGamePrefix('c4'); + + const saved = sessionStorage.getItem('c4_reconnect'); + if (saved) { + const data = JSON.parse(saved); + socket.emit('c4_reconnect', data); + } + }, [socket, setGamePrefix]); + + const handleStartGame = useCallback(() => { + if (!socket || !roomId) return; + socket.emit('c4_startGame', { roomId }); + }, [socket, roomId]); + + const handleRestart = useCallback(() => { + if (!socket || !roomId) return; + socket.emit('c4_restartGame', roomId); + }, [socket, roomId]); + + const handleLeave = useCallback(() => { + if (!socket || !roomId) return; + socket.emit('c4_leaveRoom', roomId); + clearReconnect(); + clearRoomId(); + setGameState('lobby'); + navigate('/'); + }, [socket, roomId, clearReconnect, clearRoomId, navigate]); + + const handleColumnClick = useCallback( + (col) => { + if (!roomId || gameState !== 'playing') return; + if (myPlayerIndex !== currentTurn) return; + + socket.emit('c4_makeMove', { roomId, column: col }); + }, + [roomId, gameState, myPlayerIndex, currentTurn, socket], + ); + + const isSpectator = spectators.some((s) => s.id === socket?.id); + const isHost = players[0]?.id === socket?.id; + + if (gameState === 'ended') { + const scores = players.map((p, idx) => ({ + name: p.name || `Player ${idx + 1}`, + score: 0, + })); + return ( + + ); + } + + if (roomId && gameState === 'waiting') { + return ( + setProfile(next)} + /> + ); + } + + if (roomId && gameState === 'playing') { + const canPlay = myPlayerIndex === currentTurn && !isSpectator; + + return ( + +
+ {isSpectator && ( +
+ 👁️ Spectating +
+ )} + + + +
setHoverCol(null)} + > + {board.map((row, r) => + row.map((cell, c) => { + const isWinning = winLine && winLine.includes(`${r}-${c}`); + const isLastMove = lastMove && lastMove.row === r && lastMove.col === c; + return ( +
+ {cell !== null && ( +
+ )} +
+ ); + }), + )} +
+ +
setHoverCol(null)}> + {board[0]?.map((_, col) => ( + + ))} +
+ + + Leave Room + +
+ + {gameState === 'playing' && ( + + )} + + ); + } + + return ( +
+
+

Connect 4

+ +
+ + setProfile((prev) => ({ ...prev, name: e.target.value }))} + placeholder="Enter name" + className="sketch-input w-full mt-1" + maxLength={20} + /> +
+ + setProfile((prev) => ({ ...prev, avatarIcon: icon }))} + onColorChange={(c) => setProfile((prev) => ({ ...prev, color: c }))} + /> + + + Create Room + + +
+ + { + if (e.key === 'Enter') { + const roomId = e.target.value.trim(); + if (roomId) handleJoinRoom(roomId); + } + }} + /> + { + const roomIdInput = joinRoomIdRef.current?.value || ''; + if (roomIdInput) handleJoinRoom(roomIdInput.trim()); + }} + className="w-full" + > + Join as Player + + { + const roomIdInput = joinRoomIdRef.current?.value || ''; + if (roomIdInput) handleJoinRoom(roomIdInput.trim(), true); + }} + className="w-full mt-2" + style={{ background: '#f0f8ff' }} + > + Join as Spectator + +
+
+
+ ); +}; + +export default Connect4Game; diff --git a/pro/src/connect4/Connect4Game.test.jsx b/pro/src/connect4/Connect4Game.test.jsx new file mode 100644 index 0000000..a0f7fe1 --- /dev/null +++ b/pro/src/connect4/Connect4Game.test.jsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import Connect4Game from './Connect4Game'; +import { ThemeProvider } from '../context/ThemeContext'; + +vi.mock('socket.io-client', () => ({ + io: vi.fn(() => ({ + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + connected: true, + })), +})); + +vi.mock('../context/GameContext', () => ({ + useGameContext: () => ({ + socket: { + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + }, + playerName: 'TestPlayer', + setPlayerName: vi.fn(), + roomId: null, + setRoomId: vi.fn(), + clearRoomId: vi.fn(), + gamePrefix: null, + setGamePrefix: vi.fn(), + leaveRoom: vi.fn(), + clearReconnect: vi.fn(), + profile: { name: 'TestPlayer', avatarIcon: 'cat', color: '#2a2a3e' }, + setProfile: vi.fn(), + }), +})); + +vi.mock('use-sound', () => ({ + default: vi.fn(() => [vi.fn()]), +})); + +vi.mock('canvas-confetti', () => ({ + default: vi.fn(), +})); + +vi.mock('sweetalert2', () => ({ + fire: vi.fn(), +})); + +vi.mock('framer-motion', () => ({ + motion: { + div: ({ children, ...props }) =>
{children}
, + }, + AnimatePresence: ({ children }) => <>{children}, +})); + +const Wrapper = ({ children }) => ( + + {children} + +); + +describe('Connect4Game', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('renders landing UI when not in room', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText('Connect 4')).toBeInTheDocument(); + expect(screen.getByPlaceholderText('Enter name')).toBeInTheDocument(); + }); +}); diff --git a/pro/src/context/GameContext.jsx b/pro/src/context/GameContext.jsx index 6d4cf2a..e312868 100644 --- a/pro/src/context/GameContext.jsx +++ b/pro/src/context/GameContext.jsx @@ -1,8 +1,9 @@ -import React, { createContext, useContext, useState, useEffect, useRef } from 'react'; +import React, { createContext, useContext, useState, useEffect, useRef, useCallback } from 'react'; import io from 'socket.io-client'; import logger from '../utils/logger'; +import { reportRuntimeError } from '../utils/runtimeError'; -const GameContext = createContext(); +export const GameContext = createContext(); export const useGameContext = () => { const context = useContext(GameContext); @@ -13,53 +14,123 @@ export const useGameContext = () => { }; export const GameProvider = ({ children }) => { - const [playerName, setPlayerName] = useState(localStorage.getItem('playerName') || ''); + const [profile, setProfile] = useState(() => { + const saved = localStorage.getItem('playerProfile'); + return saved + ? JSON.parse(saved) + : { + name: '', + avatarIcon: 'cat', + color: '#2a2a3e', + }; + }); const [roomId, setRoomId] = useState(null); + const [gamePrefix, setGamePrefix] = useState(null); const [socket, setSocket] = useState(null); + const [reconnectionState, setReconnectionState] = useState('disconnected'); const socketRef = useRef(null); + const lastDisconnectTimeRef = useRef(null); + const reconnectAttemptsRef = useRef(0); + const reconnectTimeoutsRef = useRef([]); useEffect(() => { - const newSocket = io('http://localhost:4000'); + localStorage.setItem('playerProfile', JSON.stringify(profile)); + }, [profile]); + + useEffect(() => { + const host = window.location.hostname || 'localhost'; + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + const port = import.meta.env.VITE_PORT || 4000; + const newSocket = io(`${protocol}//${host}:${port}`); socketRef.current = newSocket; setSocket(newSocket); newSocket.on('connect', () => { logger.info('SOCKET', `Connected with ID: ${newSocket.id}`); + setReconnectionState('connected'); + reconnectAttemptsRef.current = 0; }); newSocket.on('disconnect', (reason) => { logger.warn('SOCKET', `Disconnected: ${reason}`); + setReconnectionState('disconnected'); + lastDisconnectTimeRef.current = Date.now(); }); newSocket.on('connect_error', (error) => { logger.error('SOCKET', `Connection error: ${error.message}`); + reportRuntimeError('Socket connection error', error); + }); + + newSocket.on('error', (error) => { + logger.error('SOCKET', `Socket error: ${error?.message || error}`); + reportRuntimeError('Socket error', error); }); logger.info('SOCKET', 'Initializing socket connection...'); return () => { logger.info('SOCKET', 'Cleaning up socket connection'); + for (const timeout of reconnectTimeoutsRef.current) { + clearTimeout(timeout); + } newSocket.disconnect(); }; }, []); + const roomIdRef = useRef(roomId); useEffect(() => { - if (playerName) { - localStorage.setItem('playerName', playerName); + roomIdRef.current = roomId; + }, [roomId]); + + const clearRoomId = (id) => { + if (roomIdRef.current === id) { + setRoomId(null); } - }, [playerName]); + }; + + const clearReconnect = useCallback((prefix) => { + sessionStorage.removeItem(`${prefix}_reconnect`); + }, []); + + const leaveRoom = useCallback( + (prefix, roomId) => { + socket?.emit(`${prefix}_leaveRoom`, roomId); + clearReconnect(prefix); + clearRoomId(roomId); + }, + [socket, clearReconnect], + ); + + const setPlayerProfileName = (name) => { + setProfile((prev) => ({ ...prev, name })); + }; + + const handleReconnectFailure = useCallback( + ({ reason, roomId }) => { + reconnectAttemptsRef.current++; + sessionStorage.removeItem(`${gamePrefix}_reconnect`); + }, + [gamePrefix], + ); const value = { - playerName, - setPlayerName, + playerName: profile.name, + setPlayerName: setPlayerProfileName, + profile, + setProfile, roomId, setRoomId, - socket + clearRoomId, + socket, + gamePrefix, + setGamePrefix, + leaveRoom, + clearReconnect, + reconnectionState, + reconnectAttempts: reconnectAttemptsRef.current, + handleReconnectFailure, }; - return ( - - {children} - - ); + return {children}; }; diff --git a/pro/src/context/GameContext.test.jsx b/pro/src/context/GameContext.test.jsx index bcad5e8..e33f564 100644 --- a/pro/src/context/GameContext.test.jsx +++ b/pro/src/context/GameContext.test.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect } from 'vitest'; import { GameProvider, useGameContext } from './GameContext'; const TestComponent = () => { @@ -18,7 +18,7 @@ describe('GameContext', () => { render( - + , ); const nameDisplay = screen.getByTestId('player-name'); diff --git a/pro/src/context/ThemeContext.jsx b/pro/src/context/ThemeContext.jsx new file mode 100644 index 0000000..ab6d09e --- /dev/null +++ b/pro/src/context/ThemeContext.jsx @@ -0,0 +1,36 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; + +const ThemeContext = createContext(); + +export const useTheme = () => { + const context = useContext(ThemeContext); + if (!context) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; +}; + +export const ThemeProvider = ({ children }) => { + const [theme, setTheme] = useState(() => { + const saved = localStorage.getItem('theme'); + return saved || 'light'; + }); + + useEffect(() => { + localStorage.setItem('theme', theme); + document.documentElement.setAttribute('data-theme', theme); + }, [theme]); + + const toggleTheme = () => { + setTheme((prev) => (prev === 'light' ? 'dark' : 'light')); + }; + + const value = { + theme, + setTheme, + toggleTheme, + isDark: theme === 'dark', + }; + + return {children}; +}; diff --git a/pro/src/dab/DabGame.jsx b/pro/src/dab/DabGame.jsx index add60ae..fb63ac3 100644 --- a/pro/src/dab/DabGame.jsx +++ b/pro/src/dab/DabGame.jsx @@ -1,19 +1,43 @@ -import React, { useState, useEffect, useCallback, useRef } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { useGameContext } from '../context/GameContext'; +import GameLobby from '../components/ui/GameLobby'; +import MatchReport from '../components/ui/MatchReport'; +import UndoUI from '../components/ui/UndoUI'; import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'; -import RetroButton from '../components/ui/RetroButton'; +import { SketchButton, SketchCard, sketchPopupClass, GameLayout, AvatarReactionBar } from '../components/ui'; import useSound from 'use-sound'; import confetti from 'canvas-confetti'; import Swal from 'sweetalert2'; import { useNavigate } from 'react-router-dom'; -import { ArrowLeft, Users, Trophy, SwatchBook, Plus, Minus, RotateCcw } from 'lucide-react'; +import { ArrowLeft, Trophy, Plus, Minus, RotateCcw, Undo2 } from 'lucide-react'; +import { PlayerAvatar } from '../components/ui/AvatarSelector'; +import useReconnection from '../hooks/useReconnection'; +import useSocketListeners from '../hooks/useSocketListeners'; import logger from '../utils/logger'; - -const PLAYER_COLORS = ['#3B82F6', '#EF4444', '#22C55E', '#F97316']; -const PLAYER_TAILWIND = ['blue-500', 'red-500', 'green-500', 'orange-500']; +import DabPreGame from './DabPreGame'; + +const PLAYER_COLORS = ['#1a1a2e', '#c73e1d', '#2d4a8f', '#2f5233']; + +const addWobble = (x1, y1, x2, y2, seed = 0) => { + const segments = 8; + const wobbleAmount = 1.5; + const points = []; + for (let i = 0; i <= segments; i++) { + const t = i / segments; + const x = x1 + (x2 - x1) * t; + const y = y1 + (y2 - y1) * t; + const offsetX = Math.sin(seed + i * 2.3) * wobbleAmount; + const offsetY = Math.cos(seed + i * 1.7) * wobbleAmount; + points.push(`${x + offsetX},${y + offsetY}`); + } + return `M ${points[0]} ${points + .slice(1) + .map((p) => `L ${p}`) + .join(' ')}`; +}; const DabGame = () => { - const { socket, playerName, roomId, setRoomId } = useGameContext(); + const { socket, playerName, roomId, setRoomId, clearRoomId, setGamePrefix, profile, setProfile } = useGameContext(); const navigate = useNavigate(); const [players, setPlayers] = useState([]); @@ -29,490 +53,672 @@ const DabGame = () => { const [mode, setMode] = useState('classic'); const [customRows, setCustomRows] = useState(5); const [customCols, setCustomCols] = useState(5); - const [customPlayers, setCustomPlayers] = useState(2); const [myPlayerIndex, setMyPlayerIndex] = useState(-1); const [isPaused, setIsPaused] = useState(false); + const [redoRequest, setRedoRequest] = useState(null); const [playLine] = useSound('/sounds/move.mp3', { volume: 0.5 }); const [playBox] = useSound('/sounds/win.mp3', { volume: 0.7 }); - const reconnectAttempted = useRef(false); + const handleLeave = useCallback(() => { + Swal.fire({ + title: 'Leave Game?', + text: 'Are you sure you want to leave?', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Yes, leave', + cancelButtonText: 'Stay', + customClass: { popup: sketchPopupClass }, + }).then((result) => { + if (result.isConfirmed) { + socket.emit('dab_leaveRoom', roomId); + sessionStorage.removeItem('dab_reconnect'); + clearRoomId(roomId); + navigate('/'); + } + }); + }, [socket, clearRoomId, navigate, roomId]); + + const handleStart = useCallback( + ({ rows: gameRows, cols: gameCols }) => { + setRows(gameRows); + setCols(gameCols); + socket.emit('dab_startGame', { roomId, rows: gameRows, cols: gameCols }); + }, + [roomId, socket], + ); - useEffect(() => { - if (!socket) return; + const handleJoin = useCallback( + (roomIdValue) => { + socket.emit('dab_joinRoom', { + roomId: roomIdValue, + playerName: profile.name || playerName, + avatarIcon: profile.avatarIcon, + color: profile.color, + }); + }, + [playerName, profile, socket], + ); - const saved = sessionStorage.getItem('dab_reconnect'); - if (saved && !reconnectAttempted.current) { - reconnectAttempted.current = true; - const { roomId: savedRoomId, playerId } = JSON.parse(saved); - logger.socket('➡️', 'dab_reconnect', { roomId: savedRoomId, playerId }); - socket.emit('dab_reconnect', { roomId: savedRoomId, playerId }); - setRoomId(savedRoomId); - return; - } - - socket.on('dab_roomInfo', (room) => { - logger.socket('⬅️', 'dab_roomInfo', { roomId: room.id, gameState: room.gameState }); + const { clearReconnect } = useReconnection({ + socket, + gamePrefix: 'dab', + roomId, + onRestore: (room) => { + if (!room) return; setRoomId(room.id); - setPlayers(room.players); - setGameState(room.gameState); + setPlayers(room.players || []); + setGameState(room.gameState || 'waiting'); setCurrentTurn(room.currentTurn); setRows(room.rows); setCols(room.cols); - setHorizontalLines(room.horizontalLines); - setVerticalLines(room.verticalLines); - setBoxes(room.boxes); - setScores(room.scores); - setLastMove(room.lastMove); + setHorizontalLines(room.horizontalLines || []); + setVerticalLines(room.verticalLines || []); + setBoxes(room.boxes || []); + setScores(room.scores || []); + setLastMove(room.lastMove || null); setIsPaused(room.gameState === 'paused'); - - const idx = room.players.findIndex(p => p.id === socket.id); - if (idx !== -1) { - setMyPlayerIndex(idx); - sessionStorage.setItem('dab_reconnect', JSON.stringify({ roomId: room.id, playerId: room.players[idx].id })); + setMyPlayerIndex((room.players || []).findIndex((p) => p.id === socket?.id)); + if (room.settings) { + setMode(room.settings.mode || 'classic'); + setCustomRows(room.settings.customRows || 5); + setCustomCols(room.settings.customCols || 5); } - }); - - socket.on('dab_gameStarted', ({ firstTurn }) => { - logger.socket('⬅️', 'dab_gameStarted', { firstTurn }); - setGameState('playing'); - setIsPaused(false); - Swal.fire({ - title: 'Game Started!', - text: 'Draw lines to claim boxes!', - timer: 1500, - showConfirmButton: false, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); - - socket.on('dab_gameRestarted', () => { - logger.socket('⬅️', 'dab_gameRestarted', 'Game restarted'); - setGameState('waiting'); - setCurrentTurn(0); - setHorizontalLines(rowsArray => Array(rows).fill(null).map(() => Array(cols).fill(null))); - setVerticalLines(rowsArray => Array(rows).fill(null).map(() => Array(cols + 1).fill(null))); - setBoxes(rowsArray => Array(rows).fill(null).map(() => Array(cols).fill(null))); - setScores(Array(players.length).fill(0)); - setLastMove(null); - setIsPaused(false); - Swal.fire({ - title: 'Game Restarted', - text: 'New game starting!', - timer: 1500, - showConfirmButton: false, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); - - socket.on('dab_moveResult', ({ lineType, r, c, claimedBoxes, scores: newScores, currentTurn: newTurn, playerIndex: movePlayerIndex }) => { - logger.socket('⬅️', 'dab_moveResult', { claimedBoxes, scores: newScores }); - playLine(); - - setHorizontalLines(prev => { - const copy = prev.map(row => [...row]); - if (lineType === 'h') copy[r][c] = movePlayerIndex; - return copy; - }); - setVerticalLines(prev => { - const copy = prev.map(row => [...row]); - if (lineType === 'v') copy[r][c] = movePlayerIndex; - return copy; - }); - - if (claimedBoxes.length > 0) { - playBox(); - setBoxes(prev => { - const copy = prev.map(row => [...row]); - for (const box of claimedBoxes) { - copy[box.r][box.c] = movePlayerIndex; - } - return copy; - }); - } - - setScores(newScores); - setCurrentTurn(newTurn); - }); - - socket.on('dab_gameOver', ({ winner, scores: finalScores, winners }) => { - logger.socket('⬅️', 'dab_gameOver', { winner, winners }); - setGameState('ended'); - setScores(finalScores); - sessionStorage.removeItem('dab_reconnect'); - - confetti({ particleCount: 150, spread: 70, origin: { y: 0.6 } }); + }, + }); + + useSocketListeners( + socket, + { + dab_gameStarted: () => { + logger.socket('⬅️', 'dab_gameStarted'); + setGameState('playing'); + setIsPaused(false); + Swal.fire({ + title: 'Game Started!', + text: 'Draw lines to claim boxes!', + timer: 1500, + showConfirmButton: false, + customClass: { popup: sketchPopupClass }, + }); + }, + dab_gameRestarted: () => { + logger.socket('⬅️', 'dab_gameRestarted'); + setGameState('waiting'); + setCurrentTurn(0); + setHorizontalLines(Array.from({ length: rows }, () => Array(cols).fill(null))); + setVerticalLines(Array.from({ length: rows }, () => Array(cols + 1).fill(null))); + setBoxes(Array.from({ length: rows }, () => Array(cols).fill(null))); + setScores(Array(players.length).fill(0)); + setLastMove(null); + setIsPaused(false); + Swal.fire({ + title: 'Game Restarted', + text: 'New game starting!', + timer: 1500, + showConfirmButton: false, + customClass: { popup: sketchPopupClass }, + }); + }, + dab_moveResult: ({ + lineType, + r, + c, + claimedBoxes, + scores: newScores, + currentTurn: newTurn, + playerIndex: movePlayerIndex, + }) => { + playLine(); + setHorizontalLines((prev) => { + const copy = prev.map((row) => [...row]); + if (lineType === 'h') copy[r][c] = movePlayerIndex; + return copy; + }); + setVerticalLines((prev) => { + const copy = prev.map((row) => [...row]); + if (lineType === 'v') copy[r][c] = movePlayerIndex; + return copy; + }); + if (claimedBoxes && claimedBoxes.length > 0) { + playBox(); + const playerColor = players[movePlayerIndex]?.color || PLAYER_COLORS[movePlayerIndex] || '#2a2a3e'; + confetti({ + particleCount: 25, + spread: 35, + origin: { y: 0.6 }, + colors: [playerColor], + decay: 0.85, + gravity: 0.5, + }); + setBoxes((prev) => { + const copy = prev.map((row) => [...row]); + for (const box of claimedBoxes) copy[box.r][box.c] = movePlayerIndex; + return copy; + }); + } + setScores(newScores); + setCurrentTurn(newTurn); + setLastMove({ lineType, r, c }); + }, + dab_gameOver: ({ winner, scores: finalScores }) => { + logger.socket('⬅️', 'dab_gameOver'); + setGameState('ended'); + setScores(finalScores); + sessionStorage.removeItem('dab_reconnect'); + confetti({ particleCount: 150, spread: 70, origin: { y: 0.6 } }); + if (!winner) { + Swal.fire({ + title: "It's a Tie!", + text: 'Multiple players share the top score!', + icon: 'info', + customClass: { popup: sketchPopupClass }, + }); + } + }, + dab_playerLeft: ({ playerId }) => { + setPlayers((prev) => prev.map((p) => (p.id === playerId ? { ...p, connected: false } : p))); + }, + dab_playerReconnected: ({ playerId }) => { + setPlayers((prev) => prev.map((p) => (p.id === playerId ? { ...p, connected: true } : p))); + setIsPaused(false); + }, + dab_gamePaused: () => setIsPaused(true), + dab_redoRequested: ({ requesterId }) => setRedoRequest(requesterId), + dab_redoCancelled: () => setRedoRequest(null), + dab_moveUndone: ({ horizontalLines: h, verticalLines: v, boxes: b, scores: s, currentTurn: t }) => { + setHorizontalLines(h); + setVerticalLines(v); + setBoxes(b); + setScores(s); + setCurrentTurn(t); + setLastMove(null); + setRedoRequest(null); + }, + }, + [rows, cols, players, playBox, playLine, roomId], + ); - if (winner) { - const winnerName = players.find(p => p.id === winner)?.name || 'Player'; + useSocketListeners( + socket, + { + dab_redoResponse: ({ accepted, reason, requesterId, requesterName }) => { + if (!accepted) { + setRedoRequest(null); + if (reason === 'Requester disconnected.') { + Swal.fire({ + title: 'Redo Failed', + text: 'The player who requested undo disconnected.', + icon: 'info', + customClass: { popup: sketchPopupClass }, + }); + } else { + const name = requesterName || players.find((p) => p.id === requesterId)?.name || 'Someone'; + Swal.fire({ + title: 'Undo Denied', + text: `${name}'s undo request was denied.`, + icon: 'warning', + customClass: { popup: sketchPopupClass }, + }); + } + } else { + setRedoRequest(null); + } + }, + dab_reconnectFailed: ({ reason, roomId }) => { Swal.fire({ - title: 'Victory!', - text: `${winnerName} wins!`, - icon: 'success', - customClass: { popup: 'glass rounded-3xl paper-font' } + title: 'Reconnection Failed', + text: + reason === 'room_not_found' + ? 'The room no longer exists.' + : reason === 'player_not_found' + ? 'Your player session was not found.' + : reason === 'game_already_ended' + ? 'The game has ended.' + : 'Could not reconnect to the game.', + icon: 'error', + customClass: { popup: sketchPopupClass }, + }).then(() => { + sessionStorage.removeItem('dab_reconnect'); + clearRoomId(roomId); + navigate('/'); }); - } else { + }, + server_shutdown: ({ message }) => { Swal.fire({ - title: "It's a Tie!", - text: 'Multiple players share the top score!', + title: 'Server Shutting Down', + text: message || 'The server is going down for maintenance.', icon: 'info', - customClass: { popup: 'glass rounded-3xl paper-font' } + customClass: { popup: sketchPopupClass }, + }).then(() => { + sessionStorage.removeItem('dab_reconnect'); + clearRoomId(roomId); + navigate('/'); }); - } - }); + }, + }, + [players, clearRoomId, roomId, navigate], + ); - socket.on('dab_playerLeft', ({ playerId }) => { - logger.socket('⬅️', 'dab_playerLeft', { playerId }); - setPlayers(prev => prev.map(p => p.id === playerId ? { ...p, connected: false } : p)); - }); + useEffect(() => { + if (!socket) return; + setGamePrefix('dab'); + logger.socket('➡️', 'dab_requestRoomInfo', { roomId }); + if (roomId) socket.emit('dab_requestRoomInfo', roomId); + }, [socket, roomId, setGamePrefix]); - socket.on('dab_gamePaused', ({ reason }) => { - logger.socket('⬅️', 'dab_gamePaused', { reason }); - setIsPaused(true); - Swal.fire({ - title: 'Game Paused', - text: reason, - icon: 'warning', - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); + const handleRestartGame = useCallback(() => { + socket.emit('dab_restartGame', roomId); + }, [roomId, socket]); + + const handleLeaveRoom = useCallback(() => { + handleLeave(); + }, [handleLeave]); + + const handleStartGame = useCallback(() => { + if (!roomId) return; + handleStart({ rows, cols }); + }, [handleStart, roomId, rows, cols]); + + const handleUndoRequest = useCallback(() => { + socket.emit('dab_requestRedo', roomId); + }, [roomId, socket]); + + const handleUndoResponse = useCallback( + (accept) => { + socket.emit('dab_respondRedo', { roomId, accept }); + }, + [roomId, socket], + ); - socket.on('dab_alert', ({ icon, title, text }) => { - logger.socket('⬅️', 'dab_alert', { icon, title, text }); - Swal.fire({ icon, title, text, customClass: { popup: 'glass rounded-3xl paper-font' } }); - }); + const handleLineClick = useCallback( + (lineType, r, c) => { + if (gameState !== 'playing' || isPaused || myPlayerIndex !== currentTurn) return; + const arr = lineType === 'h' ? horizontalLines : verticalLines; + if (arr[r]?.[c] !== null) return; + socket.emit('dab_makeMove', { roomId, lineType, r, c }); + }, + [gameState, isPaused, myPlayerIndex, currentTurn, horizontalLines, verticalLines, roomId, socket], + ); - return () => { - socket.off('dab_roomInfo'); - socket.off('dab_gameStarted'); - socket.off('dab_gameRestarted'); - socket.off('dab_moveResult'); - socket.off('dab_gameOver'); - socket.off('dab_playerLeft'); - socket.off('dab_gamePaused'); - socket.off('dab_alert'); - }; - }, [socket, players, setRoomId, playLine, playBox]); - - const handleCreateRoom = () => { - let r = rows, c = cols, maxP = customPlayers; - if (mode === 'custom') { - r = customRows; - c = customCols; - maxP = customPlayers; - } - logger.socket('➡️', 'dab_createRoom', { mode, customRows: r, customCols: c, customPlayers: maxP, playerName }); - socket.emit('dab_createRoom', { mode, customRows: r, customCols: c, customPlayers: maxP, playerName }); - }; - - const handleJoinRoom = async () => { - const { value: joinRoomId } = await Swal.fire({ - title: 'Join Room', - input: 'text', - inputPlaceholder: 'Enter Room ID', - showCancelButton: true, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - if (joinRoomId) { - logger.socket('➡️', 'dab_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); - socket.emit('dab_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); - } - }; - - const handleLineClick = useCallback((lineType, r, c, e) => { - e.stopPropagation(); - logger.socket('➡️', 'dab_makeMove', { roomId, lineType, r, c, gameState, currentTurn, myPlayerIndex }); - if (gameState !== 'playing' || isPaused) return; - if (currentTurn !== myPlayerIndex) return; - - socket.emit('dab_makeMove', { roomId, lineType, r, c }); - }, [gameState, isPaused, currentTurn, myPlayerIndex, roomId, socket]); - - const handleRestartGame = () => { - logger.socket('➡️', 'dab_restartGame', { roomId, playerId: socket.id }); - socket.emit('dab_restartGame', roomId); - }; - - const handleLeaveRoom = () => { - sessionStorage.removeItem('dab_reconnect'); - setRoomId(null); - setPlayers([]); - setGameState('waiting'); - setBoxes([]); - setHorizontalLines([]); - setVerticalLines([]); - setScores([]); - setMyPlayerIndex(-1); - setIsPaused(false); - }; - - const spacing = 40; + const isHost = roomId && players[0]?.id === socket?.id; + + const customizationSlot = ( +
+

Game Mode

+
+ {['classic', 'extended', 'marathon'].map((m) => ( + setMode(m)} className={mode === m ? 'bg-ink text-white' : ''}> + {m} + + ))} +
+ setMode('custom')} className={mode === 'custom' ? 'bg-ink text-white' : ''}> + Custom Size + + {mode === 'custom' && ( +
+
+ + setCustomRows(Number(e.target.value))} + className="w-full" + /> +
+
+ + setCustomCols(Number(e.target.value))} + className="w-full" + /> +
+
+ )} +
+ ); + + const spacing = 60; const dotRadius = 4; const lineWidth = 3; - const hitLineWidth = 16; + const hitLineWidth = 20; const svgWidth = cols * spacing; const svgHeight = rows * spacing; - return ( -
- navigate('/')} - variant="secondary" - className="absolute top-2 sm:top-8 left-2 sm:left-8 flex items-center gap-1 sm:gap-2 text-xs sm:text-base px-2 sm:px-4" - > - - Back - - -

Dots & Boxes

- - {!roomId ? ( -
-
-
- - -
- - {mode === 'custom' && ( -
-
-
- - setCustomRows(Math.max(1, Math.min(30, parseInt(e.target.value) || 1)))} - className="w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font" - /> -
-
- - setCustomCols(Math.max(1, Math.min(30, parseInt(e.target.value) || 1)))} - className="w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font" - /> -
-
-
- - setCustomPlayers(Math.max(2, Math.min(4, parseInt(e.target.value) || 2)))} - className="w-full bg-white/50 border border-gray-300 rounded-lg px-3 py-2 paper-font" - /> -
-
- )} + if (!roomId) { + return ( + + ); + } + + if (gameState === 'waiting') { + return ( + setProfile(next)} + /> + ); + } + + if (gameState === 'ended') { + return ( + ({ + name: players[idx]?.name || `Player ${idx + 1}`, + score: typeof score === 'number' ? score : (score?.value ?? 0), + }))} + players={players} + onRematch={handleRestartGame} + onNewRoom={handleLeaveRoom} + /> + ); + } -
- Create Room - Join Room -
+ return ( + +
+
+
+ + + Leave Game +
-
- ) : ( -
-
-
-
- - Room: - {roomId} -
- - Leave - -
-
- {players.map((p, i) => ( -
-
- {p.name.length > 10 ? p.name.slice(0, 10) + '...' : p.name} - {scores[i] || 0} - {!p.connected && (DC)} - {i === currentTurn && gameState === 'playing' && !isPaused && p.connected && ( -
- )} +
+
+ +

+ + Scoreboard +

+
+ {players.map((p, idx) => ( +
+
+ + + {p.name} + {idx === myPlayerIndex && ' (You)'} + +
+ + {typeof scores[idx] === 'number' ? scores[idx] : 0} + +
+ ))}
- ))} -
+ + + handleUndoResponse(true)} + onDeny={() => handleUndoResponse(false)} + /> + + {gameState === 'playing' && ( + + {myPlayerIndex === currentTurn ? ( +
+
+

Your Turn!

+

Draw a line

+
+ ) : ( +
+
+

+ Waiting for {players[currentTurn]?.name}... +

+ {lastMove && players.length > 1 && myPlayerIndex === (currentTurn + 1) % players.length && ( + + Request Undo + + )} +
+ )} + + )} - {gameState === 'playing' && !isPaused && ( -
- {currentTurn === myPlayerIndex ? ( - Your turn! - ) : ( - Waiting for {players[currentTurn]?.name}... - )} -
- )} - {isPaused && ( -
- Game Paused — Waiting for players to reconnect -
- )} - {gameState === 'ended' && ( -
- Game Over! -
- )} - {gameState === 'ended' && ( - - Play Again - - )} -
+ {isPaused && ( + +

Game Paused

+

Waiting for players to reconnect

+
+ )} +
-
- - {({ zoomIn, zoomOut, resetTransform }) => ( - <> -
- - - -
- -
- + + {svgWidth > 0 && svgHeight > 0 ? ( + - {boxes.map((row, r) => - row.map((boxOwner, c) => - boxOwner !== null ? ( - - ) : null - ) + {({ zoomIn, zoomOut, resetTransform }) => ( + <> +
+ + + +
+ +
+ + + + + + + + + + + {boxes.map((row, r) => + row.map((boxOwner, c) => + boxOwner !== null ? ( + + + + + ) : null, + ), + )} + + {Array.from({ length: rows + 1 }, (_, r) => + Array.from({ length: cols }, (_, c) => { + const owner = horizontalLines[r]?.[c]; + const seed = r * 100 + c; + const isLastMoveLine = + lastMove && lastMove.lineType === 'h' && lastMove.r === r && lastMove.c === c; + return ( + + {owner !== null && ( + + )} + { + e.stopPropagation(); + handleLineClick('h', r, c); + }} + /> + + ); + }), + )} + + {Array.from({ length: rows }, (_, r) => + Array.from({ length: cols + 1 }, (_, c) => { + const owner = verticalLines[r]?.[c]; + const seed = r * 100 + c + 1000; + const isLastMoveLine = + lastMove && lastMove.lineType === 'v' && lastMove.r === r && lastMove.c === c; + return ( + + {owner !== null && ( + + )} + { + e.stopPropagation(); + handleLineClick('v', r, c); + }} + /> + + ); + }), + )} + + {Array.from({ length: rows + 1 }, (_, r) => + Array.from({ length: cols + 1 }, (_, c) => { + const seed = r * 1000 + c; + const offsetX = Math.sin(seed * 0.1) * 0.5; + const offsetY = Math.cos(seed * 0.1) * 0.5; + return ( + + ); + }), + )} + +
+
+ )} - - {Array.from({ length: rows + 1 }, (_, r) => - Array.from({ length: cols }, (_, c) => { - const owner = horizontalLines[r]?.[c]; - return ( - - {owner !== null && ( - - )} - handleLineClick('h', r, c, e)} - /> - - ); - }) - )} - - {Array.from({ length: rows }, (_, r) => - Array.from({ length: cols + 1 }, (_, c) => { - const owner = verticalLines[r]?.[c]; - return ( - - {owner !== null && ( - - )} - handleLineClick('v', r, c, e)} - /> - - ); - }) - )} - - {Array.from({ length: rows + 1 }, (_, r) => - Array.from({ length: cols + 1 }, (_, c) => ( - - )) - )} - -
-
- - )} -
+ + ) : ( +
+

Loading...

+
+ )} + +
- )} -
+
+ + + ); }; diff --git a/pro/src/dab/DabGame.test.jsx b/pro/src/dab/DabGame.test.jsx new file mode 100644 index 0000000..ea0a575 --- /dev/null +++ b/pro/src/dab/DabGame.test.jsx @@ -0,0 +1,232 @@ +import React from 'react'; +import { render, screen, fireEvent, act } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import DabGame from './DabGame'; +import { GameProvider } from '../context/GameContext'; +import { ThemeProvider } from '../context/ThemeContext'; +import { BrowserRouter } from 'react-router-dom'; + +const mockSocket = { + id: 'p1', + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + disconnect: vi.fn(), +}; + +vi.mock('socket.io-client', () => ({ default: () => mockSocket })); +vi.mock('use-sound', () => ({ default: () => [vi.fn()] })); +vi.mock('canvas-confetti', () => ({ default: vi.fn() })); +vi.mock('sweetalert2', () => ({ default: { fire: vi.fn().mockResolvedValue({ isConfirmed: true }) } })); +vi.mock('react-zoom-pan-pinch', () => ({ + TransformWrapper: ({ children }) => children({ zoomIn: vi.fn(), zoomOut: vi.fn(), resetTransform: vi.fn() }), + TransformComponent: ({ children }) => <>{children}, +})); + +const Wrapper = ({ children }) => ( + + + {children} + + +); + +const findEventCb = (event) => { + const call = mockSocket.on.mock.calls.find((c) => c[0] === event); + return call?.[1]; +}; + +const makePlayingRoomInfo = (overrides = {}) => ({ + id: 'DAB01', + creator: 'p1', + players: [ + { id: 'p1', name: 'Alice', connected: true }, + { id: 'p2', name: 'Bob', connected: true }, + ], + gameState: 'playing', + currentTurn: 0, + rows: 9, + cols: 9, + horizontalLines: Array(10) + .fill(null) + .map(() => Array(9).fill(null)), + verticalLines: Array(9) + .fill(null) + .map(() => Array(10).fill(null)), + boxes: Array(9) + .fill(null) + .map(() => Array(9).fill(null)), + scores: [0, 0], + lastMove: null, + mode: 'classic', + ...overrides, +}); + +describe('DabGame', () => { + beforeEach(() => { + vi.clearAllMocks(); + sessionStorage.clear(); + }); + + describe('Lobby - No Room', () => { + it('shows Start Game and Join Room buttons', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText('Start Game')).toBeTruthy(); + expect(screen.getByText('Join Room')).toBeTruthy(); + }); + + it('emits dab_startGame when Start Game is clicked', async () => { + render(, { wrapper: Wrapper }); + await act(async () => { + fireEvent.click(screen.getByText('Start Game')); + }); + expect(mockSocket.emit).toHaveBeenCalledWith('dab_startGame', expect.objectContaining({ rows: 9, cols: 9 })); + }); + }); + + describe('Mode Selection', () => { + it('shows Classic, Extended, and Marathon mode buttons', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText('Classic')).toBeTruthy(); + expect(screen.getByText('Extended')).toBeTruthy(); + expect(screen.getByText('Marathon')).toBeTruthy(); + }); + + it('switches mode when Extended is clicked', async () => { + render(, { wrapper: Wrapper }); + await act(async () => { + fireEvent.click(screen.getByText('Extended')); + }); + await act(async () => { + fireEvent.click(screen.getByText('Start Game')); + }); + expect(mockSocket.emit).toHaveBeenCalledWith('dab_startGame', expect.objectContaining({ rows: 14, cols: 14 })); + }); + }); + + describe('Playing State', () => { + it('shows player scores when playing', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo()); + }); + + expect(screen.getByText(/Alice/)).toBeTruthy(); + expect(screen.getByText(/Bob/)).toBeTruthy(); + }); + + it('shows "Your Turn!" when it is my turn', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo({ currentTurn: 0 })); + }); + + expect(screen.getByText('Your Turn!')).toBeTruthy(); + }); + }); + + describe('Avatar Selector', () => { + it('shows avatar picker in the lobby', () => { + render(, { wrapper: Wrapper }); + // Avatar selector shows icons in colored circles, not emojis anymore + const avatarButtons = screen.getAllByRole('button').filter((b) => b.querySelector('svg')); + expect(avatarButtons.length).toBeGreaterThan(0); + }); + }); + + describe('Game Over', () => { + it('shows Game Over text and Play Again button', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo()); + }); + + const gameOverCb = findEventCb('dab_gameOver'); + await act(async () => { + gameOverCb({ winner: 'p1', scores: [5, 3], winners: ['p1'] }); + }); + + expect(screen.getByText('Rematch')).toBeTruthy(); + }); + + it('emits dab_restartGame when Rematch is clicked', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo()); + }); + + const gameOverCb = findEventCb('dab_gameOver'); + await act(async () => { + gameOverCb({ winner: 'p1', scores: [5, 3], winners: ['p1'] }); + }); + + const rematchBtn = screen.getByText('Rematch'); + await act(async () => { + fireEvent.click(rematchBtn); + }); + + expect(mockSocket.emit).toHaveBeenCalledWith('dab_restartGame', expect.any(String)); + }); + }); + + describe('Redo Flow', () => { + it('shows redo request when dab_redoRequested is received', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo({ currentTurn: 0 })); + }); + + const redoCb = findEventCb('dab_redoRequested'); + await act(async () => { + redoCb({ requesterId: 'p2' }); + }); + + expect(screen.getByText(/wants to undo/)).toBeTruthy(); + }); + + it('shows Allow and Deny buttons when I am the current turn', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo({ currentTurn: 0 })); + }); + + const redoCb = findEventCb('dab_redoRequested'); + await act(async () => { + redoCb({ requesterId: 'p2' }); + }); + + expect(screen.getByText('Allow')).toBeTruthy(); + expect(screen.getByText('Deny')).toBeTruthy(); + }); + }); + + describe('Pause', () => { + it('shows Game Paused message when dab_gamePaused is received', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('dab_roomInfo'); + await act(async () => { + cb(makePlayingRoomInfo()); + }); + + const pauseCb = findEventCb('dab_gamePaused'); + await act(async () => { + pauseCb(); + }); + + expect(screen.getByText(/Game Paused/)).toBeTruthy(); + }); + }); +}); diff --git a/pro/src/dab/DabPreGame.jsx b/pro/src/dab/DabPreGame.jsx new file mode 100644 index 0000000..df717a4 --- /dev/null +++ b/pro/src/dab/DabPreGame.jsx @@ -0,0 +1,126 @@ +import React, { useCallback } from 'react'; +import { SketchButton, SketchCard, sketchPopupClass, AvatarSelector } from '../components/ui'; +import Swal from 'sweetalert2'; + +const DabPreGame = ({ + profile, + setProfile, + mode, + setMode, + customRows, + setCustomRows, + customCols, + setCustomCols, + onStart, + onJoin, +}) => { + const sizeMap = { classic: 9, extended: 14, marathon: 19 }; + const gameRows = mode === 'custom' ? customRows : sizeMap[mode] || 9; + const gameCols = mode === 'custom' ? customCols : sizeMap[mode] || 9; + + const handleStart = useCallback(() => { + onStart({ rows: gameRows, cols: gameCols }); + }, [gameRows, gameCols, onStart]); + + const handleJoin = useCallback(async () => { + const { value: joinRoomId } = await Swal.fire({ + title: 'Join DAB Room', + input: 'text', + inputPlaceholder: 'Enter Room ID', + showCancelButton: true, + customClass: { popup: sketchPopupClass }, + }); + if (joinRoomId) onJoin(joinRoomId.trim().toUpperCase()); + }, [onJoin]); + + return ( +
+ + setProfile((prev) => ({ ...prev, name: e.target.value }))} + placeholder="Enter your name" + className="w-full sketch-border font-handwriting text-ink px-3 py-2 rounded mb-4" + /> + setProfile((prev) => ({ ...prev, avatarIcon: icon }))} + onColorChange={(color) => setProfile((prev) => ({ ...prev, color }))} + /> + + + +
+

Game Mode

+
+ setMode('classic')} className={mode === 'classic' ? 'bg-ink text-white' : ''}> + Classic + + setMode('extended')} + className={mode === 'extended' ? 'bg-ink text-white' : ''} + > + Extended + + setMode('marathon')} + className={mode === 'marathon' ? 'bg-ink text-white' : ''} + > + Marathon + +
+ setMode('custom')} + className={`w-full mt-2 ${mode === 'custom' ? 'bg-ink text-white' : ''}`} + > + Custom Size + +
+ + {mode === 'custom' && ( +
+
+ + setCustomRows(Number(e.target.value))} + className="w-full" + /> +
+
+ + setCustomCols(Number(e.target.value))} + className="w-full" + /> +
+
+ )} + +

+ Selected size: {gameRows} × {gameCols} +

+ +
+ + Start Game + + + Join Room + +
+
+
+ ); +}; + +export default DabPreGame; diff --git a/pro/src/hooks/useAnimationVariants.js b/pro/src/hooks/useAnimationVariants.js new file mode 100644 index 0000000..0897ada --- /dev/null +++ b/pro/src/hooks/useAnimationVariants.js @@ -0,0 +1,117 @@ +// Stagger container for animating children sequentially +export const useStaggerContainer = (staggerChildren = 0.1, delayChildren = 0) => ({ + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren, + delayChildren, + }, + }, +}); + +// Item variants for use within stagger containers +export const useStaggerItem = () => ({ + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.4 }, + }, +}); + +// Fade in animation +export const useFadeIn = (duration = 0.4, delay = 0) => ({ + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { duration, delay }, + }, +}); + +// Slide in from left +export const useSlideInLeft = (duration = 0.4, delay = 0) => ({ + hidden: { opacity: 0, x: -50 }, + visible: { + opacity: 1, + x: 0, + transition: { duration, delay, ease: 'easeOut' }, + }, +}); + +// Slide in from right +export const useSlideInRight = (duration = 0.4, delay = 0) => ({ + hidden: { opacity: 0, x: 50 }, + visible: { + opacity: 1, + x: 0, + transition: { duration, delay, ease: 'easeOut' }, + }, +}); + +// Scale and fade in +export const useScaleIn = (duration = 0.4, delay = 0) => ({ + hidden: { opacity: 0, scale: 0.8 }, + visible: { + opacity: 1, + scale: 1, + transition: { duration, delay, ease: 'easeOut' }, + }, +}); + +// Bounce in +export const useBounceIn = (duration = 0.6, delay = 0) => ({ + hidden: { opacity: 0, scale: 0.3 }, + visible: { + opacity: 1, + scale: 1, + transition: { duration, delay, type: 'spring', stiffness: 300, damping: 20 }, + }, +}); + +// Rotate in +export const useRotateIn = (duration = 0.4, delay = 0) => ({ + hidden: { opacity: 0, rotate: -180 }, + visible: { + opacity: 1, + rotate: 0, + transition: { duration, delay, ease: 'easeOut' }, + }, +}); + +// Pulse animation for continuous effect +export const usePulse = () => ({ + animate: { + opacity: [1, 0.5, 1], + transition: { + duration: 2, + repeat: Infinity, + ease: 'easeInOut', + }, + }, +}); + +// Float animation (gentle up and down) +export const useFloat = (distance = 10) => ({ + animate: { + y: [0, -distance, 0], + transition: { + duration: 3, + repeat: Infinity, + ease: 'easeInOut', + }, + }, +}); + +// Shake animation +export const useShake = () => ({ + animate: { + x: [0, -10, 10, -10, 10, 0], + transition: { + duration: 0.5, + type: 'spring', + stiffness: 500, + damping: 8, + }, + }, +}); diff --git a/pro/src/hooks/useGameHandlers.js b/pro/src/hooks/useGameHandlers.js new file mode 100644 index 0000000..dea1ce2 --- /dev/null +++ b/pro/src/hooks/useGameHandlers.js @@ -0,0 +1,57 @@ +import { useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; +import Swal from 'sweetalert2'; +import { sketchPopupClass } from '../components/ui'; + +const useGameHandlers = (socket, roomId, gamePrefix, options = {}) => { + const navigate = useNavigate(); + const { onLeave, softLeave = false } = options; + + const handleCreateRoom = useCallback( + (options) => { + if (!socket) return; + socket.emit(`${gamePrefix}_createRoom`, options); + }, + [socket, gamePrefix], + ); + + const handleJoinRoom = useCallback( + (options) => { + if (!socket) return; + socket.emit(`${gamePrefix}_joinRoom`, options); + }, + [socket, gamePrefix], + ); + + const handleStartGame = useCallback(() => { + if (!socket) return; + socket.emit(`${gamePrefix}_startGame`, roomId); + }, [socket, gamePrefix, roomId]); + + const handleLeaveRoom = useCallback(async () => { + const result = await Swal.fire({ + title: 'Leave Game?', + text: 'Your progress will be lost.', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Leave', + cancelButtonText: 'Stay', + customClass: { popup: sketchPopupClass }, + }); + if (!result.isConfirmed) return; + + if (softLeave && roomId) { + socket?.emit(`${gamePrefix}_leaveRoom`, roomId); + } + + onLeave?.(); + if (!softLeave) { + socket?.disconnect(); + } + navigate('/'); + }, [socket, navigate, roomId, gamePrefix, onLeave, softLeave]); + + return { handleCreateRoom, handleJoinRoom, handleStartGame, handleLeaveRoom }; +}; + +export default useGameHandlers; diff --git a/pro/src/hooks/useGameHandlers.test.js b/pro/src/hooks/useGameHandlers.test.js new file mode 100644 index 0000000..1c3be0b --- /dev/null +++ b/pro/src/hooks/useGameHandlers.test.js @@ -0,0 +1,73 @@ +import { renderHook, act } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import useGameHandlers from './useGameHandlers'; + +const mockSocket = { + emit: vi.fn(), + disconnect: vi.fn(), +}; + +const mockNavigate = vi.fn(); + +vi.mock('react-router-dom', () => ({ + useNavigate: () => mockNavigate, +})); + +vi.mock('sweetalert2', () => ({ + default: { + fire: vi.fn().mockResolvedValue({ isConfirmed: true }), + }, +})); + +describe('useGameHandlers', () => { + beforeEach(() => { + vi.clearAllMocks(); + sessionStorage.clear(); + }); + + it('handleCreateRoom emits _createRoom with options', () => { + const { result } = renderHook(() => useGameHandlers(mockSocket, 'room1', 'ttt')); + act(() => result.current.handleCreateRoom({ playerName: 'Alice' })); + expect(mockSocket.emit).toHaveBeenCalledWith('ttt_createRoom', { playerName: 'Alice' }); + }); + + it('handleJoinRoom emits _joinRoom with options', () => { + const { result } = renderHook(() => useGameHandlers(mockSocket, 'room1', 'ttt')); + act(() => result.current.handleJoinRoom({ roomId: 'ABC', playerName: 'Bob' })); + expect(mockSocket.emit).toHaveBeenCalledWith('ttt_joinRoom', { roomId: 'ABC', playerName: 'Bob' }); + }); + + it('handleStartGame emits _startGame with roomId', () => { + const { result } = renderHook(() => useGameHandlers(mockSocket, 'room1', 'ttt')); + act(() => result.current.handleStartGame()); + expect(mockSocket.emit).toHaveBeenCalledWith('ttt_startGame', 'room1'); + }); + + it('handleLeaveRoom shows confirmation and disconnects on confirm', async () => { + const { result } = renderHook(() => useGameHandlers(mockSocket, 'room1', 'ttt')); + await act(async () => { + await result.current.handleLeaveRoom(); + }); + expect(mockSocket.disconnect).toHaveBeenCalled(); + expect(mockNavigate).toHaveBeenCalledWith('/'); + }); + + it('handleLeaveRoom does nothing when user cancels', async () => { + const Swal = (await import('sweetalert2')).default; + Swal.fire.mockResolvedValueOnce({ isConfirmed: false }); + + const { result } = renderHook(() => useGameHandlers(mockSocket, 'room1', 'ttt')); + await act(async () => { + await result.current.handleLeaveRoom(); + }); + expect(mockSocket.disconnect).not.toHaveBeenCalled(); + expect(mockNavigate).not.toHaveBeenCalled(); + }); + + it('does not emit when socket is null', () => { + const { result } = renderHook(() => useGameHandlers(null, 'room1', 'ttt')); + act(() => result.current.handleCreateRoom({ playerName: 'Alice' })); + act(() => result.current.handleStartGame()); + expect(mockSocket.emit).not.toHaveBeenCalled(); + }); +}); diff --git a/pro/src/hooks/useLastMoveHighlight.js b/pro/src/hooks/useLastMoveHighlight.js new file mode 100644 index 0000000..f28bec1 --- /dev/null +++ b/pro/src/hooks/useLastMoveHighlight.js @@ -0,0 +1,25 @@ +import { useRef, useEffect } from 'react'; +import confetti from 'canvas-confetti'; + +export const useLastMoveHighlight = (lastMove, playerColor, celebrate = false) => { + const lastMoveRef = useRef(null); + + useEffect(() => { + if (lastMove && celebrate) { + const celebrationConfig = { + particleCount: 25, + spread: 35, + origin: { y: 0.6 }, + colors: [playerColor || '#2a2a3e'], + decay: 0.85, + gravity: 0.5, + }; + confetti(celebrationConfig); + lastMoveRef.current = lastMove; + } + }, [lastMove, playerColor, celebrate]); + + return { lastMoveRef }; +}; + +export default useLastMoveHighlight; diff --git a/pro/src/hooks/usePlayerAvatars.js b/pro/src/hooks/usePlayerAvatars.js new file mode 100644 index 0000000..70eb79a --- /dev/null +++ b/pro/src/hooks/usePlayerAvatars.js @@ -0,0 +1,24 @@ +import { useState, useEffect } from 'react'; + +const STORAGE_KEY = 'player_avatar'; + +const usePlayerAvatars = () => { + const saved = (() => { + try { + return JSON.parse(sessionStorage.getItem(STORAGE_KEY)) || {}; + } catch { + return {}; + } + })(); + + const [avatar, setAvatar] = useState(saved.avatar || '🐼'); + const [color, setColor] = useState(saved.color || '#2a2a3e'); + + useEffect(() => { + sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ avatar, color })); + }, [avatar, color]); + + return { avatar, color, setAvatar, setColor }; +}; + +export default usePlayerAvatars; diff --git a/pro/src/hooks/usePlayerAvatars.test.js b/pro/src/hooks/usePlayerAvatars.test.js new file mode 100644 index 0000000..a0e5774 --- /dev/null +++ b/pro/src/hooks/usePlayerAvatars.test.js @@ -0,0 +1,48 @@ +import { renderHook, act } from '@testing-library/react'; +import { describe, it, expect, beforeEach } from 'vitest'; +import usePlayerAvatars from './usePlayerAvatars'; + +describe('usePlayerAvatars', () => { + beforeEach(() => { + sessionStorage.clear(); + }); + + it('returns default avatar and color on first use', () => { + const { result } = renderHook(() => usePlayerAvatars()); + expect(result.current.avatar).toBe('🐼'); + expect(result.current.color).toBe('#2a2a3e'); + }); + + it('persists avatar to sessionStorage when setAvatar is called', () => { + const { result } = renderHook(() => usePlayerAvatars()); + act(() => { + result.current.setAvatar('🦊'); + }); + expect(result.current.avatar).toBe('🦊'); + const stored = JSON.parse(sessionStorage.getItem('player_avatar')); + expect(stored.avatar).toBe('🦊'); + }); + + it('persists color to sessionStorage when setColor is called', () => { + const { result } = renderHook(() => usePlayerAvatars()); + act(() => { + result.current.setColor('#ff0000'); + }); + expect(result.current.color).toBe('#ff0000'); + const stored = JSON.parse(sessionStorage.getItem('player_avatar')); + expect(stored.color).toBe('#ff0000'); + }); + + it('restores avatar and color from sessionStorage on mount', () => { + sessionStorage.setItem('player_avatar', JSON.stringify({ avatar: '🐯', color: '#123456' })); + const { result } = renderHook(() => usePlayerAvatars()); + expect(result.current.avatar).toBe('🐯'); + expect(result.current.color).toBe('#123456'); + }); + + it('exposes setAvatar and setColor functions', () => { + const { result } = renderHook(() => usePlayerAvatars()); + expect(typeof result.current.setAvatar).toBe('function'); + expect(typeof result.current.setColor).toBe('function'); + }); +}); diff --git a/pro/src/hooks/usePlayerProfile.js b/pro/src/hooks/usePlayerProfile.js new file mode 100644 index 0000000..9b62f65 --- /dev/null +++ b/pro/src/hooks/usePlayerProfile.js @@ -0,0 +1,65 @@ +import { useState, useEffect, useCallback } from 'react'; +import { Cat, Dog, Bird, Fish, Monkey, PawPrint, Frog, Ticket, Lion, Bear, Koala, Fox } from 'lucide-react'; + +export const AVATAR_ICONS = [ + { id: 'cat', Icon: Cat }, + { id: 'dog', Icon: Dog }, + { id: 'bird', Icon: Bird }, + { id: 'fish', Icon: Fish }, + { id: 'monkey', Icon: Monkey }, + { id: 'panda', Icon: PawPrint }, + { id: 'frog', Icon: Frog }, + { id: 'tiger', Icon: Ticket }, + { id: 'lion', Icon: Lion }, + { id: 'bear', Icon: Bear }, + { id: 'koala', Icon: Koala }, + { id: 'fox', Icon: Fox }, +]; + +export const PLAYER_COLORS = ['#2a2a3e', '#c73e1d', '#2d4a8f', '#2f5233', '#7b2d8f', '#b5651d']; + +export const usePlayerProfile = () => { + const [profile, setProfile] = useState(() => { + const saved = localStorage.getItem('playerProfile'); + return saved + ? JSON.parse(saved) + : { + name: localStorage.getItem('playerName') || '', + avatarIcon: 'cat', + color: '#2a2a3e', + }; + }); + + useEffect(() => { + localStorage.setItem('playerProfile', JSON.stringify(profile)); + }, [profile]); + + useEffect(() => { + if (profile.name) { + localStorage.setItem('playerName', profile.name); + } + }, [profile.name]); + + const setAvatarIcon = useCallback((icon) => { + setProfile((prev) => ({ ...prev, avatarIcon: icon })); + }, []); + + const setColor = useCallback((color) => { + setProfile((prev) => ({ ...prev, color })); + }, []); + + const setName = useCallback((name) => { + setProfile((prev) => ({ ...prev, name })); + }, []); + + return { + ...profile, + setAvatarIcon, + setColor, + setName, + AVATAR_ICONS, + PLAYER_COLORS, + }; +}; + +export default usePlayerProfile; diff --git a/pro/src/hooks/useReconnection.js b/pro/src/hooks/useReconnection.js new file mode 100644 index 0000000..aed56fa --- /dev/null +++ b/pro/src/hooks/useReconnection.js @@ -0,0 +1,80 @@ +import { useEffect, useRef, useCallback } from 'react'; + +const useReconnection = ({ socket, gamePrefix, onRestore, onReconnectFailure }) => { + const attemptedRef = useRef(false); + const reconnectAttemptsRef = useRef(0); + const lastDisconnectTimeRef = useRef(null); + + const clearReconnect = useCallback(() => { + sessionStorage.removeItem(`${gamePrefix}_reconnect`); + }, [gamePrefix]); + + const handleReconnectFailure = useCallback( + (reason, roomId) => { + reconnectAttemptsRef.current++; + if (onReconnectFailure) { + onReconnectFailure(reason, roomId); + } + }, + [onReconnectFailure], + ); + + useEffect(() => { + if (!socket) return; + + const key = `${gamePrefix}_reconnect`; + const saved = sessionStorage.getItem(key); + + if (saved && !attemptedRef.current) { + attemptedRef.current = true; + try { + const parsed = JSON.parse(saved); + if (!parsed.roomId || !parsed.playerId) { + clearReconnect(); + return; + } + socket.emit(`${gamePrefix}_reconnect`, { + roomId: parsed.roomId, + playerId: parsed.playerId, + }); + } catch { + clearReconnect(); + } + } + }, [socket, gamePrefix, clearReconnect]); + + useEffect(() => { + if (!socket) return; + + const handleRoomInfo = (room) => { + reconnectAttemptsRef.current = 0; + if (socket.id && room.players) { + const myPlayer = room.players.find((p) => p.id === socket.id) || room.players[room.currentTurn]; + if (myPlayer && onRestore) { + onRestore(room, myPlayer); + } + } + }; + + const handleReconnectFailed = ({ reason, roomId }) => { + reconnectAttemptsRef.current++; + + if (reason === 'room_not_found' || reason === 'player_not_found' || reason === 'game_already_ended') { + clearReconnect(); + } + + handleReconnectFailure(reason, roomId); + }; + + socket.on(`${gamePrefix}_roomInfo`, handleRoomInfo); + socket.on(`${gamePrefix}_reconnectFailed`, handleReconnectFailed); + return () => { + socket.off(`${gamePrefix}_roomInfo`, handleRoomInfo); + socket.off(`${gamePrefix}_reconnectFailed`, handleReconnectFailed); + }; + }, [socket, gamePrefix, onRestore, clearReconnect, handleReconnectFailure]); + + return { clearReconnect }; +}; + +export default useReconnection; diff --git a/pro/src/hooks/useSocketListeners.js b/pro/src/hooks/useSocketListeners.js new file mode 100644 index 0000000..cc9fc39 --- /dev/null +++ b/pro/src/hooks/useSocketListeners.js @@ -0,0 +1,37 @@ +import { useEffect, useRef } from 'react'; +import { reportRuntimeError } from '../utils/runtimeError'; + +const useSocketListeners = (socket, listeners = {}) => { + const listenersRef = useRef(listeners); + listenersRef.current = listeners; + + useEffect(() => { + if (!socket) return; + + const handlerMap = {}; + Object.entries(listenersRef.current).forEach(([event]) => { + const wrapped = (...args) => { + try { + const handler = listenersRef.current[event]; + if (!handler) return; + const result = handler(...args); + if (result && typeof result.then === 'function') { + result.catch((error) => reportRuntimeError(`Socket event ${event}`, error)); + } + } catch (error) { + reportRuntimeError(`Socket event ${event}`, error); + } + }; + handlerMap[event] = wrapped; + socket.on(event, wrapped); + }); + + return () => { + Object.entries(handlerMap).forEach(([event, handler]) => { + socket.off(event, handler); + }); + }; + }, [socket]); +}; + +export default useSocketListeners; diff --git a/pro/src/hooks/useTurnTimer.js b/pro/src/hooks/useTurnTimer.js new file mode 100644 index 0000000..9781ec4 --- /dev/null +++ b/pro/src/hooks/useTurnTimer.js @@ -0,0 +1,29 @@ +import { useState, useEffect, useRef } from 'react'; + +const useTurnTimer = (isMyTurn, duration = 30, onExpire) => { + const [timeLeft, setTimeLeft] = useState(duration); + const expireRef = useRef(onExpire); + expireRef.current = onExpire; + + useEffect(() => { + setTimeLeft(duration); + if (!isMyTurn) return; + + const interval = setInterval(() => { + setTimeLeft((prev) => { + if (prev <= 1) { + clearInterval(interval); + expireRef.current?.(); + return 0; + } + return prev - 1; + }); + }, 1000); + + return () => clearInterval(interval); + }, [isMyTurn, duration]); + + return timeLeft; +}; + +export default useTurnTimer; diff --git a/pro/src/hooks/useTurnTimer.test.js b/pro/src/hooks/useTurnTimer.test.js new file mode 100644 index 0000000..e3eb909 --- /dev/null +++ b/pro/src/hooks/useTurnTimer.test.js @@ -0,0 +1,61 @@ +import { renderHook, act } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import useTurnTimer from './useTurnTimer'; + +describe('useTurnTimer', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + afterEach(() => { + vi.useRealTimers(); + }); + + it('returns full duration initially when isMyTurn is true', () => { + const { result } = renderHook(() => useTurnTimer(true, 30, vi.fn())); + expect(result.current).toBe(30); + }); + + it('returns full duration when isMyTurn is false', () => { + const { result } = renderHook(() => useTurnTimer(false, 30, vi.fn())); + expect(result.current).toBe(30); + }); + + it('counts down each second when isMyTurn is true', () => { + const { result } = renderHook(() => useTurnTimer(true, 30, vi.fn())); + act(() => { + vi.advanceTimersByTime(3000); + }); + expect(result.current).toBe(27); + }); + + it('does not count down when isMyTurn is false', () => { + const { result } = renderHook(() => useTurnTimer(false, 30, vi.fn())); + act(() => { + vi.advanceTimersByTime(5000); + }); + expect(result.current).toBe(30); + }); + + it('calls onExpire when timer reaches 0', () => { + const onExpire = vi.fn(); + renderHook(() => useTurnTimer(true, 3, onExpire)); + act(() => { + vi.advanceTimersByTime(3000); + }); + expect(onExpire).toHaveBeenCalledTimes(1); + }); + + it('resets timer when isMyTurn changes to true', () => { + const { result, rerender } = renderHook(({ isMyTurn }) => useTurnTimer(isMyTurn, 10, vi.fn()), { + initialProps: { isMyTurn: true }, + }); + act(() => { + vi.advanceTimersByTime(4000); + }); + expect(result.current).toBe(6); + + rerender({ isMyTurn: false }); + rerender({ isMyTurn: true }); + expect(result.current).toBe(10); + }); +}); diff --git a/pro/src/index.css b/pro/src/index.css index eb99b9a..e0e7023 100644 --- a/pro/src/index.css +++ b/pro/src/index.css @@ -1,4 +1,4 @@ -@import "tailwindcss"; +@import 'tailwindcss'; @theme { --font-hand-drawn: 'Permanent Marker', cursive; @@ -13,6 +13,180 @@ font-family: var(--font-paper); } +.font-sketch { + font-family: 'Caveat', cursive; + letter-spacing: 0.5px; +} + +.font-handwriting { + font-family: 'Patrick Hand', cursive; +} + +.text-ink { + color: #2a2a3e; +} + +.bg-paper { + background-color: #f5f1e8; + background-image: repeating-linear-gradient( + 0deg, + transparent, + transparent 30px, + rgba(139, 99, 76, 0.05) 30px, + rgba(139, 99, 76, 0.05) 31px + ); + position: relative; +} + +.bg-paper::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E"); + pointer-events: none; + z-index: 0; +} + +.sketch-card { + background: #fffef9; + border: 2px solid #2a2a3e; + border-radius: 3px; + box-shadow: + 3px 3px 0px rgba(0, 0, 0, 0.1), + inset 0 0 0 1px rgba(255, 255, 255, 0.5); + position: relative; + transform: rotate(-0.5deg); +} + +.sketch-card::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + border: 2px solid #2a2a3e; + border-radius: 3px; + opacity: 0.3; + transform: translate(1px, 1px); + pointer-events: none; +} + +.sketch-border { + border: 2px dashed #8b7355; + border-radius: 2px; + background: rgba(255, 254, 249, 0.6); + padding: 1rem; +} + +.sketch-button { + font-family: 'Patrick Hand', cursive; + background: #fffef9; + border: 2px solid #2a2a3e; + padding: 0.5rem 1rem; + border-radius: 2px; + cursor: pointer; + position: relative; + transform: rotate(-0.3deg); + transition: all 0.2s; + box-shadow: 2px 2px 0px rgba(0, 0, 0, 0.2); +} + +.sketch-button:hover { + transform: rotate(0deg) translateY(-2px); + box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2); +} + +.sketch-button:active { + transform: rotate(0deg) translateY(0); + box-shadow: 1px 1px 0px rgba(0, 0, 0, 0.2); +} + +.player-badge { + display: inline-block; + padding: 0.25rem 0.75rem; + border: 2px solid currentColor; + border-radius: 20px; + font-family: 'Patrick Hand', cursive; + transform: rotate(-1deg); + position: relative; +} + +.player-badge::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 2px solid currentColor; + border-radius: 20px; + opacity: 0.3; + transform: translate(1px, 1px); +} + +.sketch-popup { + font-family: 'Patrick Hand', cursive !important; + background: #fffef9 !important; + border: 3px solid #2a2a3e !important; + border-radius: 5px !important; +} + +.sketch-dot { + animation: sketch-wiggle 3s ease-in-out infinite; +} + +@keyframes sketch-wiggle { + 0%, + 100% { + transform: rotate(0deg) translateY(0); + } + 25% { + transform: rotate(0.5deg) translateY(-1px); + } + 75% { + transform: rotate(-0.5deg) translateY(1px); + } +} + +@keyframes wiggle { + 0%, + 100% { + transform: rotate(-1deg); + } + 50% { + transform: rotate(1deg); + } +} + +@keyframes pencil-scribble { + 0% { + filter: brightness(1); + } + 50% { + filter: brightness(1.2) contrast(1.1); + } + 100% { + filter: brightness(1); + } +} + +@keyframes screen-shake { + 0%, + 100% { + transform: translate(0); + } + 25% { + transform: translate(-2px, 2px); + } + 75% { + transform: translate(2px, -2px); + } +} + .glass { background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(10px); @@ -21,22 +195,57 @@ } body { - background: - linear-gradient(rgba(255,255,255,0.9), rgba(255,255,255,0.9)), - repeating-linear-gradient( - 0deg, - transparent, - transparent 19px, - #e5e7eb 19px, - #e5e7eb 20px - ), - repeating-linear-gradient( - 90deg, - transparent, - transparent 19px, - #e5e7eb 19px, - #e5e7eb 20px - ); + background: + linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.9)), + repeating-linear-gradient(0deg, transparent, transparent 19px, #e5e7eb 19px, #e5e7eb 20px), + repeating-linear-gradient(90deg, transparent, transparent 19px, #e5e7eb 19px, #e5e7eb 20px); background-size: 20px 20px; min-height: 100vh; -} \ No newline at end of file +} + +[data-theme='dark'] .text-ink { + color: #e5e7eb; +} + +[data-theme='dark'] .bg-paper { + background-color: #1a1a2e; + background-image: repeating-linear-gradient( + 0deg, + transparent, + transparent 30px, + rgba(229, 231, 235, 0.03) 30px, + rgba(229, 231, 235, 0.03) 31px + ); +} + +[data-theme='dark'] .sketch-card { + background: #252542; + border: 2px solid #e5e7eb; +} + +[data-theme='dark'] .sketch-card::before { + border: 2px solid #e5e7eb; +} + +[data-theme='dark'] .sketch-button { + background: #252542; + border: 2px solid #e5e7eb; + color: #e5e7eb; +} + +[data-theme='dark'] .glass { + background: rgba(37, 37, 66, 0.7); + border: 1px solid rgba(229, 231, 235, 0.2); +} + +[data-theme='dark'] .player-badge { + color: #e5e7eb; +} + +[data-theme='dark'] .font-sketch { + color: #e5e7eb; +} + +[data-theme='dark'] .font-handwriting { + color: #d1d5e0; +} diff --git a/pro/src/index.jsx b/pro/src/index.jsx index dd56628..cc27e3a 100644 --- a/pro/src/index.jsx +++ b/pro/src/index.jsx @@ -2,13 +2,24 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; +import ErrorBoundary from './components/ErrorBoundary'; +import NotificationProvider from './components/NotificationProvider'; +import RuntimeErrorProvider from './components/RuntimeErrorProvider'; import { GameProvider } from './context/GameContext'; +import { ThemeProvider } from './context/ThemeContext'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - - - - + + + + + + + + + + + , ); diff --git a/pro/src/sos/SOSGame.jsx b/pro/src/sos/SOSGame.jsx new file mode 100644 index 0000000..3953038 --- /dev/null +++ b/pro/src/sos/SOSGame.jsx @@ -0,0 +1,362 @@ +import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { useGameContext } from '../context/GameContext'; +import { useNavigate } from 'react-router-dom'; +import GameLayout from '../components/ui/GameLayout'; +import GameLobby from '../components/ui/GameLobby'; +import MatchReport from '../components/ui/MatchReport'; +import SketchButton from '../components/ui/SketchButton'; +import TurnIndicator from '../components/ui/TurnIndicator'; +import { sketchPopupClass, AvatarSelector } from '../components/ui'; +import useSocketListeners from '../hooks/useSocketListeners'; +import useReconnection from '../hooks/useReconnection'; +import Swal from 'sweetalert2'; + +const SOSGame = () => { + const { socket, playerName, roomId, setRoomId, clearRoomId, setGamePrefix, profile, setProfile } = useGameContext(); + const navigate = useNavigate(); + const [gameState, setGameState] = useState('lobby'); + const [players, setPlayers] = useState([]); + const [spectators, setSpectators] = useState([]); + const [currentTurn, setCurrentTurn] = useState(null); + const [selectedSymbol, setSelectedSymbol] = useState('S'); + const [flashCells, setFlashCells] = useState([]); + const [desiredSize, setDesiredSize] = useState(6); + const [board, setBoard] = useState([]); + const [myPlayerIndex, setMyPlayerIndex] = useState(-1); + const joinRoomIdRef = useRef(''); + const roomLoadedRef = useRef(false); + + const handleCreateRoom = useCallback(() => { + if (!socket) return; + socket.emit('sos_createRoom', { + playerName: profile.name || playerName, + avatarIcon: profile.avatarIcon, + color: profile.color, + size: desiredSize, + }); + }, [socket, profile, playerName, desiredSize]); + + const handleJoinRoom = useCallback( + (roomIdToJoin, asSpectator) => { + if (!socket) return; + socket.emit('sos_joinRoom', { + roomId: roomIdToJoin, + playerName: profile.name || playerName, + avatarIcon: profile.avatarIcon, + color: profile.color, + asSpectator, + }); + }, + [socket, profile, playerName], + ); + + const { clearReconnect } = useReconnection({ + socket, + gamePrefix: 'sos', + roomId, + onRestore: (room, myPlayer) => { + if (!room) return; + setRoomId(room.id); + setPlayers(room.players || []); + setSpectators(room.spectators || []); + setGameState(room.gameState || 'lobby'); + setCurrentTurn(room.currentTurn); + setBoard(room.board || []); + setMyPlayerIndex(myPlayer ? (room.players || []).findIndex((p) => p.id === myPlayer.id) : -1); + }, + }); + + useSocketListeners( + socket, + { + sos_roomInfo: (data) => { + roomLoadedRef.current = true; + setRoomId(data.id); + setPlayers(data.players || []); + setSpectators(data.spectators || []); + setGameState(data.gameState); + setCurrentTurn(data.currentTurn); + setBoard(data.board || []); + const myPlayer = data.players?.find((p) => p.id === socket.id); + setMyPlayerIndex(myPlayer ? data.players.findIndex((p) => p.id === myPlayer.id) : -1); + }, + sos_gameStarted: () => { + setGameState('playing'); + }, + sos_moveMade: (data) => { + setBoard(data.board || []); + if (data.patterns && data.patterns.length > 0) { + const cells = data.patterns.flatMap((p) => p.cells.map((c) => `${c.row}-${c.col}`)); + setFlashCells(cells); + setTimeout(() => setFlashCells([]), 2000); + } + }, + sos_gameOver: () => { + setGameState('ended'); + }, + sos_gamePaused: () => { + setGameState('paused'); + }, + sos_gameRestarted: () => { + setGameState('waiting'); + setSelectedSymbol('S'); + setBoard([]); + }, + sos_alert: ({ icon, title, text }) => { + Swal.fire({ icon, title, text }); + }, + sos_reconnectFailed: ({ reason, roomId: failedRoomId }) => { + Swal.fire({ + title: 'Reconnection Failed', + text: + reason === 'room_not_found' + ? 'The room no longer exists.' + : reason === 'player_not_found' + ? 'Your player session was not found.' + : reason === 'game_already_ended' + ? 'The game has ended.' + : 'Could not reconnect to the game.', + icon: 'error', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(); + navigate('/'); + }); + }, + server_shutdown: ({ message }) => { + Swal.fire({ + title: 'Server Shutting Down', + text: message || 'The server is going down for maintenance.', + icon: 'info', + customClass: { popup: sketchPopupClass }, + }).then(() => { + sessionStorage.removeItem('sos_reconnect'); + clearRoomId(); + navigate('/'); + }); + }, + }, + [clearRoomId, navigate, setRoomId], + ); + + useEffect(() => { + if (!socket) return; + setGamePrefix('sos'); + + const saved = sessionStorage.getItem('sos_reconnect'); + if (saved && !roomLoadedRef.current) { + roomLoadedRef.current = true; + const data = JSON.parse(saved); + socket.emit('sos_reconnect', data); + } + }, [socket, setGamePrefix]); + + const handleStartGame = useCallback(() => { + if (!socket || !roomId) return; + socket.emit('sos_startGame', { roomId }); + }, [socket, roomId]); + + const handleRestart = useCallback(() => { + if (!socket || !roomId) return; + socket.emit('sos_restartGame', roomId); + }, [socket, roomId]); + + const handleLeave = useCallback(() => { + if (!socket || !roomId) return; + socket.emit('sos_leaveRoom', roomId); + clearReconnect(); + clearRoomId(); + setGameState('lobby'); + navigate('/'); + }, [socket, roomId, clearReconnect, clearRoomId, navigate]); + + const handleCellClick = useCallback( + (row, col) => { + if (!roomId || gameState !== 'playing') return; + if (myPlayerIndex !== currentTurn) return; + if (board[row]?.[col] !== null) return; + + socket.emit('sos_makeMove', { roomId, row, col, value: selectedSymbol }); + }, + [roomId, gameState, myPlayerIndex, currentTurn, board, selectedSymbol, socket], + ); + + const isSpectator = spectators.some((s) => s.id === socket?.id); + const isHost = players[0]?.id === socket?.id; + + if (gameState === 'ended') { + const scores = players.map((p, idx) => ({ + name: p.name || `Player ${idx + 1}`, + score: p.score || 0, + })); + return ( + + ); + } + + if (roomId && gameState === 'waiting') { + return ( + setProfile(next)} + /> + ); + } + + if (roomId && gameState === 'playing') { + const size = board.length || desiredSize; + return ( + +
+ {isSpectator && ( +
+ 👁️ Spectating +
+ )} + +
+ Moves: {board.flat().filter((c) => c).length} / {size * size} +
+
+ {board.map((row, r) => + row.map((cell, c) => { + const isFlashing = flashCells.includes(`${r}-${c}`); + return ( + + ); + }), + )} +
+ + {!isSpectator && ( +
+ setSelectedSymbol('S')} + style={{ background: selectedSymbol === 'S' ? '#fee2e2' : '#fff' }} + > + S + + setSelectedSymbol('O')} + style={{ background: selectedSymbol === 'O' ? '#dbeafe' : '#fff' }} + > + O + +
+ )} + + + Leave Room + +
+
+ ); + } + + return ( +
+
+

SOS

+ +
+ + setProfile((prev) => ({ ...prev, name: e.target.value }))} + placeholder="Enter name" + className="sketch-input w-full mt-1" + maxLength={20} + /> +
+ +
+ + +
+ + setProfile((prev) => ({ ...prev, avatarIcon: icon }))} + onColorChange={(c) => setProfile((prev) => ({ ...prev, color: c }))} + /> + + + Create Room + + +
+ + { + if (e.key === 'Enter') { + const roomId = e.target.value.trim(); + if (roomId && profile.name) handleJoinRoom(roomId); + } + }} + /> + { + const roomIdInput = joinRoomIdRef.current?.value || ''; + if (roomIdInput && profile.name) handleJoinRoom(roomIdInput.trim()); + }} + className="w-full" + > + Join as Player + + { + const roomIdInput = joinRoomIdRef.current?.value || ''; + if (roomIdInput && profile.name) handleJoinRoom(roomIdInput.trim(), true); + }} + className="w-full mt-2" + style={{ background: '#f0f8ff' }} + > + Join as Spectator + +
+
+
+ ); +}; + +export default SOSGame; diff --git a/pro/src/sos/SOSGame.test.jsx b/pro/src/sos/SOSGame.test.jsx new file mode 100644 index 0000000..d3c6fe9 --- /dev/null +++ b/pro/src/sos/SOSGame.test.jsx @@ -0,0 +1,71 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import SOSGame from './SOSGame'; +import { ThemeProvider } from '../context/ThemeContext'; + +vi.mock('socket.io-client', () => ({ + io: vi.fn(() => ({ + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + connected: true, + })), +})); + +vi.mock('../context/GameContext', () => ({ + useGameContext: () => ({ + socket: { + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + }, + playerName: 'TestPlayer', + setPlayerName: vi.fn(), + roomId: null, + setRoomId: vi.fn(), + clearRoomId: vi.fn(), + gamePrefix: null, + setGamePrefix: vi.fn(), + leaveRoom: vi.fn(), + clearReconnect: vi.fn(), + profile: { name: 'TestPlayer', avatarIcon: 'cat', color: '#2a2a3e' }, + setProfile: vi.fn(), + }), +})); + +vi.mock('use-sound', () => ({ + default: vi.fn(() => [vi.fn()]), +})); + +vi.mock('canvas-confetti', () => ({ + default: vi.fn(), +})); + +vi.mock('sweetalert2', () => ({ + fire: vi.fn(), +})); + +const Wrapper = ({ children }) => ( + + {children} + +); + +describe('SOSGame', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('renders landing UI when not in room', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText('SOS')).toBeInTheDocument(); + expect(screen.getByPlaceholderText('Enter name')).toBeInTheDocument(); + }); + + it('has board size selector', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText(/Board Size/)).toBeInTheDocument(); + }); +}); diff --git a/pro/src/store/avatarStore.js b/pro/src/store/avatarStore.js new file mode 100644 index 0000000..18cd36e --- /dev/null +++ b/pro/src/store/avatarStore.js @@ -0,0 +1,76 @@ +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; + +// Avatar styles from dicebear +export const AVATAR_STYLES = [ + 'adventurer', + 'adventurer-neutral', + 'avataaars', + 'avataaars-neutral', + 'big-ears', + 'big-smile', + 'bottts', + 'bottts-neutral', + 'croodles', + 'croodles-neutral', + 'micah', + 'notionists', + 'open-peeps', + 'personas', + 'pixel-art', + 'pixel-art-neutral', +]; + +export const AVATAR_COLORS = [ + '#FF6B6B', // Red + '#4ECDC4', // Teal + '#45B7D1', // Blue + '#FFA07A', // Light Salmon + '#98D8C8', // Mint + '#F7DC6F', // Yellow + '#BB8FCE', // Purple + '#85C1E2', // Sky Blue + '#F8B88B', // Peach + '#82E0AA', // Light Green +]; + +export const useAvatarStore = create( + persist( + (set, get) => ({ + avatar: { + style: 'adventurer', + seed: Math.random().toString(36).substring(7), + backgroundColor: AVATAR_COLORS[0], + }, + setAvatar: (style, seed, backgroundColor) => { + set({ + avatar: { + style, + seed: seed || Math.random().toString(36).substring(7), + backgroundColor, + }, + }); + }, + generateNewAvatar: () => { + const randomStyle = AVATAR_STYLES[Math.floor(Math.random() * AVATAR_STYLES.length)]; + const randomColor = AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)]; + const randomSeed = Math.random().toString(36).substring(7); + set({ + avatar: { + style: randomStyle, + seed: randomSeed, + backgroundColor: randomColor, + }, + }); + }, + getAvatarUrl: () => { + const { avatar } = get(); + return `https://api.dicebear.com/7.x/${avatar.style}/svg?seed=${avatar.seed}&backgroundColor=${avatar.backgroundColor.replace('#', '')}`; + }, + }), + { + name: 'avatar-store', + storage: localStorage, + }, + ), +); diff --git a/pro/src/test-setup.js b/pro/src/test-setup.js index 7b0828b..66c85ee 100644 --- a/pro/src/test-setup.js +++ b/pro/src/test-setup.js @@ -1 +1,37 @@ import '@testing-library/jest-dom'; + +Object.defineProperty(window, 'localStorage', { + value: (() => { + let store = {}; + return { + getItem: (key) => store[key] ?? null, + setItem: (key, value) => { + store[key] = String(value); + }, + removeItem: (key) => { + delete store[key]; + }, + clear: () => { + store = {}; + }, + }; + })(), +}); + +Object.defineProperty(window, 'sessionStorage', { + value: (() => { + let store = {}; + return { + getItem: (key) => store[key] ?? null, + setItem: (key, value) => { + store[key] = String(value); + }, + removeItem: (key) => { + delete store[key]; + }, + clear: () => { + store = {}; + }, + }; + })(), +}); diff --git a/pro/src/tictactoe/TicTacToe.jsx b/pro/src/tictactoe/TicTacToe.jsx index d5c8539..8dbf7fa 100644 --- a/pro/src/tictactoe/TicTacToe.jsx +++ b/pro/src/tictactoe/TicTacToe.jsx @@ -1,268 +1,340 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { useGameContext } from '../context/GameContext'; -import RetroButton from '../components/ui/RetroButton'; +import { + SketchButton, + SketchCard, + sketchPopupClass, + GameLayout, + AvatarSelector, + AvatarReactionBar, +} from '../components/ui'; import useSound from 'use-sound'; import confetti from 'canvas-confetti'; import Swal from 'sweetalert2'; import { useNavigate } from 'react-router-dom'; -import { ArrowLeft, Users, Trophy, SwatchBook } from 'lucide-react'; -import logger from '../utils/logger'; +import useSocketListeners from '../hooks/useSocketListeners'; +import useReconnection from '../hooks/useReconnection'; const TicTacToe = () => { - const { socket, playerName, roomId, setRoomId } = useGameContext(); + const { socket, roomId, setRoomId, clearRoomId, setGamePrefix, profile, setProfile } = useGameContext(); const [board, setBoard] = useState(Array(9).fill(null)); const [players, setPlayers] = useState([]); const [currentTurn, setCurrentTurn] = useState(null); const [gameState, setGameState] = useState('waiting'); const [winningCells, setWinningCells] = useState([]); - const [mySymbol, setMySymbol] = useState(null); + const [lastMove, setLastMove] = useState(null); const navigate = useNavigate(); - const [playMove] = useSound('/sounds/move.mp3', { volume: 0.5 }); const [playWin] = useSound('/sounds/win.mp3', { volume: 0.7 }); - useEffect(() => { + const handleCreateRoom = useCallback(() => { if (!socket) return; - - logger.info('TTT', `Socket connected: ${socket.id}`); - - socket.on('ttt_roomInfo', ({ id, players, gameState, currentTurn, board }) => { - logger.socket('⬅️', 'ttt_roomInfo', { roomId: id, gameState }); - setRoomId(id); - setPlayers(players); - setGameState(gameState); - setCurrentTurn(currentTurn); - if (board) setBoard(board); - - const playerIndex = players.findIndex(p => p.id === socket.id); - if (playerIndex !== -1) { - setMySymbol(playerIndex === 0 ? 'X' : 'O'); - } - }); - - socket.on('ttt_gameStarted', () => { - logger.socket('⬅️', 'ttt_gameStarted', 'Game started'); - setGameState('playing'); - setWinningCells([]); - Swal.fire({ - title: 'Game Started!', - text: 'The battle begins!', - timer: 1500, - showConfirmButton: false, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); - - socket.on('ttt_gameRestarted', () => { - logger.socket('⬅️', 'ttt_gameRestarted', 'Game restarted'); - setGameState('playing'); - setWinningCells([]); - setBoard(Array(9).fill(null)); - Swal.fire({ - title: 'Game Restarted', - text: 'Round 2!', - timer: 1500, - showConfirmButton: false, - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - }); - - socket.on('ttt_moveMade', ({ position, symbol, board }) => { - logger.socket('⬅️', 'ttt_moveMade', { position, symbol }); - playMove(); - setBoard(board); + socket.emit('ttt_createRoom', { + playerName: profile.name, + avatarIcon: profile.avatarIcon, + color: profile.color, }); + }, [socket, profile]); - socket.on('ttt_nextTurn', (playerId) => { - logger.socket('⬅️', 'ttt_nextTurn', { playerId }); - setCurrentTurn(playerId); - }); - - socket.on('ttt_gameWon', ({ winner, winningLine }) => { - logger.socket('⬅️', 'ttt_gameWon', { winner, winningLine }); - playWin(); - setWinningCells(winningLine); - confetti({ - particleCount: 150, - spread: 70, - origin: { y: 0.6 } - }); - const winnerName = players.find(p => p.id === winner)?.name || 'Someone'; - Swal.fire({ - title: '🎉 Victory!', - text: `${winnerName} has won!`, - icon: 'success', - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - setGameState('ended'); - }); - - socket.on('ttt_gameDraw', () => { - logger.socket('⬅️', 'ttt_gameDraw', 'Draw!'); - Swal.fire({ - title: '🤝 Draw!', - text: 'It\'s a tie!', - icon: 'info', - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - setGameState('ended'); - }); - - socket.on('ttt_playerLeft', (playerId) => { - logger.socket('⬅️', 'ttt_playerLeft', { playerId }); - Swal.fire({ - title: 'Player Left', - text: 'The opponent has left the party.', - icon: 'warning', - customClass: { popup: 'glass rounded-3xl paper-font' } - }); - setGameState('waiting'); - setBoard(Array(9).fill(null)); - }); - - socket.on('ttt_alert', ({ icon, title, text }) => { - logger.socket('⬅️', 'ttt_alert', { icon, title, text }); - Swal.fire({ icon, title, text, customClass: { popup: 'glass rounded-3xl paper-font' } }); - }); - - return () => { - socket.off('ttt_roomInfo'); - socket.off('ttt_gameStarted'); - socket.off('ttt_gameRestarted'); - socket.off('ttt_moveMade'); - socket.off('ttt_nextTurn'); - socket.off('ttt_gameWon'); - socket.off('ttt_gameDraw'); - socket.off('ttt_playerLeft'); - socket.off('ttt_alert'); - }; - }, [socket, players, setRoomId, playMove, playWin]); - - const handleCellClick = (position) => { - if (gameState === 'playing' && currentTurn === socket?.id && !board[position]) { - logger.socket('➡️', 'ttt_makeMove', { roomId, position }); - socket.emit('ttt_makeMove', { roomId, position }); - } - }; - - const handleCreateRoom = () => { - logger.socket('➡️', 'ttt_createRoom', { playerName }); - socket.emit('ttt_createRoom', playerName); - }; - - const handleJoinRoom = async () => { + const handleJoinRoom = useCallback(async () => { const { value: joinRoomId } = await Swal.fire({ title: 'Join Room', input: 'text', inputPlaceholder: 'Enter Room ID', showCancelButton: true, - customClass: { popup: 'glass rounded-3xl paper-font' } + customClass: { popup: sketchPopupClass }, }); if (joinRoomId) { - logger.socket('➡️', 'ttt_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); - socket.emit('ttt_joinRoom', { roomId: joinRoomId.toUpperCase(), playerName }); + socket.emit('ttt_joinRoom', { + roomId: joinRoomId.toUpperCase(), + playerName: profile.name, + avatarIcon: profile.avatarIcon, + color: profile.color, + }); } - }; + }, [socket, profile]); - const handleRestartGame = () => { - logger.socket('➡️', 'ttt_restartGame', { roomId }); + const { clearReconnect } = useReconnection({ + socket, + gamePrefix: 'ttt', + roomId, + onRestore: (room) => { + if (!room) return; + setRoomId(room.id); + setPlayers(room.players || []); + setGameState(room.gameState || 'waiting'); + setCurrentTurn(room.currentTurn); + if (room.board) setBoard(room.board); + }, + }); + + useSocketListeners( + socket, + { + ttt_roomInfo: ({ id, players, gameState, currentTurn, board }) => { + setRoomId(id); + setPlayers(players); + setGameState(gameState); + setCurrentTurn(currentTurn); + if (board) setBoard([...board]); + const playerIndex = players.findIndex((p) => p.id === socket.id); + if (playerIndex !== -1) { + sessionStorage.setItem('ttt_reconnect', JSON.stringify({ roomId: id, playerId: players[playerIndex].id })); + } + }, + ttt_moveMade: ({ board, lastMove }) => { + if (board) setBoard([...board]); + if (lastMove) setLastMove(lastMove); + }, + ttt_nextTurn: ({ nextPlayerId }) => { + setCurrentTurn(nextPlayerId); + }, + ttt_gameStarted: () => { + setGameState('playing'); + setWinningCells([]); + setLastMove(null); + Swal.fire({ + title: 'Game Started!', + text: 'Make your move!', + timer: 1500, + showConfirmButton: false, + customClass: { popup: sketchPopupClass }, + }); + }, + ttt_gameRestarted: () => { + setGameState('waiting'); + setWinningCells([]); + setBoard(Array(9).fill(null)); + setLastMove(null); + }, + ttt_gameWon: ({ winningLine }) => { + playWin(); + setWinningCells(winningLine); + confetti({ + particleCount: 150, + spread: 70, + origin: { y: 0.6 }, + }); + setGameState('ended'); + clearReconnect(); + }, + ttt_gameDraw: () => { + setGameState('ended'); + clearReconnect(); + }, + ttt_playerLeft: () => { + Swal.fire({ + title: 'Player Left', + text: 'The opponent has left the party.', + icon: 'warning', + customClass: { popup: sketchPopupClass }, + }); + setGameState('waiting'); + setBoard(Array(9).fill(null)); + setLastMove(null); + }, + ttt_alert: ({ icon, title, text }) => { + Swal.fire({ icon, title, text, customClass: { popup: sketchPopupClass } }); + }, + ttt_reconnectFailed: ({ reason, roomId: failedRoomId }) => { + Swal.fire({ + title: 'Reconnection Failed', + text: + reason === 'room_not_found' + ? 'The room no longer exists.' + : reason === 'player_not_found' + ? 'Your player session was not found.' + : reason === 'game_already_ended' + ? 'The game has ended.' + : 'Could not reconnect to the game.', + icon: 'error', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(failedRoomId); + navigate('/'); + }); + }, + server_shutdown: ({ message }) => { + Swal.fire({ + title: 'Server Shutting Down', + text: message || 'The server is going down for maintenance.', + icon: 'info', + customClass: { popup: sketchPopupClass }, + }).then(() => { + clearReconnect(); + clearRoomId(roomId); + navigate('/'); + }); + }, + }, + [clearRoomId, navigate, playWin, roomId], + ); + + useEffect(() => { + if (!socket) return; + setGamePrefix('ttt'); + }, [socket, setGamePrefix]); + + const handleCellClick = useCallback( + (position) => { + if (gameState === 'playing' && currentTurn === socket?.id && !board[position]) { + socket.emit('ttt_makeMove', { roomId, position }); + } + }, + [gameState, currentTurn, roomId, socket, board], + ); + + const handleRestartGame = useCallback(() => { socket.emit('ttt_restartGame', roomId); - }; + }, [roomId, socket]); + + const handleLeaveRoom = useCallback(async () => { + const result = await Swal.fire({ + title: 'Leave Game?', + text: 'Your progress will be lost.', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Leave', + cancelButtonText: 'Stay', + customClass: { popup: sketchPopupClass }, + }); + if (!result.isConfirmed) return; + socket.emit('ttt_leaveRoom', roomId); + clearReconnect(); + clearRoomId(roomId); + navigate('/'); + }, [roomId, socket, clearReconnect, clearRoomId, navigate]); const renderBoard = () => ( -
+
- {board.map((cell, i) => ( - - ))} + {board.map((cell, i) => { + const isLastMoveCell = lastMove && lastMove.position === i; + return ( + + ); + })}
-
+ ); -return ( -
- navigate('/')} - variant="secondary" - className="absolute top-2 sm:top-8 left-2 sm:left-8 flex items-center gap-1 sm:gap-2 text-xs sm:text-base px-2 sm:px-4" - > - - Back - - -

Tic Tac Toe

+ if (!roomId) { + return ( +
+

Tic Tac Toe

+ + setProfile((prev) => ({ ...prev, name: e.target.value }))} + placeholder="Enter your name" + className="w-full px-3 py-2 border border-ink/30 rounded sketch-font text-ink bg-white/80" + /> + setProfile((prev) => ({ ...prev, avatarIcon: icon }))} + onColorChange={(c) => setProfile((prev) => ({ ...prev, color: c }))} + /> + + +
+ Create + Join +
+
+
+ ); + } - {!roomId ? ( -
- Create - Join -
- ) : ( -
-
-
- - Room: - {roomId} -
-
- {players.map((p, i) => ( -
- {p.id === currentTurn ? ( - - ) : ( -
- )} - - {p.name.length > 8 ? p.name.slice(0,8)+'...' : p.name} - -
- ))} -
+ if (gameState === 'waiting') { + return ( +
+ +
+ + Room: + {roomId} + +
+
+ {players.map((p, _idx) => ( +
+ {p.connected !== false ? '☑️' : '☐'} + {p.name} + {p.id === socket?.id && (You)} +
+ ))}
+
- {renderBoard()} + + {players.length < 2 ? 'Waiting for opponent...' : 'Start Game'} + - {gameState === 'ended' && ( - - Play Again - - )} + + Leave Room + +
+ ); + } -
- {gameState === 'playing' ? ( - currentTurn === socket?.id ? ( -
- - Your turn! -
- ) : ( -
-
- Waiting for {players.find(p => p.id === currentTurn)?.name}... - Waiting... + return ( + +
+

Tic Tac Toe

+ + {gameState !== 'waiting' && ( +
+ {gameState === 'playing' && ( +
+
+ + {currentTurn === socket?.id ? 'Your turn!' : 'Waiting for opponent...'} +
- ) - ) : ( - gameState === 'waiting' ? "Waiting for opponent..." : "Game Over!" +
)} + + {renderBoard()} + +
+ + Leave Room + +
-
+ )} + + {gameState === 'ended' && ( +
+ + Rematch + +
+ )} +
+ + {gameState === 'playing' && ( + )} -
+ ); }; diff --git a/pro/src/tictactoe/TicTacToe.test.jsx b/pro/src/tictactoe/TicTacToe.test.jsx index 9aa3e36..566676f 100644 --- a/pro/src/tictactoe/TicTacToe.test.jsx +++ b/pro/src/tictactoe/TicTacToe.test.jsx @@ -3,62 +3,165 @@ import { render, screen, fireEvent, act } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import TicTacToe from './TicTacToe'; import { GameProvider } from '../context/GameContext'; +import { ThemeProvider } from '../context/ThemeContext'; import { BrowserRouter } from 'react-router-dom'; -// Mock Socket.io const mockSocket = { - id: 'mock-id', + id: 'p1', on: vi.fn(), off: vi.fn(), emit: vi.fn(), disconnect: vi.fn(), }; -vi.mock('socket.io-client', () => ({ - default: () => mockSocket -})); +vi.mock('socket.io-client', () => ({ default: () => mockSocket })); +vi.mock('use-sound', () => ({ default: () => [vi.fn()] })); +vi.mock('canvas-confetti', () => ({ default: vi.fn() })); +vi.mock('sweetalert2', () => ({ default: { fire: vi.fn().mockResolvedValue({ isConfirmed: true }) } })); + +const Wrapper = ({ children }) => ( + + + {children} + + +); + +const findEventCb = (event) => { + const call = mockSocket.on.mock.calls.find((c) => c[0] === event); + return call?.[1]; +}; + +const playingRoomInfo = { + id: 'TTT01', + players: [ + { id: 'p1', name: 'Alice', connected: true, avatarIcon: 'cat', color: '#2a2a3e' }, + { id: 'p2', name: 'Bob', connected: true, avatarIcon: 'dog', color: '#c73e1d' }, + ], + gameState: 'playing', + currentTurn: 'p1', + board: Array(9).fill(null), +}; describe('TicTacToe', () => { beforeEach(() => { vi.clearAllMocks(); + sessionStorage.clear(); }); - it('emits ttt_makeMove when a cell is clicked', async () => { - render( - - - - - - ); - - // Simulate being in a game and it being our turn - const roomInfoCall = mockSocket.on.mock.calls.find(call => call[0] === 'ttt_roomInfo'); - if (!roomInfoCall) throw new Error('ttt_roomInfo listener not registered'); - - const roomInfoCallback = roomInfoCall[1]; - - await act(async () => { - roomInfoCallback({ - id: '123456', - players: [{ id: 'mock-id', name: 'Alice' }, { id: 'bob-id', name: 'Bob' }], - gameState: 'playing', - currentTurn: 'mock-id', - board: Array(9).fill(null) + describe('Lobby - No Room', () => { + it('shows Create and Join buttons when no room', () => { + render(, { wrapper: Wrapper }); + expect(screen.getByText('Create')).toBeTruthy(); + expect(screen.getByText('Join')).toBeTruthy(); + }); + + it('emits ttt_createRoom when Create is clicked', async () => { + render(, { wrapper: Wrapper }); + await act(async () => { + fireEvent.click(screen.getByText('Create')); }); + expect(mockSocket.emit).toHaveBeenCalledWith( + 'ttt_createRoom', + expect.objectContaining({ playerName: expect.any(String) }), + ); }); + }); + + describe('Board Rendering', () => { + it('renders the game board when roomInfo received with playing state', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('ttt_roomInfo'); + await act(async () => { + cb(playingRoomInfo); + }); + + expect(screen.getByText('Your turn!')).toBeTruthy(); + }); + + it('shows player initials in nav', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('ttt_roomInfo'); + await act(async () => { + cb(playingRoomInfo); + }); + + expect(screen.getByText('Al')).toBeTruthy(); + expect(screen.getByText('Bo')).toBeTruthy(); + }); + + it('shows Rematch button when game ends with win', async () => { + render(, { wrapper: Wrapper }); + + const cb = findEventCb('ttt_roomInfo'); + await act(async () => { + cb(playingRoomInfo); + }); + + const gameWonCb = findEventCb('ttt_gameWon'); + await act(async () => { + gameWonCb({ winner: 'p1', winningLine: [0, 1, 2] }); + }); - const cells = screen.getAllByRole('button'); - // The first few buttons might be navigation, but the board cells have numbers or are empty - // Our TicTacToe board uses ); }; @@ -54,49 +59,99 @@ const InnerGrid = ({ const renderOverlay = () => { if (macroWinner === 'DEAD') { return ( -
-
- {Array(9).fill(null).map((_, i) => ( - × - ))} +
+
+ {Array(9) + .fill(null) + .map((_, i) => ( + + × + + ))}
); } - + if (macroWinner === 'X' || macroWinner === 'O') { return ( -
- - {macroWinner} - +
+
+ + {macroWinner} + + + {macroWinner} + +
); } - + return null; }; const renderGridLines = () => ( <> -
-
-
-
+
+
+
+
); return ( -
+
- {Array(9).fill(null).map((_, i) => renderCell(i))} + {Array(9) + .fill(null) + .map((_, i) => renderCell(i))} {renderGridLines()}
{renderOverlay()} + +
); }; -export default InnerGrid; \ No newline at end of file +export default InnerGrid; diff --git a/pro/src/uttt/components/MacroGrid.jsx b/pro/src/uttt/components/MacroGrid.jsx index e06a35d..5ab7937 100644 --- a/pro/src/uttt/components/MacroGrid.jsx +++ b/pro/src/uttt/components/MacroGrid.jsx @@ -1,29 +1,67 @@ import React from 'react'; import InnerGrid from './InnerGrid'; +const getContainerClasses = () => { + const base = 'relative rounded-xl transition-all duration-300 shadow-lg'; + return `${base} bg-white/95 border-2 border-gray-800/10`; +}; + +const renderGridLines = () => ( + <> +
+
+
+
+ +); + const MacroGrid = ({ board, macroBoard, activeGrid, lastMove, onCellClick }) => { return ( -
-
- {Array(9).fill(null).map((_, gridIndex) => ( - onCellClick(gridIndex, squareIndex)} - /> - ))} +
+
+ {Array(9) + .fill(null) + .map((_, gridIndex) => ( + onCellClick(gridIndex, squareIndex)} + /> + ))} + {renderGridLines()}
-
-
-
-
+ +
); }; -export default MacroGrid; \ No newline at end of file +export default MacroGrid; diff --git a/pro/vite.config.js b/pro/vite.config.js index d0087bd..c6663bf 100644 --- a/pro/vite.config.js +++ b/pro/vite.config.js @@ -4,10 +4,11 @@ import tailwindcss from '@tailwindcss/vite'; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [ - react(), - tailwindcss(), - ], + server: { + host: true, + port: Number(process.env.VITE_PORT) || 5173, + }, + plugins: [react(), tailwindcss()], test: { globals: true, environment: 'jsdom', diff --git a/test-results/.last-run.json b/test-results/.last-run.json new file mode 100644 index 0000000..544c11f --- /dev/null +++ b/test-results/.last-run.json @@ -0,0 +1,4 @@ +{ + "status": "failed", + "failedTests": [] +}