From d0d128aa4418d85a952cfd85789a99b5502b32cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Fri, 26 Jun 2026 00:13:41 +0200 Subject: [PATCH 01/18] Add ChatRoom-React experimental workload Exercises chat-room switching in a two-pane chat UI, so timeline teardown/rebuild cost can be profiled. Original React + Vite code with deterministic, server-free fixtures and no third-party assets. Experimental, so it is off by default and does not affect the official score. SwitchRooms uses flushSync so each programmatic click commits one room switch. --- suites-experimental/chat-room/.gitignore | 19 + suites-experimental/chat-room/README.md | 38 + suites-experimental/chat-room/index.html | 21 + .../chat-room/package-lock.json | 1255 +++++++++++++++++ suites-experimental/chat-room/package.json | 19 + suites-experimental/chat-room/src/App.jsx | 33 + .../chat-room/src/components/message.jsx | 18 + .../src/components/room-list-item.jsx | 16 + .../chat-room/src/components/room-list.jsx | 11 + .../chat-room/src/components/timeline.jsx | 11 + .../chat-room/src/data/rooms.js | 147 ++ suites-experimental/chat-room/src/main.jsx | 5 + suites-experimental/chat-room/src/styles.css | 158 +++ suites-experimental/chat-room/vite.config.js | 41 + suites-experimental/suites.mjs | 20 + 15 files changed, 1812 insertions(+) create mode 100644 suites-experimental/chat-room/.gitignore create mode 100644 suites-experimental/chat-room/README.md create mode 100644 suites-experimental/chat-room/index.html create mode 100644 suites-experimental/chat-room/package-lock.json create mode 100644 suites-experimental/chat-room/package.json create mode 100644 suites-experimental/chat-room/src/App.jsx create mode 100644 suites-experimental/chat-room/src/components/message.jsx create mode 100644 suites-experimental/chat-room/src/components/room-list-item.jsx create mode 100644 suites-experimental/chat-room/src/components/room-list.jsx create mode 100644 suites-experimental/chat-room/src/components/timeline.jsx create mode 100644 suites-experimental/chat-room/src/data/rooms.js create mode 100644 suites-experimental/chat-room/src/main.jsx create mode 100644 suites-experimental/chat-room/src/styles.css create mode 100644 suites-experimental/chat-room/vite.config.js diff --git a/suites-experimental/chat-room/.gitignore b/suites-experimental/chat-room/.gitignore new file mode 100644 index 0000000000..9949708729 --- /dev/null +++ b/suites-experimental/chat-room/.gitignore @@ -0,0 +1,19 @@ +node_modules + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +pnpm-debug.log* + +# dist-ssr / local +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.sw? diff --git a/suites-experimental/chat-room/README.md b/suites-experimental/chat-room/README.md new file mode 100644 index 0000000000..a40e29cba8 --- /dev/null +++ b/suites-experimental/chat-room/README.md @@ -0,0 +1,38 @@ +## Description + +Chat applications are an extremely common class of web app, and switching +between rooms/channels is one of their most frequent and performance-sensitive +interactions: the previous conversation's timeline is torn down and a new, +often long, timeline of rich messages is rendered in its place. + +This workload is an original, self-contained React app that reproduces that +interaction. It is **not** derived from any existing chat product's source code +and ships no third-party assets, so it is free of licensing and trademark +concerns. + +## What are we testing + +- React reconciliation cost of repeatedly mounting/unmounting a large timeline +- DOM churn and layout when switching between rooms +- Flex/grid layout of a typical two-pane chat UI with many small components + (avatars, sender names, timestamps, message bodies) + +## How are we testing + +The app renders a sidebar of rooms and, for the selected room, a timeline of +messages. All content is generated deterministically at load time (no network, +no backend, no `Math.random`/`Date.now`), so every run renders identical data. + +The timed step (`SwitchRooms`) clicks through the rooms in the sidebar in turn. +Each room's timeline is keyed by room id, so a switch fully unmounts the old +timeline and mounts the new one. + +## Developer Documentation + +The app was created with Vite + React. It can be previewed during development +with `npm run dev`. To update the files run in the harness you have to run +`npm run build`, which regenerates the committed `dist/` directory. + +The built workload can be loaded within the harness at e.g. +`http://localhost:8080/?developerMode&suites=ChatRoom-React`, or directly at +`http://localhost:8080/experimental/chat-room/dist/index.html`. diff --git a/suites-experimental/chat-room/index.html b/suites-experimental/chat-room/index.html new file mode 100644 index 0000000000..42ac7d1cdb --- /dev/null +++ b/suites-experimental/chat-room/index.html @@ -0,0 +1,21 @@ + + + + + + ChatRoom + + + +
+ + + diff --git a/suites-experimental/chat-room/package-lock.json b/suites-experimental/chat-room/package-lock.json new file mode 100644 index 0000000000..a8cfa5ec5a --- /dev/null +++ b/suites-experimental/chat-room/package-lock.json @@ -0,0 +1,1255 @@ +{ + "name": "chat-room", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "chat-room", + "version": "0.0.0", + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.0.0", + "vite": "^4.1.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.40", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.40.tgz", + "integrity": "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", + "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.38", + "caniuse-lite": "^1.0.30001799", + "electron-to-chromium": "^1.5.376", + "node-releases": "^2.0.48", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", + "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "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", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.378", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.378.tgz", + "integrity": "sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "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/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "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/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz", + "integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "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/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "4.5.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz", + "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/suites-experimental/chat-room/package.json b/suites-experimental/chat-room/package.json new file mode 100644 index 0000000000..406a041b54 --- /dev/null +++ b/suites-experimental/chat-room/package.json @@ -0,0 +1,19 @@ +{ + "name": "chat-room", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.0.0", + "vite": "^4.1.0" + } +} diff --git a/suites-experimental/chat-room/src/App.jsx b/suites-experimental/chat-room/src/App.jsx new file mode 100644 index 0000000000..c35ad6422a --- /dev/null +++ b/suites-experimental/chat-room/src/App.jsx @@ -0,0 +1,33 @@ +import { useState } from "react"; +import { flushSync } from "react-dom"; +import { rooms } from "./data/rooms.js"; +import RoomList from "./components/room-list.jsx"; +import Timeline from "./components/timeline.jsx"; + +export default function App() { + const [selectedRoomId, setSelectedRoomId] = useState(rooms[0].id); + const selectedRoom = rooms.find((room) => room.id === selectedRoomId); + + // Commit each room switch synchronously. Without this, React 18 batches a + // burst of programmatic clicks into a single deferred render, so only the + // last switch would render. flushSync makes each click render one switch, + // matching how a real discrete user click behaves. + const handleSelect = (roomId) => flushSync(() => setSelectedRoomId(roomId)); + + return ( +
+ +
+
+

+ {selectedRoom.name} +

+

{selectedRoom.topic}

+
+ {/* Keyed by room id so switching rooms fully tears down the old + timeline and mounts the new one, which is the work we profile. */} + +
+
+ ); +} diff --git a/suites-experimental/chat-room/src/components/message.jsx b/suites-experimental/chat-room/src/components/message.jsx new file mode 100644 index 0000000000..072788d34d --- /dev/null +++ b/suites-experimental/chat-room/src/components/message.jsx @@ -0,0 +1,18 @@ +import { AVATAR_COLORS } from "../data/rooms.js"; + +export default function Message({ message }) { + return ( +
  • + + {message.senderInitials} + +
    +
    + {message.sender} + {message.time} +
    +
    {message.body}
    +
    +
  • + ); +} diff --git a/suites-experimental/chat-room/src/components/room-list-item.jsx b/suites-experimental/chat-room/src/components/room-list-item.jsx new file mode 100644 index 0000000000..81f8f149f8 --- /dev/null +++ b/suites-experimental/chat-room/src/components/room-list-item.jsx @@ -0,0 +1,16 @@ +import { AVATAR_COLORS } from "../data/rooms.js"; + +export default function RoomListItem({ index, room, selected, onSelect }) { + const className = selected ? "room-list-item room-list-item-selected" : "room-list-item"; + return ( + + ); +} diff --git a/suites-experimental/chat-room/src/components/room-list.jsx b/suites-experimental/chat-room/src/components/room-list.jsx new file mode 100644 index 0000000000..733730808e --- /dev/null +++ b/suites-experimental/chat-room/src/components/room-list.jsx @@ -0,0 +1,11 @@ +import RoomListItem from "./room-list-item.jsx"; + +export default function RoomList({ rooms, selectedRoomId, onSelect }) { + return ( + + ); +} diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx new file mode 100644 index 0000000000..405c77e40c --- /dev/null +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -0,0 +1,11 @@ +import Message from "./message.jsx"; + +export default function Timeline({ room }) { + return ( +
      + {room.messages.map((message) => + + )} +
    + ); +} diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js new file mode 100644 index 0000000000..84867c4e56 --- /dev/null +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -0,0 +1,147 @@ +// Deterministic, server-free chat fixtures. +// +// Everything here is generated once at module load using a plain counter, with +// no Math.random() or Date.now(), so the workload renders identical content on +// every run. The data shape is the one a chat client works with -- rooms in a +// sidebar, a timeline of messages per room -- but the content is entirely +// original, with no third-party assets. + +const ROOM_COUNT = 40; +const MESSAGES_PER_ROOM = 150; + +const ROOM_NAMES = [ + "General", + "Random", + "Announcements", + "Engineering", + "Design", + "Product", + "Support", + "Off Topic", + "Releases", + "Incidents", + "Frontend", + "Backend", + "Infra", + "Mobile", + "Performance", + "Security", + "Docs", + "Hiring", + "Watercooler", + "Standup", +]; + +const SENDERS = ["Ada Lovelace", "Alan Turing", "Grace Hopper", "Linus Pauling", "Marie Curie", "Nikola Tesla", "Rosalind Franklin", "Carl Sagan", "Katherine Johnson", "Tim Berners-Lee"]; + +export const AVATAR_COLORS = ["#368bd6", "#ac3ba8", "#03b381", "#e64f7a", "#ff812d", "#2dc2c5", "#5c56f5", "#74d12c"]; + +const AVATAR_COLOR_COUNT = AVATAR_COLORS.length; + +const WORDS = [ + "the", + "benchmark", + "switching", + "between", + "rooms", + "should", + "feel", + "instant", + "even", + "when", + "the", + "timeline", + "is", + "long", + "and", + "full", + "of", + "rich", + "messages", + "with", + "avatars", + "and", + "timestamps", + "rendering", + "performance", + "matters", + "a", + "lot", + "here", + "lets", + "measure", + "it", + "carefully", + "and", + "compare", + "across", + "browsers", + "over", + "time", +]; + +function initials(name) { + return name + .split(" ") + .map((part) => part[0]) + .join("") + .slice(0, 2) + .toUpperCase(); +} + +// Build a message body of a deterministic, varied length from the word pool. +function buildBody(seed) { + const wordCount = 6 + (seed % 22); + const words = []; + for (let i = 0; i < wordCount; i++) + words.push(WORDS[(seed + i) % WORDS.length]); + const sentence = words.join(" "); + return `${sentence.charAt(0).toUpperCase() + sentence.slice(1)}.`; +} + +// Format a deterministic HH:MM timestamp without touching the real clock. +function buildTime(seed) { + const minutesInDay = seed % (24 * 60); + const hours = Math.floor(minutesInDay / 60); + const minutes = minutesInDay % 60; + const pad = (value) => String(value).padStart(2, "0"); + return `${pad(hours)}:${pad(minutes)}`; +} + +function buildMessages(roomIndex) { + const messages = []; + for (let i = 0; i < MESSAGES_PER_ROOM; i++) { + const seed = roomIndex * MESSAGES_PER_ROOM + i; + const sender = SENDERS[seed % SENDERS.length]; + messages.push({ + id: `room-${roomIndex}-msg-${i}`, + sender, + senderInitials: initials(sender), + colorIndex: seed % AVATAR_COLOR_COUNT, + time: buildTime(seed), + body: buildBody(seed), + }); + } + return messages; +} + +function buildRooms() { + const rooms = []; + for (let i = 0; i < ROOM_COUNT; i++) { + const baseName = ROOM_NAMES[i % ROOM_NAMES.length]; + const name = i < ROOM_NAMES.length ? baseName : `${baseName} ${Math.floor(i / ROOM_NAMES.length) + 1}`; + const messages = buildMessages(i); + rooms.push({ + id: `room-${i}`, + name, + colorIndex: i % AVATAR_COLOR_COUNT, + initials: initials(name), + topic: `Discussion about ${name.toLowerCase()}`, + lastMessage: messages[messages.length - 1].body, + messages, + }); + } + return rooms; +} + +export const rooms = buildRooms(); diff --git a/suites-experimental/chat-room/src/main.jsx b/suites-experimental/chat-room/src/main.jsx new file mode 100644 index 0000000000..ac94db0e79 --- /dev/null +++ b/suites-experimental/chat-room/src/main.jsx @@ -0,0 +1,5 @@ +import { createRoot } from "react-dom/client"; +import App from "./App.jsx"; +import "./styles.css"; + +createRoot(document.getElementById("root")).render(); diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css new file mode 100644 index 0000000000..d8a1a07f6c --- /dev/null +++ b/suites-experimental/chat-room/src/styles.css @@ -0,0 +1,158 @@ +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + height: 100%; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + color: #17191c; + background-color: #f4f6fa; +} + +#root { + height: 100vh; +} + +.app { + display: grid; + grid-template-columns: 300px 1fr; + height: 100vh; + overflow: hidden; +} + +/* Avatars are CSS-drawn circles, so the workload ships no image assets. */ +.avatar { + display: inline-flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + width: 36px; + height: 36px; + border-radius: 50%; + color: #fff; + font-size: 13px; + font-weight: 600; + text-transform: uppercase; +} + +/* Room list (sidebar) */ +.room-list { + display: flex; + flex-direction: column; + overflow-y: auto; + border-right: 1px solid #e3e8ef; + background-color: #fff; +} + +.room-list-item { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 14px; + border: 0; + border-bottom: 1px solid #f0f2f5; + background: transparent; + text-align: left; + cursor: pointer; + font: inherit; + color: inherit; +} + +.room-list-item:hover { + background-color: #f4f6fa; +} + +.room-list-item-selected { + background-color: #e8f0fe; +} + +.room-list-item-text { + display: flex; + flex-direction: column; + min-width: 0; +} + +.room-list-item-name { + font-weight: 600; + font-size: 15px; +} + +.room-list-item-preview { + font-size: 13px; + color: #737d8c; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Room (main panel) */ +.room { + display: flex; + flex-direction: column; + min-width: 0; + height: 100vh; +} + +.room-header { + padding: 14px 20px; + border-bottom: 1px solid #e3e8ef; + background-color: #fff; +} + +.room-header-name { + margin: 0; + font-size: 18px; +} + +.room-header-topic { + margin: 4px 0 0; + font-size: 13px; + color: #737d8c; +} + +/* Timeline */ +.timeline { + flex: 1 1 auto; + margin: 0; + padding: 16px 20px; + list-style: none; + overflow-y: auto; +} + +.timeline-message { + display: flex; + gap: 12px; + padding: 6px 0; +} + +.timeline-message-body { + min-width: 0; +} + +.timeline-message-meta { + display: flex; + align-items: baseline; + gap: 8px; +} + +.timeline-message-sender { + font-weight: 600; + font-size: 14px; +} + +.timeline-message-time { + font-size: 12px; + color: #939aa5; +} + +.timeline-message-text { + margin-top: 2px; + font-size: 14px; + line-height: 1.4; + color: #2c3038; +} diff --git a/suites-experimental/chat-room/vite.config.js b/suites-experimental/chat-room/vite.config.js new file mode 100644 index 0000000000..64759055e0 --- /dev/null +++ b/suites-experimental/chat-room/vite.config.js @@ -0,0 +1,41 @@ +import { resolve } from "path"; +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import { generateResourcesFile } from "../../resources/shared/generate-resources.mjs"; + +// The suite entry declares a resources.txt, which tests/unittests/suites.mjs +// validates, so emit it once the bundle is on disk. +function resourcesManifest() { + return { + name: "chat-room-resources-manifest", + closeBundle() { + generateResourcesFile(resolve(__dirname, "dist")); + }, + }; +} + +export default defineConfig({ + // Since this will be loaded from the project root. + base: "./", + plugins: [react(), resourcesManifest()], + build: { + modulePreload: { polyfill: false }, + // React 19 ships its production build unminified and leaves minification + // to the bundler, so the workload has to minify to keep a payload size + // that matches what a real React app deploys, like the other suites do. + // The source map still points back at the unminified React sources, so + // the bundle stays readable while profiling. + minify: "esbuild", + sourcemap: true, + rollupOptions: { + input: { + index: resolve(__dirname, "index.html"), + }, + output: { + entryFileNames: "assets/[name].js", + chunkFileNames: "assets/[name].js", + assetFileNames: "assets/[name].[ext]", + }, + }, + }, +}); diff --git a/suites-experimental/suites.mjs b/suites-experimental/suites.mjs index 2e4496c798..88735a7cbb 100644 --- a/suites-experimental/suites.mjs +++ b/suites-experimental/suites.mjs @@ -304,4 +304,24 @@ export const ExperimentalSuites = freezeSuites([ }), ], }, + { + name: "ChatRoom-React", + url: "suites-experimental/chat-room/dist/index.html", + resources: "suites-experimental/chat-room/dist/resources.txt", + tags: ["chat-room", "experimental"], + async prepare(page) { + await page.waitForElement(".room-list-item"); + }, + tests: [ + new BenchmarkTestStep("SwitchRooms", (page) => { + const rooms = page.querySelectorAll(".room-list-item"); + const iterations = 20; + // Starts past room 0, which is already open: clicking it commits nothing. + for (let i = 1; i <= iterations; i++) { + rooms[i % rooms.length].click(); + page.layout(); + } + }), + ], + }, ]); From 81fa61e5996458e806e246d8e85731ec74f2e622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Fri, 26 Jun 2026 01:04:20 +0200 Subject: [PATCH 02/18] Commit room switches through React's normal scheduler flushSync stopped React 18 batching a burst of programmatic clicks into one deferred render, but it is not what a real app does and it bypasses the concurrent scheduler this workload exists to exercise. The switch is a plain state update now, with the step yielding a task between clicks, which makes the suite async. The yield is a MessageChannel round-trip: an async step is awaited inside the measured window, so setTimeout(0)'s clamp would be reported as workload time, and a microtask would keep all 30 switches in one task. Driving 30 switches: microtask 329ms, flushSync 348ms, MessageChannel 397ms, setTimeout(0) 427ms. --- suites-experimental/chat-room/src/App.jsx | 10 ++++------ suites-experimental/suites.mjs | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/suites-experimental/chat-room/src/App.jsx b/suites-experimental/chat-room/src/App.jsx index c35ad6422a..e6c60efea2 100644 --- a/suites-experimental/chat-room/src/App.jsx +++ b/suites-experimental/chat-room/src/App.jsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import { flushSync } from "react-dom"; import { rooms } from "./data/rooms.js"; import RoomList from "./components/room-list.jsx"; import Timeline from "./components/timeline.jsx"; @@ -8,11 +7,10 @@ export default function App() { const [selectedRoomId, setSelectedRoomId] = useState(rooms[0].id); const selectedRoom = rooms.find((room) => room.id === selectedRoomId); - // Commit each room switch synchronously. Without this, React 18 batches a - // burst of programmatic clicks into a single deferred render, so only the - // last switch would render. flushSync makes each click render one switch, - // matching how a real discrete user click behaves. - const handleSelect = (roomId) => flushSync(() => setSelectedRoomId(roomId)); + // A plain state update, so the switch commits through React's normal + // concurrent scheduler, the way a real discrete click does. The suite yields + // a task between clicks so each switch commits before the next. + const handleSelect = (roomId) => setSelectedRoomId(roomId); return (
    diff --git a/suites-experimental/suites.mjs b/suites-experimental/suites.mjs index 88735a7cbb..5b6e4dc010 100644 --- a/suites-experimental/suites.mjs +++ b/suites-experimental/suites.mjs @@ -11,6 +11,25 @@ function reportRecipeCarouselResizeEvents(stepName, resizeEvents) { console.warn(`${stepName}: recipe-carousel ResizeObserver reported 0 width changes; expected width changes during iframe resize.`); } +// Yield a task so React's concurrent scheduler lands the pending update before +// the next interaction. A MessageChannel round-trip rather than setTimeout(0): +// an async step is awaited inside the measured window (see +// resources/shared/step-runner.mjs), so the timer clamp would be reported as +// workload time. +// +// Closed at both ends because an entangled port is a cycle collector root. +function yieldTask() { + return new Promise((resolve) => { + const channel = new MessageChannel(); + channel.port1.onmessage = () => { + channel.port1.close(); + channel.port2.close(); + resolve(); + }; + channel.port2.postMessage(0); + }); +} + export const ExperimentalSuites = freezeSuites([ { name: "TodoMVC-LocalStorage", @@ -309,16 +328,18 @@ export const ExperimentalSuites = freezeSuites([ url: "suites-experimental/chat-room/dist/index.html", resources: "suites-experimental/chat-room/dist/resources.txt", tags: ["chat-room", "experimental"], + type: "async", async prepare(page) { await page.waitForElement(".room-list-item"); }, tests: [ - new BenchmarkTestStep("SwitchRooms", (page) => { + new BenchmarkTestStep("SwitchRooms", async (page) => { const rooms = page.querySelectorAll(".room-list-item"); const iterations = 20; // Starts past room 0, which is already open: clicking it commits nothing. for (let i = 1; i <= iterations; i++) { rooms[i % rooms.length].click(); + await yieldTask(); page.layout(); } }), From c870df72d88b2ebae23611ec12fd7997ffe0254c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Fri, 26 Jun 2026 15:55:36 +0200 Subject: [PATCH 03/18] Include some emojis --- .../chat-room/src/components/message.jsx | 10 ++++ .../chat-room/src/data/rooms.js | 53 ++++++++++++++++++- suites-experimental/chat-room/src/styles.css | 22 ++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/suites-experimental/chat-room/src/components/message.jsx b/suites-experimental/chat-room/src/components/message.jsx index 072788d34d..28a65409ca 100644 --- a/suites-experimental/chat-room/src/components/message.jsx +++ b/suites-experimental/chat-room/src/components/message.jsx @@ -12,6 +12,16 @@ export default function Message({ message }) { {message.time}
    {message.body}
    + {message.reactions.length > 0 + &&
    + {message.reactions.map((reaction) => + + {reaction.emoji} + {reaction.count} + + )} +
    + } ); diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index 84867c4e56..ad9f1a5a50 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -80,6 +80,13 @@ const WORDS = [ "time", ]; +// Emoji are everywhere in a real chat. The pool mixes plain codepoints with +// variation selectors, skin tone modifiers and ZWJ sequences, so the workload +// exercises grapheme clustering as well as color-font rendering. +const INLINE_EMOJIS = ["😀", "😂", "🎉", "🔥", "❤️", "🙏", "👀", "🚀", "😅", "🤔", "💯", "✨", "🙌🏽", "👍🏻", "😍", "🥳", "😭", "🤯", "👏", "💪🏾", "🧠", "☕", "🐛", "📈", "👩‍💻", "🧑‍🚀", "👨‍👩‍👧‍👦", "🏳️‍🌈", "🤷‍♀️", "🙋‍♂️", "🫠", "🫶"]; + +const REACTION_EMOJIS = ["👍", "❤️", "😂", "🎉", "🔥", "✅", "👀", "🙏", "💯", "🚀", "😅", "🤯"]; + function initials(name) { return name .split(" ") @@ -89,14 +96,55 @@ function initials(name) { .toUpperCase(); } +// Pick a run of distinct-looking emoji, strided by the seed so neighbouring +// messages don't end up with the same run. +function pickEmojis(seed, count) { + const picked = []; + for (let i = 0; i < count; i++) + picked.push(INLINE_EMOJIS[(seed * 7 + i * 13) % INLINE_EMOJIS.length]); + return picked; +} + // Build a message body of a deterministic, varied length from the word pool. +// Most messages carry emoji: roughly one in eleven is emoji-only, and many of +// the rest get some sprinkled between the words and/or a run appended at the +// end. A decent share stays plain text so that path is still exercised too. function buildBody(seed) { + if (seed % 11 === 0) + return pickEmojis(seed, 2 + (seed % 4)).join(" "); + const wordCount = 6 + (seed % 22); + const sprinkle = seed % 5 < 2; const words = []; - for (let i = 0; i < wordCount; i++) + for (let i = 0; i < wordCount; i++) { words.push(WORDS[(seed + i) % WORDS.length]); + if (sprinkle && i > 0 && i < wordCount - 1 && (seed + i) % 7 === 0) + words.push(INLINE_EMOJIS[(seed + i) % INLINE_EMOJIS.length]); + } const sentence = words.join(" "); - return `${sentence.charAt(0).toUpperCase() + sentence.slice(1)}.`; + const text = `${sentence.charAt(0).toUpperCase() + sentence.slice(1)}.`; + if (seed % 4 === 0) + return `${text} ${pickEmojis(seed, 1 + (seed % 3)).join("")}`; + if (seed % 3 === 0) + return `${text} ${INLINE_EMOJIS[seed % INLINE_EMOJIS.length]}`; + return text; +} + +// Build a deterministic reactions row. Reaction pills are all over a busy chat, +// so roughly two messages in three have at least one and popular ones collect a +// whole row of them. +function buildReactions(seed) { + if (seed % 3 === 2) + return []; + const count = 1 + (seed % 4); + const reactions = []; + for (let i = 0; i < count; i++) { + reactions.push({ + emoji: REACTION_EMOJIS[(seed + i * 5) % REACTION_EMOJIS.length], + count: 1 + ((seed + i) % 12), + }); + } + return reactions; } // Format a deterministic HH:MM timestamp without touching the real clock. @@ -120,6 +168,7 @@ function buildMessages(roomIndex) { colorIndex: seed % AVATAR_COLOR_COUNT, time: buildTime(seed), body: buildBody(seed), + reactions: buildReactions(seed), }); } return messages; diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css index d8a1a07f6c..455c710e73 100644 --- a/suites-experimental/chat-room/src/styles.css +++ b/suites-experimental/chat-room/src/styles.css @@ -156,3 +156,25 @@ body { line-height: 1.4; color: #2c3038; } + +.timeline-message-reactions { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 4px; +} + +.reaction { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 1px 8px; + border: 1px solid #e3e8ef; + border-radius: 12px; + background-color: #f4f6fa; + font-size: 12px; +} + +.reaction-count { + color: #737d8c; +} From 0370c6b932635ef90a67c8b4ad5ed1cb8d3fd300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 14:12:07 +0200 Subject: [PATCH 04/18] Anchor the ChatRoom timeline to the newest message Chat clients open a room at its most recent message; the timeline mounted at offset 0. A layout effect now assigns scrollTop = scrollHeight after commit, so SwitchRooms measures mount plus the scroll to bottom. Not flex-direction: column-reverse, which inverts scrollTop semantics in ways browsers have disagreed on, and later steps drive scrollTop explicitly. --- .../chat-room/src/components/timeline.jsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index 405c77e40c..ecd194c42e 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -1,8 +1,23 @@ +import { useLayoutEffect, useRef } from "react"; import Message from "./message.jsx"; export default function Timeline({ room }) { + const scrollerRef = useRef(null); + + // Chat clients open a room at its newest message. Reading scrollHeight + // forces layout and the assignment jumps without animation, which is the + // work a real client does on every room switch. + // + // Done by hand rather than with flex-direction: column-reverse, because + // column-reverse inverts scrollTop and later steps drive scrollTop + // explicitly. + useLayoutEffect(() => { + const scroller = scrollerRef.current; + scroller.scrollTop = scroller.scrollHeight; + }, [room.id]); + return ( -
      +
        {room.messages.map((message) => )} From c93d114a24be3c1048b262affca5ee24a61c020d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 14:30:50 +0200 Subject: [PATCH 05/18] Give ChatRoom messages realistic content and make the timeline interactive Bodies were a single plain sentence, so rows were near-uniform in height and a windowing timeline built on that would inherit an unrealistically easy height model. They are now structured blocks -- paragraphs, code, blockquotes, lists, with inline code, links and @mention/#room pills -- giving 48 distinct row heights over 150 rows. Generation moves to a Math.imul integer hash so fields derive independently from the seed. Reaction pills, room pills and reply quotes become real controls, with state in components so the fixtures stay immutable across iterations. The reply jump assigns scrollTop from measured rects rather than scrollIntoView, keeping smooth scrolling out of a timed step. Also fixes senders never repeating, so grouping never triggered, and room pills slugifying 20 names against 40 rooms. SwitchRooms grows from ~245ms to ~450ms, the cost of mounting 150 rich rows. --- suites-experimental/chat-room/src/App.jsx | 2 +- suites-experimental/chat-room/src/actions.js | 12 + .../chat-room/src/components/message.jsx | 49 ++- .../chat-room/src/components/reaction.jsx | 15 + .../chat-room/src/components/rich-text.jsx | 74 +++++ .../chat-room/src/components/timeline.jsx | 39 ++- .../chat-room/src/data/rooms.js | 314 ++++++++++++++++-- suites-experimental/chat-room/src/styles.css | 155 +++++++++ 8 files changed, 605 insertions(+), 55 deletions(-) create mode 100644 suites-experimental/chat-room/src/actions.js create mode 100644 suites-experimental/chat-room/src/components/reaction.jsx create mode 100644 suites-experimental/chat-room/src/components/rich-text.jsx diff --git a/suites-experimental/chat-room/src/App.jsx b/suites-experimental/chat-room/src/App.jsx index e6c60efea2..c804a7f50d 100644 --- a/suites-experimental/chat-room/src/App.jsx +++ b/suites-experimental/chat-room/src/App.jsx @@ -24,7 +24,7 @@ export default function App() { {/* Keyed by room id so switching rooms fully tears down the old timeline and mounts the new one, which is the work we profile. */} - + ); diff --git a/suites-experimental/chat-room/src/actions.js b/suites-experimental/chat-room/src/actions.js new file mode 100644 index 0000000000..28e6e24d6f --- /dev/null +++ b/suites-experimental/chat-room/src/actions.js @@ -0,0 +1,12 @@ +import { createContext, useContext } from "react"; + +// Timeline content is nested deep (Message -> RichText -> Span) and the +// innermost pills act on the app, so keep that out of the intermediate props. +export const ActionsContext = createContext({ + selectRoom: () => {}, + jumpToMessage: () => {}, +}); + +export function useActions() { + return useContext(ActionsContext); +} diff --git a/suites-experimental/chat-room/src/components/message.jsx b/suites-experimental/chat-room/src/components/message.jsx index 28a65409ca..5f2d1885c2 100644 --- a/suites-experimental/chat-room/src/components/message.jsx +++ b/suites-experimental/chat-room/src/components/message.jsx @@ -1,24 +1,47 @@ +import { useActions } from "../actions.js"; import { AVATAR_COLORS } from "../data/rooms.js"; +import Reaction from "./reaction.jsx"; +import RichText from "./rich-text.jsx"; + +// Consecutive messages from the same sender collapse into the previous one, the +// way a chat client renders a burst of them: no repeated avatar or name, just +// the body under a gutter that holds the timestamp on hover. +export default function Message({ message, highlighted }) { + const { jumpToMessage } = useActions(); + const classNames = ["timeline-message"]; + if (message.grouped) + classNames.push("timeline-message-grouped"); + if (highlighted) + classNames.push("timeline-message-highlighted"); -export default function Message({ message }) { return ( -
      1. - - {message.senderInitials} - +
      2. + {message.grouped + ? {message.time} + : + {message.senderInitials} + + }
        -
        - {message.sender} - {message.time} + {message.replyTo + && + } + {!message.grouped + &&
        + {message.sender} + {message.time} +
        + } +
        +
        -
        {message.body}
        {message.reactions.length > 0 &&
        {message.reactions.map((reaction) => - - {reaction.emoji} - {reaction.count} - + )}
        } diff --git a/suites-experimental/chat-room/src/components/reaction.jsx b/suites-experimental/chat-room/src/components/reaction.jsx new file mode 100644 index 0000000000..6a54b7818b --- /dev/null +++ b/suites-experimental/chat-room/src/components/reaction.jsx @@ -0,0 +1,15 @@ +import { useState } from "react"; + +// The "mine" flag is local state, so the generated fixtures stay immutable and a +// room switch remounts back to the same counts instead of letting them drift +// upward across benchmark iterations. +export default function Reaction({ reaction }) { + const [mine, setMine] = useState(false); + const className = mine ? "reaction reaction-mine" : "reaction"; + return ( + + ); +} diff --git a/suites-experimental/chat-room/src/components/rich-text.jsx b/suites-experimental/chat-room/src/components/rich-text.jsx new file mode 100644 index 0000000000..b6ae92efd9 --- /dev/null +++ b/suites-experimental/chat-room/src/components/rich-text.jsx @@ -0,0 +1,74 @@ +import { useActions } from "../actions.js"; + +// Renders the structured bodies from data/rooms.js the way a real client walks a +// parsed representation: a block switch outside, an inline span switch inside. + +function RoomPill({ span }) { + const { selectRoom } = useActions(); + return ( + + ); +} + +function Span({ span }) { + switch (span.type) { + case "code": + return {span.text}; + case "link": + // No navigation in a timed step, so the href is data only. + return ( + event.preventDefault()}> + {span.text} + + ); + case "mention": + return @{span.name}; + case "room": + return ; + default: + return span.text; + } +} + +function Spans({ spans }) { + return spans.map((span, index) => ); +} + +function Block({ block }) { + switch (block.type) { + case "code": + return ( +
        +                    {block.lines.join("\n")}
        +                
        + ); + case "quote": + return ( +
        + +
        + ); + case "list": + return ( +
          + {block.items.map((item, index) => +
        • + +
        • + )} +
        + ); + default: + return ( +

        + +

        + ); + } +} + +export default function RichText({ blocks }) { + return blocks.map((block, index) => ); +} diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index ecd194c42e..4382594315 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -1,8 +1,10 @@ -import { useLayoutEffect, useRef } from "react"; +import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react"; +import { ActionsContext } from "../actions.js"; import Message from "./message.jsx"; -export default function Timeline({ room }) { +export default function Timeline({ room, onSelectRoom }) { const scrollerRef = useRef(null); + const [highlightedId, setHighlightedId] = useState(null); // Chat clients open a room at its newest message. Reading scrollHeight // forces layout and the assignment jumps without animation, which is the @@ -16,11 +18,34 @@ export default function Timeline({ room }) { scroller.scrollTop = scroller.scrollHeight; }, [room.id]); + // Clicking a reply quote jumps to the message it quotes and leaves it + // highlighted. The offset is computed from rects and assigned to scrollTop + // directly: no smooth behavior and no scrollIntoView, so a timed step stays + // deterministic. The highlight holds until the next jump rather than + // clearing on a timer, for the same reason, and only changes background + // colour, so committing it asynchronously cannot move the offset computed + // here. + const jumpToMessage = useCallback((messageId) => { + const scroller = scrollerRef.current; + const row = scroller.querySelector(`[data-message-id="${messageId}"]`); + if (!row) + return; + setHighlightedId(messageId); + const rowRect = row.getBoundingClientRect(); + const scrollerRect = scroller.getBoundingClientRect(); + const centeringOffset = (scroller.clientHeight - rowRect.height) / 2; + scroller.scrollTop += rowRect.top - scrollerRect.top - centeringOffset; + }, []); + + const actions = useMemo(() => ({ selectRoom: onSelectRoom, jumpToMessage }), [onSelectRoom, jumpToMessage]); + return ( -
          - {room.messages.map((message) => - - )} -
        + +
          + {room.messages.map((message) => + + )} +
        +
        ); } diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index ad9f1a5a50..247da0acc9 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -1,10 +1,12 @@ -// Deterministic, server-free chat fixtures. +// Deterministic, server-free chat fixtures. Generated once at module load from an +// integer hash, with no Math.random() or Date.now(), so every run renders identical +// content -- entirely original, with no third-party assets. // -// Everything here is generated once at module load using a plain counter, with -// no Math.random() or Date.now(), so the workload renders identical content on -// every run. The data shape is the one a chat client works with -- rooms in a -// sidebar, a timeline of messages per room -- but the content is entirely -// original, with no third-party assets. +// Message bodies are structured blocks rather than plain strings, the way a real +// client keeps them once markdown has been parsed: paragraphs, fenced code, +// blockquotes and bullet lists, with inline runs for code, links, @mentions and +// #room pills. The point is non-uniform row heights, which is what a windowing +// timeline has to cope with. const ROOM_COUNT = 40; const MESSAGES_PER_ROOM = 150; @@ -87,6 +89,79 @@ const INLINE_EMOJIS = ["😀", "😂", "🎉", "🔥", "❤️", "🙏", "👀", const REACTION_EMOJIS = ["👍", "❤️", "😂", "🎉", "🔥", "✅", "👀", "🙏", "💯", "🚀", "😅", "🤯"]; +// One handle per sender, so a mention always points at somebody in the room. +const MENTION_HANDLES = SENDERS.map((name) => name.split(" ")[0].toLowerCase()); + +const CODE_TOKENS = [ + "scrollTop", + "scrollHeight", + "flushSync", + "requestAnimationFrame", + "IntersectionObserver", + "overflow-anchor", + "content-visibility", + "useLayoutEffect", + "getBoundingClientRect", + "will-change", + "ResizeObserver", + "queueMicrotask", + "clientHeight", + "offsetHeight", +]; + +const LINK_LABELS = ["the trace", "last night's run", "this regression", "the profile", "the spec text", "my notes", "the dashboard", "that comparison"]; + +const LINK_PATHS = ["traces/2f9c", "runs/nightly", "profiles/hot-path", "spec/scroll-anchoring", "notes/timeline", "dashboards/perf", "reports/42", "compare/main"]; + +const QUOTE_LINES = [ + "can we get a number on how bad the jank is before we start moving code around", + "the window only recycles about twenty rows, so the mount cost should be flat", + "every row height changes when the panel opens, which invalidates the cache", + "please do not use smooth scrolling anywhere inside a timed step", + "prepending history without pinning the anchor makes the viewport jump", +]; + +const LIST_ITEMS = [ + "estimate the row height first, then correct after measuring", + "cache measured heights per message id", + "keep the mounted window small and bounded", + "assign scroll offsets explicitly instead of animating", + "recycle rows rather than remounting them", + "break the group when a reply quote is present", + "re-measure only the rows the resize actually touched", +]; + +const CODE_SNIPPETS = [ + { lang: "js", lines: ["const scroller = scrollerRef.current;", "scroller.scrollTop = scroller.scrollHeight;"] }, + { + lang: "js", + lines: ["requestAnimationFrame(() => {", " for (const row of mounted)", " heights.set(row.id, row.offsetHeight);", "});"], + }, + { lang: "css", lines: [".timeline {", " overflow-anchor: none;", " content-visibility: auto;", "}"] }, + { lang: "sh", lines: ["npm run build", "node debugging/e2e-chatroom.mjs --browser chrome"] }, + { lang: "json", lines: ["{", ' "iterationCount": 10,', ' "suites": ["ChatRoom-React"]', "}"] }, + { lang: "js", lines: ["for (const row of rows) {", " if (!heights.has(row.id))", " heights.set(row.id, estimate);", "}"] }, + { lang: "diff", lines: ['- scroller.scrollTo({ top, behavior: "smooth" });', "+ scroller.scrollTop = top;"] }, + { lang: "js", lines: ["export function anchorToBottom(node) {", " node.scrollTop = node.scrollHeight;", "}"] }, +]; + +// An integer hash rather than a PRNG, so every field can be derived independently +// from a message seed and still be stable across runs and across engines. +// Math.imul keeps the multiplies exactly 32-bit. +function hash(seed, salt) { + let h = Math.imul(seed + 1, 2654435761) ^ Math.imul(salt + 1, 40503); + h ^= h >>> 15; + h = Math.imul(h, 2246822519); + h ^= h >>> 13; + h = Math.imul(h, 3266489917); + h ^= h >>> 16; + return h >>> 0; +} + +function pick(list, seed, salt) { + return list[hash(seed, salt) % list.length]; +} + function initials(name) { return name .split(" ") @@ -96,8 +171,20 @@ function initials(name) { .toUpperCase(); } -// Pick a run of distinct-looking emoji, strided by the seed so neighbouring -// messages don't end up with the same run. +// Derived from the index alone, so a #room pill can be pointed at a real room +// while messages are still being generated. +function roomNameFor(index) { + const baseName = ROOM_NAMES[index % ROOM_NAMES.length]; + if (index < ROOM_NAMES.length) + return baseName; + return `${baseName} ${Math.floor(index / ROOM_NAMES.length) + 1}`; +} + +function roomSlugFor(index) { + return roomNameFor(index).toLowerCase().replace(/ /g, "-"); +} + +// Strided by the seed, so neighbouring messages don't get the same run. function pickEmojis(seed, count) { const picked = []; for (let i = 0; i < count; i++) @@ -105,29 +192,127 @@ function pickEmojis(seed, count) { return picked; } -// Build a message body of a deterministic, varied length from the word pool. -// Most messages carry emoji: roughly one in eleven is emoji-only, and many of -// the rest get some sprinkled between the words and/or a run appended at the -// end. A decent share stays plain text so that path is still exercised too. -function buildBody(seed) { - if (seed % 11 === 0) - return pickEmojis(seed, 2 + (seed % 4)).join(" "); +// Turn a token list into inline spans. Words get coalesced into text spans +// carrying the whitespace around their neighbours, which is what a markdown +// renderer ends up emitting. +function tokensToSpans(tokens) { + const spans = []; + let words = []; + let afterInline = false; + const flush = (trailingSpace) => { + if (!words.length) + return; + const leading = afterInline ? " " : ""; + const trailing = trailingSpace ? " " : ""; + spans.push({ type: "text", text: `${leading}${words.join(" ")}${trailing}` }); + words = []; + afterInline = false; + }; + for (const token of tokens) { + if (typeof token === "string") { + words.push(token); + continue; + } + flush(true); + spans.push(token); + afterInline = true; + } + flush(false); + return spans; +} - const wordCount = 6 + (seed % 22); - const sprinkle = seed % 5 < 2; - const words = []; +function buildInlineSpan(seed, index, roll) { + if (roll === 0) + return { type: "code", text: pick(CODE_TOKENS, seed, index + 11) }; + if (roll === 1) + return { type: "link", text: pick(LINK_LABELS, seed, index + 12), href: `https://example.com/${pick(LINK_PATHS, seed, index + 13)}` }; + if (roll === 2) + return { type: "mention", name: pick(MENTION_HANDLES, seed, index + 14) }; + const roomIndex = hash(seed, index + 15) % ROOM_COUNT; + return { type: "room", name: roomSlugFor(roomIndex), roomId: `room-${roomIndex}` }; +} + +// A sentence from the word pool, with inline code, links, mention and room pills +// spliced between words, plus the occasional emoji. +function buildParagraph(seed, salt) { + const wordCount = 6 + (hash(seed, salt) % 22); + const start = hash(seed, salt + 1) % WORDS.length; + const tokens = []; + let lastWasInline = false; for (let i = 0; i < wordCount; i++) { - words.push(WORDS[(seed + i) % WORDS.length]); - if (sprinkle && i > 0 && i < wordCount - 1 && (seed + i) % 7 === 0) - words.push(INLINE_EMOJIS[(seed + i) % INLINE_EMOJIS.length]); + tokens.push(WORDS[(start + i) % WORDS.length]); + const interior = i > 0 && i < wordCount - 1; + if (!interior || lastWasInline) { + lastWasInline = false; + continue; + } + const roll = hash(seed, salt * 31 + i) % 22; + if (roll < 4) { + tokens.push(buildInlineSpan(seed, i, roll)); + lastWasInline = true; + continue; + } + lastWasInline = false; + if (roll === 4) + tokens.push(INLINE_EMOJIS[hash(seed, salt + i) % INLINE_EMOJIS.length]); } - const sentence = words.join(" "); - const text = `${sentence.charAt(0).toUpperCase() + sentence.slice(1)}.`; - if (seed % 4 === 0) - return `${text} ${pickEmojis(seed, 1 + (seed % 3)).join("")}`; - if (seed % 3 === 0) - return `${text} ${INLINE_EMOJIS[seed % INLINE_EMOJIS.length]}`; - return text; + + const spans = tokensToSpans(tokens); + const first = spans[0]; + if (first.type === "text") + first.text = first.text.charAt(0).toUpperCase() + first.text.slice(1); + + // Terminal punctuation, and a trailing emoji run on some messages. + const tail = hash(seed, salt + 7) % 4 === 0 ? `. ${pickEmojis(seed, 1 + (hash(seed, salt + 8) % 3)).join("")}` : "."; + const last = spans[spans.length - 1]; + if (last.type === "text") + last.text += tail; + else + spans.push({ type: "text", text: tail }); + return spans; +} + +function buildCodeBlock(seed) { + const snippet = pick(CODE_SNIPPETS, seed, 401); + return { type: "code", lang: snippet.lang, lines: snippet.lines }; +} + +function buildList(seed) { + const count = 2 + (hash(seed, 402) % 3); + const items = []; + for (let i = 0; i < count; i++) { + const tokens = [pick(LIST_ITEMS, seed, 403 + i)]; + if (hash(seed, 413 + i) % 3 === 0) + tokens.push({ type: "code", text: pick(CODE_TOKENS, seed, 423 + i) }); + items.push(tokensToSpans(tokens)); + } + return { type: "list", items }; +} + +// Compose a message body out of blocks. The shape distribution is what drives +// the row height spread: emoji-only one-liners at one end, a paragraph plus a +// fenced code block at the other. +function buildBlocks(seed) { + const shape = hash(seed, 101) % 100; + + if (shape < 8) + return [{ type: "p", spans: [{ type: "text", text: pickEmojis(seed, 2 + (hash(seed, 102) % 4)).join(" ") }] }]; + + const blocks = [{ type: "p", spans: buildParagraph(seed, 1) }]; + + if (shape < 20) { + blocks.push(buildCodeBlock(seed)); + if (shape < 13) + blocks.push({ type: "p", spans: buildParagraph(seed, 2) }); + } else if (shape < 30) { + blocks.push(buildList(seed)); + } else if (shape < 38) { + blocks.push({ type: "quote", spans: [{ type: "text", text: pick(QUOTE_LINES, seed, 103) }] }); + blocks.push({ type: "p", spans: buildParagraph(seed, 3) }); + } else if (shape < 48) { + blocks.push({ type: "p", spans: buildParagraph(seed, 4) }); + } + return blocks; } // Build a deterministic reactions row. Reaction pills are all over a busy chat, @@ -156,18 +341,80 @@ function buildTime(seed) { return `${pad(hours)}:${pad(minutes)}`; } +function spansToText(spans) { + let text = ""; + for (const span of spans) { + if (span.type === "mention") + text += `@${span.name}`; + else if (span.type === "room") + text += `#${span.name}`; + else + text += span.text; + } + return text; +} + +// Flatten a body to plain text for the sidebar preview and reply excerpts. +function blocksToText(blocks) { + const parts = []; + for (const block of blocks) { + if (block.type === "code") + parts.push(block.lines.join(" ")); + else if (block.type === "list") + parts.push(block.items.map(spansToText).join(" ")); + else + parts.push(spansToText(block.spans)); + } + return parts.join(" ").replace(/\s+/g, " ").trim(); +} + +function excerpt(text, limit) { + return text.length <= limit ? text : `${text.slice(0, limit).trimEnd()}…`; +} + +// Real conversations arrive in bursts from the same person, which is what makes +// message grouping worth rendering. Emit runs of one to three messages per +// sender, always advancing to a different sender between runs. +function buildSenderSequence(roomIndex, count) { + const senders = []; + let index = hash(roomIndex, 301) % SENDERS.length; + while (senders.length < count) { + const runLength = 1 + (hash(roomIndex * 1000 + senders.length, 302) % 3); + for (let i = 0; i < runLength && senders.length < count; i++) + senders.push(SENDERS[index]); + index = (index + 1 + (hash(roomIndex * 1000 + senders.length, 303) % (SENDERS.length - 1))) % SENDERS.length; + } + return senders; +} + +const SENDER_COLOR_INDEX = new Map(SENDERS.map((name, index) => [name, index % AVATAR_COLOR_COUNT])); + function buildMessages(roomIndex) { + const senders = buildSenderSequence(roomIndex, MESSAGES_PER_ROOM); const messages = []; for (let i = 0; i < MESSAGES_PER_ROOM; i++) { const seed = roomIndex * MESSAGES_PER_ROOM + i; - const sender = SENDERS[seed % SENDERS.length]; + const sender = senders[i]; + const blocks = buildBlocks(seed); + + // Inline reply quotes embed a parent message in the child, and always + // break the sender group above them. + let replyTo = null; + if (i > 0 && hash(seed, 201) % 100 < 18) { + const parent = messages[Math.max(0, i - 1 - (hash(seed, 202) % 6))]; + replyTo = { id: parent.id, sender: parent.sender, excerpt: excerpt(parent.preview, 80) }; + } + messages.push({ id: `room-${roomIndex}-msg-${i}`, sender, senderInitials: initials(sender), - colorIndex: seed % AVATAR_COLOR_COUNT, + colorIndex: SENDER_COLOR_INDEX.get(sender), time: buildTime(seed), - body: buildBody(seed), + blocks, + preview: blocksToText(blocks), + replyTo, + grouped: i > 0 && senders[i - 1] === sender && !replyTo, reactions: buildReactions(seed), }); } @@ -177,8 +424,7 @@ function buildMessages(roomIndex) { function buildRooms() { const rooms = []; for (let i = 0; i < ROOM_COUNT; i++) { - const baseName = ROOM_NAMES[i % ROOM_NAMES.length]; - const name = i < ROOM_NAMES.length ? baseName : `${baseName} ${Math.floor(i / ROOM_NAMES.length) + 1}`; + const name = roomNameFor(i); const messages = buildMessages(i); rooms.push({ id: `room-${i}`, @@ -186,7 +432,7 @@ function buildRooms() { colorIndex: i % AVATAR_COLOR_COUNT, initials: initials(name), topic: `Discussion about ${name.toLowerCase()}`, - lastMessage: messages[messages.length - 1].body, + lastMessage: messages[messages.length - 1].preview, messages, }); } diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css index 455c710e73..4a042ef923 100644 --- a/suites-experimental/chat-room/src/styles.css +++ b/suites-experimental/chat-room/src/styles.css @@ -130,8 +130,69 @@ body { padding: 6px 0; } +/* Grouped messages drop the avatar and name; the gutter keeps the body aligned + and carries the timestamp, revealed on hover the way real clients do. */ +.timeline-message-grouped { + padding: 1px 0; +} + +.timeline-message-gutter { + flex: 0 0 auto; + width: 36px; + font-size: 11px; + color: #939aa5; + text-align: right; + opacity: 0; +} + +.timeline-message-grouped:hover .timeline-message-gutter { + opacity: 1; +} + .timeline-message-body { min-width: 0; + flex: 1 1 auto; +} + +/* The jump target of a reply click. Background only: changing the box would + invalidate measured row heights. */ +.timeline-message-highlighted { + background-color: #fff6d8; +} + +/* Inline reply quote: a button, because clicking it jumps to the parent. */ +.timeline-message-reply { + display: flex; + gap: 6px; + align-items: baseline; + width: 100%; + margin-bottom: 2px; + padding: 0 0 0 8px; + border: 0; + border-left: 2px solid #d5dbe5; + background: transparent; + font: inherit; + font-size: 12px; + color: #737d8c; + text-align: left; + cursor: pointer; +} + +.timeline-message-reply:hover { + border-left-color: #9dc0f5; + color: #5a6472; +} + +.timeline-message-reply-sender { + flex: 0 0 auto; + font-weight: 600; + color: #5a6472; +} + +.timeline-message-reply-excerpt { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .timeline-message-meta { @@ -157,6 +218,81 @@ body { color: #2c3038; } +/* Rich message content */ +.rich-paragraph { + margin: 0 0 4px; +} + +.rich-paragraph:last-child { + margin-bottom: 0; +} + +.rich-code { + padding: 1px 4px; + border: 1px solid #e3e8ef; + border-radius: 4px; + background-color: #f4f6fa; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 0.9em; + color: #b4295c; +} + +.rich-code-block { + margin: 4px 0; + padding: 8px 10px; + overflow-x: auto; + border: 1px solid #e3e8ef; + border-radius: 6px; + background-color: #f8fafc; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 12px; + line-height: 1.45; + white-space: pre; +} + +.rich-quote { + margin: 4px 0; + padding: 2px 0 2px 10px; + border-left: 3px solid #c8d1de; + color: #5a6472; +} + +.rich-list { + margin: 4px 0; + padding-left: 20px; +} + +.rich-link { + color: #2a6fd6; + text-decoration: underline; +} + +.rich-pill { + padding: 0 5px; + border: 0; + border-radius: 10px; + font: inherit; + font-weight: 500; + white-space: nowrap; +} + +.rich-pill-mention { + background-color: #e2ecfd; + color: #24509b; +} + +/* A #room pill is a button: clicking it switches to that room. */ +.rich-pill-room { + background-color: #e6f6ee; + color: #1c6e4c; + cursor: pointer; +} + +.rich-pill-room:hover { + background-color: #d3efe1; +} + +/* Reactions */ .timeline-message-reactions { display: flex; flex-wrap: wrap; @@ -164,6 +300,7 @@ body { margin-top: 4px; } +/* Reaction pills are real toggle buttons. */ .reaction { display: inline-flex; align-items: center; @@ -172,7 +309,25 @@ body { border: 1px solid #e3e8ef; border-radius: 12px; background-color: #f4f6fa; + font: inherit; font-size: 12px; + color: inherit; + cursor: pointer; +} + +.reaction:hover { + border-color: #c8d1de; + background-color: #eaeef5; +} + +.reaction-mine { + border-color: #9dc0f5; + background-color: #e2ecfd; +} + +.reaction-mine .reaction-count { + color: #24509b; + font-weight: 600; } .reaction-count { From e3fe1e3287d4c1dcf5675e108a97630c04ad2222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 15:40:09 +0200 Subject: [PATCH 06/18] Add a message composer to the ChatRoom workload The app was a read-only viewer. There is now a text input and a Send button below the timeline; sending appends to the end and scrolls to bottom. Sent messages live in Timeline state rather than the fixtures, so the generated data stays immutable and rooms do not grow across iterations. Timestamps continue from the room's last message rather than reading the clock. Enter is an explicit onKeyDown, since a dispatched keydown triggers no default action. No new step: SwitchRooms is unchanged, so this is app surface only. --- .../chat-room/src/components/composer.jsx | 41 ++++++++++++++++ .../chat-room/src/components/timeline.jsx | 22 +++++++-- .../chat-room/src/data/rooms.js | 38 +++++++++++++- suites-experimental/chat-room/src/styles.css | 49 +++++++++++++++++++ 4 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 suites-experimental/chat-room/src/components/composer.jsx diff --git a/suites-experimental/chat-room/src/components/composer.jsx b/suites-experimental/chat-room/src/components/composer.jsx new file mode 100644 index 0000000000..c66972645e --- /dev/null +++ b/suites-experimental/chat-room/src/components/composer.jsx @@ -0,0 +1,41 @@ +import { useState } from "react"; + +// Enter is handled explicitly rather than through the form's implicit submission, +// because a dispatched keydown does not trigger default actions, and a timed step +// would have to drive this through the harness. +export default function Composer({ roomName, onSend }) { + const [draft, setDraft] = useState(""); + + const send = (event) => { + event.preventDefault(); + const text = draft.trim(); + if (!text) + return; + onSend(text); + setDraft(""); + }; + + const handleKeyDown = (event) => { + if (event.key === "Enter" && !event.shiftKey) + send(event); + }; + + return ( +
        + setDraft(event.target.value)} + onKeyDown={handleKeyDown} + /> + +
        + ); +} diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index 4382594315..53c0b6d31c 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -1,14 +1,22 @@ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react"; import { ActionsContext } from "../actions.js"; +import { createOutgoingMessage } from "../data/rooms.js"; +import Composer from "./composer.jsx"; import Message from "./message.jsx"; export default function Timeline({ room, onSelectRoom }) { const scrollerRef = useRef(null); const [highlightedId, setHighlightedId] = useState(null); - // Chat clients open a room at its newest message. Reading scrollHeight - // forces layout and the assignment jumps without animation, which is the - // work a real client does on every room switch. + // Messages the local user sent, kept here rather than pushed into the + // fixtures, so the generated data stays immutable and a room switch (which + // remounts this component) restores the original timeline. Otherwise rooms + // would grow across repeated benchmark iterations. + const [sent, setSent] = useState([]); + + // Chat clients open a room at its newest message, and jump back to the + // bottom after sending. Reading scrollHeight forces layout and the + // assignment jumps without animation, which is the work a real client does. // // Done by hand rather than with flex-direction: column-reverse, because // column-reverse inverts scrollTop and later steps drive scrollTop @@ -16,7 +24,7 @@ export default function Timeline({ room, onSelectRoom }) { useLayoutEffect(() => { const scroller = scrollerRef.current; scroller.scrollTop = scroller.scrollHeight; - }, [room.id]); + }, [room.id, sent.length]); // Clicking a reply quote jumps to the message it quotes and leaves it // highlighted. The offset is computed from rects and assigned to scrollTop @@ -39,13 +47,19 @@ export default function Timeline({ room, onSelectRoom }) { const actions = useMemo(() => ({ selectRoom: onSelectRoom, jumpToMessage }), [onSelectRoom, jumpToMessage]); + const handleSend = useCallback((text) => setSent((previous) => [...previous, createOutgoingMessage(room, previous.length, text)]), [room]); + return (
          {room.messages.map((message) => )} + {sent.map((message) => + + )}
        +
        ); } diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index 247da0acc9..a80acc7664 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -333,14 +333,17 @@ function buildReactions(seed) { } // Format a deterministic HH:MM timestamp without touching the real clock. -function buildTime(seed) { - const minutesInDay = seed % (24 * 60); +function formatTime(minutesInDay) { const hours = Math.floor(minutesInDay / 60); const minutes = minutesInDay % 60; const pad = (value) => String(value).padStart(2, "0"); return `${pad(hours)}:${pad(minutes)}`; } +function buildTime(seed) { + return formatTime(seed % (24 * 60)); +} + function spansToText(spans) { let text = ""; for (const span of spans) { @@ -440,3 +443,34 @@ function buildRooms() { } export const rooms = buildRooms(); + +const LOCAL_USER_NAME = "You"; + +export const LOCAL_USER = { + name: LOCAL_USER_NAME, + initials: initials(LOCAL_USER_NAME), + colorIndex: SENDERS.length % AVATAR_COLOR_COUNT, +}; + +// Build a message the local user just sent, in the same shape as the generated +// fixtures so the timeline renders it through the same path. +// +// The timestamp continues from the room's last message instead of reading the +// clock, keeping the workload deterministic. Runs of outgoing messages group +// under the first one, the way a burst from one sender does anywhere else. +export function createOutgoingMessage(room, sequence, text) { + const previous = room.messages[room.messages.length - 1].time.split(":").map(Number); + const sentAt = (previous[0] * 60 + previous[1] + 1 + sequence) % (24 * 60); + return { + id: `${room.id}-sent-${sequence}`, + sender: LOCAL_USER.name, + senderInitials: LOCAL_USER.initials, + colorIndex: LOCAL_USER.colorIndex, + time: formatTime(sentAt), + blocks: [{ type: "p", spans: [{ type: "text", text }] }], + preview: text, + replyTo: null, + grouped: sequence > 0, + reactions: [], + }; +} diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css index 4a042ef923..97b989a04d 100644 --- a/suites-experimental/chat-room/src/styles.css +++ b/suites-experimental/chat-room/src/styles.css @@ -115,6 +115,55 @@ body { color: #737d8c; } +/* Composer. Sits below the timeline, so the scroller gives up the height it takes. */ +.composer { + display: flex; + flex: 0 0 auto; + gap: 8px; + padding: 12px 20px; + border-top: 1px solid #e3e8ef; + background-color: #fff; +} + +.composer-input { + flex: 1 1 auto; + min-width: 0; + padding: 8px 12px; + border: 1px solid #d5dbe5; + border-radius: 8px; + font: inherit; + font-size: 14px; + color: inherit; +} + +.composer-input:focus { + border-color: #9dc0f5; + outline: 2px solid #dce8fb; + outline-offset: -1px; +} + +.composer-send { + flex: 0 0 auto; + padding: 8px 16px; + border: 0; + border-radius: 8px; + background-color: #2a6fd6; + font: inherit; + font-size: 14px; + font-weight: 600; + color: #fff; + cursor: pointer; +} + +.composer-send:hover:enabled { + background-color: #245fb8; +} + +.composer-send:disabled { + background-color: #c8d1de; + cursor: default; +} + /* Timeline */ .timeline { flex: 1 1 auto; From 23f347cabbf5ef44f1ccde94a951dce138349584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 16:00:11 +0200 Subject: [PATCH 07/18] Add image attachments and link previews to ChatRoom messages Message bodies gain an image attachment and an unfurl card block, covering about 11% of messages. Artwork is SVG data URIs built from a palette and shape variant by a new graphics module, so the workload still ships no image assets. The URIs are memoized on a reduced palette/variant key -- with the raw hashes every message got a distinct gradient id, so the browser decoded 652 images instead of 127. Images carry explicit width and height, or a row would resize once the image decoded and invalidate the height cache. Also fixes bullet lists repeating a line about 13% of the time. Row heights now span 24px to 278px with 58 distinct values, up from 229px and 48. SwitchRooms grows from ~367ms to ~442ms. --- .../chat-room/src/components/rich-text.jsx | 16 ++++ .../chat-room/src/data/graphics.js | 66 ++++++++++++++++ .../chat-room/src/data/rooms.js | 76 ++++++++++++++++--- suites-experimental/chat-room/src/styles.css | 58 ++++++++++++++ 4 files changed, 204 insertions(+), 12 deletions(-) create mode 100644 suites-experimental/chat-room/src/data/graphics.js diff --git a/suites-experimental/chat-room/src/components/rich-text.jsx b/suites-experimental/chat-room/src/components/rich-text.jsx index b6ae92efd9..e7ea69c8f0 100644 --- a/suites-experimental/chat-room/src/components/rich-text.jsx +++ b/suites-experimental/chat-room/src/components/rich-text.jsx @@ -50,6 +50,22 @@ function Block({ block }) { ); + case "image": + // Intrinsic width/height so the row reserves its space before the + // image decodes. Without them the height would change after layout, + // invalidating the timeline's height cache. + return {block.alt}; + case "unfurl": + return ( + event.preventDefault()}> + + + {block.site} + {block.title} + {block.description} + + + ); case "list": return (
          diff --git a/suites-experimental/chat-room/src/data/graphics.js b/suites-experimental/chat-room/src/data/graphics.js new file mode 100644 index 0000000000..bfe0659feb --- /dev/null +++ b/suites-experimental/chat-room/src/data/graphics.js @@ -0,0 +1,66 @@ +// Procedurally generated SVG artwork, so the workload ships no third-party image +// assets. Data URIs are memoized per variant rather than per message, so a few +// dozen images cover the corpus and the browser can reuse a decode. + +const SHAPE_VARIANTS = 4; + +const PALETTES = [ + ["#3b82f6", "#bfdbfe"], + ["#a855f7", "#f0d9ff"], + ["#10b981", "#b7f5da"], + ["#ef4444", "#ffd5d5"], + ["#f59e0b", "#ffeab0"], + ["#06b6d4", "#b8f2fb"], + ["#6366f1", "#d5daff"], + ["#84cc16", "#e3fab3"], +]; + +// Each variant arranges flat shapes over the gradient differently, so thumbnails +// read as distinct pictures without any of them being a photo. +function shapesFor(variant, width, height) { + const w = width; + const h = height; + switch (variant) { + case 0: + return ``; + case 1: + return ``; + case 2: { + const bars = [0.35, 0.62, 0.45, 0.8, 0.55]; + return bars + .map((value, index) => { + const barWidth = (w * 0.9) / bars.length - 6; + const x = w * 0.05 + index * ((w * 0.9) / bars.length); + return ``; + }) + .join(""); + } + default: + return ``; + } +} + +const cache = new Map(); + +export function generatedImage(paletteIndex, variant, width, height) { + // Callers pass raw hashes. Reduce them before they reach the cache key or the + // gradient id, or every message gets a distinct id and its own decode. + const palette = paletteIndex % PALETTES.length; + const shape = variant % SHAPE_VARIANTS; + + const key = `${palette}-${shape}-${width}x${height}`; + const cached = cache.get(key); + if (cached) + return cached; + + const [from, to] = PALETTES[palette]; + const gradientId = `g${palette}${shape}`; + const svg = `${shapesFor( + shape, + width, + height + )}`; + const src = `data:image/svg+xml,${encodeURIComponent(svg)}`; + cache.set(key, src); + return src; +} diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index a80acc7664..0296b5f90a 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -2,11 +2,10 @@ // integer hash, with no Math.random() or Date.now(), so every run renders identical // content -- entirely original, with no third-party assets. // -// Message bodies are structured blocks rather than plain strings, the way a real -// client keeps them once markdown has been parsed: paragraphs, fenced code, -// blockquotes and bullet lists, with inline runs for code, links, @mentions and -// #room pills. The point is non-uniform row heights, which is what a windowing -// timeline has to cope with. +// Bodies are structured blocks rather than plain strings, the way a client keeps +// them once markdown has been parsed. The point is non-uniform row heights. + +import { generatedImage } from "./graphics.js"; const ROOM_COUNT = 40; const MESSAGES_PER_ROOM = 150; @@ -113,6 +112,13 @@ const LINK_LABELS = ["the trace", "last night's run", "this regression", "the pr const LINK_PATHS = ["traces/2f9c", "runs/nightly", "profiles/hot-path", "spec/scroll-anchoring", "notes/timeline", "dashboards/perf", "reports/42", "compare/main"]; +const UNFURL_LINKS = [ + { site: "example.com", title: "Scroll anchoring, and why feeds jump", description: "How browsers pin a scroll position while content is inserted above the viewport, and where it gives up." }, + { site: "perf.example.com", title: "Nightly run 482 vs 481", description: "Geomean moved 1.8% on the chat suites. Row measurement dominates the profile." }, + { site: "docs.example.com", title: "Windowing a variable-height list", description: "Estimate, measure, cache, correct. The four steps every hand-rolled virtualizer ends up with." }, + { site: "bugs.example.com", title: "Timeline jumps when the panel opens", description: "Narrowing the scroller re-wraps every row, so the cached heights are all stale at once." }, +]; + const QUOTE_LINES = [ "can we get a number on how bad the jank is before we start moving code around", "the window only recycles about twenty rows, so the mount cost should be flat", @@ -279,9 +285,11 @@ function buildCodeBlock(seed) { function buildList(seed) { const count = 2 + (hash(seed, 402) % 3); + // Walk the pool from a seeded offset, so a list never repeats a line. + const start = hash(seed, 403) % LIST_ITEMS.length; const items = []; for (let i = 0; i < count; i++) { - const tokens = [pick(LIST_ITEMS, seed, 403 + i)]; + const tokens = [LIST_ITEMS[(start + i) % LIST_ITEMS.length]]; if (hash(seed, 413 + i) % 3 === 0) tokens.push({ type: "code", text: pick(CODE_TOKENS, seed, 423 + i) }); items.push(tokensToSpans(tokens)); @@ -289,9 +297,45 @@ function buildList(seed) { return { type: "list", items }; } -// Compose a message body out of blocks. The shape distribution is what drives -// the row height spread: emoji-only one-liners at one end, a paragraph plus a -// fenced code block at the other. +// A few different aspect ratios, so attachments widen the row height spread +// rather than all adding the same block. +const IMAGE_SIZES = [ + { width: 260, height: 146 }, + { width: 220, height: 165 }, + { width: 180, height: 180 }, +]; + +const IMAGE_ALTS = ["a flame chart of the room switch", "the timeline mid-scroll", "row heights before and after windowing", "a screenshot of the composer", "the scroll anchoring repro"]; + +function buildImage(seed) { + const size = IMAGE_SIZES[hash(seed, 501) % IMAGE_SIZES.length]; + return { + type: "image", + src: generatedImage(hash(seed, 502), hash(seed, 503), size.width, size.height), + width: size.width, + height: size.height, + alt: pick(IMAGE_ALTS, seed, 504), + }; +} + +// Link previews, the card a client renders after unfurling a URL. +function buildUnfurl(seed) { + const link = pick(UNFURL_LINKS, seed, 601); + return { + type: "unfurl", + href: `https://example.com/${pick(LINK_PATHS, seed, 602)}`, + site: link.site, + title: link.title, + description: link.description, + thumbSrc: generatedImage(hash(seed, 603), hash(seed, 604), 72, 72), + thumbWidth: 72, + thumbHeight: 72, + }; +} + +// The shape distribution is what drives the row height spread: emoji-only +// one-liners at one end, a paragraph plus an attachment or fenced code block at +// the other. function buildBlocks(seed) { const shape = hash(seed, 101) % 100; @@ -304,12 +348,16 @@ function buildBlocks(seed) { blocks.push(buildCodeBlock(seed)); if (shape < 13) blocks.push({ type: "p", spans: buildParagraph(seed, 2) }); - } else if (shape < 30) { + } else if (shape < 28) { blocks.push(buildList(seed)); - } else if (shape < 38) { + } else if (shape < 35) { blocks.push({ type: "quote", spans: [{ type: "text", text: pick(QUOTE_LINES, seed, 103) }] }); blocks.push({ type: "p", spans: buildParagraph(seed, 3) }); - } else if (shape < 48) { + } else if (shape < 41) { + blocks.push(buildImage(seed)); + } else if (shape < 46) { + blocks.push(buildUnfurl(seed)); + } else if (shape < 54) { blocks.push({ type: "p", spans: buildParagraph(seed, 4) }); } return blocks; @@ -365,6 +413,10 @@ function blocksToText(blocks) { parts.push(block.lines.join(" ")); else if (block.type === "list") parts.push(block.items.map(spansToText).join(" ")); + else if (block.type === "image") + parts.push(block.alt); + else if (block.type === "unfurl") + parts.push(`${block.title} ${block.site}`); else parts.push(spansToText(block.spans)); } diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css index 97b989a04d..48c4f85eb1 100644 --- a/suites-experimental/chat-room/src/styles.css +++ b/suites-experimental/chat-room/src/styles.css @@ -299,6 +299,64 @@ body { white-space: pre; } +/* Attachments and link previews. The artwork is procedurally generated SVG. */ +.rich-image { + display: block; + max-width: 100%; + height: auto; + margin: 6px 0; + border: 1px solid #e3e8ef; + border-radius: 8px; +} + +.rich-unfurl { + display: flex; + gap: 10px; + max-width: 460px; + margin: 6px 0; + padding: 10px; + border: 1px solid #e3e8ef; + border-left: 3px solid #9dc0f5; + border-radius: 8px; + background-color: #fbfcfe; + color: inherit; + text-decoration: none; +} + +.rich-unfurl:hover { + background-color: #f4f8ff; +} + +.rich-unfurl-thumb { + flex: 0 0 auto; + border-radius: 6px; +} + +.rich-unfurl-body { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; +} + +.rich-unfurl-site { + font-size: 11px; + font-weight: 600; + color: #737d8c; + text-transform: uppercase; + letter-spacing: 0.02em; +} + +.rich-unfurl-title { + font-weight: 600; + color: #24509b; +} + +.rich-unfurl-description { + font-size: 13px; + color: #5a6472; +} + .rich-quote { margin: 4px 0; padding: 2px 0 2px 10px; From 7372fb4f859eb5bc48f85d86cddace4f06c846ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 17:35:00 +0200 Subject: [PATCH 08/18] Virtualize the ChatRoom timeline and scale it to 1500 messages Speedometer has almost no scroll coverage: across the 32 default suites the only scrolling inside a timed step is a single scrollIntoView. A chat timeline is the natural vehicle for that, but only once it is windowed. Rooms grow from 150 to 1500 messages and the timeline mounts ~15 rows. The virtualizer is hand-rolled, since a generic one assumes a height it can know up front and a chat row's depends on how its text wraps. The new height model estimates, measures, caches and corrects, keeping prefix sums so an offset can be turned back into a row index without touching the DOM. Three constraints it has to respect -- the scroller's height lagging the model by a commit, the row estimate having to sit under the real mean, and overflow-anchor having to be off -- are documented at their sites. ScrollTimeline is the new step, driving explicit offsets back through history and then in long strides. SwitchRooms is unchanged but costs ~4.5x less. PageElement gains scrollTop/scrollHeight/clientHeight, since scrollIntoView cannot reach an unmounted row. --- resources/benchmark-runner.mjs | 20 ++ suites-experimental/chat-room/README.md | 29 ++- .../chat-room/src/components/message.jsx | 6 +- .../chat-room/src/components/timeline.jsx | 211 +++++++++++++++--- .../chat-room/src/data/rooms.js | 22 +- .../chat-room/src/row-heights.js | 105 +++++++++ suites-experimental/chat-room/src/styles.css | 8 +- suites-experimental/suites.mjs | 35 +++ 8 files changed, 387 insertions(+), 49 deletions(-) create mode 100644 suites-experimental/chat-room/src/row-heights.js diff --git a/resources/benchmark-runner.mjs b/resources/benchmark-runner.mjs index f443ffed91..a582087d38 100644 --- a/resources/benchmark-runner.mjs +++ b/resources/benchmark-runner.mjs @@ -201,6 +201,26 @@ class PageElement { }; } + /** + * Scroll geometry, for steps that drive a scroller to an explicit offset. + * Never animate a scroll inside a measured step: assign an offset instead. + */ + get scrollTop() { + return this.#node.scrollTop; + } + + set scrollTop(offset) { + this.#node.scrollTop = offset; + } + + get scrollHeight() { + return this.#node.scrollHeight; + } + + get clientHeight() { + return this.#node.clientHeight; + } + dispatchEvent(eventName, options = NATIVE_OPTIONS, eventType = Event) { if (eventName === "submit") // FIXME FireFox doesn't like `new Event('submit') diff --git a/suites-experimental/chat-room/README.md b/suites-experimental/chat-room/README.md index a40e29cba8..3580105268 100644 --- a/suites-experimental/chat-room/README.md +++ b/suites-experimental/chat-room/README.md @@ -5,8 +5,12 @@ between rooms/channels is one of their most frequent and performance-sensitive interactions: the previous conversation's timeline is torn down and a new, often long, timeline of rich messages is rendered in its place. -This workload is an original, self-contained React app that reproduces that -interaction. It is **not** derived from any existing chat product's source code +Reading back through a conversation is the other one, and on a room this long it +is not a plain scroll: the timeline is windowed, so every offset mounts rows +whose height is not known until they have been laid out. + +This workload is an original, self-contained React app that reproduces those +interactions. It is **not** derived from any existing chat product's source code and ships no third-party assets, so it is free of licensing and trademark concerns. @@ -14,18 +18,27 @@ concerns. - React reconciliation cost of repeatedly mounting/unmounting a large timeline - DOM churn and layout when switching between rooms +- Windowed scrolling that measures rows only after mounting them, and corrects + the scroll position against what they measured - Flex/grid layout of a typical two-pane chat UI with many small components (avatars, sender names, timestamps, message bodies) ## How are we testing -The app renders a sidebar of rooms and, for the selected room, a timeline of -messages. All content is generated deterministically at load time (no network, -no backend, no `Math.random`/`Date.now`), so every run renders identical data. +The app renders a sidebar of rooms and, for the selected room, a windowed +timeline of its 1500 messages. All content is generated deterministically at load +time (no network, no backend, no `Math.random`/`Date.now`), so every run renders +identical data. + +`ScrollTimeline` reads back through a room's history, first a viewport at a time +and then in the long strides that dragging the scrollbar produces. The two cover +opposite halves of the height model: the short steps land on rows that have +already been measured and are being recycled, the strides on rows that have only +ever been estimated. -The timed step (`SwitchRooms`) clicks through the rooms in the sidebar in turn. -Each room's timeline is keyed by room id, so a switch fully unmounts the old -timeline and mounts the new one. +`SwitchRooms` clicks through the rooms in the sidebar in turn. Each room's +timeline is keyed by room id, so a switch fully unmounts the old timeline and +mounts the new one. ## Developer Documentation diff --git a/suites-experimental/chat-room/src/components/message.jsx b/suites-experimental/chat-room/src/components/message.jsx index 5f2d1885c2..7a38c6e29e 100644 --- a/suites-experimental/chat-room/src/components/message.jsx +++ b/suites-experimental/chat-room/src/components/message.jsx @@ -6,7 +6,9 @@ import RichText from "./rich-text.jsx"; // Consecutive messages from the same sender collapse into the previous one, the // way a chat client renders a burst of them: no repeated avatar or name, just // the body under a gutter that holds the timestamp on hover. -export default function Message({ message, highlighted }) { +// The index is the row's position in the whole room, not in the mounted window, +// so the timeline can file the measured height against the right message. +export default function Message({ index, message, highlighted }) { const { jumpToMessage } = useActions(); const classNames = ["timeline-message"]; if (message.grouped) @@ -15,7 +17,7 @@ export default function Message({ message, highlighted }) { classNames.push("timeline-message-highlighted"); return ( -
        • +
        • {message.grouped ? {message.time} : diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index 53c0b6d31c..35f8479c18 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -1,63 +1,208 @@ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react"; import { ActionsContext } from "../actions.js"; import { createOutgoingMessage } from "../data/rooms.js"; +import { RowHeights } from "../row-heights.js"; import Composer from "./composer.jsx"; import Message from "./message.jsx"; +// Only the rows near the viewport are mounted; two spacers stand in for the rest. +// The scroller carries no vertical padding (see styles.css), so scrollTop maps one +// to one onto the height model's offsets. + +// Rows kept mounted either side of the visible range, so a small scroll reuses +// rows already in the DOM instead of replacing the whole window. +const OVERSCAN = 4; + +// Deliberately under the measured mean of ~111px: a room opens pinned to its +// newest message, and an estimate that ran high would shrink the measured total +// under the pin and drag the window backwards through history. +const ESTIMATED_ROW_HEIGHT = 100; + +// How close to the bottom still counts as following the conversation. +const PIN_THRESHOLD = 4; + export default function Timeline({ room, onSelectRoom }) { const scrollerRef = useRef(null); const [highlightedId, setHighlightedId] = useState(null); - // Messages the local user sent, kept here rather than pushed into the - // fixtures, so the generated data stays immutable and a room switch (which - // remounts this component) restores the original timeline. Otherwise rooms - // would grow across repeated benchmark iterations. + // Messages the local user sent, kept here rather than pushed into the fixtures, + // so a room switch remounts back to the original timeline instead of letting + // rooms grow across benchmark iterations. const [sent, setSent] = useState([]); - // Chat clients open a room at its newest message, and jump back to the - // bottom after sending. Reading scrollHeight forces layout and the - // assignment jumps without animation, which is the work a real client does. + const messages = useMemo(() => sent.length ? [...room.messages, ...sent] : room.messages, [room.messages, sent]); + + const heights = useMemo(() => new RowHeights(room.messages.length, ESTIMATED_ROW_HEIGHT), [room.messages]); + + // Only ever grows, and only at the end, so calling it here is idempotent: a + // re-render with the same messages changes nothing. + heights.grow(messages.length); + + const indexById = useMemo(() => new Map(messages.map((message, index) => [message.id, index])), [messages]); + + // The mounted range, end exclusive. Starts empty because the total height is + // still all estimates at that point: the mount effect below pins the scroller + // to the bottom first, and the window follows from that offset. + const [range, setRange] = useState({ start: 0, end: 0 }); + + // True while the timeline is following the conversation, the way a chat client + // keeps you at the newest message until you scroll away yourself. + const pinnedToBottom = useRef(true); + + // Set while a reply-quote jump is settling, because the target's offset is an + // estimate at the moment the jump is issued. + const jumpTarget = useRef(null); + + // The row under the top of the viewport, and how far into it, captured before + // measurements moved the offsets out from under it. + const anchor = useRef(null); + + // Bumped when a measurement changes a cached height, purely to get another + // render: the spacers are computed from the model during render, so nothing + // else tells React that it moved. + const [, recordMeasurements] = useState(0); + + const rangeFor = useCallback( + (scrollTop, viewportHeight) => { + const first = heights.indexAt(scrollTop); + const bottom = scrollTop + viewportHeight; + let last = first; + while (last + 1 < heights.count && heights.offsetAt(last + 1) < bottom) + last++; + return { + start: Math.max(0, first - OVERSCAN), + end: Math.min(heights.count, last + 1 + OVERSCAN), + }; + }, + [heights] + ); + + const centeredOffset = useCallback( + (index, viewportHeight) => { + const centered = heights.offsetAt(index) - (viewportHeight - heights.heightAt(index)) / 2; + return Math.max(0, Math.min(centered, heights.totalHeight - viewportHeight)); + }, + [heights] + ); + + // Comparing rather than assigning unconditionally lets React bail out when the + // window has not moved, which is the common case for a scroll inside the + // overscan and for the second pass of a correction. + const updateRange = useCallback((next) => { + setRange((previous) => previous.start === next.start && previous.end === next.end ? previous : next); + }, []); + + // Captured against the offsets the DOM was last laid out with. Restoring the + // pair after the offsets move is what keeps the content still. + const captureAnchor = useCallback( + (scrollTop) => { + const index = heights.indexAt(scrollTop); + return { index, offset: scrollTop - heights.offsetAt(index) }; + }, + [heights] + ); + + const handleScroll = useCallback(() => { + const scroller = scrollerRef.current; + pinnedToBottom.current = scroller.scrollHeight - (scroller.scrollTop + scroller.clientHeight) <= PIN_THRESHOLD; + updateRange(rangeFor(scroller.scrollTop, scroller.clientHeight)); + }, [rangeFor, updateRange]); + + // Measure what is mounted, then put the content back where it was. Runs after + // every commit, because a row's height can change without the window moving: + // that is what will make a narrower timeline re-measure in the thread-panel + // phase. // - // Done by hand rather than with flex-direction: column-reverse, because - // column-reverse inverts scrollTop and later steps drive scrollTop - // explicitly. + // Correcting the scroll position is the part that makes windowing honest. The + // rows that just mounted were laid out against estimates, so the offsets read + // before this pass are stale the moment a measurement lands, and without the + // correction the content under the viewport would jump. useLayoutEffect(() => { const scroller = scrollerRef.current; - scroller.scrollTop = scroller.scrollHeight; - }, [room.id, sent.length]); + const viewportHeight = scroller.clientHeight; + + const pending = anchor.current; + const captured = pending ?? captureAnchor(scroller.scrollTop); + + let changed = false; + for (const row of scroller.querySelectorAll(".timeline-message")) { + if (heights.measure(Number(row.dataset.index), row.getBoundingClientRect().height)) + changed = true; + } + + // The spacers were sized during render, from the heights these measurements + // just replaced, so the scroller is a commit behind the model. Take another + // render, or the offset gets clamped against a height about to change. + if (changed) { + anchor.current = captured; + recordMeasurements((passes) => passes + 1); + return; + } + + anchor.current = null; + if (jumpTarget.current !== null) { + scroller.scrollTop = centeredOffset(jumpTarget.current, viewportHeight); + jumpTarget.current = null; + } else if (pinnedToBottom.current) { + scroller.scrollTop = scroller.scrollHeight; + } else if (pending) { + scroller.scrollTop = heights.offsetAt(pending.index) + pending.offset; + } + + updateRange(rangeFor(scroller.scrollTop, viewportHeight)); + }); // Clicking a reply quote jumps to the message it quotes and leaves it - // highlighted. The offset is computed from rects and assigned to scrollTop - // directly: no smooth behavior and no scrollIntoView, so a timed step stays + // highlighted. The offset comes from the height model rather than the DOM, + // because the quoted message is usually not mounted: scrolling to an + // arbitrary row is the case a virtualizer has to answer without measuring. + // No smooth behavior and no scrollIntoView, so a timed step stays // deterministic. The highlight holds until the next jump rather than // clearing on a timer, for the same reason, and only changes background // colour, so committing it asynchronously cannot move the offset computed // here. - const jumpToMessage = useCallback((messageId) => { - const scroller = scrollerRef.current; - const row = scroller.querySelector(`[data-message-id="${messageId}"]`); - if (!row) - return; - setHighlightedId(messageId); - const rowRect = row.getBoundingClientRect(); - const scrollerRect = scroller.getBoundingClientRect(); - const centeringOffset = (scroller.clientHeight - rowRect.height) / 2; - scroller.scrollTop += rowRect.top - scrollerRect.top - centeringOffset; - }, []); + const jumpToMessage = useCallback( + (messageId) => { + const index = indexById.get(messageId); + if (index === undefined) + return; + const scroller = scrollerRef.current; + setHighlightedId(messageId); + pinnedToBottom.current = false; + jumpTarget.current = index; + scroller.scrollTop = centeredOffset(index, scroller.clientHeight); + updateRange(rangeFor(scroller.scrollTop, scroller.clientHeight)); + }, + [centeredOffset, indexById, rangeFor, updateRange] + ); const actions = useMemo(() => ({ selectRoom: onSelectRoom, jumpToMessage }), [onSelectRoom, jumpToMessage]); - const handleSend = useCallback((text) => setSent((previous) => [...previous, createOutgoingMessage(room, previous.length, text)]), [room]); + const handleSend = useCallback( + (text) => { + pinnedToBottom.current = true; + jumpTarget.current = null; + setSent((previous) => [...previous, createOutgoingMessage(room, previous.length, text)]); + }, + [room] + ); + + // Grouping is taken from the fixture rather than from the window, so a row + // renders the same whether or not the message above it happens to be mounted. + // Deriving it from the window would change a row's height as the window + // moved, which would invalidate the very cache being built here. + const rows = []; + for (let index = range.start; index < range.end; index++) { + const message = messages[index]; + rows.push(); + } return ( -
            - {room.messages.map((message) => - - )} - {sent.map((message) => - - )} +
              +
            diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index 0296b5f90a..910b068513 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -8,7 +8,12 @@ import { generatedImage } from "./graphics.js"; const ROOM_COUNT = 40; -const MESSAGES_PER_ROOM = 150; + +// Real channels hold years of history, which is only feasible to render with a +// windowed timeline. Generation is eager at module load, so this number is a +// tradeoff against load time rather than against the measured steps: see the +// figure recorded in debugging/chat-room-realism-plan.md. +const MESSAGES_PER_ROOM = 1500; const ROOM_NAMES = [ "General", @@ -434,10 +439,13 @@ function buildSenderSequence(roomIndex, count) { const senders = []; let index = hash(roomIndex, 301) % SENDERS.length; while (senders.length < count) { - const runLength = 1 + (hash(roomIndex * 1000 + senders.length, 302) % 3); + // Same construction as a message seed, so one room's run lengths stay + // independent of every other room's. + const seed = roomIndex * count + senders.length; + const runLength = 1 + (hash(seed, 302) % 3); for (let i = 0; i < runLength && senders.length < count; i++) senders.push(SENDERS[index]); - index = (index + 1 + (hash(roomIndex * 1000 + senders.length, 303) % (SENDERS.length - 1))) % SENDERS.length; + index = (index + 1 + (hash(roomIndex * count + senders.length, 303) % (SENDERS.length - 1))) % SENDERS.length; } return senders; } @@ -454,9 +462,15 @@ function buildMessages(roomIndex) { // Inline reply quotes embed a parent message in the child, and always // break the sender group above them. + // + // Most answer something just said, but one in four pulls a message back + // out of the history. Those are the interesting ones for a windowed + // timeline: the quoted message is nowhere in the DOM, so clicking the + // quote has to scroll to a row whose height has never been measured. let replyTo = null; if (i > 0 && hash(seed, 201) % 100 < 18) { - const parent = messages[Math.max(0, i - 1 - (hash(seed, 202) % 6))]; + const distance = hash(seed, 203) % 4 === 0 ? 1 + (hash(seed, 204) % Math.min(i, 400)) : 1 + (hash(seed, 202) % 6); + const parent = messages[Math.max(0, i - distance)]; replyTo = { id: parent.id, sender: parent.sender, excerpt: excerpt(parent.preview, 80) }; } diff --git a/suites-experimental/chat-room/src/row-heights.js b/suites-experimental/chat-room/src/row-heights.js new file mode 100644 index 0000000000..45f40be433 --- /dev/null +++ b/suites-experimental/chat-room/src/row-heights.js @@ -0,0 +1,105 @@ +// The height model behind the windowed timeline: estimate, measure, cache, +// correct. Offsets are prefix sums over a mix of measured and estimated heights, +// rebuilt from the earliest row that changed, which is what turns a scroll offset +// back into a row index without touching the DOM. +// +// Hand-rolled because a chat row's height depends on how its text wraps, which a +// generic virtualizer expects to know up front. + +// A negative height means "not measured yet". 0 is reachable -- a conditionally +// collapsed row measures 0px -- and has to stay measured, or it would be +// re-measured on every pass forever. +const UNMEASURED = -1; + +export class RowHeights { + #estimate; + #count; + #heights; + #offsets; + + // Index of the earliest row whose offset needs recomputing. Offsets at or + // below it are still valid, because changing row i only moves the rows after + // it. #count + 1 means everything is up to date. + #dirtyFrom; + + constructor(count, estimate) { + this.#estimate = estimate; + this.#count = count; + this.#heights = new Float64Array(count).fill(UNMEASURED); + this.#offsets = new Float64Array(count + 1); + this.#dirtyFrom = 0; + } + + get count() { + return this.#count; + } + + // A room only ever grows at the end, when the local user sends a message, so + // every measured height and every offset up to the old end survives. + grow(count) { + if (count <= this.#count) + return; + + const heights = new Float64Array(count); + heights.set(this.#heights); + heights.fill(UNMEASURED, this.#count); + const offsets = new Float64Array(count + 1); + offsets.set(this.#offsets); + + this.#dirtyFrom = Math.min(this.#dirtyFrom, this.#count); + this.#heights = heights; + this.#offsets = offsets; + this.#count = count; + } + + heightAt(index) { + const height = this.#heights[index]; + return height === UNMEASURED ? this.#estimate : height; + } + + // Returns whether the cached height moved, so a caller that read offsets + // before the pass knows they are now stale. + measure(index, height) { + if (this.#heights[index] === height) + return false; + this.#heights[index] = height; + if (index < this.#dirtyFrom) + this.#dirtyFrom = index; + return true; + } + + offsetAt(index) { + this.#recomputeOffsets(); + return this.#offsets[index]; + } + + get totalHeight() { + this.#recomputeOffsets(); + return this.#offsets[this.#count]; + } + + // The row containing a content offset, clamped at both ends. + indexAt(offset) { + this.#recomputeOffsets(); + const offsets = this.#offsets; + let low = 0; + let high = this.#count - 1; + while (low < high) { + const middle = (low + high + 1) >> 1; + if (offsets[middle] <= offset) + low = middle; + else + high = middle - 1; + } + return Math.max(0, low); + } + + #recomputeOffsets() { + if (this.#dirtyFrom > this.#count) + return; + const offsets = this.#offsets; + for (let i = this.#dirtyFrom; i < this.#count; i++) + offsets[i + 1] = offsets[i] + this.heightAt(i); + this.#dirtyFrom = this.#count + 1; + } +} diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css index 48c4f85eb1..8183fce40b 100644 --- a/suites-experimental/chat-room/src/styles.css +++ b/suites-experimental/chat-room/src/styles.css @@ -164,13 +164,17 @@ body { cursor: default; } -/* Timeline */ +/* Timeline. No vertical padding, so scrollTop maps one to one onto the height + model's row offsets. overflow-anchor is off because the timeline corrects its own + scroll position after measuring, and the browser would apply a second correction + for the same content change. */ .timeline { flex: 1 1 auto; margin: 0; - padding: 16px 20px; + padding: 0 20px; list-style: none; overflow-y: auto; + overflow-anchor: none; } .timeline-message { diff --git a/suites-experimental/suites.mjs b/suites-experimental/suites.mjs index 5b6e4dc010..c0ce8826e5 100644 --- a/suites-experimental/suites.mjs +++ b/suites-experimental/suites.mjs @@ -333,6 +333,41 @@ export const ExperimentalSuites = freezeSuites([ await page.waitForElement(".room-list-item"); }, tests: [ + // Each offset mounts a fresh set of rows, measures them, and corrects + // the scroll position against what they measured. The scroll event is + // dispatched by hand because waiting for the browser's would put a + // frame inside the measured window. + new BenchmarkTestStep("ScrollTimeline", async (page) => { + const timeline = page.querySelector("#timeline"); + const viewportHeight = timeline.clientHeight; + + const scrollTo = async (offset) => { + timeline.scrollTop = offset; + timeline.dispatchEvent("scroll"); + await yieldTask(); + page.layout(); + }; + + // A viewport at a time, from the newest message: the windows + // overlap, so rows are recycled and measured heights reused. + // Relative to the current offset rather than to scrollHeight, + // because the total height moves as rows are measured. + const pages = 10; + for (let i = 0; i < pages; i++) + await scrollTo(timeline.scrollTop - viewportHeight); + + // Then cover the whole room in long strides, the way dragging the + // scrollbar does. Every stride lands on rows that have never been + // measured, so the window is replaced outright and the correction + // runs against estimates. + const strides = 10; + for (let i = strides - 1; i >= 0; i--) + await scrollTo(((timeline.scrollHeight - viewportHeight) * i) / (strides - 1)); + + // Back to the newest message, which is where a chat client leaves + // you and where the next step expects to start. + await scrollTo(timeline.scrollHeight); + }), new BenchmarkTestStep("SwitchRooms", async (page) => { const rooms = page.querySelectorAll(".room-list-item"); const iterations = 20; From 5c862f2f7418f68e78f2c29010d46adb11951126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 18:39:07 +0200 Subject: [PATCH 09/18] Load ChatRoom history in pages, anchored against the prepend Preserving the scroll position while content is inserted above the viewport is the chat and feed pattern nothing else in Speedometer exercises, and the one real clients visibly get wrong. A room now opens on the newest 300 of its 1500 messages and fetches 120 more whenever a scroll lands within a viewport of the top. The height model grows at the front as well as the end: a row keeps its index when older history arrives, so measured heights stay valid and only the offsets shift, uniformly, which makes the correction exact. Anchored by hand rather than with the browser's scroll anchoring, which would apply a second correction for the same insertion. LoadOlderMessages is the new step; ScrollTimeline stops one stride short of the top so the two stay independent. Following a reply quote can now load history too. --- suites-experimental/chat-room/README.md | 14 +++-- .../chat-room/src/components/timeline.jsx | 51 ++++++++++++++----- .../chat-room/src/row-heights.js | 39 ++++++++++---- suites-experimental/suites.mjs | 27 +++++++--- 4 files changed, 99 insertions(+), 32 deletions(-) diff --git a/suites-experimental/chat-room/README.md b/suites-experimental/chat-room/README.md index 3580105268..55ca743af7 100644 --- a/suites-experimental/chat-room/README.md +++ b/suites-experimental/chat-room/README.md @@ -20,15 +20,17 @@ concerns. - DOM churn and layout when switching between rooms - Windowed scrolling that measures rows only after mounting them, and corrects the scroll position against what they measured +- Anchoring the viewport when a page of older messages is inserted above it - Flex/grid layout of a typical two-pane chat UI with many small components (avatars, sender names, timestamps, message bodies) ## How are we testing The app renders a sidebar of rooms and, for the selected room, a windowed -timeline of its 1500 messages. All content is generated deterministically at load -time (no network, no backend, no `Math.random`/`Date.now`), so every run renders -identical data. +timeline of its 1500 messages. A room opens on its newest page and loads older +ones as the reader goes back, the way a real client does. All content is +generated deterministically at load time (no network, no backend, no +`Math.random`/`Date.now`), so every run renders identical data. `ScrollTimeline` reads back through a room's history, first a viewport at a time and then in the long strides that dragging the scrollbar produces. The two cover @@ -40,6 +42,12 @@ ever been estimated. timeline is keyed by room id, so a switch fully unmounts the old timeline and mounts the new one. +`LoadOlderMessages` reads back past the start of the loaded history, which +fetches the next page and inserts it above the viewport. The timeline anchors +itself, correcting its own offset once the new rows have been measured, so +`overflow-anchor` is off and the work is the workload's own rather than the +browser's. + ## Developer Documentation The app was created with Vite + React. It can be previewed during development diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index 35f8479c18..94588d4cf7 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -21,6 +21,11 @@ const ESTIMATED_ROW_HEIGHT = 100; // How close to the bottom still counts as following the conversation. const PIN_THRESHOLD = 4; +// A room opens on its newest page and fetches older ones as the reader goes back, +// the way a real client does, which is what inserts content *above* the viewport. +const INITIAL_PAGE = 300; +const OLDER_PAGE = 120; + export default function Timeline({ room, onSelectRoom }) { const scrollerRef = useRef(null); const [highlightedId, setHighlightedId] = useState(null); @@ -32,11 +37,17 @@ export default function Timeline({ room, onSelectRoom }) { const messages = useMemo(() => sent.length ? [...room.messages, ...sent] : room.messages, [room.messages, sent]); - const heights = useMemo(() => new RowHeights(room.messages.length, ESTIMATED_ROW_HEIGHT), [room.messages]); + // How far back the room has been loaded. Rows before this exist in the fixture + // but are not in the timeline yet. + const initialFirst = Math.max(0, room.messages.length - INITIAL_PAGE); + const [firstLoaded, setFirstLoaded] = useState(initialFirst); + + const heights = useMemo(() => new RowHeights(room.messages.length, initialFirst, ESTIMATED_ROW_HEIGHT), [room.messages, initialFirst]); - // Only ever grows, and only at the end, so calling it here is idempotent: a - // re-render with the same messages changes nothing. + // The model only grows -- at the end when the local user sends, at the front + // when older history loads -- so calling these during render is idempotent. heights.grow(messages.length); + heights.extendTo(firstLoaded); const indexById = useMemo(() => new Map(messages.map((message, index) => [message.id, index])), [messages]); @@ -70,7 +81,7 @@ export default function Timeline({ room, onSelectRoom }) { while (last + 1 < heights.count && heights.offsetAt(last + 1) < bottom) last++; return { - start: Math.max(0, first - OVERSCAN), + start: Math.max(heights.first, first - OVERSCAN), end: Math.min(heights.count, last + 1 + OVERSCAN), }; }, @@ -105,17 +116,22 @@ export default function Timeline({ room, onSelectRoom }) { const handleScroll = useCallback(() => { const scroller = scrollerRef.current; pinnedToBottom.current = scroller.scrollHeight - (scroller.scrollTop + scroller.clientHeight) <= PIN_THRESHOLD; + + // Prefetch the next page a viewport before the top, the way a real client + // does. The anchor has to be taken before the model learns about the new + // rows. No in-flight guard: the rows land synchronously, a page below the top. + if (heights.first > 0 && scroller.scrollTop < scroller.clientHeight) { + anchor.current = captureAnchor(scroller.scrollTop); + setFirstLoaded(Math.max(0, heights.first - OLDER_PAGE)); + return; + } + updateRange(rangeFor(scroller.scrollTop, scroller.clientHeight)); - }, [rangeFor, updateRange]); + }, [captureAnchor, heights, rangeFor, updateRange]); // Measure what is mounted, then put the content back where it was. Runs after - // every commit, because a row's height can change without the window moving: - // that is what will make a narrower timeline re-measure in the thread-panel - // phase. - // - // Correcting the scroll position is the part that makes windowing honest. The - // rows that just mounted were laid out against estimates, so the offsets read - // before this pass are stale the moment a measurement lands, and without the + // every commit, because a row's height can change without the window moving. + // The rows that just mounted were laid out against estimates, so without the // correction the content under the viewport would jump. useLayoutEffect(() => { const scroller = scrollerRef.current; @@ -170,10 +186,19 @@ export default function Timeline({ room, onSelectRoom }) { setHighlightedId(messageId); pinnedToBottom.current = false; jumpTarget.current = index; + + // A quote can point further back than the room has been loaded, so the + // history in between has to come in before there is an offset to + // scroll to, the way following a permalink loads its context. + if (index < heights.first) { + heights.extendTo(Math.max(0, index - OVERSCAN)); + setFirstLoaded(heights.first); + } + scroller.scrollTop = centeredOffset(index, scroller.clientHeight); updateRange(rangeFor(scroller.scrollTop, scroller.clientHeight)); }, - [centeredOffset, indexById, rangeFor, updateRange] + [centeredOffset, heights, indexById, rangeFor, updateRange] ); const actions = useMemo(() => ({ selectRoom: onSelectRoom, jumpToMessage }), [onSelectRoom, jumpToMessage]); diff --git a/suites-experimental/chat-room/src/row-heights.js b/suites-experimental/chat-room/src/row-heights.js index 45f40be433..78b4b61173 100644 --- a/suites-experimental/chat-room/src/row-heights.js +++ b/suites-experimental/chat-room/src/row-heights.js @@ -17,25 +17,43 @@ export class RowHeights { #heights; #offsets; - // Index of the earliest row whose offset needs recomputing. Offsets at or - // below it are still valid, because changing row i only moves the rows after - // it. #count + 1 means everything is up to date. + // The oldest loaded row. The model covers [#first, #count); older rows + // contribute no height because they are not in the timeline yet. + #first; + + // Earliest row whose offset needs recomputing: changing row i only moves the + // rows after it. #count + 1 means everything is up to date. #dirtyFrom; - constructor(count, estimate) { + constructor(count, first, estimate) { this.#estimate = estimate; this.#count = count; + this.#first = first; this.#heights = new Float64Array(count).fill(UNMEASURED); this.#offsets = new Float64Array(count + 1); - this.#dirtyFrom = 0; + this.#dirtyFrom = first; } get count() { return this.#count; } - // A room only ever grows at the end, when the local user sends a message, so - // every measured height and every offset up to the old end survives. + get first() { + return this.#first; + } + + // Load older history. Measured heights stay valid because a row keeps its + // index: the offsets all shift by the height of the rows that were added, + // which is what lets the scroll position be corrected exactly. + extendTo(first) { + if (first >= this.#first) + return; + this.#first = first; + this.#dirtyFrom = first; + } + + // A room only ever grows at the end, when the local user sends, so every + // measured height and every offset up to the old end survives. grow(count) { if (count <= this.#count) return; @@ -82,7 +100,7 @@ export class RowHeights { indexAt(offset) { this.#recomputeOffsets(); const offsets = this.#offsets; - let low = 0; + let low = this.#first; let high = this.#count - 1; while (low < high) { const middle = (low + high + 1) >> 1; @@ -91,13 +109,16 @@ export class RowHeights { else high = middle - 1; } - return Math.max(0, low); + return Math.max(this.#first, low); } #recomputeOffsets() { if (this.#dirtyFrom > this.#count) return; const offsets = this.#offsets; + // Offsets run from the oldest loaded row, which is the origin the + // scroller's own coordinates line up with. + offsets[this.#first] = 0; for (let i = this.#dirtyFrom; i < this.#count; i++) offsets[i + 1] = offsets[i] + this.heightAt(i); this.#dirtyFrom = this.#count + 1; diff --git a/suites-experimental/suites.mjs b/suites-experimental/suites.mjs index c0ce8826e5..6e108c5b40 100644 --- a/suites-experimental/suites.mjs +++ b/suites-experimental/suites.mjs @@ -356,16 +356,15 @@ export const ExperimentalSuites = freezeSuites([ for (let i = 0; i < pages; i++) await scrollTo(timeline.scrollTop - viewportHeight); - // Then cover the whole room in long strides, the way dragging the - // scrollbar does. Every stride lands on rows that have never been - // measured, so the window is replaced outright and the correction - // runs against estimates. + // Then long strides, the way dragging the scrollbar does: every + // stride lands on rows that have only ever been estimated, so the + // window is replaced outright. Stops one stride short of the top, + // so it does not trip the prefetch LoadOlderMessages measures. const strides = 10; - for (let i = strides - 1; i >= 0; i--) + for (let i = strides - 1; i >= 1; i--) await scrollTo(((timeline.scrollHeight - viewportHeight) * i) / (strides - 1)); - // Back to the newest message, which is where a chat client leaves - // you and where the next step expects to start. + // Back to the newest message, where the next step expects to start. await scrollTo(timeline.scrollHeight); }), new BenchmarkTestStep("SwitchRooms", async (page) => { @@ -378,6 +377,20 @@ export const ExperimentalSuites = freezeSuites([ page.layout(); } }), + // Reading past the start of the loaded history inserts a page *above* + // the viewport, the case browsers ship scroll anchoring for. The + // timeline anchors by hand instead, so overflow-anchor is off. Each + // iteration also crosses the page the previous one prepended. + new BenchmarkTestStep("LoadOlderMessages", async (page) => { + const timeline = page.querySelector("#timeline"); + const pages = 5; + for (let i = 0; i < pages; i++) { + timeline.scrollTop = 0; + timeline.dispatchEvent("scroll"); + await yieldTask(); + page.layout(); + } + }), ], }, ]); From 0f6a681cf406de82858f8c77c9019fba537ae30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 19:33:01 +0200 Subject: [PATCH 10/18] Share ChatRoom fixture data instead of building it per message A profile shows a ~14ms nursery collection landing inside a timed step in three of the thirty measured windows, and those three are the slowest iteration of their step. The fixture build is not itself measured, but it pushes ~117MB of permanently-live data through the nursery per iteration, and a minor GC costs what it has to promote. The fixture now shares what it can: bodies come from a pool of 2048 rather than one per message, reaction rows collapse to the nine distinct values they always had, and timestamps and initials stop being rebuilt 60,000 times. The pool is drawn from the same seed space, so the spread of row heights is unchanged. The per-message preview string is gone; nothing rendered it. Building the fixtures drops from 197ms to 31ms and retains 14MB instead of 117MB, taking the unmeasured prepare phase from 335ms to 48ms per iteration. --- .../chat-room/src/data/rooms.js | 96 ++++++++++++------- 1 file changed, 64 insertions(+), 32 deletions(-) diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index 910b068513..ffeda2d6ba 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -368,9 +368,18 @@ function buildBlocks(seed) { return blocks; } -// Build a deterministic reactions row. Reaction pills are all over a busy chat, -// so roughly two messages in three have at least one and popular ones collect a -// whole row of them. +// Bodies are shared rather than generated one per message: a body is immutable and +// only read during render, so two messages can point at the same one. Generating +// 60,000 instead dominated this module's load time. Pool size trades load time +// against how often two rows on screen show the same body. +const BODY_POOL_SIZE = 2048; + +const BODY_POOL = []; +for (let i = 0; i < BODY_POOL_SIZE; i++) + BODY_POOL.push(buildBlocks(i)); + +// Reaction pills are all over a busy chat, so roughly two messages in three have +// at least one and popular ones collect a whole row. function buildReactions(seed) { if (seed % 3 === 2) return []; @@ -385,6 +394,15 @@ function buildReactions(seed) { return reactions; } +// Every term above reduces modulo 3, 4 or 12, and REACTION_EMOJIS has twelve +// entries, so a row repeats every twelve seeds and nine distinct rows cover the +// whole corpus. Anyone changing REACTION_EMOJIS has to revisit this cycle. +const REACTION_CYCLE = 12; + +const REACTION_POOL = []; +for (let i = 0; i < REACTION_CYCLE; i++) + REACTION_POOL.push(buildReactions(i)); + // Format a deterministic HH:MM timestamp without touching the real clock. function formatTime(minutesInDay) { const hours = Math.floor(minutesInDay / 60); @@ -393,9 +411,13 @@ function formatTime(minutesInDay) { return `${pad(hours)}:${pad(minutes)}`; } -function buildTime(seed) { - return formatTime(seed % (24 * 60)); -} +// Every timestamp is one of the minutes in a day, so the 1440 strings are built +// once and shared rather than formatted per message. +const MINUTES_IN_DAY = 24 * 60; + +const TIME_STRINGS = []; +for (let minutes = 0; minutes < MINUTES_IN_DAY; minutes++) + TIME_STRINGS.push(formatTime(minutes)); function spansToText(spans) { let text = ""; @@ -432,9 +454,24 @@ function excerpt(text, limit) { return text.length <= limit ? text : `${text.slice(0, limit).trimEnd()}…`; } +const REPLY_EXCERPT_LIMIT = 80; + +// Bodies are shared, so the flattened form is cached against the body rather than +// recomputed and stored for every message that might be quoted. +const BODY_EXCERPTS = new Map(); + +function bodyExcerpt(blocks) { + let text = BODY_EXCERPTS.get(blocks); + if (text === undefined) { + text = excerpt(blocksToText(blocks), REPLY_EXCERPT_LIMIT); + BODY_EXCERPTS.set(blocks, text); + } + return text; +} + // Real conversations arrive in bursts from the same person, which is what makes -// message grouping worth rendering. Emit runs of one to three messages per -// sender, always advancing to a different sender between runs. +// message grouping worth rendering. Runs of one to three, always advancing to a +// different sender between runs. function buildSenderSequence(roomIndex, count) { const senders = []; let index = hash(roomIndex, 301) % SENDERS.length; @@ -452,39 +489,38 @@ function buildSenderSequence(roomIndex, count) { const SENDER_COLOR_INDEX = new Map(SENDERS.map((name, index) => [name, index % AVATAR_COLOR_COUNT])); +// Ten senders, so the initials are derived once rather than per message. +const SENDER_INITIALS = new Map(SENDERS.map((name) => [name, initials(name)])); + function buildMessages(roomIndex) { const senders = buildSenderSequence(roomIndex, MESSAGES_PER_ROOM); const messages = []; for (let i = 0; i < MESSAGES_PER_ROOM; i++) { const seed = roomIndex * MESSAGES_PER_ROOM + i; const sender = senders[i]; - const blocks = buildBlocks(seed); - - // Inline reply quotes embed a parent message in the child, and always - // break the sender group above them. - // - // Most answer something just said, but one in four pulls a message back - // out of the history. Those are the interesting ones for a windowed - // timeline: the quoted message is nowhere in the DOM, so clicking the - // quote has to scroll to a row whose height has never been measured. + const blocks = BODY_POOL[hash(seed, 105) % BODY_POOL_SIZE]; + + // A reply quote embeds its parent in the child and breaks the sender group. + // Most answer something just said, but one in four reaches back into the + // history, where the quoted row is nowhere in the DOM and clicking the quote + // has to scroll to a height that has never been measured. let replyTo = null; if (i > 0 && hash(seed, 201) % 100 < 18) { const distance = hash(seed, 203) % 4 === 0 ? 1 + (hash(seed, 204) % Math.min(i, 400)) : 1 + (hash(seed, 202) % 6); const parent = messages[Math.max(0, i - distance)]; - replyTo = { id: parent.id, sender: parent.sender, excerpt: excerpt(parent.preview, 80) }; + replyTo = { id: parent.id, sender: parent.sender, excerpt: bodyExcerpt(parent.blocks) }; } messages.push({ id: `room-${roomIndex}-msg-${i}`, sender, - senderInitials: initials(sender), + senderInitials: SENDER_INITIALS.get(sender), colorIndex: SENDER_COLOR_INDEX.get(sender), - time: buildTime(seed), + time: TIME_STRINGS[seed % MINUTES_IN_DAY], blocks, - preview: blocksToText(blocks), replyTo, grouped: i > 0 && senders[i - 1] === sender && !replyTo, - reactions: buildReactions(seed), + reactions: REACTION_POOL[seed % REACTION_CYCLE], }); } return messages; @@ -501,7 +537,7 @@ function buildRooms() { colorIndex: i % AVATAR_COLOR_COUNT, initials: initials(name), topic: `Discussion about ${name.toLowerCase()}`, - lastMessage: messages[messages.length - 1].preview, + lastMessage: blocksToText(messages[messages.length - 1].blocks), messages, }); } @@ -518,23 +554,19 @@ export const LOCAL_USER = { colorIndex: SENDERS.length % AVATAR_COLOR_COUNT, }; -// Build a message the local user just sent, in the same shape as the generated -// fixtures so the timeline renders it through the same path. -// -// The timestamp continues from the room's last message instead of reading the -// clock, keeping the workload deterministic. Runs of outgoing messages group -// under the first one, the way a burst from one sender does anywhere else. +// Same shape as the generated fixtures, so the timeline renders it through the same +// path. The timestamp continues from the room's last message instead of reading the +// clock, keeping the workload deterministic. export function createOutgoingMessage(room, sequence, text) { const previous = room.messages[room.messages.length - 1].time.split(":").map(Number); - const sentAt = (previous[0] * 60 + previous[1] + 1 + sequence) % (24 * 60); + const sentAt = (previous[0] * 60 + previous[1] + 1 + sequence) % MINUTES_IN_DAY; return { id: `${room.id}-sent-${sequence}`, sender: LOCAL_USER.name, senderInitials: LOCAL_USER.initials, colorIndex: LOCAL_USER.colorIndex, - time: formatTime(sentAt), + time: TIME_STRINGS[sentAt], blocks: [{ type: "p", spans: [{ type: "text", text }] }], - preview: text, replyTo: null, grouped: sequence > 0, reactions: [], From 0723ade7b2bb866178f2a6a8a06a46eb9d558186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 28 Jul 2026 19:36:12 +0200 Subject: [PATCH 11/18] Build the ChatRoom message index on demand Turning a message id back into a row index is only needed when a reply quote is clicked, and neither a scroll nor a room switch clicks one. Building it during render rebuilt a map over the room's whole history on every switch, inside the timed step, where the profile puts it at 8.8% of SwitchRooms -- the largest single piece of the app's own JavaScript in the run. With the fixture sharing beneath it, this takes the content process from 1.04GB of net allocation to 459MB, minor collections from 77 to 16, and the ones inside a timed step from 14.1ms to 7.2ms on average. What is left is React's own reconciliation filling the nursery, which is the work the steps exist to measure. --- .../chat-room/src/components/timeline.jsx | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index 94588d4cf7..761fb49c52 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -49,11 +49,20 @@ export default function Timeline({ room, onSelectRoom }) { heights.grow(messages.length); heights.extendTo(firstLoaded); - const indexById = useMemo(() => new Map(messages.map((message, index) => [message.id, index])), [messages]); - - // The mounted range, end exclusive. Starts empty because the total height is - // still all estimates at that point: the mount effect below pins the scroller - // to the bottom first, and the window follows from that offset. + // Only a reply-quote click turns an id back into a row, so the index is built + // on first use. Building it during render meant rebuilding a map over the + // room's whole history inside every room switch. + const indexById = useMemo(() => { + let byId = null; + return (id) => { + if (byId === null) + byId = new Map(messages.map((message, index) => [message.id, index])); + return byId.get(id); + }; + }, [messages]); + + // The mounted range, end exclusive. Starts empty because the mount effect below + // pins the scroller to the bottom first, and the window follows from there. const [range, setRange] = useState({ start: 0, end: 0 }); // True while the timeline is following the conversation, the way a chat client @@ -168,18 +177,13 @@ export default function Timeline({ room, onSelectRoom }) { updateRange(rangeFor(scroller.scrollTop, viewportHeight)); }); - // Clicking a reply quote jumps to the message it quotes and leaves it - // highlighted. The offset comes from the height model rather than the DOM, - // because the quoted message is usually not mounted: scrolling to an - // arbitrary row is the case a virtualizer has to answer without measuring. - // No smooth behavior and no scrollIntoView, so a timed step stays - // deterministic. The highlight holds until the next jump rather than - // clearing on a timer, for the same reason, and only changes background - // colour, so committing it asynchronously cannot move the offset computed - // here. + // Jump to the quoted message and leave it highlighted. The offset comes from the + // height model, because the quoted row is usually not mounted. No smooth + // behavior, no scrollIntoView, and the highlight holds until the next jump + // rather than clearing on a timer, so a timed step stays deterministic. const jumpToMessage = useCallback( (messageId) => { - const index = indexById.get(messageId); + const index = indexById(messageId); if (index === undefined) return; const scroller = scrollerRef.current; From 295931e02b6870c53bc6e1574e653df973ef13c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 11 Aug 2026 15:24:26 +0200 Subject: [PATCH 12/18] Draw date separators and an unread divider in the ChatRoom timeline Per-render chrome that chat clients carry and this workload had none of: a labelled rule where the conversation crosses a day, and a marker above the first message the reader has not seen. Neither is a row of its own -- a row here is one message, and the height cache, spacers and offset search are all indexed by message index -- so both are drawn inside the row they belong to, keyed off the message array rather than the mounted window. Day lengths now vary between 8 and 56 messages. At a fixed size the boundary always landed just above the newest page, so no room opened with a separator in view; twenty of the forty now do. Cost is noise: 100.65ms -> 105.00ms over ten Firefox iterations against a +/-20ms spread. --- .../chat-room/src/components/message.jsx | 74 +++++++++++-------- .../chat-room/src/components/timeline.jsx | 16 ++-- .../chat-room/src/data/rooms.js | 67 +++++++++++++++-- suites-experimental/chat-room/src/styles.css | 55 +++++++++++++- 4 files changed, 170 insertions(+), 42 deletions(-) diff --git a/suites-experimental/chat-room/src/components/message.jsx b/suites-experimental/chat-room/src/components/message.jsx index 7a38c6e29e..06fdf3b60b 100644 --- a/suites-experimental/chat-room/src/components/message.jsx +++ b/suites-experimental/chat-room/src/components/message.jsx @@ -3,12 +3,16 @@ import { AVATAR_COLORS } from "../data/rooms.js"; import Reaction from "./reaction.jsx"; import RichText from "./rich-text.jsx"; -// Consecutive messages from the same sender collapse into the previous one, the -// way a chat client renders a burst of them: no repeated avatar or name, just -// the body under a gutter that holds the timestamp on hover. +// Consecutive messages from the same sender collapse into the one above, the way +// a chat client renders a burst: no repeated avatar or name, and the gutter +// carries the timestamp on hover. // The index is the row's position in the whole room, not in the mounted window, // so the timeline can file the measured height against the right message. -export default function Message({ index, message, highlighted }) { +// +// The date separator and the unread divider are drawn inside the row they belong +// to rather than as rows of their own, because the height cache, the spacers and +// the offset search are all indexed by message. +export default function Message({ index, message, highlighted, dateLabel, unreadBelow }) { const { jumpToMessage } = useActions(); const classNames = ["timeline-message"]; if (message.grouped) @@ -18,35 +22,47 @@ export default function Message({ index, message, highlighted }) { return (
          1. - {message.grouped - ? {message.time} - : - {message.senderInitials} - + {dateLabel !== null + &&
            + {dateLabel} +
            + } + {unreadBelow + &&
            + New +
            } -
            - {message.replyTo - && +
            + {message.grouped + ? {message.time} + : + {message.senderInitials} + } - {!message.grouped - &&
            - {message.sender} - {message.time} +
            + {message.replyTo + && + } + {!message.grouped + &&
            + {message.sender} + {message.time} +
            + } +
            +
            - } -
            - + {message.reactions.length > 0 + &&
            + {message.reactions.map((reaction) => + + )} +
            + }
            - {message.reactions.length > 0 - &&
            - {message.reactions.map((reaction) => - - )} -
            - }
          2. ); diff --git a/suites-experimental/chat-room/src/components/timeline.jsx b/suites-experimental/chat-room/src/components/timeline.jsx index 761fb49c52..8c646ac7eb 100644 --- a/suites-experimental/chat-room/src/components/timeline.jsx +++ b/suites-experimental/chat-room/src/components/timeline.jsx @@ -1,6 +1,6 @@ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react"; import { ActionsContext } from "../actions.js"; -import { createOutgoingMessage } from "../data/rooms.js"; +import { createOutgoingMessage, dateLabelFor } from "../data/rooms.js"; import { RowHeights } from "../row-heights.js"; import Composer from "./composer.jsx"; import Message from "./message.jsx"; @@ -216,14 +216,18 @@ export default function Timeline({ room, onSelectRoom }) { [room] ); - // Grouping is taken from the fixture rather than from the window, so a row - // renders the same whether or not the message above it happens to be mounted. - // Deriving it from the window would change a row's height as the window - // moved, which would invalidate the very cache being built here. + // Grouping and the date separator come from the message array rather than from + // the window: a row that changed height as the window moved would invalidate + // the very height cache being built here. + const lastDayIndex = messages[messages.length - 1].dayIndex; const rows = []; for (let index = range.start; index < range.end; index++) { const message = messages[index]; - rows.push(); + // messages[index - 1] is always there: the fixture holds the whole room + // even when only the newest page is in the timeline. + const previous = index > 0 ? messages[index - 1] : null; + const startsDay = previous === null || previous.dayIndex !== message.dayIndex; + rows.push(); } return ( diff --git a/suites-experimental/chat-room/src/data/rooms.js b/suites-experimental/chat-room/src/data/rooms.js index ffeda2d6ba..b7dd89d4f9 100644 --- a/suites-experimental/chat-room/src/data/rooms.js +++ b/suites-experimental/chat-room/src/data/rooms.js @@ -9,12 +9,16 @@ import { generatedImage } from "./graphics.js"; const ROOM_COUNT = 40; -// Real channels hold years of history, which is only feasible to render with a -// windowed timeline. Generation is eager at module load, so this number is a -// tradeoff against load time rather than against the measured steps: see the -// figure recorded in debugging/chat-room-realism-plan.md. +// Real channels hold years of history. Generation is eager at module load, so this +// trades against load time rather than against the measured steps. const MESSAGES_PER_ROOM = 1500; +// How many messages land on one day, as a range because a real channel does not turn +// over the same number every day. The run lengths set how often a row carries a date +// separator, and how short the newest day is decides whether a room opens on one. +const MIN_MESSAGES_PER_DAY = 8; +const MAX_MESSAGES_PER_DAY = 56; + const ROOM_NAMES = [ "General", "Random", @@ -419,6 +423,27 @@ const TIME_STRINGS = []; for (let minutes = 0; minutes < MINUTES_IN_DAY; minutes++) TIME_STRINGS.push(formatTime(minutes)); +const WEEKDAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; + +const MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + +// A synthetic calendar rather than the real one, so the workload stays +// deterministic. Sized for the shortest day a room can have, so no two days in one +// room ever share a label. +const DATE_LABELS = []; +for (let day = 0; day < Math.ceil(MESSAGES_PER_ROOM / MIN_MESSAGES_PER_DAY) + 1; day++) + DATE_LABELS.push(`${WEEKDAYS[day % WEEKDAYS.length]}, ${1 + (day % 28)} ${MONTHS[Math.floor(day / 28) % MONTHS.length]}`); + +// Real clients name the last two days rather than dating them, which is a branch +// per separator and a different string length where a room opens. +export function dateLabelFor(dayIndex, lastDayIndex) { + if (dayIndex === lastDayIndex) + return "Today"; + if (dayIndex === lastDayIndex - 1) + return "Yesterday"; + return DATE_LABELS[dayIndex % DATE_LABELS.length]; +} + function spansToText(spans) { let text = ""; for (const span of spans) { @@ -492,8 +517,25 @@ const SENDER_COLOR_INDEX = new Map(SENDERS.map((name, index) => [name, index % A // Ten senders, so the initials are derived once rather than per message. const SENDER_INITIALS = new Map(SENDERS.map((name) => [name, initials(name)])); +// Which day each message falls on, as runs of varying length. Same construction as +// the sender sequence, and precomputed so a row's day never depends on what is +// mounted. +function buildDaySequence(roomIndex, count) { + const days = []; + let day = 0; + while (days.length < count) { + const span = MAX_MESSAGES_PER_DAY - MIN_MESSAGES_PER_DAY + 1; + const length = MIN_MESSAGES_PER_DAY + (hash(roomIndex * count + day, 901) % span); + for (let i = 0; i < length && days.length < count; i++) + days.push(day); + day++; + } + return days; +} + function buildMessages(roomIndex) { const senders = buildSenderSequence(roomIndex, MESSAGES_PER_ROOM); + const days = buildDaySequence(roomIndex, MESSAGES_PER_ROOM); const messages = []; for (let i = 0; i < MESSAGES_PER_ROOM; i++) { const seed = roomIndex * MESSAGES_PER_ROOM + i; @@ -517,6 +559,9 @@ function buildMessages(roomIndex) { senderInitials: SENDER_INITIALS.get(sender), colorIndex: SENDER_COLOR_INDEX.get(sender), time: TIME_STRINGS[seed % MINUTES_IN_DAY], + // The timeline compares this against the row above to decide whether to + // draw a date separator. + dayIndex: days[i], blocks, replyTo, grouped: i > 0 && senders[i - 1] === sender && !replyTo, @@ -526,6 +571,11 @@ function buildMessages(roomIndex) { return messages; } +// How far back the unread divider sits when the room opens. At least one message +// back, so it is always a row that exists, and never further than a viewport, so +// every room switch lays one out -- which is also the common case in a real client. +const UNREAD_DEPTH = 12; + function buildRooms() { const rooms = []; for (let i = 0; i < ROOM_COUNT; i++) { @@ -538,6 +588,9 @@ function buildRooms() { initials: initials(name), topic: `Discussion about ${name.toLowerCase()}`, lastMessage: blocksToText(messages[messages.length - 1].blocks), + // The last message this user has read. The row after it carries the + // unread divider. + readUpToIndex: Math.max(0, messages.length - 1 - (1 + (hash(i, 701) % (UNREAD_DEPTH - 1)))), messages, }); } @@ -558,7 +611,8 @@ export const LOCAL_USER = { // path. The timestamp continues from the room's last message instead of reading the // clock, keeping the workload deterministic. export function createOutgoingMessage(room, sequence, text) { - const previous = room.messages[room.messages.length - 1].time.split(":").map(Number); + const newest = room.messages[room.messages.length - 1]; + const previous = newest.time.split(":").map(Number); const sentAt = (previous[0] * 60 + previous[1] + 1 + sequence) % MINUTES_IN_DAY; return { id: `${room.id}-sent-${sequence}`, @@ -566,6 +620,9 @@ export function createOutgoingMessage(room, sequence, text) { senderInitials: LOCAL_USER.initials, colorIndex: LOCAL_USER.colorIndex, time: TIME_STRINGS[sentAt], + // Same day as the message it follows, so sending does not put a date + // separator in the middle of the burst. + dayIndex: newest.dayIndex, blocks: [{ type: "p", spans: [{ type: "text", text }] }], replyTo: null, grouped: sequence > 0, diff --git a/suites-experimental/chat-room/src/styles.css b/suites-experimental/chat-room/src/styles.css index 8183fce40b..590d7ba3c0 100644 --- a/suites-experimental/chat-room/src/styles.css +++ b/suites-experimental/chat-room/src/styles.css @@ -177,14 +177,18 @@ body { overflow-anchor: none; } +/* A row is a column: the separators stack above the message's own flex row. */ .timeline-message { + padding: 6px 0; +} + +.timeline-message-row { display: flex; gap: 12px; - padding: 6px 0; } /* Grouped messages drop the avatar and name; the gutter keeps the body aligned - and carries the timestamp, revealed on hover the way real clients do. */ + and carries the timestamp on hover, the way real clients do. */ .timeline-message-grouped { padding: 1px 0; } @@ -202,6 +206,53 @@ body { opacity: 1; } +/* Date separator: a centred label between two rules, drawn with pseudo-element + borders so it costs a real layout box either side. */ +.timeline-date-separator { + display: flex; + align-items: center; + gap: 8px; + margin: 10px 0 6px; +} + +.timeline-date-separator::before, +.timeline-date-separator::after { + content: ""; + flex: 1 1 auto; + border-top: 1px solid #e3e6ea; +} + +.timeline-date-separator-label { + flex: 0 0 auto; + padding: 2px 10px; + border: 1px solid #e3e6ea; + border-radius: 10px; + background-color: #fff; + color: #6b7280; + font-size: 11px; + font-weight: 600; +} + +/* The unread divider sits above the first message the reader has not seen. */ +.timeline-unread-divider { + display: flex; + align-items: center; + gap: 8px; + margin: 8px 0 4px; + border-top: 1px solid #e2564a; +} + +.timeline-unread-divider-label { + margin-left: auto; + padding: 1px 8px; + border-radius: 0 0 8px 8px; + background-color: #e2564a; + color: #fff; + font-size: 10px; + font-weight: 700; + text-transform: uppercase; +} + .timeline-message-body { min-width: 0; flex: 1 1 auto; From 6e3b5e4d0793841b7420f30b365d4bc20514ff2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 11 Aug 2026 15:34:04 +0200 Subject: [PATCH 13/18] Build the ChatRoom workload Output of `npm run build` in suites-experimental/chat-room. Build artifacts only, so it can be dropped and regenerated whenever the source commits below it change. --- .../chat-room/dist/assets/index.css | 1 + .../chat-room/dist/assets/index.js | 51 +++++++++++++++++++ .../chat-room/dist/assets/index.js.map | 1 + suites-experimental/chat-room/dist/index.html | 23 +++++++++ .../chat-room/dist/resources.txt | 4 ++ 5 files changed, 80 insertions(+) create mode 100644 suites-experimental/chat-room/dist/assets/index.css create mode 100644 suites-experimental/chat-room/dist/assets/index.js create mode 100644 suites-experimental/chat-room/dist/assets/index.js.map create mode 100644 suites-experimental/chat-room/dist/index.html create mode 100644 suites-experimental/chat-room/dist/resources.txt diff --git a/suites-experimental/chat-room/dist/assets/index.css b/suites-experimental/chat-room/dist/assets/index.css new file mode 100644 index 0000000000..138f1781e1 --- /dev/null +++ b/suites-experimental/chat-room/dist/assets/index.css @@ -0,0 +1 @@ +*{box-sizing:border-box}html,body{margin:0;height:100%}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#17191c;background-color:#f4f6fa}#root{height:100vh}.app{display:grid;grid-template-columns:300px 1fr;height:100vh;overflow:hidden}.avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:36px;height:36px;border-radius:50%;color:#fff;font-size:13px;font-weight:600;text-transform:uppercase}.room-list{display:flex;flex-direction:column;overflow-y:auto;border-right:1px solid #e3e8ef;background-color:#fff}.room-list-item{display:flex;align-items:center;gap:12px;padding:10px 14px;border:0;border-bottom:1px solid #f0f2f5;background:transparent;text-align:left;cursor:pointer;font:inherit;color:inherit}.room-list-item:hover{background-color:#f4f6fa}.room-list-item-selected{background-color:#e8f0fe}.room-list-item-text{display:flex;flex-direction:column;min-width:0}.room-list-item-name{font-weight:600;font-size:15px}.room-list-item-preview{font-size:13px;color:#737d8c;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.room{display:flex;flex-direction:column;min-width:0;height:100vh}.room-header{padding:14px 20px;border-bottom:1px solid #e3e8ef;background-color:#fff}.room-header-name{margin:0;font-size:18px}.room-header-topic{margin:4px 0 0;font-size:13px;color:#737d8c}.composer{display:flex;flex:0 0 auto;gap:8px;padding:12px 20px;border-top:1px solid #e3e8ef;background-color:#fff}.composer-input{flex:1 1 auto;min-width:0;padding:8px 12px;border:1px solid #d5dbe5;border-radius:8px;font:inherit;font-size:14px;color:inherit}.composer-input:focus{border-color:#9dc0f5;outline:2px solid #dce8fb;outline-offset:-1px}.composer-send{flex:0 0 auto;padding:8px 16px;border:0;border-radius:8px;background-color:#2a6fd6;font:inherit;font-size:14px;font-weight:600;color:#fff;cursor:pointer}.composer-send:hover:enabled{background-color:#245fb8}.composer-send:disabled{background-color:#c8d1de;cursor:default}.timeline{flex:1 1 auto;margin:0;padding:0 20px;list-style:none;overflow-y:auto;overflow-anchor:none}.timeline-message{padding:6px 0}.timeline-message-row{display:flex;gap:12px}.timeline-message-grouped{padding:1px 0}.timeline-message-gutter{flex:0 0 auto;width:36px;font-size:11px;color:#939aa5;text-align:right;opacity:0}.timeline-message-grouped:hover .timeline-message-gutter{opacity:1}.timeline-date-separator{display:flex;align-items:center;gap:8px;margin:10px 0 6px}.timeline-date-separator:before,.timeline-date-separator:after{content:"";flex:1 1 auto;border-top:1px solid #e3e6ea}.timeline-date-separator-label{flex:0 0 auto;padding:2px 10px;border:1px solid #e3e6ea;border-radius:10px;background-color:#fff;color:#6b7280;font-size:11px;font-weight:600}.timeline-unread-divider{display:flex;align-items:center;gap:8px;margin:8px 0 4px;border-top:1px solid #e2564a}.timeline-unread-divider-label{margin-left:auto;padding:1px 8px;border-radius:0 0 8px 8px;background-color:#e2564a;color:#fff;font-size:10px;font-weight:700;text-transform:uppercase}.timeline-message-body{min-width:0;flex:1 1 auto}.timeline-message-highlighted{background-color:#fff6d8}.timeline-message-reply{display:flex;gap:6px;align-items:baseline;width:100%;margin-bottom:2px;padding:0 0 0 8px;border:0;border-left:2px solid #d5dbe5;background:transparent;font:inherit;font-size:12px;color:#737d8c;text-align:left;cursor:pointer}.timeline-message-reply:hover{border-left-color:#9dc0f5;color:#5a6472}.timeline-message-reply-sender{flex:0 0 auto;font-weight:600;color:#5a6472}.timeline-message-reply-excerpt{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.timeline-message-meta{display:flex;align-items:baseline;gap:8px}.timeline-message-sender{font-weight:600;font-size:14px}.timeline-message-time{font-size:12px;color:#939aa5}.timeline-message-text{margin-top:2px;font-size:14px;line-height:1.4;color:#2c3038}.rich-paragraph{margin:0 0 4px}.rich-paragraph:last-child{margin-bottom:0}.rich-code{padding:1px 4px;border:1px solid #e3e8ef;border-radius:4px;background-color:#f4f6fa;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9em;color:#b4295c}.rich-code-block{margin:4px 0;padding:8px 10px;overflow-x:auto;border:1px solid #e3e8ef;border-radius:6px;background-color:#f8fafc;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.45;white-space:pre}.rich-image{display:block;max-width:100%;height:auto;margin:6px 0;border:1px solid #e3e8ef;border-radius:8px}.rich-unfurl{display:flex;gap:10px;max-width:460px;margin:6px 0;padding:10px;border:1px solid #e3e8ef;border-left:3px solid #9dc0f5;border-radius:8px;background-color:#fbfcfe;color:inherit;text-decoration:none}.rich-unfurl:hover{background-color:#f4f8ff}.rich-unfurl-thumb{flex:0 0 auto;border-radius:6px}.rich-unfurl-body{display:flex;flex-direction:column;gap:2px;min-width:0}.rich-unfurl-site{font-size:11px;font-weight:600;color:#737d8c;text-transform:uppercase;letter-spacing:.02em}.rich-unfurl-title{font-weight:600;color:#24509b}.rich-unfurl-description{font-size:13px;color:#5a6472}.rich-quote{margin:4px 0;padding:2px 0 2px 10px;border-left:3px solid #c8d1de;color:#5a6472}.rich-list{margin:4px 0;padding-left:20px}.rich-link{color:#2a6fd6;text-decoration:underline}.rich-pill{padding:0 5px;border:0;border-radius:10px;font:inherit;font-weight:500;white-space:nowrap}.rich-pill-mention{background-color:#e2ecfd;color:#24509b}.rich-pill-room{background-color:#e6f6ee;color:#1c6e4c;cursor:pointer}.rich-pill-room:hover{background-color:#d3efe1}.timeline-message-reactions{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}.reaction{display:inline-flex;align-items:center;gap:4px;padding:1px 8px;border:1px solid #e3e8ef;border-radius:12px;background-color:#f4f6fa;font:inherit;font-size:12px;color:inherit;cursor:pointer}.reaction:hover{border-color:#c8d1de;background-color:#eaeef5}.reaction-mine{border-color:#9dc0f5;background-color:#e2ecfd}.reaction-mine .reaction-count{color:#24509b;font-weight:600}.reaction-count{color:#737d8c} diff --git a/suites-experimental/chat-room/dist/assets/index.js b/suites-experimental/chat-room/dist/assets/index.js new file mode 100644 index 0000000000..f9310361d3 --- /dev/null +++ b/suites-experimental/chat-room/dist/assets/index.js @@ -0,0 +1,51 @@ +var ei=(l,t,a)=>{if(!t.has(l))throw TypeError("Cannot "+a)};var L=(l,t,a)=>(ei(l,t,"read from private field"),a?a.call(l):t.get(l)),Yt=(l,t,a)=>{if(t.has(l))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(l):t.set(l,a)},zl=(l,t,a,u)=>(ei(l,t,"write to private field"),u?u.call(l,a):t.set(l,a),a);var Me=(l,t,a)=>(ei(l,t,"access private method"),a);var Y0={exports:{}},qn={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var lm=Symbol.for("react.transitional.element"),tm=Symbol.for("react.fragment");function q0(l,t,a){var u=null;if(a!==void 0&&(u=""+a),t.key!==void 0&&(u=""+t.key),"key"in t){a={};for(var e in t)e!=="key"&&(a[e]=t[e])}else a=t;return t=a.ref,{$$typeof:lm,type:l,key:u,ref:t!==void 0?t:null,props:a}}qn.Fragment=tm;qn.jsx=q0;qn.jsxs=q0;Y0.exports=qn;var E=Y0.exports,G0={exports:{}},Gn={},X0={exports:{}},Q0={};/** + * @license React + * scheduler.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */(function(l){function t(b,D){var U=b.length;b.push(D);l:for(;0>>1,vl=b[il];if(0>>1;ile(ui,U))mae(_e,ui)?(b[il]=_e,b[ma]=U,il=ma):(b[il]=ui,b[ze]=U,il=ze);else if(mae(_e,U))b[il]=_e,b[ma]=U,il=ma;else break l}}return D}function e(b,D){var U=b.sortIndex-D.sortIndex;return U!==0?U:b.id-D.id}if(l.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var n=performance;l.unstable_now=function(){return n.now()}}else{var i=Date,c=i.now();l.unstable_now=function(){return i.now()-c}}var f=[],h=[],g=1,y=null,m=3,v=!1,p=!1,z=!1,j=!1,o=typeof setTimeout=="function"?setTimeout:null,s=typeof clearTimeout=="function"?clearTimeout:null,d=typeof setImmediate<"u"?setImmediate:null;function r(b){for(var D=a(h);D!==null;){if(D.callback===null)u(h);else if(D.startTime<=b)u(h),D.sortIndex=D.expirationTime,t(f,D);else break;D=a(h)}}function A(b){if(z=!1,r(b),!p)if(a(f)!==null)p=!0,N||(N=!0,et());else{var D=a(h);D!==null&&ul(A,D.startTime-b)}}var N=!1,T=-1,O=5,C=-1;function x(){return j?!0:!(l.unstable_now()-Cb&&x());){var il=y.callback;if(typeof il=="function"){y.callback=null,m=y.priorityLevel;var vl=il(y.expirationTime<=b);if(b=l.unstable_now(),typeof vl=="function"){y.callback=vl,r(b),D=!0;break t}y===a(f)&&u(f),r(b)}else u(f);y=a(f)}if(y!==null)D=!0;else{var Ae=a(h);Ae!==null&&ul(A,Ae.startTime-b),D=!1}}break l}finally{y=null,m=U,v=!1}D=void 0}}finally{D?et():N=!1}}}var et;if(typeof d=="function")et=function(){d(Dl)};else if(typeof MessageChannel<"u"){var _=new MessageChannel,X=_.port2;_.port1.onmessage=Dl,et=function(){X.postMessage(null)}}else et=function(){o(Dl,0)};function ul(b,D){T=o(function(){b(l.unstable_now())},D)}l.unstable_IdlePriority=5,l.unstable_ImmediatePriority=1,l.unstable_LowPriority=4,l.unstable_NormalPriority=3,l.unstable_Profiling=null,l.unstable_UserBlockingPriority=2,l.unstable_cancelCallback=function(b){b.callback=null},l.unstable_forceFrameRate=function(b){0>b||125il?(b.sortIndex=U,t(h,b),a(f)===null&&b===a(h)&&(z?(s(T),T=-1):z=!0,ul(A,U-il))):(b.sortIndex=vl,t(f,b),p||v||(p=!0,N||(N=!0,et()))),b},l.unstable_shouldYield=x,l.unstable_wrapCallback=function(b){var D=m;return function(){var U=m;m=D;try{return b.apply(this,arguments)}finally{m=U}}}})(Q0);X0.exports=Q0;var am=X0.exports,Z0={exports:{}},H={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var wc=Symbol.for("react.transitional.element"),um=Symbol.for("react.portal"),em=Symbol.for("react.fragment"),nm=Symbol.for("react.strict_mode"),im=Symbol.for("react.profiler"),cm=Symbol.for("react.consumer"),fm=Symbol.for("react.context"),sm=Symbol.for("react.forward_ref"),om=Symbol.for("react.suspense"),hm=Symbol.for("react.memo"),L0=Symbol.for("react.lazy"),mm=Symbol.for("react.activity"),ls=Symbol.iterator;function dm(l){return l===null||typeof l!="object"?null:(l=ls&&l[ls]||l["@@iterator"],typeof l=="function"?l:null)}var V0={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},K0=Object.assign,J0={};function vu(l,t,a){this.props=l,this.context=t,this.refs=J0,this.updater=a||V0}vu.prototype.isReactComponent={};vu.prototype.setState=function(l,t){if(typeof l!="object"&&typeof l!="function"&&l!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,l,t,"setState")};vu.prototype.forceUpdate=function(l){this.updater.enqueueForceUpdate(this,l,"forceUpdate")};function w0(){}w0.prototype=vu.prototype;function $c(l,t,a){this.props=l,this.context=t,this.refs=J0,this.updater=a||V0}var Wc=$c.prototype=new w0;Wc.constructor=$c;K0(Wc,vu.prototype);Wc.isPureReactComponent=!0;var ts=Array.isArray;function Wi(){}var ll={H:null,A:null,T:null,S:null},$0=Object.prototype.hasOwnProperty;function Fc(l,t,a){var u=a.ref;return{$$typeof:wc,type:l,key:t,ref:u!==void 0?u:null,props:a}}function ym(l,t){return Fc(l.type,t,l.props)}function kc(l){return typeof l=="object"&&l!==null&&l.$$typeof===wc}function vm(l){var t={"=":"=0",":":"=2"};return"$"+l.replace(/[=:]/g,function(a){return t[a]})}var as=/\/+/g;function ni(l,t){return typeof l=="object"&&l!==null&&l.key!=null?vm(""+l.key):t.toString(36)}function gm(l){switch(l.status){case"fulfilled":return l.value;case"rejected":throw l.reason;default:switch(typeof l.status=="string"?l.then(Wi,Wi):(l.status="pending",l.then(function(t){l.status==="pending"&&(l.status="fulfilled",l.value=t)},function(t){l.status==="pending"&&(l.status="rejected",l.reason=t)})),l.status){case"fulfilled":return l.value;case"rejected":throw l.reason}}throw l}function xa(l,t,a,u,e){var n=typeof l;(n==="undefined"||n==="boolean")&&(l=null);var i=!1;if(l===null)i=!0;else switch(n){case"bigint":case"string":case"number":i=!0;break;case"object":switch(l.$$typeof){case wc:case um:i=!0;break;case L0:return i=l._init,xa(i(l._payload),t,a,u,e)}}if(i)return e=e(l),i=u===""?"."+ni(l,0):u,ts(e)?(a="",i!=null&&(a=i.replace(as,"$&/")+"/"),xa(e,t,a,"",function(h){return h})):e!=null&&(kc(e)&&(e=ym(e,a+(e.key==null||l&&l.key===e.key?"":(""+e.key).replace(as,"$&/")+"/")+i)),t.push(e)),1;i=0;var c=u===""?".":u+":";if(ts(l))for(var f=0;f"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(k0)}catch(l){console.error(l)}}k0(),W0.exports=Ol;var Em=W0.exports;/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var yl=am,I0=J,Am=Em;function S(l){var t="https://react.dev/errors/"+l;if(1Ga||(l.current=tc[Ga],tc[Ga]=null,Ga--)}function k(l,t){Ga++,tc[Ga]=l.current,l.current=t}var yt=vt(null),Fu=vt(null),kt=vt(null),fn=vt(null);function sn(l,t){switch(k(kt,t),k(Fu,l),k(yt,null),t.nodeType){case 9:case 11:l=(l=t.documentElement)&&(l=l.namespaceURI)?h0(l):0;break;default:if(l=t.tagName,t=t.namespaceURI)t=h0(t),l=_1(t,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}Sl(yt),k(yt,l)}function eu(){Sl(yt),Sl(Fu),Sl(kt)}function ac(l){l.memoizedState!==null&&k(fn,l);var t=yt.current,a=_1(t,l.type);t!==a&&(k(Fu,l),k(yt,a))}function on(l){Fu.current===l&&(Sl(yt),Sl(Fu)),fn.current===l&&(Sl(fn),ce._currentValue=Sa)}var ii,is;function ya(l){if(ii===void 0)try{throw Error()}catch(a){var t=a.stack.trim().match(/\n( *(at )?)/);ii=t&&t[1]||"",is=-1)":-1e||f[u]!==h[e]){var g=` +`+f[u].replace(" at new "," at ");return l.displayName&&g.includes("")&&(g=g.replace("",l.displayName)),g}while(1<=u&&0<=e);break}}}finally{ci=!1,Error.prepareStackTrace=a}return(a=l?l.displayName||l.name:"")?ya(a):""}function Dm(l,t){switch(l.tag){case 26:case 27:case 5:return ya(l.type);case 16:return ya("Lazy");case 13:return l.child!==t&&t!==null?ya("Suspense Fallback"):ya("Suspense");case 19:return ya("SuspenseList");case 0:case 15:return fi(l.type,!1);case 11:return fi(l.type.render,!1);case 1:return fi(l.type,!0);case 31:return ya("Activity");default:return""}}function cs(l){try{var t="",a=null;do t+=Dm(l,a),a=l,l=l.return;while(l);return t}catch(u){return` +Error generating stack: `+u.message+` +`+u.stack}}var uc=Object.prototype.hasOwnProperty,lf=yl.unstable_scheduleCallback,si=yl.unstable_cancelCallback,Nm=yl.unstable_shouldYield,Um=yl.unstable_requestPaint,Ql=yl.unstable_now,Hm=yl.unstable_getCurrentPriorityLevel,no=yl.unstable_ImmediatePriority,io=yl.unstable_UserBlockingPriority,hn=yl.unstable_NormalPriority,Rm=yl.unstable_LowPriority,co=yl.unstable_IdlePriority,Cm=yl.log,jm=yl.unstable_setDisableYieldValue,me=null,Zl=null;function Kt(l){if(typeof Cm=="function"&&jm(l),Zl&&typeof Zl.setStrictMode=="function")try{Zl.setStrictMode(me,l)}catch{}}var Ll=Math.clz32?Math.clz32:Ym,xm=Math.log,Bm=Math.LN2;function Ym(l){return l>>>=0,l===0?32:31-(xm(l)/Bm|0)|0}var Ne=256,Ue=262144,He=4194304;function va(l){var t=l&42;if(t!==0)return t;switch(l&-l){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:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return l&261888;case 262144:case 524288:case 1048576:case 2097152:return l&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return l&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return l}}function Qn(l,t,a){var u=l.pendingLanes;if(u===0)return 0;var e=0,n=l.suspendedLanes,i=l.pingedLanes;l=l.warmLanes;var c=u&134217727;return c!==0?(u=c&~n,u!==0?e=va(u):(i&=c,i!==0?e=va(i):a||(a=c&~l,a!==0&&(e=va(a))))):(c=u&~n,c!==0?e=va(c):i!==0?e=va(i):a||(a=u&~l,a!==0&&(e=va(a)))),e===0?0:t!==0&&t!==e&&!(t&n)&&(n=e&-e,a=t&-t,n>=a||n===32&&(a&4194048)!==0)?t:e}function de(l,t){return(l.pendingLanes&~(l.suspendedLanes&~l.pingedLanes)&t)===0}function qm(l,t){switch(l){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32: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:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function fo(){var l=He;return He<<=1,!(He&62914560)&&(He=4194304),l}function oi(l){for(var t=[],a=0;31>a;a++)t.push(l);return t}function ye(l,t){l.pendingLanes|=t,t!==268435456&&(l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0)}function Gm(l,t,a,u,e,n){var i=l.pendingLanes;l.pendingLanes=a,l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0,l.expiredLanes&=a,l.entangledLanes&=a,l.errorRecoveryDisabledLanes&=a,l.shellSuspendCounter=0;var c=l.entanglements,f=l.expirationTimes,h=l.hiddenUpdates;for(a=i&~a;0"u")return null;try{return l.activeElement||l.body}catch{return l.body}}var Km=/[\n"\\]/g;function Il(l){return l.replace(Km,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function ic(l,t,a,u,e,n,i,c){l.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?l.type=i:l.removeAttribute("type"),t!=null?i==="number"?(t===0&&l.value===""||l.value!=t)&&(l.value=""+Wl(t)):l.value!==""+Wl(t)&&(l.value=""+Wl(t)):i!=="submit"&&i!=="reset"||l.removeAttribute("value"),t!=null?cc(l,i,Wl(t)):a!=null?cc(l,i,Wl(a)):u!=null&&l.removeAttribute("value"),e==null&&n!=null&&(l.defaultChecked=!!n),e!=null&&(l.checked=e&&typeof e!="function"&&typeof e!="symbol"),c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?l.name=""+Wl(c):l.removeAttribute("name")}function So(l,t,a,u,e,n,i,c){if(n!=null&&typeof n!="function"&&typeof n!="symbol"&&typeof n!="boolean"&&(l.type=n),t!=null||a!=null){if(!(n!=="submit"&&n!=="reset"||t!=null)){nc(l);return}a=a!=null?""+Wl(a):"",t=t!=null?""+Wl(t):a,c||t===l.value||(l.value=t),l.defaultValue=t}u=u??e,u=typeof u!="function"&&typeof u!="symbol"&&!!u,l.checked=c?l.checked:!!u,l.defaultChecked=!!u,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(l.name=i),nc(l)}function cc(l,t,a){t==="number"&&mn(l.ownerDocument)===l||l.defaultValue===""+a||(l.defaultValue=""+a)}function ka(l,t,a,u){if(l=l.options,t){t={};for(var e=0;e"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),sc=!1;if(Ht)try{var zu={};Object.defineProperty(zu,"passive",{get:function(){sc=!0}}),window.addEventListener("test",zu,zu),window.removeEventListener("test",zu,zu)}catch{sc=!1}var Jt=null,cf=null,we=null;function Ao(){if(we)return we;var l,t=cf,a=t.length,u,e="value"in Jt?Jt.value:Jt.textContent,n=e.length;for(l=0;l=Yu),Ss=String.fromCharCode(32),bs=!1;function _o(l,t){switch(l){case"keyup":return bd.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Mo(l){return l=l.detail,typeof l=="object"&&"data"in l?l.data:null}var Za=!1;function Td(l,t){switch(l){case"compositionend":return Mo(t);case"keypress":return t.which!==32?null:(bs=!0,Ss);case"textInput":return l=t.data,l===Ss&&bs?null:l;default:return null}}function Ed(l,t){if(Za)return l==="compositionend"||!sf&&_o(l,t)?(l=Ao(),we=cf=Jt=null,Za=!1,l):null;switch(l){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:a,offset:t-l};l=u}l:{for(;a;){if(a.nextSibling){a=a.nextSibling;break l}a=a.parentNode}a=void 0}a=zs(a)}}function Uo(l,t){return l&&t?l===t?!0:l&&l.nodeType===3?!1:t&&t.nodeType===3?Uo(l,t.parentNode):"contains"in l?l.contains(t):l.compareDocumentPosition?!!(l.compareDocumentPosition(t)&16):!1:!1}function Ho(l){l=l!=null&&l.ownerDocument!=null&&l.ownerDocument.defaultView!=null?l.ownerDocument.defaultView:window;for(var t=mn(l.document);t instanceof l.HTMLIFrameElement;){try{var a=typeof t.contentWindow.location.href=="string"}catch{a=!1}if(a)l=t.contentWindow;else break;t=mn(l.document)}return t}function of(l){var t=l&&l.nodeName&&l.nodeName.toLowerCase();return t&&(t==="input"&&(l.type==="text"||l.type==="search"||l.type==="tel"||l.type==="url"||l.type==="password")||t==="textarea"||l.contentEditable==="true")}var Ud=Ht&&"documentMode"in document&&11>=document.documentMode,La=null,oc=null,Gu=null,hc=!1;function Ms(l,t,a){var u=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;hc||La==null||La!==mn(u)||(u=La,"selectionStart"in u&&of(u)?u={start:u.selectionStart,end:u.selectionEnd}:(u=(u.ownerDocument&&u.ownerDocument.defaultView||window).getSelection(),u={anchorNode:u.anchorNode,anchorOffset:u.anchorOffset,focusNode:u.focusNode,focusOffset:u.focusOffset}),Gu&&Pu(Gu,u)||(Gu=u,u=Un(oc,"onSelect"),0>=i,e-=i,ot=1<<32-Ll(t)+e|a<O?(C=T,T=null):C=T.sibling;var x=m(o,T,d[O],r);if(x===null){T===null&&(T=C);break}l&&T&&x.alternate===null&&t(o,T),s=n(x,s,O),N===null?A=x:N.sibling=x,N=x,T=C}if(O===d.length)return a(o,T),G&&Et(o,O),A;if(T===null){for(;OO?(C=T,T=null):C=T.sibling;var Dl=m(o,T,x.value,r);if(Dl===null){T===null&&(T=C);break}l&&T&&Dl.alternate===null&&t(o,T),s=n(Dl,s,O),N===null?A=Dl:N.sibling=Dl,N=Dl,T=C}if(x.done)return a(o,T),G&&Et(o,O),A;if(T===null){for(;!x.done;O++,x=d.next())x=y(o,x.value,r),x!==null&&(s=n(x,s,O),N===null?A=x:N.sibling=x,N=x);return G&&Et(o,O),A}for(T=u(T);!x.done;O++,x=d.next())x=v(T,o,O,x.value,r),x!==null&&(l&&x.alternate!==null&&T.delete(x.key===null?O:x.key),s=n(x,s,O),N===null?A=x:N.sibling=x,N=x);return l&&T.forEach(function(et){return t(o,et)}),G&&Et(o,O),A}function j(o,s,d,r){if(typeof d=="object"&&d!==null&&d.type===qa&&d.key===null&&(d=d.props.children),typeof d=="object"&&d!==null){switch(d.$$typeof){case De:l:{for(var A=d.key;s!==null;){if(s.key===A){if(A=d.type,A===qa){if(s.tag===7){a(o,s.sibling),r=e(s,d.props.children),r.return=o,o=r;break l}}else if(s.elementType===A||typeof A=="object"&&A!==null&&A.$$typeof===Gt&&ga(A)===s.type){a(o,s.sibling),r=e(s,d.props),Mu(r,d),r.return=o,o=r;break l}a(o,s);break}else t(o,s);s=s.sibling}d.type===qa?(r=ba(d.props.children,o.mode,r,d.key),r.return=o,o=r):(r=We(d.type,d.key,d.props,null,o.mode,r),Mu(r,d),r.return=o,o=r)}return i(o);case Uu:l:{for(A=d.key;s!==null;){if(s.key===A)if(s.tag===4&&s.stateNode.containerInfo===d.containerInfo&&s.stateNode.implementation===d.implementation){a(o,s.sibling),r=e(s,d.children||[]),r.return=o,o=r;break l}else{a(o,s);break}else t(o,s);s=s.sibling}r=bi(d,o.mode,r),r.return=o,o=r}return i(o);case Gt:return d=ga(d),j(o,s,d,r)}if(Hu(d))return p(o,s,d,r);if(Au(d)){if(A=Au(d),typeof A!="function")throw Error(S(150));return d=A.call(d),z(o,s,d,r)}if(typeof d.then=="function")return j(o,s,xe(d),r);if(d.$$typeof===_t)return j(o,s,je(o,d),r);Be(o,d)}return typeof d=="string"&&d!==""||typeof d=="number"||typeof d=="bigint"?(d=""+d,s!==null&&s.tag===6?(a(o,s.sibling),r=e(s,d),r.return=o,o=r):(a(o,s),r=Si(d,o.mode,r),r.return=o,o=r),i(o)):a(o,s)}return function(o,s,d,r){try{ae=0;var A=j(o,s,d,r);return lu=null,A}catch(T){if(T===bu||T===wn)throw T;var N=Gl(29,T,null,o.mode);return N.lanes=r,N.return=o,N}finally{}}}var _a=Jo(!0),wo=Jo(!1),Xt=!1;function bf(l){l.updateQueue={baseState:l.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Sc(l,t){l=l.updateQueue,t.updateQueue===l&&(t.updateQueue={baseState:l.baseState,firstBaseUpdate:l.firstBaseUpdate,lastBaseUpdate:l.lastBaseUpdate,shared:l.shared,callbacks:null})}function Pt(l){return{lane:l,tag:0,payload:null,callback:null,next:null}}function la(l,t,a){var u=l.updateQueue;if(u===null)return null;if(u=u.shared,Q&2){var e=u.pending;return e===null?t.next=t:(t.next=e.next,e.next=t),u.pending=t,t=yn(l),qo(l,null,a),t}return Jn(l,u,t,a),yn(l)}function Qu(l,t,a){if(t=t.updateQueue,t!==null&&(t=t.shared,(a&4194048)!==0)){var u=t.lanes;u&=l.pendingLanes,a|=u,t.lanes=a,oo(l,a)}}function Ti(l,t){var a=l.updateQueue,u=l.alternate;if(u!==null&&(u=u.updateQueue,a===u)){var e=null,n=null;if(a=a.firstBaseUpdate,a!==null){do{var i={lane:a.lane,tag:a.tag,payload:a.payload,callback:null,next:null};n===null?e=n=i:n=n.next=i,a=a.next}while(a!==null);n===null?e=n=t:n=n.next=t}else e=n=t;a={baseState:u.baseState,firstBaseUpdate:e,lastBaseUpdate:n,shared:u.shared,callbacks:u.callbacks},l.updateQueue=a;return}l=a.lastBaseUpdate,l===null?a.firstBaseUpdate=t:l.next=t,a.lastBaseUpdate=t}var bc=!1;function Zu(){if(bc){var l=Pa;if(l!==null)throw l}}function Lu(l,t,a,u){bc=!1;var e=l.updateQueue;Xt=!1;var n=e.firstBaseUpdate,i=e.lastBaseUpdate,c=e.shared.pending;if(c!==null){e.shared.pending=null;var f=c,h=f.next;f.next=null,i===null?n=h:i.next=h,i=f;var g=l.alternate;g!==null&&(g=g.updateQueue,c=g.lastBaseUpdate,c!==i&&(c===null?g.firstBaseUpdate=h:c.next=h,g.lastBaseUpdate=f))}if(n!==null){var y=e.baseState;i=0,g=h=f=null,c=n;do{var m=c.lane&-536870913,v=m!==c.lane;if(v?(q&m)===m:(u&m)===m){m!==0&&m===cu&&(bc=!0),g!==null&&(g=g.next={lane:0,tag:c.tag,payload:c.payload,callback:null,next:null});l:{var p=l,z=c;m=t;var j=a;switch(z.tag){case 1:if(p=z.payload,typeof p=="function"){y=p.call(j,y,m);break l}y=p;break l;case 3:p.flags=p.flags&-65537|128;case 0:if(p=z.payload,m=typeof p=="function"?p.call(j,y,m):p,m==null)break l;y=tl({},y,m);break l;case 2:Xt=!0}}m=c.callback,m!==null&&(l.flags|=64,v&&(l.flags|=8192),v=e.callbacks,v===null?e.callbacks=[m]:v.push(m))}else v={lane:m,tag:c.tag,payload:c.payload,callback:c.callback,next:null},g===null?(h=g=v,f=y):g=g.next=v,i|=m;if(c=c.next,c===null){if(c=e.shared.pending,c===null)break;v=c,c=v.next,v.next=null,e.lastBaseUpdate=v,e.shared.pending=null}}while(1);g===null&&(f=y),e.baseState=f,e.firstBaseUpdate=h,e.lastBaseUpdate=g,n===null&&(e.shared.lanes=0),sa|=i,l.lanes=i,l.memoizedState=y}}function $o(l,t){if(typeof l!="function")throw Error(S(191,l));l.call(t)}function Wo(l,t){var a=l.callbacks;if(a!==null)for(l.callbacks=null,l=0;ln?n:8;var i=M.T,c={};M.T=c,Rf(l,!1,t,a);try{var f=e(),h=M.S;if(h!==null&&h(c,f),f!==null&&typeof f=="object"&&typeof f.then=="function"){var g=Gd(f,u);Vu(l,t,g,Vl(l))}else Vu(l,t,u,Vl(l))}catch(y){Vu(l,t,{then:function(){},status:"rejected",reason:y},Vl())}finally{Z.p=n,i!==null&&c.types!==null&&(i.types=c.types),M.T=i}}function Kd(){}function zc(l,t,a,u){if(l.tag!==5)throw Error(S(476));var e=ph(l).queue;bh(l,e,t,Sa,a===null?Kd:function(){return Th(l),a(u)})}function ph(l){var t=l.memoizedState;if(t!==null)return t;t={memoizedState:Sa,baseState:Sa,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ct,lastRenderedState:Sa},next:null};var a={};return t.next={memoizedState:a,baseState:a,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ct,lastRenderedState:a},next:null},l.memoizedState=t,l=l.alternate,l!==null&&(l.memoizedState=t),t}function Th(l){var t=ph(l);t.next===null&&(t=l.alternate.memoizedState),Vu(l,t.next.queue,{},Vl())}function Hf(){return El(ce)}function Eh(){return fl().memoizedState}function Ah(){return fl().memoizedState}function Jd(l){for(var t=l.return;t!==null;){switch(t.tag){case 24:case 3:var a=Vl();l=Pt(a);var u=la(t,l,a);u!==null&&(jl(u,t,a),Qu(u,t,a)),t={cache:gf()},l.payload=t;return}t=t.return}}function wd(l,t,a){var u=Vl();a={lane:u,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},kn(l)?_h(t,a):(a=mf(l,t,a,u),a!==null&&(jl(a,l,u),Mh(a,t,u)))}function zh(l,t,a){var u=Vl();Vu(l,t,a,u)}function Vu(l,t,a,u){var e={lane:u,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null};if(kn(l))_h(t,e);else{var n=l.alternate;if(l.lanes===0&&(n===null||n.lanes===0)&&(n=t.lastRenderedReducer,n!==null))try{var i=t.lastRenderedState,c=n(i,a);if(e.hasEagerState=!0,e.eagerState=c,Kl(c,i))return Jn(l,t,e,0),F===null&&Kn(),!1}catch{}finally{}if(a=mf(l,t,e,u),a!==null)return jl(a,l,u),Mh(a,t,u),!0}return!1}function Rf(l,t,a,u){if(u={lane:2,revertLane:Qf(),gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},kn(l)){if(t)throw Error(S(479))}else t=mf(l,a,u,2),t!==null&&jl(t,l,2)}function kn(l){var t=l.alternate;return l===R||t!==null&&t===R}function _h(l,t){tu=pn=!0;var a=l.pending;a===null?t.next=t:(t.next=a.next,a.next=t),l.pending=t}function Mh(l,t,a){if(a&4194048){var u=t.lanes;u&=l.pendingLanes,a|=u,t.lanes=a,oo(l,a)}}var ee={readContext:El,use:Wn,useCallback:el,useContext:el,useEffect:el,useImperativeHandle:el,useLayoutEffect:el,useInsertionEffect:el,useMemo:el,useReducer:el,useRef:el,useState:el,useDebugValue:el,useDeferredValue:el,useTransition:el,useSyncExternalStore:el,useId:el,useHostTransitionStatus:el,useFormState:el,useActionState:el,useOptimistic:el,useMemoCache:el,useCacheRefresh:el};ee.useEffectEvent=el;var Oh={readContext:El,use:Wn,useCallback:function(l,t){return _l().memoizedState=[l,t===void 0?null:t],l},useContext:El,useEffect:Qs,useImperativeHandle:function(l,t,a){a=a!=null?a.concat([l]):null,Ie(4194308,4,yh.bind(null,t,l),a)},useLayoutEffect:function(l,t){return Ie(4194308,4,l,t)},useInsertionEffect:function(l,t){Ie(4,2,l,t)},useMemo:function(l,t){var a=_l();t=t===void 0?null:t;var u=l();if(Ma){Kt(!0);try{l()}finally{Kt(!1)}}return a.memoizedState=[u,t],u},useReducer:function(l,t,a){var u=_l();if(a!==void 0){var e=a(t);if(Ma){Kt(!0);try{a(t)}finally{Kt(!1)}}}else e=t;return u.memoizedState=u.baseState=e,l={pending:null,lanes:0,dispatch:null,lastRenderedReducer:l,lastRenderedState:e},u.queue=l,l=l.dispatch=wd.bind(null,R,l),[u.memoizedState,l]},useRef:function(l){var t=_l();return l={current:l},t.memoizedState=l},useState:function(l){l=Ec(l);var t=l.queue,a=zh.bind(null,R,t);return t.dispatch=a,[l.memoizedState,a]},useDebugValue:Nf,useDeferredValue:function(l,t){var a=_l();return Uf(a,l,t)},useTransition:function(){var l=Ec(!1);return l=bh.bind(null,R,l.queue,!0,!1),_l().memoizedState=l,[!1,l]},useSyncExternalStore:function(l,t,a){var u=R,e=_l();if(G){if(a===void 0)throw Error(S(407));a=a()}else{if(a=t(),F===null)throw Error(S(349));q&127||lh(u,t,a)}e.memoizedState=a;var n={value:a,getSnapshot:t};return e.queue=n,Qs(ah.bind(null,u,n,l),[l]),u.flags|=2048,su(9,{destroy:void 0},th.bind(null,u,n,a,t),null),a},useId:function(){var l=_l(),t=F.identifierPrefix;if(G){var a=ht,u=ot;a=(u&~(1<<32-Ll(u)-1)).toString(32)+a,t="_"+t+"R_"+a,a=Tn++,0<\/script>",n=n.removeChild(n.firstChild);break;case"select":n=typeof u.is=="string"?i.createElement("select",{is:u.is}):i.createElement("select"),u.multiple?n.multiple=!0:u.size&&(n.size=u.size);break;default:n=typeof u.is=="string"?i.createElement(e,{is:u.is}):i.createElement(e)}}n[pl]=t,n[xl]=u;l:for(i=t.child;i!==null;){if(i.tag===5||i.tag===6)n.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===t)break l;for(;i.sibling===null;){if(i.return===null||i.return===t)break l;i=i.return}i.sibling.return=i.return,i=i.sibling}t.stateNode=n;l:switch(Al(n,e,u),e){case"button":case"input":case"select":case"textarea":u=!!u.autoFocus;break l;case"img":u=!0;break l;default:u=!1}u&&St(t)}}return I(t),Ni(t,t.type,l===null?null:l.memoizedProps,t.pendingProps,a),null;case 6:if(l&&t.stateNode!=null)l.memoizedProps!==u&&St(t);else{if(typeof u!="string"&&t.stateNode===null)throw Error(S(166));if(l=kt.current,Ca(t)){if(l=t.stateNode,a=t.memoizedProps,u=null,e=Tl,e!==null)switch(e.tag){case 27:case 5:u=e.memoizedProps}l[pl]=t,l=!!(l.nodeValue===a||u!==null&&u.suppressHydrationWarning===!0||z1(l.nodeValue,a)),l||ca(t,!0)}else l=Hn(l).createTextNode(u),l[pl]=t,t.stateNode=l}return I(t),null;case 31:if(a=t.memoizedState,l===null||l.memoizedState!==null){if(u=Ca(t),a!==null){if(l===null){if(!u)throw Error(S(318));if(l=t.memoizedState,l=l!==null?l.dehydrated:null,!l)throw Error(S(557));l[pl]=t}else Aa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;I(t),l=!1}else a=pi(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=a),l=!0;if(!l)return t.flags&256?(ql(t),t):(ql(t),null);if(t.flags&128)throw Error(S(558))}return I(t),null;case 13:if(u=t.memoizedState,l===null||l.memoizedState!==null&&l.memoizedState.dehydrated!==null){if(e=Ca(t),u!==null&&u.dehydrated!==null){if(l===null){if(!e)throw Error(S(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(S(317));e[pl]=t}else Aa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;I(t),e=!1}else e=pi(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=e),e=!0;if(!e)return t.flags&256?(ql(t),t):(ql(t),null)}return ql(t),t.flags&128?(t.lanes=a,t):(a=u!==null,l=l!==null&&l.memoizedState!==null,a&&(u=t.child,e=null,u.alternate!==null&&u.alternate.memoizedState!==null&&u.alternate.memoizedState.cachePool!==null&&(e=u.alternate.memoizedState.cachePool.pool),n=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(n=u.memoizedState.cachePool.pool),n!==e&&(u.flags|=2048)),a!==l&&a&&(t.child.flags|=8192),Ye(t,t.updateQueue),I(t),null);case 4:return eu(),l===null&&Zf(t.stateNode.containerInfo),I(t),null;case 10:return Nt(t.type),I(t),null;case 19:if(Sl(cl),u=t.memoizedState,u===null)return I(t),null;if(e=(t.flags&128)!==0,n=u.rendering,n===null)if(e)Ou(u,!1);else{if(nl!==0||l!==null&&l.flags&128)for(l=t.child;l!==null;){if(n=bn(l),n!==null){for(t.flags|=128,Ou(u,!1),l=n.updateQueue,t.updateQueue=l,Ye(t,l),t.subtreeFlags=0,l=a,a=t.child;a!==null;)Go(a,l),a=a.sibling;return k(cl,cl.current&1|2),G&&Et(t,u.treeForkCount),t.child}l=l.sibling}u.tail!==null&&Ql()>_n&&(t.flags|=128,e=!0,Ou(u,!1),t.lanes=4194304)}else{if(!e)if(l=bn(n),l!==null){if(t.flags|=128,e=!0,l=l.updateQueue,t.updateQueue=l,Ye(t,l),Ou(u,!0),u.tail===null&&u.tailMode==="hidden"&&!n.alternate&&!G)return I(t),null}else 2*Ql()-u.renderingStartTime>_n&&a!==536870912&&(t.flags|=128,e=!0,Ou(u,!1),t.lanes=4194304);u.isBackwards?(n.sibling=t.child,t.child=n):(l=u.last,l!==null?l.sibling=n:t.child=n,u.last=n)}return u.tail!==null?(l=u.tail,u.rendering=l,u.tail=l.sibling,u.renderingStartTime=Ql(),l.sibling=null,a=cl.current,k(cl,e?a&1|2:a&1),G&&Et(t,u.treeForkCount),l):(I(t),null);case 22:case 23:return ql(t),pf(),u=t.memoizedState!==null,l!==null?l.memoizedState!==null!==u&&(t.flags|=8192):u&&(t.flags|=8192),u?a&536870912&&!(t.flags&128)&&(I(t),t.subtreeFlags&6&&(t.flags|=8192)):I(t),a=t.updateQueue,a!==null&&Ye(t,a.retryQueue),a=null,l!==null&&l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(a=l.memoizedState.cachePool.pool),u=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(u=t.memoizedState.cachePool.pool),u!==a&&(t.flags|=2048),l!==null&&Sl(pa),null;case 24:return a=null,l!==null&&(a=l.memoizedState.cache),t.memoizedState.cache!==a&&(t.flags|=2048),Nt(hl),I(t),null;case 25:return null;case 30:return null}throw Error(S(156,t.tag))}function Id(l,t){switch(vf(t),t.tag){case 1:return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 3:return Nt(hl),eu(),l=t.flags,l&65536&&!(l&128)?(t.flags=l&-65537|128,t):null;case 26:case 27:case 5:return on(t),null;case 31:if(t.memoizedState!==null){if(ql(t),t.alternate===null)throw Error(S(340));Aa()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 13:if(ql(t),l=t.memoizedState,l!==null&&l.dehydrated!==null){if(t.alternate===null)throw Error(S(340));Aa()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 19:return Sl(cl),null;case 4:return eu(),null;case 10:return Nt(t.type),null;case 22:case 23:return ql(t),pf(),l!==null&&Sl(pa),l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 24:return Nt(hl),null;case 25:return null;default:return null}}function Gh(l,t){switch(vf(t),t.tag){case 3:Nt(hl),eu();break;case 26:case 27:case 5:on(t);break;case 4:eu();break;case 31:t.memoizedState!==null&&ql(t);break;case 13:ql(t);break;case 19:Sl(cl);break;case 10:Nt(t.type);break;case 22:case 23:ql(t),pf(),l!==null&&Sl(pa);break;case 24:Nt(hl)}}function be(l,t){try{var a=t.updateQueue,u=a!==null?a.lastEffect:null;if(u!==null){var e=u.next;a=e;do{if((a.tag&l)===l){u=void 0;var n=a.create,i=a.inst;u=n(),i.destroy=u}a=a.next}while(a!==e)}}catch(c){K(t,t.return,c)}}function fa(l,t,a){try{var u=t.updateQueue,e=u!==null?u.lastEffect:null;if(e!==null){var n=e.next;u=n;do{if((u.tag&l)===l){var i=u.inst,c=i.destroy;if(c!==void 0){i.destroy=void 0,e=t;var f=a,h=c;try{h()}catch(g){K(e,f,g)}}}u=u.next}while(u!==n)}}catch(g){K(t,t.return,g)}}function Xh(l){var t=l.updateQueue;if(t!==null){var a=l.stateNode;try{Wo(t,a)}catch(u){K(l,l.return,u)}}}function Qh(l,t,a){a.props=Oa(l.type,l.memoizedProps),a.state=l.memoizedState;try{a.componentWillUnmount()}catch(u){K(l,t,u)}}function Ku(l,t){try{var a=l.ref;if(a!==null){switch(l.tag){case 26:case 27:case 5:var u=l.stateNode;break;case 30:u=l.stateNode;break;default:u=l.stateNode}typeof a=="function"?l.refCleanup=a(u):a.current=u}}catch(e){K(l,t,e)}}function mt(l,t){var a=l.ref,u=l.refCleanup;if(a!==null)if(typeof u=="function")try{u()}catch(e){K(l,t,e)}finally{l.refCleanup=null,l=l.alternate,l!=null&&(l.refCleanup=null)}else if(typeof a=="function")try{a(null)}catch(e){K(l,t,e)}else a.current=null}function Zh(l){var t=l.type,a=l.memoizedProps,u=l.stateNode;try{l:switch(t){case"button":case"input":case"select":case"textarea":a.autoFocus&&u.focus();break l;case"img":a.src?u.src=a.src:a.srcSet&&(u.srcset=a.srcSet)}}catch(e){K(l,l.return,e)}}function Ui(l,t,a){try{var u=l.stateNode;py(u,l.type,a,t),u[xl]=t}catch(e){K(l,l.return,e)}}function Lh(l){return l.tag===5||l.tag===3||l.tag===26||l.tag===27&&ha(l.type)||l.tag===4}function Hi(l){l:for(;;){for(;l.sibling===null;){if(l.return===null||Lh(l.return))return null;l=l.return}for(l.sibling.return=l.return,l=l.sibling;l.tag!==5&&l.tag!==6&&l.tag!==18;){if(l.tag===27&&ha(l.type)||l.flags&2||l.child===null||l.tag===4)continue l;l.child.return=l,l=l.child}if(!(l.flags&2))return l.stateNode}}function Nc(l,t,a){var u=l.tag;if(u===5||u===6)l=l.stateNode,t?(a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a).insertBefore(l,t):(t=a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a,t.appendChild(l),a=a._reactRootContainer,a!=null||t.onclick!==null||(t.onclick=Mt));else if(u!==4&&(u===27&&ha(l.type)&&(a=l.stateNode,t=null),l=l.child,l!==null))for(Nc(l,t,a),l=l.sibling;l!==null;)Nc(l,t,a),l=l.sibling}function zn(l,t,a){var u=l.tag;if(u===5||u===6)l=l.stateNode,t?a.insertBefore(l,t):a.appendChild(l);else if(u!==4&&(u===27&&ha(l.type)&&(a=l.stateNode),l=l.child,l!==null))for(zn(l,t,a),l=l.sibling;l!==null;)zn(l,t,a),l=l.sibling}function Vh(l){var t=l.stateNode,a=l.memoizedProps;try{for(var u=l.type,e=t.attributes;e.length;)t.removeAttributeNode(e[0]);Al(t,u,a),t[pl]=l,t[xl]=a}catch(n){K(l,l.return,n)}}var zt=!1,ol=!1,Ri=!1,l0=typeof WeakSet=="function"?WeakSet:Set,gl=null;function Pd(l,t){if(l=l.containerInfo,Bc=xn,l=Ho(l),of(l)){if("selectionStart"in l)var a={start:l.selectionStart,end:l.selectionEnd};else l:{a=(a=l.ownerDocument)&&a.defaultView||window;var u=a.getSelection&&a.getSelection();if(u&&u.rangeCount!==0){a=u.anchorNode;var e=u.anchorOffset,n=u.focusNode;u=u.focusOffset;try{a.nodeType,n.nodeType}catch{a=null;break l}var i=0,c=-1,f=-1,h=0,g=0,y=l,m=null;t:for(;;){for(var v;y!==a||e!==0&&y.nodeType!==3||(c=i+e),y!==n||u!==0&&y.nodeType!==3||(f=i+u),y.nodeType===3&&(i+=y.nodeValue.length),(v=y.firstChild)!==null;)m=y,y=v;for(;;){if(y===l)break t;if(m===a&&++h===e&&(c=i),m===n&&++g===u&&(f=i),(v=y.nextSibling)!==null)break;y=m,m=y.parentNode}y=v}a=c===-1||f===-1?null:{start:c,end:f}}else a=null}a=a||{start:0,end:0}}else a=null;for(Yc={focusedElem:l,selectionRange:a},xn=!1,gl=t;gl!==null;)if(t=gl,l=t.child,(t.subtreeFlags&1028)!==0&&l!==null)l.return=t,gl=l;else for(;gl!==null;){switch(t=gl,n=t.alternate,l=t.flags,t.tag){case 0:if(l&4&&(l=t.updateQueue,l=l!==null?l.events:null,l!==null))for(a=0;a title"))),Al(n,u,a),n[pl]=l,rl(n),u=n;break l;case"link":var i=p0("link","href",e).get(u+(a.href||""));if(i){for(var c=0;cj&&(i=j,j=z,z=i);var o=_s(c,z),s=_s(c,j);if(o&&s&&(v.rangeCount!==1||v.anchorNode!==o.node||v.anchorOffset!==o.offset||v.focusNode!==s.node||v.focusOffset!==s.offset)){var d=y.createRange();d.setStart(o.node,o.offset),v.removeAllRanges(),z>j?(v.addRange(d),v.extend(s.node,s.offset)):(d.setEnd(s.node,s.offset),v.addRange(d))}}}}for(y=[],v=c;v=v.parentNode;)v.nodeType===1&&y.push({element:v,left:v.scrollLeft,top:v.scrollTop});for(typeof c.focus=="function"&&c.focus(),c=0;ca?32:a,M.T=null,a=Rc,Rc=null;var n=aa,i=Ut;if(dl=0,hu=aa=null,Ut=0,Q&6)throw Error(S(331));var c=Q;if(Q|=4,t1(n.current),Ih(n,n.current,i,a),Q=c,pe(0,!1),Zl&&typeof Zl.onPostCommitFiberRoot=="function")try{Zl.onPostCommitFiberRoot(me,n)}catch{}return!0}finally{Z.p=e,M.T=u,g1(l,t)}}function e0(l,t,a){t=Pl(a,t),t=Mc(l.stateNode,t,2),l=la(l,t,2),l!==null&&(ye(l,2),gt(l))}function K(l,t,a){if(l.tag===3)e0(l,l,a);else for(;t!==null;){if(t.tag===3){e0(t,l,a);break}else if(t.tag===1){var u=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof u.componentDidCatch=="function"&&(ta===null||!ta.has(u))){l=Pl(a,l),a=Rh(2),u=la(t,a,2),u!==null&&(Ch(a,u,t,l),ye(u,2),gt(u));break}}t=t.return}}function ji(l,t,a){var u=l.pingCache;if(u===null){u=l.pingCache=new ay;var e=new Set;u.set(t,e)}else e=u.get(t),e===void 0&&(e=new Set,u.set(t,e));e.has(a)||(qf=!0,e.add(a),l=cy.bind(null,l,t,a),t.then(l,l))}function cy(l,t,a){var u=l.pingCache;u!==null&&u.delete(t),l.pingedLanes|=l.suspendedLanes&a,l.warmLanes&=~a,F===l&&(q&a)===a&&(nl===4||nl===3&&(q&62914560)===q&&300>Ql()-In?!(Q&2)&&mu(l,0):Gf|=a,ou===q&&(ou=0)),gt(l)}function S1(l,t){t===0&&(t=fo()),l=Ha(l,t),l!==null&&(ye(l,t),gt(l))}function fy(l){var t=l.memoizedState,a=0;t!==null&&(a=t.retryLane),S1(l,a)}function sy(l,t){var a=0;switch(l.tag){case 31:case 13:var u=l.stateNode,e=l.memoizedState;e!==null&&(a=e.retryLane);break;case 19:u=l.stateNode;break;case 22:u=l.stateNode._retryCache;break;default:throw Error(S(314))}u!==null&&u.delete(t),S1(l,a)}function oy(l,t){return lf(l,t)}var Dn=null,Ya=null,jc=!1,Nn=!1,xi=!1,Wt=0;function gt(l){l!==Ya&&l.next===null&&(Ya===null?Dn=Ya=l:Ya=Ya.next=l),Nn=!0,jc||(jc=!0,my())}function pe(l,t){if(!xi&&Nn){xi=!0;do for(var a=!1,u=Dn;u!==null;){if(!t)if(l!==0){var e=u.pendingLanes;if(e===0)var n=0;else{var i=u.suspendedLanes,c=u.pingedLanes;n=(1<<31-Ll(42|l)+1)-1,n&=e&~(i&~c),n=n&201326741?n&201326741|1:n?n|2:0}n!==0&&(a=!0,n0(u,n))}else n=q,n=Qn(u,u===F?n:0,u.cancelPendingCommit!==null||u.timeoutHandle!==-1),!(n&3)||de(u,n)||(a=!0,n0(u,n));u=u.next}while(a);xi=!1}}function hy(){b1()}function b1(){Nn=jc=!1;var l=0;Wt!==0&&Ey()&&(l=Wt);for(var t=Ql(),a=null,u=Dn;u!==null;){var e=u.next,n=p1(u,t);n===0?(u.next=null,a===null?Dn=e:a.next=e,e===null&&(Ya=a)):(a=u,(l!==0||n&3)&&(Nn=!0)),u=e}dl!==0&&dl!==5||pe(l,!1),Wt!==0&&(Wt=0)}function p1(l,t){for(var a=l.suspendedLanes,u=l.pingedLanes,e=l.expirationTimes,n=l.pendingLanes&-62914561;0c)break;var g=f.transferSize,y=f.initiatorType;g&&o0(y)&&(f=f.responseEnd,i+=g*(f"u"?null:document;function N1(l,t,a){var u=Tu;if(u&&typeof t=="string"&&t){var e=Il(t);e='link[rel="'+l+'"][href="'+e+'"]',typeof a=="string"&&(e+='[crossorigin="'+a+'"]'),r0.has(e)||(r0.add(e),l={rel:l,crossOrigin:a,href:t},u.querySelector(e)===null&&(t=u.createElement("link"),Al(t,"link",l),rl(t),u.head.appendChild(t)))}}function Hy(l){Bt.D(l),N1("dns-prefetch",l,null)}function Ry(l,t){Bt.C(l,t),N1("preconnect",l,t)}function Cy(l,t,a){Bt.L(l,t,a);var u=Tu;if(u&&l&&t){var e='link[rel="preload"][as="'+Il(t)+'"]';t==="image"&&a&&a.imageSrcSet?(e+='[imagesrcset="'+Il(a.imageSrcSet)+'"]',typeof a.imageSizes=="string"&&(e+='[imagesizes="'+Il(a.imageSizes)+'"]')):e+='[href="'+Il(l)+'"]';var n=e;switch(t){case"style":n=du(l);break;case"script":n=Eu(l)}ut.has(n)||(l=tl({rel:"preload",href:t==="image"&&a&&a.imageSrcSet?void 0:l,as:t},a),ut.set(n,l),u.querySelector(e)!==null||t==="style"&&u.querySelector(Te(n))||t==="script"&&u.querySelector(Ee(n))||(t=u.createElement("link"),Al(t,"link",l),rl(t),u.head.appendChild(t)))}}function jy(l,t){Bt.m(l,t);var a=Tu;if(a&&l){var u=t&&typeof t.as=="string"?t.as:"script",e='link[rel="modulepreload"][as="'+Il(u)+'"][href="'+Il(l)+'"]',n=e;switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":n=Eu(l)}if(!ut.has(n)&&(l=tl({rel:"modulepreload",href:l},t),ut.set(n,l),a.querySelector(e)===null)){switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(a.querySelector(Ee(n)))return}u=a.createElement("link"),Al(u,"link",l),rl(u),a.head.appendChild(u)}}}function xy(l,t,a){Bt.S(l,t,a);var u=Tu;if(u&&l){var e=Fa(u).hoistableStyles,n=du(l);t=t||"default";var i=e.get(n);if(!i){var c={loading:0,preload:null};if(i=u.querySelector(Te(n)))c.loading=5;else{l=tl({rel:"stylesheet",href:l,"data-precedence":t},a),(a=ut.get(n))&&Lf(l,a);var f=i=u.createElement("link");rl(f),Al(f,"link",l),f._p=new Promise(function(h,g){f.onload=h,f.onerror=g}),f.addEventListener("load",function(){c.loading|=1}),f.addEventListener("error",function(){c.loading|=2}),c.loading|=4,an(i,t,u)}i={type:"stylesheet",instance:i,count:1,state:c},e.set(n,i)}}}function By(l,t){Bt.X(l,t);var a=Tu;if(a&&l){var u=Fa(a).hoistableScripts,e=Eu(l),n=u.get(e);n||(n=a.querySelector(Ee(e)),n||(l=tl({src:l,async:!0},t),(t=ut.get(e))&&Vf(l,t),n=a.createElement("script"),rl(n),Al(n,"link",l),a.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},u.set(e,n))}}function Yy(l,t){Bt.M(l,t);var a=Tu;if(a&&l){var u=Fa(a).hoistableScripts,e=Eu(l),n=u.get(e);n||(n=a.querySelector(Ee(e)),n||(l=tl({src:l,async:!0,type:"module"},t),(t=ut.get(e))&&Vf(l,t),n=a.createElement("script"),rl(n),Al(n,"link",l),a.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},u.set(e,n))}}function S0(l,t,a,u){var e=(e=kt.current)?Rn(e):null;if(!e)throw Error(S(446));switch(l){case"meta":case"title":return null;case"style":return typeof a.precedence=="string"&&typeof a.href=="string"?(t=du(a.href),a=Fa(e).hoistableStyles,u=a.get(t),u||(u={type:"style",instance:null,count:0,state:null},a.set(t,u)),u):{type:"void",instance:null,count:0,state:null};case"link":if(a.rel==="stylesheet"&&typeof a.href=="string"&&typeof a.precedence=="string"){l=du(a.href);var n=Fa(e).hoistableStyles,i=n.get(l);if(i||(e=e.ownerDocument||e,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},n.set(l,i),(n=e.querySelector(Te(l)))&&!n._p&&(i.instance=n,i.state.loading=5),ut.has(l)||(a={rel:"preload",as:"style",href:a.href,crossOrigin:a.crossOrigin,integrity:a.integrity,media:a.media,hrefLang:a.hrefLang,referrerPolicy:a.referrerPolicy},ut.set(l,a),n||qy(e,l,a,i.state))),t&&u===null)throw Error(S(528,""));return i}if(t&&u!==null)throw Error(S(529,""));return null;case"script":return t=a.async,a=a.src,typeof a=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=Eu(a),a=Fa(e).hoistableScripts,u=a.get(t),u||(u={type:"script",instance:null,count:0,state:null},a.set(t,u)),u):{type:"void",instance:null,count:0,state:null};default:throw Error(S(444,l))}}function du(l){return'href="'+Il(l)+'"'}function Te(l){return'link[rel="stylesheet"]['+l+"]"}function U1(l){return tl({},l,{"data-precedence":l.precedence,precedence:null})}function qy(l,t,a,u){l.querySelector('link[rel="preload"][as="style"]['+t+"]")?u.loading=1:(t=l.createElement("link"),u.preload=t,t.addEventListener("load",function(){return u.loading|=1}),t.addEventListener("error",function(){return u.loading|=2}),Al(t,"link",a),rl(t),l.head.appendChild(t))}function Eu(l){return'[src="'+Il(l)+'"]'}function Ee(l){return"script[async]"+l}function b0(l,t,a){if(t.count++,t.instance===null)switch(t.type){case"style":var u=l.querySelector('style[data-href~="'+Il(a.href)+'"]');if(u)return t.instance=u,rl(u),u;var e=tl({},a,{"data-href":a.href,"data-precedence":a.precedence,href:null,precedence:null});return u=(l.ownerDocument||l).createElement("style"),rl(u),Al(u,"style",e),an(u,a.precedence,l),t.instance=u;case"stylesheet":e=du(a.href);var n=l.querySelector(Te(e));if(n)return t.state.loading|=4,t.instance=n,rl(n),n;u=U1(a),(e=ut.get(e))&&Lf(u,e),n=(l.ownerDocument||l).createElement("link"),rl(n);var i=n;return i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),Al(n,"link",u),t.state.loading|=4,an(n,a.precedence,l),t.instance=n;case"script":return n=Eu(a.src),(e=l.querySelector(Ee(n)))?(t.instance=e,rl(e),e):(u=a,(e=ut.get(n))&&(u=tl({},a),Vf(u,e)),l=l.ownerDocument||l,e=l.createElement("script"),rl(e),Al(e,"link",u),l.head.appendChild(e),t.instance=e);case"void":return null;default:throw Error(S(443,t.type))}else t.type==="stylesheet"&&!(t.state.loading&4)&&(u=t.instance,t.state.loading|=4,an(u,a.precedence,l));return t.instance}function an(l,t,a){for(var u=a.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),e=u.length?u[u.length-1]:null,n=e,i=0;i title"):null)}function Gy(l,t,a){if(a===1||t.itemProp!=null)return!1;switch(l){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return l=t.disabled,typeof t.precedence=="string"&&l==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function H1(l){return!(l.type==="stylesheet"&&!(l.state.loading&3))}function Xy(l,t,a,u){if(a.type==="stylesheet"&&(typeof u.media!="string"||matchMedia(u.media).matches!==!1)&&!(a.state.loading&4)){if(a.instance===null){var e=du(u.href),n=t.querySelector(Te(e));if(n){t=n._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(l.count++,l=Cn.bind(l),t.then(l,l)),a.state.loading|=4,a.instance=n,rl(n);return}n=t.ownerDocument||t,u=U1(u),(e=ut.get(e))&&Lf(u,e),n=n.createElement("link"),rl(n);var i=n;i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),Al(n,"link",u),a.instance=n}l.stylesheets===null&&(l.stylesheets=new Map),l.stylesheets.set(a,t),(t=a.state.preload)&&!(a.state.loading&3)&&(l.count++,a=Cn.bind(l),t.addEventListener("load",a),t.addEventListener("error",a))}}var Qi=0;function Qy(l,t){return l.stylesheets&&l.count===0&&en(l,l.stylesheets),0Qi?50:800)+t);return l.unsuspend=a,function(){l.unsuspend=null,clearTimeout(u),clearTimeout(e)}}:null}function Cn(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)en(this,this.stylesheets);else if(this.unsuspend){var l=this.unsuspend;this.unsuspend=null,l()}}}var jn=null;function en(l,t){l.stylesheets=null,l.unsuspend!==null&&(l.count++,jn=new Map,t.forEach(Zy,l),jn=null,Cn.call(l))}function Zy(l,t){if(!(t.state.loading&4)){var a=jn.get(l);if(a)var u=a.get(null);else{a=new Map,jn.set(l,a);for(var e=l.querySelectorAll("link[data-precedence],style[data-precedence]"),n=0;n"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(G1)}catch(l){console.error(l)}}G1(),G0.exports=Gn;var Fy=G0.exports;const ky=4,D0=[["#3b82f6","#bfdbfe"],["#a855f7","#f0d9ff"],["#10b981","#b7f5da"],["#ef4444","#ffd5d5"],["#f59e0b","#ffeab0"],["#06b6d4","#b8f2fb"],["#6366f1","#d5daff"],["#84cc16","#e3fab3"]];function Iy(l,t,a){const u=t,e=a;switch(l){case 0:return``;case 1:return``;case 2:{const n=[.35,.62,.45,.8,.55];return n.map((i,c)=>{const f=u*.9/n.length-6;return``}).join("")}default:return``}}const N0=new Map;function X1(l,t,a,u){const e=l%D0.length,n=t%ky,i=`${e}-${n}-${a}x${u}`,c=N0.get(i);if(c)return c;const[f,h]=D0[e],g=`g${e}${n}`,y=`${Iy(n,a,u)}`,m=`data:image/svg+xml,${encodeURIComponent(y)}`;return N0.set(i,m),m}const Q1=40,xu=1500,Kc=8,Py=56,Le=["General","Random","Announcements","Engineering","Design","Product","Support","Off Topic","Releases","Incidents","Frontend","Backend","Infra","Mobile","Performance","Security","Docs","Hiring","Watercooler","Standup"],Ft=["Ada Lovelace","Alan Turing","Grace Hopper","Linus Pauling","Marie Curie","Nikola Tesla","Rosalind Franklin","Carl Sagan","Katherine Johnson","Tim Berners-Lee"],Wf=["#368bd6","#ac3ba8","#03b381","#e64f7a","#ff812d","#2dc2c5","#5c56f5","#74d12c"],Ff=Wf.length,Zi=["the","benchmark","switching","between","rooms","should","feel","instant","even","when","the","timeline","is","long","and","full","of","rich","messages","with","avatars","and","timestamps","rendering","performance","matters","a","lot","here","lets","measure","it","carefully","and","compare","across","browsers","over","time"],Yn=["😀","😂","🎉","🔥","❤️","🙏","👀","🚀","😅","🤔","💯","✨","🙌🏽","👍🏻","😍","🥳","😭","🤯","👏","💪🏾","🧠","☕","🐛","📈","👩‍💻","🧑‍🚀","👨‍👩‍👧‍👦","🏳️‍🌈","🤷‍♀️","🙋‍♂️","🫠","🫶"],U0=["👍","❤️","😂","🎉","🔥","✅","👀","🙏","💯","🚀","😅","🤯"],lv=Ft.map(l=>l.split(" ")[0].toLowerCase()),Z1=["scrollTop","scrollHeight","flushSync","requestAnimationFrame","IntersectionObserver","overflow-anchor","content-visibility","useLayoutEffect","getBoundingClientRect","will-change","ResizeObserver","queueMicrotask","clientHeight","offsetHeight"],tv=["the trace","last night's run","this regression","the profile","the spec text","my notes","the dashboard","that comparison"],L1=["traces/2f9c","runs/nightly","profiles/hot-path","spec/scroll-anchoring","notes/timeline","dashboards/perf","reports/42","compare/main"],av=[{site:"example.com",title:"Scroll anchoring, and why feeds jump",description:"How browsers pin a scroll position while content is inserted above the viewport, and where it gives up."},{site:"perf.example.com",title:"Nightly run 482 vs 481",description:"Geomean moved 1.8% on the chat suites. Row measurement dominates the profile."},{site:"docs.example.com",title:"Windowing a variable-height list",description:"Estimate, measure, cache, correct. The four steps every hand-rolled virtualizer ends up with."},{site:"bugs.example.com",title:"Timeline jumps when the panel opens",description:"Narrowing the scroller re-wraps every row, so the cached heights are all stale at once."}],uv=["can we get a number on how bad the jank is before we start moving code around","the window only recycles about twenty rows, so the mount cost should be flat","every row height changes when the panel opens, which invalidates the cache","please do not use smooth scrolling anywhere inside a timed step","prepending history without pinning the anchor makes the viewport jump"],Li=["estimate the row height first, then correct after measuring","cache measured heights per message id","keep the mounted window small and bounded","assign scroll offsets explicitly instead of animating","recycle rows rather than remounting them","break the group when a reply quote is present","re-measure only the rows the resize actually touched"],ev=[{lang:"js",lines:["const scroller = scrollerRef.current;","scroller.scrollTop = scroller.scrollHeight;"]},{lang:"js",lines:["requestAnimationFrame(() => {"," for (const row of mounted)"," heights.set(row.id, row.offsetHeight);","});"]},{lang:"css",lines:[".timeline {"," overflow-anchor: none;"," content-visibility: auto;","}"]},{lang:"sh",lines:["npm run build","node debugging/e2e-chatroom.mjs --browser chrome"]},{lang:"json",lines:["{",' "iterationCount": 10,',' "suites": ["ChatRoom-React"]',"}"]},{lang:"js",lines:["for (const row of rows) {"," if (!heights.has(row.id))"," heights.set(row.id, estimate);","}"]},{lang:"diff",lines:['- scroller.scrollTo({ top, behavior: "smooth" });',"+ scroller.scrollTop = top;"]},{lang:"js",lines:["export function anchorToBottom(node) {"," node.scrollTop = node.scrollHeight;","}"]}];function W(l,t){let a=Math.imul(l+1,2654435761)^Math.imul(t+1,40503);return a^=a>>>15,a=Math.imul(a,2246822519),a^=a>>>13,a=Math.imul(a,3266489917),a^=a>>>16,a>>>0}function dt(l,t,a){return l[W(t,a)%l.length]}function kf(l){return l.split(" ").map(t=>t[0]).join("").slice(0,2).toUpperCase()}function V1(l){const t=Le[l%Le.length];return l{if(!a.length)return;const i=u?" ":"",c=n?" ":"";t.push({type:"text",text:`${i}${a.join(" ")}${c}`}),a=[],u=!1};for(const n of l){if(typeof n=="string"){a.push(n);continue}e(!0),t.push(n),u=!0}return e(!1),t}function iv(l,t,a){if(a===0)return{type:"code",text:dt(Z1,l,t+11)};if(a===1)return{type:"link",text:dt(tv,l,t+12),href:`https://example.com/${dt(L1,l,t+13)}`};if(a===2)return{type:"mention",name:dt(lv,l,t+14)};const u=W(l,t+15)%Q1;return{type:"room",name:nv(u),roomId:`room-${u}`}}function Ve(l,t){const a=6+W(l,t)%22,u=W(l,t+1)%Zi.length,e=[];let n=!1;for(let g=0;g0&&gString(e).padStart(2,"0");return`${u(t)}:${u(a)}`}const If=24*60,Pf=[];for(let l=0;l[l,t%Ff])),Tv=new Map(Ft.map(l=>[l,kf(l)]));function Ev(l,t){const a=[];let u=0;for(;a.length0&&W(n,201)%100<18){const h=W(n,203)%4===0?1+W(n,204)%Math.min(e,400):1+W(n,202)%6,g=u[Math.max(0,e-h)];f={id:g.id,sender:g.sender,excerpt:Sv(g.blocks)}}u.push({id:`room-${l}-msg-${e}`,sender:i,senderInitials:Tv.get(i),colorIndex:pv.get(i),time:Pf[n%If],dayIndex:a[e],blocks:c,replyTo:f,grouped:e>0&&t[e-1]===i&&!f,reactions:F1[n%W1]})}return u}const zv=12;function _v(){const l=[];for(let t=0;t0,reactions:[]}}function Ov({index:l,room:t,selected:a,onSelect:u}){const e=a?"room-list-item room-list-item-selected":"room-list-item";return E.jsxs("button",{id:`room-list-item-${l}`,className:e,type:"button",onClick:()=>u(t.id),children:[E.jsx("span",{className:"avatar",style:{backgroundColor:Wf[t.colorIndex]},children:t.initials}),E.jsxs("span",{className:"room-list-item-text",children:[E.jsx("span",{className:"room-list-item-name",children:t.name}),E.jsx("span",{className:"room-list-item-preview",children:t.lastMessage})]})]})}function Dv({rooms:l,selectedRoomId:t,onSelect:a}){return E.jsx("nav",{className:"room-list","aria-label":"Rooms",children:l.map((u,e)=>E.jsx(Ov,{index:e,room:u,selected:u.id===t,onSelect:a},u.id))})}const I1=J.createContext({selectRoom:()=>{},jumpToMessage:()=>{}});function P1(){return J.useContext(I1)}const Ji=-1;var oe,Hl,At,ft,st,wl,uu,cn;class Nv{constructor(t,a,u){Yt(this,uu);Yt(this,oe,void 0);Yt(this,Hl,void 0);Yt(this,At,void 0);Yt(this,ft,void 0);Yt(this,st,void 0);Yt(this,wl,void 0);zl(this,oe,u),zl(this,Hl,t),zl(this,st,a),zl(this,At,new Float64Array(t).fill(Ji)),zl(this,ft,new Float64Array(t+1)),zl(this,wl,a)}get count(){return L(this,Hl)}get first(){return L(this,st)}extendTo(t){t>=L(this,st)||(zl(this,st,t),zl(this,wl,t))}grow(t){if(t<=L(this,Hl))return;const a=new Float64Array(t);a.set(L(this,At)),a.fill(Ji,L(this,Hl));const u=new Float64Array(t+1);u.set(L(this,ft)),zl(this,wl,Math.min(L(this,wl),L(this,Hl))),zl(this,At,a),zl(this,ft,u),zl(this,Hl,t)}heightAt(t){const a=L(this,At)[t];return a===Ji?L(this,oe):a}measure(t,a){return L(this,At)[t]===a?!1:(L(this,At)[t]=a,t>1;a[n]<=t?u=n:e=n-1}return Math.max(L(this,st),u)}}oe=new WeakMap,Hl=new WeakMap,At=new WeakMap,ft=new WeakMap,st=new WeakMap,wl=new WeakMap,uu=new WeakSet,cn=function(){if(L(this,wl)>L(this,Hl))return;const t=L(this,ft);t[L(this,st)]=0;for(let a=L(this,wl);a{i.preventDefault();const c=a.trim();c&&(t(c),u(""))},n=i=>{i.key==="Enter"&&!i.shiftKey&&e(i)};return E.jsxs("form",{className:"composer",onSubmit:e,children:[E.jsx("input",{id:"composer-input",className:"composer-input",type:"text",autoComplete:"off","aria-label":`Message ${l}`,placeholder:`Message #${l.toLowerCase().replace(/ /g,"-")}`,value:a,onChange:i=>u(i.target.value),onKeyDown:n}),E.jsx("button",{id:"composer-send",className:"composer-send",type:"submit",disabled:a.trim().length===0,children:"Send"})]})}function Hv({reaction:l}){const[t,a]=J.useState(!1),u=t?"reaction reaction-mine":"reaction";return E.jsxs("button",{className:u,type:"button","aria-pressed":t,onClick:()=>a(!t),children:[E.jsx("span",{className:"reaction-emoji",children:l.emoji}),E.jsx("span",{className:"reaction-count",children:l.count+(t?1:0)})]})}function Rv({span:l}){const{selectRoom:t}=P1();return E.jsxs("button",{className:"rich-pill rich-pill-room",type:"button",onClick:()=>t(l.roomId),children:["#",l.name]})}function Cv({span:l}){switch(l.type){case"code":return E.jsx("code",{className:"rich-code",children:l.text});case"link":return E.jsx("a",{className:"rich-link",href:l.href,onClick:t=>t.preventDefault(),children:l.text});case"mention":return E.jsxs("span",{className:"rich-pill rich-pill-mention",children:["@",l.name]});case"room":return E.jsx(Rv,{span:l});default:return l.text}}function wi({spans:l}){return l.map((t,a)=>E.jsx(Cv,{span:t},a))}function jv({block:l}){switch(l.type){case"code":return E.jsx("pre",{className:"rich-code-block","data-lang":l.lang,children:E.jsx("code",{children:l.lines.join(` +`)})});case"quote":return E.jsx("blockquote",{className:"rich-quote",children:E.jsx(wi,{spans:l.spans})});case"image":return E.jsx("img",{className:"rich-image",src:l.src,width:l.width,height:l.height,alt:l.alt,decoding:"sync"});case"unfurl":return E.jsxs("a",{className:"rich-unfurl",href:l.href,onClick:t=>t.preventDefault(),children:[E.jsx("img",{className:"rich-unfurl-thumb",src:l.thumbSrc,width:l.thumbWidth,height:l.thumbHeight,alt:"",decoding:"sync"}),E.jsxs("span",{className:"rich-unfurl-body",children:[E.jsx("span",{className:"rich-unfurl-site",children:l.site}),E.jsx("span",{className:"rich-unfurl-title",children:l.title}),E.jsx("span",{className:"rich-unfurl-description",children:l.description})]})]});case"list":return E.jsx("ul",{className:"rich-list",children:l.items.map((t,a)=>E.jsx("li",{children:E.jsx(wi,{spans:t})},a))});default:return E.jsx("p",{className:"rich-paragraph",children:E.jsx(wi,{spans:l.spans})})}}function xv({blocks:l}){return l.map((t,a)=>E.jsx(jv,{block:t},a))}function Bv({index:l,message:t,highlighted:a,dateLabel:u,unreadBelow:e}){const{jumpToMessage:n}=P1(),i=["timeline-message"];return t.grouped&&i.push("timeline-message-grouped"),a&&i.push("timeline-message-highlighted"),E.jsxs("li",{className:i.join(" "),"data-message-id":t.id,"data-index":l,children:[u!==null&&E.jsx("div",{className:"timeline-date-separator",children:E.jsx("span",{className:"timeline-date-separator-label",children:u})}),e&&E.jsx("div",{className:"timeline-unread-divider","aria-label":"Unread messages",children:E.jsx("span",{className:"timeline-unread-divider-label",children:"New"})}),E.jsxs("div",{className:"timeline-message-row",children:[t.grouped?E.jsx("span",{className:"timeline-message-gutter",children:t.time}):E.jsx("span",{className:"avatar",style:{backgroundColor:Wf[t.colorIndex]},children:t.senderInitials}),E.jsxs("div",{className:"timeline-message-body",children:[t.replyTo&&E.jsxs("button",{className:"timeline-message-reply",type:"button",onClick:()=>n(t.replyTo.id),children:[E.jsx("span",{className:"timeline-message-reply-sender",children:t.replyTo.sender}),E.jsx("span",{className:"timeline-message-reply-excerpt",children:t.replyTo.excerpt})]}),!t.grouped&&E.jsxs("div",{className:"timeline-message-meta",children:[E.jsx("span",{className:"timeline-message-sender",children:t.sender}),E.jsx("span",{className:"timeline-message-time",children:t.time})]}),E.jsx("div",{className:"timeline-message-text",children:E.jsx(xv,{blocks:t.blocks})}),t.reactions.length>0&&E.jsx("div",{className:"timeline-message-reactions",children:t.reactions.map(c=>E.jsx(Hv,{reaction:c},c.emoji))})]})]})]})}const $i=4,Yv=100,qv=4,Gv=300,Xv=120;function Qv({room:l,onSelectRoom:t}){const a=J.useRef(null),[u,e]=J.useState(null),[n,i]=J.useState([]),c=J.useMemo(()=>n.length?[...l.messages,...n]:l.messages,[l.messages,n]),f=Math.max(0,l.messages.length-Gv),[h,g]=J.useState(f),y=J.useMemo(()=>new Nv(l.messages.length,f,Yv),[l.messages,f]);y.grow(c.length),y.extendTo(h);const m=J.useMemo(()=>{let _=null;return X=>(_===null&&(_=new Map(c.map((ul,b)=>[ul.id,b]))),_.get(X))},[c]),[v,p]=J.useState({start:0,end:0}),z=J.useRef(!0),j=J.useRef(null),o=J.useRef(null),[,s]=J.useState(0),d=J.useCallback((_,X)=>{const ul=y.indexAt(_),b=_+X;let D=ul;for(;D+1{const ul=y.offsetAt(_)-(X-y.heightAt(_))/2;return Math.max(0,Math.min(ul,y.totalHeight-X))},[y]),A=J.useCallback(_=>{p(X=>X.start===_.start&&X.end===_.end?X:_)},[]),N=J.useCallback(_=>{const X=y.indexAt(_);return{index:X,offset:_-y.offsetAt(X)}},[y]),T=J.useCallback(()=>{const _=a.current;if(z.current=_.scrollHeight-(_.scrollTop+_.clientHeight)<=qv,y.first>0&&_.scrollTop<_.clientHeight){o.current=N(_.scrollTop),g(Math.max(0,y.first-Xv));return}A(d(_.scrollTop,_.clientHeight))},[N,y,d,A]);J.useLayoutEffect(()=>{const _=a.current,X=_.clientHeight,ul=o.current,b=ul??N(_.scrollTop);let D=!1;for(const U of _.querySelectorAll(".timeline-message"))y.measure(Number(U.dataset.index),U.getBoundingClientRect().height)&&(D=!0);if(D){o.current=b,s(U=>U+1);return}o.current=null,j.current!==null?(_.scrollTop=r(j.current,X),j.current=null):z.current?_.scrollTop=_.scrollHeight:ul&&(_.scrollTop=y.offsetAt(ul.index)+ul.offset),A(d(_.scrollTop,X))});const O=J.useCallback(_=>{const X=m(_);if(X===void 0)return;const ul=a.current;e(_),z.current=!1,j.current=X,X({selectRoom:t,jumpToMessage:O}),[t,O]),x=J.useCallback(_=>{z.current=!0,j.current=null,i(X=>[...X,Mv(l,X.length,_)])},[l]),Dl=c[c.length-1].dayIndex,et=[];for(let _=v.start;_0?c[_-1]:null,b=ul===null||ul.dayIndex!==X.dayIndex;et.push(E.jsx(Bv,{index:_,message:X,highlighted:X.id===u,dateLabel:b?vv(X.dayIndex,Dl):null,unreadBelow:_===l.readUpToIndex+1},X.id))}return E.jsxs(I1.Provider,{value:C,children:[E.jsxs("ol",{id:"timeline",className:"timeline",ref:a,onScroll:T,children:[E.jsx("li",{className:"timeline-spacer",style:{height:y.offsetAt(v.start)},"aria-hidden":"true"}),et,E.jsx("li",{className:"timeline-spacer",style:{height:y.totalHeight-y.offsetAt(v.end)},"aria-hidden":"true"})]}),E.jsx(Uv,{roomName:l.name,onSend:x})]})}function Zv(){const[l,t]=J.useState(Vi[0].id),a=Vi.find(e=>e.id===l),u=e=>t(e);return E.jsxs("div",{className:"app",children:[E.jsx(Dv,{rooms:Vi,selectedRoomId:l,onSelect:u}),E.jsxs("main",{className:"room",children:[E.jsxs("header",{className:"room-header",children:[E.jsx("h1",{id:"room-header-name",className:"room-header-name",children:a.name}),E.jsx("p",{className:"room-header-topic",children:a.topic})]}),E.jsx(Qv,{room:a,onSelectRoom:u},a.id)]})]})}Fy.createRoot(document.getElementById("root")).render(E.jsx(Zv,{})); +//# sourceMappingURL=index.js.map diff --git a/suites-experimental/chat-room/dist/assets/index.js.map b/suites-experimental/chat-room/dist/assets/index.js.map new file mode 100644 index 0000000000..806f8825e3 --- /dev/null +++ b/suites-experimental/chat-room/dist/assets/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../../node_modules/react/cjs/react-jsx-runtime.production.js","../../node_modules/react/jsx-runtime.js","../../node_modules/scheduler/cjs/scheduler.production.js","../../node_modules/scheduler/index.js","../../node_modules/react/cjs/react.production.js","../../node_modules/react/index.js","../../node_modules/react-dom/cjs/react-dom.production.js","../../node_modules/react-dom/index.js","../../node_modules/react-dom/cjs/react-dom-client.production.js","../../node_modules/react-dom/client.js","../../src/data/graphics.js","../../src/data/rooms.js","../../src/components/room-list-item.jsx","../../src/components/room-list.jsx","../../src/actions.js","../../src/row-heights.js","../../src/components/composer.jsx","../../src/components/reaction.jsx","../../src/components/rich-text.jsx","../../src/components/message.jsx","../../src/components/timeline.jsx","../../src/App.jsx","../../src/main.jsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * @license React\n * scheduler.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nfunction push(heap, node) {\n var index = heap.length;\n heap.push(node);\n a: for (; 0 < index; ) {\n var parentIndex = (index - 1) >>> 1,\n parent = heap[parentIndex];\n if (0 < compare(parent, node))\n (heap[parentIndex] = node), (heap[index] = parent), (index = parentIndex);\n else break a;\n }\n}\nfunction peek(heap) {\n return 0 === heap.length ? null : heap[0];\n}\nfunction pop(heap) {\n if (0 === heap.length) return null;\n var first = heap[0],\n last = heap.pop();\n if (last !== first) {\n heap[0] = last;\n a: for (\n var index = 0, length = heap.length, halfLength = length >>> 1;\n index < halfLength;\n\n ) {\n var leftIndex = 2 * (index + 1) - 1,\n left = heap[leftIndex],\n rightIndex = leftIndex + 1,\n right = heap[rightIndex];\n if (0 > compare(left, last))\n rightIndex < length && 0 > compare(right, left)\n ? ((heap[index] = right),\n (heap[rightIndex] = last),\n (index = rightIndex))\n : ((heap[index] = left),\n (heap[leftIndex] = last),\n (index = leftIndex));\n else if (rightIndex < length && 0 > compare(right, last))\n (heap[index] = right), (heap[rightIndex] = last), (index = rightIndex);\n else break a;\n }\n }\n return first;\n}\nfunction compare(a, b) {\n var diff = a.sortIndex - b.sortIndex;\n return 0 !== diff ? diff : a.id - b.id;\n}\nexports.unstable_now = void 0;\nif (\"object\" === typeof performance && \"function\" === typeof performance.now) {\n var localPerformance = performance;\n exports.unstable_now = function () {\n return localPerformance.now();\n };\n} else {\n var localDate = Date,\n initialTime = localDate.now();\n exports.unstable_now = function () {\n return localDate.now() - initialTime;\n };\n}\nvar taskQueue = [],\n timerQueue = [],\n taskIdCounter = 1,\n currentTask = null,\n currentPriorityLevel = 3,\n isPerformingWork = !1,\n isHostCallbackScheduled = !1,\n isHostTimeoutScheduled = !1,\n needsPaint = !1,\n localSetTimeout = \"function\" === typeof setTimeout ? setTimeout : null,\n localClearTimeout = \"function\" === typeof clearTimeout ? clearTimeout : null,\n localSetImmediate = \"undefined\" !== typeof setImmediate ? setImmediate : null;\nfunction advanceTimers(currentTime) {\n for (var timer = peek(timerQueue); null !== timer; ) {\n if (null === timer.callback) pop(timerQueue);\n else if (timer.startTime <= currentTime)\n pop(timerQueue),\n (timer.sortIndex = timer.expirationTime),\n push(taskQueue, timer);\n else break;\n timer = peek(timerQueue);\n }\n}\nfunction handleTimeout(currentTime) {\n isHostTimeoutScheduled = !1;\n advanceTimers(currentTime);\n if (!isHostCallbackScheduled)\n if (null !== peek(taskQueue))\n (isHostCallbackScheduled = !0),\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline());\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);\n }\n}\nvar isMessageLoopRunning = !1,\n taskTimeoutID = -1,\n frameInterval = 5,\n startTime = -1;\nfunction shouldYieldToHost() {\n return needsPaint\n ? !0\n : exports.unstable_now() - startTime < frameInterval\n ? !1\n : !0;\n}\nfunction performWorkUntilDeadline() {\n needsPaint = !1;\n if (isMessageLoopRunning) {\n var currentTime = exports.unstable_now();\n startTime = currentTime;\n var hasMoreWork = !0;\n try {\n a: {\n isHostCallbackScheduled = !1;\n isHostTimeoutScheduled &&\n ((isHostTimeoutScheduled = !1),\n localClearTimeout(taskTimeoutID),\n (taskTimeoutID = -1));\n isPerformingWork = !0;\n var previousPriorityLevel = currentPriorityLevel;\n try {\n b: {\n advanceTimers(currentTime);\n for (\n currentTask = peek(taskQueue);\n null !== currentTask &&\n !(\n currentTask.expirationTime > currentTime && shouldYieldToHost()\n );\n\n ) {\n var callback = currentTask.callback;\n if (\"function\" === typeof callback) {\n currentTask.callback = null;\n currentPriorityLevel = currentTask.priorityLevel;\n var continuationCallback = callback(\n currentTask.expirationTime <= currentTime\n );\n currentTime = exports.unstable_now();\n if (\"function\" === typeof continuationCallback) {\n currentTask.callback = continuationCallback;\n advanceTimers(currentTime);\n hasMoreWork = !0;\n break b;\n }\n currentTask === peek(taskQueue) && pop(taskQueue);\n advanceTimers(currentTime);\n } else pop(taskQueue);\n currentTask = peek(taskQueue);\n }\n if (null !== currentTask) hasMoreWork = !0;\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(\n handleTimeout,\n firstTimer.startTime - currentTime\n );\n hasMoreWork = !1;\n }\n }\n break a;\n } finally {\n (currentTask = null),\n (currentPriorityLevel = previousPriorityLevel),\n (isPerformingWork = !1);\n }\n hasMoreWork = void 0;\n }\n } finally {\n hasMoreWork\n ? schedulePerformWorkUntilDeadline()\n : (isMessageLoopRunning = !1);\n }\n }\n}\nvar schedulePerformWorkUntilDeadline;\nif (\"function\" === typeof localSetImmediate)\n schedulePerformWorkUntilDeadline = function () {\n localSetImmediate(performWorkUntilDeadline);\n };\nelse if (\"undefined\" !== typeof MessageChannel) {\n var channel = new MessageChannel(),\n port = channel.port2;\n channel.port1.onmessage = performWorkUntilDeadline;\n schedulePerformWorkUntilDeadline = function () {\n port.postMessage(null);\n };\n} else\n schedulePerformWorkUntilDeadline = function () {\n localSetTimeout(performWorkUntilDeadline, 0);\n };\nfunction requestHostTimeout(callback, ms) {\n taskTimeoutID = localSetTimeout(function () {\n callback(exports.unstable_now());\n }, ms);\n}\nexports.unstable_IdlePriority = 5;\nexports.unstable_ImmediatePriority = 1;\nexports.unstable_LowPriority = 4;\nexports.unstable_NormalPriority = 3;\nexports.unstable_Profiling = null;\nexports.unstable_UserBlockingPriority = 2;\nexports.unstable_cancelCallback = function (task) {\n task.callback = null;\n};\nexports.unstable_forceFrameRate = function (fps) {\n 0 > fps || 125 < fps\n ? console.error(\n \"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"\n )\n : (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);\n};\nexports.unstable_getCurrentPriorityLevel = function () {\n return currentPriorityLevel;\n};\nexports.unstable_next = function (eventHandler) {\n switch (currentPriorityLevel) {\n case 1:\n case 2:\n case 3:\n var priorityLevel = 3;\n break;\n default:\n priorityLevel = currentPriorityLevel;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_requestPaint = function () {\n needsPaint = !0;\n};\nexports.unstable_runWithPriority = function (priorityLevel, eventHandler) {\n switch (priorityLevel) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n break;\n default:\n priorityLevel = 3;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_scheduleCallback = function (\n priorityLevel,\n callback,\n options\n) {\n var currentTime = exports.unstable_now();\n \"object\" === typeof options && null !== options\n ? ((options = options.delay),\n (options =\n \"number\" === typeof options && 0 < options\n ? currentTime + options\n : currentTime))\n : (options = currentTime);\n switch (priorityLevel) {\n case 1:\n var timeout = -1;\n break;\n case 2:\n timeout = 250;\n break;\n case 5:\n timeout = 1073741823;\n break;\n case 4:\n timeout = 1e4;\n break;\n default:\n timeout = 5e3;\n }\n timeout = options + timeout;\n priorityLevel = {\n id: taskIdCounter++,\n callback: callback,\n priorityLevel: priorityLevel,\n startTime: options,\n expirationTime: timeout,\n sortIndex: -1\n };\n options > currentTime\n ? ((priorityLevel.sortIndex = options),\n push(timerQueue, priorityLevel),\n null === peek(taskQueue) &&\n priorityLevel === peek(timerQueue) &&\n (isHostTimeoutScheduled\n ? (localClearTimeout(taskTimeoutID), (taskTimeoutID = -1))\n : (isHostTimeoutScheduled = !0),\n requestHostTimeout(handleTimeout, options - currentTime)))\n : ((priorityLevel.sortIndex = timeout),\n push(taskQueue, priorityLevel),\n isHostCallbackScheduled ||\n isPerformingWork ||\n ((isHostCallbackScheduled = !0),\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline())));\n return priorityLevel;\n};\nexports.unstable_shouldYield = shouldYieldToHost;\nexports.unstable_wrapCallback = function (callback) {\n var parentPriorityLevel = currentPriorityLevel;\n return function () {\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = parentPriorityLevel;\n try {\n return callback.apply(this, arguments);\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n };\n};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","/**\n * @license React\n * react.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function () {},\n enqueueReplaceState: function () {},\n enqueueSetState: function () {}\n },\n assign = Object.assign,\n emptyObject = {};\nfunction Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nComponent.prototype.isReactComponent = {};\nComponent.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n};\nComponent.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n};\nfunction ComponentDummy() {}\nComponentDummy.prototype = Component.prototype;\nfunction PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nvar pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());\npureComponentPrototype.constructor = PureComponent;\nassign(pureComponentPrototype, Component.prototype);\npureComponentPrototype.isPureReactComponent = !0;\nvar isArrayImpl = Array.isArray;\nfunction noop() {}\nvar ReactSharedInternals = { H: null, A: null, T: null, S: null },\n hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction ReactElement(type, key, props) {\n var refProp = props.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== refProp ? refProp : null,\n props: props\n };\n}\nfunction cloneAndReplaceKey(oldElement, newKey) {\n return ReactElement(oldElement.type, newKey, oldElement.props);\n}\nfunction isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n}\nfunction escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n}\nvar userProvidedKeyEscapeRegex = /\\/+/g;\nfunction getElementKey(element, index) {\n return \"object\" === typeof element && null !== element && null != element.key\n ? escape(\"\" + element.key)\n : index.toString(36);\n}\nfunction resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n}\nfunction mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback)\n return (\n (callback = callback(children)),\n (invokeCallback =\n \"\" === nameSoFar ? \".\" + getElementKey(children, 0) : nameSoFar),\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != invokeCallback &&\n (escapedPrefix =\n invokeCallback.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (callback = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (children && children.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n invokeCallback\n )),\n array.push(callback)),\n 1\n );\n invokeCallback = 0;\n var nextNamePrefix = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = nextNamePrefix + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n children = i.call(children), i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = nextNamePrefix + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n}\nfunction mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n}\nfunction lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ctor = payload._result;\n ctor = ctor();\n ctor.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 1), (payload._result = moduleObject);\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 2), (payload._result = error);\n }\n );\n -1 === payload._status && ((payload._status = 0), (payload._result = ctor));\n }\n if (1 === payload._status) return payload._result.default;\n throw payload._result;\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n Children = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n };\nexports.Activity = REACT_ACTIVITY_TYPE;\nexports.Children = Children;\nexports.Component = Component;\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.Profiler = REACT_PROFILER_TYPE;\nexports.PureComponent = PureComponent;\nexports.StrictMode = REACT_STRICT_MODE_TYPE;\nexports.Suspense = REACT_SUSPENSE_TYPE;\nexports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\nexports.__COMPILER_RUNTIME = {\n __proto__: null,\n c: function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n }\n};\nexports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n};\nexports.cacheSignal = function () {\n return null;\n};\nexports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" + element + \".\"\n );\n var props = assign({}, element.props),\n key = element.key;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n for (var childArray = Array(propName), i = 0; i < propName; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n return ReactElement(element.type, key, props);\n};\nexports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n return defaultValue;\n};\nexports.createElement = function (type, config, children) {\n var propName,\n props = {},\n key = null;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (props[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) props.children = children;\n else if (1 < childrenLength) {\n for (var childArray = Array(childrenLength), i = 0; i < childrenLength; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === props[propName] &&\n (props[propName] = childrenLength[propName]);\n return ReactElement(type, key, props);\n};\nexports.createRef = function () {\n return { current: null };\n};\nexports.forwardRef = function (render) {\n return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };\n};\nexports.isValidElement = isValidElement;\nexports.lazy = function (ctor) {\n return {\n $$typeof: REACT_LAZY_TYPE,\n _payload: { _status: -1, _result: ctor },\n _init: lazyInitializer\n };\n};\nexports.memo = function (type, compare) {\n return {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n};\nexports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n returnValue.then(noop, reportGlobalError);\n } catch (error) {\n reportGlobalError(error);\n } finally {\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n};\nexports.unstable_useCacheRefresh = function () {\n return ReactSharedInternals.H.useCacheRefresh();\n};\nexports.use = function (usable) {\n return ReactSharedInternals.H.use(usable);\n};\nexports.useActionState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useActionState(action, initialState, permalink);\n};\nexports.useCallback = function (callback, deps) {\n return ReactSharedInternals.H.useCallback(callback, deps);\n};\nexports.useContext = function (Context) {\n return ReactSharedInternals.H.useContext(Context);\n};\nexports.useDebugValue = function () {};\nexports.useDeferredValue = function (value, initialValue) {\n return ReactSharedInternals.H.useDeferredValue(value, initialValue);\n};\nexports.useEffect = function (create, deps) {\n return ReactSharedInternals.H.useEffect(create, deps);\n};\nexports.useEffectEvent = function (callback) {\n return ReactSharedInternals.H.useEffectEvent(callback);\n};\nexports.useId = function () {\n return ReactSharedInternals.H.useId();\n};\nexports.useImperativeHandle = function (ref, create, deps) {\n return ReactSharedInternals.H.useImperativeHandle(ref, create, deps);\n};\nexports.useInsertionEffect = function (create, deps) {\n return ReactSharedInternals.H.useInsertionEffect(create, deps);\n};\nexports.useLayoutEffect = function (create, deps) {\n return ReactSharedInternals.H.useLayoutEffect(create, deps);\n};\nexports.useMemo = function (create, deps) {\n return ReactSharedInternals.H.useMemo(create, deps);\n};\nexports.useOptimistic = function (passthrough, reducer) {\n return ReactSharedInternals.H.useOptimistic(passthrough, reducer);\n};\nexports.useReducer = function (reducer, initialArg, init) {\n return ReactSharedInternals.H.useReducer(reducer, initialArg, init);\n};\nexports.useRef = function (initialValue) {\n return ReactSharedInternals.H.useRef(initialValue);\n};\nexports.useState = function (initialState) {\n return ReactSharedInternals.H.useState(initialState);\n};\nexports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n) {\n return ReactSharedInternals.H.useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n};\nexports.useTransition = function () {\n return ReactSharedInternals.H.useTransition();\n};\nexports.version = \"19.2.8\";\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react.production.js');\n} else {\n module.exports = require('./cjs/react.development.js');\n}\n","/**\n * @license React\n * react-dom.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar React = require(\"react\");\nfunction formatProdErrorMessage(code) {\n var url = \"https://react.dev/errors/\" + code;\n if (1 < arguments.length) {\n url += \"?args[]=\" + encodeURIComponent(arguments[1]);\n for (var i = 2; i < arguments.length; i++)\n url += \"&args[]=\" + encodeURIComponent(arguments[i]);\n }\n return (\n \"Minified React error #\" +\n code +\n \"; visit \" +\n url +\n \" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"\n );\n}\nfunction noop() {}\nvar Internals = {\n d: {\n f: noop,\n r: function () {\n throw Error(formatProdErrorMessage(522));\n },\n D: noop,\n C: noop,\n L: noop,\n m: noop,\n X: noop,\n S: noop,\n M: noop\n },\n p: 0,\n findDOMNode: null\n },\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\");\nfunction createPortal$1(children, containerInfo, implementation) {\n var key =\n 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;\n return {\n $$typeof: REACT_PORTAL_TYPE,\n key: null == key ? null : \"\" + key,\n children: children,\n containerInfo: containerInfo,\n implementation: implementation\n };\n}\nvar ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\nfunction getCrossOriginStringAs(as, input) {\n if (\"font\" === as) return \"\";\n if (\"string\" === typeof input)\n return \"use-credentials\" === input ? input : \"\";\n}\nexports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n Internals;\nexports.createPortal = function (children, container) {\n var key =\n 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;\n if (\n !container ||\n (1 !== container.nodeType &&\n 9 !== container.nodeType &&\n 11 !== container.nodeType)\n )\n throw Error(formatProdErrorMessage(299));\n return createPortal$1(children, container, null, key);\n};\nexports.flushSync = function (fn) {\n var previousTransition = ReactSharedInternals.T,\n previousUpdatePriority = Internals.p;\n try {\n if (((ReactSharedInternals.T = null), (Internals.p = 2), fn)) return fn();\n } finally {\n (ReactSharedInternals.T = previousTransition),\n (Internals.p = previousUpdatePriority),\n Internals.d.f();\n }\n};\nexports.preconnect = function (href, options) {\n \"string\" === typeof href &&\n (options\n ? ((options = options.crossOrigin),\n (options =\n \"string\" === typeof options\n ? \"use-credentials\" === options\n ? options\n : \"\"\n : void 0))\n : (options = null),\n Internals.d.C(href, options));\n};\nexports.prefetchDNS = function (href) {\n \"string\" === typeof href && Internals.d.D(href);\n};\nexports.preinit = function (href, options) {\n if (\"string\" === typeof href && options && \"string\" === typeof options.as) {\n var as = options.as,\n crossOrigin = getCrossOriginStringAs(as, options.crossOrigin),\n integrity =\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n fetchPriority =\n \"string\" === typeof options.fetchPriority\n ? options.fetchPriority\n : void 0;\n \"style\" === as\n ? Internals.d.S(\n href,\n \"string\" === typeof options.precedence ? options.precedence : void 0,\n {\n crossOrigin: crossOrigin,\n integrity: integrity,\n fetchPriority: fetchPriority\n }\n )\n : \"script\" === as &&\n Internals.d.X(href, {\n crossOrigin: crossOrigin,\n integrity: integrity,\n fetchPriority: fetchPriority,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0\n });\n }\n};\nexports.preinitModule = function (href, options) {\n if (\"string\" === typeof href)\n if (\"object\" === typeof options && null !== options) {\n if (null == options.as || \"script\" === options.as) {\n var crossOrigin = getCrossOriginStringAs(\n options.as,\n options.crossOrigin\n );\n Internals.d.M(href, {\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0\n });\n }\n } else null == options && Internals.d.M(href);\n};\nexports.preload = function (href, options) {\n if (\n \"string\" === typeof href &&\n \"object\" === typeof options &&\n null !== options &&\n \"string\" === typeof options.as\n ) {\n var as = options.as,\n crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);\n Internals.d.L(href, as, {\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0,\n type: \"string\" === typeof options.type ? options.type : void 0,\n fetchPriority:\n \"string\" === typeof options.fetchPriority\n ? options.fetchPriority\n : void 0,\n referrerPolicy:\n \"string\" === typeof options.referrerPolicy\n ? options.referrerPolicy\n : void 0,\n imageSrcSet:\n \"string\" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,\n imageSizes:\n \"string\" === typeof options.imageSizes ? options.imageSizes : void 0,\n media: \"string\" === typeof options.media ? options.media : void 0\n });\n }\n};\nexports.preloadModule = function (href, options) {\n if (\"string\" === typeof href)\n if (options) {\n var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);\n Internals.d.m(href, {\n as:\n \"string\" === typeof options.as && \"script\" !== options.as\n ? options.as\n : void 0,\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0\n });\n } else Internals.d.m(href);\n};\nexports.requestFormReset = function (form) {\n Internals.d.r(form);\n};\nexports.unstable_batchedUpdates = function (fn, a) {\n return fn(a);\n};\nexports.useFormState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useFormState(action, initialState, permalink);\n};\nexports.useFormStatus = function () {\n return ReactSharedInternals.H.useHostTransitionStatus();\n};\nexports.version = \"19.2.8\";\n","'use strict';\n\nfunction checkDCE() {\n /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\n if (\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'\n ) {\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // This branch is unreachable because this function is only called\n // in production, but the condition is true only in development.\n // Therefore if the branch is still here, dead code elimination wasn't\n // properly applied.\n // Don't change the message. React DevTools relies on it. Also make sure\n // this message doesn't occur elsewhere in this function, or it will cause\n // a false positive.\n throw new Error('^_^');\n }\n try {\n // Verify that the code above has been dead code eliminated (DCE'd).\n __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);\n } catch (err) {\n // DevTools shouldn't crash React, no matter what.\n // We should still report in case we break this code.\n console.error(err);\n }\n}\n\nif (process.env.NODE_ENV === 'production') {\n // DCE check should happen before ReactDOM bundle executes so that\n // DevTools can report bad minification during injection.\n checkDCE();\n module.exports = require('./cjs/react-dom.production.js');\n} else {\n module.exports = require('./cjs/react-dom.development.js');\n}\n","/**\n * @license React\n * react-dom-client.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n\"use strict\";\nvar Scheduler = require(\"scheduler\"),\n React = require(\"react\"),\n ReactDOM = require(\"react-dom\");\nfunction formatProdErrorMessage(code) {\n var url = \"https://react.dev/errors/\" + code;\n if (1 < arguments.length) {\n url += \"?args[]=\" + encodeURIComponent(arguments[1]);\n for (var i = 2; i < arguments.length; i++)\n url += \"&args[]=\" + encodeURIComponent(arguments[i]);\n }\n return (\n \"Minified React error #\" +\n code +\n \"; visit \" +\n url +\n \" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"\n );\n}\nfunction isValidContainer(node) {\n return !(\n !node ||\n (1 !== node.nodeType && 9 !== node.nodeType && 11 !== node.nodeType)\n );\n}\nfunction getNearestMountedFiber(fiber) {\n var node = fiber,\n nearestMounted = fiber;\n if (fiber.alternate) for (; node.return; ) node = node.return;\n else {\n fiber = node;\n do\n (node = fiber),\n 0 !== (node.flags & 4098) && (nearestMounted = node.return),\n (fiber = node.return);\n while (fiber);\n }\n return 3 === node.tag ? nearestMounted : null;\n}\nfunction getSuspenseInstanceFromFiber(fiber) {\n if (13 === fiber.tag) {\n var suspenseState = fiber.memoizedState;\n null === suspenseState &&\n ((fiber = fiber.alternate),\n null !== fiber && (suspenseState = fiber.memoizedState));\n if (null !== suspenseState) return suspenseState.dehydrated;\n }\n return null;\n}\nfunction getActivityInstanceFromFiber(fiber) {\n if (31 === fiber.tag) {\n var activityState = fiber.memoizedState;\n null === activityState &&\n ((fiber = fiber.alternate),\n null !== fiber && (activityState = fiber.memoizedState));\n if (null !== activityState) return activityState.dehydrated;\n }\n return null;\n}\nfunction assertIsMounted(fiber) {\n if (getNearestMountedFiber(fiber) !== fiber)\n throw Error(formatProdErrorMessage(188));\n}\nfunction findCurrentFiberUsingSlowPath(fiber) {\n var alternate = fiber.alternate;\n if (!alternate) {\n alternate = getNearestMountedFiber(fiber);\n if (null === alternate) throw Error(formatProdErrorMessage(188));\n return alternate !== fiber ? null : fiber;\n }\n for (var a = fiber, b = alternate; ; ) {\n var parentA = a.return;\n if (null === parentA) break;\n var parentB = parentA.alternate;\n if (null === parentB) {\n b = parentA.return;\n if (null !== b) {\n a = b;\n continue;\n }\n break;\n }\n if (parentA.child === parentB.child) {\n for (parentB = parentA.child; parentB; ) {\n if (parentB === a) return assertIsMounted(parentA), fiber;\n if (parentB === b) return assertIsMounted(parentA), alternate;\n parentB = parentB.sibling;\n }\n throw Error(formatProdErrorMessage(188));\n }\n if (a.return !== b.return) (a = parentA), (b = parentB);\n else {\n for (var didFindChild = !1, child$0 = parentA.child; child$0; ) {\n if (child$0 === a) {\n didFindChild = !0;\n a = parentA;\n b = parentB;\n break;\n }\n if (child$0 === b) {\n didFindChild = !0;\n b = parentA;\n a = parentB;\n break;\n }\n child$0 = child$0.sibling;\n }\n if (!didFindChild) {\n for (child$0 = parentB.child; child$0; ) {\n if (child$0 === a) {\n didFindChild = !0;\n a = parentB;\n b = parentA;\n break;\n }\n if (child$0 === b) {\n didFindChild = !0;\n b = parentB;\n a = parentA;\n break;\n }\n child$0 = child$0.sibling;\n }\n if (!didFindChild) throw Error(formatProdErrorMessage(189));\n }\n }\n if (a.alternate !== b) throw Error(formatProdErrorMessage(190));\n }\n if (3 !== a.tag) throw Error(formatProdErrorMessage(188));\n return a.stateNode.current === a ? fiber : alternate;\n}\nfunction findCurrentHostFiberImpl(node) {\n var tag = node.tag;\n if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;\n for (node = node.child; null !== node; ) {\n tag = findCurrentHostFiberImpl(node);\n if (null !== tag) return tag;\n node = node.sibling;\n }\n return null;\n}\nvar assign = Object.assign,\n REACT_LEGACY_ELEMENT_TYPE = Symbol.for(\"react.element\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nSymbol.for(\"react.scope\");\nvar REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\");\nSymbol.for(\"react.legacy_hidden\");\nSymbol.for(\"react.tracing_marker\");\nvar REACT_MEMO_CACHE_SENTINEL = Symbol.for(\"react.memo_cache_sentinel\");\nSymbol.for(\"react.view_transition\");\nvar MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\");\nfunction getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (type.$$typeof) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n}\nvar isArrayImpl = Array.isArray,\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n ReactDOMSharedInternals =\n ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n sharedNotPendingObject = {\n pending: !1,\n data: null,\n method: null,\n action: null\n },\n valueStack = [],\n index = -1;\nfunction createCursor(defaultValue) {\n return { current: defaultValue };\n}\nfunction pop(cursor) {\n 0 > index ||\n ((cursor.current = valueStack[index]), (valueStack[index] = null), index--);\n}\nfunction push(cursor, value) {\n index++;\n valueStack[index] = cursor.current;\n cursor.current = value;\n}\nvar contextStackCursor = createCursor(null),\n contextFiberStackCursor = createCursor(null),\n rootInstanceStackCursor = createCursor(null),\n hostTransitionProviderCursor = createCursor(null);\nfunction pushHostContainer(fiber, nextRootInstance) {\n push(rootInstanceStackCursor, nextRootInstance);\n push(contextFiberStackCursor, fiber);\n push(contextStackCursor, null);\n switch (nextRootInstance.nodeType) {\n case 9:\n case 11:\n fiber = (fiber = nextRootInstance.documentElement)\n ? (fiber = fiber.namespaceURI)\n ? getOwnHostContext(fiber)\n : 0\n : 0;\n break;\n default:\n if (\n ((fiber = nextRootInstance.tagName),\n (nextRootInstance = nextRootInstance.namespaceURI))\n )\n (nextRootInstance = getOwnHostContext(nextRootInstance)),\n (fiber = getChildHostContextProd(nextRootInstance, fiber));\n else\n switch (fiber) {\n case \"svg\":\n fiber = 1;\n break;\n case \"math\":\n fiber = 2;\n break;\n default:\n fiber = 0;\n }\n }\n pop(contextStackCursor);\n push(contextStackCursor, fiber);\n}\nfunction popHostContainer() {\n pop(contextStackCursor);\n pop(contextFiberStackCursor);\n pop(rootInstanceStackCursor);\n}\nfunction pushHostContext(fiber) {\n null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber);\n var context = contextStackCursor.current;\n var JSCompiler_inline_result = getChildHostContextProd(context, fiber.type);\n context !== JSCompiler_inline_result &&\n (push(contextFiberStackCursor, fiber),\n push(contextStackCursor, JSCompiler_inline_result));\n}\nfunction popHostContext(fiber) {\n contextFiberStackCursor.current === fiber &&\n (pop(contextStackCursor), pop(contextFiberStackCursor));\n hostTransitionProviderCursor.current === fiber &&\n (pop(hostTransitionProviderCursor),\n (HostTransitionContext._currentValue = sharedNotPendingObject));\n}\nvar prefix, suffix;\nfunction describeBuiltInComponentFrame(name) {\n if (void 0 === prefix)\n try {\n throw Error();\n } catch (x) {\n var match = x.stack.trim().match(/\\n( *(at )?)/);\n prefix = (match && match[1]) || \"\";\n suffix =\n -1 < x.stack.indexOf(\"\\n at\")\n ? \" ()\"\n : -1 < x.stack.indexOf(\"@\")\n ? \"@unknown:0:0\"\n : \"\";\n }\n return \"\\n\" + prefix + name + suffix;\n}\nvar reentry = !1;\nfunction describeNativeComponentFrame(fn, construct) {\n if (!fn || reentry) return \"\";\n reentry = !0;\n var previousPrepareStackTrace = Error.prepareStackTrace;\n Error.prepareStackTrace = void 0;\n try {\n var RunInRootFrame = {\n DetermineComponentFrameRoot: function () {\n try {\n if (construct) {\n var Fake = function () {\n throw Error();\n };\n Object.defineProperty(Fake.prototype, \"props\", {\n set: function () {\n throw Error();\n }\n });\n if (\"object\" === typeof Reflect && Reflect.construct) {\n try {\n Reflect.construct(Fake, []);\n } catch (x) {\n var control = x;\n }\n Reflect.construct(fn, [], Fake);\n } else {\n try {\n Fake.call();\n } catch (x$1) {\n control = x$1;\n }\n fn.call(Fake.prototype);\n }\n } else {\n try {\n throw Error();\n } catch (x$2) {\n control = x$2;\n }\n (Fake = fn()) &&\n \"function\" === typeof Fake.catch &&\n Fake.catch(function () {});\n }\n } catch (sample) {\n if (sample && control && \"string\" === typeof sample.stack)\n return [sample.stack, control.stack];\n }\n return [null, null];\n }\n };\n RunInRootFrame.DetermineComponentFrameRoot.displayName =\n \"DetermineComponentFrameRoot\";\n var namePropDescriptor = Object.getOwnPropertyDescriptor(\n RunInRootFrame.DetermineComponentFrameRoot,\n \"name\"\n );\n namePropDescriptor &&\n namePropDescriptor.configurable &&\n Object.defineProperty(\n RunInRootFrame.DetermineComponentFrameRoot,\n \"name\",\n { value: \"DetermineComponentFrameRoot\" }\n );\n var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(),\n sampleStack = _RunInRootFrame$Deter[0],\n controlStack = _RunInRootFrame$Deter[1];\n if (sampleStack && controlStack) {\n var sampleLines = sampleStack.split(\"\\n\"),\n controlLines = controlStack.split(\"\\n\");\n for (\n namePropDescriptor = RunInRootFrame = 0;\n RunInRootFrame < sampleLines.length &&\n !sampleLines[RunInRootFrame].includes(\"DetermineComponentFrameRoot\");\n\n )\n RunInRootFrame++;\n for (\n ;\n namePropDescriptor < controlLines.length &&\n !controlLines[namePropDescriptor].includes(\n \"DetermineComponentFrameRoot\"\n );\n\n )\n namePropDescriptor++;\n if (\n RunInRootFrame === sampleLines.length ||\n namePropDescriptor === controlLines.length\n )\n for (\n RunInRootFrame = sampleLines.length - 1,\n namePropDescriptor = controlLines.length - 1;\n 1 <= RunInRootFrame &&\n 0 <= namePropDescriptor &&\n sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor];\n\n )\n namePropDescriptor--;\n for (\n ;\n 1 <= RunInRootFrame && 0 <= namePropDescriptor;\n RunInRootFrame--, namePropDescriptor--\n )\n if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) {\n if (1 !== RunInRootFrame || 1 !== namePropDescriptor) {\n do\n if (\n (RunInRootFrame--,\n namePropDescriptor--,\n 0 > namePropDescriptor ||\n sampleLines[RunInRootFrame] !==\n controlLines[namePropDescriptor])\n ) {\n var frame =\n \"\\n\" +\n sampleLines[RunInRootFrame].replace(\" at new \", \" at \");\n fn.displayName &&\n frame.includes(\"\") &&\n (frame = frame.replace(\"\", fn.displayName));\n return frame;\n }\n while (1 <= RunInRootFrame && 0 <= namePropDescriptor);\n }\n break;\n }\n }\n } finally {\n (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace);\n }\n return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : \"\")\n ? describeBuiltInComponentFrame(previousPrepareStackTrace)\n : \"\";\n}\nfunction describeFiber(fiber, childFiber) {\n switch (fiber.tag) {\n case 26:\n case 27:\n case 5:\n return describeBuiltInComponentFrame(fiber.type);\n case 16:\n return describeBuiltInComponentFrame(\"Lazy\");\n case 13:\n return fiber.child !== childFiber && null !== childFiber\n ? describeBuiltInComponentFrame(\"Suspense Fallback\")\n : describeBuiltInComponentFrame(\"Suspense\");\n case 19:\n return describeBuiltInComponentFrame(\"SuspenseList\");\n case 0:\n case 15:\n return describeNativeComponentFrame(fiber.type, !1);\n case 11:\n return describeNativeComponentFrame(fiber.type.render, !1);\n case 1:\n return describeNativeComponentFrame(fiber.type, !0);\n case 31:\n return describeBuiltInComponentFrame(\"Activity\");\n default:\n return \"\";\n }\n}\nfunction getStackByFiberInDevAndProd(workInProgress) {\n try {\n var info = \"\",\n previous = null;\n do\n (info += describeFiber(workInProgress, previous)),\n (previous = workInProgress),\n (workInProgress = workInProgress.return);\n while (workInProgress);\n return info;\n } catch (x) {\n return \"\\nError generating stack: \" + x.message + \"\\n\" + x.stack;\n }\n}\nvar hasOwnProperty = Object.prototype.hasOwnProperty,\n scheduleCallback$3 = Scheduler.unstable_scheduleCallback,\n cancelCallback$1 = Scheduler.unstable_cancelCallback,\n shouldYield = Scheduler.unstable_shouldYield,\n requestPaint = Scheduler.unstable_requestPaint,\n now = Scheduler.unstable_now,\n getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,\n ImmediatePriority = Scheduler.unstable_ImmediatePriority,\n UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,\n NormalPriority$1 = Scheduler.unstable_NormalPriority,\n LowPriority = Scheduler.unstable_LowPriority,\n IdlePriority = Scheduler.unstable_IdlePriority,\n log$1 = Scheduler.log,\n unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue,\n rendererID = null,\n injectedHook = null;\nfunction setIsStrictModeForDevtools(newIsStrictMode) {\n \"function\" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode);\n if (injectedHook && \"function\" === typeof injectedHook.setStrictMode)\n try {\n injectedHook.setStrictMode(rendererID, newIsStrictMode);\n } catch (err) {}\n}\nvar clz32 = Math.clz32 ? Math.clz32 : clz32Fallback,\n log = Math.log,\n LN2 = Math.LN2;\nfunction clz32Fallback(x) {\n x >>>= 0;\n return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0;\n}\nvar nextTransitionUpdateLane = 256,\n nextTransitionDeferredLane = 262144,\n nextRetryLane = 4194304;\nfunction getHighestPriorityLanes(lanes) {\n var pendingSyncLanes = lanes & 42;\n if (0 !== pendingSyncLanes) return pendingSyncLanes;\n switch (lanes & -lanes) {\n case 1:\n return 1;\n case 2:\n return 2;\n case 4:\n return 4;\n case 8:\n return 8;\n case 16:\n return 16;\n case 32:\n return 32;\n case 64:\n return 64;\n case 128:\n return 128;\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n return lanes & 261888;\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n return lanes & 3932160;\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n return lanes & 62914560;\n case 67108864:\n return 67108864;\n case 134217728:\n return 134217728;\n case 268435456:\n return 268435456;\n case 536870912:\n return 536870912;\n case 1073741824:\n return 0;\n default:\n return lanes;\n }\n}\nfunction getNextLanes(root, wipLanes, rootHasPendingCommit) {\n var pendingLanes = root.pendingLanes;\n if (0 === pendingLanes) return 0;\n var nextLanes = 0,\n suspendedLanes = root.suspendedLanes,\n pingedLanes = root.pingedLanes;\n root = root.warmLanes;\n var nonIdlePendingLanes = pendingLanes & 134217727;\n 0 !== nonIdlePendingLanes\n ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes),\n 0 !== pendingLanes\n ? (nextLanes = getHighestPriorityLanes(pendingLanes))\n : ((pingedLanes &= nonIdlePendingLanes),\n 0 !== pingedLanes\n ? (nextLanes = getHighestPriorityLanes(pingedLanes))\n : rootHasPendingCommit ||\n ((rootHasPendingCommit = nonIdlePendingLanes & ~root),\n 0 !== rootHasPendingCommit &&\n (nextLanes = getHighestPriorityLanes(rootHasPendingCommit)))))\n : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes),\n 0 !== nonIdlePendingLanes\n ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes))\n : 0 !== pingedLanes\n ? (nextLanes = getHighestPriorityLanes(pingedLanes))\n : rootHasPendingCommit ||\n ((rootHasPendingCommit = pendingLanes & ~root),\n 0 !== rootHasPendingCommit &&\n (nextLanes = getHighestPriorityLanes(rootHasPendingCommit))));\n return 0 === nextLanes\n ? 0\n : 0 !== wipLanes &&\n wipLanes !== nextLanes &&\n 0 === (wipLanes & suspendedLanes) &&\n ((suspendedLanes = nextLanes & -nextLanes),\n (rootHasPendingCommit = wipLanes & -wipLanes),\n suspendedLanes >= rootHasPendingCommit ||\n (32 === suspendedLanes && 0 !== (rootHasPendingCommit & 4194048)))\n ? wipLanes\n : nextLanes;\n}\nfunction checkIfRootIsPrerendering(root, renderLanes) {\n return (\n 0 ===\n (root.pendingLanes &\n ~(root.suspendedLanes & ~root.pingedLanes) &\n renderLanes)\n );\n}\nfunction computeExpirationTime(lane, currentTime) {\n switch (lane) {\n case 1:\n case 2:\n case 4:\n case 8:\n case 64:\n return currentTime + 250;\n case 16:\n case 32:\n case 128:\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n return currentTime + 5e3;\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n return -1;\n case 67108864:\n case 134217728:\n case 268435456:\n case 536870912:\n case 1073741824:\n return -1;\n default:\n return -1;\n }\n}\nfunction claimNextRetryLane() {\n var lane = nextRetryLane;\n nextRetryLane <<= 1;\n 0 === (nextRetryLane & 62914560) && (nextRetryLane = 4194304);\n return lane;\n}\nfunction createLaneMap(initial) {\n for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);\n return laneMap;\n}\nfunction markRootUpdated$1(root, updateLane) {\n root.pendingLanes |= updateLane;\n 268435456 !== updateLane &&\n ((root.suspendedLanes = 0), (root.pingedLanes = 0), (root.warmLanes = 0));\n}\nfunction markRootFinished(\n root,\n finishedLanes,\n remainingLanes,\n spawnedLane,\n updatedLanes,\n suspendedRetryLanes\n) {\n var previouslyPendingLanes = root.pendingLanes;\n root.pendingLanes = remainingLanes;\n root.suspendedLanes = 0;\n root.pingedLanes = 0;\n root.warmLanes = 0;\n root.expiredLanes &= remainingLanes;\n root.entangledLanes &= remainingLanes;\n root.errorRecoveryDisabledLanes &= remainingLanes;\n root.shellSuspendCounter = 0;\n var entanglements = root.entanglements,\n expirationTimes = root.expirationTimes,\n hiddenUpdates = root.hiddenUpdates;\n for (\n remainingLanes = previouslyPendingLanes & ~remainingLanes;\n 0 < remainingLanes;\n\n ) {\n var index$7 = 31 - clz32(remainingLanes),\n lane = 1 << index$7;\n entanglements[index$7] = 0;\n expirationTimes[index$7] = -1;\n var hiddenUpdatesForLane = hiddenUpdates[index$7];\n if (null !== hiddenUpdatesForLane)\n for (\n hiddenUpdates[index$7] = null, index$7 = 0;\n index$7 < hiddenUpdatesForLane.length;\n index$7++\n ) {\n var update = hiddenUpdatesForLane[index$7];\n null !== update && (update.lane &= -536870913);\n }\n remainingLanes &= ~lane;\n }\n 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, 0);\n 0 !== suspendedRetryLanes &&\n 0 === updatedLanes &&\n 0 !== root.tag &&\n (root.suspendedLanes |=\n suspendedRetryLanes & ~(previouslyPendingLanes & ~finishedLanes));\n}\nfunction markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {\n root.pendingLanes |= spawnedLane;\n root.suspendedLanes &= ~spawnedLane;\n var spawnedLaneIndex = 31 - clz32(spawnedLane);\n root.entangledLanes |= spawnedLane;\n root.entanglements[spawnedLaneIndex] =\n root.entanglements[spawnedLaneIndex] |\n 1073741824 |\n (entangledLanes & 261930);\n}\nfunction markRootEntangled(root, entangledLanes) {\n var rootEntangledLanes = (root.entangledLanes |= entangledLanes);\n for (root = root.entanglements; rootEntangledLanes; ) {\n var index$8 = 31 - clz32(rootEntangledLanes),\n lane = 1 << index$8;\n (lane & entangledLanes) | (root[index$8] & entangledLanes) &&\n (root[index$8] |= entangledLanes);\n rootEntangledLanes &= ~lane;\n }\n}\nfunction getBumpedLaneForHydration(root, renderLanes) {\n var renderLane = renderLanes & -renderLanes;\n renderLane =\n 0 !== (renderLane & 42) ? 1 : getBumpedLaneForHydrationByLane(renderLane);\n return 0 !== (renderLane & (root.suspendedLanes | renderLanes))\n ? 0\n : renderLane;\n}\nfunction getBumpedLaneForHydrationByLane(lane) {\n switch (lane) {\n case 2:\n lane = 1;\n break;\n case 8:\n lane = 4;\n break;\n case 32:\n lane = 16;\n break;\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n lane = 128;\n break;\n case 268435456:\n lane = 134217728;\n break;\n default:\n lane = 0;\n }\n return lane;\n}\nfunction lanesToEventPriority(lanes) {\n lanes &= -lanes;\n return 2 < lanes\n ? 8 < lanes\n ? 0 !== (lanes & 134217727)\n ? 32\n : 268435456\n : 8\n : 2;\n}\nfunction resolveUpdatePriority() {\n var updatePriority = ReactDOMSharedInternals.p;\n if (0 !== updatePriority) return updatePriority;\n updatePriority = window.event;\n return void 0 === updatePriority ? 32 : getEventPriority(updatePriority.type);\n}\nfunction runWithPriority(priority, fn) {\n var previousPriority = ReactDOMSharedInternals.p;\n try {\n return (ReactDOMSharedInternals.p = priority), fn();\n } finally {\n ReactDOMSharedInternals.p = previousPriority;\n }\n}\nvar randomKey = Math.random().toString(36).slice(2),\n internalInstanceKey = \"__reactFiber$\" + randomKey,\n internalPropsKey = \"__reactProps$\" + randomKey,\n internalContainerInstanceKey = \"__reactContainer$\" + randomKey,\n internalEventHandlersKey = \"__reactEvents$\" + randomKey,\n internalEventHandlerListenersKey = \"__reactListeners$\" + randomKey,\n internalEventHandlesSetKey = \"__reactHandles$\" + randomKey,\n internalRootNodeResourcesKey = \"__reactResources$\" + randomKey,\n internalHoistableMarker = \"__reactMarker$\" + randomKey;\nfunction detachDeletedInstance(node) {\n delete node[internalInstanceKey];\n delete node[internalPropsKey];\n delete node[internalEventHandlersKey];\n delete node[internalEventHandlerListenersKey];\n delete node[internalEventHandlesSetKey];\n}\nfunction getClosestInstanceFromNode(targetNode) {\n var targetInst = targetNode[internalInstanceKey];\n if (targetInst) return targetInst;\n for (var parentNode = targetNode.parentNode; parentNode; ) {\n if (\n (targetInst =\n parentNode[internalContainerInstanceKey] ||\n parentNode[internalInstanceKey])\n ) {\n parentNode = targetInst.alternate;\n if (\n null !== targetInst.child ||\n (null !== parentNode && null !== parentNode.child)\n )\n for (\n targetNode = getParentHydrationBoundary(targetNode);\n null !== targetNode;\n\n ) {\n if ((parentNode = targetNode[internalInstanceKey])) return parentNode;\n targetNode = getParentHydrationBoundary(targetNode);\n }\n return targetInst;\n }\n targetNode = parentNode;\n parentNode = targetNode.parentNode;\n }\n return null;\n}\nfunction getInstanceFromNode(node) {\n if (\n (node = node[internalInstanceKey] || node[internalContainerInstanceKey])\n ) {\n var tag = node.tag;\n if (\n 5 === tag ||\n 6 === tag ||\n 13 === tag ||\n 31 === tag ||\n 26 === tag ||\n 27 === tag ||\n 3 === tag\n )\n return node;\n }\n return null;\n}\nfunction getNodeFromInstance(inst) {\n var tag = inst.tag;\n if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return inst.stateNode;\n throw Error(formatProdErrorMessage(33));\n}\nfunction getResourcesFromRoot(root) {\n var resources = root[internalRootNodeResourcesKey];\n resources ||\n (resources = root[internalRootNodeResourcesKey] =\n { hoistableStyles: new Map(), hoistableScripts: new Map() });\n return resources;\n}\nfunction markNodeAsHoistable(node) {\n node[internalHoistableMarker] = !0;\n}\nvar allNativeEvents = new Set(),\n registrationNameDependencies = {};\nfunction registerTwoPhaseEvent(registrationName, dependencies) {\n registerDirectEvent(registrationName, dependencies);\n registerDirectEvent(registrationName + \"Capture\", dependencies);\n}\nfunction registerDirectEvent(registrationName, dependencies) {\n registrationNameDependencies[registrationName] = dependencies;\n for (\n registrationName = 0;\n registrationName < dependencies.length;\n registrationName++\n )\n allNativeEvents.add(dependencies[registrationName]);\n}\nvar VALID_ATTRIBUTE_NAME_REGEX = RegExp(\n \"^[: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]*$\"\n ),\n illegalAttributeNameCache = {},\n validatedAttributeNameCache = {};\nfunction isAttributeNameSafe(attributeName) {\n if (hasOwnProperty.call(validatedAttributeNameCache, attributeName))\n return !0;\n if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) return !1;\n if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName))\n return (validatedAttributeNameCache[attributeName] = !0);\n illegalAttributeNameCache[attributeName] = !0;\n return !1;\n}\nfunction setValueForAttribute(node, name, value) {\n if (isAttributeNameSafe(name))\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n node.removeAttribute(name);\n return;\n case \"boolean\":\n var prefix$10 = name.toLowerCase().slice(0, 5);\n if (\"data-\" !== prefix$10 && \"aria-\" !== prefix$10) {\n node.removeAttribute(name);\n return;\n }\n }\n node.setAttribute(name, \"\" + value);\n }\n}\nfunction setValueForKnownAttribute(node, name, value) {\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"boolean\":\n node.removeAttribute(name);\n return;\n }\n node.setAttribute(name, \"\" + value);\n }\n}\nfunction setValueForNamespacedAttribute(node, namespace, name, value) {\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"boolean\":\n node.removeAttribute(name);\n return;\n }\n node.setAttributeNS(namespace, name, \"\" + value);\n }\n}\nfunction getToStringValue(value) {\n switch (typeof value) {\n case \"bigint\":\n case \"boolean\":\n case \"number\":\n case \"string\":\n case \"undefined\":\n return value;\n case \"object\":\n return value;\n default:\n return \"\";\n }\n}\nfunction isCheckable(elem) {\n var type = elem.type;\n return (\n (elem = elem.nodeName) &&\n \"input\" === elem.toLowerCase() &&\n (\"checkbox\" === type || \"radio\" === type)\n );\n}\nfunction trackValueOnNode(node, valueField, currentValue) {\n var descriptor = Object.getOwnPropertyDescriptor(\n node.constructor.prototype,\n valueField\n );\n if (\n !node.hasOwnProperty(valueField) &&\n \"undefined\" !== typeof descriptor &&\n \"function\" === typeof descriptor.get &&\n \"function\" === typeof descriptor.set\n ) {\n var get = descriptor.get,\n set = descriptor.set;\n Object.defineProperty(node, valueField, {\n configurable: !0,\n get: function () {\n return get.call(this);\n },\n set: function (value) {\n currentValue = \"\" + value;\n set.call(this, value);\n }\n });\n Object.defineProperty(node, valueField, {\n enumerable: descriptor.enumerable\n });\n return {\n getValue: function () {\n return currentValue;\n },\n setValue: function (value) {\n currentValue = \"\" + value;\n },\n stopTracking: function () {\n node._valueTracker = null;\n delete node[valueField];\n }\n };\n }\n}\nfunction track(node) {\n if (!node._valueTracker) {\n var valueField = isCheckable(node) ? \"checked\" : \"value\";\n node._valueTracker = trackValueOnNode(\n node,\n valueField,\n \"\" + node[valueField]\n );\n }\n}\nfunction updateValueIfChanged(node) {\n if (!node) return !1;\n var tracker = node._valueTracker;\n if (!tracker) return !0;\n var lastValue = tracker.getValue();\n var value = \"\";\n node &&\n (value = isCheckable(node)\n ? node.checked\n ? \"true\"\n : \"false\"\n : node.value);\n node = value;\n return node !== lastValue ? (tracker.setValue(node), !0) : !1;\n}\nfunction getActiveElement(doc) {\n doc = doc || (\"undefined\" !== typeof document ? document : void 0);\n if (\"undefined\" === typeof doc) return null;\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\nvar escapeSelectorAttributeValueInsideDoubleQuotesRegex = /[\\n\"\\\\]/g;\nfunction escapeSelectorAttributeValueInsideDoubleQuotes(value) {\n return value.replace(\n escapeSelectorAttributeValueInsideDoubleQuotesRegex,\n function (ch) {\n return \"\\\\\" + ch.charCodeAt(0).toString(16) + \" \";\n }\n );\n}\nfunction updateInput(\n element,\n value,\n defaultValue,\n lastDefaultValue,\n checked,\n defaultChecked,\n type,\n name\n) {\n element.name = \"\";\n null != type &&\n \"function\" !== typeof type &&\n \"symbol\" !== typeof type &&\n \"boolean\" !== typeof type\n ? (element.type = type)\n : element.removeAttribute(\"type\");\n if (null != value)\n if (\"number\" === type) {\n if ((0 === value && \"\" === element.value) || element.value != value)\n element.value = \"\" + getToStringValue(value);\n } else\n element.value !== \"\" + getToStringValue(value) &&\n (element.value = \"\" + getToStringValue(value));\n else\n (\"submit\" !== type && \"reset\" !== type) || element.removeAttribute(\"value\");\n null != value\n ? setDefaultValue(element, type, getToStringValue(value))\n : null != defaultValue\n ? setDefaultValue(element, type, getToStringValue(defaultValue))\n : null != lastDefaultValue && element.removeAttribute(\"value\");\n null == checked &&\n null != defaultChecked &&\n (element.defaultChecked = !!defaultChecked);\n null != checked &&\n (element.checked =\n checked && \"function\" !== typeof checked && \"symbol\" !== typeof checked);\n null != name &&\n \"function\" !== typeof name &&\n \"symbol\" !== typeof name &&\n \"boolean\" !== typeof name\n ? (element.name = \"\" + getToStringValue(name))\n : element.removeAttribute(\"name\");\n}\nfunction initInput(\n element,\n value,\n defaultValue,\n checked,\n defaultChecked,\n type,\n name,\n isHydrating\n) {\n null != type &&\n \"function\" !== typeof type &&\n \"symbol\" !== typeof type &&\n \"boolean\" !== typeof type &&\n (element.type = type);\n if (null != value || null != defaultValue) {\n if (\n !(\n (\"submit\" !== type && \"reset\" !== type) ||\n (void 0 !== value && null !== value)\n )\n ) {\n track(element);\n return;\n }\n defaultValue =\n null != defaultValue ? \"\" + getToStringValue(defaultValue) : \"\";\n value = null != value ? \"\" + getToStringValue(value) : defaultValue;\n isHydrating || value === element.value || (element.value = value);\n element.defaultValue = value;\n }\n checked = null != checked ? checked : defaultChecked;\n checked =\n \"function\" !== typeof checked && \"symbol\" !== typeof checked && !!checked;\n element.checked = isHydrating ? element.checked : !!checked;\n element.defaultChecked = !!checked;\n null != name &&\n \"function\" !== typeof name &&\n \"symbol\" !== typeof name &&\n \"boolean\" !== typeof name &&\n (element.name = name);\n track(element);\n}\nfunction setDefaultValue(node, type, value) {\n (\"number\" === type && getActiveElement(node.ownerDocument) === node) ||\n node.defaultValue === \"\" + value ||\n (node.defaultValue = \"\" + value);\n}\nfunction updateOptions(node, multiple, propValue, setDefaultSelected) {\n node = node.options;\n if (multiple) {\n multiple = {};\n for (var i = 0; i < propValue.length; i++)\n multiple[\"$\" + propValue[i]] = !0;\n for (propValue = 0; propValue < node.length; propValue++)\n (i = multiple.hasOwnProperty(\"$\" + node[propValue].value)),\n node[propValue].selected !== i && (node[propValue].selected = i),\n i && setDefaultSelected && (node[propValue].defaultSelected = !0);\n } else {\n propValue = \"\" + getToStringValue(propValue);\n multiple = null;\n for (i = 0; i < node.length; i++) {\n if (node[i].value === propValue) {\n node[i].selected = !0;\n setDefaultSelected && (node[i].defaultSelected = !0);\n return;\n }\n null !== multiple || node[i].disabled || (multiple = node[i]);\n }\n null !== multiple && (multiple.selected = !0);\n }\n}\nfunction updateTextarea(element, value, defaultValue) {\n if (\n null != value &&\n ((value = \"\" + getToStringValue(value)),\n value !== element.value && (element.value = value),\n null == defaultValue)\n ) {\n element.defaultValue !== value && (element.defaultValue = value);\n return;\n }\n element.defaultValue =\n null != defaultValue ? \"\" + getToStringValue(defaultValue) : \"\";\n}\nfunction initTextarea(element, value, defaultValue, children) {\n if (null == value) {\n if (null != children) {\n if (null != defaultValue) throw Error(formatProdErrorMessage(92));\n if (isArrayImpl(children)) {\n if (1 < children.length) throw Error(formatProdErrorMessage(93));\n children = children[0];\n }\n defaultValue = children;\n }\n null == defaultValue && (defaultValue = \"\");\n value = defaultValue;\n }\n defaultValue = getToStringValue(value);\n element.defaultValue = defaultValue;\n children = element.textContent;\n children === defaultValue &&\n \"\" !== children &&\n null !== children &&\n (element.value = children);\n track(element);\n}\nfunction setTextContent(node, text) {\n if (text) {\n var firstChild = node.firstChild;\n if (\n firstChild &&\n firstChild === node.lastChild &&\n 3 === firstChild.nodeType\n ) {\n firstChild.nodeValue = text;\n return;\n }\n }\n node.textContent = text;\n}\nvar unitlessNumbers = new Set(\n \"animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp\".split(\n \" \"\n )\n);\nfunction setValueForStyle(style, styleName, value) {\n var isCustomProperty = 0 === styleName.indexOf(\"--\");\n null == value || \"boolean\" === typeof value || \"\" === value\n ? isCustomProperty\n ? style.setProperty(styleName, \"\")\n : \"float\" === styleName\n ? (style.cssFloat = \"\")\n : (style[styleName] = \"\")\n : isCustomProperty\n ? style.setProperty(styleName, value)\n : \"number\" !== typeof value ||\n 0 === value ||\n unitlessNumbers.has(styleName)\n ? \"float\" === styleName\n ? (style.cssFloat = value)\n : (style[styleName] = (\"\" + value).trim())\n : (style[styleName] = value + \"px\");\n}\nfunction setValueForStyles(node, styles, prevStyles) {\n if (null != styles && \"object\" !== typeof styles)\n throw Error(formatProdErrorMessage(62));\n node = node.style;\n if (null != prevStyles) {\n for (var styleName in prevStyles)\n !prevStyles.hasOwnProperty(styleName) ||\n (null != styles && styles.hasOwnProperty(styleName)) ||\n (0 === styleName.indexOf(\"--\")\n ? node.setProperty(styleName, \"\")\n : \"float\" === styleName\n ? (node.cssFloat = \"\")\n : (node[styleName] = \"\"));\n for (var styleName$16 in styles)\n (styleName = styles[styleName$16]),\n styles.hasOwnProperty(styleName$16) &&\n prevStyles[styleName$16] !== styleName &&\n setValueForStyle(node, styleName$16, styleName);\n } else\n for (var styleName$17 in styles)\n styles.hasOwnProperty(styleName$17) &&\n setValueForStyle(node, styleName$17, styles[styleName$17]);\n}\nfunction isCustomElement(tagName) {\n if (-1 === tagName.indexOf(\"-\")) return !1;\n switch (tagName) {\n case \"annotation-xml\":\n case \"color-profile\":\n case \"font-face\":\n case \"font-face-src\":\n case \"font-face-uri\":\n case \"font-face-format\":\n case \"font-face-name\":\n case \"missing-glyph\":\n return !1;\n default:\n return !0;\n }\n}\nvar aliases = new Map([\n [\"acceptCharset\", \"accept-charset\"],\n [\"htmlFor\", \"for\"],\n [\"httpEquiv\", \"http-equiv\"],\n [\"crossOrigin\", \"crossorigin\"],\n [\"accentHeight\", \"accent-height\"],\n [\"alignmentBaseline\", \"alignment-baseline\"],\n [\"arabicForm\", \"arabic-form\"],\n [\"baselineShift\", \"baseline-shift\"],\n [\"capHeight\", \"cap-height\"],\n [\"clipPath\", \"clip-path\"],\n [\"clipRule\", \"clip-rule\"],\n [\"colorInterpolation\", \"color-interpolation\"],\n [\"colorInterpolationFilters\", \"color-interpolation-filters\"],\n [\"colorProfile\", \"color-profile\"],\n [\"colorRendering\", \"color-rendering\"],\n [\"dominantBaseline\", \"dominant-baseline\"],\n [\"enableBackground\", \"enable-background\"],\n [\"fillOpacity\", \"fill-opacity\"],\n [\"fillRule\", \"fill-rule\"],\n [\"floodColor\", \"flood-color\"],\n [\"floodOpacity\", \"flood-opacity\"],\n [\"fontFamily\", \"font-family\"],\n [\"fontSize\", \"font-size\"],\n [\"fontSizeAdjust\", \"font-size-adjust\"],\n [\"fontStretch\", \"font-stretch\"],\n [\"fontStyle\", \"font-style\"],\n [\"fontVariant\", \"font-variant\"],\n [\"fontWeight\", \"font-weight\"],\n [\"glyphName\", \"glyph-name\"],\n [\"glyphOrientationHorizontal\", \"glyph-orientation-horizontal\"],\n [\"glyphOrientationVertical\", \"glyph-orientation-vertical\"],\n [\"horizAdvX\", \"horiz-adv-x\"],\n [\"horizOriginX\", \"horiz-origin-x\"],\n [\"imageRendering\", \"image-rendering\"],\n [\"letterSpacing\", \"letter-spacing\"],\n [\"lightingColor\", \"lighting-color\"],\n [\"markerEnd\", \"marker-end\"],\n [\"markerMid\", \"marker-mid\"],\n [\"markerStart\", \"marker-start\"],\n [\"overlinePosition\", \"overline-position\"],\n [\"overlineThickness\", \"overline-thickness\"],\n [\"paintOrder\", \"paint-order\"],\n [\"panose-1\", \"panose-1\"],\n [\"pointerEvents\", \"pointer-events\"],\n [\"renderingIntent\", \"rendering-intent\"],\n [\"shapeRendering\", \"shape-rendering\"],\n [\"stopColor\", \"stop-color\"],\n [\"stopOpacity\", \"stop-opacity\"],\n [\"strikethroughPosition\", \"strikethrough-position\"],\n [\"strikethroughThickness\", \"strikethrough-thickness\"],\n [\"strokeDasharray\", \"stroke-dasharray\"],\n [\"strokeDashoffset\", \"stroke-dashoffset\"],\n [\"strokeLinecap\", \"stroke-linecap\"],\n [\"strokeLinejoin\", \"stroke-linejoin\"],\n [\"strokeMiterlimit\", \"stroke-miterlimit\"],\n [\"strokeOpacity\", \"stroke-opacity\"],\n [\"strokeWidth\", \"stroke-width\"],\n [\"textAnchor\", \"text-anchor\"],\n [\"textDecoration\", \"text-decoration\"],\n [\"textRendering\", \"text-rendering\"],\n [\"transformOrigin\", \"transform-origin\"],\n [\"underlinePosition\", \"underline-position\"],\n [\"underlineThickness\", \"underline-thickness\"],\n [\"unicodeBidi\", \"unicode-bidi\"],\n [\"unicodeRange\", \"unicode-range\"],\n [\"unitsPerEm\", \"units-per-em\"],\n [\"vAlphabetic\", \"v-alphabetic\"],\n [\"vHanging\", \"v-hanging\"],\n [\"vIdeographic\", \"v-ideographic\"],\n [\"vMathematical\", \"v-mathematical\"],\n [\"vectorEffect\", \"vector-effect\"],\n [\"vertAdvY\", \"vert-adv-y\"],\n [\"vertOriginX\", \"vert-origin-x\"],\n [\"vertOriginY\", \"vert-origin-y\"],\n [\"wordSpacing\", \"word-spacing\"],\n [\"writingMode\", \"writing-mode\"],\n [\"xmlnsXlink\", \"xmlns:xlink\"],\n [\"xHeight\", \"x-height\"]\n ]),\n isJavaScriptProtocol =\n /^[\\u0000-\\u001F ]*j[\\r\\n\\t]*a[\\r\\n\\t]*v[\\r\\n\\t]*a[\\r\\n\\t]*s[\\r\\n\\t]*c[\\r\\n\\t]*r[\\r\\n\\t]*i[\\r\\n\\t]*p[\\r\\n\\t]*t[\\r\\n\\t]*:/i;\nfunction sanitizeURL(url) {\n return isJavaScriptProtocol.test(\"\" + url)\n ? \"javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')\"\n : url;\n}\nfunction noop$1() {}\nvar currentReplayingEvent = null;\nfunction getEventTarget(nativeEvent) {\n nativeEvent = nativeEvent.target || nativeEvent.srcElement || window;\n nativeEvent.correspondingUseElement &&\n (nativeEvent = nativeEvent.correspondingUseElement);\n return 3 === nativeEvent.nodeType ? nativeEvent.parentNode : nativeEvent;\n}\nvar restoreTarget = null,\n restoreQueue = null;\nfunction restoreStateOfTarget(target) {\n var internalInstance = getInstanceFromNode(target);\n if (internalInstance && (target = internalInstance.stateNode)) {\n var props = target[internalPropsKey] || null;\n a: switch (((target = internalInstance.stateNode), internalInstance.type)) {\n case \"input\":\n updateInput(\n target,\n props.value,\n props.defaultValue,\n props.defaultValue,\n props.checked,\n props.defaultChecked,\n props.type,\n props.name\n );\n internalInstance = props.name;\n if (\"radio\" === props.type && null != internalInstance) {\n for (props = target; props.parentNode; ) props = props.parentNode;\n props = props.querySelectorAll(\n 'input[name=\"' +\n escapeSelectorAttributeValueInsideDoubleQuotes(\n \"\" + internalInstance\n ) +\n '\"][type=\"radio\"]'\n );\n for (\n internalInstance = 0;\n internalInstance < props.length;\n internalInstance++\n ) {\n var otherNode = props[internalInstance];\n if (otherNode !== target && otherNode.form === target.form) {\n var otherProps = otherNode[internalPropsKey] || null;\n if (!otherProps) throw Error(formatProdErrorMessage(90));\n updateInput(\n otherNode,\n otherProps.value,\n otherProps.defaultValue,\n otherProps.defaultValue,\n otherProps.checked,\n otherProps.defaultChecked,\n otherProps.type,\n otherProps.name\n );\n }\n }\n for (\n internalInstance = 0;\n internalInstance < props.length;\n internalInstance++\n )\n (otherNode = props[internalInstance]),\n otherNode.form === target.form && updateValueIfChanged(otherNode);\n }\n break a;\n case \"textarea\":\n updateTextarea(target, props.value, props.defaultValue);\n break a;\n case \"select\":\n (internalInstance = props.value),\n null != internalInstance &&\n updateOptions(target, !!props.multiple, internalInstance, !1);\n }\n }\n}\nvar isInsideEventHandler = !1;\nfunction batchedUpdates$1(fn, a, b) {\n if (isInsideEventHandler) return fn(a, b);\n isInsideEventHandler = !0;\n try {\n var JSCompiler_inline_result = fn(a);\n return JSCompiler_inline_result;\n } finally {\n if (\n ((isInsideEventHandler = !1),\n null !== restoreTarget || null !== restoreQueue)\n )\n if (\n (flushSyncWork$1(),\n restoreTarget &&\n ((a = restoreTarget),\n (fn = restoreQueue),\n (restoreQueue = restoreTarget = null),\n restoreStateOfTarget(a),\n fn))\n )\n for (a = 0; a < fn.length; a++) restoreStateOfTarget(fn[a]);\n }\n}\nfunction getListener(inst, registrationName) {\n var stateNode = inst.stateNode;\n if (null === stateNode) return null;\n var props = stateNode[internalPropsKey] || null;\n if (null === props) return null;\n stateNode = props[registrationName];\n a: switch (registrationName) {\n case \"onClick\":\n case \"onClickCapture\":\n case \"onDoubleClick\":\n case \"onDoubleClickCapture\":\n case \"onMouseDown\":\n case \"onMouseDownCapture\":\n case \"onMouseMove\":\n case \"onMouseMoveCapture\":\n case \"onMouseUp\":\n case \"onMouseUpCapture\":\n case \"onMouseEnter\":\n (props = !props.disabled) ||\n ((inst = inst.type),\n (props = !(\n \"button\" === inst ||\n \"input\" === inst ||\n \"select\" === inst ||\n \"textarea\" === inst\n )));\n inst = !props;\n break a;\n default:\n inst = !1;\n }\n if (inst) return null;\n if (stateNode && \"function\" !== typeof stateNode)\n throw Error(\n formatProdErrorMessage(231, registrationName, typeof stateNode)\n );\n return stateNode;\n}\nvar canUseDOM = !(\n \"undefined\" === typeof window ||\n \"undefined\" === typeof window.document ||\n \"undefined\" === typeof window.document.createElement\n ),\n passiveBrowserEventsSupported = !1;\nif (canUseDOM)\n try {\n var options = {};\n Object.defineProperty(options, \"passive\", {\n get: function () {\n passiveBrowserEventsSupported = !0;\n }\n });\n window.addEventListener(\"test\", options, options);\n window.removeEventListener(\"test\", options, options);\n } catch (e) {\n passiveBrowserEventsSupported = !1;\n }\nvar root = null,\n startText = null,\n fallbackText = null;\nfunction getData() {\n if (fallbackText) return fallbackText;\n var start,\n startValue = startText,\n startLength = startValue.length,\n end,\n endValue = \"value\" in root ? root.value : root.textContent,\n endLength = endValue.length;\n for (\n start = 0;\n start < startLength && startValue[start] === endValue[start];\n start++\n );\n var minEnd = startLength - start;\n for (\n end = 1;\n end <= minEnd &&\n startValue[startLength - end] === endValue[endLength - end];\n end++\n );\n return (fallbackText = endValue.slice(start, 1 < end ? 1 - end : void 0));\n}\nfunction getEventCharCode(nativeEvent) {\n var keyCode = nativeEvent.keyCode;\n \"charCode\" in nativeEvent\n ? ((nativeEvent = nativeEvent.charCode),\n 0 === nativeEvent && 13 === keyCode && (nativeEvent = 13))\n : (nativeEvent = keyCode);\n 10 === nativeEvent && (nativeEvent = 13);\n return 32 <= nativeEvent || 13 === nativeEvent ? nativeEvent : 0;\n}\nfunction functionThatReturnsTrue() {\n return !0;\n}\nfunction functionThatReturnsFalse() {\n return !1;\n}\nfunction createSyntheticEvent(Interface) {\n function SyntheticBaseEvent(\n reactName,\n reactEventType,\n targetInst,\n nativeEvent,\n nativeEventTarget\n ) {\n this._reactName = reactName;\n this._targetInst = targetInst;\n this.type = reactEventType;\n this.nativeEvent = nativeEvent;\n this.target = nativeEventTarget;\n this.currentTarget = null;\n for (var propName in Interface)\n Interface.hasOwnProperty(propName) &&\n ((reactName = Interface[propName]),\n (this[propName] = reactName\n ? reactName(nativeEvent)\n : nativeEvent[propName]));\n this.isDefaultPrevented = (\n null != nativeEvent.defaultPrevented\n ? nativeEvent.defaultPrevented\n : !1 === nativeEvent.returnValue\n )\n ? functionThatReturnsTrue\n : functionThatReturnsFalse;\n this.isPropagationStopped = functionThatReturnsFalse;\n return this;\n }\n assign(SyntheticBaseEvent.prototype, {\n preventDefault: function () {\n this.defaultPrevented = !0;\n var event = this.nativeEvent;\n event &&\n (event.preventDefault\n ? event.preventDefault()\n : \"unknown\" !== typeof event.returnValue && (event.returnValue = !1),\n (this.isDefaultPrevented = functionThatReturnsTrue));\n },\n stopPropagation: function () {\n var event = this.nativeEvent;\n event &&\n (event.stopPropagation\n ? event.stopPropagation()\n : \"unknown\" !== typeof event.cancelBubble &&\n (event.cancelBubble = !0),\n (this.isPropagationStopped = functionThatReturnsTrue));\n },\n persist: function () {},\n isPersistent: functionThatReturnsTrue\n });\n return SyntheticBaseEvent;\n}\nvar EventInterface = {\n eventPhase: 0,\n bubbles: 0,\n cancelable: 0,\n timeStamp: function (event) {\n return event.timeStamp || Date.now();\n },\n defaultPrevented: 0,\n isTrusted: 0\n },\n SyntheticEvent = createSyntheticEvent(EventInterface),\n UIEventInterface = assign({}, EventInterface, { view: 0, detail: 0 }),\n SyntheticUIEvent = createSyntheticEvent(UIEventInterface),\n lastMovementX,\n lastMovementY,\n lastMouseEvent,\n MouseEventInterface = assign({}, UIEventInterface, {\n screenX: 0,\n screenY: 0,\n clientX: 0,\n clientY: 0,\n pageX: 0,\n pageY: 0,\n ctrlKey: 0,\n shiftKey: 0,\n altKey: 0,\n metaKey: 0,\n getModifierState: getEventModifierState,\n button: 0,\n buttons: 0,\n relatedTarget: function (event) {\n return void 0 === event.relatedTarget\n ? event.fromElement === event.srcElement\n ? event.toElement\n : event.fromElement\n : event.relatedTarget;\n },\n movementX: function (event) {\n if (\"movementX\" in event) return event.movementX;\n event !== lastMouseEvent &&\n (lastMouseEvent && \"mousemove\" === event.type\n ? ((lastMovementX = event.screenX - lastMouseEvent.screenX),\n (lastMovementY = event.screenY - lastMouseEvent.screenY))\n : (lastMovementY = lastMovementX = 0),\n (lastMouseEvent = event));\n return lastMovementX;\n },\n movementY: function (event) {\n return \"movementY\" in event ? event.movementY : lastMovementY;\n }\n }),\n SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface),\n DragEventInterface = assign({}, MouseEventInterface, { dataTransfer: 0 }),\n SyntheticDragEvent = createSyntheticEvent(DragEventInterface),\n FocusEventInterface = assign({}, UIEventInterface, { relatedTarget: 0 }),\n SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface),\n AnimationEventInterface = assign({}, EventInterface, {\n animationName: 0,\n elapsedTime: 0,\n pseudoElement: 0\n }),\n SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface),\n ClipboardEventInterface = assign({}, EventInterface, {\n clipboardData: function (event) {\n return \"clipboardData\" in event\n ? event.clipboardData\n : window.clipboardData;\n }\n }),\n SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface),\n CompositionEventInterface = assign({}, EventInterface, { data: 0 }),\n SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface),\n normalizeKey = {\n Esc: \"Escape\",\n Spacebar: \" \",\n Left: \"ArrowLeft\",\n Up: \"ArrowUp\",\n Right: \"ArrowRight\",\n Down: \"ArrowDown\",\n Del: \"Delete\",\n Win: \"OS\",\n Menu: \"ContextMenu\",\n Apps: \"ContextMenu\",\n Scroll: \"ScrollLock\",\n MozPrintableKey: \"Unidentified\"\n },\n translateToKey = {\n 8: \"Backspace\",\n 9: \"Tab\",\n 12: \"Clear\",\n 13: \"Enter\",\n 16: \"Shift\",\n 17: \"Control\",\n 18: \"Alt\",\n 19: \"Pause\",\n 20: \"CapsLock\",\n 27: \"Escape\",\n 32: \" \",\n 33: \"PageUp\",\n 34: \"PageDown\",\n 35: \"End\",\n 36: \"Home\",\n 37: \"ArrowLeft\",\n 38: \"ArrowUp\",\n 39: \"ArrowRight\",\n 40: \"ArrowDown\",\n 45: \"Insert\",\n 46: \"Delete\",\n 112: \"F1\",\n 113: \"F2\",\n 114: \"F3\",\n 115: \"F4\",\n 116: \"F5\",\n 117: \"F6\",\n 118: \"F7\",\n 119: \"F8\",\n 120: \"F9\",\n 121: \"F10\",\n 122: \"F11\",\n 123: \"F12\",\n 144: \"NumLock\",\n 145: \"ScrollLock\",\n 224: \"Meta\"\n },\n modifierKeyToProp = {\n Alt: \"altKey\",\n Control: \"ctrlKey\",\n Meta: \"metaKey\",\n Shift: \"shiftKey\"\n };\nfunction modifierStateGetter(keyArg) {\n var nativeEvent = this.nativeEvent;\n return nativeEvent.getModifierState\n ? nativeEvent.getModifierState(keyArg)\n : (keyArg = modifierKeyToProp[keyArg])\n ? !!nativeEvent[keyArg]\n : !1;\n}\nfunction getEventModifierState() {\n return modifierStateGetter;\n}\nvar KeyboardEventInterface = assign({}, UIEventInterface, {\n key: function (nativeEvent) {\n if (nativeEvent.key) {\n var key = normalizeKey[nativeEvent.key] || nativeEvent.key;\n if (\"Unidentified\" !== key) return key;\n }\n return \"keypress\" === nativeEvent.type\n ? ((nativeEvent = getEventCharCode(nativeEvent)),\n 13 === nativeEvent ? \"Enter\" : String.fromCharCode(nativeEvent))\n : \"keydown\" === nativeEvent.type || \"keyup\" === nativeEvent.type\n ? translateToKey[nativeEvent.keyCode] || \"Unidentified\"\n : \"\";\n },\n code: 0,\n location: 0,\n ctrlKey: 0,\n shiftKey: 0,\n altKey: 0,\n metaKey: 0,\n repeat: 0,\n locale: 0,\n getModifierState: getEventModifierState,\n charCode: function (event) {\n return \"keypress\" === event.type ? getEventCharCode(event) : 0;\n },\n keyCode: function (event) {\n return \"keydown\" === event.type || \"keyup\" === event.type\n ? event.keyCode\n : 0;\n },\n which: function (event) {\n return \"keypress\" === event.type\n ? getEventCharCode(event)\n : \"keydown\" === event.type || \"keyup\" === event.type\n ? event.keyCode\n : 0;\n }\n }),\n SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface),\n PointerEventInterface = assign({}, MouseEventInterface, {\n pointerId: 0,\n width: 0,\n height: 0,\n pressure: 0,\n tangentialPressure: 0,\n tiltX: 0,\n tiltY: 0,\n twist: 0,\n pointerType: 0,\n isPrimary: 0\n }),\n SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface),\n TouchEventInterface = assign({}, UIEventInterface, {\n touches: 0,\n targetTouches: 0,\n changedTouches: 0,\n altKey: 0,\n metaKey: 0,\n ctrlKey: 0,\n shiftKey: 0,\n getModifierState: getEventModifierState\n }),\n SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface),\n TransitionEventInterface = assign({}, EventInterface, {\n propertyName: 0,\n elapsedTime: 0,\n pseudoElement: 0\n }),\n SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface),\n WheelEventInterface = assign({}, MouseEventInterface, {\n deltaX: function (event) {\n return \"deltaX\" in event\n ? event.deltaX\n : \"wheelDeltaX\" in event\n ? -event.wheelDeltaX\n : 0;\n },\n deltaY: function (event) {\n return \"deltaY\" in event\n ? event.deltaY\n : \"wheelDeltaY\" in event\n ? -event.wheelDeltaY\n : \"wheelDelta\" in event\n ? -event.wheelDelta\n : 0;\n },\n deltaZ: 0,\n deltaMode: 0\n }),\n SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface),\n ToggleEventInterface = assign({}, EventInterface, {\n newState: 0,\n oldState: 0\n }),\n SyntheticToggleEvent = createSyntheticEvent(ToggleEventInterface),\n END_KEYCODES = [9, 13, 27, 32],\n canUseCompositionEvent = canUseDOM && \"CompositionEvent\" in window,\n documentMode = null;\ncanUseDOM &&\n \"documentMode\" in document &&\n (documentMode = document.documentMode);\nvar canUseTextInputEvent = canUseDOM && \"TextEvent\" in window && !documentMode,\n useFallbackCompositionData =\n canUseDOM &&\n (!canUseCompositionEvent ||\n (documentMode && 8 < documentMode && 11 >= documentMode)),\n SPACEBAR_CHAR = String.fromCharCode(32),\n hasSpaceKeypress = !1;\nfunction isFallbackCompositionEnd(domEventName, nativeEvent) {\n switch (domEventName) {\n case \"keyup\":\n return -1 !== END_KEYCODES.indexOf(nativeEvent.keyCode);\n case \"keydown\":\n return 229 !== nativeEvent.keyCode;\n case \"keypress\":\n case \"mousedown\":\n case \"focusout\":\n return !0;\n default:\n return !1;\n }\n}\nfunction getDataFromCustomEvent(nativeEvent) {\n nativeEvent = nativeEvent.detail;\n return \"object\" === typeof nativeEvent && \"data\" in nativeEvent\n ? nativeEvent.data\n : null;\n}\nvar isComposing = !1;\nfunction getNativeBeforeInputChars(domEventName, nativeEvent) {\n switch (domEventName) {\n case \"compositionend\":\n return getDataFromCustomEvent(nativeEvent);\n case \"keypress\":\n if (32 !== nativeEvent.which) return null;\n hasSpaceKeypress = !0;\n return SPACEBAR_CHAR;\n case \"textInput\":\n return (\n (domEventName = nativeEvent.data),\n domEventName === SPACEBAR_CHAR && hasSpaceKeypress ? null : domEventName\n );\n default:\n return null;\n }\n}\nfunction getFallbackBeforeInputChars(domEventName, nativeEvent) {\n if (isComposing)\n return \"compositionend\" === domEventName ||\n (!canUseCompositionEvent &&\n isFallbackCompositionEnd(domEventName, nativeEvent))\n ? ((domEventName = getData()),\n (fallbackText = startText = root = null),\n (isComposing = !1),\n domEventName)\n : null;\n switch (domEventName) {\n case \"paste\":\n return null;\n case \"keypress\":\n if (\n !(nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) ||\n (nativeEvent.ctrlKey && nativeEvent.altKey)\n ) {\n if (nativeEvent.char && 1 < nativeEvent.char.length)\n return nativeEvent.char;\n if (nativeEvent.which) return String.fromCharCode(nativeEvent.which);\n }\n return null;\n case \"compositionend\":\n return useFallbackCompositionData && \"ko\" !== nativeEvent.locale\n ? null\n : nativeEvent.data;\n default:\n return null;\n }\n}\nvar supportedInputTypes = {\n color: !0,\n date: !0,\n datetime: !0,\n \"datetime-local\": !0,\n email: !0,\n month: !0,\n number: !0,\n password: !0,\n range: !0,\n search: !0,\n tel: !0,\n text: !0,\n time: !0,\n url: !0,\n week: !0\n};\nfunction isTextInputElement(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return \"input\" === nodeName\n ? !!supportedInputTypes[elem.type]\n : \"textarea\" === nodeName\n ? !0\n : !1;\n}\nfunction createAndAccumulateChangeEvent(\n dispatchQueue,\n inst,\n nativeEvent,\n target\n) {\n restoreTarget\n ? restoreQueue\n ? restoreQueue.push(target)\n : (restoreQueue = [target])\n : (restoreTarget = target);\n inst = accumulateTwoPhaseListeners(inst, \"onChange\");\n 0 < inst.length &&\n ((nativeEvent = new SyntheticEvent(\n \"onChange\",\n \"change\",\n null,\n nativeEvent,\n target\n )),\n dispatchQueue.push({ event: nativeEvent, listeners: inst }));\n}\nvar activeElement$1 = null,\n activeElementInst$1 = null;\nfunction runEventInBatch(dispatchQueue) {\n processDispatchQueue(dispatchQueue, 0);\n}\nfunction getInstIfValueChanged(targetInst) {\n var targetNode = getNodeFromInstance(targetInst);\n if (updateValueIfChanged(targetNode)) return targetInst;\n}\nfunction getTargetInstForChangeEvent(domEventName, targetInst) {\n if (\"change\" === domEventName) return targetInst;\n}\nvar isInputEventSupported = !1;\nif (canUseDOM) {\n var JSCompiler_inline_result$jscomp$286;\n if (canUseDOM) {\n var isSupported$jscomp$inline_427 = \"oninput\" in document;\n if (!isSupported$jscomp$inline_427) {\n var element$jscomp$inline_428 = document.createElement(\"div\");\n element$jscomp$inline_428.setAttribute(\"oninput\", \"return;\");\n isSupported$jscomp$inline_427 =\n \"function\" === typeof element$jscomp$inline_428.oninput;\n }\n JSCompiler_inline_result$jscomp$286 = isSupported$jscomp$inline_427;\n } else JSCompiler_inline_result$jscomp$286 = !1;\n isInputEventSupported =\n JSCompiler_inline_result$jscomp$286 &&\n (!document.documentMode || 9 < document.documentMode);\n}\nfunction stopWatchingForValueChange() {\n activeElement$1 &&\n (activeElement$1.detachEvent(\"onpropertychange\", handlePropertyChange),\n (activeElementInst$1 = activeElement$1 = null));\n}\nfunction handlePropertyChange(nativeEvent) {\n if (\n \"value\" === nativeEvent.propertyName &&\n getInstIfValueChanged(activeElementInst$1)\n ) {\n var dispatchQueue = [];\n createAndAccumulateChangeEvent(\n dispatchQueue,\n activeElementInst$1,\n nativeEvent,\n getEventTarget(nativeEvent)\n );\n batchedUpdates$1(runEventInBatch, dispatchQueue);\n }\n}\nfunction handleEventsForInputEventPolyfill(domEventName, target, targetInst) {\n \"focusin\" === domEventName\n ? (stopWatchingForValueChange(),\n (activeElement$1 = target),\n (activeElementInst$1 = targetInst),\n activeElement$1.attachEvent(\"onpropertychange\", handlePropertyChange))\n : \"focusout\" === domEventName && stopWatchingForValueChange();\n}\nfunction getTargetInstForInputEventPolyfill(domEventName) {\n if (\n \"selectionchange\" === domEventName ||\n \"keyup\" === domEventName ||\n \"keydown\" === domEventName\n )\n return getInstIfValueChanged(activeElementInst$1);\n}\nfunction getTargetInstForClickEvent(domEventName, targetInst) {\n if (\"click\" === domEventName) return getInstIfValueChanged(targetInst);\n}\nfunction getTargetInstForInputOrChangeEvent(domEventName, targetInst) {\n if (\"input\" === domEventName || \"change\" === domEventName)\n return getInstIfValueChanged(targetInst);\n}\nfunction is(x, y) {\n return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);\n}\nvar objectIs = \"function\" === typeof Object.is ? Object.is : is;\nfunction shallowEqual(objA, objB) {\n if (objectIs(objA, objB)) return !0;\n if (\n \"object\" !== typeof objA ||\n null === objA ||\n \"object\" !== typeof objB ||\n null === objB\n )\n return !1;\n var keysA = Object.keys(objA),\n keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return !1;\n for (keysB = 0; keysB < keysA.length; keysB++) {\n var currentKey = keysA[keysB];\n if (\n !hasOwnProperty.call(objB, currentKey) ||\n !objectIs(objA[currentKey], objB[currentKey])\n )\n return !1;\n }\n return !0;\n}\nfunction getLeafNode(node) {\n for (; node && node.firstChild; ) node = node.firstChild;\n return node;\n}\nfunction getNodeForCharacterOffset(root, offset) {\n var node = getLeafNode(root);\n root = 0;\n for (var nodeEnd; node; ) {\n if (3 === node.nodeType) {\n nodeEnd = root + node.textContent.length;\n if (root <= offset && nodeEnd >= offset)\n return { node: node, offset: offset - root };\n root = nodeEnd;\n }\n a: {\n for (; node; ) {\n if (node.nextSibling) {\n node = node.nextSibling;\n break a;\n }\n node = node.parentNode;\n }\n node = void 0;\n }\n node = getLeafNode(node);\n }\n}\nfunction containsNode(outerNode, innerNode) {\n return outerNode && innerNode\n ? outerNode === innerNode\n ? !0\n : outerNode && 3 === outerNode.nodeType\n ? !1\n : innerNode && 3 === innerNode.nodeType\n ? containsNode(outerNode, innerNode.parentNode)\n : \"contains\" in outerNode\n ? outerNode.contains(innerNode)\n : outerNode.compareDocumentPosition\n ? !!(outerNode.compareDocumentPosition(innerNode) & 16)\n : !1\n : !1;\n}\nfunction getActiveElementDeep(containerInfo) {\n containerInfo =\n null != containerInfo &&\n null != containerInfo.ownerDocument &&\n null != containerInfo.ownerDocument.defaultView\n ? containerInfo.ownerDocument.defaultView\n : window;\n for (\n var element = getActiveElement(containerInfo.document);\n element instanceof containerInfo.HTMLIFrameElement;\n\n ) {\n try {\n var JSCompiler_inline_result =\n \"string\" === typeof element.contentWindow.location.href;\n } catch (err) {\n JSCompiler_inline_result = !1;\n }\n if (JSCompiler_inline_result) containerInfo = element.contentWindow;\n else break;\n element = getActiveElement(containerInfo.document);\n }\n return element;\n}\nfunction hasSelectionCapabilities(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return (\n nodeName &&\n ((\"input\" === nodeName &&\n (\"text\" === elem.type ||\n \"search\" === elem.type ||\n \"tel\" === elem.type ||\n \"url\" === elem.type ||\n \"password\" === elem.type)) ||\n \"textarea\" === nodeName ||\n \"true\" === elem.contentEditable)\n );\n}\nvar skipSelectionChangeEvent =\n canUseDOM && \"documentMode\" in document && 11 >= document.documentMode,\n activeElement = null,\n activeElementInst = null,\n lastSelection = null,\n mouseDown = !1;\nfunction constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {\n var doc =\n nativeEventTarget.window === nativeEventTarget\n ? nativeEventTarget.document\n : 9 === nativeEventTarget.nodeType\n ? nativeEventTarget\n : nativeEventTarget.ownerDocument;\n mouseDown ||\n null == activeElement ||\n activeElement !== getActiveElement(doc) ||\n ((doc = activeElement),\n \"selectionStart\" in doc && hasSelectionCapabilities(doc)\n ? (doc = { start: doc.selectionStart, end: doc.selectionEnd })\n : ((doc = (\n (doc.ownerDocument && doc.ownerDocument.defaultView) ||\n window\n ).getSelection()),\n (doc = {\n anchorNode: doc.anchorNode,\n anchorOffset: doc.anchorOffset,\n focusNode: doc.focusNode,\n focusOffset: doc.focusOffset\n })),\n (lastSelection && shallowEqual(lastSelection, doc)) ||\n ((lastSelection = doc),\n (doc = accumulateTwoPhaseListeners(activeElementInst, \"onSelect\")),\n 0 < doc.length &&\n ((nativeEvent = new SyntheticEvent(\n \"onSelect\",\n \"select\",\n null,\n nativeEvent,\n nativeEventTarget\n )),\n dispatchQueue.push({ event: nativeEvent, listeners: doc }),\n (nativeEvent.target = activeElement))));\n}\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes[\"Webkit\" + styleProp] = \"webkit\" + eventName;\n prefixes[\"Moz\" + styleProp] = \"moz\" + eventName;\n return prefixes;\n}\nvar vendorPrefixes = {\n animationend: makePrefixMap(\"Animation\", \"AnimationEnd\"),\n animationiteration: makePrefixMap(\"Animation\", \"AnimationIteration\"),\n animationstart: makePrefixMap(\"Animation\", \"AnimationStart\"),\n transitionrun: makePrefixMap(\"Transition\", \"TransitionRun\"),\n transitionstart: makePrefixMap(\"Transition\", \"TransitionStart\"),\n transitioncancel: makePrefixMap(\"Transition\", \"TransitionCancel\"),\n transitionend: makePrefixMap(\"Transition\", \"TransitionEnd\")\n },\n prefixedEventNames = {},\n style = {};\ncanUseDOM &&\n ((style = document.createElement(\"div\").style),\n \"AnimationEvent\" in window ||\n (delete vendorPrefixes.animationend.animation,\n delete vendorPrefixes.animationiteration.animation,\n delete vendorPrefixes.animationstart.animation),\n \"TransitionEvent\" in window ||\n delete vendorPrefixes.transitionend.transition);\nfunction getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) return prefixedEventNames[eventName];\n if (!vendorPrefixes[eventName]) return eventName;\n var prefixMap = vendorPrefixes[eventName],\n styleProp;\n for (styleProp in prefixMap)\n if (prefixMap.hasOwnProperty(styleProp) && styleProp in style)\n return (prefixedEventNames[eventName] = prefixMap[styleProp]);\n return eventName;\n}\nvar ANIMATION_END = getVendorPrefixedEventName(\"animationend\"),\n ANIMATION_ITERATION = getVendorPrefixedEventName(\"animationiteration\"),\n ANIMATION_START = getVendorPrefixedEventName(\"animationstart\"),\n TRANSITION_RUN = getVendorPrefixedEventName(\"transitionrun\"),\n TRANSITION_START = getVendorPrefixedEventName(\"transitionstart\"),\n TRANSITION_CANCEL = getVendorPrefixedEventName(\"transitioncancel\"),\n TRANSITION_END = getVendorPrefixedEventName(\"transitionend\"),\n topLevelEventsToReactNames = new Map(),\n simpleEventPluginEvents =\n \"abort auxClick beforeToggle 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(\n \" \"\n );\nsimpleEventPluginEvents.push(\"scrollEnd\");\nfunction registerSimpleEvent(domEventName, reactName) {\n topLevelEventsToReactNames.set(domEventName, reactName);\n registerTwoPhaseEvent(reactName, [domEventName]);\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n concurrentQueues = [],\n concurrentQueuesIndex = 0,\n concurrentlyUpdatedLanes = 0;\nfunction finishQueueingConcurrentUpdates() {\n for (\n var endIndex = concurrentQueuesIndex,\n i = (concurrentlyUpdatedLanes = concurrentQueuesIndex = 0);\n i < endIndex;\n\n ) {\n var fiber = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var queue = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var update = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var lane = concurrentQueues[i];\n concurrentQueues[i++] = null;\n if (null !== queue && null !== update) {\n var pending = queue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n queue.pending = update;\n }\n 0 !== lane && markUpdateLaneFromFiberToRoot(fiber, update, lane);\n }\n}\nfunction enqueueUpdate$1(fiber, queue, update, lane) {\n concurrentQueues[concurrentQueuesIndex++] = fiber;\n concurrentQueues[concurrentQueuesIndex++] = queue;\n concurrentQueues[concurrentQueuesIndex++] = update;\n concurrentQueues[concurrentQueuesIndex++] = lane;\n concurrentlyUpdatedLanes |= lane;\n fiber.lanes |= lane;\n fiber = fiber.alternate;\n null !== fiber && (fiber.lanes |= lane);\n}\nfunction enqueueConcurrentHookUpdate(fiber, queue, update, lane) {\n enqueueUpdate$1(fiber, queue, update, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction enqueueConcurrentRenderForLane(fiber, lane) {\n enqueueUpdate$1(fiber, null, null, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) {\n sourceFiber.lanes |= lane;\n var alternate = sourceFiber.alternate;\n null !== alternate && (alternate.lanes |= lane);\n for (var isHidden = !1, parent = sourceFiber.return; null !== parent; )\n (parent.childLanes |= lane),\n (alternate = parent.alternate),\n null !== alternate && (alternate.childLanes |= lane),\n 22 === parent.tag &&\n ((sourceFiber = parent.stateNode),\n null === sourceFiber || sourceFiber._visibility & 1 || (isHidden = !0)),\n (sourceFiber = parent),\n (parent = parent.return);\n return 3 === sourceFiber.tag\n ? ((parent = sourceFiber.stateNode),\n isHidden &&\n null !== update &&\n ((isHidden = 31 - clz32(lane)),\n (sourceFiber = parent.hiddenUpdates),\n (alternate = sourceFiber[isHidden]),\n null === alternate\n ? (sourceFiber[isHidden] = [update])\n : alternate.push(update),\n (update.lane = lane | 536870912)),\n parent)\n : null;\n}\nfunction getRootForUpdatedFiber(sourceFiber) {\n if (50 < nestedUpdateCount)\n throw (\n ((nestedUpdateCount = 0),\n (rootWithNestedUpdates = null),\n Error(formatProdErrorMessage(185)))\n );\n for (var parent = sourceFiber.return; null !== parent; )\n (sourceFiber = parent), (parent = sourceFiber.return);\n return 3 === sourceFiber.tag ? sourceFiber.stateNode : null;\n}\nvar emptyContextObject = {};\nfunction FiberNode(tag, pendingProps, key, mode) {\n this.tag = tag;\n this.key = key;\n this.sibling =\n this.child =\n this.return =\n this.stateNode =\n this.type =\n this.elementType =\n null;\n this.index = 0;\n this.refCleanup = this.ref = null;\n this.pendingProps = pendingProps;\n this.dependencies =\n this.memoizedState =\n this.updateQueue =\n this.memoizedProps =\n null;\n this.mode = mode;\n this.subtreeFlags = this.flags = 0;\n this.deletions = null;\n this.childLanes = this.lanes = 0;\n this.alternate = null;\n}\nfunction createFiberImplClass(tag, pendingProps, key, mode) {\n return new FiberNode(tag, pendingProps, key, mode);\n}\nfunction shouldConstruct(Component) {\n Component = Component.prototype;\n return !(!Component || !Component.isReactComponent);\n}\nfunction createWorkInProgress(current, pendingProps) {\n var workInProgress = current.alternate;\n null === workInProgress\n ? ((workInProgress = createFiberImplClass(\n current.tag,\n pendingProps,\n current.key,\n current.mode\n )),\n (workInProgress.elementType = current.elementType),\n (workInProgress.type = current.type),\n (workInProgress.stateNode = current.stateNode),\n (workInProgress.alternate = current),\n (current.alternate = workInProgress))\n : ((workInProgress.pendingProps = pendingProps),\n (workInProgress.type = current.type),\n (workInProgress.flags = 0),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.deletions = null));\n workInProgress.flags = current.flags & 65011712;\n workInProgress.childLanes = current.childLanes;\n workInProgress.lanes = current.lanes;\n workInProgress.child = current.child;\n workInProgress.memoizedProps = current.memoizedProps;\n workInProgress.memoizedState = current.memoizedState;\n workInProgress.updateQueue = current.updateQueue;\n pendingProps = current.dependencies;\n workInProgress.dependencies =\n null === pendingProps\n ? null\n : { lanes: pendingProps.lanes, firstContext: pendingProps.firstContext };\n workInProgress.sibling = current.sibling;\n workInProgress.index = current.index;\n workInProgress.ref = current.ref;\n workInProgress.refCleanup = current.refCleanup;\n return workInProgress;\n}\nfunction resetWorkInProgress(workInProgress, renderLanes) {\n workInProgress.flags &= 65011714;\n var current = workInProgress.alternate;\n null === current\n ? ((workInProgress.childLanes = 0),\n (workInProgress.lanes = renderLanes),\n (workInProgress.child = null),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.memoizedProps = null),\n (workInProgress.memoizedState = null),\n (workInProgress.updateQueue = null),\n (workInProgress.dependencies = null),\n (workInProgress.stateNode = null))\n : ((workInProgress.childLanes = current.childLanes),\n (workInProgress.lanes = current.lanes),\n (workInProgress.child = current.child),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.deletions = null),\n (workInProgress.memoizedProps = current.memoizedProps),\n (workInProgress.memoizedState = current.memoizedState),\n (workInProgress.updateQueue = current.updateQueue),\n (workInProgress.type = current.type),\n (renderLanes = current.dependencies),\n (workInProgress.dependencies =\n null === renderLanes\n ? null\n : {\n lanes: renderLanes.lanes,\n firstContext: renderLanes.firstContext\n }));\n return workInProgress;\n}\nfunction createFiberFromTypeAndProps(\n type,\n key,\n pendingProps,\n owner,\n mode,\n lanes\n) {\n var fiberTag = 0;\n owner = type;\n if (\"function\" === typeof type) shouldConstruct(type) && (fiberTag = 1);\n else if (\"string\" === typeof type)\n fiberTag = isHostHoistableType(\n type,\n pendingProps,\n contextStackCursor.current\n )\n ? 26\n : \"html\" === type || \"head\" === type || \"body\" === type\n ? 27\n : 5;\n else\n a: switch (type) {\n case REACT_ACTIVITY_TYPE:\n return (\n (type = createFiberImplClass(31, pendingProps, key, mode)),\n (type.elementType = REACT_ACTIVITY_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_FRAGMENT_TYPE:\n return createFiberFromFragment(pendingProps.children, mode, lanes, key);\n case REACT_STRICT_MODE_TYPE:\n fiberTag = 8;\n mode |= 24;\n break;\n case REACT_PROFILER_TYPE:\n return (\n (type = createFiberImplClass(12, pendingProps, key, mode | 2)),\n (type.elementType = REACT_PROFILER_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_SUSPENSE_TYPE:\n return (\n (type = createFiberImplClass(13, pendingProps, key, mode)),\n (type.elementType = REACT_SUSPENSE_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_SUSPENSE_LIST_TYPE:\n return (\n (type = createFiberImplClass(19, pendingProps, key, mode)),\n (type.elementType = REACT_SUSPENSE_LIST_TYPE),\n (type.lanes = lanes),\n type\n );\n default:\n if (\"object\" === typeof type && null !== type)\n switch (type.$$typeof) {\n case REACT_CONTEXT_TYPE:\n fiberTag = 10;\n break a;\n case REACT_CONSUMER_TYPE:\n fiberTag = 9;\n break a;\n case REACT_FORWARD_REF_TYPE:\n fiberTag = 11;\n break a;\n case REACT_MEMO_TYPE:\n fiberTag = 14;\n break a;\n case REACT_LAZY_TYPE:\n fiberTag = 16;\n owner = null;\n break a;\n }\n fiberTag = 29;\n pendingProps = Error(\n formatProdErrorMessage(130, null === type ? \"null\" : typeof type, \"\")\n );\n owner = null;\n }\n key = createFiberImplClass(fiberTag, pendingProps, key, mode);\n key.elementType = type;\n key.type = owner;\n key.lanes = lanes;\n return key;\n}\nfunction createFiberFromFragment(elements, mode, lanes, key) {\n elements = createFiberImplClass(7, elements, key, mode);\n elements.lanes = lanes;\n return elements;\n}\nfunction createFiberFromText(content, mode, lanes) {\n content = createFiberImplClass(6, content, null, mode);\n content.lanes = lanes;\n return content;\n}\nfunction createFiberFromDehydratedFragment(dehydratedNode) {\n var fiber = createFiberImplClass(18, null, null, 0);\n fiber.stateNode = dehydratedNode;\n return fiber;\n}\nfunction createFiberFromPortal(portal, mode, lanes) {\n mode = createFiberImplClass(\n 4,\n null !== portal.children ? portal.children : [],\n portal.key,\n mode\n );\n mode.lanes = lanes;\n mode.stateNode = {\n containerInfo: portal.containerInfo,\n pendingChildren: null,\n implementation: portal.implementation\n };\n return mode;\n}\nvar CapturedStacks = new WeakMap();\nfunction createCapturedValueAtFiber(value, source) {\n if (\"object\" === typeof value && null !== value) {\n var existing = CapturedStacks.get(value);\n if (void 0 !== existing) return existing;\n source = {\n value: value,\n source: source,\n stack: getStackByFiberInDevAndProd(source)\n };\n CapturedStacks.set(value, source);\n return source;\n }\n return {\n value: value,\n source: source,\n stack: getStackByFiberInDevAndProd(source)\n };\n}\nvar forkStack = [],\n forkStackIndex = 0,\n treeForkProvider = null,\n treeForkCount = 0,\n idStack = [],\n idStackIndex = 0,\n treeContextProvider = null,\n treeContextId = 1,\n treeContextOverflow = \"\";\nfunction pushTreeFork(workInProgress, totalChildren) {\n forkStack[forkStackIndex++] = treeForkCount;\n forkStack[forkStackIndex++] = treeForkProvider;\n treeForkProvider = workInProgress;\n treeForkCount = totalChildren;\n}\nfunction pushTreeId(workInProgress, totalChildren, index) {\n idStack[idStackIndex++] = treeContextId;\n idStack[idStackIndex++] = treeContextOverflow;\n idStack[idStackIndex++] = treeContextProvider;\n treeContextProvider = workInProgress;\n var baseIdWithLeadingBit = treeContextId;\n workInProgress = treeContextOverflow;\n var baseLength = 32 - clz32(baseIdWithLeadingBit) - 1;\n baseIdWithLeadingBit &= ~(1 << baseLength);\n index += 1;\n var length = 32 - clz32(totalChildren) + baseLength;\n if (30 < length) {\n var numberOfOverflowBits = baseLength - (baseLength % 5);\n length = (\n baseIdWithLeadingBit &\n ((1 << numberOfOverflowBits) - 1)\n ).toString(32);\n baseIdWithLeadingBit >>= numberOfOverflowBits;\n baseLength -= numberOfOverflowBits;\n treeContextId =\n (1 << (32 - clz32(totalChildren) + baseLength)) |\n (index << baseLength) |\n baseIdWithLeadingBit;\n treeContextOverflow = length + workInProgress;\n } else\n (treeContextId =\n (1 << length) | (index << baseLength) | baseIdWithLeadingBit),\n (treeContextOverflow = workInProgress);\n}\nfunction pushMaterializedTreeId(workInProgress) {\n null !== workInProgress.return &&\n (pushTreeFork(workInProgress, 1), pushTreeId(workInProgress, 1, 0));\n}\nfunction popTreeContext(workInProgress) {\n for (; workInProgress === treeForkProvider; )\n (treeForkProvider = forkStack[--forkStackIndex]),\n (forkStack[forkStackIndex] = null),\n (treeForkCount = forkStack[--forkStackIndex]),\n (forkStack[forkStackIndex] = null);\n for (; workInProgress === treeContextProvider; )\n (treeContextProvider = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null),\n (treeContextOverflow = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null),\n (treeContextId = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null);\n}\nfunction restoreSuspendedTreeContext(workInProgress, suspendedContext) {\n idStack[idStackIndex++] = treeContextId;\n idStack[idStackIndex++] = treeContextOverflow;\n idStack[idStackIndex++] = treeContextProvider;\n treeContextId = suspendedContext.id;\n treeContextOverflow = suspendedContext.overflow;\n treeContextProvider = workInProgress;\n}\nvar hydrationParentFiber = null,\n nextHydratableInstance = null,\n isHydrating = !1,\n hydrationErrors = null,\n rootOrSingletonContext = !1,\n HydrationMismatchException = Error(formatProdErrorMessage(519));\nfunction throwOnHydrationMismatch(fiber) {\n var error = Error(\n formatProdErrorMessage(\n 418,\n 1 < arguments.length && void 0 !== arguments[1] && arguments[1]\n ? \"text\"\n : \"HTML\",\n \"\"\n )\n );\n queueHydrationError(createCapturedValueAtFiber(error, fiber));\n throw HydrationMismatchException;\n}\nfunction prepareToHydrateHostInstance(fiber) {\n var instance = fiber.stateNode,\n type = fiber.type,\n props = fiber.memoizedProps;\n instance[internalInstanceKey] = fiber;\n instance[internalPropsKey] = props;\n switch (type) {\n case \"dialog\":\n listenToNonDelegatedEvent(\"cancel\", instance);\n listenToNonDelegatedEvent(\"close\", instance);\n break;\n case \"iframe\":\n case \"object\":\n case \"embed\":\n listenToNonDelegatedEvent(\"load\", instance);\n break;\n case \"video\":\n case \"audio\":\n for (type = 0; type < mediaEventTypes.length; type++)\n listenToNonDelegatedEvent(mediaEventTypes[type], instance);\n break;\n case \"source\":\n listenToNonDelegatedEvent(\"error\", instance);\n break;\n case \"img\":\n case \"image\":\n case \"link\":\n listenToNonDelegatedEvent(\"error\", instance);\n listenToNonDelegatedEvent(\"load\", instance);\n break;\n case \"details\":\n listenToNonDelegatedEvent(\"toggle\", instance);\n break;\n case \"input\":\n listenToNonDelegatedEvent(\"invalid\", instance);\n initInput(\n instance,\n props.value,\n props.defaultValue,\n props.checked,\n props.defaultChecked,\n props.type,\n props.name,\n !0\n );\n break;\n case \"select\":\n listenToNonDelegatedEvent(\"invalid\", instance);\n break;\n case \"textarea\":\n listenToNonDelegatedEvent(\"invalid\", instance),\n initTextarea(instance, props.value, props.defaultValue, props.children);\n }\n type = props.children;\n (\"string\" !== typeof type &&\n \"number\" !== typeof type &&\n \"bigint\" !== typeof type) ||\n instance.textContent === \"\" + type ||\n !0 === props.suppressHydrationWarning ||\n checkForUnmatchedText(instance.textContent, type)\n ? (null != props.popover &&\n (listenToNonDelegatedEvent(\"beforetoggle\", instance),\n listenToNonDelegatedEvent(\"toggle\", instance)),\n null != props.onScroll && listenToNonDelegatedEvent(\"scroll\", instance),\n null != props.onScrollEnd &&\n listenToNonDelegatedEvent(\"scrollend\", instance),\n null != props.onClick && (instance.onclick = noop$1),\n (instance = !0))\n : (instance = !1);\n instance || throwOnHydrationMismatch(fiber, !0);\n}\nfunction popToNextHostParent(fiber) {\n for (hydrationParentFiber = fiber.return; hydrationParentFiber; )\n switch (hydrationParentFiber.tag) {\n case 5:\n case 31:\n case 13:\n rootOrSingletonContext = !1;\n return;\n case 27:\n case 3:\n rootOrSingletonContext = !0;\n return;\n default:\n hydrationParentFiber = hydrationParentFiber.return;\n }\n}\nfunction popHydrationState(fiber) {\n if (fiber !== hydrationParentFiber) return !1;\n if (!isHydrating) return popToNextHostParent(fiber), (isHydrating = !0), !1;\n var tag = fiber.tag,\n JSCompiler_temp;\n if ((JSCompiler_temp = 3 !== tag && 27 !== tag)) {\n if ((JSCompiler_temp = 5 === tag))\n (JSCompiler_temp = fiber.type),\n (JSCompiler_temp =\n !(\"form\" !== JSCompiler_temp && \"button\" !== JSCompiler_temp) ||\n shouldSetTextContent(fiber.type, fiber.memoizedProps));\n JSCompiler_temp = !JSCompiler_temp;\n }\n JSCompiler_temp && nextHydratableInstance && throwOnHydrationMismatch(fiber);\n popToNextHostParent(fiber);\n if (13 === tag) {\n fiber = fiber.memoizedState;\n fiber = null !== fiber ? fiber.dehydrated : null;\n if (!fiber) throw Error(formatProdErrorMessage(317));\n nextHydratableInstance =\n getNextHydratableInstanceAfterHydrationBoundary(fiber);\n } else if (31 === tag) {\n fiber = fiber.memoizedState;\n fiber = null !== fiber ? fiber.dehydrated : null;\n if (!fiber) throw Error(formatProdErrorMessage(317));\n nextHydratableInstance =\n getNextHydratableInstanceAfterHydrationBoundary(fiber);\n } else\n 27 === tag\n ? ((tag = nextHydratableInstance),\n isSingletonScope(fiber.type)\n ? ((fiber = previousHydratableOnEnteringScopedSingleton),\n (previousHydratableOnEnteringScopedSingleton = null),\n (nextHydratableInstance = fiber))\n : (nextHydratableInstance = tag))\n : (nextHydratableInstance = hydrationParentFiber\n ? getNextHydratable(fiber.stateNode.nextSibling)\n : null);\n return !0;\n}\nfunction resetHydrationState() {\n nextHydratableInstance = hydrationParentFiber = null;\n isHydrating = !1;\n}\nfunction upgradeHydrationErrorsToRecoverable() {\n var queuedErrors = hydrationErrors;\n null !== queuedErrors &&\n (null === workInProgressRootRecoverableErrors\n ? (workInProgressRootRecoverableErrors = queuedErrors)\n : workInProgressRootRecoverableErrors.push.apply(\n workInProgressRootRecoverableErrors,\n queuedErrors\n ),\n (hydrationErrors = null));\n return queuedErrors;\n}\nfunction queueHydrationError(error) {\n null === hydrationErrors\n ? (hydrationErrors = [error])\n : hydrationErrors.push(error);\n}\nvar valueCursor = createCursor(null),\n currentlyRenderingFiber$1 = null,\n lastContextDependency = null;\nfunction pushProvider(providerFiber, context, nextValue) {\n push(valueCursor, context._currentValue);\n context._currentValue = nextValue;\n}\nfunction popProvider(context) {\n context._currentValue = valueCursor.current;\n pop(valueCursor);\n}\nfunction scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {\n for (; null !== parent; ) {\n var alternate = parent.alternate;\n (parent.childLanes & renderLanes) !== renderLanes\n ? ((parent.childLanes |= renderLanes),\n null !== alternate && (alternate.childLanes |= renderLanes))\n : null !== alternate &&\n (alternate.childLanes & renderLanes) !== renderLanes &&\n (alternate.childLanes |= renderLanes);\n if (parent === propagationRoot) break;\n parent = parent.return;\n }\n}\nfunction propagateContextChanges(\n workInProgress,\n contexts,\n renderLanes,\n forcePropagateEntireTree\n) {\n var fiber = workInProgress.child;\n null !== fiber && (fiber.return = workInProgress);\n for (; null !== fiber; ) {\n var list = fiber.dependencies;\n if (null !== list) {\n var nextFiber = fiber.child;\n list = list.firstContext;\n a: for (; null !== list; ) {\n var dependency = list;\n list = fiber;\n for (var i = 0; i < contexts.length; i++)\n if (dependency.context === contexts[i]) {\n list.lanes |= renderLanes;\n dependency = list.alternate;\n null !== dependency && (dependency.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(\n list.return,\n renderLanes,\n workInProgress\n );\n forcePropagateEntireTree || (nextFiber = null);\n break a;\n }\n list = dependency.next;\n }\n } else if (18 === fiber.tag) {\n nextFiber = fiber.return;\n if (null === nextFiber) throw Error(formatProdErrorMessage(341));\n nextFiber.lanes |= renderLanes;\n list = nextFiber.alternate;\n null !== list && (list.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress);\n nextFiber = null;\n } else nextFiber = fiber.child;\n if (null !== nextFiber) nextFiber.return = fiber;\n else\n for (nextFiber = fiber; null !== nextFiber; ) {\n if (nextFiber === workInProgress) {\n nextFiber = null;\n break;\n }\n fiber = nextFiber.sibling;\n if (null !== fiber) {\n fiber.return = nextFiber.return;\n nextFiber = fiber;\n break;\n }\n nextFiber = nextFiber.return;\n }\n fiber = nextFiber;\n }\n}\nfunction propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n forcePropagateEntireTree\n) {\n current = null;\n for (\n var parent = workInProgress, isInsidePropagationBailout = !1;\n null !== parent;\n\n ) {\n if (!isInsidePropagationBailout)\n if (0 !== (parent.flags & 524288)) isInsidePropagationBailout = !0;\n else if (0 !== (parent.flags & 262144)) break;\n if (10 === parent.tag) {\n var currentParent = parent.alternate;\n if (null === currentParent) throw Error(formatProdErrorMessage(387));\n currentParent = currentParent.memoizedProps;\n if (null !== currentParent) {\n var context = parent.type;\n objectIs(parent.pendingProps.value, currentParent.value) ||\n (null !== current ? current.push(context) : (current = [context]));\n }\n } else if (parent === hostTransitionProviderCursor.current) {\n currentParent = parent.alternate;\n if (null === currentParent) throw Error(formatProdErrorMessage(387));\n currentParent.memoizedState.memoizedState !==\n parent.memoizedState.memoizedState &&\n (null !== current\n ? current.push(HostTransitionContext)\n : (current = [HostTransitionContext]));\n }\n parent = parent.return;\n }\n null !== current &&\n propagateContextChanges(\n workInProgress,\n current,\n renderLanes,\n forcePropagateEntireTree\n );\n workInProgress.flags |= 262144;\n}\nfunction checkIfContextChanged(currentDependencies) {\n for (\n currentDependencies = currentDependencies.firstContext;\n null !== currentDependencies;\n\n ) {\n if (\n !objectIs(\n currentDependencies.context._currentValue,\n currentDependencies.memoizedValue\n )\n )\n return !0;\n currentDependencies = currentDependencies.next;\n }\n return !1;\n}\nfunction prepareToReadContext(workInProgress) {\n currentlyRenderingFiber$1 = workInProgress;\n lastContextDependency = null;\n workInProgress = workInProgress.dependencies;\n null !== workInProgress && (workInProgress.firstContext = null);\n}\nfunction readContext(context) {\n return readContextForConsumer(currentlyRenderingFiber$1, context);\n}\nfunction readContextDuringReconciliation(consumer, context) {\n null === currentlyRenderingFiber$1 && prepareToReadContext(consumer);\n return readContextForConsumer(consumer, context);\n}\nfunction readContextForConsumer(consumer, context) {\n var value = context._currentValue;\n context = { context: context, memoizedValue: value, next: null };\n if (null === lastContextDependency) {\n if (null === consumer) throw Error(formatProdErrorMessage(308));\n lastContextDependency = context;\n consumer.dependencies = { lanes: 0, firstContext: context };\n consumer.flags |= 524288;\n } else lastContextDependency = lastContextDependency.next = context;\n return value;\n}\nvar AbortControllerLocal =\n \"undefined\" !== typeof AbortController\n ? AbortController\n : function () {\n var listeners = [],\n signal = (this.signal = {\n aborted: !1,\n addEventListener: function (type, listener) {\n listeners.push(listener);\n }\n });\n this.abort = function () {\n signal.aborted = !0;\n listeners.forEach(function (listener) {\n return listener();\n });\n };\n },\n scheduleCallback$2 = Scheduler.unstable_scheduleCallback,\n NormalPriority = Scheduler.unstable_NormalPriority,\n CacheContext = {\n $$typeof: REACT_CONTEXT_TYPE,\n Consumer: null,\n Provider: null,\n _currentValue: null,\n _currentValue2: null,\n _threadCount: 0\n };\nfunction createCache() {\n return {\n controller: new AbortControllerLocal(),\n data: new Map(),\n refCount: 0\n };\n}\nfunction releaseCache(cache) {\n cache.refCount--;\n 0 === cache.refCount &&\n scheduleCallback$2(NormalPriority, function () {\n cache.controller.abort();\n });\n}\nvar currentEntangledListeners = null,\n currentEntangledPendingCount = 0,\n currentEntangledLane = 0,\n currentEntangledActionThenable = null;\nfunction entangleAsyncAction(transition, thenable) {\n if (null === currentEntangledListeners) {\n var entangledListeners = (currentEntangledListeners = []);\n currentEntangledPendingCount = 0;\n currentEntangledLane = requestTransitionLane();\n currentEntangledActionThenable = {\n status: \"pending\",\n value: void 0,\n then: function (resolve) {\n entangledListeners.push(resolve);\n }\n };\n }\n currentEntangledPendingCount++;\n thenable.then(pingEngtangledActionScope, pingEngtangledActionScope);\n return thenable;\n}\nfunction pingEngtangledActionScope() {\n if (\n 0 === --currentEntangledPendingCount &&\n null !== currentEntangledListeners\n ) {\n null !== currentEntangledActionThenable &&\n (currentEntangledActionThenable.status = \"fulfilled\");\n var listeners = currentEntangledListeners;\n currentEntangledListeners = null;\n currentEntangledLane = 0;\n currentEntangledActionThenable = null;\n for (var i = 0; i < listeners.length; i++) (0, listeners[i])();\n }\n}\nfunction chainThenableValue(thenable, result) {\n var listeners = [],\n thenableWithOverride = {\n status: \"pending\",\n value: null,\n reason: null,\n then: function (resolve) {\n listeners.push(resolve);\n }\n };\n thenable.then(\n function () {\n thenableWithOverride.status = \"fulfilled\";\n thenableWithOverride.value = result;\n for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result);\n },\n function (error) {\n thenableWithOverride.status = \"rejected\";\n thenableWithOverride.reason = error;\n for (error = 0; error < listeners.length; error++)\n (0, listeners[error])(void 0);\n }\n );\n return thenableWithOverride;\n}\nvar prevOnStartTransitionFinish = ReactSharedInternals.S;\nReactSharedInternals.S = function (transition, returnValue) {\n globalMostRecentTransitionTime = now();\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n entangleAsyncAction(transition, returnValue);\n null !== prevOnStartTransitionFinish &&\n prevOnStartTransitionFinish(transition, returnValue);\n};\nvar resumedCache = createCursor(null);\nfunction peekCacheFromPool() {\n var cacheResumedFromPreviousRender = resumedCache.current;\n return null !== cacheResumedFromPreviousRender\n ? cacheResumedFromPreviousRender\n : workInProgressRoot.pooledCache;\n}\nfunction pushTransition(offscreenWorkInProgress, prevCachePool) {\n null === prevCachePool\n ? push(resumedCache, resumedCache.current)\n : push(resumedCache, prevCachePool.pool);\n}\nfunction getSuspendedCache() {\n var cacheFromPool = peekCacheFromPool();\n return null === cacheFromPool\n ? null\n : { parent: CacheContext._currentValue, pool: cacheFromPool };\n}\nvar SuspenseException = Error(formatProdErrorMessage(460)),\n SuspenseyCommitException = Error(formatProdErrorMessage(474)),\n SuspenseActionException = Error(formatProdErrorMessage(542)),\n noopSuspenseyCommitThenable = { then: function () {} };\nfunction isThenableResolved(thenable) {\n thenable = thenable.status;\n return \"fulfilled\" === thenable || \"rejected\" === thenable;\n}\nfunction trackUsedThenable(thenableState, thenable, index) {\n index = thenableState[index];\n void 0 === index\n ? thenableState.push(thenable)\n : index !== thenable && (thenable.then(noop$1, noop$1), (thenable = index));\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw (\n ((thenableState = thenable.reason),\n checkIfUseWrappedInAsyncCatch(thenableState),\n thenableState)\n );\n default:\n if (\"string\" === typeof thenable.status) thenable.then(noop$1, noop$1);\n else {\n thenableState = workInProgressRoot;\n if (null !== thenableState && 100 < thenableState.shellSuspendCounter)\n throw Error(formatProdErrorMessage(482));\n thenableState = thenable;\n thenableState.status = \"pending\";\n thenableState.then(\n function (fulfilledValue) {\n if (\"pending\" === thenable.status) {\n var fulfilledThenable = thenable;\n fulfilledThenable.status = \"fulfilled\";\n fulfilledThenable.value = fulfilledValue;\n }\n },\n function (error) {\n if (\"pending\" === thenable.status) {\n var rejectedThenable = thenable;\n rejectedThenable.status = \"rejected\";\n rejectedThenable.reason = error;\n }\n }\n );\n }\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw (\n ((thenableState = thenable.reason),\n checkIfUseWrappedInAsyncCatch(thenableState),\n thenableState)\n );\n }\n suspendedThenable = thenable;\n throw SuspenseException;\n }\n}\nfunction resolveLazy(lazyType) {\n try {\n var init = lazyType._init;\n return init(lazyType._payload);\n } catch (x) {\n if (null !== x && \"object\" === typeof x && \"function\" === typeof x.then)\n throw ((suspendedThenable = x), SuspenseException);\n throw x;\n }\n}\nvar suspendedThenable = null;\nfunction getSuspendedThenable() {\n if (null === suspendedThenable) throw Error(formatProdErrorMessage(459));\n var thenable = suspendedThenable;\n suspendedThenable = null;\n return thenable;\n}\nfunction checkIfUseWrappedInAsyncCatch(rejectedReason) {\n if (\n rejectedReason === SuspenseException ||\n rejectedReason === SuspenseActionException\n )\n throw Error(formatProdErrorMessage(483));\n}\nvar thenableState$1 = null,\n thenableIndexCounter$1 = 0;\nfunction unwrapThenable(thenable) {\n var index = thenableIndexCounter$1;\n thenableIndexCounter$1 += 1;\n null === thenableState$1 && (thenableState$1 = []);\n return trackUsedThenable(thenableState$1, thenable, index);\n}\nfunction coerceRef(workInProgress, element) {\n element = element.props.ref;\n workInProgress.ref = void 0 !== element ? element : null;\n}\nfunction throwOnInvalidObjectTypeImpl(returnFiber, newChild) {\n if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE)\n throw Error(formatProdErrorMessage(525));\n returnFiber = Object.prototype.toString.call(newChild);\n throw Error(\n formatProdErrorMessage(\n 31,\n \"[object Object]\" === returnFiber\n ? \"object with keys {\" + Object.keys(newChild).join(\", \") + \"}\"\n : returnFiber\n )\n );\n}\nfunction createChildReconciler(shouldTrackSideEffects) {\n function deleteChild(returnFiber, childToDelete) {\n if (shouldTrackSideEffects) {\n var deletions = returnFiber.deletions;\n null === deletions\n ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16))\n : deletions.push(childToDelete);\n }\n }\n function deleteRemainingChildren(returnFiber, currentFirstChild) {\n if (!shouldTrackSideEffects) return null;\n for (; null !== currentFirstChild; )\n deleteChild(returnFiber, currentFirstChild),\n (currentFirstChild = currentFirstChild.sibling);\n return null;\n }\n function mapRemainingChildren(currentFirstChild) {\n for (var existingChildren = new Map(); null !== currentFirstChild; )\n null !== currentFirstChild.key\n ? existingChildren.set(currentFirstChild.key, currentFirstChild)\n : existingChildren.set(currentFirstChild.index, currentFirstChild),\n (currentFirstChild = currentFirstChild.sibling);\n return existingChildren;\n }\n function useFiber(fiber, pendingProps) {\n fiber = createWorkInProgress(fiber, pendingProps);\n fiber.index = 0;\n fiber.sibling = null;\n return fiber;\n }\n function placeChild(newFiber, lastPlacedIndex, newIndex) {\n newFiber.index = newIndex;\n if (!shouldTrackSideEffects)\n return (newFiber.flags |= 1048576), lastPlacedIndex;\n newIndex = newFiber.alternate;\n if (null !== newIndex)\n return (\n (newIndex = newIndex.index),\n newIndex < lastPlacedIndex\n ? ((newFiber.flags |= 67108866), lastPlacedIndex)\n : newIndex\n );\n newFiber.flags |= 67108866;\n return lastPlacedIndex;\n }\n function placeSingleChild(newFiber) {\n shouldTrackSideEffects &&\n null === newFiber.alternate &&\n (newFiber.flags |= 67108866);\n return newFiber;\n }\n function updateTextNode(returnFiber, current, textContent, lanes) {\n if (null === current || 6 !== current.tag)\n return (\n (current = createFiberFromText(textContent, returnFiber.mode, lanes)),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, textContent);\n current.return = returnFiber;\n return current;\n }\n function updateElement(returnFiber, current, element, lanes) {\n var elementType = element.type;\n if (elementType === REACT_FRAGMENT_TYPE)\n return updateFragment(\n returnFiber,\n current,\n element.props.children,\n lanes,\n element.key\n );\n if (\n null !== current &&\n (current.elementType === elementType ||\n (\"object\" === typeof elementType &&\n null !== elementType &&\n elementType.$$typeof === REACT_LAZY_TYPE &&\n resolveLazy(elementType) === current.type))\n )\n return (\n (current = useFiber(current, element.props)),\n coerceRef(current, element),\n (current.return = returnFiber),\n current\n );\n current = createFiberFromTypeAndProps(\n element.type,\n element.key,\n element.props,\n null,\n returnFiber.mode,\n lanes\n );\n coerceRef(current, element);\n current.return = returnFiber;\n return current;\n }\n function updatePortal(returnFiber, current, portal, lanes) {\n if (\n null === current ||\n 4 !== current.tag ||\n current.stateNode.containerInfo !== portal.containerInfo ||\n current.stateNode.implementation !== portal.implementation\n )\n return (\n (current = createFiberFromPortal(portal, returnFiber.mode, lanes)),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, portal.children || []);\n current.return = returnFiber;\n return current;\n }\n function updateFragment(returnFiber, current, fragment, lanes, key) {\n if (null === current || 7 !== current.tag)\n return (\n (current = createFiberFromFragment(\n fragment,\n returnFiber.mode,\n lanes,\n key\n )),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, fragment);\n current.return = returnFiber;\n return current;\n }\n function createChild(returnFiber, newChild, lanes) {\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return (\n (newChild = createFiberFromText(\n \"\" + newChild,\n returnFiber.mode,\n lanes\n )),\n (newChild.return = returnFiber),\n newChild\n );\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return (\n (lanes = createFiberFromTypeAndProps(\n newChild.type,\n newChild.key,\n newChild.props,\n null,\n returnFiber.mode,\n lanes\n )),\n coerceRef(lanes, newChild),\n (lanes.return = returnFiber),\n lanes\n );\n case REACT_PORTAL_TYPE:\n return (\n (newChild = createFiberFromPortal(\n newChild,\n returnFiber.mode,\n lanes\n )),\n (newChild.return = returnFiber),\n newChild\n );\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n createChild(returnFiber, newChild, lanes)\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return (\n (newChild = createFiberFromFragment(\n newChild,\n returnFiber.mode,\n lanes,\n null\n )),\n (newChild.return = returnFiber),\n newChild\n );\n if (\"function\" === typeof newChild.then)\n return createChild(returnFiber, unwrapThenable(newChild), lanes);\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return createChild(\n returnFiber,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return null;\n }\n function updateSlot(returnFiber, oldFiber, newChild, lanes) {\n var key = null !== oldFiber ? oldFiber.key : null;\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return null !== key\n ? null\n : updateTextNode(returnFiber, oldFiber, \"\" + newChild, lanes);\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return newChild.key === key\n ? updateElement(returnFiber, oldFiber, newChild, lanes)\n : null;\n case REACT_PORTAL_TYPE:\n return newChild.key === key\n ? updatePortal(returnFiber, oldFiber, newChild, lanes)\n : null;\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n updateSlot(returnFiber, oldFiber, newChild, lanes)\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return null !== key\n ? null\n : updateFragment(returnFiber, oldFiber, newChild, lanes, null);\n if (\"function\" === typeof newChild.then)\n return updateSlot(\n returnFiber,\n oldFiber,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return updateSlot(\n returnFiber,\n oldFiber,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return null;\n }\n function updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n newChild,\n lanes\n ) {\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return (\n (existingChildren = existingChildren.get(newIdx) || null),\n updateTextNode(returnFiber, existingChildren, \"\" + newChild, lanes)\n );\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return (\n (existingChildren =\n existingChildren.get(\n null === newChild.key ? newIdx : newChild.key\n ) || null),\n updateElement(returnFiber, existingChildren, newChild, lanes)\n );\n case REACT_PORTAL_TYPE:\n return (\n (existingChildren =\n existingChildren.get(\n null === newChild.key ? newIdx : newChild.key\n ) || null),\n updatePortal(returnFiber, existingChildren, newChild, lanes)\n );\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n newChild,\n lanes\n )\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return (\n (existingChildren = existingChildren.get(newIdx) || null),\n updateFragment(returnFiber, existingChildren, newChild, lanes, null)\n );\n if (\"function\" === typeof newChild.then)\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return null;\n }\n function reconcileChildrenArray(\n returnFiber,\n currentFirstChild,\n newChildren,\n lanes\n ) {\n for (\n var resultingFirstChild = null,\n previousNewFiber = null,\n oldFiber = currentFirstChild,\n newIdx = (currentFirstChild = 0),\n nextOldFiber = null;\n null !== oldFiber && newIdx < newChildren.length;\n newIdx++\n ) {\n oldFiber.index > newIdx\n ? ((nextOldFiber = oldFiber), (oldFiber = null))\n : (nextOldFiber = oldFiber.sibling);\n var newFiber = updateSlot(\n returnFiber,\n oldFiber,\n newChildren[newIdx],\n lanes\n );\n if (null === newFiber) {\n null === oldFiber && (oldFiber = nextOldFiber);\n break;\n }\n shouldTrackSideEffects &&\n oldFiber &&\n null === newFiber.alternate &&\n deleteChild(returnFiber, oldFiber);\n currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx);\n null === previousNewFiber\n ? (resultingFirstChild = newFiber)\n : (previousNewFiber.sibling = newFiber);\n previousNewFiber = newFiber;\n oldFiber = nextOldFiber;\n }\n if (newIdx === newChildren.length)\n return (\n deleteRemainingChildren(returnFiber, oldFiber),\n isHydrating && pushTreeFork(returnFiber, newIdx),\n resultingFirstChild\n );\n if (null === oldFiber) {\n for (; newIdx < newChildren.length; newIdx++)\n (oldFiber = createChild(returnFiber, newChildren[newIdx], lanes)),\n null !== oldFiber &&\n ((currentFirstChild = placeChild(\n oldFiber,\n currentFirstChild,\n newIdx\n )),\n null === previousNewFiber\n ? (resultingFirstChild = oldFiber)\n : (previousNewFiber.sibling = oldFiber),\n (previousNewFiber = oldFiber));\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n for (\n oldFiber = mapRemainingChildren(oldFiber);\n newIdx < newChildren.length;\n newIdx++\n )\n (nextOldFiber = updateFromMap(\n oldFiber,\n returnFiber,\n newIdx,\n newChildren[newIdx],\n lanes\n )),\n null !== nextOldFiber &&\n (shouldTrackSideEffects &&\n null !== nextOldFiber.alternate &&\n oldFiber.delete(\n null === nextOldFiber.key ? newIdx : nextOldFiber.key\n ),\n (currentFirstChild = placeChild(\n nextOldFiber,\n currentFirstChild,\n newIdx\n )),\n null === previousNewFiber\n ? (resultingFirstChild = nextOldFiber)\n : (previousNewFiber.sibling = nextOldFiber),\n (previousNewFiber = nextOldFiber));\n shouldTrackSideEffects &&\n oldFiber.forEach(function (child) {\n return deleteChild(returnFiber, child);\n });\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n function reconcileChildrenIterator(\n returnFiber,\n currentFirstChild,\n newChildren,\n lanes\n ) {\n if (null == newChildren) throw Error(formatProdErrorMessage(151));\n for (\n var resultingFirstChild = null,\n previousNewFiber = null,\n oldFiber = currentFirstChild,\n newIdx = (currentFirstChild = 0),\n nextOldFiber = null,\n step = newChildren.next();\n null !== oldFiber && !step.done;\n newIdx++, step = newChildren.next()\n ) {\n oldFiber.index > newIdx\n ? ((nextOldFiber = oldFiber), (oldFiber = null))\n : (nextOldFiber = oldFiber.sibling);\n var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);\n if (null === newFiber) {\n null === oldFiber && (oldFiber = nextOldFiber);\n break;\n }\n shouldTrackSideEffects &&\n oldFiber &&\n null === newFiber.alternate &&\n deleteChild(returnFiber, oldFiber);\n currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx);\n null === previousNewFiber\n ? (resultingFirstChild = newFiber)\n : (previousNewFiber.sibling = newFiber);\n previousNewFiber = newFiber;\n oldFiber = nextOldFiber;\n }\n if (step.done)\n return (\n deleteRemainingChildren(returnFiber, oldFiber),\n isHydrating && pushTreeFork(returnFiber, newIdx),\n resultingFirstChild\n );\n if (null === oldFiber) {\n for (; !step.done; newIdx++, step = newChildren.next())\n (step = createChild(returnFiber, step.value, lanes)),\n null !== step &&\n ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)),\n null === previousNewFiber\n ? (resultingFirstChild = step)\n : (previousNewFiber.sibling = step),\n (previousNewFiber = step));\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n for (\n oldFiber = mapRemainingChildren(oldFiber);\n !step.done;\n newIdx++, step = newChildren.next()\n )\n (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)),\n null !== step &&\n (shouldTrackSideEffects &&\n null !== step.alternate &&\n oldFiber.delete(null === step.key ? newIdx : step.key),\n (currentFirstChild = placeChild(step, currentFirstChild, newIdx)),\n null === previousNewFiber\n ? (resultingFirstChild = step)\n : (previousNewFiber.sibling = step),\n (previousNewFiber = step));\n shouldTrackSideEffects &&\n oldFiber.forEach(function (child) {\n return deleteChild(returnFiber, child);\n });\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n function reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n ) {\n \"object\" === typeof newChild &&\n null !== newChild &&\n newChild.type === REACT_FRAGMENT_TYPE &&\n null === newChild.key &&\n (newChild = newChild.props.children);\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n a: {\n for (var key = newChild.key; null !== currentFirstChild; ) {\n if (currentFirstChild.key === key) {\n key = newChild.type;\n if (key === REACT_FRAGMENT_TYPE) {\n if (7 === currentFirstChild.tag) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(\n currentFirstChild,\n newChild.props.children\n );\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n }\n } else if (\n currentFirstChild.elementType === key ||\n (\"object\" === typeof key &&\n null !== key &&\n key.$$typeof === REACT_LAZY_TYPE &&\n resolveLazy(key) === currentFirstChild.type)\n ) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(currentFirstChild, newChild.props);\n coerceRef(lanes, newChild);\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n }\n deleteRemainingChildren(returnFiber, currentFirstChild);\n break;\n } else deleteChild(returnFiber, currentFirstChild);\n currentFirstChild = currentFirstChild.sibling;\n }\n newChild.type === REACT_FRAGMENT_TYPE\n ? ((lanes = createFiberFromFragment(\n newChild.props.children,\n returnFiber.mode,\n lanes,\n newChild.key\n )),\n (lanes.return = returnFiber),\n (returnFiber = lanes))\n : ((lanes = createFiberFromTypeAndProps(\n newChild.type,\n newChild.key,\n newChild.props,\n null,\n returnFiber.mode,\n lanes\n )),\n coerceRef(lanes, newChild),\n (lanes.return = returnFiber),\n (returnFiber = lanes));\n }\n return placeSingleChild(returnFiber);\n case REACT_PORTAL_TYPE:\n a: {\n for (key = newChild.key; null !== currentFirstChild; ) {\n if (currentFirstChild.key === key)\n if (\n 4 === currentFirstChild.tag &&\n currentFirstChild.stateNode.containerInfo ===\n newChild.containerInfo &&\n currentFirstChild.stateNode.implementation ===\n newChild.implementation\n ) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(currentFirstChild, newChild.children || []);\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n } else {\n deleteRemainingChildren(returnFiber, currentFirstChild);\n break;\n }\n else deleteChild(returnFiber, currentFirstChild);\n currentFirstChild = currentFirstChild.sibling;\n }\n lanes = createFiberFromPortal(newChild, returnFiber.mode, lanes);\n lanes.return = returnFiber;\n returnFiber = lanes;\n }\n return placeSingleChild(returnFiber);\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n )\n );\n }\n if (isArrayImpl(newChild))\n return reconcileChildrenArray(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n if (getIteratorFn(newChild)) {\n key = getIteratorFn(newChild);\n if (\"function\" !== typeof key) throw Error(formatProdErrorMessage(150));\n newChild = key.call(newChild);\n return reconcileChildrenIterator(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n }\n if (\"function\" === typeof newChild.then)\n return reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n ? ((newChild = \"\" + newChild),\n null !== currentFirstChild && 6 === currentFirstChild.tag\n ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling),\n (lanes = useFiber(currentFirstChild, newChild)),\n (lanes.return = returnFiber),\n (returnFiber = lanes))\n : (deleteRemainingChildren(returnFiber, currentFirstChild),\n (lanes = createFiberFromText(newChild, returnFiber.mode, lanes)),\n (lanes.return = returnFiber),\n (returnFiber = lanes)),\n placeSingleChild(returnFiber))\n : deleteRemainingChildren(returnFiber, currentFirstChild);\n }\n return function (returnFiber, currentFirstChild, newChild, lanes) {\n try {\n thenableIndexCounter$1 = 0;\n var firstChildFiber = reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n thenableState$1 = null;\n return firstChildFiber;\n } catch (x) {\n if (x === SuspenseException || x === SuspenseActionException) throw x;\n var fiber = createFiberImplClass(29, x, null, returnFiber.mode);\n fiber.lanes = lanes;\n fiber.return = returnFiber;\n return fiber;\n } finally {\n }\n };\n}\nvar reconcileChildFibers = createChildReconciler(!0),\n mountChildFibers = createChildReconciler(!1),\n hasForceUpdate = !1;\nfunction initializeUpdateQueue(fiber) {\n fiber.updateQueue = {\n baseState: fiber.memoizedState,\n firstBaseUpdate: null,\n lastBaseUpdate: null,\n shared: { pending: null, lanes: 0, hiddenCallbacks: null },\n callbacks: null\n };\n}\nfunction cloneUpdateQueue(current, workInProgress) {\n current = current.updateQueue;\n workInProgress.updateQueue === current &&\n (workInProgress.updateQueue = {\n baseState: current.baseState,\n firstBaseUpdate: current.firstBaseUpdate,\n lastBaseUpdate: current.lastBaseUpdate,\n shared: current.shared,\n callbacks: null\n });\n}\nfunction createUpdate(lane) {\n return { lane: lane, tag: 0, payload: null, callback: null, next: null };\n}\nfunction enqueueUpdate(fiber, update, lane) {\n var updateQueue = fiber.updateQueue;\n if (null === updateQueue) return null;\n updateQueue = updateQueue.shared;\n if (0 !== (executionContext & 2)) {\n var pending = updateQueue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n updateQueue.pending = update;\n update = getRootForUpdatedFiber(fiber);\n markUpdateLaneFromFiberToRoot(fiber, null, lane);\n return update;\n }\n enqueueUpdate$1(fiber, updateQueue, update, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction entangleTransitions(root, fiber, lane) {\n fiber = fiber.updateQueue;\n if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194048))) {\n var queueLanes = fiber.lanes;\n queueLanes &= root.pendingLanes;\n lane |= queueLanes;\n fiber.lanes = lane;\n markRootEntangled(root, lane);\n }\n}\nfunction enqueueCapturedUpdate(workInProgress, capturedUpdate) {\n var queue = workInProgress.updateQueue,\n current = workInProgress.alternate;\n if (\n null !== current &&\n ((current = current.updateQueue), queue === current)\n ) {\n var newFirst = null,\n newLast = null;\n queue = queue.firstBaseUpdate;\n if (null !== queue) {\n do {\n var clone = {\n lane: queue.lane,\n tag: queue.tag,\n payload: queue.payload,\n callback: null,\n next: null\n };\n null === newLast\n ? (newFirst = newLast = clone)\n : (newLast = newLast.next = clone);\n queue = queue.next;\n } while (null !== queue);\n null === newLast\n ? (newFirst = newLast = capturedUpdate)\n : (newLast = newLast.next = capturedUpdate);\n } else newFirst = newLast = capturedUpdate;\n queue = {\n baseState: current.baseState,\n firstBaseUpdate: newFirst,\n lastBaseUpdate: newLast,\n shared: current.shared,\n callbacks: current.callbacks\n };\n workInProgress.updateQueue = queue;\n return;\n }\n workInProgress = queue.lastBaseUpdate;\n null === workInProgress\n ? (queue.firstBaseUpdate = capturedUpdate)\n : (workInProgress.next = capturedUpdate);\n queue.lastBaseUpdate = capturedUpdate;\n}\nvar didReadFromEntangledAsyncAction = !1;\nfunction suspendIfUpdateReadFromEntangledAsyncAction() {\n if (didReadFromEntangledAsyncAction) {\n var entangledActionThenable = currentEntangledActionThenable;\n if (null !== entangledActionThenable) throw entangledActionThenable;\n }\n}\nfunction processUpdateQueue(\n workInProgress$jscomp$0,\n props,\n instance$jscomp$0,\n renderLanes\n) {\n didReadFromEntangledAsyncAction = !1;\n var queue = workInProgress$jscomp$0.updateQueue;\n hasForceUpdate = !1;\n var firstBaseUpdate = queue.firstBaseUpdate,\n lastBaseUpdate = queue.lastBaseUpdate,\n pendingQueue = queue.shared.pending;\n if (null !== pendingQueue) {\n queue.shared.pending = null;\n var lastPendingUpdate = pendingQueue,\n firstPendingUpdate = lastPendingUpdate.next;\n lastPendingUpdate.next = null;\n null === lastBaseUpdate\n ? (firstBaseUpdate = firstPendingUpdate)\n : (lastBaseUpdate.next = firstPendingUpdate);\n lastBaseUpdate = lastPendingUpdate;\n var current = workInProgress$jscomp$0.alternate;\n null !== current &&\n ((current = current.updateQueue),\n (pendingQueue = current.lastBaseUpdate),\n pendingQueue !== lastBaseUpdate &&\n (null === pendingQueue\n ? (current.firstBaseUpdate = firstPendingUpdate)\n : (pendingQueue.next = firstPendingUpdate),\n (current.lastBaseUpdate = lastPendingUpdate)));\n }\n if (null !== firstBaseUpdate) {\n var newState = queue.baseState;\n lastBaseUpdate = 0;\n current = firstPendingUpdate = lastPendingUpdate = null;\n pendingQueue = firstBaseUpdate;\n do {\n var updateLane = pendingQueue.lane & -536870913,\n isHiddenUpdate = updateLane !== pendingQueue.lane;\n if (\n isHiddenUpdate\n ? (workInProgressRootRenderLanes & updateLane) === updateLane\n : (renderLanes & updateLane) === updateLane\n ) {\n 0 !== updateLane &&\n updateLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction = !0);\n null !== current &&\n (current = current.next =\n {\n lane: 0,\n tag: pendingQueue.tag,\n payload: pendingQueue.payload,\n callback: null,\n next: null\n });\n a: {\n var workInProgress = workInProgress$jscomp$0,\n update = pendingQueue;\n updateLane = props;\n var instance = instance$jscomp$0;\n switch (update.tag) {\n case 1:\n workInProgress = update.payload;\n if (\"function\" === typeof workInProgress) {\n newState = workInProgress.call(instance, newState, updateLane);\n break a;\n }\n newState = workInProgress;\n break a;\n case 3:\n workInProgress.flags = (workInProgress.flags & -65537) | 128;\n case 0:\n workInProgress = update.payload;\n updateLane =\n \"function\" === typeof workInProgress\n ? workInProgress.call(instance, newState, updateLane)\n : workInProgress;\n if (null === updateLane || void 0 === updateLane) break a;\n newState = assign({}, newState, updateLane);\n break a;\n case 2:\n hasForceUpdate = !0;\n }\n }\n updateLane = pendingQueue.callback;\n null !== updateLane &&\n ((workInProgress$jscomp$0.flags |= 64),\n isHiddenUpdate && (workInProgress$jscomp$0.flags |= 8192),\n (isHiddenUpdate = queue.callbacks),\n null === isHiddenUpdate\n ? (queue.callbacks = [updateLane])\n : isHiddenUpdate.push(updateLane));\n } else\n (isHiddenUpdate = {\n lane: updateLane,\n tag: pendingQueue.tag,\n payload: pendingQueue.payload,\n callback: pendingQueue.callback,\n next: null\n }),\n null === current\n ? ((firstPendingUpdate = current = isHiddenUpdate),\n (lastPendingUpdate = newState))\n : (current = current.next = isHiddenUpdate),\n (lastBaseUpdate |= updateLane);\n pendingQueue = pendingQueue.next;\n if (null === pendingQueue)\n if (((pendingQueue = queue.shared.pending), null === pendingQueue))\n break;\n else\n (isHiddenUpdate = pendingQueue),\n (pendingQueue = isHiddenUpdate.next),\n (isHiddenUpdate.next = null),\n (queue.lastBaseUpdate = isHiddenUpdate),\n (queue.shared.pending = null);\n } while (1);\n null === current && (lastPendingUpdate = newState);\n queue.baseState = lastPendingUpdate;\n queue.firstBaseUpdate = firstPendingUpdate;\n queue.lastBaseUpdate = current;\n null === firstBaseUpdate && (queue.shared.lanes = 0);\n workInProgressRootSkippedLanes |= lastBaseUpdate;\n workInProgress$jscomp$0.lanes = lastBaseUpdate;\n workInProgress$jscomp$0.memoizedState = newState;\n }\n}\nfunction callCallback(callback, context) {\n if (\"function\" !== typeof callback)\n throw Error(formatProdErrorMessage(191, callback));\n callback.call(context);\n}\nfunction commitCallbacks(updateQueue, context) {\n var callbacks = updateQueue.callbacks;\n if (null !== callbacks)\n for (\n updateQueue.callbacks = null, updateQueue = 0;\n updateQueue < callbacks.length;\n updateQueue++\n )\n callCallback(callbacks[updateQueue], context);\n}\nvar currentTreeHiddenStackCursor = createCursor(null),\n prevEntangledRenderLanesCursor = createCursor(0);\nfunction pushHiddenContext(fiber, context) {\n fiber = entangledRenderLanes;\n push(prevEntangledRenderLanesCursor, fiber);\n push(currentTreeHiddenStackCursor, context);\n entangledRenderLanes = fiber | context.baseLanes;\n}\nfunction reuseHiddenContextOnStack() {\n push(prevEntangledRenderLanesCursor, entangledRenderLanes);\n push(currentTreeHiddenStackCursor, currentTreeHiddenStackCursor.current);\n}\nfunction popHiddenContext() {\n entangledRenderLanes = prevEntangledRenderLanesCursor.current;\n pop(currentTreeHiddenStackCursor);\n pop(prevEntangledRenderLanesCursor);\n}\nvar suspenseHandlerStackCursor = createCursor(null),\n shellBoundary = null;\nfunction pushPrimaryTreeSuspenseHandler(handler) {\n var current = handler.alternate;\n push(suspenseStackCursor, suspenseStackCursor.current & 1);\n push(suspenseHandlerStackCursor, handler);\n null === shellBoundary &&\n (null === current || null !== currentTreeHiddenStackCursor.current\n ? (shellBoundary = handler)\n : null !== current.memoizedState && (shellBoundary = handler));\n}\nfunction pushDehydratedActivitySuspenseHandler(fiber) {\n push(suspenseStackCursor, suspenseStackCursor.current);\n push(suspenseHandlerStackCursor, fiber);\n null === shellBoundary && (shellBoundary = fiber);\n}\nfunction pushOffscreenSuspenseHandler(fiber) {\n 22 === fiber.tag\n ? (push(suspenseStackCursor, suspenseStackCursor.current),\n push(suspenseHandlerStackCursor, fiber),\n null === shellBoundary && (shellBoundary = fiber))\n : reuseSuspenseHandlerOnStack(fiber);\n}\nfunction reuseSuspenseHandlerOnStack() {\n push(suspenseStackCursor, suspenseStackCursor.current);\n push(suspenseHandlerStackCursor, suspenseHandlerStackCursor.current);\n}\nfunction popSuspenseHandler(fiber) {\n pop(suspenseHandlerStackCursor);\n shellBoundary === fiber && (shellBoundary = null);\n pop(suspenseStackCursor);\n}\nvar suspenseStackCursor = createCursor(0);\nfunction findFirstSuspended(row) {\n for (var node = row; null !== node; ) {\n if (13 === node.tag) {\n var state = node.memoizedState;\n if (\n null !== state &&\n ((state = state.dehydrated),\n null === state ||\n isSuspenseInstancePending(state) ||\n isSuspenseInstanceFallback(state))\n )\n return node;\n } else if (\n 19 === node.tag &&\n (\"forwards\" === node.memoizedProps.revealOrder ||\n \"backwards\" === node.memoizedProps.revealOrder ||\n \"unstable_legacy-backwards\" === node.memoizedProps.revealOrder ||\n \"together\" === node.memoizedProps.revealOrder)\n ) {\n if (0 !== (node.flags & 128)) return node;\n } else if (null !== node.child) {\n node.child.return = node;\n node = node.child;\n continue;\n }\n if (node === row) break;\n for (; null === node.sibling; ) {\n if (null === node.return || node.return === row) return null;\n node = node.return;\n }\n node.sibling.return = node.return;\n node = node.sibling;\n }\n return null;\n}\nvar renderLanes = 0,\n currentlyRenderingFiber = null,\n currentHook = null,\n workInProgressHook = null,\n didScheduleRenderPhaseUpdate = !1,\n didScheduleRenderPhaseUpdateDuringThisPass = !1,\n shouldDoubleInvokeUserFnsInHooksDEV = !1,\n localIdCounter = 0,\n thenableIndexCounter = 0,\n thenableState = null,\n globalClientIdCounter = 0;\nfunction throwInvalidHookError() {\n throw Error(formatProdErrorMessage(321));\n}\nfunction areHookInputsEqual(nextDeps, prevDeps) {\n if (null === prevDeps) return !1;\n for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++)\n if (!objectIs(nextDeps[i], prevDeps[i])) return !1;\n return !0;\n}\nfunction renderWithHooks(\n current,\n workInProgress,\n Component,\n props,\n secondArg,\n nextRenderLanes\n) {\n renderLanes = nextRenderLanes;\n currentlyRenderingFiber = workInProgress;\n workInProgress.memoizedState = null;\n workInProgress.updateQueue = null;\n workInProgress.lanes = 0;\n ReactSharedInternals.H =\n null === current || null === current.memoizedState\n ? HooksDispatcherOnMount\n : HooksDispatcherOnUpdate;\n shouldDoubleInvokeUserFnsInHooksDEV = !1;\n nextRenderLanes = Component(props, secondArg);\n shouldDoubleInvokeUserFnsInHooksDEV = !1;\n didScheduleRenderPhaseUpdateDuringThisPass &&\n (nextRenderLanes = renderWithHooksAgain(\n workInProgress,\n Component,\n props,\n secondArg\n ));\n finishRenderingHooks(current);\n return nextRenderLanes;\n}\nfunction finishRenderingHooks(current) {\n ReactSharedInternals.H = ContextOnlyDispatcher;\n var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next;\n renderLanes = 0;\n workInProgressHook = currentHook = currentlyRenderingFiber = null;\n didScheduleRenderPhaseUpdate = !1;\n thenableIndexCounter = 0;\n thenableState = null;\n if (didRenderTooFewHooks) throw Error(formatProdErrorMessage(300));\n null === current ||\n didReceiveUpdate ||\n ((current = current.dependencies),\n null !== current &&\n checkIfContextChanged(current) &&\n (didReceiveUpdate = !0));\n}\nfunction renderWithHooksAgain(workInProgress, Component, props, secondArg) {\n currentlyRenderingFiber = workInProgress;\n var numberOfReRenders = 0;\n do {\n didScheduleRenderPhaseUpdateDuringThisPass && (thenableState = null);\n thenableIndexCounter = 0;\n didScheduleRenderPhaseUpdateDuringThisPass = !1;\n if (25 <= numberOfReRenders) throw Error(formatProdErrorMessage(301));\n numberOfReRenders += 1;\n workInProgressHook = currentHook = null;\n if (null != workInProgress.updateQueue) {\n var children = workInProgress.updateQueue;\n children.lastEffect = null;\n children.events = null;\n children.stores = null;\n null != children.memoCache && (children.memoCache.index = 0);\n }\n ReactSharedInternals.H = HooksDispatcherOnRerender;\n children = Component(props, secondArg);\n } while (didScheduleRenderPhaseUpdateDuringThisPass);\n return children;\n}\nfunction TransitionAwareHostComponent() {\n var dispatcher = ReactSharedInternals.H,\n maybeThenable = dispatcher.useState()[0];\n maybeThenable =\n \"function\" === typeof maybeThenable.then\n ? useThenable(maybeThenable)\n : maybeThenable;\n dispatcher = dispatcher.useState()[0];\n (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher &&\n (currentlyRenderingFiber.flags |= 1024);\n return maybeThenable;\n}\nfunction checkDidRenderIdHook() {\n var didRenderIdHook = 0 !== localIdCounter;\n localIdCounter = 0;\n return didRenderIdHook;\n}\nfunction bailoutHooks(current, workInProgress, lanes) {\n workInProgress.updateQueue = current.updateQueue;\n workInProgress.flags &= -2053;\n current.lanes &= ~lanes;\n}\nfunction resetHooksOnUnwind(workInProgress) {\n if (didScheduleRenderPhaseUpdate) {\n for (\n workInProgress = workInProgress.memoizedState;\n null !== workInProgress;\n\n ) {\n var queue = workInProgress.queue;\n null !== queue && (queue.pending = null);\n workInProgress = workInProgress.next;\n }\n didScheduleRenderPhaseUpdate = !1;\n }\n renderLanes = 0;\n workInProgressHook = currentHook = currentlyRenderingFiber = null;\n didScheduleRenderPhaseUpdateDuringThisPass = !1;\n thenableIndexCounter = localIdCounter = 0;\n thenableState = null;\n}\nfunction mountWorkInProgressHook() {\n var hook = {\n memoizedState: null,\n baseState: null,\n baseQueue: null,\n queue: null,\n next: null\n };\n null === workInProgressHook\n ? (currentlyRenderingFiber.memoizedState = workInProgressHook = hook)\n : (workInProgressHook = workInProgressHook.next = hook);\n return workInProgressHook;\n}\nfunction updateWorkInProgressHook() {\n if (null === currentHook) {\n var nextCurrentHook = currentlyRenderingFiber.alternate;\n nextCurrentHook =\n null !== nextCurrentHook ? nextCurrentHook.memoizedState : null;\n } else nextCurrentHook = currentHook.next;\n var nextWorkInProgressHook =\n null === workInProgressHook\n ? currentlyRenderingFiber.memoizedState\n : workInProgressHook.next;\n if (null !== nextWorkInProgressHook)\n (workInProgressHook = nextWorkInProgressHook),\n (currentHook = nextCurrentHook);\n else {\n if (null === nextCurrentHook) {\n if (null === currentlyRenderingFiber.alternate)\n throw Error(formatProdErrorMessage(467));\n throw Error(formatProdErrorMessage(310));\n }\n currentHook = nextCurrentHook;\n nextCurrentHook = {\n memoizedState: currentHook.memoizedState,\n baseState: currentHook.baseState,\n baseQueue: currentHook.baseQueue,\n queue: currentHook.queue,\n next: null\n };\n null === workInProgressHook\n ? (currentlyRenderingFiber.memoizedState = workInProgressHook =\n nextCurrentHook)\n : (workInProgressHook = workInProgressHook.next = nextCurrentHook);\n }\n return workInProgressHook;\n}\nfunction createFunctionComponentUpdateQueue() {\n return { lastEffect: null, events: null, stores: null, memoCache: null };\n}\nfunction useThenable(thenable) {\n var index = thenableIndexCounter;\n thenableIndexCounter += 1;\n null === thenableState && (thenableState = []);\n thenable = trackUsedThenable(thenableState, thenable, index);\n index = currentlyRenderingFiber;\n null ===\n (null === workInProgressHook\n ? index.memoizedState\n : workInProgressHook.next) &&\n ((index = index.alternate),\n (ReactSharedInternals.H =\n null === index || null === index.memoizedState\n ? HooksDispatcherOnMount\n : HooksDispatcherOnUpdate));\n return thenable;\n}\nfunction use(usable) {\n if (null !== usable && \"object\" === typeof usable) {\n if (\"function\" === typeof usable.then) return useThenable(usable);\n if (usable.$$typeof === REACT_CONTEXT_TYPE) return readContext(usable);\n }\n throw Error(formatProdErrorMessage(438, String(usable)));\n}\nfunction useMemoCache(size) {\n var memoCache = null,\n updateQueue = currentlyRenderingFiber.updateQueue;\n null !== updateQueue && (memoCache = updateQueue.memoCache);\n if (null == memoCache) {\n var current = currentlyRenderingFiber.alternate;\n null !== current &&\n ((current = current.updateQueue),\n null !== current &&\n ((current = current.memoCache),\n null != current &&\n (memoCache = {\n data: current.data.map(function (array) {\n return array.slice();\n }),\n index: 0\n })));\n }\n null == memoCache && (memoCache = { data: [], index: 0 });\n null === updateQueue &&\n ((updateQueue = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = updateQueue));\n updateQueue.memoCache = memoCache;\n updateQueue = memoCache.data[memoCache.index];\n if (void 0 === updateQueue)\n for (\n updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0;\n current < size;\n current++\n )\n updateQueue[current] = REACT_MEMO_CACHE_SENTINEL;\n memoCache.index++;\n return updateQueue;\n}\nfunction basicStateReducer(state, action) {\n return \"function\" === typeof action ? action(state) : action;\n}\nfunction updateReducer(reducer) {\n var hook = updateWorkInProgressHook();\n return updateReducerImpl(hook, currentHook, reducer);\n}\nfunction updateReducerImpl(hook, current, reducer) {\n var queue = hook.queue;\n if (null === queue) throw Error(formatProdErrorMessage(311));\n queue.lastRenderedReducer = reducer;\n var baseQueue = hook.baseQueue,\n pendingQueue = queue.pending;\n if (null !== pendingQueue) {\n if (null !== baseQueue) {\n var baseFirst = baseQueue.next;\n baseQueue.next = pendingQueue.next;\n pendingQueue.next = baseFirst;\n }\n current.baseQueue = baseQueue = pendingQueue;\n queue.pending = null;\n }\n pendingQueue = hook.baseState;\n if (null === baseQueue) hook.memoizedState = pendingQueue;\n else {\n current = baseQueue.next;\n var newBaseQueueFirst = (baseFirst = null),\n newBaseQueueLast = null,\n update = current,\n didReadFromEntangledAsyncAction$60 = !1;\n do {\n var updateLane = update.lane & -536870913;\n if (\n updateLane !== update.lane\n ? (workInProgressRootRenderLanes & updateLane) === updateLane\n : (renderLanes & updateLane) === updateLane\n ) {\n var revertLane = update.revertLane;\n if (0 === revertLane)\n null !== newBaseQueueLast &&\n (newBaseQueueLast = newBaseQueueLast.next =\n {\n lane: 0,\n revertLane: 0,\n gesture: null,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n updateLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction$60 = !0);\n else if ((renderLanes & revertLane) === revertLane) {\n update = update.next;\n revertLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction$60 = !0);\n continue;\n } else\n (updateLane = {\n lane: 0,\n revertLane: update.revertLane,\n gesture: null,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n null === newBaseQueueLast\n ? ((newBaseQueueFirst = newBaseQueueLast = updateLane),\n (baseFirst = pendingQueue))\n : (newBaseQueueLast = newBaseQueueLast.next = updateLane),\n (currentlyRenderingFiber.lanes |= revertLane),\n (workInProgressRootSkippedLanes |= revertLane);\n updateLane = update.action;\n shouldDoubleInvokeUserFnsInHooksDEV &&\n reducer(pendingQueue, updateLane);\n pendingQueue = update.hasEagerState\n ? update.eagerState\n : reducer(pendingQueue, updateLane);\n } else\n (revertLane = {\n lane: updateLane,\n revertLane: update.revertLane,\n gesture: update.gesture,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n null === newBaseQueueLast\n ? ((newBaseQueueFirst = newBaseQueueLast = revertLane),\n (baseFirst = pendingQueue))\n : (newBaseQueueLast = newBaseQueueLast.next = revertLane),\n (currentlyRenderingFiber.lanes |= updateLane),\n (workInProgressRootSkippedLanes |= updateLane);\n update = update.next;\n } while (null !== update && update !== current);\n null === newBaseQueueLast\n ? (baseFirst = pendingQueue)\n : (newBaseQueueLast.next = newBaseQueueFirst);\n if (\n !objectIs(pendingQueue, hook.memoizedState) &&\n ((didReceiveUpdate = !0),\n didReadFromEntangledAsyncAction$60 &&\n ((reducer = currentEntangledActionThenable), null !== reducer))\n )\n throw reducer;\n hook.memoizedState = pendingQueue;\n hook.baseState = baseFirst;\n hook.baseQueue = newBaseQueueLast;\n queue.lastRenderedState = pendingQueue;\n }\n null === baseQueue && (queue.lanes = 0);\n return [hook.memoizedState, queue.dispatch];\n}\nfunction rerenderReducer(reducer) {\n var hook = updateWorkInProgressHook(),\n queue = hook.queue;\n if (null === queue) throw Error(formatProdErrorMessage(311));\n queue.lastRenderedReducer = reducer;\n var dispatch = queue.dispatch,\n lastRenderPhaseUpdate = queue.pending,\n newState = hook.memoizedState;\n if (null !== lastRenderPhaseUpdate) {\n queue.pending = null;\n var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next);\n do (newState = reducer(newState, update.action)), (update = update.next);\n while (update !== lastRenderPhaseUpdate);\n objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0);\n hook.memoizedState = newState;\n null === hook.baseQueue && (hook.baseState = newState);\n queue.lastRenderedState = newState;\n }\n return [newState, dispatch];\n}\nfunction updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {\n var fiber = currentlyRenderingFiber,\n hook = updateWorkInProgressHook(),\n isHydrating$jscomp$0 = isHydrating;\n if (isHydrating$jscomp$0) {\n if (void 0 === getServerSnapshot) throw Error(formatProdErrorMessage(407));\n getServerSnapshot = getServerSnapshot();\n } else getServerSnapshot = getSnapshot();\n var snapshotChanged = !objectIs(\n (currentHook || hook).memoizedState,\n getServerSnapshot\n );\n snapshotChanged &&\n ((hook.memoizedState = getServerSnapshot), (didReceiveUpdate = !0));\n hook = hook.queue;\n updateEffect(subscribeToStore.bind(null, fiber, hook, subscribe), [\n subscribe\n ]);\n if (\n hook.getSnapshot !== getSnapshot ||\n snapshotChanged ||\n (null !== workInProgressHook && workInProgressHook.memoizedState.tag & 1)\n ) {\n fiber.flags |= 2048;\n pushSimpleEffect(\n 9,\n { destroy: void 0 },\n updateStoreInstance.bind(\n null,\n fiber,\n hook,\n getServerSnapshot,\n getSnapshot\n ),\n null\n );\n if (null === workInProgressRoot) throw Error(formatProdErrorMessage(349));\n isHydrating$jscomp$0 ||\n 0 !== (renderLanes & 127) ||\n pushStoreConsistencyCheck(fiber, getSnapshot, getServerSnapshot);\n }\n return getServerSnapshot;\n}\nfunction pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {\n fiber.flags |= 16384;\n fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };\n getSnapshot = currentlyRenderingFiber.updateQueue;\n null === getSnapshot\n ? ((getSnapshot = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = getSnapshot),\n (getSnapshot.stores = [fiber]))\n : ((renderedSnapshot = getSnapshot.stores),\n null === renderedSnapshot\n ? (getSnapshot.stores = [fiber])\n : renderedSnapshot.push(fiber));\n}\nfunction updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {\n inst.value = nextSnapshot;\n inst.getSnapshot = getSnapshot;\n checkIfSnapshotChanged(inst) && forceStoreRerender(fiber);\n}\nfunction subscribeToStore(fiber, inst, subscribe) {\n return subscribe(function () {\n checkIfSnapshotChanged(inst) && forceStoreRerender(fiber);\n });\n}\nfunction checkIfSnapshotChanged(inst) {\n var latestGetSnapshot = inst.getSnapshot;\n inst = inst.value;\n try {\n var nextValue = latestGetSnapshot();\n return !objectIs(inst, nextValue);\n } catch (error) {\n return !0;\n }\n}\nfunction forceStoreRerender(fiber) {\n var root = enqueueConcurrentRenderForLane(fiber, 2);\n null !== root && scheduleUpdateOnFiber(root, fiber, 2);\n}\nfunction mountStateImpl(initialState) {\n var hook = mountWorkInProgressHook();\n if (\"function\" === typeof initialState) {\n var initialStateInitializer = initialState;\n initialState = initialStateInitializer();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n initialStateInitializer();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n }\n hook.memoizedState = hook.baseState = initialState;\n hook.queue = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: initialState\n };\n return hook;\n}\nfunction updateOptimisticImpl(hook, current, passthrough, reducer) {\n hook.baseState = passthrough;\n return updateReducerImpl(\n hook,\n currentHook,\n \"function\" === typeof reducer ? reducer : basicStateReducer\n );\n}\nfunction dispatchActionState(\n fiber,\n actionQueue,\n setPendingState,\n setState,\n payload\n) {\n if (isRenderPhaseUpdate(fiber)) throw Error(formatProdErrorMessage(485));\n fiber = actionQueue.action;\n if (null !== fiber) {\n var actionNode = {\n payload: payload,\n action: fiber,\n next: null,\n isTransition: !0,\n status: \"pending\",\n value: null,\n reason: null,\n listeners: [],\n then: function (listener) {\n actionNode.listeners.push(listener);\n }\n };\n null !== ReactSharedInternals.T\n ? setPendingState(!0)\n : (actionNode.isTransition = !1);\n setState(actionNode);\n setPendingState = actionQueue.pending;\n null === setPendingState\n ? ((actionNode.next = actionQueue.pending = actionNode),\n runActionStateAction(actionQueue, actionNode))\n : ((actionNode.next = setPendingState.next),\n (actionQueue.pending = setPendingState.next = actionNode));\n }\n}\nfunction runActionStateAction(actionQueue, node) {\n var action = node.action,\n payload = node.payload,\n prevState = actionQueue.state;\n if (node.isTransition) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = action(prevState, payload),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n handleActionReturnValue(actionQueue, node, returnValue);\n } catch (error) {\n onActionError(actionQueue, node, error);\n } finally {\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n } else\n try {\n (prevTransition = action(prevState, payload)),\n handleActionReturnValue(actionQueue, node, prevTransition);\n } catch (error$66) {\n onActionError(actionQueue, node, error$66);\n }\n}\nfunction handleActionReturnValue(actionQueue, node, returnValue) {\n null !== returnValue &&\n \"object\" === typeof returnValue &&\n \"function\" === typeof returnValue.then\n ? returnValue.then(\n function (nextState) {\n onActionSuccess(actionQueue, node, nextState);\n },\n function (error) {\n return onActionError(actionQueue, node, error);\n }\n )\n : onActionSuccess(actionQueue, node, returnValue);\n}\nfunction onActionSuccess(actionQueue, actionNode, nextState) {\n actionNode.status = \"fulfilled\";\n actionNode.value = nextState;\n notifyActionListeners(actionNode);\n actionQueue.state = nextState;\n actionNode = actionQueue.pending;\n null !== actionNode &&\n ((nextState = actionNode.next),\n nextState === actionNode\n ? (actionQueue.pending = null)\n : ((nextState = nextState.next),\n (actionNode.next = nextState),\n runActionStateAction(actionQueue, nextState)));\n}\nfunction onActionError(actionQueue, actionNode, error) {\n var last = actionQueue.pending;\n actionQueue.pending = null;\n if (null !== last) {\n last = last.next;\n do\n (actionNode.status = \"rejected\"),\n (actionNode.reason = error),\n notifyActionListeners(actionNode),\n (actionNode = actionNode.next);\n while (actionNode !== last);\n }\n actionQueue.action = null;\n}\nfunction notifyActionListeners(actionNode) {\n actionNode = actionNode.listeners;\n for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])();\n}\nfunction actionStateReducer(oldState, newState) {\n return newState;\n}\nfunction mountActionState(action, initialStateProp) {\n if (isHydrating) {\n var ssrFormState = workInProgressRoot.formState;\n if (null !== ssrFormState) {\n a: {\n var JSCompiler_inline_result = currentlyRenderingFiber;\n if (isHydrating) {\n if (nextHydratableInstance) {\n b: {\n var JSCompiler_inline_result$jscomp$0 = nextHydratableInstance;\n for (\n var inRootOrSingleton = rootOrSingletonContext;\n 8 !== JSCompiler_inline_result$jscomp$0.nodeType;\n\n ) {\n if (!inRootOrSingleton) {\n JSCompiler_inline_result$jscomp$0 = null;\n break b;\n }\n JSCompiler_inline_result$jscomp$0 = getNextHydratable(\n JSCompiler_inline_result$jscomp$0.nextSibling\n );\n if (null === JSCompiler_inline_result$jscomp$0) {\n JSCompiler_inline_result$jscomp$0 = null;\n break b;\n }\n }\n inRootOrSingleton = JSCompiler_inline_result$jscomp$0.data;\n JSCompiler_inline_result$jscomp$0 =\n \"F!\" === inRootOrSingleton || \"F\" === inRootOrSingleton\n ? JSCompiler_inline_result$jscomp$0\n : null;\n }\n if (JSCompiler_inline_result$jscomp$0) {\n nextHydratableInstance = getNextHydratable(\n JSCompiler_inline_result$jscomp$0.nextSibling\n );\n JSCompiler_inline_result =\n \"F!\" === JSCompiler_inline_result$jscomp$0.data;\n break a;\n }\n }\n throwOnHydrationMismatch(JSCompiler_inline_result);\n }\n JSCompiler_inline_result = !1;\n }\n JSCompiler_inline_result && (initialStateProp = ssrFormState[0]);\n }\n }\n ssrFormState = mountWorkInProgressHook();\n ssrFormState.memoizedState = ssrFormState.baseState = initialStateProp;\n JSCompiler_inline_result = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: actionStateReducer,\n lastRenderedState: initialStateProp\n };\n ssrFormState.queue = JSCompiler_inline_result;\n ssrFormState = dispatchSetState.bind(\n null,\n currentlyRenderingFiber,\n JSCompiler_inline_result\n );\n JSCompiler_inline_result.dispatch = ssrFormState;\n JSCompiler_inline_result = mountStateImpl(!1);\n inRootOrSingleton = dispatchOptimisticSetState.bind(\n null,\n currentlyRenderingFiber,\n !1,\n JSCompiler_inline_result.queue\n );\n JSCompiler_inline_result = mountWorkInProgressHook();\n JSCompiler_inline_result$jscomp$0 = {\n state: initialStateProp,\n dispatch: null,\n action: action,\n pending: null\n };\n JSCompiler_inline_result.queue = JSCompiler_inline_result$jscomp$0;\n ssrFormState = dispatchActionState.bind(\n null,\n currentlyRenderingFiber,\n JSCompiler_inline_result$jscomp$0,\n inRootOrSingleton,\n ssrFormState\n );\n JSCompiler_inline_result$jscomp$0.dispatch = ssrFormState;\n JSCompiler_inline_result.memoizedState = action;\n return [initialStateProp, ssrFormState, !1];\n}\nfunction updateActionState(action) {\n var stateHook = updateWorkInProgressHook();\n return updateActionStateImpl(stateHook, currentHook, action);\n}\nfunction updateActionStateImpl(stateHook, currentStateHook, action) {\n currentStateHook = updateReducerImpl(\n stateHook,\n currentStateHook,\n actionStateReducer\n )[0];\n stateHook = updateReducer(basicStateReducer)[0];\n if (\n \"object\" === typeof currentStateHook &&\n null !== currentStateHook &&\n \"function\" === typeof currentStateHook.then\n )\n try {\n var state = useThenable(currentStateHook);\n } catch (x) {\n if (x === SuspenseException) throw SuspenseActionException;\n throw x;\n }\n else state = currentStateHook;\n currentStateHook = updateWorkInProgressHook();\n var actionQueue = currentStateHook.queue,\n dispatch = actionQueue.dispatch;\n action !== currentStateHook.memoizedState &&\n ((currentlyRenderingFiber.flags |= 2048),\n pushSimpleEffect(\n 9,\n { destroy: void 0 },\n actionStateActionEffect.bind(null, actionQueue, action),\n null\n ));\n return [state, dispatch, stateHook];\n}\nfunction actionStateActionEffect(actionQueue, action) {\n actionQueue.action = action;\n}\nfunction rerenderActionState(action) {\n var stateHook = updateWorkInProgressHook(),\n currentStateHook = currentHook;\n if (null !== currentStateHook)\n return updateActionStateImpl(stateHook, currentStateHook, action);\n updateWorkInProgressHook();\n stateHook = stateHook.memoizedState;\n currentStateHook = updateWorkInProgressHook();\n var dispatch = currentStateHook.queue.dispatch;\n currentStateHook.memoizedState = action;\n return [stateHook, dispatch, !1];\n}\nfunction pushSimpleEffect(tag, inst, create, deps) {\n tag = { tag: tag, create: create, deps: deps, inst: inst, next: null };\n inst = currentlyRenderingFiber.updateQueue;\n null === inst &&\n ((inst = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = inst));\n create = inst.lastEffect;\n null === create\n ? (inst.lastEffect = tag.next = tag)\n : ((deps = create.next),\n (create.next = tag),\n (tag.next = deps),\n (inst.lastEffect = tag));\n return tag;\n}\nfunction updateRef() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction mountEffectImpl(fiberFlags, hookFlags, create, deps) {\n var hook = mountWorkInProgressHook();\n currentlyRenderingFiber.flags |= fiberFlags;\n hook.memoizedState = pushSimpleEffect(\n 1 | hookFlags,\n { destroy: void 0 },\n create,\n void 0 === deps ? null : deps\n );\n}\nfunction updateEffectImpl(fiberFlags, hookFlags, create, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var inst = hook.memoizedState.inst;\n null !== currentHook &&\n null !== deps &&\n areHookInputsEqual(deps, currentHook.memoizedState.deps)\n ? (hook.memoizedState = pushSimpleEffect(hookFlags, inst, create, deps))\n : ((currentlyRenderingFiber.flags |= fiberFlags),\n (hook.memoizedState = pushSimpleEffect(\n 1 | hookFlags,\n inst,\n create,\n deps\n )));\n}\nfunction mountEffect(create, deps) {\n mountEffectImpl(8390656, 8, create, deps);\n}\nfunction updateEffect(create, deps) {\n updateEffectImpl(2048, 8, create, deps);\n}\nfunction useEffectEventImpl(payload) {\n currentlyRenderingFiber.flags |= 4;\n var componentUpdateQueue = currentlyRenderingFiber.updateQueue;\n if (null === componentUpdateQueue)\n (componentUpdateQueue = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = componentUpdateQueue),\n (componentUpdateQueue.events = [payload]);\n else {\n var events = componentUpdateQueue.events;\n null === events\n ? (componentUpdateQueue.events = [payload])\n : events.push(payload);\n }\n}\nfunction updateEvent(callback) {\n var ref = updateWorkInProgressHook().memoizedState;\n useEffectEventImpl({ ref: ref, nextImpl: callback });\n return function () {\n if (0 !== (executionContext & 2)) throw Error(formatProdErrorMessage(440));\n return ref.impl.apply(void 0, arguments);\n };\n}\nfunction updateInsertionEffect(create, deps) {\n return updateEffectImpl(4, 2, create, deps);\n}\nfunction updateLayoutEffect(create, deps) {\n return updateEffectImpl(4, 4, create, deps);\n}\nfunction imperativeHandleEffect(create, ref) {\n if (\"function\" === typeof ref) {\n create = create();\n var refCleanup = ref(create);\n return function () {\n \"function\" === typeof refCleanup ? refCleanup() : ref(null);\n };\n }\n if (null !== ref && void 0 !== ref)\n return (\n (create = create()),\n (ref.current = create),\n function () {\n ref.current = null;\n }\n );\n}\nfunction updateImperativeHandle(ref, create, deps) {\n deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;\n updateEffectImpl(4, 4, imperativeHandleEffect.bind(null, create, ref), deps);\n}\nfunction mountDebugValue() {}\nfunction updateCallback(callback, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var prevState = hook.memoizedState;\n if (null !== deps && areHookInputsEqual(deps, prevState[1]))\n return prevState[0];\n hook.memoizedState = [callback, deps];\n return callback;\n}\nfunction updateMemo(nextCreate, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var prevState = hook.memoizedState;\n if (null !== deps && areHookInputsEqual(deps, prevState[1]))\n return prevState[0];\n prevState = nextCreate();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n nextCreate();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n hook.memoizedState = [prevState, deps];\n return prevState;\n}\nfunction mountDeferredValueImpl(hook, value, initialValue) {\n if (\n void 0 === initialValue ||\n (0 !== (renderLanes & 1073741824) &&\n 0 === (workInProgressRootRenderLanes & 261930))\n )\n return (hook.memoizedState = value);\n hook.memoizedState = initialValue;\n hook = requestDeferredLane();\n currentlyRenderingFiber.lanes |= hook;\n workInProgressRootSkippedLanes |= hook;\n return initialValue;\n}\nfunction updateDeferredValueImpl(hook, prevValue, value, initialValue) {\n if (objectIs(value, prevValue)) return value;\n if (null !== currentTreeHiddenStackCursor.current)\n return (\n (hook = mountDeferredValueImpl(hook, value, initialValue)),\n objectIs(hook, prevValue) || (didReceiveUpdate = !0),\n hook\n );\n if (\n 0 === (renderLanes & 42) ||\n (0 !== (renderLanes & 1073741824) &&\n 0 === (workInProgressRootRenderLanes & 261930))\n )\n return (didReceiveUpdate = !0), (hook.memoizedState = value);\n hook = requestDeferredLane();\n currentlyRenderingFiber.lanes |= hook;\n workInProgressRootSkippedLanes |= hook;\n return prevValue;\n}\nfunction startTransition(fiber, queue, pendingState, finishedState, callback) {\n var previousPriority = ReactDOMSharedInternals.p;\n ReactDOMSharedInternals.p =\n 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8;\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n dispatchOptimisticSetState(fiber, !1, queue, pendingState);\n try {\n var returnValue = callback(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n if (\n null !== returnValue &&\n \"object\" === typeof returnValue &&\n \"function\" === typeof returnValue.then\n ) {\n var thenableForFinishedState = chainThenableValue(\n returnValue,\n finishedState\n );\n dispatchSetStateInternal(\n fiber,\n queue,\n thenableForFinishedState,\n requestUpdateLane(fiber)\n );\n } else\n dispatchSetStateInternal(\n fiber,\n queue,\n finishedState,\n requestUpdateLane(fiber)\n );\n } catch (error) {\n dispatchSetStateInternal(\n fiber,\n queue,\n { then: function () {}, status: \"rejected\", reason: error },\n requestUpdateLane()\n );\n } finally {\n (ReactDOMSharedInternals.p = previousPriority),\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n}\nfunction noop() {}\nfunction startHostTransition(formFiber, pendingState, action, formData) {\n if (5 !== formFiber.tag) throw Error(formatProdErrorMessage(476));\n var queue = ensureFormComponentIsStateful(formFiber).queue;\n startTransition(\n formFiber,\n queue,\n pendingState,\n sharedNotPendingObject,\n null === action\n ? noop\n : function () {\n requestFormReset$1(formFiber);\n return action(formData);\n }\n );\n}\nfunction ensureFormComponentIsStateful(formFiber) {\n var existingStateHook = formFiber.memoizedState;\n if (null !== existingStateHook) return existingStateHook;\n existingStateHook = {\n memoizedState: sharedNotPendingObject,\n baseState: sharedNotPendingObject,\n baseQueue: null,\n queue: {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: sharedNotPendingObject\n },\n next: null\n };\n var initialResetState = {};\n existingStateHook.next = {\n memoizedState: initialResetState,\n baseState: initialResetState,\n baseQueue: null,\n queue: {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: initialResetState\n },\n next: null\n };\n formFiber.memoizedState = existingStateHook;\n formFiber = formFiber.alternate;\n null !== formFiber && (formFiber.memoizedState = existingStateHook);\n return existingStateHook;\n}\nfunction requestFormReset$1(formFiber) {\n var stateHook = ensureFormComponentIsStateful(formFiber);\n null === stateHook.next && (stateHook = formFiber.alternate.memoizedState);\n dispatchSetStateInternal(\n formFiber,\n stateHook.next.queue,\n {},\n requestUpdateLane()\n );\n}\nfunction useHostTransitionStatus() {\n return readContext(HostTransitionContext);\n}\nfunction updateId() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction updateRefresh() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction refreshCache(fiber) {\n for (var provider = fiber.return; null !== provider; ) {\n switch (provider.tag) {\n case 24:\n case 3:\n var lane = requestUpdateLane();\n fiber = createUpdate(lane);\n var root$69 = enqueueUpdate(provider, fiber, lane);\n null !== root$69 &&\n (scheduleUpdateOnFiber(root$69, provider, lane),\n entangleTransitions(root$69, provider, lane));\n provider = { cache: createCache() };\n fiber.payload = provider;\n return;\n }\n provider = provider.return;\n }\n}\nfunction dispatchReducerAction(fiber, queue, action) {\n var lane = requestUpdateLane();\n action = {\n lane: lane,\n revertLane: 0,\n gesture: null,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n isRenderPhaseUpdate(fiber)\n ? enqueueRenderPhaseUpdate(queue, action)\n : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)),\n null !== action &&\n (scheduleUpdateOnFiber(action, fiber, lane),\n entangleTransitionUpdate(action, queue, lane)));\n}\nfunction dispatchSetState(fiber, queue, action) {\n var lane = requestUpdateLane();\n dispatchSetStateInternal(fiber, queue, action, lane);\n}\nfunction dispatchSetStateInternal(fiber, queue, action, lane) {\n var update = {\n lane: lane,\n revertLane: 0,\n gesture: null,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update);\n else {\n var alternate = fiber.alternate;\n if (\n 0 === fiber.lanes &&\n (null === alternate || 0 === alternate.lanes) &&\n ((alternate = queue.lastRenderedReducer), null !== alternate)\n )\n try {\n var currentState = queue.lastRenderedState,\n eagerState = alternate(currentState, action);\n update.hasEagerState = !0;\n update.eagerState = eagerState;\n if (objectIs(eagerState, currentState))\n return (\n enqueueUpdate$1(fiber, queue, update, 0),\n null === workInProgressRoot && finishQueueingConcurrentUpdates(),\n !1\n );\n } catch (error) {\n } finally {\n }\n action = enqueueConcurrentHookUpdate(fiber, queue, update, lane);\n if (null !== action)\n return (\n scheduleUpdateOnFiber(action, fiber, lane),\n entangleTransitionUpdate(action, queue, lane),\n !0\n );\n }\n return !1;\n}\nfunction dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) {\n action = {\n lane: 2,\n revertLane: requestTransitionLane(),\n gesture: null,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n if (isRenderPhaseUpdate(fiber)) {\n if (throwIfDuringRender) throw Error(formatProdErrorMessage(479));\n } else\n (throwIfDuringRender = enqueueConcurrentHookUpdate(\n fiber,\n queue,\n action,\n 2\n )),\n null !== throwIfDuringRender &&\n scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2);\n}\nfunction isRenderPhaseUpdate(fiber) {\n var alternate = fiber.alternate;\n return (\n fiber === currentlyRenderingFiber ||\n (null !== alternate && alternate === currentlyRenderingFiber)\n );\n}\nfunction enqueueRenderPhaseUpdate(queue, update) {\n didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate =\n !0;\n var pending = queue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n queue.pending = update;\n}\nfunction entangleTransitionUpdate(root, queue, lane) {\n if (0 !== (lane & 4194048)) {\n var queueLanes = queue.lanes;\n queueLanes &= root.pendingLanes;\n lane |= queueLanes;\n queue.lanes = lane;\n markRootEntangled(root, lane);\n }\n}\nvar ContextOnlyDispatcher = {\n readContext: readContext,\n use: use,\n useCallback: throwInvalidHookError,\n useContext: throwInvalidHookError,\n useEffect: throwInvalidHookError,\n useImperativeHandle: throwInvalidHookError,\n useLayoutEffect: throwInvalidHookError,\n useInsertionEffect: throwInvalidHookError,\n useMemo: throwInvalidHookError,\n useReducer: throwInvalidHookError,\n useRef: throwInvalidHookError,\n useState: throwInvalidHookError,\n useDebugValue: throwInvalidHookError,\n useDeferredValue: throwInvalidHookError,\n useTransition: throwInvalidHookError,\n useSyncExternalStore: throwInvalidHookError,\n useId: throwInvalidHookError,\n useHostTransitionStatus: throwInvalidHookError,\n useFormState: throwInvalidHookError,\n useActionState: throwInvalidHookError,\n useOptimistic: throwInvalidHookError,\n useMemoCache: throwInvalidHookError,\n useCacheRefresh: throwInvalidHookError\n};\nContextOnlyDispatcher.useEffectEvent = throwInvalidHookError;\nvar HooksDispatcherOnMount = {\n readContext: readContext,\n use: use,\n useCallback: function (callback, deps) {\n mountWorkInProgressHook().memoizedState = [\n callback,\n void 0 === deps ? null : deps\n ];\n return callback;\n },\n useContext: readContext,\n useEffect: mountEffect,\n useImperativeHandle: function (ref, create, deps) {\n deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;\n mountEffectImpl(\n 4194308,\n 4,\n imperativeHandleEffect.bind(null, create, ref),\n deps\n );\n },\n useLayoutEffect: function (create, deps) {\n return mountEffectImpl(4194308, 4, create, deps);\n },\n useInsertionEffect: function (create, deps) {\n mountEffectImpl(4, 2, create, deps);\n },\n useMemo: function (nextCreate, deps) {\n var hook = mountWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var nextValue = nextCreate();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n nextCreate();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n hook.memoizedState = [nextValue, deps];\n return nextValue;\n },\n useReducer: function (reducer, initialArg, init) {\n var hook = mountWorkInProgressHook();\n if (void 0 !== init) {\n var initialState = init(initialArg);\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n init(initialArg);\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n } else initialState = initialArg;\n hook.memoizedState = hook.baseState = initialState;\n reducer = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: reducer,\n lastRenderedState: initialState\n };\n hook.queue = reducer;\n reducer = reducer.dispatch = dispatchReducerAction.bind(\n null,\n currentlyRenderingFiber,\n reducer\n );\n return [hook.memoizedState, reducer];\n },\n useRef: function (initialValue) {\n var hook = mountWorkInProgressHook();\n initialValue = { current: initialValue };\n return (hook.memoizedState = initialValue);\n },\n useState: function (initialState) {\n initialState = mountStateImpl(initialState);\n var queue = initialState.queue,\n dispatch = dispatchSetState.bind(null, currentlyRenderingFiber, queue);\n queue.dispatch = dispatch;\n return [initialState.memoizedState, dispatch];\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = mountWorkInProgressHook();\n return mountDeferredValueImpl(hook, value, initialValue);\n },\n useTransition: function () {\n var stateHook = mountStateImpl(!1);\n stateHook = startTransition.bind(\n null,\n currentlyRenderingFiber,\n stateHook.queue,\n !0,\n !1\n );\n mountWorkInProgressHook().memoizedState = stateHook;\n return [!1, stateHook];\n },\n useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {\n var fiber = currentlyRenderingFiber,\n hook = mountWorkInProgressHook();\n if (isHydrating) {\n if (void 0 === getServerSnapshot)\n throw Error(formatProdErrorMessage(407));\n getServerSnapshot = getServerSnapshot();\n } else {\n getServerSnapshot = getSnapshot();\n if (null === workInProgressRoot)\n throw Error(formatProdErrorMessage(349));\n 0 !== (workInProgressRootRenderLanes & 127) ||\n pushStoreConsistencyCheck(fiber, getSnapshot, getServerSnapshot);\n }\n hook.memoizedState = getServerSnapshot;\n var inst = { value: getServerSnapshot, getSnapshot: getSnapshot };\n hook.queue = inst;\n mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [\n subscribe\n ]);\n fiber.flags |= 2048;\n pushSimpleEffect(\n 9,\n { destroy: void 0 },\n updateStoreInstance.bind(\n null,\n fiber,\n inst,\n getServerSnapshot,\n getSnapshot\n ),\n null\n );\n return getServerSnapshot;\n },\n useId: function () {\n var hook = mountWorkInProgressHook(),\n identifierPrefix = workInProgressRoot.identifierPrefix;\n if (isHydrating) {\n var JSCompiler_inline_result = treeContextOverflow;\n var idWithLeadingBit = treeContextId;\n JSCompiler_inline_result =\n (\n idWithLeadingBit & ~(1 << (32 - clz32(idWithLeadingBit) - 1))\n ).toString(32) + JSCompiler_inline_result;\n identifierPrefix =\n \"_\" + identifierPrefix + \"R_\" + JSCompiler_inline_result;\n JSCompiler_inline_result = localIdCounter++;\n 0 < JSCompiler_inline_result &&\n (identifierPrefix += \"H\" + JSCompiler_inline_result.toString(32));\n identifierPrefix += \"_\";\n } else\n (JSCompiler_inline_result = globalClientIdCounter++),\n (identifierPrefix =\n \"_\" +\n identifierPrefix +\n \"r_\" +\n JSCompiler_inline_result.toString(32) +\n \"_\");\n return (hook.memoizedState = identifierPrefix);\n },\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: mountActionState,\n useActionState: mountActionState,\n useOptimistic: function (passthrough) {\n var hook = mountWorkInProgressHook();\n hook.memoizedState = hook.baseState = passthrough;\n var queue = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: null,\n lastRenderedState: null\n };\n hook.queue = queue;\n hook = dispatchOptimisticSetState.bind(\n null,\n currentlyRenderingFiber,\n !0,\n queue\n );\n queue.dispatch = hook;\n return [passthrough, hook];\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: function () {\n return (mountWorkInProgressHook().memoizedState = refreshCache.bind(\n null,\n currentlyRenderingFiber\n ));\n },\n useEffectEvent: function (callback) {\n var hook = mountWorkInProgressHook(),\n ref = { impl: callback };\n hook.memoizedState = ref;\n return function () {\n if (0 !== (executionContext & 2))\n throw Error(formatProdErrorMessage(440));\n return ref.impl.apply(void 0, arguments);\n };\n }\n },\n HooksDispatcherOnUpdate = {\n readContext: readContext,\n use: use,\n useCallback: updateCallback,\n useContext: readContext,\n useEffect: updateEffect,\n useImperativeHandle: updateImperativeHandle,\n useInsertionEffect: updateInsertionEffect,\n useLayoutEffect: updateLayoutEffect,\n useMemo: updateMemo,\n useReducer: updateReducer,\n useRef: updateRef,\n useState: function () {\n return updateReducer(basicStateReducer);\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = updateWorkInProgressHook();\n return updateDeferredValueImpl(\n hook,\n currentHook.memoizedState,\n value,\n initialValue\n );\n },\n useTransition: function () {\n var booleanOrThenable = updateReducer(basicStateReducer)[0],\n start = updateWorkInProgressHook().memoizedState;\n return [\n \"boolean\" === typeof booleanOrThenable\n ? booleanOrThenable\n : useThenable(booleanOrThenable),\n start\n ];\n },\n useSyncExternalStore: updateSyncExternalStore,\n useId: updateId,\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: updateActionState,\n useActionState: updateActionState,\n useOptimistic: function (passthrough, reducer) {\n var hook = updateWorkInProgressHook();\n return updateOptimisticImpl(hook, currentHook, passthrough, reducer);\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: updateRefresh\n };\nHooksDispatcherOnUpdate.useEffectEvent = updateEvent;\nvar HooksDispatcherOnRerender = {\n readContext: readContext,\n use: use,\n useCallback: updateCallback,\n useContext: readContext,\n useEffect: updateEffect,\n useImperativeHandle: updateImperativeHandle,\n useInsertionEffect: updateInsertionEffect,\n useLayoutEffect: updateLayoutEffect,\n useMemo: updateMemo,\n useReducer: rerenderReducer,\n useRef: updateRef,\n useState: function () {\n return rerenderReducer(basicStateReducer);\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = updateWorkInProgressHook();\n return null === currentHook\n ? mountDeferredValueImpl(hook, value, initialValue)\n : updateDeferredValueImpl(\n hook,\n currentHook.memoizedState,\n value,\n initialValue\n );\n },\n useTransition: function () {\n var booleanOrThenable = rerenderReducer(basicStateReducer)[0],\n start = updateWorkInProgressHook().memoizedState;\n return [\n \"boolean\" === typeof booleanOrThenable\n ? booleanOrThenable\n : useThenable(booleanOrThenable),\n start\n ];\n },\n useSyncExternalStore: updateSyncExternalStore,\n useId: updateId,\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: rerenderActionState,\n useActionState: rerenderActionState,\n useOptimistic: function (passthrough, reducer) {\n var hook = updateWorkInProgressHook();\n if (null !== currentHook)\n return updateOptimisticImpl(hook, currentHook, passthrough, reducer);\n hook.baseState = passthrough;\n return [passthrough, hook.queue.dispatch];\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: updateRefresh\n};\nHooksDispatcherOnRerender.useEffectEvent = updateEvent;\nfunction applyDerivedStateFromProps(\n workInProgress,\n ctor,\n getDerivedStateFromProps,\n nextProps\n) {\n ctor = workInProgress.memoizedState;\n getDerivedStateFromProps = getDerivedStateFromProps(nextProps, ctor);\n getDerivedStateFromProps =\n null === getDerivedStateFromProps || void 0 === getDerivedStateFromProps\n ? ctor\n : assign({}, ctor, getDerivedStateFromProps);\n workInProgress.memoizedState = getDerivedStateFromProps;\n 0 === workInProgress.lanes &&\n (workInProgress.updateQueue.baseState = getDerivedStateFromProps);\n}\nvar classComponentUpdater = {\n enqueueSetState: function (inst, payload, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.payload = payload;\n void 0 !== callback && null !== callback && (update.callback = callback);\n payload = enqueueUpdate(inst, update, lane);\n null !== payload &&\n (scheduleUpdateOnFiber(payload, inst, lane),\n entangleTransitions(payload, inst, lane));\n },\n enqueueReplaceState: function (inst, payload, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.tag = 1;\n update.payload = payload;\n void 0 !== callback && null !== callback && (update.callback = callback);\n payload = enqueueUpdate(inst, update, lane);\n null !== payload &&\n (scheduleUpdateOnFiber(payload, inst, lane),\n entangleTransitions(payload, inst, lane));\n },\n enqueueForceUpdate: function (inst, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.tag = 2;\n void 0 !== callback && null !== callback && (update.callback = callback);\n callback = enqueueUpdate(inst, update, lane);\n null !== callback &&\n (scheduleUpdateOnFiber(callback, inst, lane),\n entangleTransitions(callback, inst, lane));\n }\n};\nfunction checkShouldComponentUpdate(\n workInProgress,\n ctor,\n oldProps,\n newProps,\n oldState,\n newState,\n nextContext\n) {\n workInProgress = workInProgress.stateNode;\n return \"function\" === typeof workInProgress.shouldComponentUpdate\n ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext)\n : ctor.prototype && ctor.prototype.isPureReactComponent\n ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)\n : !0;\n}\nfunction callComponentWillReceiveProps(\n workInProgress,\n instance,\n newProps,\n nextContext\n) {\n workInProgress = instance.state;\n \"function\" === typeof instance.componentWillReceiveProps &&\n instance.componentWillReceiveProps(newProps, nextContext);\n \"function\" === typeof instance.UNSAFE_componentWillReceiveProps &&\n instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);\n instance.state !== workInProgress &&\n classComponentUpdater.enqueueReplaceState(instance, instance.state, null);\n}\nfunction resolveClassComponentProps(Component, baseProps) {\n var newProps = baseProps;\n if (\"ref\" in baseProps) {\n newProps = {};\n for (var propName in baseProps)\n \"ref\" !== propName && (newProps[propName] = baseProps[propName]);\n }\n if ((Component = Component.defaultProps)) {\n newProps === baseProps && (newProps = assign({}, newProps));\n for (var propName$73 in Component)\n void 0 === newProps[propName$73] &&\n (newProps[propName$73] = Component[propName$73]);\n }\n return newProps;\n}\nfunction defaultOnUncaughtError(error) {\n reportGlobalError(error);\n}\nfunction defaultOnCaughtError(error) {\n console.error(error);\n}\nfunction defaultOnRecoverableError(error) {\n reportGlobalError(error);\n}\nfunction logUncaughtError(root, errorInfo) {\n try {\n var onUncaughtError = root.onUncaughtError;\n onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack });\n } catch (e$74) {\n setTimeout(function () {\n throw e$74;\n });\n }\n}\nfunction logCaughtError(root, boundary, errorInfo) {\n try {\n var onCaughtError = root.onCaughtError;\n onCaughtError(errorInfo.value, {\n componentStack: errorInfo.stack,\n errorBoundary: 1 === boundary.tag ? boundary.stateNode : null\n });\n } catch (e$75) {\n setTimeout(function () {\n throw e$75;\n });\n }\n}\nfunction createRootErrorUpdate(root, errorInfo, lane) {\n lane = createUpdate(lane);\n lane.tag = 3;\n lane.payload = { element: null };\n lane.callback = function () {\n logUncaughtError(root, errorInfo);\n };\n return lane;\n}\nfunction createClassErrorUpdate(lane) {\n lane = createUpdate(lane);\n lane.tag = 3;\n return lane;\n}\nfunction initializeClassErrorUpdate(update, root, fiber, errorInfo) {\n var getDerivedStateFromError = fiber.type.getDerivedStateFromError;\n if (\"function\" === typeof getDerivedStateFromError) {\n var error = errorInfo.value;\n update.payload = function () {\n return getDerivedStateFromError(error);\n };\n update.callback = function () {\n logCaughtError(root, fiber, errorInfo);\n };\n }\n var inst = fiber.stateNode;\n null !== inst &&\n \"function\" === typeof inst.componentDidCatch &&\n (update.callback = function () {\n logCaughtError(root, fiber, errorInfo);\n \"function\" !== typeof getDerivedStateFromError &&\n (null === legacyErrorBoundariesThatAlreadyFailed\n ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this]))\n : legacyErrorBoundariesThatAlreadyFailed.add(this));\n var stack = errorInfo.stack;\n this.componentDidCatch(errorInfo.value, {\n componentStack: null !== stack ? stack : \"\"\n });\n });\n}\nfunction throwException(\n root,\n returnFiber,\n sourceFiber,\n value,\n rootRenderLanes\n) {\n sourceFiber.flags |= 32768;\n if (\n null !== value &&\n \"object\" === typeof value &&\n \"function\" === typeof value.then\n ) {\n returnFiber = sourceFiber.alternate;\n null !== returnFiber &&\n propagateParentContextChanges(\n returnFiber,\n sourceFiber,\n rootRenderLanes,\n !0\n );\n sourceFiber = suspenseHandlerStackCursor.current;\n if (null !== sourceFiber) {\n switch (sourceFiber.tag) {\n case 31:\n case 13:\n return (\n null === shellBoundary\n ? renderDidSuspendDelayIfPossible()\n : null === sourceFiber.alternate &&\n 0 === workInProgressRootExitStatus &&\n (workInProgressRootExitStatus = 3),\n (sourceFiber.flags &= -257),\n (sourceFiber.flags |= 65536),\n (sourceFiber.lanes = rootRenderLanes),\n value === noopSuspenseyCommitThenable\n ? (sourceFiber.flags |= 16384)\n : ((returnFiber = sourceFiber.updateQueue),\n null === returnFiber\n ? (sourceFiber.updateQueue = new Set([value]))\n : returnFiber.add(value),\n attachPingListener(root, value, rootRenderLanes)),\n !1\n );\n case 22:\n return (\n (sourceFiber.flags |= 65536),\n value === noopSuspenseyCommitThenable\n ? (sourceFiber.flags |= 16384)\n : ((returnFiber = sourceFiber.updateQueue),\n null === returnFiber\n ? ((returnFiber = {\n transitions: null,\n markerInstances: null,\n retryQueue: new Set([value])\n }),\n (sourceFiber.updateQueue = returnFiber))\n : ((sourceFiber = returnFiber.retryQueue),\n null === sourceFiber\n ? (returnFiber.retryQueue = new Set([value]))\n : sourceFiber.add(value)),\n attachPingListener(root, value, rootRenderLanes)),\n !1\n );\n }\n throw Error(formatProdErrorMessage(435, sourceFiber.tag));\n }\n attachPingListener(root, value, rootRenderLanes);\n renderDidSuspendDelayIfPossible();\n return !1;\n }\n if (isHydrating)\n return (\n (returnFiber = suspenseHandlerStackCursor.current),\n null !== returnFiber\n ? (0 === (returnFiber.flags & 65536) && (returnFiber.flags |= 256),\n (returnFiber.flags |= 65536),\n (returnFiber.lanes = rootRenderLanes),\n value !== HydrationMismatchException &&\n ((root = Error(formatProdErrorMessage(422), { cause: value })),\n queueHydrationError(createCapturedValueAtFiber(root, sourceFiber))))\n : (value !== HydrationMismatchException &&\n ((returnFiber = Error(formatProdErrorMessage(423), {\n cause: value\n })),\n queueHydrationError(\n createCapturedValueAtFiber(returnFiber, sourceFiber)\n )),\n (root = root.current.alternate),\n (root.flags |= 65536),\n (rootRenderLanes &= -rootRenderLanes),\n (root.lanes |= rootRenderLanes),\n (value = createCapturedValueAtFiber(value, sourceFiber)),\n (rootRenderLanes = createRootErrorUpdate(\n root.stateNode,\n value,\n rootRenderLanes\n )),\n enqueueCapturedUpdate(root, rootRenderLanes),\n 4 !== workInProgressRootExitStatus &&\n (workInProgressRootExitStatus = 2)),\n !1\n );\n var wrapperError = Error(formatProdErrorMessage(520), { cause: value });\n wrapperError = createCapturedValueAtFiber(wrapperError, sourceFiber);\n null === workInProgressRootConcurrentErrors\n ? (workInProgressRootConcurrentErrors = [wrapperError])\n : workInProgressRootConcurrentErrors.push(wrapperError);\n 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2);\n if (null === returnFiber) return !0;\n value = createCapturedValueAtFiber(value, sourceFiber);\n sourceFiber = returnFiber;\n do {\n switch (sourceFiber.tag) {\n case 3:\n return (\n (sourceFiber.flags |= 65536),\n (root = rootRenderLanes & -rootRenderLanes),\n (sourceFiber.lanes |= root),\n (root = createRootErrorUpdate(sourceFiber.stateNode, value, root)),\n enqueueCapturedUpdate(sourceFiber, root),\n !1\n );\n case 1:\n if (\n ((returnFiber = sourceFiber.type),\n (wrapperError = sourceFiber.stateNode),\n 0 === (sourceFiber.flags & 128) &&\n (\"function\" === typeof returnFiber.getDerivedStateFromError ||\n (null !== wrapperError &&\n \"function\" === typeof wrapperError.componentDidCatch &&\n (null === legacyErrorBoundariesThatAlreadyFailed ||\n !legacyErrorBoundariesThatAlreadyFailed.has(wrapperError)))))\n )\n return (\n (sourceFiber.flags |= 65536),\n (rootRenderLanes &= -rootRenderLanes),\n (sourceFiber.lanes |= rootRenderLanes),\n (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)),\n initializeClassErrorUpdate(\n rootRenderLanes,\n root,\n sourceFiber,\n value\n ),\n enqueueCapturedUpdate(sourceFiber, rootRenderLanes),\n !1\n );\n }\n sourceFiber = sourceFiber.return;\n } while (null !== sourceFiber);\n return !1;\n}\nvar SelectiveHydrationException = Error(formatProdErrorMessage(461)),\n didReceiveUpdate = !1;\nfunction reconcileChildren(current, workInProgress, nextChildren, renderLanes) {\n workInProgress.child =\n null === current\n ? mountChildFibers(workInProgress, null, nextChildren, renderLanes)\n : reconcileChildFibers(\n workInProgress,\n current.child,\n nextChildren,\n renderLanes\n );\n}\nfunction updateForwardRef(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n Component = Component.render;\n var ref = workInProgress.ref;\n if (\"ref\" in nextProps) {\n var propsWithoutRef = {};\n for (var key in nextProps)\n \"ref\" !== key && (propsWithoutRef[key] = nextProps[key]);\n } else propsWithoutRef = nextProps;\n prepareToReadContext(workInProgress);\n nextProps = renderWithHooks(\n current,\n workInProgress,\n Component,\n propsWithoutRef,\n ref,\n renderLanes\n );\n key = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && key && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n return workInProgress.child;\n}\nfunction updateMemoComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n if (null === current) {\n var type = Component.type;\n if (\n \"function\" === typeof type &&\n !shouldConstruct(type) &&\n void 0 === type.defaultProps &&\n null === Component.compare\n )\n return (\n (workInProgress.tag = 15),\n (workInProgress.type = type),\n updateSimpleMemoComponent(\n current,\n workInProgress,\n type,\n nextProps,\n renderLanes\n )\n );\n current = createFiberFromTypeAndProps(\n Component.type,\n null,\n nextProps,\n workInProgress,\n workInProgress.mode,\n renderLanes\n );\n current.ref = workInProgress.ref;\n current.return = workInProgress;\n return (workInProgress.child = current);\n }\n type = current.child;\n if (!checkScheduledUpdateOrContext(current, renderLanes)) {\n var prevProps = type.memoizedProps;\n Component = Component.compare;\n Component = null !== Component ? Component : shallowEqual;\n if (Component(prevProps, nextProps) && current.ref === workInProgress.ref)\n return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);\n }\n workInProgress.flags |= 1;\n current = createWorkInProgress(type, nextProps);\n current.ref = workInProgress.ref;\n current.return = workInProgress;\n return (workInProgress.child = current);\n}\nfunction updateSimpleMemoComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n if (null !== current) {\n var prevProps = current.memoizedProps;\n if (\n shallowEqual(prevProps, nextProps) &&\n current.ref === workInProgress.ref\n )\n if (\n ((didReceiveUpdate = !1),\n (workInProgress.pendingProps = nextProps = prevProps),\n checkScheduledUpdateOrContext(current, renderLanes))\n )\n 0 !== (current.flags & 131072) && (didReceiveUpdate = !0);\n else\n return (\n (workInProgress.lanes = current.lanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n }\n return updateFunctionComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n );\n}\nfunction updateOffscreenComponent(\n current,\n workInProgress,\n renderLanes,\n nextProps\n) {\n var nextChildren = nextProps.children,\n prevState = null !== current ? current.memoizedState : null;\n null === current &&\n null === workInProgress.stateNode &&\n (workInProgress.stateNode = {\n _visibility: 1,\n _pendingMarkers: null,\n _retryCache: null,\n _transitions: null\n });\n if (\"hidden\" === nextProps.mode) {\n if (0 !== (workInProgress.flags & 128)) {\n prevState =\n null !== prevState ? prevState.baseLanes | renderLanes : renderLanes;\n if (null !== current) {\n nextProps = workInProgress.child = current.child;\n for (nextChildren = 0; null !== nextProps; )\n (nextChildren =\n nextChildren | nextProps.lanes | nextProps.childLanes),\n (nextProps = nextProps.sibling);\n nextProps = nextChildren & ~prevState;\n } else (nextProps = 0), (workInProgress.child = null);\n return deferHiddenOffscreenComponent(\n current,\n workInProgress,\n prevState,\n renderLanes,\n nextProps\n );\n }\n if (0 !== (renderLanes & 536870912))\n (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }),\n null !== current &&\n pushTransition(\n workInProgress,\n null !== prevState ? prevState.cachePool : null\n ),\n null !== prevState\n ? pushHiddenContext(workInProgress, prevState)\n : reuseHiddenContextOnStack(),\n pushOffscreenSuspenseHandler(workInProgress);\n else\n return (\n (nextProps = workInProgress.lanes = 536870912),\n deferHiddenOffscreenComponent(\n current,\n workInProgress,\n null !== prevState ? prevState.baseLanes | renderLanes : renderLanes,\n renderLanes,\n nextProps\n )\n );\n } else\n null !== prevState\n ? (pushTransition(workInProgress, prevState.cachePool),\n pushHiddenContext(workInProgress, prevState),\n reuseSuspenseHandlerOnStack(workInProgress),\n (workInProgress.memoizedState = null))\n : (null !== current && pushTransition(workInProgress, null),\n reuseHiddenContextOnStack(),\n reuseSuspenseHandlerOnStack(workInProgress));\n reconcileChildren(current, workInProgress, nextChildren, renderLanes);\n return workInProgress.child;\n}\nfunction bailoutOffscreenComponent(current, workInProgress) {\n (null !== current && 22 === current.tag) ||\n null !== workInProgress.stateNode ||\n (workInProgress.stateNode = {\n _visibility: 1,\n _pendingMarkers: null,\n _retryCache: null,\n _transitions: null\n });\n return workInProgress.sibling;\n}\nfunction deferHiddenOffscreenComponent(\n current,\n workInProgress,\n nextBaseLanes,\n renderLanes,\n remainingChildLanes\n) {\n var JSCompiler_inline_result = peekCacheFromPool();\n JSCompiler_inline_result =\n null === JSCompiler_inline_result\n ? null\n : { parent: CacheContext._currentValue, pool: JSCompiler_inline_result };\n workInProgress.memoizedState = {\n baseLanes: nextBaseLanes,\n cachePool: JSCompiler_inline_result\n };\n null !== current && pushTransition(workInProgress, null);\n reuseHiddenContextOnStack();\n pushOffscreenSuspenseHandler(workInProgress);\n null !== current &&\n propagateParentContextChanges(current, workInProgress, renderLanes, !0);\n workInProgress.childLanes = remainingChildLanes;\n return null;\n}\nfunction mountActivityChildren(workInProgress, nextProps) {\n nextProps = mountWorkInProgressOffscreenFiber(\n { mode: nextProps.mode, children: nextProps.children },\n workInProgress.mode\n );\n nextProps.ref = workInProgress.ref;\n workInProgress.child = nextProps;\n nextProps.return = workInProgress;\n return nextProps;\n}\nfunction retryActivityComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n) {\n reconcileChildFibers(workInProgress, current.child, null, renderLanes);\n current = mountActivityChildren(workInProgress, workInProgress.pendingProps);\n current.flags |= 2;\n popSuspenseHandler(workInProgress);\n workInProgress.memoizedState = null;\n return current;\n}\nfunction updateActivityComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n didSuspend = 0 !== (workInProgress.flags & 128);\n workInProgress.flags &= -129;\n if (null === current) {\n if (isHydrating) {\n if (\"hidden\" === nextProps.mode)\n return (\n (current = mountActivityChildren(workInProgress, nextProps)),\n (workInProgress.lanes = 536870912),\n bailoutOffscreenComponent(null, current)\n );\n pushDehydratedActivitySuspenseHandler(workInProgress);\n (current = nextHydratableInstance)\n ? ((current = canHydrateHydrationBoundary(\n current,\n rootOrSingletonContext\n )),\n (current = null !== current && \"&\" === current.data ? current : null),\n null !== current &&\n ((workInProgress.memoizedState = {\n dehydrated: current,\n treeContext:\n null !== treeContextProvider\n ? { id: treeContextId, overflow: treeContextOverflow }\n : null,\n retryLane: 536870912,\n hydrationErrors: null\n }),\n (renderLanes = createFiberFromDehydratedFragment(current)),\n (renderLanes.return = workInProgress),\n (workInProgress.child = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null)))\n : (current = null);\n if (null === current) throw throwOnHydrationMismatch(workInProgress);\n workInProgress.lanes = 536870912;\n return null;\n }\n return mountActivityChildren(workInProgress, nextProps);\n }\n var prevState = current.memoizedState;\n if (null !== prevState) {\n var dehydrated = prevState.dehydrated;\n pushDehydratedActivitySuspenseHandler(workInProgress);\n if (didSuspend)\n if (workInProgress.flags & 256)\n (workInProgress.flags &= -257),\n (workInProgress = retryActivityComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n ));\n else if (null !== workInProgress.memoizedState)\n (workInProgress.child = current.child),\n (workInProgress.flags |= 128),\n (workInProgress = null);\n else throw Error(formatProdErrorMessage(558));\n else if (\n (didReceiveUpdate ||\n propagateParentContextChanges(current, workInProgress, renderLanes, !1),\n (didSuspend = 0 !== (renderLanes & current.childLanes)),\n didReceiveUpdate || didSuspend)\n ) {\n nextProps = workInProgressRoot;\n if (\n null !== nextProps &&\n ((dehydrated = getBumpedLaneForHydration(nextProps, renderLanes)),\n 0 !== dehydrated && dehydrated !== prevState.retryLane)\n )\n throw (\n ((prevState.retryLane = dehydrated),\n enqueueConcurrentRenderForLane(current, dehydrated),\n scheduleUpdateOnFiber(nextProps, current, dehydrated),\n SelectiveHydrationException)\n );\n renderDidSuspendDelayIfPossible();\n workInProgress = retryActivityComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else\n (current = prevState.treeContext),\n (nextHydratableInstance = getNextHydratable(dehydrated.nextSibling)),\n (hydrationParentFiber = workInProgress),\n (isHydrating = !0),\n (hydrationErrors = null),\n (rootOrSingletonContext = !1),\n null !== current &&\n restoreSuspendedTreeContext(workInProgress, current),\n (workInProgress = mountActivityChildren(workInProgress, nextProps)),\n (workInProgress.flags |= 4096);\n return workInProgress;\n }\n current = createWorkInProgress(current.child, {\n mode: nextProps.mode,\n children: nextProps.children\n });\n current.ref = workInProgress.ref;\n workInProgress.child = current;\n current.return = workInProgress;\n return current;\n}\nfunction markRef(current, workInProgress) {\n var ref = workInProgress.ref;\n if (null === ref)\n null !== current &&\n null !== current.ref &&\n (workInProgress.flags |= 4194816);\n else {\n if (\"function\" !== typeof ref && \"object\" !== typeof ref)\n throw Error(formatProdErrorMessage(284));\n if (null === current || current.ref !== ref)\n workInProgress.flags |= 4194816;\n }\n}\nfunction updateFunctionComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n Component = renderWithHooks(\n current,\n workInProgress,\n Component,\n nextProps,\n void 0,\n renderLanes\n );\n nextProps = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && nextProps && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, Component, renderLanes);\n return workInProgress.child;\n}\nfunction replayFunctionComponent(\n current,\n workInProgress,\n nextProps,\n Component,\n secondArg,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n workInProgress.updateQueue = null;\n nextProps = renderWithHooksAgain(\n workInProgress,\n Component,\n nextProps,\n secondArg\n );\n finishRenderingHooks(current);\n Component = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && Component && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n return workInProgress.child;\n}\nfunction updateClassComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n if (null === workInProgress.stateNode) {\n var context = emptyContextObject,\n contextType = Component.contextType;\n \"object\" === typeof contextType &&\n null !== contextType &&\n (context = readContext(contextType));\n context = new Component(nextProps, context);\n workInProgress.memoizedState =\n null !== context.state && void 0 !== context.state ? context.state : null;\n context.updater = classComponentUpdater;\n workInProgress.stateNode = context;\n context._reactInternals = workInProgress;\n context = workInProgress.stateNode;\n context.props = nextProps;\n context.state = workInProgress.memoizedState;\n context.refs = {};\n initializeUpdateQueue(workInProgress);\n contextType = Component.contextType;\n context.context =\n \"object\" === typeof contextType && null !== contextType\n ? readContext(contextType)\n : emptyContextObject;\n context.state = workInProgress.memoizedState;\n contextType = Component.getDerivedStateFromProps;\n \"function\" === typeof contextType &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n contextType,\n nextProps\n ),\n (context.state = workInProgress.memoizedState));\n \"function\" === typeof Component.getDerivedStateFromProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate ||\n (\"function\" !== typeof context.UNSAFE_componentWillMount &&\n \"function\" !== typeof context.componentWillMount) ||\n ((contextType = context.state),\n \"function\" === typeof context.componentWillMount &&\n context.componentWillMount(),\n \"function\" === typeof context.UNSAFE_componentWillMount &&\n context.UNSAFE_componentWillMount(),\n contextType !== context.state &&\n classComponentUpdater.enqueueReplaceState(context, context.state, null),\n processUpdateQueue(workInProgress, nextProps, context, renderLanes),\n suspendIfUpdateReadFromEntangledAsyncAction(),\n (context.state = workInProgress.memoizedState));\n \"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308);\n nextProps = !0;\n } else if (null === current) {\n context = workInProgress.stateNode;\n var unresolvedOldProps = workInProgress.memoizedProps,\n oldProps = resolveClassComponentProps(Component, unresolvedOldProps);\n context.props = oldProps;\n var oldContext = context.context,\n contextType$jscomp$0 = Component.contextType;\n contextType = emptyContextObject;\n \"object\" === typeof contextType$jscomp$0 &&\n null !== contextType$jscomp$0 &&\n (contextType = readContext(contextType$jscomp$0));\n var getDerivedStateFromProps = Component.getDerivedStateFromProps;\n contextType$jscomp$0 =\n \"function\" === typeof getDerivedStateFromProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate;\n unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps;\n contextType$jscomp$0 ||\n (\"function\" !== typeof context.UNSAFE_componentWillReceiveProps &&\n \"function\" !== typeof context.componentWillReceiveProps) ||\n ((unresolvedOldProps || oldContext !== contextType) &&\n callComponentWillReceiveProps(\n workInProgress,\n context,\n nextProps,\n contextType\n ));\n hasForceUpdate = !1;\n var oldState = workInProgress.memoizedState;\n context.state = oldState;\n processUpdateQueue(workInProgress, nextProps, context, renderLanes);\n suspendIfUpdateReadFromEntangledAsyncAction();\n oldContext = workInProgress.memoizedState;\n unresolvedOldProps || oldState !== oldContext || hasForceUpdate\n ? (\"function\" === typeof getDerivedStateFromProps &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n getDerivedStateFromProps,\n nextProps\n ),\n (oldContext = workInProgress.memoizedState)),\n (oldProps =\n hasForceUpdate ||\n checkShouldComponentUpdate(\n workInProgress,\n Component,\n oldProps,\n nextProps,\n oldState,\n oldContext,\n contextType\n ))\n ? (contextType$jscomp$0 ||\n (\"function\" !== typeof context.UNSAFE_componentWillMount &&\n \"function\" !== typeof context.componentWillMount) ||\n (\"function\" === typeof context.componentWillMount &&\n context.componentWillMount(),\n \"function\" === typeof context.UNSAFE_componentWillMount &&\n context.UNSAFE_componentWillMount()),\n \"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308))\n : (\"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308),\n (workInProgress.memoizedProps = nextProps),\n (workInProgress.memoizedState = oldContext)),\n (context.props = nextProps),\n (context.state = oldContext),\n (context.context = contextType),\n (nextProps = oldProps))\n : (\"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308),\n (nextProps = !1));\n } else {\n context = workInProgress.stateNode;\n cloneUpdateQueue(current, workInProgress);\n contextType = workInProgress.memoizedProps;\n contextType$jscomp$0 = resolveClassComponentProps(Component, contextType);\n context.props = contextType$jscomp$0;\n getDerivedStateFromProps = workInProgress.pendingProps;\n oldState = context.context;\n oldContext = Component.contextType;\n oldProps = emptyContextObject;\n \"object\" === typeof oldContext &&\n null !== oldContext &&\n (oldProps = readContext(oldContext));\n unresolvedOldProps = Component.getDerivedStateFromProps;\n (oldContext =\n \"function\" === typeof unresolvedOldProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate) ||\n (\"function\" !== typeof context.UNSAFE_componentWillReceiveProps &&\n \"function\" !== typeof context.componentWillReceiveProps) ||\n ((contextType !== getDerivedStateFromProps || oldState !== oldProps) &&\n callComponentWillReceiveProps(\n workInProgress,\n context,\n nextProps,\n oldProps\n ));\n hasForceUpdate = !1;\n oldState = workInProgress.memoizedState;\n context.state = oldState;\n processUpdateQueue(workInProgress, nextProps, context, renderLanes);\n suspendIfUpdateReadFromEntangledAsyncAction();\n var newState = workInProgress.memoizedState;\n contextType !== getDerivedStateFromProps ||\n oldState !== newState ||\n hasForceUpdate ||\n (null !== current &&\n null !== current.dependencies &&\n checkIfContextChanged(current.dependencies))\n ? (\"function\" === typeof unresolvedOldProps &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n unresolvedOldProps,\n nextProps\n ),\n (newState = workInProgress.memoizedState)),\n (contextType$jscomp$0 =\n hasForceUpdate ||\n checkShouldComponentUpdate(\n workInProgress,\n Component,\n contextType$jscomp$0,\n nextProps,\n oldState,\n newState,\n oldProps\n ) ||\n (null !== current &&\n null !== current.dependencies &&\n checkIfContextChanged(current.dependencies)))\n ? (oldContext ||\n (\"function\" !== typeof context.UNSAFE_componentWillUpdate &&\n \"function\" !== typeof context.componentWillUpdate) ||\n (\"function\" === typeof context.componentWillUpdate &&\n context.componentWillUpdate(nextProps, newState, oldProps),\n \"function\" === typeof context.UNSAFE_componentWillUpdate &&\n context.UNSAFE_componentWillUpdate(\n nextProps,\n newState,\n oldProps\n )),\n \"function\" === typeof context.componentDidUpdate &&\n (workInProgress.flags |= 4),\n \"function\" === typeof context.getSnapshotBeforeUpdate &&\n (workInProgress.flags |= 1024))\n : (\"function\" !== typeof context.componentDidUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 4),\n \"function\" !== typeof context.getSnapshotBeforeUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 1024),\n (workInProgress.memoizedProps = nextProps),\n (workInProgress.memoizedState = newState)),\n (context.props = nextProps),\n (context.state = newState),\n (context.context = oldProps),\n (nextProps = contextType$jscomp$0))\n : (\"function\" !== typeof context.componentDidUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 4),\n \"function\" !== typeof context.getSnapshotBeforeUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 1024),\n (nextProps = !1));\n }\n context = nextProps;\n markRef(current, workInProgress);\n nextProps = 0 !== (workInProgress.flags & 128);\n context || nextProps\n ? ((context = workInProgress.stateNode),\n (Component =\n nextProps && \"function\" !== typeof Component.getDerivedStateFromError\n ? null\n : context.render()),\n (workInProgress.flags |= 1),\n null !== current && nextProps\n ? ((workInProgress.child = reconcileChildFibers(\n workInProgress,\n current.child,\n null,\n renderLanes\n )),\n (workInProgress.child = reconcileChildFibers(\n workInProgress,\n null,\n Component,\n renderLanes\n )))\n : reconcileChildren(current, workInProgress, Component, renderLanes),\n (workInProgress.memoizedState = context.state),\n (current = workInProgress.child))\n : (current = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n ));\n return current;\n}\nfunction mountHostRootWithoutHydrating(\n current,\n workInProgress,\n nextChildren,\n renderLanes\n) {\n resetHydrationState();\n workInProgress.flags |= 256;\n reconcileChildren(current, workInProgress, nextChildren, renderLanes);\n return workInProgress.child;\n}\nvar SUSPENDED_MARKER = {\n dehydrated: null,\n treeContext: null,\n retryLane: 0,\n hydrationErrors: null\n};\nfunction mountSuspenseOffscreenState(renderLanes) {\n return { baseLanes: renderLanes, cachePool: getSuspendedCache() };\n}\nfunction getRemainingWorkInPrimaryTree(\n current,\n primaryTreeDidDefer,\n renderLanes\n) {\n current = null !== current ? current.childLanes & ~renderLanes : 0;\n primaryTreeDidDefer && (current |= workInProgressDeferredLane);\n return current;\n}\nfunction updateSuspenseComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n showFallback = !1,\n didSuspend = 0 !== (workInProgress.flags & 128),\n JSCompiler_temp;\n (JSCompiler_temp = didSuspend) ||\n (JSCompiler_temp =\n null !== current && null === current.memoizedState\n ? !1\n : 0 !== (suspenseStackCursor.current & 2));\n JSCompiler_temp && ((showFallback = !0), (workInProgress.flags &= -129));\n JSCompiler_temp = 0 !== (workInProgress.flags & 32);\n workInProgress.flags &= -33;\n if (null === current) {\n if (isHydrating) {\n showFallback\n ? pushPrimaryTreeSuspenseHandler(workInProgress)\n : reuseSuspenseHandlerOnStack(workInProgress);\n (current = nextHydratableInstance)\n ? ((current = canHydrateHydrationBoundary(\n current,\n rootOrSingletonContext\n )),\n (current = null !== current && \"&\" !== current.data ? current : null),\n null !== current &&\n ((workInProgress.memoizedState = {\n dehydrated: current,\n treeContext:\n null !== treeContextProvider\n ? { id: treeContextId, overflow: treeContextOverflow }\n : null,\n retryLane: 536870912,\n hydrationErrors: null\n }),\n (renderLanes = createFiberFromDehydratedFragment(current)),\n (renderLanes.return = workInProgress),\n (workInProgress.child = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null)))\n : (current = null);\n if (null === current) throw throwOnHydrationMismatch(workInProgress);\n isSuspenseInstanceFallback(current)\n ? (workInProgress.lanes = 32)\n : (workInProgress.lanes = 536870912);\n return null;\n }\n var nextPrimaryChildren = nextProps.children;\n nextProps = nextProps.fallback;\n if (showFallback)\n return (\n reuseSuspenseHandlerOnStack(workInProgress),\n (showFallback = workInProgress.mode),\n (nextPrimaryChildren = mountWorkInProgressOffscreenFiber(\n { mode: \"hidden\", children: nextPrimaryChildren },\n showFallback\n )),\n (nextProps = createFiberFromFragment(\n nextProps,\n showFallback,\n renderLanes,\n null\n )),\n (nextPrimaryChildren.return = workInProgress),\n (nextProps.return = workInProgress),\n (nextPrimaryChildren.sibling = nextProps),\n (workInProgress.child = nextPrimaryChildren),\n (nextProps = workInProgress.child),\n (nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes)),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n bailoutOffscreenComponent(null, nextProps)\n );\n pushPrimaryTreeSuspenseHandler(workInProgress);\n return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);\n }\n var prevState = current.memoizedState;\n if (\n null !== prevState &&\n ((nextPrimaryChildren = prevState.dehydrated), null !== nextPrimaryChildren)\n ) {\n if (didSuspend)\n workInProgress.flags & 256\n ? (pushPrimaryTreeSuspenseHandler(workInProgress),\n (workInProgress.flags &= -257),\n (workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n )))\n : null !== workInProgress.memoizedState\n ? (reuseSuspenseHandlerOnStack(workInProgress),\n (workInProgress.child = current.child),\n (workInProgress.flags |= 128),\n (workInProgress = null))\n : (reuseSuspenseHandlerOnStack(workInProgress),\n (nextPrimaryChildren = nextProps.fallback),\n (showFallback = workInProgress.mode),\n (nextProps = mountWorkInProgressOffscreenFiber(\n { mode: \"visible\", children: nextProps.children },\n showFallback\n )),\n (nextPrimaryChildren = createFiberFromFragment(\n nextPrimaryChildren,\n showFallback,\n renderLanes,\n null\n )),\n (nextPrimaryChildren.flags |= 2),\n (nextProps.return = workInProgress),\n (nextPrimaryChildren.return = workInProgress),\n (nextProps.sibling = nextPrimaryChildren),\n (workInProgress.child = nextProps),\n reconcileChildFibers(\n workInProgress,\n current.child,\n null,\n renderLanes\n ),\n (nextProps = workInProgress.child),\n (nextProps.memoizedState =\n mountSuspenseOffscreenState(renderLanes)),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n (workInProgress = bailoutOffscreenComponent(null, nextProps)));\n else if (\n (pushPrimaryTreeSuspenseHandler(workInProgress),\n isSuspenseInstanceFallback(nextPrimaryChildren))\n ) {\n JSCompiler_temp =\n nextPrimaryChildren.nextSibling &&\n nextPrimaryChildren.nextSibling.dataset;\n if (JSCompiler_temp) var digest = JSCompiler_temp.dgst;\n JSCompiler_temp = digest;\n nextProps = Error(formatProdErrorMessage(419));\n nextProps.stack = \"\";\n nextProps.digest = JSCompiler_temp;\n queueHydrationError({ value: nextProps, source: null, stack: null });\n workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else if (\n (didReceiveUpdate ||\n propagateParentContextChanges(current, workInProgress, renderLanes, !1),\n (JSCompiler_temp = 0 !== (renderLanes & current.childLanes)),\n didReceiveUpdate || JSCompiler_temp)\n ) {\n JSCompiler_temp = workInProgressRoot;\n if (\n null !== JSCompiler_temp &&\n ((nextProps = getBumpedLaneForHydration(JSCompiler_temp, renderLanes)),\n 0 !== nextProps && nextProps !== prevState.retryLane)\n )\n throw (\n ((prevState.retryLane = nextProps),\n enqueueConcurrentRenderForLane(current, nextProps),\n scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps),\n SelectiveHydrationException)\n );\n isSuspenseInstancePending(nextPrimaryChildren) ||\n renderDidSuspendDelayIfPossible();\n workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else\n isSuspenseInstancePending(nextPrimaryChildren)\n ? ((workInProgress.flags |= 192),\n (workInProgress.child = current.child),\n (workInProgress = null))\n : ((current = prevState.treeContext),\n (nextHydratableInstance = getNextHydratable(\n nextPrimaryChildren.nextSibling\n )),\n (hydrationParentFiber = workInProgress),\n (isHydrating = !0),\n (hydrationErrors = null),\n (rootOrSingletonContext = !1),\n null !== current &&\n restoreSuspendedTreeContext(workInProgress, current),\n (workInProgress = mountSuspensePrimaryChildren(\n workInProgress,\n nextProps.children\n )),\n (workInProgress.flags |= 4096));\n return workInProgress;\n }\n if (showFallback)\n return (\n reuseSuspenseHandlerOnStack(workInProgress),\n (nextPrimaryChildren = nextProps.fallback),\n (showFallback = workInProgress.mode),\n (prevState = current.child),\n (digest = prevState.sibling),\n (nextProps = createWorkInProgress(prevState, {\n mode: \"hidden\",\n children: nextProps.children\n })),\n (nextProps.subtreeFlags = prevState.subtreeFlags & 65011712),\n null !== digest\n ? (nextPrimaryChildren = createWorkInProgress(\n digest,\n nextPrimaryChildren\n ))\n : ((nextPrimaryChildren = createFiberFromFragment(\n nextPrimaryChildren,\n showFallback,\n renderLanes,\n null\n )),\n (nextPrimaryChildren.flags |= 2)),\n (nextPrimaryChildren.return = workInProgress),\n (nextProps.return = workInProgress),\n (nextProps.sibling = nextPrimaryChildren),\n (workInProgress.child = nextProps),\n bailoutOffscreenComponent(null, nextProps),\n (nextProps = workInProgress.child),\n (nextPrimaryChildren = current.child.memoizedState),\n null === nextPrimaryChildren\n ? (nextPrimaryChildren = mountSuspenseOffscreenState(renderLanes))\n : ((showFallback = nextPrimaryChildren.cachePool),\n null !== showFallback\n ? ((prevState = CacheContext._currentValue),\n (showFallback =\n showFallback.parent !== prevState\n ? { parent: prevState, pool: prevState }\n : showFallback))\n : (showFallback = getSuspendedCache()),\n (nextPrimaryChildren = {\n baseLanes: nextPrimaryChildren.baseLanes | renderLanes,\n cachePool: showFallback\n })),\n (nextProps.memoizedState = nextPrimaryChildren),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n bailoutOffscreenComponent(current.child, nextProps)\n );\n pushPrimaryTreeSuspenseHandler(workInProgress);\n renderLanes = current.child;\n current = renderLanes.sibling;\n renderLanes = createWorkInProgress(renderLanes, {\n mode: \"visible\",\n children: nextProps.children\n });\n renderLanes.return = workInProgress;\n renderLanes.sibling = null;\n null !== current &&\n ((JSCompiler_temp = workInProgress.deletions),\n null === JSCompiler_temp\n ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16))\n : JSCompiler_temp.push(current));\n workInProgress.child = renderLanes;\n workInProgress.memoizedState = null;\n return renderLanes;\n}\nfunction mountSuspensePrimaryChildren(workInProgress, primaryChildren) {\n primaryChildren = mountWorkInProgressOffscreenFiber(\n { mode: \"visible\", children: primaryChildren },\n workInProgress.mode\n );\n primaryChildren.return = workInProgress;\n return (workInProgress.child = primaryChildren);\n}\nfunction mountWorkInProgressOffscreenFiber(offscreenProps, mode) {\n offscreenProps = createFiberImplClass(22, offscreenProps, null, mode);\n offscreenProps.lanes = 0;\n return offscreenProps;\n}\nfunction retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n) {\n reconcileChildFibers(workInProgress, current.child, null, renderLanes);\n current = mountSuspensePrimaryChildren(\n workInProgress,\n workInProgress.pendingProps.children\n );\n current.flags |= 2;\n workInProgress.memoizedState = null;\n return current;\n}\nfunction scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {\n fiber.lanes |= renderLanes;\n var alternate = fiber.alternate;\n null !== alternate && (alternate.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);\n}\nfunction initSuspenseListRenderState(\n workInProgress,\n isBackwards,\n tail,\n lastContentRow,\n tailMode,\n treeForkCount\n) {\n var renderState = workInProgress.memoizedState;\n null === renderState\n ? (workInProgress.memoizedState = {\n isBackwards: isBackwards,\n rendering: null,\n renderingStartTime: 0,\n last: lastContentRow,\n tail: tail,\n tailMode: tailMode,\n treeForkCount: treeForkCount\n })\n : ((renderState.isBackwards = isBackwards),\n (renderState.rendering = null),\n (renderState.renderingStartTime = 0),\n (renderState.last = lastContentRow),\n (renderState.tail = tail),\n (renderState.tailMode = tailMode),\n (renderState.treeForkCount = treeForkCount));\n}\nfunction updateSuspenseListComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n revealOrder = nextProps.revealOrder,\n tailMode = nextProps.tail;\n nextProps = nextProps.children;\n var suspenseContext = suspenseStackCursor.current,\n shouldForceFallback = 0 !== (suspenseContext & 2);\n shouldForceFallback\n ? ((suspenseContext = (suspenseContext & 1) | 2),\n (workInProgress.flags |= 128))\n : (suspenseContext &= 1);\n push(suspenseStackCursor, suspenseContext);\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n nextProps = isHydrating ? treeForkCount : 0;\n if (!shouldForceFallback && null !== current && 0 !== (current.flags & 128))\n a: for (current = workInProgress.child; null !== current; ) {\n if (13 === current.tag)\n null !== current.memoizedState &&\n scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);\n else if (19 === current.tag)\n scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);\n else if (null !== current.child) {\n current.child.return = current;\n current = current.child;\n continue;\n }\n if (current === workInProgress) break a;\n for (; null === current.sibling; ) {\n if (null === current.return || current.return === workInProgress)\n break a;\n current = current.return;\n }\n current.sibling.return = current.return;\n current = current.sibling;\n }\n switch (revealOrder) {\n case \"forwards\":\n renderLanes = workInProgress.child;\n for (revealOrder = null; null !== renderLanes; )\n (current = renderLanes.alternate),\n null !== current &&\n null === findFirstSuspended(current) &&\n (revealOrder = renderLanes),\n (renderLanes = renderLanes.sibling);\n renderLanes = revealOrder;\n null === renderLanes\n ? ((revealOrder = workInProgress.child), (workInProgress.child = null))\n : ((revealOrder = renderLanes.sibling), (renderLanes.sibling = null));\n initSuspenseListRenderState(\n workInProgress,\n !1,\n revealOrder,\n renderLanes,\n tailMode,\n nextProps\n );\n break;\n case \"backwards\":\n case \"unstable_legacy-backwards\":\n renderLanes = null;\n revealOrder = workInProgress.child;\n for (workInProgress.child = null; null !== revealOrder; ) {\n current = revealOrder.alternate;\n if (null !== current && null === findFirstSuspended(current)) {\n workInProgress.child = revealOrder;\n break;\n }\n current = revealOrder.sibling;\n revealOrder.sibling = renderLanes;\n renderLanes = revealOrder;\n revealOrder = current;\n }\n initSuspenseListRenderState(\n workInProgress,\n !0,\n renderLanes,\n null,\n tailMode,\n nextProps\n );\n break;\n case \"together\":\n initSuspenseListRenderState(\n workInProgress,\n !1,\n null,\n null,\n void 0,\n nextProps\n );\n break;\n default:\n workInProgress.memoizedState = null;\n }\n return workInProgress.child;\n}\nfunction bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {\n null !== current && (workInProgress.dependencies = current.dependencies);\n workInProgressRootSkippedLanes |= workInProgress.lanes;\n if (0 === (renderLanes & workInProgress.childLanes))\n if (null !== current) {\n if (\n (propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n !1\n ),\n 0 === (renderLanes & workInProgress.childLanes))\n )\n return null;\n } else return null;\n if (null !== current && workInProgress.child !== current.child)\n throw Error(formatProdErrorMessage(153));\n if (null !== workInProgress.child) {\n current = workInProgress.child;\n renderLanes = createWorkInProgress(current, current.pendingProps);\n workInProgress.child = renderLanes;\n for (renderLanes.return = workInProgress; null !== current.sibling; )\n (current = current.sibling),\n (renderLanes = renderLanes.sibling =\n createWorkInProgress(current, current.pendingProps)),\n (renderLanes.return = workInProgress);\n renderLanes.sibling = null;\n }\n return workInProgress.child;\n}\nfunction checkScheduledUpdateOrContext(current, renderLanes) {\n if (0 !== (current.lanes & renderLanes)) return !0;\n current = current.dependencies;\n return null !== current && checkIfContextChanged(current) ? !0 : !1;\n}\nfunction attemptEarlyBailoutIfNoScheduledUpdate(\n current,\n workInProgress,\n renderLanes\n) {\n switch (workInProgress.tag) {\n case 3:\n pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n pushProvider(workInProgress, CacheContext, current.memoizedState.cache);\n resetHydrationState();\n break;\n case 27:\n case 5:\n pushHostContext(workInProgress);\n break;\n case 4:\n pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n break;\n case 10:\n pushProvider(\n workInProgress,\n workInProgress.type,\n workInProgress.memoizedProps.value\n );\n break;\n case 31:\n if (null !== workInProgress.memoizedState)\n return (\n (workInProgress.flags |= 128),\n pushDehydratedActivitySuspenseHandler(workInProgress),\n null\n );\n break;\n case 13:\n var state$102 = workInProgress.memoizedState;\n if (null !== state$102) {\n if (null !== state$102.dehydrated)\n return (\n pushPrimaryTreeSuspenseHandler(workInProgress),\n (workInProgress.flags |= 128),\n null\n );\n if (0 !== (renderLanes & workInProgress.child.childLanes))\n return updateSuspenseComponent(current, workInProgress, renderLanes);\n pushPrimaryTreeSuspenseHandler(workInProgress);\n current = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n );\n return null !== current ? current.sibling : null;\n }\n pushPrimaryTreeSuspenseHandler(workInProgress);\n break;\n case 19:\n var didSuspendBefore = 0 !== (current.flags & 128);\n state$102 = 0 !== (renderLanes & workInProgress.childLanes);\n state$102 ||\n (propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n !1\n ),\n (state$102 = 0 !== (renderLanes & workInProgress.childLanes)));\n if (didSuspendBefore) {\n if (state$102)\n return updateSuspenseListComponent(\n current,\n workInProgress,\n renderLanes\n );\n workInProgress.flags |= 128;\n }\n didSuspendBefore = workInProgress.memoizedState;\n null !== didSuspendBefore &&\n ((didSuspendBefore.rendering = null),\n (didSuspendBefore.tail = null),\n (didSuspendBefore.lastEffect = null));\n push(suspenseStackCursor, suspenseStackCursor.current);\n if (state$102) break;\n else return null;\n case 22:\n return (\n (workInProgress.lanes = 0),\n updateOffscreenComponent(\n current,\n workInProgress,\n renderLanes,\n workInProgress.pendingProps\n )\n );\n case 24:\n pushProvider(workInProgress, CacheContext, current.memoizedState.cache);\n }\n return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);\n}\nfunction beginWork(current, workInProgress, renderLanes) {\n if (null !== current)\n if (current.memoizedProps !== workInProgress.pendingProps)\n didReceiveUpdate = !0;\n else {\n if (\n !checkScheduledUpdateOrContext(current, renderLanes) &&\n 0 === (workInProgress.flags & 128)\n )\n return (\n (didReceiveUpdate = !1),\n attemptEarlyBailoutIfNoScheduledUpdate(\n current,\n workInProgress,\n renderLanes\n )\n );\n didReceiveUpdate = 0 !== (current.flags & 131072) ? !0 : !1;\n }\n else\n (didReceiveUpdate = !1),\n isHydrating &&\n 0 !== (workInProgress.flags & 1048576) &&\n pushTreeId(workInProgress, treeForkCount, workInProgress.index);\n workInProgress.lanes = 0;\n switch (workInProgress.tag) {\n case 16:\n a: {\n var props = workInProgress.pendingProps;\n current = resolveLazy(workInProgress.elementType);\n workInProgress.type = current;\n if (\"function\" === typeof current)\n shouldConstruct(current)\n ? ((props = resolveClassComponentProps(current, props)),\n (workInProgress.tag = 1),\n (workInProgress = updateClassComponent(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n )))\n : ((workInProgress.tag = 0),\n (workInProgress = updateFunctionComponent(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n )));\n else {\n if (void 0 !== current && null !== current) {\n var $$typeof = current.$$typeof;\n if ($$typeof === REACT_FORWARD_REF_TYPE) {\n workInProgress.tag = 11;\n workInProgress = updateForwardRef(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n );\n break a;\n } else if ($$typeof === REACT_MEMO_TYPE) {\n workInProgress.tag = 14;\n workInProgress = updateMemoComponent(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n );\n break a;\n }\n }\n workInProgress = getComponentNameFromType(current) || current;\n throw Error(formatProdErrorMessage(306, workInProgress, \"\"));\n }\n }\n return workInProgress;\n case 0:\n return updateFunctionComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 1:\n return (\n (props = workInProgress.type),\n ($$typeof = resolveClassComponentProps(\n props,\n workInProgress.pendingProps\n )),\n updateClassComponent(\n current,\n workInProgress,\n props,\n $$typeof,\n renderLanes\n )\n );\n case 3:\n a: {\n pushHostContainer(\n workInProgress,\n workInProgress.stateNode.containerInfo\n );\n if (null === current) throw Error(formatProdErrorMessage(387));\n props = workInProgress.pendingProps;\n var prevState = workInProgress.memoizedState;\n $$typeof = prevState.element;\n cloneUpdateQueue(current, workInProgress);\n processUpdateQueue(workInProgress, props, null, renderLanes);\n var nextState = workInProgress.memoizedState;\n props = nextState.cache;\n pushProvider(workInProgress, CacheContext, props);\n props !== prevState.cache &&\n propagateContextChanges(\n workInProgress,\n [CacheContext],\n renderLanes,\n !0\n );\n suspendIfUpdateReadFromEntangledAsyncAction();\n props = nextState.element;\n if (prevState.isDehydrated)\n if (\n ((prevState = {\n element: props,\n isDehydrated: !1,\n cache: nextState.cache\n }),\n (workInProgress.updateQueue.baseState = prevState),\n (workInProgress.memoizedState = prevState),\n workInProgress.flags & 256)\n ) {\n workInProgress = mountHostRootWithoutHydrating(\n current,\n workInProgress,\n props,\n renderLanes\n );\n break a;\n } else if (props !== $$typeof) {\n $$typeof = createCapturedValueAtFiber(\n Error(formatProdErrorMessage(424)),\n workInProgress\n );\n queueHydrationError($$typeof);\n workInProgress = mountHostRootWithoutHydrating(\n current,\n workInProgress,\n props,\n renderLanes\n );\n break a;\n } else {\n current = workInProgress.stateNode.containerInfo;\n switch (current.nodeType) {\n case 9:\n current = current.body;\n break;\n default:\n current =\n \"HTML\" === current.nodeName\n ? current.ownerDocument.body\n : current;\n }\n nextHydratableInstance = getNextHydratable(current.firstChild);\n hydrationParentFiber = workInProgress;\n isHydrating = !0;\n hydrationErrors = null;\n rootOrSingletonContext = !0;\n renderLanes = mountChildFibers(\n workInProgress,\n null,\n props,\n renderLanes\n );\n for (workInProgress.child = renderLanes; renderLanes; )\n (renderLanes.flags = (renderLanes.flags & -3) | 4096),\n (renderLanes = renderLanes.sibling);\n }\n else {\n resetHydrationState();\n if (props === $$typeof) {\n workInProgress = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n );\n break a;\n }\n reconcileChildren(current, workInProgress, props, renderLanes);\n }\n workInProgress = workInProgress.child;\n }\n return workInProgress;\n case 26:\n return (\n markRef(current, workInProgress),\n null === current\n ? (renderLanes = getResource(\n workInProgress.type,\n null,\n workInProgress.pendingProps,\n null\n ))\n ? (workInProgress.memoizedState = renderLanes)\n : isHydrating ||\n ((renderLanes = workInProgress.type),\n (current = workInProgress.pendingProps),\n (props = getOwnerDocumentFromRootContainer(\n rootInstanceStackCursor.current\n ).createElement(renderLanes)),\n (props[internalInstanceKey] = workInProgress),\n (props[internalPropsKey] = current),\n setInitialProperties(props, renderLanes, current),\n markNodeAsHoistable(props),\n (workInProgress.stateNode = props))\n : (workInProgress.memoizedState = getResource(\n workInProgress.type,\n current.memoizedProps,\n workInProgress.pendingProps,\n current.memoizedState\n )),\n null\n );\n case 27:\n return (\n pushHostContext(workInProgress),\n null === current &&\n isHydrating &&\n ((props = workInProgress.stateNode =\n resolveSingletonInstance(\n workInProgress.type,\n workInProgress.pendingProps,\n rootInstanceStackCursor.current\n )),\n (hydrationParentFiber = workInProgress),\n (rootOrSingletonContext = !0),\n ($$typeof = nextHydratableInstance),\n isSingletonScope(workInProgress.type)\n ? ((previousHydratableOnEnteringScopedSingleton = $$typeof),\n (nextHydratableInstance = getNextHydratable(props.firstChild)))\n : (nextHydratableInstance = $$typeof)),\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n markRef(current, workInProgress),\n null === current && (workInProgress.flags |= 4194304),\n workInProgress.child\n );\n case 5:\n if (null === current && isHydrating) {\n if (($$typeof = props = nextHydratableInstance))\n (props = canHydrateInstance(\n props,\n workInProgress.type,\n workInProgress.pendingProps,\n rootOrSingletonContext\n )),\n null !== props\n ? ((workInProgress.stateNode = props),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = getNextHydratable(props.firstChild)),\n (rootOrSingletonContext = !1),\n ($$typeof = !0))\n : ($$typeof = !1);\n $$typeof || throwOnHydrationMismatch(workInProgress);\n }\n pushHostContext(workInProgress);\n $$typeof = workInProgress.type;\n prevState = workInProgress.pendingProps;\n nextState = null !== current ? current.memoizedProps : null;\n props = prevState.children;\n shouldSetTextContent($$typeof, prevState)\n ? (props = null)\n : null !== nextState &&\n shouldSetTextContent($$typeof, nextState) &&\n (workInProgress.flags |= 32);\n null !== workInProgress.memoizedState &&\n (($$typeof = renderWithHooks(\n current,\n workInProgress,\n TransitionAwareHostComponent,\n null,\n null,\n renderLanes\n )),\n (HostTransitionContext._currentValue = $$typeof));\n markRef(current, workInProgress);\n reconcileChildren(current, workInProgress, props, renderLanes);\n return workInProgress.child;\n case 6:\n if (null === current && isHydrating) {\n if ((current = renderLanes = nextHydratableInstance))\n (renderLanes = canHydrateTextInstance(\n renderLanes,\n workInProgress.pendingProps,\n rootOrSingletonContext\n )),\n null !== renderLanes\n ? ((workInProgress.stateNode = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null),\n (current = !0))\n : (current = !1);\n current || throwOnHydrationMismatch(workInProgress);\n }\n return null;\n case 13:\n return updateSuspenseComponent(current, workInProgress, renderLanes);\n case 4:\n return (\n pushHostContainer(\n workInProgress,\n workInProgress.stateNode.containerInfo\n ),\n (props = workInProgress.pendingProps),\n null === current\n ? (workInProgress.child = reconcileChildFibers(\n workInProgress,\n null,\n props,\n renderLanes\n ))\n : reconcileChildren(current, workInProgress, props, renderLanes),\n workInProgress.child\n );\n case 11:\n return updateForwardRef(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 7:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps,\n renderLanes\n ),\n workInProgress.child\n );\n case 8:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 12:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 10:\n return (\n (props = workInProgress.pendingProps),\n pushProvider(workInProgress, workInProgress.type, props.value),\n reconcileChildren(current, workInProgress, props.children, renderLanes),\n workInProgress.child\n );\n case 9:\n return (\n ($$typeof = workInProgress.type._context),\n (props = workInProgress.pendingProps.children),\n prepareToReadContext(workInProgress),\n ($$typeof = readContext($$typeof)),\n (props = props($$typeof)),\n (workInProgress.flags |= 1),\n reconcileChildren(current, workInProgress, props, renderLanes),\n workInProgress.child\n );\n case 14:\n return updateMemoComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 15:\n return updateSimpleMemoComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 19:\n return updateSuspenseListComponent(current, workInProgress, renderLanes);\n case 31:\n return updateActivityComponent(current, workInProgress, renderLanes);\n case 22:\n return updateOffscreenComponent(\n current,\n workInProgress,\n renderLanes,\n workInProgress.pendingProps\n );\n case 24:\n return (\n prepareToReadContext(workInProgress),\n (props = readContext(CacheContext)),\n null === current\n ? (($$typeof = peekCacheFromPool()),\n null === $$typeof &&\n (($$typeof = workInProgressRoot),\n (prevState = createCache()),\n ($$typeof.pooledCache = prevState),\n prevState.refCount++,\n null !== prevState && ($$typeof.pooledCacheLanes |= renderLanes),\n ($$typeof = prevState)),\n (workInProgress.memoizedState = { parent: props, cache: $$typeof }),\n initializeUpdateQueue(workInProgress),\n pushProvider(workInProgress, CacheContext, $$typeof))\n : (0 !== (current.lanes & renderLanes) &&\n (cloneUpdateQueue(current, workInProgress),\n processUpdateQueue(workInProgress, null, null, renderLanes),\n suspendIfUpdateReadFromEntangledAsyncAction()),\n ($$typeof = current.memoizedState),\n (prevState = workInProgress.memoizedState),\n $$typeof.parent !== props\n ? (($$typeof = { parent: props, cache: props }),\n (workInProgress.memoizedState = $$typeof),\n 0 === workInProgress.lanes &&\n (workInProgress.memoizedState =\n workInProgress.updateQueue.baseState =\n $$typeof),\n pushProvider(workInProgress, CacheContext, props))\n : ((props = prevState.cache),\n pushProvider(workInProgress, CacheContext, props),\n props !== $$typeof.cache &&\n propagateContextChanges(\n workInProgress,\n [CacheContext],\n renderLanes,\n !0\n ))),\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 29:\n throw workInProgress.pendingProps;\n }\n throw Error(formatProdErrorMessage(156, workInProgress.tag));\n}\nfunction markUpdate(workInProgress) {\n workInProgress.flags |= 4;\n}\nfunction preloadInstanceAndSuspendIfNeeded(\n workInProgress,\n type,\n oldProps,\n newProps,\n renderLanes\n) {\n if ((type = 0 !== (workInProgress.mode & 32))) type = !1;\n if (type) {\n if (\n ((workInProgress.flags |= 16777216),\n (renderLanes & 335544128) === renderLanes)\n )\n if (workInProgress.stateNode.complete) workInProgress.flags |= 8192;\n else if (shouldRemainOnPreviousScreen()) workInProgress.flags |= 8192;\n else\n throw (\n ((suspendedThenable = noopSuspenseyCommitThenable),\n SuspenseyCommitException)\n );\n } else workInProgress.flags &= -16777217;\n}\nfunction preloadResourceAndSuspendIfNeeded(workInProgress, resource) {\n if (\"stylesheet\" !== resource.type || 0 !== (resource.state.loading & 4))\n workInProgress.flags &= -16777217;\n else if (((workInProgress.flags |= 16777216), !preloadResource(resource)))\n if (shouldRemainOnPreviousScreen()) workInProgress.flags |= 8192;\n else\n throw (\n ((suspendedThenable = noopSuspenseyCommitThenable),\n SuspenseyCommitException)\n );\n}\nfunction scheduleRetryEffect(workInProgress, retryQueue) {\n null !== retryQueue && (workInProgress.flags |= 4);\n workInProgress.flags & 16384 &&\n ((retryQueue =\n 22 !== workInProgress.tag ? claimNextRetryLane() : 536870912),\n (workInProgress.lanes |= retryQueue),\n (workInProgressSuspendedRetryLanes |= retryQueue));\n}\nfunction cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {\n if (!isHydrating)\n switch (renderState.tailMode) {\n case \"hidden\":\n hasRenderedATailFallback = renderState.tail;\n for (var lastTailNode = null; null !== hasRenderedATailFallback; )\n null !== hasRenderedATailFallback.alternate &&\n (lastTailNode = hasRenderedATailFallback),\n (hasRenderedATailFallback = hasRenderedATailFallback.sibling);\n null === lastTailNode\n ? (renderState.tail = null)\n : (lastTailNode.sibling = null);\n break;\n case \"collapsed\":\n lastTailNode = renderState.tail;\n for (var lastTailNode$106 = null; null !== lastTailNode; )\n null !== lastTailNode.alternate && (lastTailNode$106 = lastTailNode),\n (lastTailNode = lastTailNode.sibling);\n null === lastTailNode$106\n ? hasRenderedATailFallback || null === renderState.tail\n ? (renderState.tail = null)\n : (renderState.tail.sibling = null)\n : (lastTailNode$106.sibling = null);\n }\n}\nfunction bubbleProperties(completedWork) {\n var didBailout =\n null !== completedWork.alternate &&\n completedWork.alternate.child === completedWork.child,\n newChildLanes = 0,\n subtreeFlags = 0;\n if (didBailout)\n for (var child$107 = completedWork.child; null !== child$107; )\n (newChildLanes |= child$107.lanes | child$107.childLanes),\n (subtreeFlags |= child$107.subtreeFlags & 65011712),\n (subtreeFlags |= child$107.flags & 65011712),\n (child$107.return = completedWork),\n (child$107 = child$107.sibling);\n else\n for (child$107 = completedWork.child; null !== child$107; )\n (newChildLanes |= child$107.lanes | child$107.childLanes),\n (subtreeFlags |= child$107.subtreeFlags),\n (subtreeFlags |= child$107.flags),\n (child$107.return = completedWork),\n (child$107 = child$107.sibling);\n completedWork.subtreeFlags |= subtreeFlags;\n completedWork.childLanes = newChildLanes;\n return didBailout;\n}\nfunction completeWork(current, workInProgress, renderLanes) {\n var newProps = workInProgress.pendingProps;\n popTreeContext(workInProgress);\n switch (workInProgress.tag) {\n case 16:\n case 15:\n case 0:\n case 11:\n case 7:\n case 8:\n case 12:\n case 9:\n case 14:\n return bubbleProperties(workInProgress), null;\n case 1:\n return bubbleProperties(workInProgress), null;\n case 3:\n renderLanes = workInProgress.stateNode;\n newProps = null;\n null !== current && (newProps = current.memoizedState.cache);\n workInProgress.memoizedState.cache !== newProps &&\n (workInProgress.flags |= 2048);\n popProvider(CacheContext);\n popHostContainer();\n renderLanes.pendingContext &&\n ((renderLanes.context = renderLanes.pendingContext),\n (renderLanes.pendingContext = null));\n if (null === current || null === current.child)\n popHydrationState(workInProgress)\n ? markUpdate(workInProgress)\n : null === current ||\n (current.memoizedState.isDehydrated &&\n 0 === (workInProgress.flags & 256)) ||\n ((workInProgress.flags |= 1024),\n upgradeHydrationErrorsToRecoverable());\n bubbleProperties(workInProgress);\n return null;\n case 26:\n var type = workInProgress.type,\n nextResource = workInProgress.memoizedState;\n null === current\n ? (markUpdate(workInProgress),\n null !== nextResource\n ? (bubbleProperties(workInProgress),\n preloadResourceAndSuspendIfNeeded(workInProgress, nextResource))\n : (bubbleProperties(workInProgress),\n preloadInstanceAndSuspendIfNeeded(\n workInProgress,\n type,\n null,\n newProps,\n renderLanes\n )))\n : nextResource\n ? nextResource !== current.memoizedState\n ? (markUpdate(workInProgress),\n bubbleProperties(workInProgress),\n preloadResourceAndSuspendIfNeeded(workInProgress, nextResource))\n : (bubbleProperties(workInProgress),\n (workInProgress.flags &= -16777217))\n : ((current = current.memoizedProps),\n current !== newProps && markUpdate(workInProgress),\n bubbleProperties(workInProgress),\n preloadInstanceAndSuspendIfNeeded(\n workInProgress,\n type,\n current,\n newProps,\n renderLanes\n ));\n return null;\n case 27:\n popHostContext(workInProgress);\n renderLanes = rootInstanceStackCursor.current;\n type = workInProgress.type;\n if (null !== current && null != workInProgress.stateNode)\n current.memoizedProps !== newProps && markUpdate(workInProgress);\n else {\n if (!newProps) {\n if (null === workInProgress.stateNode)\n throw Error(formatProdErrorMessage(166));\n bubbleProperties(workInProgress);\n return null;\n }\n current = contextStackCursor.current;\n popHydrationState(workInProgress)\n ? prepareToHydrateHostInstance(workInProgress, current)\n : ((current = resolveSingletonInstance(type, newProps, renderLanes)),\n (workInProgress.stateNode = current),\n markUpdate(workInProgress));\n }\n bubbleProperties(workInProgress);\n return null;\n case 5:\n popHostContext(workInProgress);\n type = workInProgress.type;\n if (null !== current && null != workInProgress.stateNode)\n current.memoizedProps !== newProps && markUpdate(workInProgress);\n else {\n if (!newProps) {\n if (null === workInProgress.stateNode)\n throw Error(formatProdErrorMessage(166));\n bubbleProperties(workInProgress);\n return null;\n }\n nextResource = contextStackCursor.current;\n if (popHydrationState(workInProgress))\n prepareToHydrateHostInstance(workInProgress, nextResource);\n else {\n var ownerDocument = getOwnerDocumentFromRootContainer(\n rootInstanceStackCursor.current\n );\n switch (nextResource) {\n case 1:\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/2000/svg\",\n type\n );\n break;\n case 2:\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/1998/Math/MathML\",\n type\n );\n break;\n default:\n switch (type) {\n case \"svg\":\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/2000/svg\",\n type\n );\n break;\n case \"math\":\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/1998/Math/MathML\",\n type\n );\n break;\n case \"script\":\n nextResource = ownerDocument.createElement(\"div\");\n nextResource.innerHTML = \" + + + + +
            + + + diff --git a/suites-experimental/chat-room/dist/resources.txt b/suites-experimental/chat-room/dist/resources.txt new file mode 100644 index 0000000000..eca8290f07 --- /dev/null +++ b/suites-experimental/chat-room/dist/resources.txt @@ -0,0 +1,4 @@ +assets/index.css +assets/index.js +assets/index.js.map +index.html From c5fec60d44282bd488dc93545fb3145c30a04b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 11 Nov 2026 18:27:46 +0100 Subject: [PATCH 14/18] Share the ChatRoom steps across suites Moves ChatRoom-React's steps into a chatRoomTests array, so other ports of the workload can be measured on identical interactions. --- suites-experimental/suites.mjs | 123 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/suites-experimental/suites.mjs b/suites-experimental/suites.mjs index 6e108c5b40..5c264f37f3 100644 --- a/suites-experimental/suites.mjs +++ b/suites-experimental/suites.mjs @@ -30,6 +30,68 @@ function yieldTask() { }); } +// Shared by every ChatRoom port, so each framework is measured on the same interactions. +const chatRoomTests = [ + // Each offset mounts a fresh set of rows, measures them, and corrects + // the scroll position against what they measured. The scroll event is + // dispatched by hand because waiting for the browser's would put a + // frame inside the measured window. + new BenchmarkTestStep("ScrollTimeline", async (page) => { + const timeline = page.querySelector("#timeline"); + const viewportHeight = timeline.clientHeight; + + const scrollTo = async (offset) => { + timeline.scrollTop = offset; + timeline.dispatchEvent("scroll"); + await yieldTask(); + page.layout(); + }; + + // A viewport at a time, from the newest message: the windows + // overlap, so rows are recycled and measured heights reused. + // Relative to the current offset rather than to scrollHeight, + // because the total height moves as rows are measured. + const pages = 10; + for (let i = 0; i < pages; i++) + await scrollTo(timeline.scrollTop - viewportHeight); + + // Then long strides, the way dragging the scrollbar does: every + // stride lands on rows that have only ever been estimated, so the + // window is replaced outright. Stops one stride short of the top, + // so it does not trip the prefetch LoadOlderMessages measures. + const strides = 10; + for (let i = strides - 1; i >= 1; i--) + await scrollTo(((timeline.scrollHeight - viewportHeight) * i) / (strides - 1)); + + // Back to the newest message, where the next step expects to start. + await scrollTo(timeline.scrollHeight); + }), + new BenchmarkTestStep("SwitchRooms", async (page) => { + const rooms = page.querySelectorAll(".room-list-item"); + const iterations = 20; + // Starts past room 0, which is already open: clicking it commits nothing. + for (let i = 1; i <= iterations; i++) { + rooms[i % rooms.length].click(); + await yieldTask(); + page.layout(); + } + }), + // Reading past the start of the loaded history inserts a page *above* + // the viewport, the case browsers ship scroll anchoring for. The + // timeline anchors by hand instead, so overflow-anchor is off. Each + // iteration also crosses the page the previous one prepended. + new BenchmarkTestStep("LoadOlderMessages", async (page) => { + const timeline = page.querySelector("#timeline"); + const pages = 5; + for (let i = 0; i < pages; i++) { + timeline.scrollTop = 0; + timeline.dispatchEvent("scroll"); + await yieldTask(); + page.layout(); + } + }), +]; + export const ExperimentalSuites = freezeSuites([ { name: "TodoMVC-LocalStorage", @@ -332,65 +394,6 @@ export const ExperimentalSuites = freezeSuites([ async prepare(page) { await page.waitForElement(".room-list-item"); }, - tests: [ - // Each offset mounts a fresh set of rows, measures them, and corrects - // the scroll position against what they measured. The scroll event is - // dispatched by hand because waiting for the browser's would put a - // frame inside the measured window. - new BenchmarkTestStep("ScrollTimeline", async (page) => { - const timeline = page.querySelector("#timeline"); - const viewportHeight = timeline.clientHeight; - - const scrollTo = async (offset) => { - timeline.scrollTop = offset; - timeline.dispatchEvent("scroll"); - await yieldTask(); - page.layout(); - }; - - // A viewport at a time, from the newest message: the windows - // overlap, so rows are recycled and measured heights reused. - // Relative to the current offset rather than to scrollHeight, - // because the total height moves as rows are measured. - const pages = 10; - for (let i = 0; i < pages; i++) - await scrollTo(timeline.scrollTop - viewportHeight); - - // Then long strides, the way dragging the scrollbar does: every - // stride lands on rows that have only ever been estimated, so the - // window is replaced outright. Stops one stride short of the top, - // so it does not trip the prefetch LoadOlderMessages measures. - const strides = 10; - for (let i = strides - 1; i >= 1; i--) - await scrollTo(((timeline.scrollHeight - viewportHeight) * i) / (strides - 1)); - - // Back to the newest message, where the next step expects to start. - await scrollTo(timeline.scrollHeight); - }), - new BenchmarkTestStep("SwitchRooms", async (page) => { - const rooms = page.querySelectorAll(".room-list-item"); - const iterations = 20; - // Starts past room 0, which is already open: clicking it commits nothing. - for (let i = 1; i <= iterations; i++) { - rooms[i % rooms.length].click(); - await yieldTask(); - page.layout(); - } - }), - // Reading past the start of the loaded history inserts a page *above* - // the viewport, the case browsers ship scroll anchoring for. The - // timeline anchors by hand instead, so overflow-anchor is off. Each - // iteration also crosses the page the previous one prepended. - new BenchmarkTestStep("LoadOlderMessages", async (page) => { - const timeline = page.querySelector("#timeline"); - const pages = 5; - for (let i = 0; i < pages; i++) { - timeline.scrollTop = 0; - timeline.dispatchEvent("scroll"); - await yieldTask(); - page.layout(); - } - }), - ], + tests: chatRoomTests, }, ]); From f7fccffe8379f03629cf72b391dac75fb5a9efa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Thu, 22 Oct 2026 19:09:24 +0200 Subject: [PATCH 15/18] Add ChatRoom-Svelte experimental workload A Svelte 5 port of ChatRoom-React that renders the same DOM from the same fixtures. --- .../chat-room-svelte/.gitignore | 19 + .../chat-room-svelte/README.md | 36 + .../chat-room-svelte/index.html | 21 + .../chat-room-svelte/package-lock.json | 1090 +++++++++++++++++ .../chat-room-svelte/package.json | 18 + .../chat-room-svelte/src/App.svelte | 27 + .../chat-room-svelte/src/actions.js | 5 + .../src/components/composer.svelte | 35 + .../src/components/message.svelte | 63 + .../src/components/reaction.svelte | 12 + .../src/components/rich-text.svelte | 58 + .../src/components/room-list-item.svelte | 13 + .../src/components/room-list.svelte | 11 + .../src/components/timeline.svelte | 249 ++++ .../chat-room-svelte/src/data/graphics.js | 66 + .../chat-room-svelte/src/data/rooms.js | 631 ++++++++++ .../chat-room-svelte/src/main.js | 5 + .../chat-room-svelte/src/row-heights.js | 126 ++ .../chat-room-svelte/src/styles.css | 497 ++++++++ .../chat-room-svelte/vite.config.js | 35 + 20 files changed, 3017 insertions(+) create mode 100644 suites-experimental/chat-room-svelte/.gitignore create mode 100644 suites-experimental/chat-room-svelte/README.md create mode 100644 suites-experimental/chat-room-svelte/index.html create mode 100644 suites-experimental/chat-room-svelte/package-lock.json create mode 100644 suites-experimental/chat-room-svelte/package.json create mode 100644 suites-experimental/chat-room-svelte/src/App.svelte create mode 100644 suites-experimental/chat-room-svelte/src/actions.js create mode 100644 suites-experimental/chat-room-svelte/src/components/composer.svelte create mode 100644 suites-experimental/chat-room-svelte/src/components/message.svelte create mode 100644 suites-experimental/chat-room-svelte/src/components/reaction.svelte create mode 100644 suites-experimental/chat-room-svelte/src/components/rich-text.svelte create mode 100644 suites-experimental/chat-room-svelte/src/components/room-list-item.svelte create mode 100644 suites-experimental/chat-room-svelte/src/components/room-list.svelte create mode 100644 suites-experimental/chat-room-svelte/src/components/timeline.svelte create mode 100644 suites-experimental/chat-room-svelte/src/data/graphics.js create mode 100644 suites-experimental/chat-room-svelte/src/data/rooms.js create mode 100644 suites-experimental/chat-room-svelte/src/main.js create mode 100644 suites-experimental/chat-room-svelte/src/row-heights.js create mode 100644 suites-experimental/chat-room-svelte/src/styles.css create mode 100644 suites-experimental/chat-room-svelte/vite.config.js diff --git a/suites-experimental/chat-room-svelte/.gitignore b/suites-experimental/chat-room-svelte/.gitignore new file mode 100644 index 0000000000..9949708729 --- /dev/null +++ b/suites-experimental/chat-room-svelte/.gitignore @@ -0,0 +1,19 @@ +node_modules + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +pnpm-debug.log* + +# dist-ssr / local +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.sw? diff --git a/suites-experimental/chat-room-svelte/README.md b/suites-experimental/chat-room-svelte/README.md new file mode 100644 index 0000000000..3cc448a64a --- /dev/null +++ b/suites-experimental/chat-room-svelte/README.md @@ -0,0 +1,36 @@ +## Description + +A Svelte 5 port of the [ChatRoom-React](../chat-room/README.md) workload: the same +two-pane chat app, the same deterministic fixtures, the same windowed timeline, +and the same measured steps, so the two can be compared directly. + +`src/data/`, `src/row-heights.js` and `src/styles.css` are copies of the React +workload's files and should be kept in sync with them. The components are +rewritten with runes, and render the same DOM as the React version, row for row +and pixel for pixel. + +## What are we testing + +The same interactions as ChatRoom-React (see its README), through Svelte's +fine-grained reactivity instead of React's reconciliation: + +- Mounting and destroying a large keyed timeline (`{#key}` on the room id) +- Keyed `{#each}` updates as the timeline window moves +- An `$effect` that measures the mounted rows after each update and corrects the + scroll position, rerunning until the measurements settle, in place of + React's `useLayoutEffect` loop + +## How are we testing + +The suite shares its steps (`ScrollTimeline`, `SwitchRooms`, +`LoadOlderMessages`) with ChatRoom-React, see `suites-experimental/suites.mjs`. + +## Developer Documentation + +The app was created with Vite + Svelte. It can be previewed during development +with `npm run dev`. To update the files run in the harness you have to run +`npm run build`, which regenerates the committed `dist/` directory. + +The built workload can be loaded within the harness at e.g. +`http://localhost:8080/?developerMode&suites=ChatRoom-Svelte`, or directly at +`http://localhost:8080/suites-experimental/chat-room-svelte/dist/index.html`. diff --git a/suites-experimental/chat-room-svelte/index.html b/suites-experimental/chat-room-svelte/index.html new file mode 100644 index 0000000000..1cdd6d8803 --- /dev/null +++ b/suites-experimental/chat-room-svelte/index.html @@ -0,0 +1,21 @@ + + + + + + ChatRoom + + + +
            + + + diff --git a/suites-experimental/chat-room-svelte/package-lock.json b/suites-experimental/chat-room-svelte/package-lock.json new file mode 100644 index 0000000000..fbc1ae31e5 --- /dev/null +++ b/suites-experimental/chat-room-svelte/package-lock.json @@ -0,0 +1,1090 @@ +{ + "name": "chat-room-svelte", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "chat-room-svelte", + "version": "0.0.0", + "dependencies": { + "svelte": "^5.57.2" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^7.3.1", + "vite": "^8.3.5" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.155.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz", + "integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz", + "integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz", + "integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz", + "integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz", + "integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz", + "integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz", + "integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz", + "integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz", + "integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz", + "integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz", + "integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz", + "integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz", + "integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz", + "integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz", + "integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz", + "integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.13.tgz", + "integrity": "sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.3.1.tgz", + "integrity": "sha512-ZPsLN8B1e/En+Ak5s4V7srFDT532oS0qieLsQwu63NGKsS+iAjoO2Js1BochlHlglcU+Pt7WAO3C5Ee+4f6gVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "deepmerge": "^4.3.1", + "magic-string": "^1.0.0", + "obug": "^2.1.0", + "vitefu": "^1.1.2" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.46.4", + "vite": "^8.0.0-beta.7 || ^8.0.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.9.4", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.4.tgz", + "integrity": "sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==", + "license": "MIT" + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.4.0.tgz", + "integrity": "sha512-CQPcneEHw/czj32uwQC52nYnax8H4SXt25FCM+LIwGZ49cMIxpOj3bP8wmzcI+Z0HIy5KkClaPhRLfCySzwHPA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz", + "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz", + "integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.20", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rolldown": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz", + "integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.155.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.15", + "@rolldown/binding-android-arm64": "1.2.15", + "@rolldown/binding-darwin-arm64": "1.2.15", + "@rolldown/binding-darwin-x64": "1.2.15", + "@rolldown/binding-freebsd-x64": "1.2.15", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.15", + "@rolldown/binding-linux-arm64-gnu": "1.2.15", + "@rolldown/binding-linux-arm64-musl": "1.2.15", + "@rolldown/binding-linux-ppc64-gnu": "1.2.15", + "@rolldown/binding-linux-s390x-gnu": "1.2.15", + "@rolldown/binding-linux-x64-gnu": "1.2.15", + "@rolldown/binding-linux-x64-musl": "1.2.15", + "@rolldown/binding-openharmony-arm64": "1.2.15", + "@rolldown/binding-win32-arm64-msvc": "1.2.15", + "@rolldown/binding-win32-x64-msvc": "1.2.15" + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.57.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.57.2.tgz", + "integrity": "sha512-1YiPCAXT0Ct6g1vOMmSLa0Nsc3QRMvtDF32ihgglGVrugIuIK38RyDiFNXVDhtQ81TJjSO57NdMw6DyYLqSGDQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "@jridgewell/sourcemap-codec": "^1.6.0", + "@sveltejs/acorn-typescript": "^1.0.13", + "@types/estree": "^1.0.9", + "acorn": "^8.18.0", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.9.2", + "esm-env": "^1.2.1", + "esrap": "^2.3.6", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/vite": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz", + "integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.30", + "rolldown": "~1.2.14", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1 || ^0.8.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.5.tgz", + "integrity": "sha512-msJxIvYDYcoNL+PJsu+7qmpDWsYmAxTY+2TNYXXF0hzBzBk0BMecOqDOG/EckUoKCuKwObfbugIl8QpqHDXeFA==", + "license": "MIT" + } + } +} diff --git a/suites-experimental/chat-room-svelte/package.json b/suites-experimental/chat-room-svelte/package.json new file mode 100644 index 0000000000..d3d6556c48 --- /dev/null +++ b/suites-experimental/chat-room-svelte/package.json @@ -0,0 +1,18 @@ +{ + "name": "chat-room-svelte", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "svelte": "^5.57.2" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^7.3.1", + "vite": "^8.3.5" + } +} diff --git a/suites-experimental/chat-room-svelte/src/App.svelte b/suites-experimental/chat-room-svelte/src/App.svelte new file mode 100644 index 0000000000..4b5991007f --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/App.svelte @@ -0,0 +1,27 @@ + + +
            + +
            +
            +

            {selectedRoom.name}

            +

            {selectedRoom.topic}

            +
            + + {#key selectedRoom.id} + + {/key} +
            +
            diff --git a/suites-experimental/chat-room-svelte/src/actions.js b/suites-experimental/chat-room-svelte/src/actions.js new file mode 100644 index 0000000000..4b9162f94d --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/actions.js @@ -0,0 +1,5 @@ +import { createContext } from "svelte"; + +// Timeline content is nested deep (Message -> RichText -> Span) and the +// innermost pills act on the app, so keep that out of the intermediate props. +export const [getActions, setActions] = createContext(); diff --git a/suites-experimental/chat-room-svelte/src/components/composer.svelte b/suites-experimental/chat-room-svelte/src/components/composer.svelte new file mode 100644 index 0000000000..9252e6377c --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/composer.svelte @@ -0,0 +1,35 @@ + + +
            + + +
            diff --git a/suites-experimental/chat-room-svelte/src/components/message.svelte b/suites-experimental/chat-room-svelte/src/components/message.svelte new file mode 100644 index 0000000000..48c824cbc6 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/message.svelte @@ -0,0 +1,63 @@ + + +
          3. + {#if dateLabel !== null} +
            + {dateLabel} +
            + {/if} + {#if unreadBelow} +
            + New +
            + {/if} +
            + {#if message.grouped} + {message.time} + {:else} + {message.senderInitials} + {/if} +
            + {#if message.replyTo} + + {/if} + {#if !message.grouped} +
            + {message.sender} + {message.time} +
            + {/if} +
            + +
            + {#if message.reactions.length > 0} +
            + {#each message.reactions as reaction (reaction.emoji)} + + {/each} +
            + {/if} +
            +
            +
          4. diff --git a/suites-experimental/chat-room-svelte/src/components/reaction.svelte b/suites-experimental/chat-room-svelte/src/components/reaction.svelte new file mode 100644 index 0000000000..13b6ab8f89 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/reaction.svelte @@ -0,0 +1,12 @@ + + + diff --git a/suites-experimental/chat-room-svelte/src/components/rich-text.svelte b/suites-experimental/chat-room-svelte/src/components/rich-text.svelte new file mode 100644 index 0000000000..92e44a0219 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/rich-text.svelte @@ -0,0 +1,58 @@ + + +{#snippet spans(items)} + {#each items as span} + {#if span.type === "code"} + {span.text} + {:else if span.type === "link"} + {span.text} + {:else if span.type === "mention"} + @{span.name} + {:else if span.type === "room"} + + {:else} + {span.text} + {/if} + {/each} +{/snippet} + +{#each blocks as block} + {#if block.type === "code"} +
            {block.lines.join("\n")}
            + {:else if block.type === "quote"} +
            {@render spans(block.spans)}
            + {:else if block.type === "image"} + + {block.alt} + {:else if block.type === "unfurl"} + + + + {block.site} + {block.title} + {block.description} + + + {:else if block.type === "list"} +
              + {#each block.items as item} +
            • {@render spans(item)}
            • + {/each} +
            + {:else} +

            {@render spans(block.spans)}

            + {/if} +{/each} diff --git a/suites-experimental/chat-room-svelte/src/components/room-list-item.svelte b/suites-experimental/chat-room-svelte/src/components/room-list-item.svelte new file mode 100644 index 0000000000..ea26abead7 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/room-list-item.svelte @@ -0,0 +1,13 @@ + + + diff --git a/suites-experimental/chat-room-svelte/src/components/room-list.svelte b/suites-experimental/chat-room-svelte/src/components/room-list.svelte new file mode 100644 index 0000000000..b92ad58d17 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/room-list.svelte @@ -0,0 +1,11 @@ + + + diff --git a/suites-experimental/chat-room-svelte/src/components/timeline.svelte b/suites-experimental/chat-room-svelte/src/components/timeline.svelte new file mode 100644 index 0000000000..c54c0a74a9 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/components/timeline.svelte @@ -0,0 +1,249 @@ + + +
              + + {#each rows as row (row.message.id)} + + {/each} + +
            + diff --git a/suites-experimental/chat-room-svelte/src/data/graphics.js b/suites-experimental/chat-room-svelte/src/data/graphics.js new file mode 100644 index 0000000000..bfe0659feb --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/data/graphics.js @@ -0,0 +1,66 @@ +// Procedurally generated SVG artwork, so the workload ships no third-party image +// assets. Data URIs are memoized per variant rather than per message, so a few +// dozen images cover the corpus and the browser can reuse a decode. + +const SHAPE_VARIANTS = 4; + +const PALETTES = [ + ["#3b82f6", "#bfdbfe"], + ["#a855f7", "#f0d9ff"], + ["#10b981", "#b7f5da"], + ["#ef4444", "#ffd5d5"], + ["#f59e0b", "#ffeab0"], + ["#06b6d4", "#b8f2fb"], + ["#6366f1", "#d5daff"], + ["#84cc16", "#e3fab3"], +]; + +// Each variant arranges flat shapes over the gradient differently, so thumbnails +// read as distinct pictures without any of them being a photo. +function shapesFor(variant, width, height) { + const w = width; + const h = height; + switch (variant) { + case 0: + return ``; + case 1: + return ``; + case 2: { + const bars = [0.35, 0.62, 0.45, 0.8, 0.55]; + return bars + .map((value, index) => { + const barWidth = (w * 0.9) / bars.length - 6; + const x = w * 0.05 + index * ((w * 0.9) / bars.length); + return ``; + }) + .join(""); + } + default: + return ``; + } +} + +const cache = new Map(); + +export function generatedImage(paletteIndex, variant, width, height) { + // Callers pass raw hashes. Reduce them before they reach the cache key or the + // gradient id, or every message gets a distinct id and its own decode. + const palette = paletteIndex % PALETTES.length; + const shape = variant % SHAPE_VARIANTS; + + const key = `${palette}-${shape}-${width}x${height}`; + const cached = cache.get(key); + if (cached) + return cached; + + const [from, to] = PALETTES[palette]; + const gradientId = `g${palette}${shape}`; + const svg = `${shapesFor( + shape, + width, + height + )}`; + const src = `data:image/svg+xml,${encodeURIComponent(svg)}`; + cache.set(key, src); + return src; +} diff --git a/suites-experimental/chat-room-svelte/src/data/rooms.js b/suites-experimental/chat-room-svelte/src/data/rooms.js new file mode 100644 index 0000000000..b7dd89d4f9 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/data/rooms.js @@ -0,0 +1,631 @@ +// Deterministic, server-free chat fixtures. Generated once at module load from an +// integer hash, with no Math.random() or Date.now(), so every run renders identical +// content -- entirely original, with no third-party assets. +// +// Bodies are structured blocks rather than plain strings, the way a client keeps +// them once markdown has been parsed. The point is non-uniform row heights. + +import { generatedImage } from "./graphics.js"; + +const ROOM_COUNT = 40; + +// Real channels hold years of history. Generation is eager at module load, so this +// trades against load time rather than against the measured steps. +const MESSAGES_PER_ROOM = 1500; + +// How many messages land on one day, as a range because a real channel does not turn +// over the same number every day. The run lengths set how often a row carries a date +// separator, and how short the newest day is decides whether a room opens on one. +const MIN_MESSAGES_PER_DAY = 8; +const MAX_MESSAGES_PER_DAY = 56; + +const ROOM_NAMES = [ + "General", + "Random", + "Announcements", + "Engineering", + "Design", + "Product", + "Support", + "Off Topic", + "Releases", + "Incidents", + "Frontend", + "Backend", + "Infra", + "Mobile", + "Performance", + "Security", + "Docs", + "Hiring", + "Watercooler", + "Standup", +]; + +const SENDERS = ["Ada Lovelace", "Alan Turing", "Grace Hopper", "Linus Pauling", "Marie Curie", "Nikola Tesla", "Rosalind Franklin", "Carl Sagan", "Katherine Johnson", "Tim Berners-Lee"]; + +export const AVATAR_COLORS = ["#368bd6", "#ac3ba8", "#03b381", "#e64f7a", "#ff812d", "#2dc2c5", "#5c56f5", "#74d12c"]; + +const AVATAR_COLOR_COUNT = AVATAR_COLORS.length; + +const WORDS = [ + "the", + "benchmark", + "switching", + "between", + "rooms", + "should", + "feel", + "instant", + "even", + "when", + "the", + "timeline", + "is", + "long", + "and", + "full", + "of", + "rich", + "messages", + "with", + "avatars", + "and", + "timestamps", + "rendering", + "performance", + "matters", + "a", + "lot", + "here", + "lets", + "measure", + "it", + "carefully", + "and", + "compare", + "across", + "browsers", + "over", + "time", +]; + +// Emoji are everywhere in a real chat. The pool mixes plain codepoints with +// variation selectors, skin tone modifiers and ZWJ sequences, so the workload +// exercises grapheme clustering as well as color-font rendering. +const INLINE_EMOJIS = ["😀", "😂", "🎉", "🔥", "❤️", "🙏", "👀", "🚀", "😅", "🤔", "💯", "✨", "🙌🏽", "👍🏻", "😍", "🥳", "😭", "🤯", "👏", "💪🏾", "🧠", "☕", "🐛", "📈", "👩‍💻", "🧑‍🚀", "👨‍👩‍👧‍👦", "🏳️‍🌈", "🤷‍♀️", "🙋‍♂️", "🫠", "🫶"]; + +const REACTION_EMOJIS = ["👍", "❤️", "😂", "🎉", "🔥", "✅", "👀", "🙏", "💯", "🚀", "😅", "🤯"]; + +// One handle per sender, so a mention always points at somebody in the room. +const MENTION_HANDLES = SENDERS.map((name) => name.split(" ")[0].toLowerCase()); + +const CODE_TOKENS = [ + "scrollTop", + "scrollHeight", + "flushSync", + "requestAnimationFrame", + "IntersectionObserver", + "overflow-anchor", + "content-visibility", + "useLayoutEffect", + "getBoundingClientRect", + "will-change", + "ResizeObserver", + "queueMicrotask", + "clientHeight", + "offsetHeight", +]; + +const LINK_LABELS = ["the trace", "last night's run", "this regression", "the profile", "the spec text", "my notes", "the dashboard", "that comparison"]; + +const LINK_PATHS = ["traces/2f9c", "runs/nightly", "profiles/hot-path", "spec/scroll-anchoring", "notes/timeline", "dashboards/perf", "reports/42", "compare/main"]; + +const UNFURL_LINKS = [ + { site: "example.com", title: "Scroll anchoring, and why feeds jump", description: "How browsers pin a scroll position while content is inserted above the viewport, and where it gives up." }, + { site: "perf.example.com", title: "Nightly run 482 vs 481", description: "Geomean moved 1.8% on the chat suites. Row measurement dominates the profile." }, + { site: "docs.example.com", title: "Windowing a variable-height list", description: "Estimate, measure, cache, correct. The four steps every hand-rolled virtualizer ends up with." }, + { site: "bugs.example.com", title: "Timeline jumps when the panel opens", description: "Narrowing the scroller re-wraps every row, so the cached heights are all stale at once." }, +]; + +const QUOTE_LINES = [ + "can we get a number on how bad the jank is before we start moving code around", + "the window only recycles about twenty rows, so the mount cost should be flat", + "every row height changes when the panel opens, which invalidates the cache", + "please do not use smooth scrolling anywhere inside a timed step", + "prepending history without pinning the anchor makes the viewport jump", +]; + +const LIST_ITEMS = [ + "estimate the row height first, then correct after measuring", + "cache measured heights per message id", + "keep the mounted window small and bounded", + "assign scroll offsets explicitly instead of animating", + "recycle rows rather than remounting them", + "break the group when a reply quote is present", + "re-measure only the rows the resize actually touched", +]; + +const CODE_SNIPPETS = [ + { lang: "js", lines: ["const scroller = scrollerRef.current;", "scroller.scrollTop = scroller.scrollHeight;"] }, + { + lang: "js", + lines: ["requestAnimationFrame(() => {", " for (const row of mounted)", " heights.set(row.id, row.offsetHeight);", "});"], + }, + { lang: "css", lines: [".timeline {", " overflow-anchor: none;", " content-visibility: auto;", "}"] }, + { lang: "sh", lines: ["npm run build", "node debugging/e2e-chatroom.mjs --browser chrome"] }, + { lang: "json", lines: ["{", ' "iterationCount": 10,', ' "suites": ["ChatRoom-React"]', "}"] }, + { lang: "js", lines: ["for (const row of rows) {", " if (!heights.has(row.id))", " heights.set(row.id, estimate);", "}"] }, + { lang: "diff", lines: ['- scroller.scrollTo({ top, behavior: "smooth" });', "+ scroller.scrollTop = top;"] }, + { lang: "js", lines: ["export function anchorToBottom(node) {", " node.scrollTop = node.scrollHeight;", "}"] }, +]; + +// An integer hash rather than a PRNG, so every field can be derived independently +// from a message seed and still be stable across runs and across engines. +// Math.imul keeps the multiplies exactly 32-bit. +function hash(seed, salt) { + let h = Math.imul(seed + 1, 2654435761) ^ Math.imul(salt + 1, 40503); + h ^= h >>> 15; + h = Math.imul(h, 2246822519); + h ^= h >>> 13; + h = Math.imul(h, 3266489917); + h ^= h >>> 16; + return h >>> 0; +} + +function pick(list, seed, salt) { + return list[hash(seed, salt) % list.length]; +} + +function initials(name) { + return name + .split(" ") + .map((part) => part[0]) + .join("") + .slice(0, 2) + .toUpperCase(); +} + +// Derived from the index alone, so a #room pill can be pointed at a real room +// while messages are still being generated. +function roomNameFor(index) { + const baseName = ROOM_NAMES[index % ROOM_NAMES.length]; + if (index < ROOM_NAMES.length) + return baseName; + return `${baseName} ${Math.floor(index / ROOM_NAMES.length) + 1}`; +} + +function roomSlugFor(index) { + return roomNameFor(index).toLowerCase().replace(/ /g, "-"); +} + +// Strided by the seed, so neighbouring messages don't get the same run. +function pickEmojis(seed, count) { + const picked = []; + for (let i = 0; i < count; i++) + picked.push(INLINE_EMOJIS[(seed * 7 + i * 13) % INLINE_EMOJIS.length]); + return picked; +} + +// Turn a token list into inline spans. Words get coalesced into text spans +// carrying the whitespace around their neighbours, which is what a markdown +// renderer ends up emitting. +function tokensToSpans(tokens) { + const spans = []; + let words = []; + let afterInline = false; + const flush = (trailingSpace) => { + if (!words.length) + return; + const leading = afterInline ? " " : ""; + const trailing = trailingSpace ? " " : ""; + spans.push({ type: "text", text: `${leading}${words.join(" ")}${trailing}` }); + words = []; + afterInline = false; + }; + for (const token of tokens) { + if (typeof token === "string") { + words.push(token); + continue; + } + flush(true); + spans.push(token); + afterInline = true; + } + flush(false); + return spans; +} + +function buildInlineSpan(seed, index, roll) { + if (roll === 0) + return { type: "code", text: pick(CODE_TOKENS, seed, index + 11) }; + if (roll === 1) + return { type: "link", text: pick(LINK_LABELS, seed, index + 12), href: `https://example.com/${pick(LINK_PATHS, seed, index + 13)}` }; + if (roll === 2) + return { type: "mention", name: pick(MENTION_HANDLES, seed, index + 14) }; + const roomIndex = hash(seed, index + 15) % ROOM_COUNT; + return { type: "room", name: roomSlugFor(roomIndex), roomId: `room-${roomIndex}` }; +} + +// A sentence from the word pool, with inline code, links, mention and room pills +// spliced between words, plus the occasional emoji. +function buildParagraph(seed, salt) { + const wordCount = 6 + (hash(seed, salt) % 22); + const start = hash(seed, salt + 1) % WORDS.length; + const tokens = []; + let lastWasInline = false; + for (let i = 0; i < wordCount; i++) { + tokens.push(WORDS[(start + i) % WORDS.length]); + const interior = i > 0 && i < wordCount - 1; + if (!interior || lastWasInline) { + lastWasInline = false; + continue; + } + const roll = hash(seed, salt * 31 + i) % 22; + if (roll < 4) { + tokens.push(buildInlineSpan(seed, i, roll)); + lastWasInline = true; + continue; + } + lastWasInline = false; + if (roll === 4) + tokens.push(INLINE_EMOJIS[hash(seed, salt + i) % INLINE_EMOJIS.length]); + } + + const spans = tokensToSpans(tokens); + const first = spans[0]; + if (first.type === "text") + first.text = first.text.charAt(0).toUpperCase() + first.text.slice(1); + + // Terminal punctuation, and a trailing emoji run on some messages. + const tail = hash(seed, salt + 7) % 4 === 0 ? `. ${pickEmojis(seed, 1 + (hash(seed, salt + 8) % 3)).join("")}` : "."; + const last = spans[spans.length - 1]; + if (last.type === "text") + last.text += tail; + else + spans.push({ type: "text", text: tail }); + return spans; +} + +function buildCodeBlock(seed) { + const snippet = pick(CODE_SNIPPETS, seed, 401); + return { type: "code", lang: snippet.lang, lines: snippet.lines }; +} + +function buildList(seed) { + const count = 2 + (hash(seed, 402) % 3); + // Walk the pool from a seeded offset, so a list never repeats a line. + const start = hash(seed, 403) % LIST_ITEMS.length; + const items = []; + for (let i = 0; i < count; i++) { + const tokens = [LIST_ITEMS[(start + i) % LIST_ITEMS.length]]; + if (hash(seed, 413 + i) % 3 === 0) + tokens.push({ type: "code", text: pick(CODE_TOKENS, seed, 423 + i) }); + items.push(tokensToSpans(tokens)); + } + return { type: "list", items }; +} + +// A few different aspect ratios, so attachments widen the row height spread +// rather than all adding the same block. +const IMAGE_SIZES = [ + { width: 260, height: 146 }, + { width: 220, height: 165 }, + { width: 180, height: 180 }, +]; + +const IMAGE_ALTS = ["a flame chart of the room switch", "the timeline mid-scroll", "row heights before and after windowing", "a screenshot of the composer", "the scroll anchoring repro"]; + +function buildImage(seed) { + const size = IMAGE_SIZES[hash(seed, 501) % IMAGE_SIZES.length]; + return { + type: "image", + src: generatedImage(hash(seed, 502), hash(seed, 503), size.width, size.height), + width: size.width, + height: size.height, + alt: pick(IMAGE_ALTS, seed, 504), + }; +} + +// Link previews, the card a client renders after unfurling a URL. +function buildUnfurl(seed) { + const link = pick(UNFURL_LINKS, seed, 601); + return { + type: "unfurl", + href: `https://example.com/${pick(LINK_PATHS, seed, 602)}`, + site: link.site, + title: link.title, + description: link.description, + thumbSrc: generatedImage(hash(seed, 603), hash(seed, 604), 72, 72), + thumbWidth: 72, + thumbHeight: 72, + }; +} + +// The shape distribution is what drives the row height spread: emoji-only +// one-liners at one end, a paragraph plus an attachment or fenced code block at +// the other. +function buildBlocks(seed) { + const shape = hash(seed, 101) % 100; + + if (shape < 8) + return [{ type: "p", spans: [{ type: "text", text: pickEmojis(seed, 2 + (hash(seed, 102) % 4)).join(" ") }] }]; + + const blocks = [{ type: "p", spans: buildParagraph(seed, 1) }]; + + if (shape < 20) { + blocks.push(buildCodeBlock(seed)); + if (shape < 13) + blocks.push({ type: "p", spans: buildParagraph(seed, 2) }); + } else if (shape < 28) { + blocks.push(buildList(seed)); + } else if (shape < 35) { + blocks.push({ type: "quote", spans: [{ type: "text", text: pick(QUOTE_LINES, seed, 103) }] }); + blocks.push({ type: "p", spans: buildParagraph(seed, 3) }); + } else if (shape < 41) { + blocks.push(buildImage(seed)); + } else if (shape < 46) { + blocks.push(buildUnfurl(seed)); + } else if (shape < 54) { + blocks.push({ type: "p", spans: buildParagraph(seed, 4) }); + } + return blocks; +} + +// Bodies are shared rather than generated one per message: a body is immutable and +// only read during render, so two messages can point at the same one. Generating +// 60,000 instead dominated this module's load time. Pool size trades load time +// against how often two rows on screen show the same body. +const BODY_POOL_SIZE = 2048; + +const BODY_POOL = []; +for (let i = 0; i < BODY_POOL_SIZE; i++) + BODY_POOL.push(buildBlocks(i)); + +// Reaction pills are all over a busy chat, so roughly two messages in three have +// at least one and popular ones collect a whole row. +function buildReactions(seed) { + if (seed % 3 === 2) + return []; + const count = 1 + (seed % 4); + const reactions = []; + for (let i = 0; i < count; i++) { + reactions.push({ + emoji: REACTION_EMOJIS[(seed + i * 5) % REACTION_EMOJIS.length], + count: 1 + ((seed + i) % 12), + }); + } + return reactions; +} + +// Every term above reduces modulo 3, 4 or 12, and REACTION_EMOJIS has twelve +// entries, so a row repeats every twelve seeds and nine distinct rows cover the +// whole corpus. Anyone changing REACTION_EMOJIS has to revisit this cycle. +const REACTION_CYCLE = 12; + +const REACTION_POOL = []; +for (let i = 0; i < REACTION_CYCLE; i++) + REACTION_POOL.push(buildReactions(i)); + +// Format a deterministic HH:MM timestamp without touching the real clock. +function formatTime(minutesInDay) { + const hours = Math.floor(minutesInDay / 60); + const minutes = minutesInDay % 60; + const pad = (value) => String(value).padStart(2, "0"); + return `${pad(hours)}:${pad(minutes)}`; +} + +// Every timestamp is one of the minutes in a day, so the 1440 strings are built +// once and shared rather than formatted per message. +const MINUTES_IN_DAY = 24 * 60; + +const TIME_STRINGS = []; +for (let minutes = 0; minutes < MINUTES_IN_DAY; minutes++) + TIME_STRINGS.push(formatTime(minutes)); + +const WEEKDAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; + +const MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + +// A synthetic calendar rather than the real one, so the workload stays +// deterministic. Sized for the shortest day a room can have, so no two days in one +// room ever share a label. +const DATE_LABELS = []; +for (let day = 0; day < Math.ceil(MESSAGES_PER_ROOM / MIN_MESSAGES_PER_DAY) + 1; day++) + DATE_LABELS.push(`${WEEKDAYS[day % WEEKDAYS.length]}, ${1 + (day % 28)} ${MONTHS[Math.floor(day / 28) % MONTHS.length]}`); + +// Real clients name the last two days rather than dating them, which is a branch +// per separator and a different string length where a room opens. +export function dateLabelFor(dayIndex, lastDayIndex) { + if (dayIndex === lastDayIndex) + return "Today"; + if (dayIndex === lastDayIndex - 1) + return "Yesterday"; + return DATE_LABELS[dayIndex % DATE_LABELS.length]; +} + +function spansToText(spans) { + let text = ""; + for (const span of spans) { + if (span.type === "mention") + text += `@${span.name}`; + else if (span.type === "room") + text += `#${span.name}`; + else + text += span.text; + } + return text; +} + +// Flatten a body to plain text for the sidebar preview and reply excerpts. +function blocksToText(blocks) { + const parts = []; + for (const block of blocks) { + if (block.type === "code") + parts.push(block.lines.join(" ")); + else if (block.type === "list") + parts.push(block.items.map(spansToText).join(" ")); + else if (block.type === "image") + parts.push(block.alt); + else if (block.type === "unfurl") + parts.push(`${block.title} ${block.site}`); + else + parts.push(spansToText(block.spans)); + } + return parts.join(" ").replace(/\s+/g, " ").trim(); +} + +function excerpt(text, limit) { + return text.length <= limit ? text : `${text.slice(0, limit).trimEnd()}…`; +} + +const REPLY_EXCERPT_LIMIT = 80; + +// Bodies are shared, so the flattened form is cached against the body rather than +// recomputed and stored for every message that might be quoted. +const BODY_EXCERPTS = new Map(); + +function bodyExcerpt(blocks) { + let text = BODY_EXCERPTS.get(blocks); + if (text === undefined) { + text = excerpt(blocksToText(blocks), REPLY_EXCERPT_LIMIT); + BODY_EXCERPTS.set(blocks, text); + } + return text; +} + +// Real conversations arrive in bursts from the same person, which is what makes +// message grouping worth rendering. Runs of one to three, always advancing to a +// different sender between runs. +function buildSenderSequence(roomIndex, count) { + const senders = []; + let index = hash(roomIndex, 301) % SENDERS.length; + while (senders.length < count) { + // Same construction as a message seed, so one room's run lengths stay + // independent of every other room's. + const seed = roomIndex * count + senders.length; + const runLength = 1 + (hash(seed, 302) % 3); + for (let i = 0; i < runLength && senders.length < count; i++) + senders.push(SENDERS[index]); + index = (index + 1 + (hash(roomIndex * count + senders.length, 303) % (SENDERS.length - 1))) % SENDERS.length; + } + return senders; +} + +const SENDER_COLOR_INDEX = new Map(SENDERS.map((name, index) => [name, index % AVATAR_COLOR_COUNT])); + +// Ten senders, so the initials are derived once rather than per message. +const SENDER_INITIALS = new Map(SENDERS.map((name) => [name, initials(name)])); + +// Which day each message falls on, as runs of varying length. Same construction as +// the sender sequence, and precomputed so a row's day never depends on what is +// mounted. +function buildDaySequence(roomIndex, count) { + const days = []; + let day = 0; + while (days.length < count) { + const span = MAX_MESSAGES_PER_DAY - MIN_MESSAGES_PER_DAY + 1; + const length = MIN_MESSAGES_PER_DAY + (hash(roomIndex * count + day, 901) % span); + for (let i = 0; i < length && days.length < count; i++) + days.push(day); + day++; + } + return days; +} + +function buildMessages(roomIndex) { + const senders = buildSenderSequence(roomIndex, MESSAGES_PER_ROOM); + const days = buildDaySequence(roomIndex, MESSAGES_PER_ROOM); + const messages = []; + for (let i = 0; i < MESSAGES_PER_ROOM; i++) { + const seed = roomIndex * MESSAGES_PER_ROOM + i; + const sender = senders[i]; + const blocks = BODY_POOL[hash(seed, 105) % BODY_POOL_SIZE]; + + // A reply quote embeds its parent in the child and breaks the sender group. + // Most answer something just said, but one in four reaches back into the + // history, where the quoted row is nowhere in the DOM and clicking the quote + // has to scroll to a height that has never been measured. + let replyTo = null; + if (i > 0 && hash(seed, 201) % 100 < 18) { + const distance = hash(seed, 203) % 4 === 0 ? 1 + (hash(seed, 204) % Math.min(i, 400)) : 1 + (hash(seed, 202) % 6); + const parent = messages[Math.max(0, i - distance)]; + replyTo = { id: parent.id, sender: parent.sender, excerpt: bodyExcerpt(parent.blocks) }; + } + + messages.push({ + id: `room-${roomIndex}-msg-${i}`, + sender, + senderInitials: SENDER_INITIALS.get(sender), + colorIndex: SENDER_COLOR_INDEX.get(sender), + time: TIME_STRINGS[seed % MINUTES_IN_DAY], + // The timeline compares this against the row above to decide whether to + // draw a date separator. + dayIndex: days[i], + blocks, + replyTo, + grouped: i > 0 && senders[i - 1] === sender && !replyTo, + reactions: REACTION_POOL[seed % REACTION_CYCLE], + }); + } + return messages; +} + +// How far back the unread divider sits when the room opens. At least one message +// back, so it is always a row that exists, and never further than a viewport, so +// every room switch lays one out -- which is also the common case in a real client. +const UNREAD_DEPTH = 12; + +function buildRooms() { + const rooms = []; + for (let i = 0; i < ROOM_COUNT; i++) { + const name = roomNameFor(i); + const messages = buildMessages(i); + rooms.push({ + id: `room-${i}`, + name, + colorIndex: i % AVATAR_COLOR_COUNT, + initials: initials(name), + topic: `Discussion about ${name.toLowerCase()}`, + lastMessage: blocksToText(messages[messages.length - 1].blocks), + // The last message this user has read. The row after it carries the + // unread divider. + readUpToIndex: Math.max(0, messages.length - 1 - (1 + (hash(i, 701) % (UNREAD_DEPTH - 1)))), + messages, + }); + } + return rooms; +} + +export const rooms = buildRooms(); + +const LOCAL_USER_NAME = "You"; + +export const LOCAL_USER = { + name: LOCAL_USER_NAME, + initials: initials(LOCAL_USER_NAME), + colorIndex: SENDERS.length % AVATAR_COLOR_COUNT, +}; + +// Same shape as the generated fixtures, so the timeline renders it through the same +// path. The timestamp continues from the room's last message instead of reading the +// clock, keeping the workload deterministic. +export function createOutgoingMessage(room, sequence, text) { + const newest = room.messages[room.messages.length - 1]; + const previous = newest.time.split(":").map(Number); + const sentAt = (previous[0] * 60 + previous[1] + 1 + sequence) % MINUTES_IN_DAY; + return { + id: `${room.id}-sent-${sequence}`, + sender: LOCAL_USER.name, + senderInitials: LOCAL_USER.initials, + colorIndex: LOCAL_USER.colorIndex, + time: TIME_STRINGS[sentAt], + // Same day as the message it follows, so sending does not put a date + // separator in the middle of the burst. + dayIndex: newest.dayIndex, + blocks: [{ type: "p", spans: [{ type: "text", text }] }], + replyTo: null, + grouped: sequence > 0, + reactions: [], + }; +} diff --git a/suites-experimental/chat-room-svelte/src/main.js b/suites-experimental/chat-room-svelte/src/main.js new file mode 100644 index 0000000000..64f3a738e9 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/main.js @@ -0,0 +1,5 @@ +import { mount } from "svelte"; +import App from "./App.svelte"; +import "./styles.css"; + +mount(App, { target: document.getElementById("root") }); diff --git a/suites-experimental/chat-room-svelte/src/row-heights.js b/suites-experimental/chat-room-svelte/src/row-heights.js new file mode 100644 index 0000000000..78b4b61173 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/row-heights.js @@ -0,0 +1,126 @@ +// The height model behind the windowed timeline: estimate, measure, cache, +// correct. Offsets are prefix sums over a mix of measured and estimated heights, +// rebuilt from the earliest row that changed, which is what turns a scroll offset +// back into a row index without touching the DOM. +// +// Hand-rolled because a chat row's height depends on how its text wraps, which a +// generic virtualizer expects to know up front. + +// A negative height means "not measured yet". 0 is reachable -- a conditionally +// collapsed row measures 0px -- and has to stay measured, or it would be +// re-measured on every pass forever. +const UNMEASURED = -1; + +export class RowHeights { + #estimate; + #count; + #heights; + #offsets; + + // The oldest loaded row. The model covers [#first, #count); older rows + // contribute no height because they are not in the timeline yet. + #first; + + // Earliest row whose offset needs recomputing: changing row i only moves the + // rows after it. #count + 1 means everything is up to date. + #dirtyFrom; + + constructor(count, first, estimate) { + this.#estimate = estimate; + this.#count = count; + this.#first = first; + this.#heights = new Float64Array(count).fill(UNMEASURED); + this.#offsets = new Float64Array(count + 1); + this.#dirtyFrom = first; + } + + get count() { + return this.#count; + } + + get first() { + return this.#first; + } + + // Load older history. Measured heights stay valid because a row keeps its + // index: the offsets all shift by the height of the rows that were added, + // which is what lets the scroll position be corrected exactly. + extendTo(first) { + if (first >= this.#first) + return; + this.#first = first; + this.#dirtyFrom = first; + } + + // A room only ever grows at the end, when the local user sends, so every + // measured height and every offset up to the old end survives. + grow(count) { + if (count <= this.#count) + return; + + const heights = new Float64Array(count); + heights.set(this.#heights); + heights.fill(UNMEASURED, this.#count); + const offsets = new Float64Array(count + 1); + offsets.set(this.#offsets); + + this.#dirtyFrom = Math.min(this.#dirtyFrom, this.#count); + this.#heights = heights; + this.#offsets = offsets; + this.#count = count; + } + + heightAt(index) { + const height = this.#heights[index]; + return height === UNMEASURED ? this.#estimate : height; + } + + // Returns whether the cached height moved, so a caller that read offsets + // before the pass knows they are now stale. + measure(index, height) { + if (this.#heights[index] === height) + return false; + this.#heights[index] = height; + if (index < this.#dirtyFrom) + this.#dirtyFrom = index; + return true; + } + + offsetAt(index) { + this.#recomputeOffsets(); + return this.#offsets[index]; + } + + get totalHeight() { + this.#recomputeOffsets(); + return this.#offsets[this.#count]; + } + + // The row containing a content offset, clamped at both ends. + indexAt(offset) { + this.#recomputeOffsets(); + const offsets = this.#offsets; + let low = this.#first; + let high = this.#count - 1; + while (low < high) { + const middle = (low + high + 1) >> 1; + if (offsets[middle] <= offset) + low = middle; + else + high = middle - 1; + } + return Math.max(this.#first, low); + } + + #recomputeOffsets() { + if (this.#dirtyFrom > this.#count) + return; + const offsets = this.#offsets; + // Offsets run from the oldest loaded row, which is the origin the + // scroller's own coordinates line up with. + offsets[this.#first] = 0; + for (let i = this.#dirtyFrom; i < this.#count; i++) + offsets[i + 1] = offsets[i] + this.heightAt(i); + this.#dirtyFrom = this.#count + 1; + } +} diff --git a/suites-experimental/chat-room-svelte/src/styles.css b/suites-experimental/chat-room-svelte/src/styles.css new file mode 100644 index 0000000000..590d7ba3c0 --- /dev/null +++ b/suites-experimental/chat-room-svelte/src/styles.css @@ -0,0 +1,497 @@ +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + height: 100%; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + color: #17191c; + background-color: #f4f6fa; +} + +#root { + height: 100vh; +} + +.app { + display: grid; + grid-template-columns: 300px 1fr; + height: 100vh; + overflow: hidden; +} + +/* Avatars are CSS-drawn circles, so the workload ships no image assets. */ +.avatar { + display: inline-flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + width: 36px; + height: 36px; + border-radius: 50%; + color: #fff; + font-size: 13px; + font-weight: 600; + text-transform: uppercase; +} + +/* Room list (sidebar) */ +.room-list { + display: flex; + flex-direction: column; + overflow-y: auto; + border-right: 1px solid #e3e8ef; + background-color: #fff; +} + +.room-list-item { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 14px; + border: 0; + border-bottom: 1px solid #f0f2f5; + background: transparent; + text-align: left; + cursor: pointer; + font: inherit; + color: inherit; +} + +.room-list-item:hover { + background-color: #f4f6fa; +} + +.room-list-item-selected { + background-color: #e8f0fe; +} + +.room-list-item-text { + display: flex; + flex-direction: column; + min-width: 0; +} + +.room-list-item-name { + font-weight: 600; + font-size: 15px; +} + +.room-list-item-preview { + font-size: 13px; + color: #737d8c; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Room (main panel) */ +.room { + display: flex; + flex-direction: column; + min-width: 0; + height: 100vh; +} + +.room-header { + padding: 14px 20px; + border-bottom: 1px solid #e3e8ef; + background-color: #fff; +} + +.room-header-name { + margin: 0; + font-size: 18px; +} + +.room-header-topic { + margin: 4px 0 0; + font-size: 13px; + color: #737d8c; +} + +/* Composer. Sits below the timeline, so the scroller gives up the height it takes. */ +.composer { + display: flex; + flex: 0 0 auto; + gap: 8px; + padding: 12px 20px; + border-top: 1px solid #e3e8ef; + background-color: #fff; +} + +.composer-input { + flex: 1 1 auto; + min-width: 0; + padding: 8px 12px; + border: 1px solid #d5dbe5; + border-radius: 8px; + font: inherit; + font-size: 14px; + color: inherit; +} + +.composer-input:focus { + border-color: #9dc0f5; + outline: 2px solid #dce8fb; + outline-offset: -1px; +} + +.composer-send { + flex: 0 0 auto; + padding: 8px 16px; + border: 0; + border-radius: 8px; + background-color: #2a6fd6; + font: inherit; + font-size: 14px; + font-weight: 600; + color: #fff; + cursor: pointer; +} + +.composer-send:hover:enabled { + background-color: #245fb8; +} + +.composer-send:disabled { + background-color: #c8d1de; + cursor: default; +} + +/* Timeline. No vertical padding, so scrollTop maps one to one onto the height + model's row offsets. overflow-anchor is off because the timeline corrects its own + scroll position after measuring, and the browser would apply a second correction + for the same content change. */ +.timeline { + flex: 1 1 auto; + margin: 0; + padding: 0 20px; + list-style: none; + overflow-y: auto; + overflow-anchor: none; +} + +/* A row is a column: the separators stack above the message's own flex row. */ +.timeline-message { + padding: 6px 0; +} + +.timeline-message-row { + display: flex; + gap: 12px; +} + +/* Grouped messages drop the avatar and name; the gutter keeps the body aligned + and carries the timestamp on hover, the way real clients do. */ +.timeline-message-grouped { + padding: 1px 0; +} + +.timeline-message-gutter { + flex: 0 0 auto; + width: 36px; + font-size: 11px; + color: #939aa5; + text-align: right; + opacity: 0; +} + +.timeline-message-grouped:hover .timeline-message-gutter { + opacity: 1; +} + +/* Date separator: a centred label between two rules, drawn with pseudo-element + borders so it costs a real layout box either side. */ +.timeline-date-separator { + display: flex; + align-items: center; + gap: 8px; + margin: 10px 0 6px; +} + +.timeline-date-separator::before, +.timeline-date-separator::after { + content: ""; + flex: 1 1 auto; + border-top: 1px solid #e3e6ea; +} + +.timeline-date-separator-label { + flex: 0 0 auto; + padding: 2px 10px; + border: 1px solid #e3e6ea; + border-radius: 10px; + background-color: #fff; + color: #6b7280; + font-size: 11px; + font-weight: 600; +} + +/* The unread divider sits above the first message the reader has not seen. */ +.timeline-unread-divider { + display: flex; + align-items: center; + gap: 8px; + margin: 8px 0 4px; + border-top: 1px solid #e2564a; +} + +.timeline-unread-divider-label { + margin-left: auto; + padding: 1px 8px; + border-radius: 0 0 8px 8px; + background-color: #e2564a; + color: #fff; + font-size: 10px; + font-weight: 700; + text-transform: uppercase; +} + +.timeline-message-body { + min-width: 0; + flex: 1 1 auto; +} + +/* The jump target of a reply click. Background only: changing the box would + invalidate measured row heights. */ +.timeline-message-highlighted { + background-color: #fff6d8; +} + +/* Inline reply quote: a button, because clicking it jumps to the parent. */ +.timeline-message-reply { + display: flex; + gap: 6px; + align-items: baseline; + width: 100%; + margin-bottom: 2px; + padding: 0 0 0 8px; + border: 0; + border-left: 2px solid #d5dbe5; + background: transparent; + font: inherit; + font-size: 12px; + color: #737d8c; + text-align: left; + cursor: pointer; +} + +.timeline-message-reply:hover { + border-left-color: #9dc0f5; + color: #5a6472; +} + +.timeline-message-reply-sender { + flex: 0 0 auto; + font-weight: 600; + color: #5a6472; +} + +.timeline-message-reply-excerpt { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.timeline-message-meta { + display: flex; + align-items: baseline; + gap: 8px; +} + +.timeline-message-sender { + font-weight: 600; + font-size: 14px; +} + +.timeline-message-time { + font-size: 12px; + color: #939aa5; +} + +.timeline-message-text { + margin-top: 2px; + font-size: 14px; + line-height: 1.4; + color: #2c3038; +} + +/* Rich message content */ +.rich-paragraph { + margin: 0 0 4px; +} + +.rich-paragraph:last-child { + margin-bottom: 0; +} + +.rich-code { + padding: 1px 4px; + border: 1px solid #e3e8ef; + border-radius: 4px; + background-color: #f4f6fa; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 0.9em; + color: #b4295c; +} + +.rich-code-block { + margin: 4px 0; + padding: 8px 10px; + overflow-x: auto; + border: 1px solid #e3e8ef; + border-radius: 6px; + background-color: #f8fafc; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 12px; + line-height: 1.45; + white-space: pre; +} + +/* Attachments and link previews. The artwork is procedurally generated SVG. */ +.rich-image { + display: block; + max-width: 100%; + height: auto; + margin: 6px 0; + border: 1px solid #e3e8ef; + border-radius: 8px; +} + +.rich-unfurl { + display: flex; + gap: 10px; + max-width: 460px; + margin: 6px 0; + padding: 10px; + border: 1px solid #e3e8ef; + border-left: 3px solid #9dc0f5; + border-radius: 8px; + background-color: #fbfcfe; + color: inherit; + text-decoration: none; +} + +.rich-unfurl:hover { + background-color: #f4f8ff; +} + +.rich-unfurl-thumb { + flex: 0 0 auto; + border-radius: 6px; +} + +.rich-unfurl-body { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; +} + +.rich-unfurl-site { + font-size: 11px; + font-weight: 600; + color: #737d8c; + text-transform: uppercase; + letter-spacing: 0.02em; +} + +.rich-unfurl-title { + font-weight: 600; + color: #24509b; +} + +.rich-unfurl-description { + font-size: 13px; + color: #5a6472; +} + +.rich-quote { + margin: 4px 0; + padding: 2px 0 2px 10px; + border-left: 3px solid #c8d1de; + color: #5a6472; +} + +.rich-list { + margin: 4px 0; + padding-left: 20px; +} + +.rich-link { + color: #2a6fd6; + text-decoration: underline; +} + +.rich-pill { + padding: 0 5px; + border: 0; + border-radius: 10px; + font: inherit; + font-weight: 500; + white-space: nowrap; +} + +.rich-pill-mention { + background-color: #e2ecfd; + color: #24509b; +} + +/* A #room pill is a button: clicking it switches to that room. */ +.rich-pill-room { + background-color: #e6f6ee; + color: #1c6e4c; + cursor: pointer; +} + +.rich-pill-room:hover { + background-color: #d3efe1; +} + +/* Reactions */ +.timeline-message-reactions { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 4px; +} + +/* Reaction pills are real toggle buttons. */ +.reaction { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 1px 8px; + border: 1px solid #e3e8ef; + border-radius: 12px; + background-color: #f4f6fa; + font: inherit; + font-size: 12px; + color: inherit; + cursor: pointer; +} + +.reaction:hover { + border-color: #c8d1de; + background-color: #eaeef5; +} + +.reaction-mine { + border-color: #9dc0f5; + background-color: #e2ecfd; +} + +.reaction-mine .reaction-count { + color: #24509b; + font-weight: 600; +} + +.reaction-count { + color: #737d8c; +} diff --git a/suites-experimental/chat-room-svelte/vite.config.js b/suites-experimental/chat-room-svelte/vite.config.js new file mode 100644 index 0000000000..dcded847dd --- /dev/null +++ b/suites-experimental/chat-room-svelte/vite.config.js @@ -0,0 +1,35 @@ +import { resolve } from "path"; +import { defineConfig } from "vite"; +import { svelte } from "@sveltejs/vite-plugin-svelte"; +import { generateResourcesFile } from "../../resources/shared/generate-resources.mjs"; + +// The suite entry declares a resources.txt, which tests/unittests/suites.mjs +// validates, so emit it once the bundle is on disk. +function resourcesManifest() { + return { + name: "chat-room-svelte-resources-manifest", + closeBundle() { + generateResourcesFile(resolve(import.meta.dirname, "dist")); + }, + }; +} + +export default defineConfig({ + // Since this will be loaded from the project root. + base: "./", + plugins: [svelte(), resourcesManifest()], + build: { + modulePreload: { polyfill: false }, + sourcemap: true, + rollupOptions: { + input: { + index: resolve(import.meta.dirname, "index.html"), + }, + output: { + entryFileNames: "assets/[name].js", + chunkFileNames: "assets/[name].js", + assetFileNames: "assets/[name].[ext]", + }, + }, + }, +}); From b779775066e90fe653f564d282a404db955f63f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Thu, 22 Oct 2026 19:09:24 +0200 Subject: [PATCH 16/18] Build and enable the ChatRoom-Svelte workload --- .../chat-room-svelte/dist/assets/index.css | 1 + .../chat-room-svelte/dist/assets/index.js | 4 ++++ .../chat-room-svelte/dist/assets/index.js.map | 1 + .../chat-room-svelte/dist/index.html | 22 +++++++++++++++++++ .../chat-room-svelte/dist/resources.txt | 4 ++++ suites-experimental/suites.mjs | 11 ++++++++++ 6 files changed, 43 insertions(+) create mode 100644 suites-experimental/chat-room-svelte/dist/assets/index.css create mode 100644 suites-experimental/chat-room-svelte/dist/assets/index.js create mode 100644 suites-experimental/chat-room-svelte/dist/assets/index.js.map create mode 100644 suites-experimental/chat-room-svelte/dist/index.html create mode 100644 suites-experimental/chat-room-svelte/dist/resources.txt diff --git a/suites-experimental/chat-room-svelte/dist/assets/index.css b/suites-experimental/chat-room-svelte/dist/assets/index.css new file mode 100644 index 0000000000..b4994384ce --- /dev/null +++ b/suites-experimental/chat-room-svelte/dist/assets/index.css @@ -0,0 +1 @@ +*{box-sizing:border-box}html,body{height:100%;margin:0}body{color:#17191c;background-color:#f4f6fa;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif}#root{height:100vh}.app{grid-template-columns:300px 1fr;height:100vh;display:grid;overflow:hidden}.avatar{color:#fff;text-transform:uppercase;border-radius:50%;flex:none;justify-content:center;align-items:center;width:36px;height:36px;font-size:13px;font-weight:600;display:inline-flex}.room-list{background-color:#fff;border-right:1px solid #e3e8ef;flex-direction:column;display:flex;overflow-y:auto}.room-list-item{text-align:left;cursor:pointer;font:inherit;color:inherit;background:0 0;border:0;border-bottom:1px solid #f0f2f5;align-items:center;gap:12px;padding:10px 14px;display:flex}.room-list-item:hover{background-color:#f4f6fa}.room-list-item-selected{background-color:#e8f0fe}.room-list-item-text{flex-direction:column;min-width:0;display:flex}.room-list-item-name{font-size:15px;font-weight:600}.room-list-item-preview{color:#737d8c;white-space:nowrap;text-overflow:ellipsis;font-size:13px;overflow:hidden}.room{flex-direction:column;min-width:0;height:100vh;display:flex}.room-header{background-color:#fff;border-bottom:1px solid #e3e8ef;padding:14px 20px}.room-header-name{margin:0;font-size:18px}.room-header-topic{color:#737d8c;margin:4px 0 0;font-size:13px}.composer{background-color:#fff;border-top:1px solid #e3e8ef;flex:none;gap:8px;padding:12px 20px;display:flex}.composer-input{min-width:0;font:inherit;color:inherit;border:1px solid #d5dbe5;border-radius:8px;flex:auto;padding:8px 12px;font-size:14px}.composer-input:focus{outline-offset:-1px;border-color:#9dc0f5;outline:2px solid #dce8fb}.composer-send{font:inherit;color:#fff;cursor:pointer;background-color:#2a6fd6;border:0;border-radius:8px;flex:none;padding:8px 16px;font-size:14px;font-weight:600}.composer-send:hover:enabled{background-color:#245fb8}.composer-send:disabled{cursor:default;background-color:#c8d1de}.timeline{overflow-anchor:none;flex:auto;margin:0;padding:0 20px;list-style:none;overflow-y:auto}.timeline-message{padding:6px 0}.timeline-message-row{gap:12px;display:flex}.timeline-message-grouped{padding:1px 0}.timeline-message-gutter{color:#939aa5;text-align:right;opacity:0;flex:none;width:36px;font-size:11px}.timeline-message-grouped:hover .timeline-message-gutter{opacity:1}.timeline-date-separator{align-items:center;gap:8px;margin:10px 0 6px;display:flex}.timeline-date-separator:before,.timeline-date-separator:after{content:"";border-top:1px solid #e3e6ea;flex:auto}.timeline-date-separator-label{color:#6b7280;background-color:#fff;border:1px solid #e3e6ea;border-radius:10px;flex:none;padding:2px 10px;font-size:11px;font-weight:600}.timeline-unread-divider{border-top:1px solid #e2564a;align-items:center;gap:8px;margin:8px 0 4px;display:flex}.timeline-unread-divider-label{color:#fff;text-transform:uppercase;background-color:#e2564a;border-radius:0 0 8px 8px;margin-left:auto;padding:1px 8px;font-size:10px;font-weight:700}.timeline-message-body{flex:auto;min-width:0}.timeline-message-highlighted{background-color:#fff6d8}.timeline-message-reply{width:100%;font:inherit;color:#737d8c;text-align:left;cursor:pointer;background:0 0;border:0;border-left:2px solid #d5dbe5;align-items:baseline;gap:6px;margin-bottom:2px;padding:0 0 0 8px;font-size:12px;display:flex}.timeline-message-reply:hover{color:#5a6472;border-left-color:#9dc0f5}.timeline-message-reply-sender{color:#5a6472;flex:none;font-weight:600}.timeline-message-reply-excerpt{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.timeline-message-meta{align-items:baseline;gap:8px;display:flex}.timeline-message-sender{font-size:14px;font-weight:600}.timeline-message-time{color:#939aa5;font-size:12px}.timeline-message-text{color:#2c3038;margin-top:2px;font-size:14px;line-height:1.4}.rich-paragraph{margin:0 0 4px}.rich-paragraph:last-child{margin-bottom:0}.rich-code{color:#b4295c;background-color:#f4f6fa;border:1px solid #e3e8ef;border-radius:4px;padding:1px 4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9em}.rich-code-block{white-space:pre;background-color:#f8fafc;border:1px solid #e3e8ef;border-radius:6px;margin:4px 0;padding:8px 10px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.45;overflow-x:auto}.rich-image{border:1px solid #e3e8ef;border-radius:8px;max-width:100%;height:auto;margin:6px 0;display:block}.rich-unfurl{max-width:460px;color:inherit;background-color:#fbfcfe;border:1px solid #e3e8ef;border-left:3px solid #9dc0f5;border-radius:8px;gap:10px;margin:6px 0;padding:10px;text-decoration:none;display:flex}.rich-unfurl:hover{background-color:#f4f8ff}.rich-unfurl-thumb{border-radius:6px;flex:none}.rich-unfurl-body{flex-direction:column;gap:2px;min-width:0;display:flex}.rich-unfurl-site{color:#737d8c;text-transform:uppercase;letter-spacing:.02em;font-size:11px;font-weight:600}.rich-unfurl-title{color:#24509b;font-weight:600}.rich-unfurl-description{color:#5a6472;font-size:13px}.rich-quote{color:#5a6472;border-left:3px solid #c8d1de;margin:4px 0;padding:2px 0 2px 10px}.rich-list{margin:4px 0;padding-left:20px}.rich-link{color:#2a6fd6;text-decoration:underline}.rich-pill{font:inherit;white-space:nowrap;border:0;border-radius:10px;padding:0 5px;font-weight:500}.rich-pill-mention{color:#24509b;background-color:#e2ecfd}.rich-pill-room{color:#1c6e4c;cursor:pointer;background-color:#e6f6ee}.rich-pill-room:hover{background-color:#d3efe1}.timeline-message-reactions{flex-wrap:wrap;gap:6px;margin-top:4px;display:flex}.reaction{font:inherit;color:inherit;cursor:pointer;background-color:#f4f6fa;border:1px solid #e3e8ef;border-radius:12px;align-items:center;gap:4px;padding:1px 8px;font-size:12px;display:inline-flex}.reaction:hover{background-color:#eaeef5;border-color:#c8d1de}.reaction-mine{background-color:#e2ecfd;border-color:#9dc0f5}.reaction-mine .reaction-count{color:#24509b;font-weight:600}.reaction-count{color:#737d8c} diff --git a/suites-experimental/chat-room-svelte/dist/assets/index.js b/suites-experimental/chat-room-svelte/dist/assets/index.js new file mode 100644 index 0000000000..b2f008b1b0 --- /dev/null +++ b/suites-experimental/chat-room-svelte/dist/assets/index.js @@ -0,0 +1,4 @@ +var e=Array.isArray,t=Array.prototype.indexOf,n=Array.prototype.includes,r=Array.from,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyDescriptors,s=Object.prototype,c=Array.prototype,l=Object.getPrototypeOf,u=Object.isExtensible,d=()=>{};function f(e){for(var t=0;t{e=n,t=r}),resolve:e,reject:t}}var m=1024,h=2048,g=4096,_=8192,v=16384,y=32768,b=1<<25,x=65536,S=1<<19,ee=1<<20,te=1<<25,ne=1<<21,re=1<<22,ie=1<<23,ae=Symbol(`$state`),oe=Symbol(`component`),se=Symbol(``),ce=Symbol(`attributes`),le=Symbol(`class`),ue=Symbol(`style`),de=Symbol(`text`),fe=Symbol(`form reset`),pe=new class extends Error{name=`StaleReactionError`;message="The reaction that called `getAbortSignal()` was re-run or destroyed"},me=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`),he={},C=Symbol(`uninitialized`),ge=`http://www.w3.org/1999/xhtml`;function _e(){console.warn(`https://svelte.dev/e/derived_inert`)}function ve(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function ye(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var w=!1;function be(e){w=e}var T;function E(e){if(e===null)throw ve(),he;return T=e}function xe(){return E(on(T))}function D(e){if(w){if(on(T)!==null)throw ve(),he;T=e}}function Se(e=1){if(w){for(var t=e,n=T;t--;)n=on(n);T=n}}function Ce(e=!0){for(var t=0,n=T;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else(r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=on(n);e&&n.remove(),n=i}}function we(e){if(!e||e.nodeType!==8)throw ve(),he;return e.data}function Te(e){return e===this.v}function Ee(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function De(e){return!Ee(e,this.v)}function Oe(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function ke(){throw Error(`https://svelte.dev/e/missing_context`)}function Ae(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function je(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Me(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function Ne(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Pe(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Fe(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function Ie(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Le(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function Re(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function ze(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}function Be(e,t,n){let r={};return[()=>(n(r)||ke(),e(r)),e=>t(r,e),()=>n(r)]}function Ve(e){let t=e.p;for(;t!==null&&t.c===null;)t=t.p;return t?.c??null}function He(e,t){return e===null&&Oe(t),e.c??=new Map(Ve(e)||void 0)}var O=null;function Ue(e){O=e}function We(){return Be(Ge,Ke,qe)}function Ge(e){return He(O,`getContext`).get(e)}function Ke(e,t){return He(O,`setContext`).set(e,t),t}function qe(e){return He(O,`hasContext`).has(e)}function Je(e,t=!1,n){O={p:O,i:!1,c:null,e:null,s:e,x:null,r:W,l:null}}function Ye(e){var t=O,n=t.e;if(n!==null){t.e=null;for(var r of n)bn(r)}return e!==void 0&&(t.x=e),t.i=!0,O=t.p,Xe(e)}function Xe(e={}){return i(e,oe,{value:!0}),e}function Ze(){return!0}var Qe=[];function $e(){var e=Qe;Qe=[],f(e)}function et(e){if(Qe.length===0&&!Et){var t=Qe;queueMicrotask(()=>{t===Qe&&$e()})}Qe.push(e)}function tt(){for(;Qe.length>0;)$e()}var nt=~(h|g|m);function k(e,t){e.f=e.f&nt|t}function rt(e){e.f&512||e.deps===null?k(e,m):k(e,g)}function it(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),k(e,m)}var at=!1;function ot(){at||(at=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[fe]?.()})},{capture:!0}))}function st(e){var t=V,n=W;U(null),zn(null);try{return e()}finally{U(t),zn(n)}}function ct(e,t,n,r=n){e.addEventListener(t,()=>st(n));let i=e[fe];e[fe]=i?()=>{i(),r(!0)}:()=>r(!0),ot()}function lt(e,t,n,r){let i=Ze()?pt:_t;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=W,c=ut(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){pn(e,s)}dt()}}var d=ft();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>ht(e))).then(u).catch(e=>pn(e,s)).finally(d)}l?l.then(()=>{s.f&16384?d():(c(),f(),dt())}):f()}function ut(){var e=W,t=V,n=O,r=A;return function(i=!0){zn(e),U(t),Ue(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function dt(e=!0){zn(null),U(null),Ue(null),e&&A?.deactivate()}function ft(){var e=W,t=e.b,n=A,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function pt(e){var t=2|h;return W!==null&&(W.f|=S),{ctx:O,deps:null,effects:null,equals:Te,f:t,fn:e,reactions:null,rv:0,v:C,wv:0,parent:W,ac:null}}var mt=Symbol(`obsolete`);function ht(e,t,n){let r=W;r===null&&Ae();var i=void 0,a=Ut(C),o=!V,s=new Set;return Cn(()=>{var t=W,n=p();i=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==pe&&n.reject(e)}).finally(dt)}catch(e){n.reject(e),dt()}var c=A;if(o){if(t.f&32768)var l=ft();if(r.b?.is_rendered())c.async_deriveds.get(t)?.reject(mt);else for(let e of s.values())e.reject(mt);s.add(n),c.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),s.delete(n),t!==mt&&(c.activate(),t?(a.f|=ie,qt(a,t)):(a.f&8388608&&(a.f^=ie),qt(a,e)),c.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),vn(()=>{for(let e of s)e.reject(mt)}),new Promise(e=>{function t(n){function r(){n===i?e(a):t(i)}n.then(r,r)}t(i)})}function gt(e){let t=pt(e);return Vn(t),t}function _t(e){let t=pt(e);return t.equals=De,t}function vt(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n{t.ac.abort(pe),t.ac=null}),t.fn!==null&&(t.teardown=d),$n(t,0),Dn(t))}function St(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&er(t)}var Ct=null,A=null,wt=null,j=null,Tt=null,Et=!1,Dt=!1,Ot=null,kt=null,At=0,jt=1,Mt=class e{id=jt++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){Ct===null?Ct=this:(Ct.#n=this,this.#t=Ct),Ct=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)k(r,h),t(r);for(r of n.m)k(r,g),t(r)}this.#p.add(e)}#g(){var e=[];for(let i of this.#c)if(!(i.f&16384||!(i.f&6144))){for(var t=i,n=!1;t.parent!==null;){t=t.parent;var r=t.f;if(r&96){if(!(r&1024)){n=!0;break}t.f^=m}}n||e.push(t)}return this.#c=[],e}#_(){this.#e=!0;for(let e of this.#u)this.#d.delete(e),k(e,h),this.schedule(e);for(let e of this.#d)k(e,g),this.schedule(e);this.apply();for(var t=Ot=[],n=[],r=kt=[];this.#c.length>0;){At++>1e3&&(this.#S(),Pt());for(let e of this.#g())try{this.#v(e,t,n)}catch(t){throw zt(e),this.#h()||this.discard(),t}}if(A=null,r.length>0){var i=e.ensure();for(let e of r)i.schedule(e)}if(Ot=null,kt=null,this.#h()){this.#x(n),this.#x(t);for(let[e,t]of this.#f)Rt(e,t);r.length>0&&A.#_();return}let a=this.#y();if(a)this.#x(n),this.#x(t),a.#b(this);else{this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),wt=this,It(n),It(t),wt=null,this.#s?.resolve();var o=A;if(this.#a===0&&(this.#c.length===0||o!==null)&&this.#S(),this.#c.length>0){if(o!==null){for(let e of this.#c)o.#c.push(e);this.#c=[]}else o=this}o!==null&&(Vt.clear(),o.#_())}}#v(e,t,n){e.f^=m;for(var r=e.first;r!==null;){var i=r.f,a=!!(i&96);if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=m:i&4?t.push(r):Jn(r)&&(i&16&&this.#d.add(r),er(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#y(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#b(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null&&!(e.f&2&&!(e.f&6144)))for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),k(i,h),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),A=this,this.#_()}#x(e){for(var t=0;t{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=p()).promise}static ensure(){if(A===null){let t=A=new e;!Dt&&!Et&&et(()=>{t.#e||t.flush()})}return A}apply(){j=null}schedule(e){Tt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)?e.b.defer_effect(e):this.#c.push(e)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null||(e.#n=t),t===null?Ct=e:t.#t=e,this.linked=!1}}};function Nt(e){var t=Et,n=wt;wt=null,Et=!0;try{var r;for(e&&(Nt(),r=e());;){if(tt(),A===null)return r;A.flush()}}finally{Et=t,wt=n}}function Pt(){try{Fe()}catch(e){pn(e,Tt)}}var Ft=null;function It(e){var t=e.length;if(t!==0){for(var n=0;n0)){Vt.clear();for(let e of Ft){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Ft.has(n)&&(Ft.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||er(n)}}Ft.clear()}}Ft=null}}function Lt(e){A.schedule(e)}function Rt(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),k(e,m);for(var n=e.first;n!==null;)Rt(n,t),n=n.next}}function zt(e){k(e,m);for(var t=e.first;t!==null;)zt(t),t=t.next}var Bt=new Set,Vt=new Map,Ht=!1;function Ut(e,t){return{f:0,v:e,reactions:null,equals:Te,rv:0,wv:0}}function M(e,t){let n=Ut(e,t);return Vn(n),n}function Wt(e,t=!1,n=!0){let r=Ut(e);return t||(r.equals=De),r}function N(e,t,n=!1){return V!==null&&(!H||V.f&131072)&&Ze()&&V.f&4325394&&(Bn===null||!Bn.has(e))&&Re(),qt(e,n?Qt(t):t,kt)}var Gt=null,Kt=0;function qt(e,t,n=null){if(!e.equals(t)){Ln?Vt.set(e,t):Vt.has(e)||Vt.set(e,e.v);var r=Mt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&yt(t),j===null&&rt(t)}e.wv=qn(),Gt=null,Kt=0,Zt(e,h,n),Gt=null,Ze()&&W!==null&&W.f&1024&&!(W.f&96)&&(q===null?Hn([e]):q.push(e)),!r.is_fork&&Bt.size>0&&!Ht&&Jt()}return t}function Jt(){Ht=!1;for(let e of Bt){e.f&1024&&k(e,g);let t;try{t=Jn(e)}catch{t=!0}t&&er(e)}Bt.clear()}function Yt(e,t=1){var n=J(e),r=t===1?n++:n--;return N(e,n),r}function Xt(e){N(e,e.v+1)}function Zt(e,t,n){var r=e.reactions;if(r!==null){var i=Ze(),a=r.length;if(Kt+=a,Kt>1e5&&Gt===null&&(Gt=new Set),Gt!==null){if(Gt.has(e))return;Gt.add(e)}for(var o=0;o{if(Gn===d)return e();var t=V,n=Gn;U(null),Kn(d);var r=e();return U(t),Kn(n),r};return i&&r.set(`length`,M(t.length,u)),new Proxy(t,{defineProperty(e,t,n){`value`in n&&n.configurable!==!1&&n.enumerable!==!1&&n.writable!==!1||Ie();var i=r.get(t);return i===void 0?f(()=>{var e=M(n.value,u);return r.set(t,e),e}):N(i,n.value,!0),!0},deleteProperty(e,t){var n=r.get(t);if(n===void 0){if(t in e){let e=f(()=>M(C,u));r.set(t,e),Xt(o)}}else N(n,C),Xt(o);return!0},get(e,n,i){if(n===ae)return t;var o=r.get(n),s=n in e;if(o===void 0&&(!s||a(e,n)?.writable)&&(o=f(()=>M(Qt(s?e[n]:C),u)),r.set(n,o)),o!==void 0){var c=J(o);return c===C?void 0:c}return Reflect.get(e,n,i)},getOwnPropertyDescriptor(e,t){this.has?.(e,t);var n=Reflect.getOwnPropertyDescriptor(e,t),i=r.get(t);if(i!==void 0){var a=J(i);if(a===C)return;if(n&&`value`in n)n.value=a;else return{enumerable:!0,configurable:!0,value:a,writable:!0}}return n},has(e,t){if(t===ae)return!0;var n=r.get(t),i=n!==void 0&&n.v!==C||Reflect.has(e,t);return(n!==void 0||W!==null&&(!i||a(e,t)?.writable))&&(n===void 0&&(n=f(()=>M(i?Qt(e[t]):C,u)),r.set(t,n)),J(n)===C)?!1:i},set(e,t,n,s){var c=r.get(t),l=t in e;if(i&&t===`length`)for(var d=n;dM(C,u)),r.set(d+``,p)):N(p,C)}if(c===void 0)(!l||a(e,t)?.writable)&&(c=f(()=>M(void 0,u)),N(c,Qt(n)),r.set(t,c));else{l=c.v!==C;var m=f(()=>Qt(n));N(c,m)}var h=Reflect.getOwnPropertyDescriptor(e,t);if(h?.set&&h.set.call(s,n),!l){if(i&&typeof t==`string`){var g=r.get(`length`),_=Number(t);Number.isInteger(_)&&_>=g.v&&N(g,_+1)}Xt(o)}return!0},ownKeys(e){J(o);var t=Reflect.ownKeys(e).filter(e=>{var t=r.get(e);return t===void 0||t.v!==C});for(var[n,i]of r)i.v!==C&&!(n in e)&&t.push(n);return t},setPrototypeOf(){Le()}})}var $t,en,tn,nn;function rn(){if($t===void 0){$t=window,en=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;tn=a(t,`firstChild`).get,nn=a(t,`nextSibling`).get,u(e)&&(e[le]=void 0,e[ce]=null,e[ue]=void 0,e.__e=void 0),u(n)&&(n[de]=void 0)}}function P(e=``){return document.createTextNode(e)}function an(e){return tn.call(e)}function on(e){return nn.call(e)}function F(e,t){if(!w)return an(e);var n=an(T);if(n===null)n=T.appendChild(P());else if(t&&n.nodeType!==3){var r=P();return n?.before(r),E(r),r}return t&&dn(n),E(n),n}function sn(e,t=!1){if(!w){var n=an(e);return n instanceof Comment&&n.data===``?on(n):n}if(t){if(T?.nodeType!==3){var r=P();return T?.before(r),E(r),r}dn(T)}return T}function I(e,t=!1){if(!w)return an(e);var n=F(e,t);return D(e),n}function L(e,t=1,n=!1){let r=w?T:e;for(var i;t--;)i=r,r=on(r);if(!w)return r;if(n){if(r?.nodeType!==3){var a=P();return r===null?i?.after(a):r.before(a),E(a),a}dn(r)}return E(r),r}function cn(e){e.textContent=``}function ln(){return!1}function un(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function dn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function fn(e){var t=W;if(t===null)return V.f|=ie,e;if(!(t.f&32768)&&!(t.f&4))throw e;pn(e,t)}function pn(e,t){if(e===he)throw e;if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128&&!(t.f&33570816)){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}function mn(e){W===null&&(V===null&&Pe(e),Ne()),Ln&&Me(e)}function hn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function gn(e,t){var n=W;n!==null&&n.f&8192&&(e|=_);var r={ctx:O,deps:null,nodes:null,f:e|h|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};A?.register_created_effect(r);var i=r;if(e&4)Ot===null?Mt.ensure().schedule(r):Ot.push(r);else if(t!==null){try{er(r)}catch(e){throw B(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=x))}if(i!==null&&(i.parent=n,n!==null&&hn(i,n),V!==null&&V.f&2&&!(e&64))){var a=V;(a.effects??=[]).push(i)}return r}function _n(){return V!==null&&!H}function vn(e){let t=gn(8,null);return k(t,m),t.teardown=e,t}function yn(e){mn(`$effect`);var t=W.f;if(!V&&t&32&&O!==null&&!O.i){var n=O;(n.e??=[]).push(e)}else return bn(e)}function bn(e){return gn(4|ee,e)}function xn(e){Mt.ensure();let t=gn(64|S,e);return(e={})=>new Promise(n=>{e.outro?jn(t,()=>{B(t),n(void 0)}):(B(t),n(void 0))})}function Sn(e){return gn(4,e)}function Cn(e){return gn(re|S,e)}function wn(e,t=0){return gn(8|t,e)}function R(e,t=[],n=[],r=[]){lt(r,t,n,t=>{gn(8,()=>{e(...t.map(J))})})}function Tn(e,t=0){return gn(16|t,e)}function z(e){return gn(32|S,e)}function En(e){var t=e.teardown;if(t!==null){let n=Ln,r=V;Rn(!0),U(null);try{t.call(null)}catch(t){pn(t,e.parent)}finally{Rn(n),U(r)}}}function Dn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&st(()=>{e.abort(pe)});var r=n.next;n.f&64?n.parent=null:B(n,t),n=r}}function On(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||B(t),t=n}}function B(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(kn(e.nodes.start,e.nodes.end),n=!0),e.f|=b,Dn(e,t&&!n),$n(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();En(e),e.f^=b,e.f|=v;var i=e.parent;i!==null&&i.first!==null&&An(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function kn(e,t){for(;e!==null;){var n=e===t?null:on(e);e.remove(),e=n}}function An(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function jn(e,t,n=!0){var r=[];e.f|=256,Mn(e,r,!0);var i=()=>{n&&B(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function Mn(e,t,n){if(!(e.f&8192)){e.f^=_;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=!!(i.f&65536)||!!(i.f&32)&&!!(e.f&16);Mn(i,t,o?n:!1)}i=a}}}function Nn(e){e.f&=-257,Pn(e,!0)}function Pn(e,t){if(!(e.f&256)&&e.f&8192){e.f^=_,e.f&1024||(k(e,h),Mt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=!!(n.f&65536)||!!(n.f&32);Pn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function Fn(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:on(n);t.append(n),n=i}}var In=null,Ln=!1;function Rn(e){Ln=e}var V=null,H=!1;function U(e){V=e}var W=null;function zn(e){W=e}var Bn=null;function Vn(e){V!==null&&(V.f&2097152||V.f&2)&&(Bn??=new Set).add(e)}var G=null,K=0,q=null;function Hn(e){q=e}var Un=1,Wn=0,Gn=Wn;function Kn(e){Gn=e}function qn(){return++Un}function Jn(e){var t=e.f;if(t&2048)return!0;if(t&4096){for(var n=e.deps,r=n.length,i=0;ie.wv)return!0}t&512&&j===null&&k(e,m)}return!1}function Yn(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Bn!==null&&Bn.has(e)))for(var i=0;i{e.ac.abort(pe)}),e.ac=null);try{e.f|=ne;var u=e.fn,d=u();e.f|=y;var f=Zn(e);if(Ze()&&q!==null&&!H&&f!==null&&!(e.f&6146))for(var p=0;p0)for(t.length=K+G.length,r=0;r{s.ac.abort(pe),s.ac=null,k(s,h)}),xt(s),$n(s,0)}}function $n(e,t){var n=e.deps;if(n!==null)for(var r=t;rn?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?(i.__removed=!1,et(()=>{i.__removed||t.addEventListener(e,i,r)})):t.addEventListener(e,i,r),i}function dr(e,t,n,r,i){var a={capture:r,passive:i},o=ur(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&vn(()=>{o.__removed=!0,t.removeEventListener(e,o,a)})}function fr(e,t,n){(t[sr]??={})[e]=n}function pr(e){for(var t=0;t{hr=!1,mr=null}));var s=0,c=mr===e&&e[sr];if(c){var l=a.indexOf(c);if(l!==-1&&(t===document||t===window)){e[sr]=t;return}var u=a.indexOf(t);if(u===-1)return;l<=u&&(s=l)}if(o=a[s]||e.target,o!==t){i(e,`currentTarget`,{configurable:!0,get(){return o||n}});var d=V,f=W;U(null),zn(null);try{for(var p,m=[];o!==null&&o!==t;){try{var h=o[sr]?.[r];h==null||o.disabled&&e.target!==o||h.call(o,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;s++,o=s{throw e});throw p}}finally{e[sr]=t,delete e.currentTarget,U(d),zn(f)}}}var _r=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function vr(e){return _r?.createHTML(e)??e}function yr(e){var t=un(`template`);return t.innerHTML=vr(e.replaceAll(``,``)),t.content}function br(e,t){var n=W;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function Y(e,t){var n=!!(t&1),r=!!(t&2),i,a=!e.startsWith(``);return()=>{if(w)return br(T,null),T;i===void 0&&(i=yr(a?e:``+e),n||(i=an(i)));var t=r||en?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=an(t),s=t.lastChild;br(o,s)}else br(t,t);return t}}function xr(e=``){if(!w){var t=P(e+``);return br(t,t),t}var n=T;return n.nodeType===3?dn(n):(n.before(n=P()),E(n)),br(n,n),n}function Sr(){if(w)return br(T,null),T;var e=document.createDocumentFragment(),t=document.createComment(``),n=P();return e.append(t,n),br(t,n),e}function X(e,t){if(w){var n=W;n.f&32768&&n.nodes.end!==null||(n.nodes.end=T),xe()}else e!==null&&e.before(t)}function Cr(e){let t=0,n=Ut(0),r;return()=>{_n()&&(J(n),wn(()=>(t===0&&(r=ir(()=>e(()=>Xt(n)))),t+=1,()=>{et(()=>{--t,t===0&&(r?.(),r=void 0,Xt(n))})})))}}var wr=x|S;function Tr(e,t,n,r){new Er(e,t,n,r)}var Er=class{parent;is_pending=!1;transform_error;#e;#t=w?T:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=Cr(()=>(this.#m=Ut(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=W;t.b=this,t.f|=128,n(e)},this.parent=W.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=Tn(()=>{if(w){let e=we(this.#t);xe();let t=e===`[!`;if(e.startsWith(`[?`)){let t=JSON.parse(e.slice(2));this.#_(t)}else t?this.#b():this.#g()}else this.#x()},wr),w&&(this.#e=T)}#g(){try{this.#a=z(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed,{reset:n,invoke_onerror:r}=this.#v(e);et(r),t&&(this.#s=z(()=>{t(this.#e,()=>e,()=>n)}))}#v(e){var t=!1,n=!1;let r=()=>{this.#y()||(t?ye():(t=!0,n&&ze(),this.#s!==null&&jn(this.#s,()=>{this.#s=null}),this.#C(()=>{this.#x()})))};return{reset:r,invoke_onerror:()=>{if(!this.#y())try{n=!0,this.#n.onerror?.(e,r),n=!1}catch(e){pn(e,this.#i&&this.#i.parent)}}}}#y(){return(this.#i.f&(v|b))!==0}#b(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=z(()=>e(this.#e)),et(()=>{if(!this.#y()){var e=this.#c=document.createDocumentFragment(),t=P(),n=!1;e.append(t),this.#a=this.#C(()=>{try{return z(()=>this.#r(t))}catch(e){try{this.error(e),n=!0}catch(e){pn(e,this.#i.parent)}return null}}),this.#a===null?(this.#c=null,n&&this.#S(A)):this.#u===0&&(this.#e.before(e),this.#c=null,jn(this.#o,()=>{this.#o=null}),this.#S(A))}}))}#x(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=z(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();Fn(this.#a,e);let t=this.#n.pending;this.#o=z(()=>t(this.#e))}else this.#S(A)}catch(e){this.error(e)}}#S(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){it(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#C(e){var t=W,n=V,r=O;zn(this.#i),U(this.#i),Ue(this.#i.ctx);try{return Mt.ensure(),e()}finally{zn(t),U(n),Ue(r)}}#w(e,t){this.has_pending_snippet()?(this.#u+=e,this.#u===0&&(this.#S(t),this.#o&&jn(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))):this.parent&&this.parent.#w(e,t)}update_pending_count(e,t){this.#w(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,et(()=>{this.#d=!1,this.#m&&qt(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),J(this.#m)}error(e){if(e===he||!this.#n.onerror&&!this.#n.failed)throw e;A?.is_fork?(this.#a&&A.skip_effect(this.#a),this.#o&&A.skip_effect(this.#o),this.#s&&A.skip_effect(this.#s),A.oncommit(()=>{this.#y()||this.#T(e)})):this.#T(e)}#T(e){this.#a&&=(B(this.#a),null),this.#o&&=(B(this.#o),null),this.#s&&=(B(this.#s),null),w&&(E(this.#t),Se(),E(Ce()));let t=this.#n.failed,n=e=>{if(this.#y())return;let{reset:n,invoke_onerror:r}=this.#v(e);r(),t&&!this.#y()&&(this.#s=this.#C(()=>{try{return z(()=>{var r=W;r.b=this,r.f|=128,t(this.#e,()=>e,()=>n)})}catch(e){return pn(e,this.#i.parent),null}}))};et(()=>{if(!this.#y()){var t;try{t=this.transform_error(e)}catch(e){pn(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(n,e=>pn(e,this.#i&&this.#i.parent)):n(t)}})}};function Z(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[de]??=e.nodeValue)&&(e[de]=n,e.nodeValue=`${n}`)}function Dr(e,t){return kr(e,t)}var Or=new Map;function kr(e,{target:t,anchor:n,props:i={},events:a,context:o,intro:s=!0,transformError:c}){rn();var l=void 0,u=xn(()=>{var s=n??t.appendChild(P());Tr(s,{pending:()=>{}},t=>{Je({});var n=O;if(o&&(n.c=o),a&&(i.$$events=a),w&&br(t,null),l=e(t,i)||Xe(),w&&(W.nodes.end=T,T===null||T.nodeType!==8||T.data!==`]`))throw ve(),he;Ye()},c);var u=new Set,d=e=>{for(var n=0;n{for(var e of u)for(let n of[t,document]){var r=Or.get(n),i=r.get(e);--i==0?(n.removeEventListener(e,gr),r.delete(e),r.size===0&&Or.delete(n)):r.set(e,i)}lr.delete(d),s!==n&&s.parentNode?.removeChild(s)}});return Ar.set(l,u),l}var Ar=new WeakMap,jr=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)Nn(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(Nn(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(B(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();Fn(r,t),t.append(P()),this.#n.set(e,{effect:r,fragment:t})}else B(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),jn(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(B(n.effect),this.#n.delete(e))};ensure(e,t){var n=A,r=ln();if(t&&!this.#t.has(e)&&!this.#n.has(e)){if(r){var i=document.createDocumentFragment(),a=P();i.append(a),this.#n.set(e,{effect:z(()=>t(a)),fragment:i})}else this.#t.set(e,z(()=>t(this.anchor)))}if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else w&&(this.anchor=T),this.#a(n)}};function Mr(e,t,n=!1){var r;w&&(r=T,xe());var i=new jr(e),a=n?x:0;function o(e,t){if(w){var n=we(r);if(e!==parseInt(n.substring(1))){var a=Ce();E(a),i.anchor=a,be(!1),i.ensure(e,t),be(!0);return}}i.ensure(e,t)}Tn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}var Nr=Symbol(`NaN`);function Pr(e,t,n){w&&xe();var r=new jr(e),i=!Ze();Tn(()=>{var e=t();e!==e&&(e=Nr),i&&typeof e==`object`&&e&&(e={}),r.ensure(e,n)})}function Fr(e,t){return t}function Ir(e,t,n){for(var i=[],a=t.length,o,s=t.length,c=0;c{if(o){if(o.pending.delete(n),o.done.add(n),o.pending.size===0){var t=e.outrogroups;Lr(e,r(o.done)),t.delete(o),t.size===0&&(e.outrogroups=null)}}else--s},!1)}if(s===0){var l=i.length===0&&n!==null&&e.pending.size===0;if(l){var u=n,d=u.parentNode;cn(d),d.append(u),e.items.clear()}Lr(e,t,!l)}else o={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(o)}function Lr(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i{var t=i();return e(t)?t:t==null?[]:r(t)}),p=new Map,m=!0;function h(e){if(!(_.effect.f&16384)){_.pending.delete(e);var t=J(f);_.fallback=d,Vr(_,t,c,n,a),d!==null&&(t.length===0?d.f&33554432?(d.f^=te,Ur(d,null,c)):Nn(d):jn(d,()=>{d=null}))}}function g(e){_.pending.delete(e)}var _={effect:Tn(()=>{var e=J(f),t=e.length;let r=!1;w&&we(c)===`[!`!=(t===0)&&(c=Ce(),E(c),be(!1),r=!0);for(var u=new Set,_=A,v=ln(),y=0;ys(c)):(d=z(()=>s(Rr??=P())),d.f|=te)),t>u.size&&je(``,``,``),w&&t>0&&E(Ce()),!m){if(p.set(_,u),v){for(let[e,t]of l)u.has(e)||_.skip_effect(t.e);_.oncommit(h),_.ondiscard(g)}else h(_)}r&&be(!0),J(f)}),flags:n,items:l,pending:p,outrogroups:null,fallback:d};m=!1,w&&(c=T)}function Br(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function Vr(e,t,n,i,a){var o=!!(i&8),s=t.length,c=e.items,l=Br(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(o)for(v=0;v0){var ie=i&4&&s===0?n:null;if(o){for(v=0;v{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function Hr(e,t,n,r,i,a,o,s){var c=o&1?o&16?Ut(n):Wt(n,!1,!1):null,l=o&2?Ut(i):null;return{v:c,i:l,e:z(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function Ur(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=on(r);if(a.before(r),r===i)return;r=o}}function Wr(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Gr(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`){if(Array.isArray(e)){var i=e.length;for(t=0;t=0;){var s=o+a;(o===0||Jr.includes(r[o-1]))&&(s===r.length||Jr.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function Xr(e,t=!1){var n=t?` !important;`:`;`,r=``;for(var i of Object.keys(e)){var a=e[i];a!=null&&a!==``&&(r+=` `+i+`: `+a+n)}return r}function Zr(e){return e[0]!==`-`||e[1]!==`-`?e.toLowerCase():e}function Qr(e,t){if(t){var n=``,r,i;if(Array.isArray(t)?(r=t[0],i=t[1]):r=t,e){e=String(e).replaceAll(/\/\*.*?\*\//g,``).trim();var a=!1,o=0,s=!1,c=[];r&&c.push(...Object.keys(r).map(Zr)),i&&c.push(...Object.keys(i).map(Zr));var l=0,u=-1;let t=e.length;for(var d=0;d{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;Q(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;Q(e,`checked`,null),e.checked=r}}};e[fe]=n,et(n),ot()}}function Q(e,t,n,r){var i=oi(e);w&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===ii)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[se]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&ci(e).has(t)?e[t]=n:e.setAttribute(t,n))}function oi(e){return e[ce]??={[ni]:e.nodeName.includes(`-`),[ri]:e.namespaceURI===ge}}var si=new Map;function ci(e){var t=e.getAttribute(`is`)||e.nodeName,n=si.get(t);if(n)return n;si.set(t,n=new Set);for(var r,i=e,a=Element.prototype;a!==i;){for(var s in r=o(i),r)r[s].set&&s!==`innerHTML`&&s!==`textContent`&&s!==`innerText`&&n.add(s);i=l(i)}return n}function li(e,t,n=t){var r=new WeakSet;ct(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=ui(e)?di(a):a,n(a),A!==null&&r.add(A),await tr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(w&&e.defaultValue!==e.value||ir(t)==null&&e.value)&&(n(ui(e)?di(e.value):e.value),A!==null&&r.add(A)),wn(()=>{var n=t();if(e===document.activeElement){var i=A;if(r.has(i))return}ui(e)&&n===di(e.value)||(e.type!==`date`||n||e.value)&&n!==e.value&&(e.value=n??``)})}function ui(e){var t=e.type;return t===`number`||t===`range`}function di(e){return e===``?null:+e}function fi(e,t){return e===t||e?.[ae]===t}function pi(e=Xe(),t,n,r){var i=O.r,a=W;return Sn(()=>{var o,s;return wn(()=>{o=s,s=r?.()||[],ir(()=>{fi(n(...s),e)||(t(e,...s),o&&fi(n(...o),e)&&t(null,...o))})}),()=>{let r=a;for(;r!==i&&r.parent!==null&&r.parent.f&33554432;)r=r.parent;let o=()=>{s&&fi(n(...s),e)&&t(null,...s)},c=r.teardown;r.teardown=()=>{o(),c?.()}}}),e}typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var mi=4,hi=[[`#3b82f6`,`#bfdbfe`],[`#a855f7`,`#f0d9ff`],[`#10b981`,`#b7f5da`],[`#ef4444`,`#ffd5d5`],[`#f59e0b`,`#ffeab0`],[`#06b6d4`,`#b8f2fb`],[`#6366f1`,`#d5daff`],[`#84cc16`,`#e3fab3`]];function gi(e,t,n){let r=t,i=n;switch(e){case 0:return``;case 1:return``;case 2:{let e=[.35,.62,.45,.8,.55];return e.map((t,n)=>{let a=r*.9/e.length-6;return``}).join(``)}default:return``}}var _i=new Map;function vi(e,t,n,r){let i=e%hi.length,a=t%mi,o=`${i}-${a}-${n}x${r}`,s=_i.get(o);if(s)return s;let[c,l]=hi[i],u=`g${i}${a}`,d=`${gi(a,n,r)}`,f=`data:image/svg+xml,${encodeURIComponent(d)}`;return _i.set(o,f),f}var yi=40,bi=1500,xi=8,Si=[`General`,`Random`,`Announcements`,`Engineering`,`Design`,`Product`,`Support`,`Off Topic`,`Releases`,`Incidents`,`Frontend`,`Backend`,`Infra`,`Mobile`,`Performance`,`Security`,`Docs`,`Hiring`,`Watercooler`,`Standup`],Ci=[`Ada Lovelace`,`Alan Turing`,`Grace Hopper`,`Linus Pauling`,`Marie Curie`,`Nikola Tesla`,`Rosalind Franklin`,`Carl Sagan`,`Katherine Johnson`,`Tim Berners-Lee`],wi=[`#368bd6`,`#ac3ba8`,`#03b381`,`#e64f7a`,`#ff812d`,`#2dc2c5`,`#5c56f5`,`#74d12c`],Ti=wi.length,Ei=`the.benchmark.switching.between.rooms.should.feel.instant.even.when.the.timeline.is.long.and.full.of.rich.messages.with.avatars.and.timestamps.rendering.performance.matters.a.lot.here.lets.measure.it.carefully.and.compare.across.browsers.over.time`.split(`.`),Di=`😀.😂.🎉.🔥.❤️.🙏.👀.🚀.😅.🤔.💯.✨.🙌🏽.👍🏻.😍.🥳.😭.🤯.👏.💪🏾.🧠.☕.🐛.📈.👩‍💻.🧑‍🚀.👨‍👩‍👧‍👦.🏳️‍🌈.🤷‍♀️.🙋‍♂️.🫠.🫶`.split(`.`),Oi=[`👍`,`❤️`,`😂`,`🎉`,`🔥`,`✅`,`👀`,`🙏`,`💯`,`🚀`,`😅`,`🤯`],ki=Ci.map(e=>e.split(` `)[0].toLowerCase()),Ai=[`scrollTop`,`scrollHeight`,`flushSync`,`requestAnimationFrame`,`IntersectionObserver`,`overflow-anchor`,`content-visibility`,`useLayoutEffect`,`getBoundingClientRect`,`will-change`,`ResizeObserver`,`queueMicrotask`,`clientHeight`,`offsetHeight`],ji=[`the trace`,`last night's run`,`this regression`,`the profile`,`the spec text`,`my notes`,`the dashboard`,`that comparison`],Mi=[`traces/2f9c`,`runs/nightly`,`profiles/hot-path`,`spec/scroll-anchoring`,`notes/timeline`,`dashboards/perf`,`reports/42`,`compare/main`],Ni=[{site:`example.com`,title:`Scroll anchoring, and why feeds jump`,description:`How browsers pin a scroll position while content is inserted above the viewport, and where it gives up.`},{site:`perf.example.com`,title:`Nightly run 482 vs 481`,description:`Geomean moved 1.8% on the chat suites. Row measurement dominates the profile.`},{site:`docs.example.com`,title:`Windowing a variable-height list`,description:`Estimate, measure, cache, correct. The four steps every hand-rolled virtualizer ends up with.`},{site:`bugs.example.com`,title:`Timeline jumps when the panel opens`,description:`Narrowing the scroller re-wraps every row, so the cached heights are all stale at once.`}],Pi=[`can we get a number on how bad the jank is before we start moving code around`,`the window only recycles about twenty rows, so the mount cost should be flat`,`every row height changes when the panel opens, which invalidates the cache`,`please do not use smooth scrolling anywhere inside a timed step`,`prepending history without pinning the anchor makes the viewport jump`],Fi=[`estimate the row height first, then correct after measuring`,`cache measured heights per message id`,`keep the mounted window small and bounded`,`assign scroll offsets explicitly instead of animating`,`recycle rows rather than remounting them`,`break the group when a reply quote is present`,`re-measure only the rows the resize actually touched`],Ii=[{lang:`js`,lines:[`const scroller = scrollerRef.current;`,`scroller.scrollTop = scroller.scrollHeight;`]},{lang:`js`,lines:[`requestAnimationFrame(() => {`,` for (const row of mounted)`,` heights.set(row.id, row.offsetHeight);`,`});`]},{lang:`css`,lines:[`.timeline {`,` overflow-anchor: none;`,` content-visibility: auto;`,`}`]},{lang:`sh`,lines:[`npm run build`,`node debugging/e2e-chatroom.mjs --browser chrome`]},{lang:`json`,lines:[`{`,` "iterationCount": 10,`,` "suites": ["ChatRoom-React"]`,`}`]},{lang:`js`,lines:[`for (const row of rows) {`,` if (!heights.has(row.id))`,` heights.set(row.id, estimate);`,`}`]},{lang:`diff`,lines:[`- scroller.scrollTo({ top, behavior: "smooth" });`,`+ scroller.scrollTop = top;`]},{lang:`js`,lines:[`export function anchorToBottom(node) {`,` node.scrollTop = node.scrollHeight;`,`}`]}];function $(e,t){let n=Math.imul(e+1,2654435761)^Math.imul(t+1,40503);return n^=n>>>15,n=Math.imul(n,2246822519),n^=n>>>13,n=Math.imul(n,3266489917),n^=n>>>16,n>>>0}function Li(e,t,n){return e[$(t,n)%e.length]}function Ri(e){return e.split(` `).map(e=>e[0]).join(``).slice(0,2).toUpperCase()}function zi(e){let t=Si[e%Si.length];return e{if(!n.length)return;let i=r?` `:``,a=e?` `:``;t.push({type:`text`,text:`${i}${n.join(` `)}${a}`}),n=[],r=!1};for(let a of e)typeof a==`string`?n.push(a):(i(!0),t.push(a),r=!0);return i(!1),t}function Ui(e,t,n){if(n===0)return{type:`code`,text:Li(Ai,e,t+11)};if(n===1)return{type:`link`,text:Li(ji,e,t+12),href:`https://example.com/${Li(Mi,e,t+13)}`};if(n===2)return{type:`mention`,name:Li(ki,e,t+14)};let r=$(e,t+15)%yi;return{type:`room`,name:Bi(r),roomId:`room-${r}`}}function Wi(e,t){let n=6+$(e,t)%22,r=$(e,t+1)%Ei.length,i=[],a=!1;for(let o=0;o0&&oString(e).padStart(2,`0`);return`${r(t)}:${r(n)}`}var ia=1440,aa=[];for(let e=0;e[e,t%Ti])),va=new Map(Ci.map(e=>[e,Ri(e)]));function ya(e,t){let n=[],r=0;for(;n.length0&&$(a,201)%100<18){let e=$(a,203)%4==0?1+$(a,204)%Math.min(i,400):1+$(a,202)%6,t=r[Math.max(0,i-e)];c={id:t.id,sender:t.sender,excerpt:ha(t.blocks)}}r.push({id:`room-${e}-msg-${i}`,sender:o,senderInitials:va.get(o),colorIndex:_a.get(o),time:aa[a%ia],dayIndex:n[i],blocks:s,replyTo:c,grouped:i>0&&t[i-1]===o&&!c,reactions:na[a%ta]})}return r}function xa(){let e=[];for(let t=0;t0,reactions:[]}}var Ea=Y(``);function Da(e,t){Je(t,!0);var n=Ea(),r=F(n);let i;var a=I(r,!0),o=L(r,2),s=F(o),c=I(s,!0),l=I(L(s,2),!0);D(o),D(n),R(()=>{Q(n,`id`,`room-list-item-${t.index??``}`),$r(n,1,qr([`room-list-item`,t.selected&&`room-list-item-selected`])),i=ti(r,``,i,{"background-color":wi[t.room.colorIndex]}),Z(a,t.room.initials),Z(c,t.room.name),Z(l,t.room.lastMessage)}),fr(`click`,n,()=>t.onSelect(t.room.id)),X(e,n),Ye()}pr([`click`]);var Oa=Y(``);function ka(e,t){var n=Oa();zr(n,23,()=>t.rooms,e=>e.id,(e,n,r)=>{{let i=gt(()=>J(n).id===t.selectedRoomId);Da(e,{get index(){return J(r)},get room(){return J(n)},get selected(){return J(i)},get onSelect(){return t.onSelect}})}}),D(n),X(e,n)}var[Aa,ja]=We(),Ma=-1,Na=class{#e;#t;#n;#r;#i;#a;constructor(e,t,n){this.#e=n,this.#t=e,this.#i=t,this.#n=new Float64Array(e).fill(Ma),this.#r=new Float64Array(e+1),this.#a=t}get count(){return this.#t}get first(){return this.#i}extendTo(e){e>=this.#i||(this.#i=e,this.#a=e)}grow(e){if(e<=this.#t)return;let t=new Float64Array(e);t.set(this.#n),t.fill(Ma,this.#t);let n=new Float64Array(e+1);n.set(this.#r),this.#a=Math.min(this.#a,this.#t),this.#n=t,this.#r=n,this.#t=e}heightAt(e){let t=this.#n[e];return t===Ma?this.#e:t}measure(e,t){return this.#n[e]!==t&&(this.#n[e]=t,e>1;t[i]<=e?n=i:r=i-1}return Math.max(this.#i,n)}#o(){if(this.#a>this.#t)return;let e=this.#r;e[this.#i]=0;for(let t=this.#a;t `);function Fa(e,t){Je(t,!0);let n=M(``);function r(e){e.preventDefault();let r=J(n).trim();r&&(t.onSend(r),N(n,``))}function i(e){e.key===`Enter`&&!e.shiftKey&&r(e)}var a=Pa(),o=F(a);ai(o);var s=L(o,2);D(a),R((e,n)=>{Q(o,`aria-label`,`Message ${t.roomName??``}`),Q(o,`placeholder`,`Message #${e??``}`),s.disabled=n},[()=>t.roomName.toLowerCase().replace(/ /g,`-`),()=>J(n).trim().length===0]),dr(`submit`,a,r),fr(`keydown`,o,i),li(o,()=>J(n),e=>N(n,e)),X(e,a),Ye()}pr([`keydown`]);var Ia=Y(``);function La(e,t){Je(t,!0);let n=M(!1);var r=Ia(),i=F(r),a=I(i,!0),o=I(L(i,2),!0);D(r),R(()=>{$r(r,1,qr([`reaction`,J(n)&&`reaction-mine`])),Q(r,`aria-pressed`,J(n)),Z(a,t.reaction.emoji),Z(o,t.reaction.count+ +!!J(n))}),fr(`click`,r,()=>N(n,!J(n))),X(e,r),Ye()}pr([`click`]);var Ra=Y(` `),za=Y(` `),Ba=Y(` `),Va=Y(``),Ha=Y(`
             
            `),Ua=Y(`
            `),Wa=Y(``),Ga=Y(` `),Ka=Y(`
          5. `),qa=Y(`
              `),Ja=Y(`

              `);function Ya(e,t){Je(t,!0);let n=(e,t=d)=>{var n=Sr();zr(sn(n),17,t,Fr,(e,t)=>{var n=Sr(),a=sn(n),o=e=>{var n=Ra(),r=I(n,!0);R(()=>Z(r,J(t).text)),X(e,n)},s=e=>{var n=za(),r=I(n,!0);R(()=>{Q(n,`href`,J(t).href),Z(r,J(t).text)}),fr(`click`,n,i),X(e,n)},c=e=>{var n=Ba(),r=I(n);R(()=>Z(r,`@${J(t).name??``}`)),X(e,n)},l=e=>{var n=Va(),i=I(n);R(()=>Z(i,`#${J(t).name??``}`)),fr(`click`,n,()=>r(J(t).roomId)),X(e,n)},u=e=>{var n=xr();R(()=>Z(n,J(t).text)),X(e,n)};Mr(a,e=>{J(t).type===`code`?e(o):J(t).type===`link`?e(s,1):J(t).type===`mention`?e(c,2):J(t).type===`room`?e(l,3):e(u,-1)}),X(e,n)}),X(e,n)},{selectRoom:r}=Aa(),i=e=>e.preventDefault();var a=Sr();zr(sn(a),17,()=>t.blocks,Fr,(e,t)=>{var r=Sr(),a=sn(r),o=e=>{var n=Ha(),r=I(F(n),!0);D(n),R(e=>{Q(n,`data-lang`,J(t).lang),Z(r,e)},[()=>J(t).lines.join(` +`)]),X(e,n)},s=e=>{var r=Ua(),i=F(r);n(i,()=>J(t).spans),D(r),X(e,r)},c=e=>{var n=Wa();R(()=>{Q(n,`src`,J(t).src),Q(n,`width`,J(t).width),Q(n,`height`,J(t).height),Q(n,`alt`,J(t).alt)}),X(e,n)},l=e=>{var n=Ga(),r=F(n),a=L(r,2),o=F(a),s=I(o,!0),c=L(o,2),l=I(c,!0),u=I(L(c,2),!0);D(a),D(n),R(()=>{Q(n,`href`,J(t).href),Q(r,`src`,J(t).thumbSrc),Q(r,`width`,J(t).thumbWidth),Q(r,`height`,J(t).thumbHeight),Z(s,J(t).site),Z(l,J(t).title),Z(u,J(t).description)}),fr(`click`,n,i),X(e,n)},u=e=>{var r=qa();zr(r,21,()=>J(t).items,Fr,(e,t)=>{var r=Ka(),i=F(r);n(i,()=>J(t)),D(r),X(e,r)}),D(r),X(e,r)},d=e=>{var r=Ja(),i=F(r);n(i,()=>J(t).spans),D(r),X(e,r)};Mr(a,e=>{J(t).type===`code`?e(o):J(t).type===`quote`?e(s,1):J(t).type===`image`?e(c,2):J(t).type===`unfurl`?e(l,3):J(t).type===`list`?e(u,4):e(d,-1)}),X(e,r)}),X(e,a),Ye()}pr([`click`]);var Xa=Y(`
              `),Za=Y(`
              New
              `),Qa=Y(` `),$a=Y(` `),eo=Y(``),to=Y(`
              `),no=Y(`
              `),ro=Y(`
            • `);function io(e,t){Je(t,!0);let{jumpToMessage:n}=Aa();var r=ro(),i=F(r),a=e=>{var n=Xa(),r=I(F(n),!0);D(n),R(()=>Z(r,t.dateLabel)),X(e,n)};Mr(i,e=>{t.dateLabel!==null&&e(a)});var o=L(i,2),s=e=>{X(e,Za())};Mr(o,e=>{t.unreadBelow&&e(s)});var c=L(o,2),l=F(c),u=e=>{var n=Qa(),r=I(n,!0);R(()=>Z(r,t.message.time)),X(e,n)},d=e=>{var n=$a();let r;var i=I(n,!0);R(()=>{r=ti(n,``,r,{"background-color":wi[t.message.colorIndex]}),Z(i,t.message.senderInitials)}),X(e,n)};Mr(l,e=>{t.message.grouped?e(u):e(d,-1)});var f=L(l,2),p=F(f),m=e=>{var r=eo(),i=F(r),a=I(i,!0),o=I(L(i,2),!0);D(r),R(()=>{Z(a,t.message.replyTo.sender),Z(o,t.message.replyTo.excerpt)}),fr(`click`,r,()=>n(t.message.replyTo.id)),X(e,r)};Mr(p,e=>{t.message.replyTo&&e(m)});var h=L(p,2),g=e=>{var n=to(),r=F(n),i=I(r,!0),a=I(L(r,2),!0);D(n),R(()=>{Z(i,t.message.sender),Z(a,t.message.time)}),X(e,n)};Mr(h,e=>{t.message.grouped||e(g)});var _=L(h,2);Ya(F(_),{get blocks(){return t.message.blocks}}),D(_);var v=L(_,2),y=e=>{var n=no();zr(n,21,()=>t.message.reactions,e=>e.emoji,(e,t)=>{La(e,{get reaction(){return J(t)}})}),D(n),X(e,n)};Mr(v,e=>{t.message.reactions.length>0&&e(y)}),D(f),D(c),D(r),R(()=>{$r(r,1,qr([`timeline-message`,t.message.grouped&&`timeline-message-grouped`,t.highlighted&&`timeline-message-highlighted`])),Q(r,`data-message-id`,t.message.id),Q(r,`data-index`,t.index)}),X(e,r),Ye()}pr([`click`]);var ao=Y(`
              `,1);function oo(e,t){Je(t,!0);let n,r=M(null),i=M([]),a=gt(()=>J(i).length?[...t.room.messages,...J(i)]:t.room.messages),o=gt(()=>new Na(t.room.messages.length,Math.max(0,t.room.messages.length-300),100)),s=M(0),c=gt(()=>{let e=J(a),t=null;return n=>(t===null&&(t=new Map(e.map((e,t)=>[e.id,t]))),t.get(n))}),l=M({start:0,end:0}),u=!0,d=null,f=null;function p(e,t){let n=J(o).indexAt(e),r=e+t,i=n;for(;i+10&&n.scrollTopt.onSelectRoom(e),jumpToMessage:y});let x=gt(()=>{let e=J(a)[J(a).length-1].dayIndex,n=[];for(let r=J(l).start;r0?J(a)[r-1]:null,s=o===null||o.dayIndex!==i.dayIndex;n.push({index:r,message:i,dateLabel:s?la(i.dayIndex,e):null,unreadBelow:r===t.room.readUpToIndex+1})}return n}),S=gt(()=>(J(s),{top:J(o).offsetAt(J(l).start),bottom:J(o).totalHeight-J(o).offsetAt(J(l).end)}));yn(()=>{J(x),J(S),J(r),ir(v)});var ee=ao(),te=sn(ee),ne=F(te);let re;var ie=L(ne,2);zr(ie,17,()=>J(x),e=>e.message.id,(e,t)=>{{let n=gt(()=>J(t).message.id===J(r));io(e,{get index(){return J(t).index},get message(){return J(t).message},get highlighted(){return J(n)},get dateLabel(){return J(t).dateLabel},get unreadBelow(){return J(t).unreadBelow}})}});var ae=L(ie,2);let oe;D(te),pi(te,e=>n=e,()=>n),Fa(L(te,2),{get roomName(){return t.room.name},onSend:b}),R(()=>{re=ti(ne,``,re,{height:`${J(S).top??``}px`}),oe=ti(ae,``,oe,{height:`${J(S).bottom??``}px`})}),dr(`scroll`,te,_),X(e,ee),Ye()}var so=Y(`

              `);function co(e,t){Je(t,!0);let n=M(Qt(Sa[0].id)),r=gt(()=>Sa.find(e=>e.id===J(n))),i=e=>{N(n,e,!0)};var a=so(),o=F(a);ka(o,{get rooms(){return Sa},get selectedRoomId(){return J(n)},onSelect:i});var s=L(o,2),c=F(s),l=F(c),u=I(l,!0),d=I(L(l,2),!0);D(c),Pr(L(c,2),()=>J(r).id,e=>{oo(e,{get room(){return J(r)},onSelectRoom:i})}),D(s),D(a),R(()=>{Z(u,J(r).name),Z(d,J(r).topic)}),X(e,a),Ye()}Dr(co,{target:document.getElementById(`root`)}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/suites-experimental/chat-room-svelte/dist/assets/index.js.map b/suites-experimental/chat-room-svelte/dist/assets/index.js.map new file mode 100644 index 0000000000..ba2692d68f --- /dev/null +++ b/suites-experimental/chat-room-svelte/dist/assets/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","names":["clsx","_clsx","root","$.from_html","$.child","$.only_child","$.sibling","$.clsx","$.set_style","$.delegate","root","$.from_html","$.derived","$.get","root","$.from_html","$.state","$.get","$.child","$.sibling","$.set","$.delegate","root","$.from_html","$.state","$.child","$.only_child","$.sibling","$.clsx","$.get","$.set","$.delegate","root","$.from_html","root_1","root_2","root_3","root_4","root_5","root_6","root_7","$.noop","$.comment","$.first_child","$.index","$.only_child","$.set_text","$.get","$.text","$.child","$.sibling","$.delegate","root","$.from_html","$.child","$.only_child","$.set_text","$.sibling","$.set_style","$.get","$.clsx","$.delegate","root","$.from_html","$.state","$.derived","$.get","$.first_child","$.child","$.sibling","$.set_style","$.from_html","$.state","$.proxy","$.derived","$.get","$.child","$.sibling","$.only_child","is_array","index_of","includes","array_from","define_property","get_descriptor","get_descriptors","object_prototype","array_prototype","get_prototype_of","is_extensible","noop","run_all","i","arr","deferred","resolve","reject","res","rej","CLEAN","DIRTY","MAYBE_DIRTY","INERT","DESTROYED","REACTION_RAN","DESTROYING","EFFECT_TRANSPARENT","EFFECT_PRESERVED","USER_EFFECT","EFFECT_OFFSCREEN","REACTION_IS_UPDATING","ASYNC","ERROR_VALUE","STATE_SYMBOL","COMPONENT_SYMBOL","LOADING_ATTR_SYMBOL","ATTRIBUTES_CACHE","CLASS_CACHE","STYLE_CACHE","TEXT_CACHE","FORM_RESET_HANDLER","STALE_REACTION","IS_XHTML","HYDRATION_ERROR","UNINITIALIZED","NAMESPACE_HTML","derived_inert","hydration_mismatch","svelte_boundary_reset_noop","hydrating","set_hydrating","value","hydrate_node","set_hydrate_node","node","hydrate_next","get_next_sibling","reset","next","count","skip_nodes","depth","data","remove","read_hydration_instruction","equals","safe_not_equal","a","b","safe_equals","lifecycle_outside_component","missing_context","async_derived_orphan","each_key_duplicate","effect_in_teardown","effect_in_unowned_derived","effect_orphan","effect_update_depth_exceeded","state_descriptors_fixed","state_prototype_fixed","state_unsafe_mutation","svelte_boundary_reset_onerror","create_context","key","has_context","get_context","set_context","context","get_parent_context","parent","get_or_init_context_map","name","component_context","set_component_context","createContext","getContext","setContext","hasContext","push","props","active_effect","pop","effects","fn","create_user_effect","component","mark_as_component","is_runes","micro_tasks","run_micro_tasks","tasks","queue_micro_task","is_flushing_sync","flush_tasks","STATUS_MASK","set_signal_status","signal","status","update_derived_status","derived","defer_effect","effect","dirty_effects","maybe_dirty_effects","listening_to_form_reset","add_form_reset_listener","evt","e","without_reactive_context","previous_reaction","active_reaction","previous_effect","set_active_reaction","set_active_effect","listen_to_event_and_reset_event","handler","element","event","prev","on_reset","flatten","d","derived_safe_equal","pending","blockers","deriveds","sync","async","restore","capture","blocker_promise","finish","error","invoke_error_boundary","unset_context","decrement_pending","increment_pending","run","async_derived","expression","previous_component_context","previous_batch","current_batch","activate_batch","deactivate_batch","boundary","batch","blocking","flags","OBSOLETE","promise","source","should_suspend","deferreds","async_effect","internal_set","teardown","go","p","fulfil","user_derived","push_reaction_value","destroy_derived_effects","destroy_effect","execute_derived","prev_active_effect","is_destroying_effect","update_reaction","update_derived","increment_write_version","batch_values","effect_tracking","freeze_derived_effects","remove_reactions","destroy_effect_children","unfreeze_derived_effects","update_effect","last_batch","last_scheduled_effect","is_processing","collected_effects","legacy_updates","flush_count","uid","Batch","#next","#prev","#blocking_pending","skipped","#skipped_branches","#unskipped_branches","tracked","callback","roots","#scheduled","covered","#started","#dirty_effects","#maybe_dirty_effects","render_effects","updates","#unlink","infinite_loop_guard","root","#resolve","#traverse","reset_all","#is_deferred","#defer_effects","reset_branch","#process","earlier_batch","#find_earlier_batch","#merge","#commit_callbacks","flush_queued_effects","#deferred","next_batch","#pending","old_values","is_branch","is_dirty","child","is_derived","mark","reactions","reaction","#discard_callbacks","#new_effects","blocking_pending_count","#decrement_queued","flushSync","was_flushing_sync","prev_previous_batch","result","eager_block_effects","length","unlink_effect","ordered_effects","ancestor","j","schedule_effect","eager_effects","eager_effects_deferred","state","s","v","stack","mutable_source","initial_value","immutable","set","untracking","current_sources","should_proxy","proxy","seen","count_deps","mark_reactions","updated_during_traversal","untracked_writes","set_untracked_writes","flush_eager_effects","dirty","update","get","increment","runes","not_dirty","prototype","sources","is_proxied_array","version","parent_version","update_version","with_parent","set_update_version","descriptor","prop","target","exists","receiver","has","other_s","ls","n","own_keys","$window","is_firefox","first_child_getter","next_sibling_getter","init_operations","element_prototype","node_prototype","text_prototype","create_text","get_first_child","is_text","text","merge_text_nodes","first_child","first","only_child","sibling","next_sibling","last_sibling","clear_text_content","should_defer_append","create_element","namespace","is","tag","handle_error","validate_effect","rune","push_effect","parent_last","parent_effect","create_effect","type","user_effect","component_root","options","pause_effect","render_effect","template_effect","values","block","branch","execute_effect_teardown","previously_destroying_effect","set_is_destroying_effect","controller","remove_dom","destroy_block_effect_children","removed","remove_effect_dom","transitions","transition","end","pause_children","destroy","remaining","check","t","local","transparent","resume_effect","resume_children","move_effect","fragment","captured_signals","new_deps","skipped_deps","write_version","read_version","dependencies","dependency","schedule_possible_effect_self_invalidation","previous_deps","previous_skipped_deps","previous_untracked_writes","previous_sources","previous_untracking","previous_update_version","deps","update_dependencies","dep","is_fork","remove_reaction","index","new_length","start_index","tick","depends_on_old_values","should_connect","is_new","reconnect","untrack","PASSIVE_EVENTS","is_passive_event","event_symbol","all_registered_events","root_event_handles","create_event","target_handler","handle_event_propagation","dom","event_name","delegated","delegate","events","last_propagated_event","last_propagated_event_clear_scheduled","handler_element","owner_document","path","current_target","path_idx","handled_at","at_idx","handler_idx","throw_error","other_errors","policy","html","create_trusted_html","create_fragment_from_html","elem","assign_nodes","from_html","is_fragment","use_import_node","has_start","content","clone","start","comment","frag","anchor","append","createSubscriber","subscribers","stop","Boundary","children","transform_error","#effect_pending","#local_pending_count","#anchor","#props","#children","#effect","comment_data","#hydrate_open","server_rendered_pending","serialized_error","#hydrate_failed_content","#hydrate_pending_content","#hydrate_resolved_content","#render","#main_effect","failed","#create_reset","invoke_onerror","#failed_effect","did_reset","calling_on_error","#is_destroyed","#run","err","#pending_effect","#offscreen_fragment","handled","#pending_count","previous_ctx","#update_pending_count","#pending_count_update_queued","#effect_pending_subscriber","#handle_error","handle_error_result","transformed_error","set_text","str","mount","_mount","listeners","unmount","anchor_node","ctx","Component","transformError","registered_events","event_handle","passive","counts","mounted_components","BranchManager","#transition","#batches","onscreen","#onscreen","#outroing","offscreen","#offscreen","k","on_destroy","keys","defer","#commit","#discard","if_block","marker","branches","elseif","update_branch","has_branch","NAN","legacy","get_key","render_fn","pause_effects","to_destroy","group","groups","destroy_effects","fast_path","controlled_anchor","parent_node","preserved_effects","offscreen_anchor","each","items","fallback","each_array","collection","get_collection","first_run","commit","array","reconcile","move","discard","mismatch","item","create_item","fallback_fn","skip_to_branch","is_animated","current","to_animate","matched","stashed","link","destroy_length","dest","next_node","r","f","o","clsx$1","clsx","whitespace","to_class","classname","hash","directives","len","append_styles","separator","important","css","styles","to_css_name","to_style","new_style","normal_styles","important_styles","in_str","in_apo","in_comment","reserved_names","name_index","c","property","set_class","next_class_name","next_classes","is_html","prev_classes","is_present","update_styles","priority","set_style","next_style_attr","next_styles","prev_styles","IS_CUSTOM_ELEMENT","IS_HTML","LINK_TAG","remove_input_defaults","already_removed","remove_defaults","input","set_attribute","checked","attributes","get_attributes","attribute","get_setters","setters_cache","cache_key","setters","descriptors","proto","element_proto","bind_value","batches","is_reset","is_numberlike_input","to_number","is_bound_this","bound_value","element_or_component","bind_this","component_effect","old_parts","parts","get_parts","get_value","original_teardown","SHAPE_VARIANTS","PALETTES","shapesFor","w","width","h","height","variant","bars","barWidth","cache","generatedImage","palette","paletteIndex","shape","cached","from","to","gradientId","svg","src","ROOM_COUNT","MESSAGES_PER_ROOM","MIN_MESSAGES_PER_DAY","ROOM_NAMES","SENDERS","AVATAR_COLORS","AVATAR_COLOR_COUNT","WORDS","INLINE_EMOJIS","REACTION_EMOJIS","MENTION_HANDLES","CODE_TOKENS","LINK_LABELS","LINK_PATHS","UNFURL_LINKS","QUOTE_LINES","LIST_ITEMS","CODE_SNIPPETS","seed","salt","pick","list","initials","part","roomNameFor","baseName","roomSlugFor","pickEmojis","picked","tokensToSpans","spans","words","afterInline","flush","leading","trailing","trailingSpace","token","tokens","buildInlineSpan","roll","roomIndex","buildParagraph","wordCount","lastWasInline","tail","last","buildCodeBlock","snippet","buildList","IMAGE_SIZES","IMAGE_ALTS","buildImage","size","buildUnfurl","buildBlocks","blocks","BODY_POOL_SIZE","BODY_POOL","buildReactions","REACTION_CYCLE","REACTION_POOL","formatTime","hours","minutesInDay","minutes","pad","MINUTES_IN_DAY","TIME_STRINGS","WEEKDAYS","MONTHS","DATE_LABELS","day","dateLabelFor","dayIndex","lastDayIndex","spansToText","span","blocksToText","excerpt","limit","REPLY_EXCERPT_LIMIT","BODY_EXCERPTS","bodyExcerpt","buildSenderSequence","senders","runLength","SENDER_COLOR_INDEX","SENDER_INITIALS","buildDaySequence","days","buildMessages","messages","sender","replyTo","distance","buildRooms","rooms","LOCAL_USER_NAME","LOCAL_USER","createOutgoingMessage","newest","room","previous","sentAt","sequence","root$7","Room_list_item","$$props","button","span_1","span_2","text_1","text_2","$$anchor","root$6","Room_list","nav","$0","getActions","setActions","UNMEASURED","RowHeights","#estimate","estimate","#count","#first","#heights","#offsets","#dirtyFrom","heights","offsets","#recomputeOffsets","low","high","middle","offset","root$5","Composer","draft","send","handleKeyDown","form","$1","$$value","root$4","Reaction","mine","root$3","root_1$1","root_2$1","root_3$1","root_4$1","root_5$1","root_6$1","root_7$1","root_8","root_9","root_10","Rich_text","fragment_1","node_1","consequent","code","consequent_1","preventDefault","consequent_2","consequent_3","text_3","selectRoom","alternate","text_4","$$render","fragment_3","fragment_4","node_3","consequent_4","pre","text_5","consequent_5","blockquote","node_4","consequent_6","img","consequent_7","a_1","img_1","span_3","text_6","span_4","text_7","text_8","consequent_8","ul","li","node_5","alternate_1","node_6","root$2","root_1","root_2","root_3","root_4","root_5","root_6","root_7","Message","div","div_2","node_2","div_3","jumpToMessage","div_4","span_5","div_5","div_6","root$1","Timeline","scroller","highlightedId","sent","heightsVersion","indexById","byId","message","id","range","pinnedToBottom","jumpTarget","rangeFor","scrollTop","bottom","viewportHeight","centeredOffset","centered","updateRange","captureAnchor","handleScroll","settle","captured","changed","row","messageId","handleSend","roomId","rows","startsDay","spacers","ol","li_1","styles_1","App","selectedRoomId","selectedRoom","handleSelect","main","header","h1"],"sources":["../../node_modules/svelte/src/internal/shared/utils.js","../../node_modules/svelte/src/internal/client/constants.js","../../node_modules/svelte/src/constants.js","../../node_modules/svelte/src/internal/client/warnings.js","../../node_modules/svelte/src/internal/client/dom/hydration.js","../../node_modules/svelte/src/internal/client/reactivity/equality.js","../../node_modules/svelte/src/internal/shared/errors.js","../../node_modules/svelte/src/internal/client/errors.js","../../node_modules/svelte/src/internal/flags/index.js","../../node_modules/svelte/src/internal/client/dev/tracing.js","../../node_modules/svelte/src/internal/shared/dev.js","../../node_modules/svelte/src/internal/shared/context.js","../../node_modules/svelte/src/internal/client/context.js","../../node_modules/svelte/src/internal/client/dom/task.js","../../node_modules/svelte/src/internal/client/reactivity/status.js","../../node_modules/svelte/src/internal/client/reactivity/utils.js","../../node_modules/svelte/src/internal/client/dom/elements/misc.js","../../node_modules/svelte/src/internal/client/dom/elements/bindings/shared.js","../../node_modules/svelte/src/internal/client/reactivity/async.js","../../node_modules/svelte/src/internal/client/reactivity/deriveds.js","../../node_modules/svelte/src/internal/client/reactivity/batch.js","../../node_modules/svelte/src/internal/client/reactivity/sources.js","../../node_modules/svelte/src/internal/client/proxy.js","../../node_modules/svelte/src/internal/client/dev/equality.js","../../node_modules/svelte/src/internal/client/dom/operations.js","../../node_modules/svelte/src/internal/client/error-handling.js","../../node_modules/svelte/src/internal/client/reactivity/effects.js","../../node_modules/svelte/src/internal/client/legacy.js","../../node_modules/svelte/src/internal/client/runtime.js","../../node_modules/svelte/src/utils.js","../../node_modules/svelte/src/internal/client/dom/elements/events.js","../../node_modules/svelte/src/internal/client/dom/reconciler.js","../../node_modules/svelte/src/internal/client/dom/template.js","../../node_modules/svelte/src/reactivity/create-subscriber.js","../../node_modules/svelte/src/internal/client/dom/blocks/boundary.js","../../node_modules/svelte/src/internal/client/render.js","../../node_modules/svelte/src/internal/client/dom/blocks/branches.js","../../node_modules/svelte/src/internal/client/dom/blocks/if.js","../../node_modules/svelte/src/internal/client/dom/blocks/key.js","../../node_modules/svelte/src/internal/client/dom/blocks/each.js","../../node_modules/clsx/dist/clsx.mjs","../../node_modules/svelte/src/internal/shared/attributes.js","../../node_modules/svelte/src/internal/client/dom/elements/class.js","../../node_modules/svelte/src/internal/client/dom/elements/style.js","../../node_modules/svelte/src/internal/client/dom/elements/attributes.js","../../node_modules/svelte/src/internal/client/dom/elements/bindings/input.js","../../node_modules/svelte/src/internal/client/dom/elements/bindings/this.js","../../node_modules/svelte/src/legacy/legacy-client.js","../../node_modules/svelte/src/internal/client/dom/elements/custom-element.js","../../node_modules/svelte/src/index-client.js","../../node_modules/svelte/src/internal/disclose-version.js","../../src/data/graphics.js","../../src/data/rooms.js","../../src/components/room-list-item.svelte","../../src/components/room-list.svelte","../../src/actions.js","../../src/row-heights.js","../../src/components/composer.svelte","../../src/components/reaction.svelte","../../src/components/rich-text.svelte","../../src/components/message.svelte","../../src/components/timeline.svelte","../../src/App.svelte","../../src/main.js"],"sourcesContent":["// Store the references to globals in case someone tries to monkey patch these, causing the below\n// to de-opt (this occurs often when using popular extensions).\nexport var is_array = Array.isArray;\nexport var index_of = Array.prototype.indexOf;\nexport var includes = Array.prototype.includes;\nexport var array_from = Array.from;\nexport var object_keys = Object.keys;\nexport var define_property = Object.defineProperty;\nexport var get_descriptor = Object.getOwnPropertyDescriptor;\nexport var get_descriptors = Object.getOwnPropertyDescriptors;\nexport var object_prototype = Object.prototype;\nexport var array_prototype = Array.prototype;\nexport var get_prototype_of = Object.getPrototypeOf;\nexport var is_extensible = Object.isExtensible;\nexport var has_own_property = Object.prototype.hasOwnProperty;\n\n/**\n * @param {any} thing\n * @returns {thing is Function}\n */\nexport function is_function(thing) {\n\treturn typeof thing === 'function';\n}\n\nexport const noop = () => {};\n\n// Adapted from https://github.com/then/is-promise/blob/master/index.js\n// Distributed under MIT License https://github.com/then/is-promise/blob/master/LICENSE\n\n/**\n * @template [T=any]\n * @param {any} value\n * @returns {value is PromiseLike}\n */\nexport function is_promise(value) {\n\treturn typeof value?.then === 'function';\n}\n\n/** @param {Function} fn */\nexport function run(fn) {\n\treturn fn();\n}\n\n/** @param {Array<() => void>} arr */\nexport function run_all(arr) {\n\tfor (var i = 0; i < arr.length; i++) {\n\t\tarr[i]();\n\t}\n}\n\n/**\n * TODO replace with Promise.withResolvers once supported widely enough\n * @template [T=void]\n */\nexport function deferred() {\n\t/** @type {(value: T) => void} */\n\tvar resolve;\n\n\t/** @type {(reason: any) => void} */\n\tvar reject;\n\n\t/** @type {Promise} */\n\tvar promise = new Promise((res, rej) => {\n\t\tresolve = res;\n\t\treject = rej;\n\t});\n\n\t// @ts-expect-error\n\treturn { promise, resolve, reject };\n}\n\n/**\n * @template V\n * @param {V} value\n * @param {V | (() => V)} fallback\n * @param {boolean} [lazy]\n * @returns {V}\n */\nexport function fallback(value, fallback, lazy = false) {\n\treturn value === undefined\n\t\t? lazy\n\t\t\t? /** @type {() => V} */ (fallback)()\n\t\t\t: /** @type {V} */ (fallback)\n\t\t: value;\n}\n\n/**\n * When encountering a situation like `let [a, b, c] = $derived(blah())`,\n * we need to stash an intermediate value that `a`, `b`, and `c` derive\n * from, in case it's an iterable\n * @template T\n * @param {ArrayLike | Iterable} value\n * @param {number} [n]\n * @returns {Array}\n */\nexport function to_array(value, n) {\n\t// return arrays unchanged\n\tif (Array.isArray(value)) {\n\t\treturn value;\n\t}\n\n\t// if value is not iterable, or `n` is unspecified (indicates a rest\n\t// element, which means we're not concerned about unbounded iterables)\n\t// convert to an array with `Array.from`\n\tif (n === undefined || !(Symbol.iterator in value)) {\n\t\treturn Array.from(value);\n\t}\n\n\t// otherwise, populate an array with `n` values\n\n\t/** @type {T[]} */\n\tconst array = [];\n\n\tfor (const element of value) {\n\t\tarray.push(element);\n\t\tif (array.length === n) break;\n\t}\n\n\treturn array;\n}\n\n/**\n * @param {Record} obj\n * @param {Array} keys\n * @returns {Record}\n */\nexport function exclude_from_object(obj, keys) {\n\t/** @type {Record} */\n\tvar result = {};\n\n\tfor (var key in obj) {\n\t\tif (!keys.includes(key)) {\n\t\t\tresult[key] = obj[key];\n\t\t}\n\t}\n\n\tfor (var symbol of Object.getOwnPropertySymbols(obj)) {\n\t\tif (Object.propertyIsEnumerable.call(obj, symbol) && !keys.includes(symbol)) {\n\t\t\tresult[symbol] = obj[symbol];\n\t\t}\n\t}\n\n\treturn result;\n}\n","// General flags\nexport const DERIVED = 1 << 1;\nexport const EFFECT = 1 << 2;\nexport const RENDER_EFFECT = 1 << 3;\n/**\n * An effect that does not destroy its child effects when it reruns.\n * Runs as part of render effects, i.e. not eagerly as part of tree traversal or effect flushing.\n */\nexport const MANAGED_EFFECT = 1 << 24;\n/**\n * An effect that does not destroy its child effects when it reruns (like MANAGED_EFFECT).\n * Runs eagerly as part of tree traversal or effect flushing.\n */\nexport const BLOCK_EFFECT = 1 << 4;\nexport const BRANCH_EFFECT = 1 << 5;\nexport const ROOT_EFFECT = 1 << 6;\nexport const BOUNDARY_EFFECT = 1 << 7;\n/**\n * Set on the effect that `pause_effect` was called on, i.e. the root of a paused subtree,\n * as opposed to its descendants which are merely `INERT`. This allows `resume_effect` on\n * an ancestor to skip subtrees that were paused for their own reasons (such as a block\n * whose condition is still false) rather than resurrecting them\n */\nexport const PAUSED = 1 << 8;\n/**\n * Indicates that a reaction is connected to an effect root — either it is an effect,\n * or it is a derived that is depended on by at least one effect. If a derived has\n * no dependents, we can disconnect it from the graph, allowing it to either be\n * GC'd or reconnected later if an effect comes to depend on it again\n */\nexport const CONNECTED = 1 << 9;\nexport const CLEAN = 1 << 10;\nexport const DIRTY = 1 << 11;\nexport const MAYBE_DIRTY = 1 << 12;\nexport const INERT = 1 << 13;\nexport const DESTROYED = 1 << 14;\n/** Set once a reaction has run for the first time */\nexport const REACTION_RAN = 1 << 15;\n/** Effect is in the process of getting destroyed. Can be observed in child teardown functions */\nexport const DESTROYING = 1 << 25;\n\n// Flags exclusive to effects\n/**\n * 'Transparent' effects do not create a transition boundary.\n * This is on a block effect 99% of the time but may also be on a branch effect if its parent block effect was pruned\n */\nexport const EFFECT_TRANSPARENT = 1 << 16;\nexport const EAGER_EFFECT = 1 << 17;\nexport const HEAD_EFFECT = 1 << 18;\nexport const EFFECT_PRESERVED = 1 << 19;\nexport const USER_EFFECT = 1 << 20;\nexport const EFFECT_OFFSCREEN = 1 << 25;\n\n// Flags used for async\nexport const REACTION_IS_UPDATING = 1 << 21;\nexport const ASYNC = 1 << 22;\n\nexport const ERROR_VALUE = 1 << 23;\n\nexport const STATE_SYMBOL = Symbol('$state');\n/** Marks component export objects, so that `proxy(...)` leaves them untouched */\nexport const COMPONENT_SYMBOL = Symbol('component');\nexport const LEGACY_PROPS = Symbol('legacy props');\nexport const LOADING_ATTR_SYMBOL = Symbol('');\nexport const PROXY_PATH_SYMBOL = Symbol('proxy path');\nexport const ATTRIBUTES_CACHE = Symbol('attributes');\nexport const CLASS_CACHE = Symbol('class');\nexport const STYLE_CACHE = Symbol('style');\nexport const TEXT_CACHE = Symbol('text');\nexport const FORM_RESET_HANDLER = Symbol('form reset');\n/** An anchor might change, via this symbol on the original anchor we can tell HMR about the updated anchor */\nexport const HMR_ANCHOR = Symbol('hmr anchor');\n\n/** allow users to ignore aborted signal errors if `reason.name === 'StaleReactionError` */\nexport const STALE_REACTION = new (class StaleReactionError extends Error {\n\tname = 'StaleReactionError';\n\tmessage = 'The reaction that called `getAbortSignal()` was re-run or destroyed';\n})();\n\nexport const IS_XHTML =\n\t// We gotta write it like this because after downleveling the pure comment may end up in the wrong location\n\t!!globalThis.document?.contentType &&\n\t/* @__PURE__ */ globalThis.document.contentType.includes('xml');\nexport const ELEMENT_NODE = 1;\nexport const TEXT_NODE = 3;\nexport const COMMENT_NODE = 8;\nexport const DOCUMENT_FRAGMENT_NODE = 11;\n","export const EACH_ITEM_REACTIVE = 1;\nexport const EACH_INDEX_REACTIVE = 1 << 1;\n/** See EachBlock interface metadata.is_controlled for an explanation what this is */\nexport const EACH_IS_CONTROLLED = 1 << 2;\nexport const EACH_IS_ANIMATED = 1 << 3;\nexport const EACH_ITEM_IMMUTABLE = 1 << 4;\n\nexport const PROPS_IS_IMMUTABLE = 1;\nexport const PROPS_IS_RUNES = 1 << 1;\nexport const PROPS_IS_UPDATED = 1 << 2;\nexport const PROPS_IS_BINDABLE = 1 << 3;\nexport const PROPS_IS_LAZY_INITIAL = 1 << 4;\n\nexport const TRANSITION_IN = 1;\nexport const TRANSITION_OUT = 1 << 1;\nexport const TRANSITION_GLOBAL = 1 << 2;\n\nexport const TEMPLATE_FRAGMENT = 1;\nexport const TEMPLATE_USE_IMPORT_NODE = 1 << 1;\nexport const TEMPLATE_USE_SVG = 1 << 2;\nexport const TEMPLATE_USE_MATHML = 1 << 3;\n\nexport const HYDRATION_START = '[';\n/** used to indicate that an `{:else}...` block was rendered */\nexport const HYDRATION_START_ELSE = '[!';\n/** used to indicate that a boundary's `failed` snippet was rendered on the server */\nexport const HYDRATION_START_FAILED = '[?';\nexport const HYDRATION_END = ']';\nexport const HYDRATION_ERROR = {};\n\nexport const ELEMENT_IS_NAMESPACED = 1;\nexport const ELEMENT_PRESERVE_ATTRIBUTE_CASE = 1 << 1;\nexport const ELEMENT_IS_INPUT = 1 << 2;\n\nexport const UNINITIALIZED = Symbol('uninitialized');\n\n// Dev-time component properties\nexport const FILENAME = Symbol('filename');\nexport const HMR = Symbol('hmr');\n\nexport const NAMESPACE_HTML = 'http://www.w3.org/1999/xhtml';\nexport const NAMESPACE_SVG = 'http://www.w3.org/2000/svg';\nexport const NAMESPACE_MATHML = 'http://www.w3.org/1998/Math/MathML';\n\n// we use a list of ignorable runtime warnings because not every runtime warning\n// can be ignored and we want to keep the validation for svelte-ignore in place\nexport const IGNORABLE_RUNTIME_WARNINGS = /** @type {const} */ ([\n\t'await_waterfall',\n\t'await_reactivity_loss',\n\t'state_snapshot_uncloneable',\n\t'binding_property_non_reactive',\n\t'hydration_attribute_changed',\n\t'hydration_html_changed',\n\t'ownership_invalid_binding',\n\t'ownership_invalid_mutation'\n]);\n\n/**\n * Whitespace inside one of these elements will not result in\n * a whitespace node being created in any circumstances. (This\n * list is almost certainly very incomplete)\n * TODO this is currently unused\n */\nexport const ELEMENTS_WITHOUT_TEXT = ['audio', 'datalist', 'dl', 'optgroup', 'select', 'video'];\n\nexport const ATTACHMENT_KEY = '@attach';\n","/* This file is generated by scripts/process-messages/index.js. Do not edit! */\n\nimport { DEV } from 'esm-env';\n\nvar bold = 'font-weight: bold';\nvar normal = 'font-weight: normal';\n\n/**\n * Assignment to `%property%` property (%location%) will evaluate to the right-hand side, not the value of `%property%` following the assignment. This may result in unexpected behaviour.\n * @param {string} property\n * @param {string} location\n */\nexport function assignment_value_stale(property, location) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] assignment_value_stale\\n%cAssignment to \\`${property}\\` property (${location}) will evaluate to the right-hand side, not the value of \\`${property}\\` following the assignment. This may result in unexpected behaviour.\\nhttps://svelte.dev/e/assignment_value_stale`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/assignment_value_stale`);\n\t}\n}\n\n/**\n * Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`\n * @param {string} name\n */\nexport function await_reactivity_loss(name) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] await_reactivity_loss\\n%cDetected reactivity loss when reading \\`${name}\\`. This happens when state is read in an async function after an earlier \\`await\\`\\nhttps://svelte.dev/e/await_reactivity_loss`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/await_reactivity_loss`);\n\t}\n}\n\n/**\n * An async derived, `%name%` (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app\n * @param {string} name\n * @param {string} location\n */\nexport function await_waterfall(name, location) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] await_waterfall\\n%cAn async derived, \\`${name}\\` (${location}) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app\\nhttps://svelte.dev/e/await_waterfall`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/await_waterfall`);\n\t}\n}\n\n/**\n * `%binding%` (%location%) is binding to a non-reactive property\n * @param {string} binding\n * @param {string | undefined | null} [location]\n */\nexport function binding_property_non_reactive(binding, location) {\n\tif (DEV) {\n\t\tconsole.warn(\n\t\t\t`%c[svelte] binding_property_non_reactive\\n%c${location\n\t\t\t\t? `\\`${binding}\\` (${location}) is binding to a non-reactive property`\n\t\t\t\t: `\\`${binding}\\` is binding to a non-reactive property`}\\nhttps://svelte.dev/e/binding_property_non_reactive`,\n\t\t\tbold,\n\t\t\tnormal\n\t\t);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/binding_property_non_reactive`);\n\t}\n}\n\n/**\n * Your `console.%method%` contained `$state` proxies. Consider using `$inspect(...)` or `$state.snapshot(...)` instead\n * @param {string} method\n */\nexport function console_log_state(method) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] console_log_state\\n%cYour \\`console.${method}\\` contained \\`$state\\` proxies. Consider using \\`$inspect(...)\\` or \\`$state.snapshot(...)\\` instead\\nhttps://svelte.dev/e/console_log_state`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/console_log_state`);\n\t}\n}\n\n/**\n * Reading a derived belonging to a now-destroyed effect may result in stale values\n */\nexport function derived_inert() {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] derived_inert\\n%cReading a derived belonging to a now-destroyed effect may result in stale values\\nhttps://svelte.dev/e/derived_inert`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/derived_inert`);\n\t}\n}\n\n/**\n * %handler% should be a function. Did you mean to %suggestion%?\n * @param {string} handler\n * @param {string} suggestion\n */\nexport function event_handler_invalid(handler, suggestion) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] event_handler_invalid\\n%c${handler} should be a function. Did you mean to ${suggestion}?\\nhttps://svelte.dev/e/event_handler_invalid`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/event_handler_invalid`);\n\t}\n}\n\n/**\n * Expected to find a hydratable with key `%key%` during hydration, but did not.\n * @param {string} key\n */\nexport function hydratable_missing_but_expected(key) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] hydratable_missing_but_expected\\n%cExpected to find a hydratable with key \\`${key}\\` during hydration, but did not.\\nhttps://svelte.dev/e/hydratable_missing_but_expected`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/hydratable_missing_but_expected`);\n\t}\n}\n\n/**\n * The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value\n * @param {string} attribute\n * @param {string} html\n * @param {string} value\n */\nexport function hydration_attribute_changed(attribute, html, value) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] hydration_attribute_changed\\n%cThe \\`${attribute}\\` attribute on \\`${html}\\` changed its value between server and client renders. The client value, \\`${value}\\`, will be ignored in favour of the server value\\nhttps://svelte.dev/e/hydration_attribute_changed`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/hydration_attribute_changed`);\n\t}\n}\n\n/**\n * The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value\n * @param {string | undefined | null} [location]\n */\nexport function hydration_html_changed(location) {\n\tif (DEV) {\n\t\tconsole.warn(\n\t\t\t`%c[svelte] hydration_html_changed\\n%c${location\n\t\t\t\t? `The value of an \\`{@html ...}\\` block ${location} changed between server and client renders. The client value will be ignored in favour of the server value`\n\t\t\t\t: 'The value of an `{@html ...}` block changed between server and client renders. The client value will be ignored in favour of the server value'}\\nhttps://svelte.dev/e/hydration_html_changed`,\n\t\t\tbold,\n\t\t\tnormal\n\t\t);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/hydration_html_changed`);\n\t}\n}\n\n/**\n * Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%\n * @param {string | undefined | null} [location]\n */\nexport function hydration_mismatch(location) {\n\tif (DEV) {\n\t\tconsole.warn(\n\t\t\t`%c[svelte] hydration_mismatch\\n%c${location\n\t\t\t\t? `Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near ${location}`\n\t\t\t\t: 'Hydration failed because the initial UI does not match what was rendered on the server'}\\nhttps://svelte.dev/e/hydration_mismatch`,\n\t\t\tbold,\n\t\t\tnormal\n\t\t);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/hydration_mismatch`);\n\t}\n}\n\n/**\n * The `render` function passed to `createRawSnippet` should return HTML for a single element\n */\nexport function invalid_raw_snippet_render() {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] invalid_raw_snippet_render\\n%cThe \\`render\\` function passed to \\`createRawSnippet\\` should return HTML for a single element\\nhttps://svelte.dev/e/invalid_raw_snippet_render`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/invalid_raw_snippet_render`);\n\t}\n}\n\n/**\n * Detected a migrated `$:` reactive block in `%filename%` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.\n * @param {string} filename\n */\nexport function legacy_recursive_reactive_block(filename) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] legacy_recursive_reactive_block\\n%cDetected a migrated \\`$:\\` reactive block in \\`${filename}\\` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an \\`$effect\\`.\\nhttps://svelte.dev/e/legacy_recursive_reactive_block`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/legacy_recursive_reactive_block`);\n\t}\n}\n\n/**\n * Tried to unmount a component that was not mounted\n */\nexport function lifecycle_double_unmount() {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] lifecycle_double_unmount\\n%cTried to unmount a component that was not mounted\\nhttps://svelte.dev/e/lifecycle_double_unmount`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/lifecycle_double_unmount`);\n\t}\n}\n\n/**\n * %parent% passed property `%prop%` to %child% with `bind:`, but its parent component %owner% did not declare `%prop%` as a binding. Consider creating a binding between %owner% and %parent% (e.g. `bind:%prop%={...}` instead of `%prop%={...}`)\n * @param {string} parent\n * @param {string} prop\n * @param {string} child\n * @param {string} owner\n */\nexport function ownership_invalid_binding(parent, prop, child, owner) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] ownership_invalid_binding\\n%c${parent} passed property \\`${prop}\\` to ${child} with \\`bind:\\`, but its parent component ${owner} did not declare \\`${prop}\\` as a binding. Consider creating a binding between ${owner} and ${parent} (e.g. \\`bind:${prop}={...}\\` instead of \\`${prop}={...}\\`)\\nhttps://svelte.dev/e/ownership_invalid_binding`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/ownership_invalid_binding`);\n\t}\n}\n\n/**\n * Mutating unbound props (`%name%`, at %location%) is strongly discouraged. Consider using `bind:%prop%={...}` in %parent% (or using a callback) instead\n * @param {string} name\n * @param {string} location\n * @param {string} prop\n * @param {string} parent\n */\nexport function ownership_invalid_mutation(name, location, prop, parent) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] ownership_invalid_mutation\\n%cMutating unbound props (\\`${name}\\`, at ${location}) is strongly discouraged. Consider using \\`bind:${prop}={...}\\` in ${parent} (or using a callback) instead\\nhttps://svelte.dev/e/ownership_invalid_mutation`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/ownership_invalid_mutation`);\n\t}\n}\n\n/**\n * The `value` property of a `\\` element should be an array, but it received a non-array value. The selection will be kept as is.\\nhttps://svelte.dev/e/select_multiple_invalid_value`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/select_multiple_invalid_value`);\n\t}\n}\n\n/**\n * Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results\n * @param {string} operator\n */\nexport function state_proxy_equality_mismatch(operator) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] state_proxy_equality_mismatch\\n%cReactive \\`$state(...)\\` proxies and the values they proxy have different identities. Because of this, comparisons with \\`${operator}\\` will produce unexpected results\\nhttps://svelte.dev/e/state_proxy_equality_mismatch`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/state_proxy_equality_mismatch`);\n\t}\n}\n\n/**\n * A `` `reset` function only resets the boundary the first time it is called\n */\nexport function svelte_boundary_reset_noop() {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] svelte_boundary_reset_noop\\n%cA \\`\\` \\`reset\\` function only resets the boundary the first time it is called\\nhttps://svelte.dev/e/svelte_boundary_reset_noop`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);\n\t}\n}\n\n/**\n * The `slide` transition does not work correctly for elements with `display: %value%`\n * @param {string} value\n */\nexport function transition_slide_display(value) {\n\tif (DEV) {\n\t\tconsole.warn(`%c[svelte] transition_slide_display\\n%cThe \\`slide\\` transition does not work correctly for elements with \\`display: ${value}\\`\\nhttps://svelte.dev/e/transition_slide_display`, bold, normal);\n\t} else {\n\t\tconsole.warn(`https://svelte.dev/e/transition_slide_display`);\n\t}\n}","/** @import { TemplateNode } from '#client' */\n\nimport { COMMENT_NODE } from '#client/constants';\nimport {\n\tHYDRATION_END,\n\tHYDRATION_ERROR,\n\tHYDRATION_START,\n\tHYDRATION_START_ELSE\n} from '../../../constants.js';\nimport * as w from '../warnings.js';\nimport { get_next_sibling } from './operations.js';\n\n/**\n * Use this variable to guard everything related to hydration code so it can be treeshaken out\n * if the user doesn't use the `hydrate` method and these code paths are therefore not needed.\n */\nexport let hydrating = false;\n\n/** @param {boolean} value */\nexport function set_hydrating(value) {\n\thydrating = value;\n}\n\n/**\n * The node that is currently being hydrated. This starts out as the first node inside the opening\n * comment, and updates each time a component calls `$.child(...)` or `$.sibling(...)`.\n * When entering a block (e.g. `{#if ...}`), `hydrate_node` is the block opening comment; by the\n * time we leave the block it is the closing comment, which serves as the block's anchor.\n * @type {TemplateNode}\n */\nexport let hydrate_node;\n\n/** @param {TemplateNode | null} node */\nexport function set_hydrate_node(node) {\n\tif (node === null) {\n\t\tw.hydration_mismatch();\n\t\tthrow HYDRATION_ERROR;\n\t}\n\n\treturn (hydrate_node = node);\n}\n\nexport function hydrate_next() {\n\treturn set_hydrate_node(get_next_sibling(hydrate_node));\n}\n\n/** @param {TemplateNode} node */\nexport function reset(node) {\n\tif (!hydrating) return;\n\n\t// If the node has remaining siblings, something has gone wrong\n\tif (get_next_sibling(hydrate_node) !== null) {\n\t\tw.hydration_mismatch();\n\t\tthrow HYDRATION_ERROR;\n\t}\n\n\thydrate_node = node;\n}\n\n/**\n * @param {HTMLTemplateElement} template\n */\nexport function hydrate_template(template) {\n\tif (hydrating) {\n\t\t// @ts-expect-error TemplateNode doesn't include DocumentFragment, but it's actually fine\n\t\thydrate_node = template.content;\n\t}\n}\n\nexport function next(count = 1) {\n\tif (hydrating) {\n\t\tvar i = count;\n\t\tvar node = hydrate_node;\n\n\t\twhile (i--) {\n\t\t\tnode = /** @type {TemplateNode} */ (get_next_sibling(node));\n\t\t}\n\n\t\thydrate_node = node;\n\t}\n}\n\n/**\n * Skips or removes (depending on {@link remove}) all nodes starting at `hydrate_node` up until the next hydration end comment\n * @param {boolean} remove\n */\nexport function skip_nodes(remove = true) {\n\tvar depth = 0;\n\tvar node = hydrate_node;\n\n\twhile (true) {\n\t\tif (node.nodeType === COMMENT_NODE) {\n\t\t\tvar data = /** @type {Comment} */ (node).data;\n\n\t\t\tif (data === HYDRATION_END) {\n\t\t\t\tif (depth === 0) return node;\n\t\t\t\tdepth -= 1;\n\t\t\t} else if (\n\t\t\t\tdata === HYDRATION_START ||\n\t\t\t\tdata === HYDRATION_START_ELSE ||\n\t\t\t\t// \"[1\", \"[2\", etc. for if blocks\n\t\t\t\t(data[0] === '[' && !isNaN(Number(data.slice(1))))\n\t\t\t) {\n\t\t\t\tdepth += 1;\n\t\t\t}\n\t\t}\n\n\t\tvar next = /** @type {TemplateNode} */ (get_next_sibling(node));\n\t\tif (remove) node.remove();\n\t\tnode = next;\n\t}\n}\n\n/**\n *\n * @param {TemplateNode} node\n */\nexport function read_hydration_instruction(node) {\n\tif (!node || node.nodeType !== COMMENT_NODE) {\n\t\tw.hydration_mismatch();\n\t\tthrow HYDRATION_ERROR;\n\t}\n\n\treturn /** @type {Comment} */ (node).data;\n}\n","/** @import { Equals } from '#client' */\n\n/** @type {Equals} */\nexport function equals(value) {\n\treturn value === this.v;\n}\n\n/**\n * @param {unknown} a\n * @param {unknown} b\n * @returns {boolean}\n */\nexport function safe_not_equal(a, b) {\n\treturn a != a\n\t\t? b == b\n\t\t: a !== b || (a !== null && typeof a === 'object') || typeof a === 'function';\n}\n\n/**\n * @param {unknown} a\n * @param {unknown} b\n * @returns {boolean}\n */\nexport function not_equal(a, b) {\n\treturn a !== b;\n}\n\n/** @type {Equals} */\nexport function safe_equals(value) {\n\treturn !safe_not_equal(value, this.v);\n}\n","/* This file is generated by scripts/process-messages/index.js. Do not edit! */\n\nimport { DEV } from 'esm-env';\n\n/**\n * Cannot use `%name%(...)` unless the `experimental.async` compiler option is `true`\n * @param {string} name\n * @returns {never}\n */\nexport function experimental_async_required(name) {\n\tif (DEV) {\n\t\tconst error = new Error(`experimental_async_required\\nCannot use \\`${name}(...)\\` unless the \\`experimental.async\\` compiler option is \\`true\\`\\nhttps://svelte.dev/e/experimental_async_required`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/experimental_async_required`);\n\t}\n}\n\n/**\n * Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead\n * @returns {never}\n */\nexport function invalid_default_snippet() {\n\tif (DEV) {\n\t\tconst error = new Error(`invalid_default_snippet\\nCannot use \\`{@render children(...)}\\` if the parent component uses \\`let:\\` directives. Consider using a named snippet instead\\nhttps://svelte.dev/e/invalid_default_snippet`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/invalid_default_snippet`);\n\t}\n}\n\n/**\n * A snippet function was passed invalid arguments. Snippets should only be instantiated via `{@render ...}`\n * @returns {never}\n */\nexport function invalid_snippet_arguments() {\n\tif (DEV) {\n\t\tconst error = new Error(`invalid_snippet_arguments\\nA snippet function was passed invalid arguments. Snippets should only be instantiated via \\`{@render ...}\\`\\nhttps://svelte.dev/e/invalid_snippet_arguments`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/invalid_snippet_arguments`);\n\t}\n}\n\n/**\n * An invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app — please open an issue at https://github.com/sveltejs/svelte, citing the following message: \"%message%\"\n * @param {string} message\n * @returns {never}\n */\nexport function invariant_violation(message) {\n\tif (DEV) {\n\t\tconst error = new Error(`invariant_violation\\nAn invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app — please open an issue at https://github.com/sveltejs/svelte, citing the following message: \"${message}\"\\nhttps://svelte.dev/e/invariant_violation`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/invariant_violation`);\n\t}\n}\n\n/**\n * `%name%(...)` can only be used during component initialisation\n * @param {string} name\n * @returns {never}\n */\nexport function lifecycle_outside_component(name) {\n\tif (DEV) {\n\t\tconst error = new Error(`lifecycle_outside_component\\n\\`${name}(...)\\` can only be used during component initialisation\\nhttps://svelte.dev/e/lifecycle_outside_component`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/lifecycle_outside_component`);\n\t}\n}\n\n/**\n * Context was not set in the current component or any of its ancestors\n * @returns {never}\n */\nexport function missing_context() {\n\tif (DEV) {\n\t\tconst error = new Error(`missing_context\\nContext was not set in the current component or any of its ancestors\\nhttps://svelte.dev/e/missing_context`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/missing_context`);\n\t}\n}\n\n/**\n * `setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression\n * @returns {never}\n */\nexport function set_context_after_init() {\n\tif (DEV) {\n\t\tconst error = new Error(`set_context_after_init\\n\\`setContext\\` must be called when a component first initializes, not in a subsequent effect or after an \\`await\\` expression\\nhttps://svelte.dev/e/set_context_after_init`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/set_context_after_init`);\n\t}\n}\n\n/**\n * Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`.\n * @returns {never}\n */\nexport function snippet_without_render_tag() {\n\tif (DEV) {\n\t\tconst error = new Error(`snippet_without_render_tag\\nAttempted to render a snippet without a \\`{@render}\\` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change \\`{snippet}\\` to \\`{@render snippet()}\\`.\\nhttps://svelte.dev/e/snippet_without_render_tag`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/snippet_without_render_tag`);\n\t}\n}\n\n/**\n * `%name%` is not a store with a `subscribe` method\n * @param {string} name\n * @returns {never}\n */\nexport function store_invalid_shape(name) {\n\tif (DEV) {\n\t\tconst error = new Error(`store_invalid_shape\\n\\`${name}\\` is not a store with a \\`subscribe\\` method\\nhttps://svelte.dev/e/store_invalid_shape`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/store_invalid_shape`);\n\t}\n}\n\n/**\n * The `this` prop on `` must be a string, if defined\n * @returns {never}\n */\nexport function svelte_element_invalid_this_value() {\n\tif (DEV) {\n\t\tconst error = new Error(`svelte_element_invalid_this_value\\nThe \\`this\\` prop on \\`\\` must be a string, if defined\\nhttps://svelte.dev/e/svelte_element_invalid_this_value`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/svelte_element_invalid_this_value`);\n\t}\n}","/* This file is generated by scripts/process-messages/index.js. Do not edit! */\n\nimport { DEV } from 'esm-env';\n\nexport * from '../shared/errors.js';\n\n/**\n * Cannot create a `$derived(...)` with an `await` expression outside of an effect tree\n * @returns {never}\n */\nexport function async_derived_orphan() {\n\tif (DEV) {\n\t\tconst error = new Error(`async_derived_orphan\\nCannot create a \\`$derived(...)\\` with an \\`await\\` expression outside of an effect tree\\nhttps://svelte.dev/e/async_derived_orphan`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/async_derived_orphan`);\n\t}\n}\n\n/**\n * Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead\n * @returns {never}\n */\nexport function bind_invalid_checkbox_value() {\n\tif (DEV) {\n\t\tconst error = new Error(`bind_invalid_checkbox_value\\nUsing \\`bind:value\\` together with a checkbox input is not allowed. Use \\`bind:checked\\` instead\\nhttps://svelte.dev/e/bind_invalid_checkbox_value`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/bind_invalid_checkbox_value`);\n\t}\n}\n\n/**\n * Component %component% has an export named `%key%` that a consumer component is trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this` (e.g. `<%name% bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.%key%`)\n * @param {string} component\n * @param {string} key\n * @param {string} name\n * @returns {never}\n */\nexport function bind_invalid_export(component, key, name) {\n\tif (DEV) {\n\t\tconst error = new Error(`bind_invalid_export\\nComponent ${component} has an export named \\`${key}\\` that a consumer component is trying to access using \\`bind:${key}\\`, which is disallowed. Instead, use \\`bind:this\\` (e.g. \\`<${name} bind:this={component} />\\`) and then access the property on the bound component instance (e.g. \\`component.${key}\\`)\\nhttps://svelte.dev/e/bind_invalid_export`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/bind_invalid_export`);\n\t}\n}\n\n/**\n * A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()`\n * @param {string} key\n * @param {string} component\n * @param {string} name\n * @returns {never}\n */\nexport function bind_not_bindable(key, component, name) {\n\tif (DEV) {\n\t\tconst error = new Error(`bind_not_bindable\\nA component is attempting to bind to a non-bindable property \\`${key}\\` belonging to ${component} (i.e. \\`<${name} bind:${key}={...}>\\`). To mark a property as bindable: \\`let { ${key} = $bindable() } = $props()\\`\\nhttps://svelte.dev/e/bind_not_bindable`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/bind_not_bindable`);\n\t}\n}\n\n/**\n * Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5\n * @param {string} method\n * @param {string} component\n * @returns {never}\n */\nexport function component_api_changed(method, component) {\n\tif (DEV) {\n\t\tconst error = new Error(`component_api_changed\\nCalling \\`${method}\\` on a component instance (of ${component}) is no longer valid in Svelte 5\\nhttps://svelte.dev/e/component_api_changed`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/component_api_changed`);\n\t}\n}\n\n/**\n * Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working.\n * @param {string} component\n * @param {string} name\n * @returns {never}\n */\nexport function component_api_invalid_new(component, name) {\n\tif (DEV) {\n\t\tconst error = new Error(`component_api_invalid_new\\nAttempted to instantiate ${component} with \\`new ${name}\\`, which is no longer valid in Svelte 5. If this component is not under your control, set the \\`compatibility.componentApi\\` compiler option to \\`4\\` to keep it working.\\nhttps://svelte.dev/e/component_api_invalid_new`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/component_api_invalid_new`);\n\t}\n}\n\n/**\n * A derived value cannot reference itself recursively\n * @returns {never}\n */\nexport function derived_references_self() {\n\tif (DEV) {\n\t\tconst error = new Error(`derived_references_self\\nA derived value cannot reference itself recursively\\nhttps://svelte.dev/e/derived_references_self`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/derived_references_self`);\n\t}\n}\n\n/**\n * Keyed each block has duplicate key `%value%` at indexes %a% and %b%\n * @param {string} a\n * @param {string} b\n * @param {string | undefined | null} [value]\n * @returns {never}\n */\nexport function each_key_duplicate(a, b, value) {\n\tif (DEV) {\n\t\tconst error = new Error(`each_key_duplicate\\n${value\n\t\t\t? `Keyed each block has duplicate key \\`${value}\\` at indexes ${a} and ${b}`\n\t\t\t: `Keyed each block has duplicate key at indexes ${a} and ${b}`}\\nhttps://svelte.dev/e/each_key_duplicate`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/each_key_duplicate`);\n\t}\n}\n\n/**\n * Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given item\n * @param {string} index\n * @param {string} a\n * @param {string} b\n * @returns {never}\n */\nexport function each_key_volatile(index, a, b) {\n\tif (DEV) {\n\t\tconst error = new Error(`each_key_volatile\\nKeyed each block has key that is not idempotent — the key for item at index ${index} was \\`${a}\\` but is now \\`${b}\\`. Keys must be the same each time for a given item\\nhttps://svelte.dev/e/each_key_volatile`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/each_key_volatile`);\n\t}\n}\n\n/**\n * `%rune%` cannot be used inside an effect cleanup function\n * @param {string} rune\n * @returns {never}\n */\nexport function effect_in_teardown(rune) {\n\tif (DEV) {\n\t\tconst error = new Error(`effect_in_teardown\\n\\`${rune}\\` cannot be used inside an effect cleanup function\\nhttps://svelte.dev/e/effect_in_teardown`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/effect_in_teardown`);\n\t}\n}\n\n/**\n * Effect cannot be created inside a `$derived` value that was not itself created inside an effect\n * @returns {never}\n */\nexport function effect_in_unowned_derived() {\n\tif (DEV) {\n\t\tconst error = new Error(`effect_in_unowned_derived\\nEffect cannot be created inside a \\`$derived\\` value that was not itself created inside an effect\\nhttps://svelte.dev/e/effect_in_unowned_derived`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/effect_in_unowned_derived`);\n\t}\n}\n\n/**\n * `%rune%` can only be used inside an effect (e.g. during component initialisation)\n * @param {string} rune\n * @returns {never}\n */\nexport function effect_orphan(rune) {\n\tif (DEV) {\n\t\tconst error = new Error(`effect_orphan\\n\\`${rune}\\` can only be used inside an effect (e.g. during component initialisation)\\nhttps://svelte.dev/e/effect_orphan`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/effect_orphan`);\n\t}\n}\n\n/**\n * `$effect.pending()` can only be called inside an effect or derived\n * @returns {never}\n */\nexport function effect_pending_outside_reaction() {\n\tif (DEV) {\n\t\tconst error = new Error(`effect_pending_outside_reaction\\n\\`$effect.pending()\\` can only be called inside an effect or derived\\nhttps://svelte.dev/e/effect_pending_outside_reaction`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/effect_pending_outside_reaction`);\n\t}\n}\n\n/**\n * Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state\n * @returns {never}\n */\nexport function effect_update_depth_exceeded() {\n\tif (DEV) {\n\t\tconst error = new Error(`effect_update_depth_exceeded\\nMaximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state\\nhttps://svelte.dev/e/effect_update_depth_exceeded`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);\n\t}\n}\n\n/**\n * Cannot use `flushSync` inside an effect\n * @returns {never}\n */\nexport function flush_sync_in_effect() {\n\tif (DEV) {\n\t\tconst error = new Error(`flush_sync_in_effect\\nCannot use \\`flushSync\\` inside an effect\\nhttps://svelte.dev/e/flush_sync_in_effect`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/flush_sync_in_effect`);\n\t}\n}\n\n/**\n * Cannot commit a fork that was already discarded\n * @returns {never}\n */\nexport function fork_discarded() {\n\tif (DEV) {\n\t\tconst error = new Error(`fork_discarded\\nCannot commit a fork that was already discarded\\nhttps://svelte.dev/e/fork_discarded`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/fork_discarded`);\n\t}\n}\n\n/**\n * Cannot create a fork inside an effect or when state changes are pending\n * @returns {never}\n */\nexport function fork_timing() {\n\tif (DEV) {\n\t\tconst error = new Error(`fork_timing\\nCannot create a fork inside an effect or when state changes are pending\\nhttps://svelte.dev/e/fork_timing`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/fork_timing`);\n\t}\n}\n\n/**\n * `getAbortSignal()` can only be called inside an effect or derived\n * @returns {never}\n */\nexport function get_abort_signal_outside_reaction() {\n\tif (DEV) {\n\t\tconst error = new Error(`get_abort_signal_outside_reaction\\n\\`getAbortSignal()\\` can only be called inside an effect or derived\\nhttps://svelte.dev/e/get_abort_signal_outside_reaction`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/get_abort_signal_outside_reaction`);\n\t}\n}\n\n/**\n * Expected to find a hydratable with key `%key%` during hydration, but did not.\n * @param {string} key\n * @returns {never}\n */\nexport function hydratable_missing_but_required(key) {\n\tif (DEV) {\n\t\tconst error = new Error(`hydratable_missing_but_required\\nExpected to find a hydratable with key \\`${key}\\` during hydration, but did not.\\nhttps://svelte.dev/e/hydratable_missing_but_required`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/hydratable_missing_but_required`);\n\t}\n}\n\n/**\n * Failed to hydrate the application\n * @returns {never}\n */\nexport function hydration_failed() {\n\tif (DEV) {\n\t\tconst error = new Error(`hydration_failed\\nFailed to hydrate the application\\nhttps://svelte.dev/e/hydration_failed`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/hydration_failed`);\n\t}\n}\n\n/**\n * Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`\n * @returns {never}\n */\nexport function invalid_snippet() {\n\tif (DEV) {\n\t\tconst error = new Error(`invalid_snippet\\nCould not \\`{@render}\\` snippet due to the expression being \\`null\\` or \\`undefined\\`. Consider using optional chaining \\`{@render snippet?.()}\\`\\nhttps://svelte.dev/e/invalid_snippet`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/invalid_snippet`);\n\t}\n}\n\n/**\n * `%name%(...)` cannot be used in runes mode\n * @param {string} name\n * @returns {never}\n */\nexport function lifecycle_legacy_only(name) {\n\tif (DEV) {\n\t\tconst error = new Error(`lifecycle_legacy_only\\n\\`${name}(...)\\` cannot be used in runes mode\\nhttps://svelte.dev/e/lifecycle_legacy_only`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/lifecycle_legacy_only`);\n\t}\n}\n\n/**\n * Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value\n * @param {string} key\n * @returns {never}\n */\nexport function props_invalid_value(key) {\n\tif (DEV) {\n\t\tconst error = new Error(`props_invalid_value\\nCannot do \\`bind:${key}={undefined}\\` when \\`${key}\\` has a fallback value\\nhttps://svelte.dev/e/props_invalid_value`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/props_invalid_value`);\n\t}\n}\n\n/**\n * Rest element properties of `$props()` such as `%property%` are readonly\n * @param {string} property\n * @returns {never}\n */\nexport function props_rest_readonly(property) {\n\tif (DEV) {\n\t\tconst error = new Error(`props_rest_readonly\\nRest element properties of \\`$props()\\` such as \\`${property}\\` are readonly\\nhttps://svelte.dev/e/props_rest_readonly`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/props_rest_readonly`);\n\t}\n}\n\n/**\n * The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files\n * @param {string} rune\n * @returns {never}\n */\nexport function rune_outside_svelte(rune) {\n\tif (DEV) {\n\t\tconst error = new Error(`rune_outside_svelte\\nThe \\`${rune}\\` rune is only available inside \\`.svelte\\` and \\`.svelte.js/ts\\` files\\nhttps://svelte.dev/e/rune_outside_svelte`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/rune_outside_svelte`);\n\t}\n}\n\n/**\n * Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.\n * @returns {never}\n */\nexport function state_descriptors_fixed() {\n\tif (DEV) {\n\t\tconst error = new Error(`state_descriptors_fixed\\nProperty descriptors defined on \\`$state\\` objects must contain \\`value\\` and always be \\`enumerable\\`, \\`configurable\\` and \\`writable\\`.\\nhttps://svelte.dev/e/state_descriptors_fixed`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/state_descriptors_fixed`);\n\t}\n}\n\n/**\n * Cannot set prototype of `$state` object\n * @returns {never}\n */\nexport function state_prototype_fixed() {\n\tif (DEV) {\n\t\tconst error = new Error(`state_prototype_fixed\\nCannot set prototype of \\`$state\\` object\\nhttps://svelte.dev/e/state_prototype_fixed`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/state_prototype_fixed`);\n\t}\n}\n\n/**\n * Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`\n * @returns {never}\n */\nexport function state_unsafe_mutation() {\n\tif (DEV) {\n\t\tconst error = new Error(`state_unsafe_mutation\\nUpdating state inside \\`$derived(...)\\`, \\`$inspect(...)\\` or a template expression is forbidden. If the value should not be reactive, declare it without \\`$state\\`\\nhttps://svelte.dev/e/state_unsafe_mutation`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/state_unsafe_mutation`);\n\t}\n}\n\n/**\n * A `` `reset` function cannot be called while an error is still being handled\n * @returns {never}\n */\nexport function svelte_boundary_reset_onerror() {\n\tif (DEV) {\n\t\tconst error = new Error(`svelte_boundary_reset_onerror\\nA \\`\\` \\`reset\\` function cannot be called while an error is still being handled\\nhttps://svelte.dev/e/svelte_boundary_reset_onerror`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);\n\t}\n}","/** True if experimental.async=true */\nexport let async_mode_flag = false;\n/** True if we're not certain that we only have Svelte 5 code in the compilation */\nexport let legacy_mode_flag = false;\n/** True if $inspect.trace is used */\nexport let tracing_mode_flag = false;\n\nexport function enable_async_mode_flag() {\n\tasync_mode_flag = true;\n}\n\n/** ONLY USE THIS DURING TESTING */\nexport function disable_async_mode_flag() {\n\tasync_mode_flag = false;\n}\n\nexport function enable_legacy_mode_flag() {\n\tlegacy_mode_flag = true;\n}\n\nexport function enable_tracing_mode_flag() {\n\ttracing_mode_flag = true;\n}\n","/** @import { Derived, Reaction, Value } from '#client' */\nimport { UNINITIALIZED } from '../../../constants.js';\nimport { snapshot } from '../../shared/clone.js';\nimport { DERIVED, ASYNC, PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants';\nimport { effect_tracking } from '../reactivity/effects.js';\nimport { active_reaction, untrack } from '../runtime.js';\n\n/**\n * @typedef {{\n * traces: Error[];\n * }} TraceEntry\n */\n\n/** @type {{ reaction: Reaction | null, entries: Map } | null} */\nexport let tracing_expressions = null;\n\n/**\n * @param {Value} signal\n * @param {TraceEntry} [entry]\n */\nfunction log_entry(signal, entry) {\n\tconst value = signal.v;\n\n\tif (value === UNINITIALIZED) {\n\t\treturn;\n\t}\n\n\tconst type = get_type(signal);\n\tconst current_reaction = /** @type {Reaction} */ (active_reaction);\n\tconst dirty = signal.wv > current_reaction.wv || current_reaction.wv === 0;\n\tconst style = dirty\n\t\t? 'color: CornflowerBlue; font-weight: bold'\n\t\t: 'color: grey; font-weight: normal';\n\n\t// eslint-disable-next-line no-console\n\tconsole.groupCollapsed(\n\t\tsignal.label ? `%c${type}%c ${signal.label}` : `%c${type}%c`,\n\t\tstyle,\n\t\tdirty ? 'font-weight: normal' : style,\n\t\ttypeof value === 'object' && value !== null && STATE_SYMBOL in value\n\t\t\t? snapshot(value, true)\n\t\t\t: value\n\t);\n\n\tif (type === '$derived') {\n\t\tconst deps = new Set(/** @type {Derived} */ (signal).deps);\n\t\tfor (const dep of deps) {\n\t\t\tlog_entry(dep);\n\t\t}\n\t}\n\n\tif (signal.created) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(signal.created);\n\t}\n\n\tif (dirty && signal.updated) {\n\t\tfor (const updated of signal.updated.values()) {\n\t\t\tif (updated.error) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(updated.error);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (entry) {\n\t\tfor (var trace of entry.traces) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(trace);\n\t\t}\n\t}\n\n\t// eslint-disable-next-line no-console\n\tconsole.groupEnd();\n}\n\n/**\n * @param {Value} signal\n * @returns {'$state' | '$derived' | 'store'}\n */\nfunction get_type(signal) {\n\tif ((signal.f & (DERIVED | ASYNC)) !== 0) return '$derived';\n\treturn signal.label?.startsWith('$') ? 'store' : '$state';\n}\n\n/**\n * @template T\n * @param {() => string} label\n * @param {() => T} fn\n */\nexport function trace(label, fn) {\n\tvar previously_tracing_expressions = tracing_expressions;\n\n\ttry {\n\t\ttracing_expressions = { entries: new Map(), reaction: active_reaction };\n\n\t\tvar start = performance.now();\n\t\tvar value = fn();\n\t\tvar time = (performance.now() - start).toFixed(2);\n\n\t\tvar prefix = untrack(label);\n\n\t\tif (!effect_tracking()) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(`${prefix} %cran outside of an effect (${time}ms)`, 'color: grey');\n\t\t} else if (tracing_expressions.entries.size === 0) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(`${prefix} %cno reactive dependencies (${time}ms)`, 'color: grey');\n\t\t} else {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.group(`${prefix} %c(${time}ms)`, 'color: grey');\n\n\t\t\tvar entries = tracing_expressions.entries;\n\n\t\t\tuntrack(() => {\n\t\t\t\tfor (const [signal, traces] of entries) {\n\t\t\t\t\tlog_entry(signal, traces);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttracing_expressions = null;\n\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.groupEnd();\n\t\t}\n\n\t\treturn value;\n\t} finally {\n\t\ttracing_expressions = previously_tracing_expressions;\n\t}\n}\n\n/**\n * @template {Value} T\n * @param {T} source\n * @param {string} label\n * @returns {T}\n */\nexport function tag(source, label) {\n\tsource.label = label;\n\ttag_proxy(source.v, label);\n\n\treturn source;\n}\n\n/**\n * @param {unknown} value\n * @param {string} label\n */\nexport function tag_proxy(value, label) {\n\t// @ts-expect-error\n\tvalue?.[PROXY_PATH_SYMBOL]?.(label);\n\treturn value;\n}\n\n/**\n * @param {unknown} value\n */\nexport function label(value) {\n\tif (typeof value === 'symbol') return `Symbol(${value.description})`;\n\tif (typeof value === 'function') return '';\n\tif (typeof value === 'object' && value) return '';\n\treturn String(value);\n}\n","import { DEV } from 'esm-env';\nimport { define_property } from './utils.js';\nimport * as e from './errors.js';\n\n/**\n * @param {string} label\n * @returns {Error & { stack: string } | null}\n */\nexport function get_error(label) {\n\tconst error = new Error();\n\tconst stack = get_stack();\n\n\tif (stack.length === 0) {\n\t\treturn null;\n\t}\n\n\tstack.unshift('\\n');\n\n\tdefine_property(error, 'stack', {\n\t\tvalue: stack.join('\\n')\n\t});\n\n\tdefine_property(error, 'name', {\n\t\tvalue: label\n\t});\n\n\treturn /** @type {Error & { stack: string }} */ (error);\n}\n\n/**\n * @returns {string[]}\n */\nexport function get_stack() {\n\t// @ts-ignore - doesn't exist everywhere\n\tconst limit = Error.stackTraceLimit;\n\t// @ts-ignore - doesn't exist everywhere\n\tError.stackTraceLimit = Infinity;\n\tconst stack = new Error().stack;\n\t// @ts-ignore - doesn't exist everywhere\n\tError.stackTraceLimit = limit;\n\n\tif (!stack) return [];\n\n\tconst lines = stack.split('\\n');\n\tconst new_lines = [];\n\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i];\n\t\tconst posixified = line.replaceAll('\\\\', '/');\n\n\t\tif (line.trim() === 'Error') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (line.includes('validate_each_keys')) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (posixified.includes('svelte/src/internal') || posixified.includes('node_modules/.vite')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tnew_lines.push(line);\n\t}\n\n\treturn new_lines;\n}\n\n/**\n * @param {boolean} condition\n * @param {string} message\n */\nexport function invariant(condition, message) {\n\tif (!DEV) {\n\t\tthrow new Error('invariant(...) was not guarded by if (DEV)');\n\t}\n\n\tif (!condition) e.invariant_violation(message);\n}\n","import { lifecycle_outside_component, missing_context } from './errors.js';\n\n/**\n * @template T\n * @param {(key: object) => T} get_context\n * @param {(key: object, context: T) => T} set_context\n * @param {(key: object) => boolean} has_context\n * @returns {[() => T, (context: T) => T, () => boolean]}\n */\nexport function create_context(get_context, set_context, has_context) {\n\tconst key = {};\n\n\treturn [\n\t\t() => {\n\t\t\tif (!has_context(key)) {\n\t\t\t\tmissing_context();\n\t\t\t}\n\n\t\t\treturn get_context(key);\n\t\t},\n\t\t(context) => set_context(key, context),\n\t\t() => has_context(key)\n\t];\n}\n\n/**\n * @typedef {{ p: Context | null, c: Map | null }} Context\n */\n\n/**\n * @param {Context} context\n * @returns {Map | null}\n */\nfunction get_parent_context(context) {\n\tlet parent = context.p;\n\twhile (parent !== null && parent.c === null) {\n\t\tparent = parent.p;\n\t}\n\treturn parent?.c ?? null;\n}\n\n/**\n * @param {Context | null} context\n * @param {string} name\n * @returns {Map}\n */\nexport function get_or_init_context_map(context, name) {\n\tif (context === null) {\n\t\tlifecycle_outside_component(name);\n\t}\n\n\treturn (context.c ??= new Map(get_parent_context(context) || undefined));\n}\n","/** @import { ComponentContext, DevStackEntry, Effect } from '#client' */\nimport { DEV } from 'esm-env';\nimport * as e from './errors.js';\nimport { active_effect, active_reaction } from './runtime.js';\nimport { create_user_effect } from './reactivity/effects.js';\nimport { async_mode_flag, legacy_mode_flag } from '../flags/index.js';\nimport { FILENAME } from '../../constants.js';\nimport { BRANCH_EFFECT, COMPONENT_SYMBOL } from './constants.js';\nimport { define_property } from '../shared/utils.js';\nimport { create_context, get_or_init_context_map } from '../shared/context.js';\n\n/** @type {ComponentContext | null} */\nexport let component_context = null;\n\n/** @param {ComponentContext | null} context */\nexport function set_component_context(context) {\n\tcomponent_context = context;\n}\n\n/** @type {DevStackEntry | null} */\nexport let dev_stack = null;\n\n/** @param {DevStackEntry | null} stack */\nexport function set_dev_stack(stack) {\n\tdev_stack = stack;\n}\n\n/**\n * Execute a callback with a new dev stack entry\n * @param {() => any} callback - Function to execute\n * @param {DevStackEntry['type']} type - Type of block/component\n * @param {any} component - Component function\n * @param {number} line - Line number\n * @param {number} column - Column number\n * @param {Record} [additional] - Any additional properties to add to the dev stack entry\n * @returns {any}\n */\nexport function add_svelte_meta(callback, type, component, line, column, additional) {\n\tconst parent = dev_stack;\n\n\tdev_stack = {\n\t\ttype,\n\t\tfile: component[FILENAME],\n\t\tline,\n\t\tcolumn,\n\t\tparent,\n\t\t...additional\n\t};\n\n\ttry {\n\t\treturn callback();\n\t} finally {\n\t\tdev_stack = parent;\n\t}\n}\n\n/**\n * The current component function. Different from current component context:\n * ```html\n * \n * \n * \n * \n * ```\n * @type {ComponentContext['function']}\n */\nexport let dev_current_component_function = null;\n\n/** @param {ComponentContext['function']} fn */\nexport function set_dev_current_component_function(fn) {\n\tdev_current_component_function = fn;\n}\n\n/**\n * Returns a `[get, set, has]` triplet of functions for working with context in a type-safe way.\n *\n * `get` will throw an error if `set` has not yet been called in the current component or any of\n * its ancestors.\n *\n * @template T\n * @returns {[() => T, (context: T) => T, () => boolean]}\n * @since 5.40.0\n */\nexport function createContext() {\n\treturn /** @type {[() => T, (context: T) => T, () => boolean]} */ (\n\t\tcreate_context(getContext, setContext, hasContext)\n\t);\n}\n\n/**\n * Retrieves the context set with the specified `key` in the current component or any of its\n * ancestors. If multiple components set the same key, the value from the closest one is returned.\n * A `setContext` call in the current component is only visible to `getContext` calls that run after it.\n * Must be called during component initialisation.\n *\n * [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative.\n *\n * @template T\n * @param {any} key\n * @returns {T}\n */\nexport function getContext(key) {\n\tconst context_map = get_or_init_context_map(component_context, 'getContext');\n\tconst result = /** @type {T} */ (context_map.get(key));\n\treturn result;\n}\n\n/**\n * Associates an arbitrary `context` object with the current component and the specified `key`\n * and returns that object. The context is then available to the component itself and all of its\n * descendants (including slotted content) with `getContext`.\n *\n * Like lifecycle functions, this must be called during component initialisation.\n *\n * [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative.\n *\n * @template T\n * @param {any} key\n * @param {T} context\n * @returns {T}\n */\nexport function setContext(key, context) {\n\tconst context_map = get_or_init_context_map(component_context, 'setContext');\n\n\tif (async_mode_flag) {\n\t\tvar flags = /** @type {Effect} */ (active_effect).f;\n\t\tvar valid =\n\t\t\t!active_reaction &&\n\t\t\t(flags & BRANCH_EFFECT) !== 0 &&\n\t\t\t// pop() runs synchronously, so this indicates we're setting context after an await\n\t\t\t!(/** @type {ComponentContext} */ (component_context).i);\n\n\t\tif (!valid) {\n\t\t\te.set_context_after_init();\n\t\t}\n\t}\n\n\tcontext_map.set(key, context);\n\treturn context;\n}\n\n/**\n * Checks whether a given `key` has been set in the context of the current component or any of\n * its ancestors. Must be called during component initialisation.\n *\n * @param {any} key\n * @returns {boolean}\n */\nexport function hasContext(key) {\n\tconst context_map = get_or_init_context_map(component_context, 'hasContext');\n\treturn context_map.has(key);\n}\n\n/**\n * Retrieves the whole context map that belongs to the current component, including entries\n * inherited from its ancestors. Must be called during component initialisation. Useful, for\n * example, if you programmatically create a component and want to pass the existing context to it.\n *\n * @template {Map} [T=Map]\n * @returns {T}\n */\nexport function getAllContexts() {\n\tconst context_map = get_or_init_context_map(component_context, 'getAllContexts');\n\treturn /** @type {T} */ (context_map);\n}\n\n/**\n * @param {Record} props\n * @param {any} runes\n * @param {Function} [fn]\n * @returns {void}\n */\nexport function push(props, runes = false, fn) {\n\tcomponent_context = {\n\t\tp: component_context,\n\t\ti: false,\n\t\tc: null,\n\t\te: null,\n\t\ts: props,\n\t\tx: null,\n\t\tr: /** @type {Effect} */ (active_effect),\n\t\tl: legacy_mode_flag && !runes ? { s: null, u: null, $: [] } : null\n\t};\n\n\tif (DEV) {\n\t\t// component function\n\t\tcomponent_context.function = fn;\n\t\tdev_current_component_function = fn;\n\t}\n}\n\n/**\n * @template {Record} T\n * @param {T} [component]\n * @returns {T}\n */\nexport function pop(component) {\n\tvar context = /** @type {ComponentContext} */ (component_context);\n\tvar effects = context.e;\n\n\tif (effects !== null) {\n\t\tcontext.e = null;\n\n\t\tfor (var fn of effects) {\n\t\t\tcreate_user_effect(fn);\n\t\t}\n\t}\n\n\tif (component !== undefined) {\n\t\tcontext.x = component;\n\t}\n\n\tcontext.i = true;\n\n\tcomponent_context = context.p;\n\n\tif (DEV) {\n\t\tdev_current_component_function = component_context?.function ?? null;\n\t}\n\n\treturn mark_as_component(component);\n}\n\n/**\n * Add a symbol to the object (or create one if undefined) to mark it as a component so it isn't proxified.\n * @param {any} component\n */\nexport function mark_as_component(component = {}) {\n\tdefine_property(component, COMPONENT_SYMBOL, { value: true });\n\treturn component;\n}\n\n/** @returns {boolean} */\nexport function is_runes() {\n\treturn !legacy_mode_flag || (component_context !== null && component_context.l === null);\n}\n","import { run_all } from '../../shared/utils.js';\nimport { is_flushing_sync } from '../reactivity/batch.js';\n\n/** @type {Array<() => void>} */\nlet micro_tasks = [];\n\nfunction run_micro_tasks() {\n\tvar tasks = micro_tasks;\n\tmicro_tasks = [];\n\trun_all(tasks);\n}\n\n/**\n * @param {() => void} fn\n */\nexport function queue_micro_task(fn) {\n\tif (micro_tasks.length === 0 && !is_flushing_sync) {\n\t\tvar tasks = micro_tasks;\n\t\tqueueMicrotask(() => {\n\t\t\t// If this is false, a flushSync happened in the meantime. Do _not_ run new scheduled microtasks in that case\n\t\t\t// as the ordering of microtasks would be broken at that point - consider this case:\n\t\t\t// - queue_micro_task schedules microtask A to flush task X\n\t\t\t// - synchronously after, flushSync runs, processing task X\n\t\t\t// - synchronously after, some other microtask B is scheduled, but not through queue_micro_task but for example a Promise.resolve() in user code\n\t\t\t// - synchronously after, queue_micro_task schedules microtask C to flush task Y\n\t\t\t// - one tick later, microtask A now resolves, flushing task Y before microtask B, which is incorrect\n\t\t\t// This if check prevents that race condition (that realistically will only happen in tests)\n\t\t\tif (tasks === micro_tasks) run_micro_tasks();\n\t\t});\n\t}\n\n\tmicro_tasks.push(fn);\n}\n\n/**\n * Synchronously run any queued tasks.\n */\nexport function flush_tasks() {\n\twhile (micro_tasks.length > 0) {\n\t\trun_micro_tasks();\n\t}\n}\n","/** @import { Derived, Signal } from '#client' */\nimport { CLEAN, CONNECTED, DIRTY, MAYBE_DIRTY } from '#client/constants';\n\nconst STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);\n\n/**\n * @param {Signal} signal\n * @param {number} status\n */\nexport function set_signal_status(signal, status) {\n\tsignal.f = (signal.f & STATUS_MASK) | status;\n}\n\n/**\n * Set a derived's status to CLEAN or MAYBE_DIRTY based on its connection state.\n * @param {Derived} derived\n */\nexport function update_derived_status(derived) {\n\t// Only mark as MAYBE_DIRTY if disconnected and has dependencies.\n\tif ((derived.f & CONNECTED) !== 0 || derived.deps === null) {\n\t\tset_signal_status(derived, CLEAN);\n\t} else {\n\t\tset_signal_status(derived, MAYBE_DIRTY);\n\t}\n}\n","/** @import { Effect } from '#client' */\nimport { CLEAN, DIRTY, MAYBE_DIRTY } from '#client/constants';\nimport { set_signal_status } from './status.js';\n\n/**\n * @param {Effect} effect\n * @param {Set} dirty_effects\n * @param {Set} maybe_dirty_effects\n */\nexport function defer_effect(effect, dirty_effects, maybe_dirty_effects) {\n\tif ((effect.f & DIRTY) !== 0) {\n\t\tdirty_effects.add(effect);\n\t} else if ((effect.f & MAYBE_DIRTY) !== 0) {\n\t\tmaybe_dirty_effects.add(effect);\n\t}\n\n\t// mark as clean so they get scheduled if they depend on pending async state\n\tset_signal_status(effect, CLEAN);\n}\n","import { hydrating } from '../hydration.js';\nimport { clear_text_content, get_first_child } from '../operations.js';\nimport { queue_micro_task } from '../task.js';\nimport { FORM_RESET_HANDLER } from '../../constants.js';\n\n/**\n * @param {HTMLElement} dom\n * @param {boolean} value\n * @returns {void}\n */\nexport function autofocus(dom, value) {\n\tif (value) {\n\t\tconst body = document.body;\n\t\tdom.autofocus = true;\n\n\t\tqueue_micro_task(() => {\n\t\t\tif (document.activeElement === body) {\n\t\t\t\tdom.focus();\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * The child of a textarea actually corresponds to the defaultValue property, so we need\n * to remove it upon hydration to avoid a bug when someone resets the form value.\n * @param {HTMLTextAreaElement} dom\n * @returns {void}\n */\nexport function remove_textarea_child(dom) {\n\tif (hydrating && get_first_child(dom) !== null) {\n\t\tclear_text_content(dom);\n\t}\n}\n\nlet listening_to_form_reset = false;\n\nexport function add_form_reset_listener() {\n\tif (!listening_to_form_reset) {\n\t\tlistening_to_form_reset = true;\n\t\tdocument.addEventListener(\n\t\t\t'reset',\n\t\t\t(evt) => {\n\t\t\t\t// Needs to happen one tick later or else the dom properties of the form\n\t\t\t\t// elements have not updated to their reset values yet\n\t\t\t\tPromise.resolve().then(() => {\n\t\t\t\t\tif (!evt.defaultPrevented) {\n\t\t\t\t\t\tfor (const e of /**@type {HTMLFormElement} */ (evt.target).elements) {\n\t\t\t\t\t\t\t/** @type {any} */ (e)[FORM_RESET_HANDLER]?.();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\t// In the capture phase to guarantee we get noticed of it (no possibility of stopPropagation)\n\t\t\t{ capture: true }\n\t\t);\n\t}\n}\n","import { teardown } from '../../../reactivity/effects.js';\nimport {\n\tactive_effect,\n\tactive_reaction,\n\tset_active_effect,\n\tset_active_reaction\n} from '../../../runtime.js';\nimport { FORM_RESET_HANDLER } from '../../../constants.js';\nimport { add_form_reset_listener } from '../misc.js';\n\n/**\n * Fires the handler once immediately (unless corresponding arg is set to `false`),\n * then listens to the given events until the render effect context is destroyed\n * @param {EventTarget} target\n * @param {Array} events\n * @param {(event?: Event) => void} handler\n * @param {any} call_handler_immediately\n */\nexport function listen(target, events, handler, call_handler_immediately = true) {\n\tif (call_handler_immediately) {\n\t\thandler();\n\t}\n\n\tfor (var name of events) {\n\t\ttarget.addEventListener(name, handler);\n\t}\n\n\tteardown(() => {\n\t\tfor (var name of events) {\n\t\t\ttarget.removeEventListener(name, handler);\n\t\t}\n\t});\n}\n\n/**\n * @template T\n * @param {() => T} fn\n */\nexport function without_reactive_context(fn) {\n\tvar previous_reaction = active_reaction;\n\tvar previous_effect = active_effect;\n\tset_active_reaction(null);\n\tset_active_effect(null);\n\ttry {\n\t\treturn fn();\n\t} finally {\n\t\tset_active_reaction(previous_reaction);\n\t\tset_active_effect(previous_effect);\n\t}\n}\n\n/**\n * Listen to the given event, and then instantiate a global form reset listener if not already done,\n * to notify all bindings when the form is reset\n * @param {HTMLElement} element\n * @param {string} event\n * @param {(is_reset?: true) => void} handler\n * @param {(is_reset?: true) => void} [on_reset]\n */\nexport function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) {\n\telement.addEventListener(event, () => without_reactive_context(handler));\n\tconst prev = /** @type {any} */ (element)[FORM_RESET_HANDLER];\n\tif (prev) {\n\t\t// special case for checkbox that can have multiple binds (group & checked)\n\t\t/** @type {any} */ (element)[FORM_RESET_HANDLER] = () => {\n\t\t\tprev();\n\t\t\ton_reset(true);\n\t\t};\n\t} else {\n\t\t/** @type {any} */ (element)[FORM_RESET_HANDLER] = () => on_reset(true);\n\t}\n\n\tadd_form_reset_listener();\n}\n","/** @import { Blocker, Effect, Source, Value } from '#client' */\nimport { DESTROYED, STALE_REACTION } from '#client/constants';\nimport { DEV } from 'esm-env';\nimport {\n\tcomponent_context,\n\tdev_stack,\n\tis_runes,\n\tset_component_context,\n\tset_dev_stack\n} from '../context.js';\nimport { invoke_error_boundary } from '../error-handling.js';\nimport {\n\tactive_effect,\n\tactive_reaction,\n\tset_active_effect,\n\tset_active_reaction\n} from '../runtime.js';\nimport { Batch, current_batch } from './batch.js';\nimport {\n\tasync_derived,\n\treactivity_loss_tracker,\n\tderived,\n\tderived_safe_equal,\n\tset_reactivity_loss_tracker\n} from './deriveds.js';\nimport { aborted } from './effects.js';\n\n/**\n * @param {Blocker[]} blockers\n * @param {Array<() => any>} sync\n * @param {Array<() => Promise>} async\n * @param {(values: Value[]) => any} fn\n */\nexport function flatten(blockers, sync, async, fn) {\n\tconst d = is_runes() ? derived : derived_safe_equal;\n\n\t// Filter out already-settled blockers - no need to wait for them\n\tvar pending = blockers.filter((b) => !b.settled);\n\n\tvar deriveds = sync.map(d);\n\n\tif (DEV) {\n\t\tderiveds.forEach((d, i) => {\n\t\t\t// TODO this is kinda useful for debugging but a lousy implementation —\n\t\t\t// maybe the compiler could pass through the template string\n\t\t\td.label = sync[i]\n\t\t\t\t.toString()\n\t\t\t\t.replace('() => ', '')\n\t\t\t\t.replaceAll('$.eager(() => ', '$state.eager(')\n\t\t\t\t.replace(/\\$\\.get\\((.+?)\\)/g, (_, id) => id);\n\t\t});\n\t}\n\n\tif (async.length === 0 && pending.length === 0) {\n\t\tfn(deriveds);\n\t\treturn;\n\t}\n\n\tvar parent = /** @type {Effect} */ (active_effect);\n\n\tvar restore = capture();\n\tvar blocker_promise =\n\t\tpending.length === 1\n\t\t\t? pending[0].promise\n\t\t\t: pending.length > 1\n\t\t\t\t? Promise.all(pending.map((b) => b.promise))\n\t\t\t\t: null;\n\n\t/**\n\t * @param {Source[]} async\n\t */\n\tfunction finish(async) {\n\t\tif ((parent.f & DESTROYED) !== 0) {\n\t\t\treturn;\n\t\t}\n\n\t\trestore();\n\n\t\ttry {\n\t\t\tfn([...deriveds, ...async]);\n\t\t} catch (error) {\n\t\t\tinvoke_error_boundary(error, parent);\n\t\t}\n\n\t\tunset_context();\n\t}\n\n\tvar decrement_pending = increment_pending();\n\n\t// Fast path: blockers but no async expressions\n\tif (async.length === 0) {\n\t\t/** @type {Promise} */ (blocker_promise).then(() => finish([])).finally(decrement_pending);\n\t\treturn;\n\t}\n\n\t// Full path: has async expressions\n\tfunction run() {\n\t\tPromise.all(async.map((expression) => async_derived(expression)))\n\t\t\t.then(finish)\n\t\t\t.catch((error) => invoke_error_boundary(error, parent))\n\t\t\t.finally(decrement_pending);\n\t}\n\n\tif (blocker_promise) {\n\t\tblocker_promise.then(() => {\n\t\t\tif ((parent.f & DESTROYED) !== 0) {\n\t\t\t\tdecrement_pending();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\trestore();\n\t\t\trun();\n\t\t\tunset_context();\n\t\t});\n\t} else {\n\t\trun();\n\t}\n}\n\n/**\n * @param {Blocker[]} blockers\n * @param {(values: Value[]) => any} fn\n */\nexport function run_after_blockers(blockers, fn) {\n\tflatten(blockers, [], [], fn);\n}\n\n/**\n * Captures the current effect context so that we can restore it after\n * some asynchronous work has happened (so that e.g. `await a + b`\n * causes `b` to be registered as a dependency).\n */\nexport function capture() {\n\tvar previous_effect = /** @type {Effect} */ (active_effect);\n\tvar previous_reaction = active_reaction;\n\tvar previous_component_context = component_context;\n\tvar previous_batch = /** @type {Batch} */ (current_batch);\n\n\tif (DEV) {\n\t\tvar previous_dev_stack = dev_stack;\n\t}\n\n\treturn function restore(activate_batch = true) {\n\t\tset_active_effect(previous_effect);\n\t\tset_active_reaction(previous_reaction);\n\t\tset_component_context(previous_component_context);\n\n\t\tif (activate_batch && (previous_effect.f & DESTROYED) === 0) {\n\t\t\t// TODO we only need optional chaining here because `{#await ...}` blocks\n\t\t\t// are anomalous. Once we retire them we can get rid of it\n\t\t\tprevious_batch?.activate();\n\t\t\tprevious_batch?.apply();\n\t\t}\n\n\t\tif (DEV) {\n\t\t\tset_reactivity_loss_tracker(null);\n\t\t\tset_dev_stack(previous_dev_stack);\n\t\t}\n\t};\n}\n\n/** `true` between a `save` thunk restoring a context and the end of that synchronous segment */\nvar restored = false;\n\n/**\n * Wraps an `await` expression in such a way that the effect context that was\n * active before the expression evaluated can be reapplied afterwards —\n * `await a + b` becomes `(await $.save(a))() + b`\n * @template T\n * @param {Promise} promise\n * @returns {Promise<() => T>}\n */\nexport async function save(promise) {\n\tvar restore = capture();\n\t// the context restored by an earlier `save` in this expression must not\n\t// outlive the synchronous segment that is about to end at this `await`\n\tunsave();\n\tvar value = await promise;\n\n\treturn () => {\n\t\trestore();\n\t\trestored = true;\n\t\treturn value;\n\t};\n}\n\n/**\n * Unset the context if a `save` thunk restored it in the current synchronous segment,\n * so that a foreign microtask can never run inside a restored reaction context.\n * Called at every suspension point, and at the end of async expression bodies —\n * `async () => (await $.save(a))().b` becomes `async () => { try { return (await $.save(a))().b; } finally { $.unsave(); } }`\n * @template T\n * @param {T} [value]\n * @returns {T}\n */\nexport function unsave(value) {\n\tif (restored) unset_context();\n\treturn /** @type {T} */ (value);\n}\n\n/**\n * Reset `current_async_effect` after the `promise` resolves, so\n * that we can emit `await_reactivity_loss` warnings\n * @template T\n * @param {Promise} promise\n * @returns {Promise<() => T>}\n */\nexport async function track_reactivity_loss(promise) {\n\tunsave();\n\tvar previous_reactivity_loss_tracker = reactivity_loss_tracker;\n\t// Ensure that unrelated reads after an async operation is kicked off don't cause false positives\n\tqueueMicrotask(() => {\n\t\tif (reactivity_loss_tracker === previous_reactivity_loss_tracker) {\n\t\t\tset_reactivity_loss_tracker(null);\n\t\t}\n\t});\n\n\tvar value = await promise;\n\n\treturn () => {\n\t\tset_reactivity_loss_tracker(previous_reactivity_loss_tracker);\n\t\t// While this can result in false negatives it also guards against the more important\n\t\t// false positives that would occur if this is the last in a chain of async operations,\n\t\t// and the reactivity_loss_tracker would then stay around until the next async operation happens.\n\t\tqueueMicrotask(() => {\n\t\t\tif (reactivity_loss_tracker === previous_reactivity_loss_tracker) {\n\t\t\t\tset_reactivity_loss_tracker(null);\n\t\t\t}\n\t\t});\n\n\t\treturn value;\n\t};\n}\n\n/**\n * Used in `for await` loops in DEV, so\n * that we can emit `await_reactivity_loss` warnings\n * after each `async_iterator` result resolves and\n * after the `async_iterator` return resolves (if it runs)\n * @template T\n * @template TReturn\n * @param {Iterable | AsyncIterable} iterable\n * @returns {AsyncGenerator}\n */\nexport async function* for_await_track_reactivity_loss(iterable) {\n\t// This is based on the algorithms described in ECMA-262:\n\t// ForIn/OfBodyEvaluation\n\t// https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset\n\t// AsyncIteratorClose\n\t// https://tc39.es/ecma262/multipage/abstract-operations.html#sec-asynciteratorclose\n\n\t/** @type {AsyncIterator} */\n\t// @ts-ignore\n\tconst iterator = iterable[Symbol.asyncIterator]?.() ?? iterable[Symbol.iterator]?.();\n\n\tif (iterator === undefined) {\n\t\tthrow new TypeError('value is not async iterable');\n\t}\n\n\t// eslint-disable-next-line no-useless-assignment\n\tlet invoke_return = true;\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = (await track_reactivity_loss(iterator.next()))();\n\t\t\tif (done) {\n\t\t\t\tinvoke_return = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar prev = reactivity_loss_tracker;\n\t\t\ttry {\n\t\t\t\tyield value;\n\t\t\t} catch (e) {\n\t\t\t\tset_reactivity_loss_tracker(prev);\n\t\t\t\t// If the yield throws, we need to call `return` but not return its value, instead rethrow\n\t\t\t\tif (iterator.return !== undefined) {\n\t\t\t\t\t(await track_reactivity_loss(iterator.return()))();\n\t\t\t\t}\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t\tset_reactivity_loss_tracker(prev);\n\t\t}\n\t} catch (error) {\n\t\tinvoke_return = false;\n\t\tthrow error;\n\t} finally {\n\t\t// If the iterator had an abrupt completion (break) and `return` is defined on the iterator, call it and return the value\n\t\tif (invoke_return && iterator.return !== undefined) {\n\t\t\t// eslint-disable-next-line no-unsafe-finally\n\t\t\treturn /** @type {TReturn} */ ((await track_reactivity_loss(iterator.return()))().value);\n\t\t}\n\t}\n}\n\nexport function unset_context(deactivate_batch = true) {\n\trestored = false;\n\tset_active_effect(null);\n\tset_active_reaction(null);\n\tset_component_context(null);\n\tif (deactivate_batch) current_batch?.deactivate();\n\n\tif (DEV) {\n\t\tset_reactivity_loss_tracker(null);\n\t\tset_dev_stack(null);\n\t}\n}\n\n/**\n * @param {Array<() => void | Promise>} thunks\n */\nexport function run(thunks) {\n\tconst restore = capture();\n\n\tconst decrement_pending = increment_pending();\n\n\tvar active = /** @type {Effect} */ (active_effect);\n\n\t/** @type {null | { error: any }} */\n\tvar errored = null;\n\n\t/** @param {any} error */\n\tconst handle_error = (error) => {\n\t\terrored = { error }; // wrap in object in case a promise rejects with a falsy value\n\n\t\tif (!aborted(active)) {\n\t\t\tinvoke_error_boundary(error, active);\n\t\t}\n\t};\n\n\tvar promise = Promise.resolve(thunks[0]()).catch(handle_error);\n\n\t/** @type {Blocker} */\n\tvar blocker = { promise, settled: false };\n\tvar blockers = [blocker];\n\n\tpromise.finally(() => {\n\t\tblocker.settled = true;\n\t\tunset_context();\n\t});\n\n\tfor (const fn of thunks.slice(1)) {\n\t\tpromise = promise\n\t\t\t.then(() => {\n\t\t\t\trestore();\n\n\t\t\t\ttry {\n\t\t\t\t\tif (errored) {\n\t\t\t\t\t\tthrow errored.error;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (aborted(active)) {\n\t\t\t\t\t\tthrow STALE_REACTION;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn fn();\n\t\t\t\t} finally {\n\t\t\t\t\t// We gotta unset context directly in case the function returns a promise, in which case\n\t\t\t\t\t// unset_context in .finally() would be too late ...\n\t\t\t\t\tunset_context();\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(handle_error);\n\n\t\tconst blocker = { promise, settled: false };\n\t\tblockers.push(blocker);\n\n\t\tpromise.finally(() => {\n\t\t\tblocker.settled = true;\n\t\t\t// ... but we also need it after such a promise has resolved in case it restores our context\n\t\t\tunset_context();\n\t\t});\n\t}\n\n\tpromise\n\t\t// wait one more tick, so that template effects are\n\t\t// guaranteed to run before `$effect(...)`\n\t\t.then(() => Promise.resolve())\n\t\t.finally(decrement_pending);\n\n\treturn blockers;\n}\n\n/**\n * @param {Blocker[]} blockers\n */\nexport function wait(blockers) {\n\treturn Promise.all(blockers.map((b) => b.promise));\n}\n\n/**\n * @returns {(skip?: boolean) => void}\n */\nexport function increment_pending() {\n\tvar effect = /** @type {Effect} */ (active_effect);\n\tvar boundary = effect.b; // undefined if called outside the render tree, e.g. a standalone $effect.root\n\tvar batch = /** @type {Batch} */ (current_batch);\n\tvar blocking = !!boundary?.is_rendered();\n\n\tboundary?.update_pending_count(1, batch);\n\tbatch.increment(blocking, effect);\n\n\treturn () => {\n\t\tboundary?.update_pending_count(-1, batch);\n\t\tbatch.decrement(blocking, effect);\n\t};\n}\n","/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */\n/** @import { Batch } from './batch.js'; */\n/** @import { Boundary } from '../dom/blocks/boundary.js'; */\nimport { DEV } from 'esm-env';\nimport {\n\tERROR_VALUE,\n\tDERIVED,\n\tDIRTY,\n\tEFFECT_PRESERVED,\n\tSTALE_REACTION,\n\tASYNC,\n\tDESTROYED,\n\tCLEAN,\n\tREACTION_RAN,\n\tINERT\n} from '#client/constants';\nimport {\n\tactive_reaction,\n\tactive_effect,\n\tupdate_reaction,\n\tincrement_write_version,\n\tset_active_effect,\n\tpush_reaction_value,\n\tis_destroying_effect,\n\tupdate_effect,\n\tremove_reactions,\n\tskipped_deps,\n\tnew_deps\n} from '../runtime.js';\nimport { without_reactive_context } from '../dom/elements/bindings/shared.js';\nimport { equals, safe_equals } from './equality.js';\nimport * as e from '../errors.js';\nimport * as w from '../warnings.js';\nimport {\n\tasync_effect,\n\tdestroy_effect,\n\tdestroy_effect_children,\n\teffect_tracking,\n\tteardown\n} from './effects.js';\nimport { eager_effects, internal_set, set_eager_effects, source } from './sources.js';\nimport { get_error } from '../../shared/dev.js';\nimport { async_mode_flag, tracing_mode_flag } from '../../flags/index.js';\nimport { component_context } from '../context.js';\nimport { UNINITIALIZED } from '../../../constants.js';\nimport { batch_values, current_batch, previous_batch } from './batch.js';\nimport { increment_pending, unset_context } from './async.js';\nimport { deferred, includes, noop } from '../../shared/utils.js';\nimport { set_signal_status, update_derived_status } from './status.js';\n\n/**\n * This allows us to track 'reactivity loss' that occurs when signals\n * are read after a non-context-restoring `await`. Dev-only\n * @type {{ effect: Effect, effect_deps: Set, warned: boolean } | null}\n */\nexport let reactivity_loss_tracker = null;\n\n/** @param {{ effect: Effect, effect_deps: Set, warned: boolean } | null} v */\nexport function set_reactivity_loss_tracker(v) {\n\treactivity_loss_tracker = v;\n}\n\nexport const recent_async_deriveds = new Set();\n\n/**\n * @template V\n * @param {() => V} fn\n * @returns {Derived}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function derived(fn) {\n\tvar flags = DERIVED | DIRTY;\n\n\tif (active_effect !== null) {\n\t\t// Since deriveds are evaluated lazily, any effects created inside them are\n\t\t// created too late to ensure that the parent effect is added to the tree\n\t\tactive_effect.f |= EFFECT_PRESERVED;\n\t}\n\n\t/** @type {Derived} */\n\tconst signal = {\n\t\tctx: component_context,\n\t\tdeps: null,\n\t\teffects: null,\n\t\tequals,\n\t\tf: flags,\n\t\tfn,\n\t\treactions: null,\n\t\trv: 0,\n\t\tv: /** @type {V} */ (UNINITIALIZED),\n\t\twv: 0,\n\t\tparent: active_effect,\n\t\tac: null\n\t};\n\n\tif (DEV && tracing_mode_flag) {\n\t\tsignal.created = get_error('created at');\n\t}\n\n\treturn signal;\n}\n\nexport const OBSOLETE = Symbol('obsolete');\n\n/**\n * @template V\n * @param {() => V | Promise} fn\n * @param {string} [label]\n * @param {string} [location] If provided, print a warning if the value is not read immediately after update\n * @returns {Promise>}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function async_derived(fn, label, location) {\n\tlet parent = /** @type {Effect | null} */ (active_effect);\n\n\tif (parent === null) {\n\t\te.async_derived_orphan();\n\t}\n\n\tvar promise = /** @type {Promise} */ (/** @type {unknown} */ (undefined));\n\tvar signal = source(/** @type {V} */ (UNINITIALIZED));\n\n\tif (DEV) signal.label = label ?? fn.toString();\n\n\t// only suspend in async deriveds created on initialisation\n\tvar should_suspend = !active_reaction;\n\n\t/** @type {Set>>} */\n\tvar deferreds = new Set();\n\n\tasync_effect(() => {\n\t\tvar effect = /** @type {Effect} */ (active_effect);\n\n\t\tif (DEV) {\n\t\t\treactivity_loss_tracker = { effect, effect_deps: new Set(), warned: false };\n\t\t}\n\n\t\t/** @type {ReturnType>} */\n\t\tvar d = deferred();\n\t\tpromise = d.promise;\n\n\t\ttry {\n\t\t\t// If this code is changed at some point, make sure to still access the then property\n\t\t\t// of fn() to read any signals it might access, so that we track them as dependencies.\n\t\t\t// We call `unset_context` to undo any `save` calls that happen inside `fn()`\n\t\t\tPromise.resolve(fn())\n\t\t\t\t.then(d.resolve, (e) => {\n\t\t\t\t\t// if the promise was rejected by the user, via `getAbortSignal`, then\n\t\t\t\t\t// wait for a subsequent resolution instead of flushing the batch\n\t\t\t\t\tif (e !== STALE_REACTION) d.reject(e);\n\t\t\t\t})\n\t\t\t\t.finally(unset_context);\n\t\t} catch (error) {\n\t\t\td.reject(error);\n\t\t\tunset_context();\n\t\t}\n\n\t\tif (DEV) {\n\t\t\tif (reactivity_loss_tracker) {\n\t\t\t\t// Reused deps from previous run (indices 0 to skipped_deps-1)\n\t\t\t\t// We deliberately only track direct dependencies of the async expression to encourage\n\t\t\t\t// dependencies being directly visible at the point of the expression\n\t\t\t\tif (effect.deps !== null) {\n\t\t\t\t\tfor (let i = 0; i < skipped_deps; i += 1) {\n\t\t\t\t\t\treactivity_loss_tracker.effect_deps.add(effect.deps[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// New deps discovered this run\n\t\t\t\tif (new_deps !== null) {\n\t\t\t\t\tfor (let i = 0; i < new_deps.length; i += 1) {\n\t\t\t\t\t\treactivity_loss_tracker.effect_deps.add(new_deps[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treactivity_loss_tracker = null;\n\t\t}\n\n\t\tvar batch = /** @type {Batch} */ (current_batch);\n\n\t\tif (should_suspend) {\n\t\t\t// we only increment the batch's pending state for updates, not creation, otherwise\n\t\t\t// we will decrement to zero before the work that depends on this promise (e.g. a\n\t\t\t// template effect) has initialized, causing the batch to resolve prematurely\n\t\t\tif ((effect.f & REACTION_RAN) !== 0) {\n\t\t\t\tvar decrement_pending = increment_pending();\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t// boundary can be null if the async derived is inside an $effect.root not connected to the component render tree\n\t\t\t\tparent.b?.is_rendered()\n\t\t\t) {\n\t\t\t\tbatch.async_deriveds.get(effect)?.reject(OBSOLETE);\n\t\t\t} else {\n\t\t\t\t// While the boundary is still showing pending, a new run supersedes all older in-flight runs\n\t\t\t\t// for this async expression. Cancel eagerly so resolution cannot commit stale values.\n\t\t\t\tfor (const d of deferreds.values()) {\n\t\t\t\t\td.reject(OBSOLETE);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdeferreds.add(d);\n\t\t\tbatch.async_deriveds.set(effect, d);\n\t\t}\n\n\t\t/**\n\t\t * @param {any} value\n\t\t * @param {unknown} error\n\t\t */\n\t\tconst handler = (value, error = undefined) => {\n\t\t\tif (DEV) {\n\t\t\t\treactivity_loss_tracker = null;\n\t\t\t}\n\n\t\t\tdecrement_pending?.();\n\t\t\tdeferreds.delete(d);\n\n\t\t\tif (error === OBSOLETE) return;\n\n\t\t\tbatch.activate();\n\n\t\t\tif (error) {\n\t\t\t\tsignal.f |= ERROR_VALUE;\n\n\t\t\t\t// @ts-expect-error the error is the wrong type, but we don't care\n\t\t\t\tinternal_set(signal, error);\n\t\t\t} else {\n\t\t\t\tif ((signal.f & ERROR_VALUE) !== 0) {\n\t\t\t\t\tsignal.f ^= ERROR_VALUE;\n\t\t\t\t}\n\n\t\t\t\tif (DEV && location !== undefined && !signal.equals(value)) {\n\t\t\t\t\trecent_async_deriveds.add(signal);\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (recent_async_deriveds.has(signal) && (effect.f & DESTROYED) === 0) {\n\t\t\t\t\t\t\tw.await_waterfall(/** @type {string} */ (signal.label), location);\n\t\t\t\t\t\t\trecent_async_deriveds.delete(signal);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tinternal_set(signal, value);\n\t\t\t}\n\n\t\t\tbatch.deactivate();\n\t\t};\n\n\t\td.promise.then(handler, (e) => handler(null, e || 'unknown'));\n\t});\n\n\tteardown(() => {\n\t\tfor (const d of deferreds) {\n\t\t\td.reject(OBSOLETE);\n\t\t}\n\t});\n\n\tif (DEV) {\n\t\t// add a flag that lets this be printed as a derived\n\t\t// when using `$inspect.trace()`\n\t\tsignal.f |= ASYNC;\n\t}\n\n\treturn new Promise((fulfil) => {\n\t\t/** @param {Promise} p */\n\t\tfunction next(p) {\n\t\t\tfunction go() {\n\t\t\t\tif (p === promise) {\n\t\t\t\t\tfulfil(signal);\n\t\t\t\t} else {\n\t\t\t\t\t// if the effect re-runs before the initial promise\n\t\t\t\t\t// resolves, delay resolution until we have a value\n\t\t\t\t\tnext(promise);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.then(go, go);\n\t\t}\n\n\t\tnext(promise);\n\t});\n}\n\n/**\n * @template V\n * @param {() => V} fn\n * @returns {Derived}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function user_derived(fn) {\n\tconst d = derived(fn);\n\n\tif (!async_mode_flag) push_reaction_value(d);\n\n\treturn d;\n}\n\n/**\n * @template V\n * @param {() => V} fn\n * @returns {Derived}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function derived_safe_equal(fn) {\n\tconst signal = derived(fn);\n\tsignal.equals = safe_equals;\n\treturn signal;\n}\n\n/**\n * @param {Derived} derived\n * @returns {void}\n */\nexport function destroy_derived_effects(derived) {\n\tvar effects = derived.effects;\n\n\tif (effects !== null) {\n\t\tderived.effects = null;\n\n\t\tfor (var i = 0; i < effects.length; i += 1) {\n\t\t\tdestroy_effect(/** @type {Effect} */ (effects[i]));\n\t\t}\n\t}\n}\n\n/**\n * The currently updating deriveds, used to detect infinite recursion\n * in dev mode and provide a nicer error than 'too much recursion'\n * @type {Derived[]}\n */\nlet stack = [];\n\n/**\n * @template T\n * @param {Derived} derived\n * @returns {T}\n */\nexport function execute_derived(derived) {\n\tvar value;\n\tvar prev_active_effect = active_effect;\n\tvar parent = derived.parent;\n\n\tif (\n\t\t!is_destroying_effect &&\n\t\tparent !== null &&\n\t\tderived.v !== UNINITIALIZED && // if it was never evaluated before, it's guaranteed to fail downstream, so we try to execute instead\n\t\t(parent.f & (DESTROYED | INERT)) !== 0\n\t) {\n\t\tw.derived_inert();\n\n\t\treturn derived.v;\n\t}\n\n\tset_active_effect(parent);\n\n\tif (DEV) {\n\t\tlet prev_eager_effects = eager_effects;\n\t\tset_eager_effects(new Set());\n\t\ttry {\n\t\t\tif (includes.call(stack, derived)) {\n\t\t\t\te.derived_references_self();\n\t\t\t}\n\n\t\t\tstack.push(derived);\n\n\t\t\tdestroy_derived_effects(derived);\n\t\t\tvalue = update_reaction(derived);\n\t\t} finally {\n\t\t\tset_active_effect(prev_active_effect);\n\t\t\tset_eager_effects(prev_eager_effects);\n\t\t\tstack.pop();\n\t\t}\n\t} else {\n\t\ttry {\n\t\t\tdestroy_derived_effects(derived);\n\t\t\tvalue = update_reaction(derived);\n\t\t} finally {\n\t\t\tset_active_effect(prev_active_effect);\n\t\t}\n\t}\n\n\treturn value;\n}\n\n/**\n * @param {Derived} derived\n * @returns {void}\n */\nexport function update_derived(derived) {\n\tvar value = execute_derived(derived);\n\n\tif (!derived.equals(value)) {\n\t\tderived.wv = increment_write_version();\n\n\t\t// in a fork, we don't update the underlying value, just `batch_values`.\n\t\t// the underlying value will be updated when the fork is committed.\n\t\t// otherwise, the next time we get here after a 'real world' state\n\t\t// change, `derived.equals` may incorrectly return `true`\n\t\tif (!current_batch?.is_fork || derived.deps === null) {\n\t\t\tif (current_batch !== null) {\n\t\t\t\t// We also write to previous_batch because if it exists, it is a sign that we're\n\t\t\t\t// currently in the process of flushing effects. These updates to deriveds may belong\n\t\t\t\t// to the previous batch, not the new one (which can already exist if an earlier\n\t\t\t\t// effect wrote to a source). This can cause bugs when running batch.#commit() later,\n\t\t\t\t// but not adding it to current_batch can, too, so we add it to both.\n\t\t\t\t// See https://github.com/sveltejs/svelte/pull/18117 for more details.\n\t\t\t\tcurrent_batch.capture(derived, value, true);\n\t\t\t\tprevious_batch?.capture(derived, value, true);\n\t\t\t} else {\n\t\t\t\tderived.v = value;\n\t\t\t}\n\n\t\t\t// deriveds without dependencies should never be recomputed\n\t\t\tif (derived.deps === null) {\n\t\t\t\tset_signal_status(derived, CLEAN);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// don't mark derived clean if we're reading it inside a\n\t// cleanup function, or it will cache a stale value\n\tif (is_destroying_effect) {\n\t\treturn;\n\t}\n\n\t// During time traveling we don't want to reset the status so that\n\t// traversal of the graph in the other batches still happens\n\tif (batch_values !== null) {\n\t\t// only cache the value if we're in a tracking context, otherwise we won't\n\t\t// clear the cache in `mark_reactions` when dependencies are updated\n\t\tif (effect_tracking() || current_batch?.is_fork) {\n\t\t\tbatch_values.set(derived, value);\n\t\t}\n\t} else {\n\t\tupdate_derived_status(derived);\n\t}\n}\n\n/**\n * @param {Derived} derived\n */\nexport function freeze_derived_effects(derived) {\n\tif (derived.effects === null) return;\n\n\tfor (const e of derived.effects) {\n\t\t// if the effect has a teardown function or abort signal, call it\n\t\tif (e.teardown || e.ac) {\n\t\t\te.teardown?.();\n\t\t\tif (e.ac !== null) {\n\t\t\t\twithout_reactive_context(() => {\n\t\t\t\t\t/** @type {AbortController} */ (e.ac).abort(STALE_REACTION);\n\t\t\t\t\te.ac = null;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// make it a noop so it doesn't get called again if the derived\n\t\t\t// is unfrozen. we don't set it to `null`, because the existence\n\t\t\t// of a teardown function is what determines whether the\n\t\t\t// effect runs again during unfreezing (but not for teardown-only effects)\n\t\t\tif (e.fn !== null) e.teardown = noop;\n\n\t\t\tremove_reactions(e, 0);\n\t\t\tdestroy_effect_children(e);\n\t\t}\n\t}\n}\n\n/**\n * @param {Derived} derived\n */\nexport function unfreeze_derived_effects(derived) {\n\tif (derived.effects === null) return;\n\n\tfor (const e of derived.effects) {\n\t\t// if the effect was previously frozen — indicated by the presence\n\t\t// of a teardown function — unfreeze it\n\t\tif (e.teardown && e.fn !== null) {\n\t\t\tupdate_effect(e);\n\t\t}\n\t}\n}\n","/** @import { Fork } from 'svelte' */\n/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */\nimport {\n\tBLOCK_EFFECT,\n\tBRANCH_EFFECT,\n\tCLEAN,\n\tDESTROYED,\n\tDIRTY,\n\tEFFECT,\n\tASYNC,\n\tINERT,\n\tRENDER_EFFECT,\n\tROOT_EFFECT,\n\tMAYBE_DIRTY,\n\tDERIVED,\n\tEAGER_EFFECT,\n\tERROR_VALUE,\n\tMANAGED_EFFECT,\n\tREACTION_RAN,\n\tDESTROYING\n} from '#client/constants';\nimport { async_mode_flag } from '../../flags/index.js';\nimport { deferred, define_property, includes } from '../../shared/utils.js';\nimport {\n\tactive_reaction,\n\tget,\n\tincrement_write_version,\n\tis_dirty,\n\tupdate_effect\n} from '../runtime.js';\nimport * as e from '../errors.js';\nimport { flush_tasks, queue_micro_task } from '../dom/task.js';\nimport { DEV } from 'esm-env';\nimport { invoke_error_boundary } from '../error-handling.js';\nimport { flush_eager_effects, old_values, set_eager_effects, source, update } from './sources.js';\nimport { eager_effect, teardown, unlink_effect } from './effects.js';\nimport { defer_effect } from './utils.js';\nimport { UNINITIALIZED } from '../../../constants.js';\nimport { set_signal_status } from './status.js';\nimport { invariant } from '../../shared/dev.js';\nimport { log_effect_tree } from '../dev/debug.js';\nimport { OBSOLETE } from './deriveds.js';\n\n/** @type {Batch | null} */\nlet first_batch = null;\n\n/** @type {Batch | null} */\nlet last_batch = null;\n\n/** @type {Batch | null} */\nexport let current_batch = null;\n\n/**\n * This is needed to avoid overwriting inputs\n * @type {Batch | null}\n */\nexport let previous_batch = null;\n\n/**\n * When time travelling (i.e. working in one batch, while other batches\n * still have ongoing work), we ignore the real values of affected\n * signals in favour of their values within the batch\n * @type {Map | null}\n */\nexport let batch_values = null;\n\n/** @type {Effect | null} */\nlet last_scheduled_effect = null;\n\nexport let is_flushing_sync = false;\nlet is_processing = false;\n\n/**\n * During traversal, this is an array. Newly created effects are (if not immediately\n * executed) pushed to this array, rather than going through the scheduling\n * rigamarole that would cause another turn of the flush loop.\n * @type {Effect[] | null}\n */\nexport let collected_effects = null;\n\n/**\n * An array of effects that are marked during traversal as a result of a `set`\n * (not `internal_set`) call. These will be added to the next batch and\n * trigger another `batch.process()`\n * @type {Effect[] | null}\n * @deprecated when we get rid of legacy mode and stores, we can get rid of this\n */\nexport let legacy_updates = null;\n\nvar flush_count = 0;\n\n/** @type {Set} */\nvar source_stacks = new Set();\n\nlet uid = 1;\n\nexport class Batch {\n\tid = uid++;\n\n\t/** True as soon as `#process` was called */\n\t#started = false;\n\n\tlinked = true;\n\n\t/** @type {Batch | null} */\n\t#prev = null;\n\n\t/** @type {Batch | null} */\n\t#next = null;\n\n\t/** @type {Map>>} */\n\tasync_deriveds = new Map();\n\n\t/**\n\t * The current values of any signals that are updated in this batch.\n\t * Tuple format: [value, is_derived] (note: is_derived is false for deriveds, too, if they were overridden via assignment)\n\t * They keys of this map are identical to `this.#previous`\n\t * @type {Map}\n\t */\n\tcurrent = new Map();\n\n\t/**\n\t * The values of any signals (sources and deriveds) that are updated in this batch _before_ those updates took place.\n\t * They keys of this map are identical to `this.#current`\n\t * @type {Map}\n\t */\n\tprevious = new Map();\n\n\t/**\n\t * When the batch is committed (and the DOM is updated), we need to remove old branches\n\t * and append new ones by calling the functions added inside (if/each/key/etc) blocks\n\t * @type {Set<(batch: Batch) => void>}\n\t */\n\t#commit_callbacks = new Set();\n\n\t/**\n\t * If a fork is discarded, we need to destroy any effects that are no longer needed\n\t * @type {Set<(batch: Batch) => void>}\n\t */\n\t#discard_callbacks = new Set();\n\n\t/**\n\t * The number of async effects that are currently in flight\n\t */\n\t#pending = 0;\n\n\t/**\n\t * Async effects that are currently in flight, _not_ inside a pending boundary\n\t * @type {Map}\n\t */\n\t#blocking_pending = new Map();\n\n\t/**\n\t * A deferred that resolves when the batch is committed, used with `settled()`\n\t * TODO replace with Promise.withResolvers once supported widely enough\n\t * @type {{ promise: Promise, resolve: (value?: any) => void, reject: (reason: unknown) => void } | null}\n\t */\n\t#deferred = null;\n\n\t/**\n\t * Effects that were scheduled in this batch but not yet 'resolved' into the\n\t * root effects that need to be flushed. Resolving — the upwards traversal that\n\t * marks the path to each effect on the shared effect tree (see #resolve) — is\n\t * deferred until the batch is processed, so that the markers are created and\n\t * consumed within a single traversal. Scheduling into other batches (which can\n\t * happen concurrently, e.g. while a batch is committed) can therefore never\n\t * observe (and be confused by) this batch's markers.\n\t * May contain duplicates — deduplication happens during resolving\n\t * @type {Effect[]}\n\t */\n\t#scheduled = [];\n\n\t/**\n\t * Effects created while this batch was active.\n\t * @type {Effect[]}\n\t */\n\t#new_effects = [];\n\n\t/**\n\t * Deferred effects (which run after async work has completed) that are DIRTY\n\t * @type {Set}\n\t */\n\t#dirty_effects = new Set();\n\n\t/**\n\t * Deferred effects that are MAYBE_DIRTY\n\t * @type {Set}\n\t */\n\t#maybe_dirty_effects = new Set();\n\n\t/**\n\t * A map of branches that still exist, but will be destroyed when this batch\n\t * is committed — we skip over these during `process`.\n\t * The value contains child effects that were dirty/maybe_dirty before being reset,\n\t * so they can be rescheduled if the branch survives.\n\t * @type {Map}\n\t */\n\t#skipped_branches = new Map();\n\n\t/**\n\t * Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing\n\t * @type {Set}\n\t */\n\t#unskipped_branches = new Set();\n\n\tis_fork = false;\n\n\t#decrement_queued = false;\n\n\tconstructor() {\n\t\t// link batch\n\t\tif (last_batch === null) {\n\t\t\tfirst_batch = last_batch = this;\n\t\t} else {\n\t\t\tlast_batch.#next = this;\n\t\t\tthis.#prev = last_batch;\n\t\t}\n\n\t\tlast_batch = this;\n\t}\n\n\t#is_deferred() {\n\t\tif (this.is_fork) return true;\n\n\t\tfor (const effect of this.#blocking_pending.keys()) {\n\t\t\tvar e = effect;\n\t\t\tvar skipped = false;\n\n\t\t\twhile (e.parent !== null) {\n\t\t\t\tif (this.#skipped_branches.has(e)) {\n\t\t\t\t\tskipped = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\te = e.parent;\n\t\t\t}\n\n\t\t\tif (!skipped) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add an effect to the #skipped_branches map and reset its children\n\t * @param {Effect} effect\n\t */\n\tskip_effect(effect) {\n\t\tif (!this.#skipped_branches.has(effect)) {\n\t\t\tthis.#skipped_branches.set(effect, { d: [], m: [] });\n\t\t}\n\t\tthis.#unskipped_branches.delete(effect);\n\t}\n\n\t/**\n\t * Remove an effect from the #skipped_branches map and reschedule\n\t * any tracked dirty/maybe_dirty child effects\n\t * @param {Effect} effect\n\t * @param {(e: Effect) => void} callback\n\t */\n\tunskip_effect(effect, callback = (e) => this.schedule(e)) {\n\t\tvar tracked = this.#skipped_branches.get(effect);\n\t\tif (tracked) {\n\t\t\tthis.#skipped_branches.delete(effect);\n\n\t\t\tfor (var e of tracked.d) {\n\t\t\t\tset_signal_status(e, DIRTY);\n\t\t\t\tcallback(e);\n\t\t\t}\n\n\t\t\tfor (e of tracked.m) {\n\t\t\t\tset_signal_status(e, MAYBE_DIRTY);\n\t\t\t\tcallback(e);\n\t\t\t}\n\t\t}\n\t\tthis.#unskipped_branches.add(effect);\n\t}\n\n\t/**\n\t * Convert the effects that were scheduled in this batch into the root effects\n\t * that need to be traversed, marking the path to each effect (by clearing the\n\t * `CLEAN` flag on ancestor branches) so that the traversal can find them.\n\t * This happens right before traversal rather than at scheduling time, so that\n\t * the markers left on the (shared) effect tree are created and consumed within\n\t * a single traversal — scheduling into other batches can never observe them\n\t * @returns {Effect[]}\n\t */\n\t#resolve() {\n\t\t/** @type {Effect[]} */\n\t\tvar roots = [];\n\n\t\tfor (const effect of this.#scheduled) {\n\t\t\t// skip effects that are destroyed, or that already ran (e.g. because\n\t\t\t// they were reached by the traversal that preceded a drain iteration,\n\t\t\t// or because they were scheduled twice)\n\t\t\tif ((effect.f & DESTROYED) !== 0 || (effect.f & (DIRTY | MAYBE_DIRTY)) === 0) continue;\n\n\t\t\tvar e = effect;\n\t\t\tvar covered = false;\n\n\t\t\twhile (e.parent !== null) {\n\t\t\t\te = e.parent;\n\t\t\t\tvar flags = e.f;\n\n\t\t\t\tif ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {\n\t\t\t\t\tif ((flags & CLEAN) === 0) {\n\t\t\t\t\t\t// the path to the root was already marked, meaning the\n\t\t\t\t\t\t// root was already collected — nothing left to do\n\t\t\t\t\t\tcovered = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\te.f ^= CLEAN;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!covered) {\n\t\t\t\troots.push(e);\n\t\t\t}\n\t\t}\n\n\t\tthis.#scheduled = [];\n\n\t\treturn roots;\n\t}\n\n\t#process() {\n\t\tthis.#started = true;\n\n\t\tif (DEV) {\n\t\t\t// track all the values that were updated during this flush,\n\t\t\t// so that they can be reset afterwards\n\t\t\tfor (const value of this.current.keys()) {\n\t\t\t\tsource_stacks.add(value);\n\t\t\t}\n\t\t}\n\n\t\t// We always reschedule previously-deferred effects, not just when\n\t\t// #is_deferred() is true, because traversing the tree could make\n\t\t// an if block that contains the last blocking pending effect falsy,\n\t\t// causing the block to no longer be deferred.\n\t\tfor (const e of this.#dirty_effects) {\n\t\t\tthis.#maybe_dirty_effects.delete(e);\n\t\t\tset_signal_status(e, DIRTY);\n\t\t\tthis.schedule(e);\n\t\t}\n\n\t\tfor (const e of this.#maybe_dirty_effects) {\n\t\t\tset_signal_status(e, MAYBE_DIRTY);\n\t\t\tthis.schedule(e);\n\t\t}\n\n\t\tthis.apply();\n\n\t\t/** @type {Effect[]} */\n\t\tvar effects = (collected_effects = []);\n\n\t\t/** @type {Effect[]} */\n\t\tvar render_effects = [];\n\n\t\t/**\n\t\t * @type {Effect[]}\n\t\t * @deprecated when we get rid of legacy mode and stores, we can get rid of this\n\t\t */\n\t\tvar updates = (legacy_updates = []);\n\n\t\t// Effects can be scheduled during traversal (e.g. because a parent each/await/etc\n\t\t// block updated an internal source, or because an effect invalidated itself)\n\t\t// hence we loop until there are no more scheduled effects.\n\t\twhile (this.#scheduled.length > 0) {\n\t\t\tif (flush_count++ > 1000) {\n\t\t\t\tthis.#unlink();\n\t\t\t\tinfinite_loop_guard(); // TODO try to reset_all() here?\n\t\t\t}\n\n\t\t\tfor (const root of this.#resolve()) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.#traverse(root, effects, render_effects);\n\t\t\t\t} catch (e) {\n\t\t\t\t\treset_all(root);\n\t\t\t\t\t// If there's no async work left, this branch is now dead and needs\n\t\t\t\t\t// to be discarded to not become a zombie that is never cleaned up.\n\t\t\t\t\t// See https://github.com/sveltejs/svelte/issues/18221#issuecomment-4497918414\n\t\t\t\t\t// for a (non-minimal) reproduction that demonstrates a case where this is necessary\n\t\t\t\t\t// to not get follow-up false-positives via \"batch has scheduled roots\" invariant errors.\n\t\t\t\t\tif (!this.#is_deferred()) this.discard();\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// any writes should take effect in a subsequent batch\n\t\tcurrent_batch = null;\n\n\t\tif (updates.length > 0) {\n\t\t\tvar batch = Batch.ensure();\n\t\t\tfor (const e of updates) {\n\t\t\t\tbatch.schedule(e);\n\t\t\t}\n\t\t}\n\n\t\tcollected_effects = null;\n\t\tlegacy_updates = null;\n\n\t\t// if the batch has outstanding pending work, stash effects and bail\n\t\tif (this.#is_deferred()) {\n\t\t\tthis.#defer_effects(render_effects);\n\t\t\tthis.#defer_effects(effects);\n\n\t\t\tfor (const [e, t] of this.#skipped_branches) {\n\t\t\t\treset_branch(e, t);\n\t\t\t}\n\n\t\t\tif (updates.length > 0) {\n\t\t\t\t/** @type {Batch} */ (/** @type {unknown} */ (current_batch)).#process();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst earlier_batch = this.#find_earlier_batch();\n\n\t\tif (earlier_batch) {\n\t\t\t// If this batch collected deferred effects during traversal, they still need\n\t\t\t// to run after being merged into the earlier batch.\n\t\t\tthis.#defer_effects(render_effects);\n\t\t\tthis.#defer_effects(effects);\n\t\t\tearlier_batch.#merge(this);\n\t\t\treturn;\n\t\t}\n\n\t\t// clear effects. Those that are still needed will be rescheduled through unskipping the skipped branches.\n\t\tthis.#dirty_effects.clear();\n\t\tthis.#maybe_dirty_effects.clear();\n\n\t\t// append/remove branches\n\t\tfor (const fn of this.#commit_callbacks) fn(this);\n\t\tthis.#commit_callbacks.clear();\n\n\t\tprevious_batch = this;\n\t\tflush_queued_effects(render_effects);\n\t\tflush_queued_effects(effects);\n\t\tprevious_batch = null;\n\n\t\tthis.#deferred?.resolve();\n\n\t\tvar next_batch = /** @type {Batch | null} */ (/** @type {unknown} */ (current_batch));\n\n\t\tif (this.#pending === 0 && (this.#scheduled.length === 0 || next_batch !== null)) {\n\t\t\tthis.#unlink();\n\n\t\t\t// Order matters here - we need to commit and THEN continue flushing new batches, not the other way around,\n\t\t\t// else we could start flushing a new batch and then, if it has pending work, rebase it right afterwards, which is wrong.\n\t\t\t// In sync mode flushSync can cause #commit to wrongfully think that there needs to be a rebase, so we only do it in async mode\n\t\t\t// TODO fix the underlying cause, otherwise this will likely regress when non-async mode is removed\n\t\t\tif (async_mode_flag) {\n\t\t\t\tthis.#commit();\n\t\t\t\t// Rebases can activate other batches or null it out, therefore restore the new one here\n\t\t\t\tcurrent_batch = next_batch;\n\t\t\t}\n\t\t}\n\n\t\t// Edge case: During traversal new branches might create effects that run immediately and set state,\n\t\t// causing an effect to be scheduled again. We need to traverse the current batch\n\t\t// once more in that case - most of the time this will just clean up dirty branches.\n\t\tif (this.#scheduled.length > 0) {\n\t\t\tif (next_batch !== null) {\n\t\t\t\tfor (const e of this.#scheduled) {\n\t\t\t\t\tnext_batch.#scheduled.push(e);\n\t\t\t\t}\n\n\t\t\t\tthis.#scheduled = [];\n\t\t\t} else {\n\t\t\t\tnext_batch = this;\n\t\t\t}\n\t\t}\n\n\t\tif (next_batch !== null) {\n\t\t\told_values.clear();\n\t\t\tnext_batch.#process();\n\t\t}\n\t}\n\n\t/**\n\t * Traverse the effect tree, executing effects or stashing\n\t * them for later execution as appropriate\n\t * @param {Effect} root\n\t * @param {Effect[]} effects\n\t * @param {Effect[]} render_effects\n\t */\n\t#traverse(root, effects, render_effects) {\n\t\troot.f ^= CLEAN;\n\n\t\tvar effect = root.first;\n\n\t\twhile (effect !== null) {\n\t\t\tvar flags = effect.f;\n\t\t\tvar is_branch = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) !== 0;\n\t\t\tvar is_skippable_branch = is_branch && (flags & CLEAN) !== 0;\n\n\t\t\tvar skip = is_skippable_branch || (flags & INERT) !== 0 || this.#skipped_branches.has(effect);\n\n\t\t\tif (!skip && effect.fn !== null) {\n\t\t\t\tif (is_branch) {\n\t\t\t\t\teffect.f ^= CLEAN;\n\t\t\t\t} else if ((flags & EFFECT) !== 0) {\n\t\t\t\t\teffects.push(effect);\n\t\t\t\t} else if (async_mode_flag && (flags & (RENDER_EFFECT | MANAGED_EFFECT)) !== 0) {\n\t\t\t\t\trender_effects.push(effect);\n\t\t\t\t} else if (is_dirty(effect)) {\n\t\t\t\t\tif ((flags & BLOCK_EFFECT) !== 0) this.#maybe_dirty_effects.add(effect);\n\t\t\t\t\tupdate_effect(effect);\n\t\t\t\t}\n\n\t\t\t\tvar child = effect.first;\n\n\t\t\t\tif (child !== null) {\n\t\t\t\t\teffect = child;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile (effect !== null) {\n\t\t\t\tvar next = effect.next;\n\n\t\t\t\tif (next !== null) {\n\t\t\t\t\teffect = next;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\teffect = effect.parent;\n\t\t\t}\n\t\t}\n\t}\n\n\t#find_earlier_batch() {\n\t\tvar batch = this.#prev;\n\n\t\twhile (batch !== null) {\n\t\t\tif (!batch.is_fork) {\n\t\t\t\t// if the batches are connected, break\n\t\t\t\tfor (const [value, [, is_derived]] of this.current) {\n\t\t\t\t\tif (batch.current.has(value) && !is_derived) {\n\t\t\t\t\t\treturn batch;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbatch = batch.#prev;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * @param {Batch} batch\n\t */\n\t#merge(batch) {\n\t\tfor (const [source, value] of batch.current) {\n\t\t\tif (!this.previous.has(source) && batch.previous.has(source)) {\n\t\t\t\tthis.previous.set(source, batch.previous.get(source));\n\t\t\t}\n\n\t\t\tthis.current.set(source, value);\n\t\t}\n\n\t\tfor (const [effect, deferred] of batch.async_deriveds) {\n\t\t\tconst d = this.async_deriveds.get(effect);\n\t\t\tif (d) deferred.promise.then(d.resolve).catch(d.reject);\n\t\t}\n\n\t\t// Clear them or else those that are still pending might get rejected on discard (after merged-into batch is done).\n\t\t// This can happen when batch Y merged into X and Y has a pending boundary and therefore still-pending async deriveds inside.\n\t\tbatch.async_deriveds.clear();\n\n\t\t// Mark is not guaranteed not touch these, so we transfer them\n\t\tthis.transfer_effects(batch.#dirty_effects, batch.#maybe_dirty_effects);\n\n\t\t/**\n\t\t * mark all effects that depend on `batch.current`, except the\n\t\t * async effects that we just resolved (TODO unless they depend\n\t\t * on values in this batch that are NOT in the later batch?).\n\t\t * Through this we also will populate the correct #skipped_branches,\n\t\t * oncommit callbacks etc, so we don't need to merge them separately.\n\t\t * @param {Value} value\n\t\t */\n\t\tconst mark = (value) => {\n\t\t\tvar reactions = value.reactions;\n\t\t\tif (reactions === null) return;\n\t\t\t// skip if value is derived and is neither dirty nor maybe dirty. transitive\n\t\t\t// deriveds (a derived depending on another derived) are only MAYBE_DIRTY, so\n\t\t\t// we must continue traversing them to reach the effects that depend on them\n\t\t\tif ((value.f & DERIVED) !== 0 && (value.f & (DIRTY | MAYBE_DIRTY)) === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (const reaction of reactions) {\n\t\t\t\tvar flags = reaction.f;\n\n\t\t\t\tif ((flags & DERIVED) !== 0) {\n\t\t\t\t\tmark(/** @type {Derived} */ (reaction));\n\t\t\t\t} else {\n\t\t\t\t\tvar effect = /** @type {Effect} */ (reaction);\n\n\t\t\t\t\tif (flags & (ASYNC | BLOCK_EFFECT) && !this.async_deriveds.has(effect)) {\n\t\t\t\t\t\tthis.#maybe_dirty_effects.delete(effect);\n\t\t\t\t\t\tset_signal_status(effect, DIRTY);\n\t\t\t\t\t\tthis.schedule(effect);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tfor (const source of this.current.keys()) {\n\t\t\tmark(source);\n\t\t}\n\n\t\tthis.oncommit(() => batch.discard());\n\t\tbatch.#unlink();\n\n\t\tcurrent_batch = this;\n\t\tthis.#process();\n\t}\n\n\t/**\n\t * @param {Effect[]} effects\n\t */\n\t#defer_effects(effects) {\n\t\tfor (var i = 0; i < effects.length; i += 1) {\n\t\t\tdefer_effect(effects[i], this.#dirty_effects, this.#maybe_dirty_effects);\n\t\t}\n\t}\n\n\t/**\n\t * Associate a change to a given source with the current\n\t * batch, noting its previous and current values\n\t * @param {Value} source\n\t * @param {any} value\n\t * @param {boolean} [is_derived]\n\t */\n\tcapture(source, value, is_derived = false) {\n\t\tif (source.v !== UNINITIALIZED && !this.previous.has(source)) {\n\t\t\tthis.previous.set(source, source.v);\n\t\t}\n\n\t\t// Don't save errors in `batch_values`, or they won't be thrown in `runtime.js#get`\n\t\tif ((source.f & ERROR_VALUE) === 0) {\n\t\t\tthis.current.set(source, [value, is_derived]);\n\t\t\tbatch_values?.set(source, value);\n\t\t}\n\n\t\tif (!this.is_fork) {\n\t\t\tsource.v = value;\n\t\t}\n\t}\n\n\tactivate() {\n\t\tcurrent_batch = this;\n\t}\n\n\tdeactivate() {\n\t\tcurrent_batch = null;\n\t\tbatch_values = null;\n\t}\n\n\tflush() {\n\t\ttry {\n\t\t\tif (DEV) {\n\t\t\t\tsource_stacks.clear();\n\t\t\t}\n\n\t\t\tis_processing = true;\n\t\t\tcurrent_batch = this;\n\n\t\t\tthis.#process();\n\t\t} finally {\n\t\t\tflush_count = 0;\n\t\t\tlast_scheduled_effect = null;\n\t\t\tcollected_effects = null;\n\t\t\tlegacy_updates = null;\n\t\t\tis_processing = false;\n\n\t\t\tcurrent_batch = null;\n\t\t\tbatch_values = null;\n\n\t\t\told_values.clear();\n\n\t\t\tif (DEV) {\n\t\t\t\tfor (const source of source_stacks) {\n\t\t\t\t\tsource.updated = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdiscard() {\n\t\tfor (const fn of this.#discard_callbacks) fn(this);\n\t\tthis.#discard_callbacks.clear();\n\n\t\tfor (const deferred of this.async_deriveds.values()) {\n\t\t\tdeferred.reject(OBSOLETE);\n\t\t}\n\n\t\tthis.#unlink();\n\t\tthis.#deferred?.resolve();\n\t}\n\n\t/**\n\t * @param {Effect} effect\n\t */\n\tregister_created_effect(effect) {\n\t\tthis.#new_effects.push(effect);\n\t}\n\n\t#commit() {\n\t\t// If there are other pending batches, they now need to be 'rebased' —\n\t\t// in other words, we re-run block/async effects with the newly\n\t\t// committed state, unless the batch in question has a more\n\t\t// recent value for a given source\n\t\tfor (let batch = first_batch; batch !== null; batch = batch.#next) {\n\t\t\tvar is_earlier = batch.id < this.id;\n\n\t\t\t/** @type {Source[]} */\n\t\t\tvar sources = [];\n\n\t\t\tfor (const [source, [value, is_derived]] of this.current) {\n\t\t\t\tif (batch.current.has(source)) {\n\t\t\t\t\tvar batch_value = /** @type {[any, boolean]} */ (batch.current.get(source))[0]; // faster than destructuring\n\n\t\t\t\t\tif (is_earlier && value !== batch_value) {\n\t\t\t\t\t\t// bring the value up to date\n\t\t\t\t\t\tbatch.current.set(source, [value, is_derived]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// same value or later batch has more recent value,\n\t\t\t\t\t\t// no need to re-run these effects\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsources.push(source);\n\t\t\t}\n\n\t\t\tif (is_earlier) {\n\t\t\t\t// TODO do we need to restart these in some cases, instead of\n\t\t\t\t// immediately resolving them? Likely not because of how this.apply() works.\n\t\t\t\tfor (const [effect, deferred] of this.async_deriveds) {\n\t\t\t\t\tconst d = batch.async_deriveds.get(effect);\n\t\t\t\t\tif (d) deferred.promise.then(d.resolve).catch(d.reject);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar current = [...batch.current.keys()].filter(\n\t\t\t\t(source) => !(/** @type {[any, boolean]} */ (batch.current.get(source))[1])\n\t\t\t);\n\n\t\t\t// If not started yet or no sources to update (which is e.g. possible for the very first batch) then bail\n\t\t\tif (!batch.#started || current.length === 0) continue;\n\n\t\t\t// Re-run async/block effects that depend on distinct values changed in both batches (ignoring deriveds)\n\t\t\tvar others = current.filter((source) => !this.current.has(source));\n\n\t\t\tif (others.length === 0) {\n\t\t\t\tif (is_earlier) {\n\t\t\t\t\t// this batch is now obsolete and can be discarded\n\t\t\t\t\tbatch.discard();\n\t\t\t\t}\n\t\t\t} else if (sources.length > 0) {\n\t\t\t\t// The microtask queue can contain the batch already scheduled to run right\n\t\t\t\t// after this one is finished, so throwing the invariant would be wrong here.\n\t\t\t\tif (DEV && !batch.#decrement_queued) {\n\t\t\t\t\tinvariant(batch.#scheduled.length === 0, 'Batch has scheduled effects');\n\t\t\t\t}\n\n\t\t\t\t// A batch was unskipped in a later batch -> tell prior batches to unskip it, too\n\t\t\t\tif (is_earlier) {\n\t\t\t\t\tfor (const unskipped of this.#unskipped_branches) {\n\t\t\t\t\t\tbatch.unskip_effect(unskipped, (e) => {\n\t\t\t\t\t\t\tif ((e.f & (BLOCK_EFFECT | ASYNC)) !== 0) {\n\t\t\t\t\t\t\t\tbatch.schedule(e);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbatch.#defer_effects([e]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbatch.activate();\n\n\t\t\t\t/** @type {Set} */\n\t\t\t\tvar marked = new Set();\n\n\t\t\t\t/** @type {Map} */\n\t\t\t\tvar checked = new Map();\n\n\t\t\t\tfor (var source of sources) {\n\t\t\t\t\tmark_effects(source, others, marked, checked);\n\t\t\t\t}\n\n\t\t\t\tchecked = new Map();\n\t\t\t\tvar current_unequal = [...batch.current]\n\t\t\t\t\t.filter(([c, v1]) => {\n\t\t\t\t\t\tconst v2 = this.current.get(c);\n\t\t\t\t\t\tif (!v2) return true;\n\t\t\t\t\t\t// Either their values are different or one is a derived but not the other\n\t\t\t\t\t\treturn v2[0] !== v1[0] || v2[1] !== v1[1];\n\t\t\t\t\t})\n\t\t\t\t\t.map(([c]) => c);\n\n\t\t\t\tif (current_unequal.length > 0) {\n\t\t\t\t\tfor (const effect of this.#new_effects) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(effect.f & (DESTROYED | INERT | EAGER_EFFECT)) === 0 &&\n\t\t\t\t\t\t\tdepends_on(effect, current_unequal, checked)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tif ((effect.f & (ASYNC | BLOCK_EFFECT)) !== 0) {\n\t\t\t\t\t\t\t\tset_signal_status(effect, DIRTY);\n\t\t\t\t\t\t\t\tbatch.schedule(effect);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbatch.#dirty_effects.add(effect);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Only apply and traverse when we know we triggered async work with marking the effects\n\t\t\t\t// and know this won't run anyway right afterwards\n\t\t\t\tif (batch.#scheduled.length > 0 && !batch.#decrement_queued) {\n\t\t\t\t\tbatch.apply();\n\n\t\t\t\t\tfor (var root of batch.#resolve()) {\n\t\t\t\t\t\tbatch.#traverse(root, [], []);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbatch.deactivate();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @param {boolean} blocking\n\t * @param {Effect} effect\n\t */\n\tincrement(blocking, effect) {\n\t\tthis.#pending += 1;\n\n\t\tif (blocking) {\n\t\t\tlet blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;\n\t\t\tthis.#blocking_pending.set(effect, blocking_pending_count + 1);\n\t\t}\n\t}\n\n\t/**\n\t * @param {boolean} blocking\n\t * @param {Effect} effect\n\t */\n\tdecrement(blocking, effect) {\n\t\tthis.#pending -= 1;\n\n\t\tif (blocking) {\n\t\t\tlet blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;\n\n\t\t\tif (blocking_pending_count === 1) {\n\t\t\t\tthis.#blocking_pending.delete(effect);\n\t\t\t} else {\n\t\t\t\tthis.#blocking_pending.set(effect, blocking_pending_count - 1);\n\t\t\t}\n\t\t}\n\n\t\tif (this.#decrement_queued) return;\n\t\tthis.#decrement_queued = true;\n\n\t\tqueue_micro_task(() => {\n\t\t\tthis.#decrement_queued = false;\n\n\t\t\tif (this.linked) {\n\t\t\t\tthis.flush();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * @param {Set} dirty_effects\n\t * @param {Set} maybe_dirty_effects\n\t */\n\ttransfer_effects(dirty_effects, maybe_dirty_effects) {\n\t\tfor (const e of dirty_effects) {\n\t\t\tthis.#dirty_effects.add(e);\n\t\t}\n\n\t\tfor (const e of maybe_dirty_effects) {\n\t\t\tthis.#maybe_dirty_effects.add(e);\n\t\t}\n\n\t\tdirty_effects.clear();\n\t\tmaybe_dirty_effects.clear();\n\t}\n\n\t/** @param {(batch: Batch) => void} fn */\n\toncommit(fn) {\n\t\tthis.#commit_callbacks.add(fn);\n\t}\n\n\t/** @param {(batch: Batch) => void} fn */\n\tondiscard(fn) {\n\t\tthis.#discard_callbacks.add(fn);\n\t}\n\n\tsettled() {\n\t\treturn (this.#deferred ??= deferred()).promise;\n\t}\n\n\tstatic ensure() {\n\t\tif (current_batch === null) {\n\t\t\tconst batch = (current_batch = new Batch());\n\n\t\t\tif (!is_processing && !is_flushing_sync) {\n\t\t\t\tqueue_micro_task(() => {\n\t\t\t\t\tif (!batch.#started) {\n\t\t\t\t\t\tbatch.flush();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn current_batch;\n\t}\n\n\tapply() {\n\t\tif (!async_mode_flag || (!this.is_fork && this.#prev === null && this.#next === null)) {\n\t\t\tbatch_values = null;\n\t\t\treturn;\n\t\t}\n\n\t\t// if there are multiple batches, we are 'time travelling' —\n\t\t// we need to override values with the ones in this batch...\n\t\tbatch_values = new Map();\n\t\tfor (const [source, [value]] of this.current) {\n\t\t\tbatch_values.set(source, value);\n\t\t}\n\n\t\t// ...and undo changes belonging to other batches unless they intersect\n\t\tfor (let batch = first_batch; batch !== null; batch = batch.#next) {\n\t\t\tif (batch === this || batch.is_fork) continue;\n\n\t\t\t// If two batches intersect, the latter batch will be merged into the earlier batch,\n\t\t\t// and we should treat them as a single set of changes\n\t\t\tvar intersects = false;\n\n\t\t\tif (batch.id < this.id) {\n\t\t\t\tfor (const [source, [, is_derived]] of batch.current) {\n\t\t\t\t\t// Derived values don't partake in the intersection mechanism, because a derived could\n\t\t\t\t\t// be triggered in one batch already but not the other one yet, causing a false-positive\n\t\t\t\t\tif (is_derived) continue;\n\n\t\t\t\t\tif (this.current.has(source)) {\n\t\t\t\t\t\tintersects = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Since the latter batch merges into the earlier (if it resolves before the earlier one),\n\t\t\t// we treat the earlier values as \"already applied\". This way we don't need to rerun async\n\t\t\t// effects of the earlier batch in case they are merged.\n\t\t\t// As a result you can think of batch_values as having the latest values of all intersecting\n\t\t\t// batches up until this batch.\n\t\t\tif (!intersects) {\n\t\t\t\tfor (const [source, previous] of batch.previous) {\n\t\t\t\t\tif (!batch_values.has(source)) {\n\t\t\t\t\t\tbatch_values.set(source, previous);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param {Effect} effect\n\t */\n\tschedule(effect) {\n\t\tlast_scheduled_effect = effect;\n\n\t\t// defer render effects inside a pending boundary\n\t\t// TODO the `REACTION_RAN` check is only necessary because of legacy `$:` effects AFAICT — we can remove later\n\t\tif (\n\t\t\teffect.b?.is_pending &&\n\t\t\t(effect.f & (EFFECT | RENDER_EFFECT | MANAGED_EFFECT)) !== 0 &&\n\t\t\t(effect.f & REACTION_RAN) === 0\n\t\t) {\n\t\t\teffect.b.defer_effect(effect);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#scheduled.push(effect);\n\t}\n\n\t#unlink() {\n\t\t// #merge calls #unlink, discard later on does it again - prevent\n\t\t// running it multiple times to not corrupt the linked list\n\t\tif (!this.linked) return;\n\n\t\tvar prev = this.#prev;\n\t\tvar next = this.#next;\n\n\t\tif (prev === null) {\n\t\t\tfirst_batch = next;\n\t\t} else {\n\t\t\tprev.#next = next;\n\t\t}\n\n\t\tif (next === null) {\n\t\t\tlast_batch = prev;\n\t\t} else {\n\t\t\tnext.#prev = prev;\n\t\t}\n\n\t\tthis.linked = false;\n\t}\n}\n\n// TODO Svelte@6 think about removing the callback argument.\n/**\n * Synchronously flush any pending updates.\n * Returns void if no callback is provided, otherwise returns the result of calling the callback.\n * @template [T=void]\n * @param {(() => T) | undefined} [fn]\n * @returns {T}\n */\nexport function flushSync(fn) {\n\tvar was_flushing_sync = is_flushing_sync;\n\tvar prev_previous_batch = previous_batch;\n\tprevious_batch = null;\n\tis_flushing_sync = true;\n\n\ttry {\n\t\tvar result;\n\n\t\tif (fn) {\n\t\t\tflushSync(); // flush anything pending through the while loop below\n\n\t\t\tresult = fn();\n\t\t}\n\n\t\twhile (true) {\n\t\t\tflush_tasks();\n\n\t\t\tif (current_batch === null) {\n\t\t\t\treturn /** @type {T} */ (result);\n\t\t\t}\n\n\t\t\tcurrent_batch.flush();\n\t\t}\n\t} finally {\n\t\tis_flushing_sync = was_flushing_sync;\n\t\tprevious_batch = prev_previous_batch;\n\t}\n}\n\nfunction infinite_loop_guard() {\n\tif (DEV) {\n\t\tvar updates = new Map();\n\n\t\tfor (const source of /** @type {Batch} */ (current_batch).current.keys()) {\n\t\t\tfor (const [stack, update] of source.updated ?? []) {\n\t\t\t\tvar entry = updates.get(stack);\n\n\t\t\t\tif (!entry) {\n\t\t\t\t\tentry = { error: update.error, count: 0 };\n\t\t\t\t\tupdates.set(stack, entry);\n\t\t\t\t}\n\n\t\t\t\tentry.count += update.count;\n\t\t\t}\n\t\t}\n\n\t\tfor (const update of updates.values()) {\n\t\t\tif (update.error) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error(update.error);\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\te.effect_update_depth_exceeded();\n\t} catch (error) {\n\t\tif (DEV) {\n\t\t\t// stack contains no useful information, replace it\n\t\t\tdefine_property(error, 'stack', { value: '' });\n\t\t}\n\n\t\t// Best effort: invoke the boundary nearest the most recent\n\t\t// effect and hope that it's relevant to the infinite loop\n\t\tinvoke_error_boundary(error, last_scheduled_effect);\n\t}\n}\n\n/** @type {Set | null} */\nexport let eager_block_effects = null;\n\n/**\n * @param {Array} effects\n * @returns {void}\n */\nfunction flush_queued_effects(effects) {\n\tvar length = effects.length;\n\tif (length === 0) return;\n\n\tvar i = 0;\n\n\twhile (i < length) {\n\t\tvar effect = effects[i++];\n\n\t\tif ((effect.f & (DESTROYED | INERT)) === 0 && is_dirty(effect)) {\n\t\t\teager_block_effects = new Set();\n\n\t\t\tupdate_effect(effect);\n\n\t\t\t// Effects with no dependencies or teardown do not get added to the effect tree.\n\t\t\t// Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we\n\t\t\t// don't know if we need to keep them until they are executed. Doing the check\n\t\t\t// here (rather than in `update_effect`) allows us to skip the work for\n\t\t\t// immediate effects.\n\t\t\tif (\n\t\t\t\teffect.deps === null &&\n\t\t\t\teffect.first === null &&\n\t\t\t\teffect.nodes === null &&\n\t\t\t\teffect.teardown === null &&\n\t\t\t\teffect.ac === null\n\t\t\t) {\n\t\t\t\t// remove this effect from the graph\n\t\t\t\tunlink_effect(effect);\n\t\t\t}\n\n\t\t\t// If update_effect() has a flushSync() in it, we may have flushed another flush_queued_effects(),\n\t\t\t// which already handled this logic and did set eager_block_effects to null.\n\t\t\tif (eager_block_effects?.size > 0) {\n\t\t\t\told_values.clear();\n\n\t\t\t\tfor (const e of eager_block_effects) {\n\t\t\t\t\t// Skip eager effects that have already been unmounted\n\t\t\t\t\tif ((e.f & (DESTROYED | INERT)) !== 0) continue;\n\n\t\t\t\t\t// Run effects in order from ancestor to descendant, else we could run into nullpointers\n\t\t\t\t\t/** @type {Effect[]} */\n\t\t\t\t\tconst ordered_effects = [e];\n\t\t\t\t\tlet ancestor = e.parent;\n\t\t\t\t\twhile (ancestor !== null) {\n\t\t\t\t\t\tif (eager_block_effects.has(ancestor)) {\n\t\t\t\t\t\t\teager_block_effects.delete(ancestor);\n\t\t\t\t\t\t\tordered_effects.push(ancestor);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tancestor = ancestor.parent;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (let j = ordered_effects.length - 1; j >= 0; j--) {\n\t\t\t\t\t\tconst e = ordered_effects[j];\n\t\t\t\t\t\t// Skip eager effects that have already been unmounted\n\t\t\t\t\t\tif ((e.f & (DESTROYED | INERT)) !== 0) continue;\n\t\t\t\t\t\tupdate_effect(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teager_block_effects.clear();\n\t\t\t}\n\t\t}\n\t}\n\n\teager_block_effects = null;\n}\n\n/**\n * This is similar to `mark_reactions`, but it only marks async/block effects\n * depending on `value` and at least one of the other `sources`, so that\n * these effects can re-run after another batch has been committed\n * @param {Value} value\n * @param {Source[]} sources\n * @param {Set} marked\n * @param {Map} checked\n */\nfunction mark_effects(value, sources, marked, checked) {\n\tif (marked.has(value)) return;\n\tmarked.add(value);\n\n\tif (value.reactions !== null) {\n\t\tfor (const reaction of value.reactions) {\n\t\t\tconst flags = reaction.f;\n\n\t\t\tif ((flags & DERIVED) !== 0) {\n\t\t\t\tmark_effects(/** @type {Derived} */ (reaction), sources, marked, checked);\n\t\t\t} else if (\n\t\t\t\t(flags & (ASYNC | BLOCK_EFFECT)) !== 0 &&\n\t\t\t\t(flags & DIRTY) === 0 &&\n\t\t\t\tdepends_on(reaction, sources, checked)\n\t\t\t) {\n\t\t\t\tset_signal_status(reaction, DIRTY);\n\t\t\t\tschedule_effect(/** @type {Effect} */ (reaction));\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * When committing a fork, we need to trigger eager effects so that\n * any `$state.eager(...)` expressions update immediately. This\n * function allows us to discover them\n * @param {Value} value\n * @param {Set} effects\n */\nfunction mark_eager_effects(value, effects) {\n\tif (value.reactions === null) return;\n\n\tfor (const reaction of value.reactions) {\n\t\tconst flags = reaction.f;\n\n\t\tif ((flags & DERIVED) !== 0) {\n\t\t\tmark_eager_effects(/** @type {Derived} */ (reaction), effects);\n\t\t} else if ((flags & EAGER_EFFECT) !== 0) {\n\t\t\tset_signal_status(reaction, DIRTY);\n\t\t\teffects.add(/** @type {Effect} */ (reaction));\n\t\t}\n\t}\n}\n\n/**\n * @param {Reaction} reaction\n * @param {Source[]} sources\n * @param {Map} checked\n */\nfunction depends_on(reaction, sources, checked) {\n\tconst depends = checked.get(reaction);\n\tif (depends !== undefined) return depends;\n\n\tif (reaction.deps !== null) {\n\t\tfor (const dep of reaction.deps) {\n\t\t\tif (includes.call(sources, dep)) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif ((dep.f & DERIVED) !== 0 && depends_on(/** @type {Derived} */ (dep), sources, checked)) {\n\t\t\t\tchecked.set(/** @type {Derived} */ (dep), true);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\tchecked.set(reaction, false);\n\n\treturn false;\n}\n\n/**\n * @param {Effect} effect\n * @returns {void}\n */\nexport function schedule_effect(effect) {\n\t/** @type {Batch} */ (current_batch).schedule(effect);\n}\n\n/** @type {Source[]} */\nlet eager_versions = [];\n\nfunction eager_flush() {\n\tflushSync(() => {\n\t\tconst eager = eager_versions;\n\t\teager_versions = [];\n\t\tfor (const version of eager) {\n\t\t\tupdate(version);\n\t\t}\n\t});\n}\n\n/** @type {Map>} */\nvar version_map = new Map();\n\n/**\n * Implementation of `$state.eager(fn())`\n * @template T\n * @param {() => T} fn\n * @returns {T}\n */\nexport function eager(fn) {\n\tvar initial = true;\n\tvar value = /** @type {T} */ (undefined);\n\n\tif (active_reaction === null) {\n\t\treturn fn();\n\t}\n\n\tlet parent = active_reaction;\n\n\tlet version = version_map.get(parent) ?? source(0);\n\tversion_map.set(parent, version);\n\n\tif (DEV) {\n\t\tversion.label ??= '$state.eager version';\n\t}\n\n\tteardown(() => {\n\t\tif (parent.f & DESTROYING) version_map.delete(parent);\n\t});\n\n\tget(version);\n\n\teager_effect(() => {\n\t\tif (initial) {\n\t\t\t// the first time this runs, we create an eager effect\n\t\t\t// that will run eagerly whenever the expression changes\n\t\t\tvar previous_batch_values = batch_values;\n\n\t\t\ttry {\n\t\t\t\tbatch_values = null;\n\t\t\t\tvalue = fn();\n\t\t\t} finally {\n\t\t\t\tbatch_values = previous_batch_values;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// the second time this effect runs, it's to schedule a\n\t\t// `version` update. since this will recreate the effect,\n\t\t// we don't need to evaluate the expression here\n\t\tif (eager_versions.length === 0) {\n\t\t\tqueue_micro_task(eager_flush);\n\t\t}\n\n\t\teager_versions.push(version);\n\t});\n\n\tinitial = false;\n\n\treturn value;\n}\n\n/**\n * Mark all the effects inside a skipped branch CLEAN, so that\n * they can be correctly rescheduled later. Tracks dirty and maybe_dirty\n * effects so they can be rescheduled if the branch survives.\n * @param {Effect} effect\n * @param {{ d: Effect[], m: Effect[] }} tracked\n */\nfunction reset_branch(effect, tracked) {\n\t// clean branch = nothing dirty inside, no need to traverse further\n\tif ((effect.f & BRANCH_EFFECT) !== 0 && (effect.f & CLEAN) !== 0) {\n\t\treturn;\n\t}\n\n\tif ((effect.f & DIRTY) !== 0) {\n\t\ttracked.d.push(effect);\n\t} else if ((effect.f & MAYBE_DIRTY) !== 0) {\n\t\ttracked.m.push(effect);\n\t}\n\n\tset_signal_status(effect, CLEAN);\n\n\tvar e = effect.first;\n\twhile (e !== null) {\n\t\treset_branch(e, tracked);\n\t\te = e.next;\n\t}\n}\n\n/**\n * Mark an entire effect tree clean following an error\n * @param {Effect} effect\n */\nfunction reset_all(effect) {\n\tset_signal_status(effect, CLEAN);\n\n\tvar e = effect.first;\n\twhile (e !== null) {\n\t\treset_all(e);\n\t\te = e.next;\n\t}\n}\n\n/**\n * Creates a 'fork', in which state changes are evaluated but not applied to the DOM.\n * This is useful for speculatively loading data (for example) when you suspect that\n * the user is about to take some action.\n *\n * Frameworks like SvelteKit can use this to preload data when the user touches or\n * hovers over a link, making any subsequent navigation feel instantaneous.\n *\n * The `fn` parameter is a synchronous function that modifies some state. The\n * state changes will be reverted after the fork is initialised, then reapplied\n * if and when the fork is eventually committed.\n *\n * When it becomes clear that a fork will _not_ be committed (e.g. because the\n * user navigated elsewhere), it must be discarded to avoid leaking memory.\n *\n * @param {() => void} fn\n * @returns {Fork}\n * @since 5.42\n */\nexport function fork(fn) {\n\tif (!async_mode_flag) {\n\t\te.experimental_async_required('fork');\n\t}\n\n\tif (current_batch !== null) {\n\t\te.fork_timing();\n\t}\n\n\tflushSync();\n\n\tvar batch = Batch.ensure();\n\tbatch.is_fork = true;\n\tbatch_values = new Map();\n\n\tvar committed = false;\n\tvar settled = batch.settled();\n\n\tfn();\n\tflushSync();\n\n\treturn {\n\t\tcommit: async () => {\n\t\t\tif (committed) {\n\t\t\t\tawait settled;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!batch.linked) {\n\t\t\t\te.fork_discarded();\n\t\t\t}\n\n\t\t\tcommitted = true;\n\n\t\t\tbatch.is_fork = false;\n\n\t\t\t// apply changes and update write versions so deriveds see the change\n\t\t\tfor (var [source, [value]] of batch.current) {\n\t\t\t\tsource.v = value;\n\t\t\t\tsource.wv = increment_write_version();\n\t\t\t}\n\n\t\t\t// trigger any `$state.eager(...)` expressions with the new state.\n\t\t\t// eager effects don't get scheduled like other effects, so we\n\t\t\t// can't just encounter them during traversal, we need to\n\t\t\t// proactively flush them\n\t\t\t// TODO maybe there's a better implementation?\n\t\t\tflushSync(() => {\n\t\t\t\t/** @type {Set} */\n\t\t\t\tvar eager_effects = new Set();\n\n\t\t\t\tfor (var source of batch.current.keys()) {\n\t\t\t\t\tmark_eager_effects(source, eager_effects);\n\t\t\t\t}\n\n\t\t\t\tset_eager_effects(eager_effects);\n\t\t\t\tflush_eager_effects();\n\t\t\t});\n\n\t\t\tbatch.flush();\n\t\t\tawait settled;\n\t\t},\n\t\tdiscard: () => {\n\t\t\t// cause any MAYBE_DIRTY deriveds to update\n\t\t\t// if they depend on things thath changed\n\t\t\t// inside the discarded fork\n\t\t\tfor (var source of batch.current.keys()) {\n\t\t\t\tsource.wv = increment_write_version();\n\t\t\t}\n\n\t\t\tif (!committed && batch.linked) {\n\t\t\t\tbatch.discard();\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Forcibly remove all current batches, to prevent cross-talk between tests\n */\nexport function clear() {\n\tfirst_batch = last_batch = null;\n}\n","/** @import { Derived, Effect, Source, Value } from '#client' */\nimport { DEV } from 'esm-env';\nimport {\n\tactive_reaction,\n\tactive_effect,\n\tuntracked_writes,\n\tget,\n\tset_untracked_writes,\n\tuntrack,\n\tincrement_write_version,\n\tupdate_effect,\n\tcurrent_sources,\n\tis_dirty,\n\tuntracking,\n\tis_destroying_effect,\n\tpush_reaction_value\n} from '../runtime.js';\nimport { equals, safe_equals } from './equality.js';\nimport {\n\tCLEAN,\n\tDERIVED,\n\tDIRTY,\n\tBRANCH_EFFECT,\n\tEAGER_EFFECT,\n\tMAYBE_DIRTY,\n\tBLOCK_EFFECT,\n\tROOT_EFFECT,\n\tASYNC\n} from '#client/constants';\nimport * as e from '../errors.js';\nimport { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js';\nimport { tag_proxy } from '../dev/tracing.js';\nimport { get_error } from '../../shared/dev.js';\nimport { component_context, is_runes } from '../context.js';\nimport {\n\tBatch,\n\tbatch_values,\n\teager_block_effects,\n\tschedule_effect,\n\tlegacy_updates\n} from './batch.js';\nimport { proxy } from '../proxy.js';\nimport { execute_derived } from './deriveds.js';\nimport { set_signal_status, update_derived_status } from './status.js';\n\n/** @type {Set} */\nexport let eager_effects = new Set();\n\n/** @type {Map} */\nexport const old_values = new Map();\n\n/**\n * @param {Set} v\n */\nexport function set_eager_effects(v) {\n\teager_effects = v;\n}\n\nlet eager_effects_deferred = false;\n\nexport function set_eager_effects_deferred() {\n\teager_effects_deferred = true;\n}\n\n/**\n * @template V\n * @param {V} v\n * @param {Error | null} [stack]\n * @returns {Source}\n */\n// TODO rename this to `state` throughout the codebase\nexport function source(v, stack) {\n\t/** @type {Value} */\n\tvar signal = {\n\t\tf: 0, // TODO ideally we could skip this altogether, but it causes type errors\n\t\tv,\n\t\treactions: null,\n\t\tequals,\n\t\trv: 0,\n\t\twv: 0\n\t};\n\n\tif (DEV && tracing_mode_flag) {\n\t\tsignal.created = stack ?? get_error('created at');\n\t\tsignal.updated = null;\n\t\tsignal.set_during_effect = false;\n\t\tsignal.trace = null;\n\t}\n\n\treturn signal;\n}\n\n/**\n * @template V\n * @param {V} v\n * @param {Error | null} [stack]\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function state(v, stack) {\n\tconst s = source(v, stack);\n\n\tpush_reaction_value(s);\n\n\treturn s;\n}\n\n/**\n * @template V\n * @param {V} initial_value\n * @param {boolean} [immutable]\n * @returns {Source}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function mutable_source(initial_value, immutable = false, trackable = true) {\n\tconst s = source(initial_value);\n\tif (!immutable) {\n\t\ts.equals = safe_equals;\n\t}\n\n\t// bind the signal to the component context, in case we need to\n\t// track updates to trigger beforeUpdate/afterUpdate callbacks\n\tif (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) {\n\t\t(component_context.l.s ??= []).push(s);\n\t}\n\n\treturn s;\n}\n\n/**\n * @template V\n * @param {Value} source\n * @param {V} value\n */\nexport function mutate(source, value) {\n\tset(\n\t\tsource,\n\t\tuntrack(() => get(source))\n\t);\n\treturn value;\n}\n\n/**\n * @template V\n * @param {Value} source\n * @param {V} value\n * @param {boolean} [should_proxy]\n * @returns {V}\n */\nexport function set(source, value, should_proxy = false) {\n\tif (\n\t\tactive_reaction !== null &&\n\t\t// since we are untracking the function inside `$inspect.with` we need to add this check\n\t\t// to ensure we error if state is set inside an inspect effect\n\t\t(!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) &&\n\t\tis_runes() &&\n\t\t(active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 &&\n\t\t(current_sources === null || !current_sources.has(source))\n\t) {\n\t\te.state_unsafe_mutation();\n\t}\n\n\tlet new_value = should_proxy ? proxy(value) : value;\n\n\tif (DEV) {\n\t\ttag_proxy(new_value, /** @type {string} */ (source.label));\n\t}\n\n\treturn internal_set(source, new_value, legacy_updates);\n}\n\n/**\n * A set of signals we have already seen while traversing in mark_reactions.\n * Not always set to balance the common case of sources only having a couple\n * of (transitive) dependencies (where always creating a Set would be bad for perf)\n * with the edge case of extremely deep or wide dependency arrays with cycles.\n * @type {Set | null}\n */\nvar seen = null;\n/** Number of transitive dependencies, see {@link seen} for more info */\nvar count_deps = 0;\n\n/**\n * @template V\n * @param {Value} source\n * @param {V} value\n * @param {Effect[] | null} [updated_during_traversal]\n * @returns {V}\n */\nexport function internal_set(source, value, updated_during_traversal = null) {\n\tif (!source.equals(value)) {\n\t\tif (is_destroying_effect) {\n\t\t\told_values.set(source, value);\n\t\t} else if (!old_values.has(source)) {\n\t\t\t// only record the value from before the first write in this flush, otherwise a\n\t\t\t// teardown would see the value from before whichever write happened to be last\n\t\t\told_values.set(source, source.v);\n\t\t}\n\n\t\tvar batch = Batch.ensure();\n\t\tbatch.capture(source, value);\n\n\t\tif (DEV) {\n\t\t\tif (tracing_mode_flag || active_effect !== null) {\n\t\t\t\tsource.updated ??= new Map();\n\n\t\t\t\t// For performance reasons, when not using $inspect.trace, we only start collecting stack traces\n\t\t\t\t// after the same source has been updated more than 5 times in the same flush cycle.\n\t\t\t\tconst count = (source.updated.get('')?.count ?? 0) + 1;\n\t\t\t\tsource.updated.set('', { error: /** @type {any} */ (null), count });\n\n\t\t\t\tif (tracing_mode_flag || count > 5) {\n\t\t\t\t\tconst error = get_error('updated at');\n\n\t\t\t\t\tif (error !== null) {\n\t\t\t\t\t\tlet entry = source.updated.get(error.stack);\n\n\t\t\t\t\t\tif (!entry) {\n\t\t\t\t\t\t\tentry = { error, count: 0 };\n\t\t\t\t\t\t\tsource.updated.set(error.stack, entry);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tentry.count++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (active_effect !== null) {\n\t\t\t\tsource.set_during_effect = true;\n\t\t\t}\n\t\t}\n\n\t\tif ((source.f & DERIVED) !== 0) {\n\t\t\tconst derived = /** @type {Derived} */ (source);\n\n\t\t\t// if we are assigning to a dirty derived we set it to clean/maybe dirty but we also eagerly execute it to track the dependencies\n\t\t\tif ((source.f & DIRTY) !== 0) {\n\t\t\t\texecute_derived(derived);\n\t\t\t}\n\n\t\t\t// During time traveling we don't want to reset the status so that\n\t\t\t// traversal of the graph in the other batches still happens\n\t\t\tif (batch_values === null) {\n\t\t\t\tupdate_derived_status(derived);\n\t\t\t}\n\t\t}\n\n\t\tsource.wv = increment_write_version();\n\n\t\t// For debugging, in case you want to know which reactions are being scheduled:\n\t\t// log_reactions(source);\n\t\tseen = null;\n\t\tcount_deps = 0;\n\t\tmark_reactions(source, DIRTY, updated_during_traversal);\n\t\tseen = null;\n\n\t\t// It's possible that the current reaction might not have up-to-date dependencies\n\t\t// whilst it's actively running. So in the case of ensuring it registers the reaction\n\t\t// properly for itself, we need to ensure the current effect actually gets\n\t\t// scheduled. i.e: `$effect(() => x++)`\n\t\tif (\n\t\t\tis_runes() &&\n\t\t\tactive_effect !== null &&\n\t\t\t(active_effect.f & CLEAN) !== 0 &&\n\t\t\t(active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT)) === 0\n\t\t) {\n\t\t\tif (untracked_writes === null) {\n\t\t\t\tset_untracked_writes([source]);\n\t\t\t} else {\n\t\t\t\tuntracked_writes.push(source);\n\t\t\t}\n\t\t}\n\n\t\tif (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) {\n\t\t\tflush_eager_effects();\n\t\t}\n\t}\n\n\treturn value;\n}\n\nexport function flush_eager_effects() {\n\teager_effects_deferred = false;\n\n\tfor (const effect of eager_effects) {\n\t\t// Mark clean inspect-effects as maybe dirty and then check their dirtiness\n\t\t// instead of just updating the effects - this way we avoid overfiring.\n\t\tif ((effect.f & CLEAN) !== 0) {\n\t\t\tset_signal_status(effect, MAYBE_DIRTY);\n\t\t}\n\n\t\tlet dirty;\n\n\t\ttry {\n\t\t\tdirty = is_dirty(effect);\n\t\t} catch {\n\t\t\t// Dirty-checking can evaluate derived dependencies and throw in cases where\n\t\t\t// parent effects are about to destroy this eager effect. Run the effect so\n\t\t\t// its own error handling can deal with transient failures.\n\t\t\tdirty = true;\n\t\t}\n\n\t\tif (dirty) {\n\t\t\tupdate_effect(effect);\n\t\t}\n\t}\n\n\teager_effects.clear();\n}\n\n/**\n * @template {number | bigint} T\n * @param {Source} source\n * @param {1 | -1} [d]\n * @returns {T}\n */\nexport function update(source, d = 1) {\n\tvar value = get(source);\n\tvar result = d === 1 ? value++ : value--;\n\n\tset(source, value);\n\n\t// @ts-expect-error\n\treturn result;\n}\n\n/**\n * @template {number | bigint} T\n * @param {Source} source\n * @param {1 | -1} [d]\n * @returns {T}\n */\nexport function update_pre(source, d = 1) {\n\tvar value = get(source);\n\n\t// @ts-expect-error\n\t// eslint-disable-next-line no-useless-assignment -- `++`/`--` used for return value, not side effect on `value`\n\treturn set(source, d === 1 ? ++value : --value);\n}\n\n/**\n * Silently (without using `get`) increment a source\n * @param {Source} source\n */\nexport function increment(source) {\n\tset(source, source.v + 1);\n}\n\n/**\n * @param {Value} signal\n * @param {number} status should be DIRTY or MAYBE_DIRTY\n * @param {Effect[] | null} updated_during_traversal\n * @returns {void}\n */\nfunction mark_reactions(signal, status, updated_during_traversal) {\n\tvar reactions = signal.reactions;\n\tif (reactions === null) return;\n\n\tvar runes = is_runes();\n\tvar length = reactions.length;\n\n\tcount_deps += length;\n\t// Activate the `seen` Set if we think from the unusually high number of deps that\n\t// there might be cycles in the graph, to avoid repeated lookups for reactions\n\t// Example: https://github.com/sveltejs/svelte/issues/16658 has a graph with one source\n\t// reaching ~10000 distinct deriveds/effects each, resulting in 65 million walks through repeated visits.\n\tif (count_deps > 100000 && seen === null) seen = new Set();\n\n\tif (seen !== null) {\n\t\tif (seen.has(signal)) return;\n\t\tseen.add(signal);\n\t}\n\n\tfor (var i = 0; i < length; i++) {\n\t\tvar reaction = reactions[i];\n\t\tvar flags = reaction.f;\n\n\t\t// In legacy mode, skip the current effect to prevent infinite loops\n\t\tif (!runes && reaction === active_effect) continue;\n\n\t\tvar not_dirty = (flags & DIRTY) === 0;\n\n\t\t// don't set a DIRTY reaction to MAYBE_DIRTY\n\t\tif (not_dirty) {\n\t\t\tset_signal_status(reaction, status);\n\t\t}\n\n\t\tif ((flags & EAGER_EFFECT) !== 0) {\n\t\t\t// Eager effects need to run immediately:\n\t\t\t// - for $inspect so that the stack trace makes sense\n\t\t\t// - for $state.eager because they might be without an effect parent\n\t\t\teager_effects.add(/** @type {Effect} */ (reaction));\n\t\t} else if ((flags & DERIVED) !== 0) {\n\t\t\tvar derived = /** @type {Derived} */ (reaction);\n\n\t\t\tbatch_values?.delete(derived);\n\t\t\tmark_reactions(derived, MAYBE_DIRTY, updated_during_traversal);\n\t\t} else if (not_dirty) {\n\t\t\tvar effect = /** @type {Effect} */ (reaction);\n\n\t\t\tif ((flags & BLOCK_EFFECT) !== 0 && eager_block_effects !== null) {\n\t\t\t\teager_block_effects.add(effect);\n\t\t\t}\n\n\t\t\tif (updated_during_traversal !== null) {\n\t\t\t\tupdated_during_traversal.push(effect);\n\t\t\t} else {\n\t\t\t\tschedule_effect(effect);\n\t\t\t}\n\t\t}\n\t}\n}\n","/** @import { Source } from '#client' */\nimport { DEV } from 'esm-env';\nimport {\n\tget,\n\tactive_effect,\n\tupdate_version,\n\tactive_reaction,\n\tset_update_version,\n\tset_active_reaction\n} from './runtime.js';\nimport {\n\tarray_prototype,\n\tget_descriptor,\n\tget_prototype_of,\n\tis_array,\n\tobject_prototype\n} from '../shared/utils.js';\nimport {\n\tstate as source,\n\tset,\n\tincrement,\n\tflush_eager_effects,\n\tset_eager_effects_deferred\n} from './reactivity/sources.js';\nimport { COMPONENT_SYMBOL, PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants';\nimport { UNINITIALIZED } from '../../constants.js';\nimport * as e from './errors.js';\nimport { tag } from './dev/tracing.js';\nimport { get_error } from '../shared/dev.js';\nimport { tracing_mode_flag } from '../flags/index.js';\n\n// TODO move all regexes into shared module?\nconst regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;\n\n/**\n * @template T\n * @param {T} value\n * @returns {T}\n */\nexport function proxy(value) {\n\t// if non-proxyable, a component instance, or already a proxy, return `value`\n\tif (\n\t\ttypeof value !== 'object' ||\n\t\tvalue === null ||\n\t\tSTATE_SYMBOL in value ||\n\t\tCOMPONENT_SYMBOL in value\n\t) {\n\t\treturn value;\n\t}\n\n\tconst prototype = get_prototype_of(value);\n\n\tif (prototype !== object_prototype && prototype !== array_prototype) {\n\t\treturn value;\n\t}\n\n\t/** @type {Map>} */\n\tvar sources = new Map();\n\tvar is_proxied_array = is_array(value);\n\tvar version = source(0);\n\n\tvar stack = DEV && tracing_mode_flag ? get_error('created at') : null;\n\tvar parent_version = update_version;\n\n\t/**\n\t * Executes the proxy in the context of the reaction it was originally created in, if any\n\t * @template T\n\t * @param {() => T} fn\n\t */\n\tvar with_parent = (fn) => {\n\t\tif (update_version === parent_version) {\n\t\t\treturn fn();\n\t\t}\n\n\t\t// child source is being created after the initial proxy —\n\t\t// prevent it from being associated with the current reaction\n\t\tvar reaction = active_reaction;\n\t\tvar version = update_version;\n\n\t\tset_active_reaction(null);\n\t\tset_update_version(parent_version);\n\n\t\tvar result = fn();\n\n\t\tset_active_reaction(reaction);\n\t\tset_update_version(version);\n\n\t\treturn result;\n\t};\n\n\tif (is_proxied_array) {\n\t\t// We need to create the length source eagerly to ensure that\n\t\t// mutations to the array are properly synced with our proxy\n\t\tsources.set('length', source(/** @type {any[]} */ (value).length, stack));\n\t\tif (DEV) {\n\t\t\tvalue = /** @type {any} */ (inspectable_array(/** @type {any[]} */ (value)));\n\t\t}\n\t}\n\n\t/** Used in dev for $inspect.trace() */\n\tvar path = '';\n\tlet updating = false;\n\t/** @param {string} new_path */\n\tfunction update_path(new_path) {\n\t\tif (updating) return;\n\t\tupdating = true;\n\t\tpath = new_path;\n\n\t\ttag(version, `${path} version`);\n\n\t\t// rename all child sources and child proxies\n\t\tfor (const [prop, source] of sources) {\n\t\t\ttag(source, get_label(path, prop));\n\t\t}\n\t\tupdating = false;\n\t}\n\n\treturn new Proxy(/** @type {any} */ (value), {\n\t\tdefineProperty(_, prop, descriptor) {\n\t\t\tif (\n\t\t\t\t!('value' in descriptor) ||\n\t\t\t\tdescriptor.configurable === false ||\n\t\t\t\tdescriptor.enumerable === false ||\n\t\t\t\tdescriptor.writable === false\n\t\t\t) {\n\t\t\t\t// we disallow non-basic descriptors, because unless they are applied to the\n\t\t\t\t// target object — which we avoid, so that state can be forked — we will run\n\t\t\t\t// afoul of the various invariants\n\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor#invariants\n\t\t\t\te.state_descriptors_fixed();\n\t\t\t}\n\t\t\tvar s = sources.get(prop);\n\t\t\tif (s === undefined) {\n\t\t\t\twith_parent(() => {\n\t\t\t\t\tvar s = source(descriptor.value, stack);\n\t\t\t\t\tsources.set(prop, s);\n\t\t\t\t\tif (DEV && typeof prop === 'string') {\n\t\t\t\t\t\ttag(s, get_label(path, prop));\n\t\t\t\t\t}\n\t\t\t\t\treturn s;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tset(s, descriptor.value, true);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\tdeleteProperty(target, prop) {\n\t\t\tvar s = sources.get(prop);\n\n\t\t\tif (s === undefined) {\n\t\t\t\tif (prop in target) {\n\t\t\t\t\tconst s = with_parent(() => source(UNINITIALIZED, stack));\n\t\t\t\t\tsources.set(prop, s);\n\t\t\t\t\tincrement(version);\n\n\t\t\t\t\tif (DEV) {\n\t\t\t\t\t\ttag(s, get_label(path, prop));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tset(s, UNINITIALIZED);\n\t\t\t\tincrement(version);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\tget(target, prop, receiver) {\n\t\t\tif (prop === STATE_SYMBOL) {\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tif (DEV && prop === PROXY_PATH_SYMBOL) {\n\t\t\t\treturn update_path;\n\t\t\t}\n\n\t\t\tvar s = sources.get(prop);\n\t\t\tvar exists = prop in target;\n\n\t\t\t// create a source, but only if it's an own property and not a prototype property\n\t\t\tif (s === undefined && (!exists || get_descriptor(target, prop)?.writable)) {\n\t\t\t\ts = with_parent(() => {\n\t\t\t\t\tvar p = proxy(exists ? target[prop] : UNINITIALIZED);\n\t\t\t\t\tvar s = source(p, stack);\n\n\t\t\t\t\tif (DEV) {\n\t\t\t\t\t\ttag(s, get_label(path, prop));\n\t\t\t\t\t}\n\n\t\t\t\t\treturn s;\n\t\t\t\t});\n\n\t\t\t\tsources.set(prop, s);\n\t\t\t}\n\n\t\t\tif (s !== undefined) {\n\t\t\t\tvar v = get(s);\n\t\t\t\treturn v === UNINITIALIZED ? undefined : v;\n\t\t\t}\n\n\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t},\n\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\tthis.has?.(target, prop);\n\n\t\t\tvar descriptor = Reflect.getOwnPropertyDescriptor(target, prop);\n\t\t\tvar s = sources.get(prop);\n\n\t\t\tif (s !== undefined) {\n\t\t\t\tvar value = get(s);\n\n\t\t\t\tif (value === UNINITIALIZED) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tif (descriptor && 'value' in descriptor) {\n\t\t\t\t\tdescriptor.value = value;\n\t\t\t\t} else {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tenumerable: true,\n\t\t\t\t\t\tconfigurable: true,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\twritable: true\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn descriptor;\n\t\t},\n\n\t\thas(target, prop) {\n\t\t\tif (prop === STATE_SYMBOL) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvar s = sources.get(prop);\n\t\t\tvar has = (s !== undefined && s.v !== UNINITIALIZED) || Reflect.has(target, prop);\n\n\t\t\tif (\n\t\t\t\ts !== undefined ||\n\t\t\t\t(active_effect !== null && (!has || get_descriptor(target, prop)?.writable))\n\t\t\t) {\n\t\t\t\tif (s === undefined) {\n\t\t\t\t\ts = with_parent(() => {\n\t\t\t\t\t\tvar p = has ? proxy(target[prop]) : UNINITIALIZED;\n\t\t\t\t\t\tvar s = source(p, stack);\n\n\t\t\t\t\t\tif (DEV) {\n\t\t\t\t\t\t\ttag(s, get_label(path, prop));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn s;\n\t\t\t\t\t});\n\n\t\t\t\t\tsources.set(prop, s);\n\t\t\t\t}\n\n\t\t\t\tvar value = get(s);\n\t\t\t\tif (value === UNINITIALIZED) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn has;\n\t\t},\n\n\t\tset(target, prop, value, receiver) {\n\t\t\tvar s = sources.get(prop);\n\t\t\tvar has = prop in target;\n\n\t\t\t// variable.length = value -> clear all signals with index >= value\n\t\t\tif (is_proxied_array && prop === 'length') {\n\t\t\t\tfor (var i = value; i < /** @type {Source} */ (s).v; i += 1) {\n\t\t\t\t\tvar other_s = sources.get(i + '');\n\t\t\t\t\tif (other_s !== undefined) {\n\t\t\t\t\t\tset(other_s, UNINITIALIZED);\n\t\t\t\t\t} else if (i in target) {\n\t\t\t\t\t\t// If the item exists in the original, we need to create an uninitialized source,\n\t\t\t\t\t\t// else a later read of the property would result in a source being created with\n\t\t\t\t\t\t// the value of the original item at that index.\n\t\t\t\t\t\tother_s = with_parent(() => source(UNINITIALIZED, stack));\n\t\t\t\t\t\tsources.set(i + '', other_s);\n\n\t\t\t\t\t\tif (DEV) {\n\t\t\t\t\t\t\ttag(other_s, get_label(path, i));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we haven't yet created a source for this property, we need to ensure\n\t\t\t// we do so otherwise if we read it later, then the write won't be tracked and\n\t\t\t// the heuristics of effects will be different vs if we had read the proxied\n\t\t\t// object property before writing to that property.\n\t\t\tif (s === undefined) {\n\t\t\t\tif (!has || get_descriptor(target, prop)?.writable) {\n\t\t\t\t\ts = with_parent(() => source(undefined, stack));\n\n\t\t\t\t\tif (DEV) {\n\t\t\t\t\t\ttag(s, get_label(path, prop));\n\t\t\t\t\t}\n\t\t\t\t\tset(s, proxy(value));\n\n\t\t\t\t\tsources.set(prop, s);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\thas = s.v !== UNINITIALIZED;\n\n\t\t\t\tvar p = with_parent(() => proxy(value));\n\t\t\t\tset(s, p);\n\t\t\t}\n\n\t\t\tvar descriptor = Reflect.getOwnPropertyDescriptor(target, prop);\n\n\t\t\t// Set the new value before updating any signals so that any listeners get the new value\n\t\t\tif (descriptor?.set) {\n\t\t\t\tdescriptor.set.call(receiver, value);\n\t\t\t}\n\n\t\t\tif (!has) {\n\t\t\t\t// If we have mutated an array directly, we might need to\n\t\t\t\t// signal that length has also changed. Do it before updating metadata\n\t\t\t\t// to ensure that iterating over the array as a result of a metadata update\n\t\t\t\t// will not cause the length to be out of sync.\n\t\t\t\tif (is_proxied_array && typeof prop === 'string') {\n\t\t\t\t\tvar ls = /** @type {Source} */ (sources.get('length'));\n\t\t\t\t\tvar n = Number(prop);\n\n\t\t\t\t\tif (Number.isInteger(n) && n >= ls.v) {\n\t\t\t\t\t\tset(ls, n + 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tincrement(version);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\townKeys(target) {\n\t\t\tget(version);\n\n\t\t\tvar own_keys = Reflect.ownKeys(target).filter((key) => {\n\t\t\t\tvar source = sources.get(key);\n\t\t\t\treturn source === undefined || source.v !== UNINITIALIZED;\n\t\t\t});\n\n\t\t\tfor (var [key, source] of sources) {\n\t\t\t\tif (source.v !== UNINITIALIZED && !(key in target)) {\n\t\t\t\t\town_keys.push(key);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn own_keys;\n\t\t},\n\n\t\tsetPrototypeOf() {\n\t\t\te.state_prototype_fixed();\n\t\t}\n\t});\n}\n\n/**\n * @param {string} path\n * @param {string | symbol} prop\n */\nfunction get_label(path, prop) {\n\tif (typeof prop === 'symbol') return `${path}[Symbol(${prop.description ?? ''})]`;\n\tif (regex_is_valid_identifier.test(prop)) return `${path}.${prop}`;\n\treturn /^\\d+$/.test(prop) ? `${path}[${prop}]` : `${path}['${prop}']`;\n}\n\n/**\n * @param {any} value\n */\nexport function get_proxied_value(value) {\n\ttry {\n\t\tif (value !== null && typeof value === 'object' && STATE_SYMBOL in value) {\n\t\t\treturn value[STATE_SYMBOL];\n\t\t}\n\t} catch {\n\t\t// the above if check can throw an error if the value in question\n\t\t// is the contentWindow of an iframe on another domain, in which\n\t\t// case we want to just return the value (because it's definitely\n\t\t// not a proxied value) so we don't break any JavaScript interacting\n\t\t// with that iframe (such as various payment companies client side\n\t\t// JavaScript libraries interacting with their iframes on the same\n\t\t// domain)\n\t}\n\n\treturn value;\n}\n\n/**\n * @param {any} a\n * @param {any} b\n */\nexport function is(a, b) {\n\treturn Object.is(get_proxied_value(a), get_proxied_value(b));\n}\n\nconst ARRAY_MUTATING_METHODS = new Set([\n\t'copyWithin',\n\t'fill',\n\t'pop',\n\t'push',\n\t'reverse',\n\t'shift',\n\t'sort',\n\t'splice',\n\t'unshift'\n]);\n\n/**\n * Wrap array mutating methods so $inspect is triggered only once and\n * to prevent logging an array in intermediate state (e.g. with an empty slot)\n * @param {any[]} array\n */\nfunction inspectable_array(array) {\n\treturn new Proxy(array, {\n\t\tget(target, prop, receiver) {\n\t\t\tvar value = Reflect.get(target, prop, receiver);\n\t\t\tif (!ARRAY_MUTATING_METHODS.has(/** @type {string} */ (prop))) {\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * @this {any[]}\n\t\t\t * @param {any[]} args\n\t\t\t */\n\t\t\treturn function (...args) {\n\t\t\t\tset_eager_effects_deferred();\n\t\t\t\tvar result = value.apply(this, args);\n\t\t\t\tflush_eager_effects();\n\t\t\t\treturn result;\n\t\t\t};\n\t\t}\n\t});\n}\n","import * as w from '../warnings.js';\nimport { get_proxied_value } from '../proxy.js';\n\nexport function init_array_prototype_warnings() {\n\tconst array_prototype = Array.prototype;\n\t// The REPL ends up here over and over, and this prevents it from adding more and more patches\n\t// of the same kind to the prototype, which would slow down everything over time.\n\t// @ts-expect-error\n\tconst cleanup = Array.__svelte_cleanup;\n\tif (cleanup) {\n\t\tcleanup();\n\t}\n\n\tconst { indexOf, lastIndexOf, includes } = array_prototype;\n\n\tarray_prototype.indexOf = function (item, from_index) {\n\t\tconst index = indexOf.call(this, item, from_index);\n\n\t\tif (index === -1) {\n\t\t\tfor (let i = from_index ?? 0; i < this.length; i += 1) {\n\t\t\t\tif (get_proxied_value(this[i]) === item) {\n\t\t\t\t\tw.state_proxy_equality_mismatch('array.indexOf(...)');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t};\n\n\tarray_prototype.lastIndexOf = function (item, from_index) {\n\t\t// we need to specify this.length - 1 because it's probably using something like\n\t\t// `arguments` inside so passing undefined is different from not passing anything\n\t\tconst index = lastIndexOf.call(this, item, from_index ?? this.length - 1);\n\n\t\tif (index === -1) {\n\t\t\tfor (let i = 0; i <= (from_index ?? this.length - 1); i += 1) {\n\t\t\t\tif (get_proxied_value(this[i]) === item) {\n\t\t\t\t\tw.state_proxy_equality_mismatch('array.lastIndexOf(...)');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t};\n\n\tarray_prototype.includes = function (item, from_index) {\n\t\tconst has = includes.call(this, item, from_index);\n\n\t\tif (!has) {\n\t\t\tfor (let i = 0; i < this.length; i += 1) {\n\t\t\t\tif (get_proxied_value(this[i]) === item) {\n\t\t\t\t\tw.state_proxy_equality_mismatch('array.includes(...)');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn has;\n\t};\n\n\t// @ts-expect-error\n\tArray.__svelte_cleanup = () => {\n\t\tarray_prototype.indexOf = indexOf;\n\t\tarray_prototype.lastIndexOf = lastIndexOf;\n\t\tarray_prototype.includes = includes;\n\t};\n}\n\n/**\n * @param {any} a\n * @param {any} b\n * @param {boolean} equal\n * @returns {boolean}\n */\nexport function strict_equals(a, b, equal = true) {\n\t// try-catch needed because this tries to read properties of `a` and `b`,\n\t// which could be disallowed for example in a secure context\n\ttry {\n\t\tif ((a === b) !== (get_proxied_value(a) === get_proxied_value(b))) {\n\t\t\tw.state_proxy_equality_mismatch(equal ? '===' : '!==');\n\t\t}\n\t} catch {}\n\n\treturn (a === b) === equal;\n}\n\n/**\n * @param {any} a\n * @param {any} b\n * @param {boolean} equal\n * @returns {boolean}\n */\nexport function equals(a, b, equal = true) {\n\tif ((a == b) !== (get_proxied_value(a) == get_proxied_value(b))) {\n\t\tw.state_proxy_equality_mismatch(equal ? '==' : '!=');\n\t}\n\n\treturn (a == b) === equal;\n}\n","/** @import { Effect, TemplateNode } from '#client' */\nimport { hydrate_node, hydrating, reset, set_hydrate_node } from './hydration.js';\nimport { DEV } from 'esm-env';\nimport { init_array_prototype_warnings } from '../dev/equality.js';\nimport { get_descriptor, is_extensible } from '../../shared/utils.js';\nimport { active_effect } from '../runtime.js';\nimport { async_mode_flag } from '../../flags/index.js';\nimport {\n\tATTRIBUTES_CACHE,\n\tCLASS_CACHE,\n\tREACTION_RAN,\n\tSTYLE_CACHE,\n\tTEXT_CACHE,\n\tTEXT_NODE\n} from '#client/constants';\nimport { eager_block_effects } from '../reactivity/batch.js';\nimport { NAMESPACE_HTML } from '../../../constants.js';\n\n// export these for reference in the compiled code, making global name deduplication unnecessary\n/** @type {Window} */\nexport var $window;\n\n/** @type {Document} */\nexport var $document;\n\n/** @type {boolean} */\nexport var is_firefox;\n\n/** @type {() => Node | null} */\nvar first_child_getter;\n/** @type {() => Node | null} */\nvar next_sibling_getter;\n\n/**\n * Initialize these lazily to avoid issues when using the runtime in a server context\n * where these globals are not available while avoiding a separate server entry point\n */\nexport function init_operations() {\n\tif ($window !== undefined) {\n\t\treturn;\n\t}\n\n\t$window = window;\n\t$document = document;\n\tis_firefox = /Firefox/.test(navigator.userAgent);\n\n\tvar element_prototype = Element.prototype;\n\tvar node_prototype = Node.prototype;\n\tvar text_prototype = Text.prototype;\n\n\t// @ts-ignore\n\tfirst_child_getter = get_descriptor(node_prototype, 'firstChild').get;\n\t// @ts-ignore\n\tnext_sibling_getter = get_descriptor(node_prototype, 'nextSibling').get;\n\n\tif (is_extensible(element_prototype)) {\n\t\t// the following assignments improve perf of lookups on DOM nodes\n\t\t/** @type {any} */ (element_prototype)[CLASS_CACHE] = undefined;\n\t\t/** @type {any} */ (element_prototype)[ATTRIBUTES_CACHE] = null;\n\t\t/** @type {any} */ (element_prototype)[STYLE_CACHE] = undefined;\n\t\t// @ts-expect-error\n\t\telement_prototype.__e = undefined;\n\t}\n\n\tif (is_extensible(text_prototype)) {\n\t\t/** @type {any} */ (text_prototype)[TEXT_CACHE] = undefined;\n\t}\n\n\tif (DEV) {\n\t\t// @ts-expect-error\n\t\telement_prototype.__svelte_meta = null;\n\n\t\tinit_array_prototype_warnings();\n\t}\n}\n\n/**\n * @param {string} value\n * @returns {Text}\n */\nexport function create_text(value = '') {\n\treturn document.createTextNode(value);\n}\n\n/**\n * @template {Node} N\n * @param {N} node\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function get_first_child(node) {\n\treturn /** @type {TemplateNode | null} */ (first_child_getter.call(node));\n}\n\n/**\n * @template {Node} N\n * @param {N} node\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function get_next_sibling(node) {\n\treturn /** @type {TemplateNode | null} */ (next_sibling_getter.call(node));\n}\n\n/**\n * Don't mark this as side-effect-free, hydration needs to walk all nodes\n * @template {Node} N\n * @param {N} node\n * @param {boolean} is_text\n * @returns {TemplateNode | null}\n */\nexport function child(node, is_text) {\n\tif (!hydrating) {\n\t\treturn get_first_child(node);\n\t}\n\n\tvar child = get_first_child(hydrate_node);\n\n\t// Child can be null if we have an element with a single child, like `

              {text}

              `, where `text` is empty\n\tif (child === null) {\n\t\tchild = hydrate_node.appendChild(create_text());\n\t} else if (is_text && child.nodeType !== TEXT_NODE) {\n\t\tvar text = create_text();\n\t\tchild?.before(text);\n\t\tset_hydrate_node(text);\n\t\treturn text;\n\t}\n\n\tif (is_text) {\n\t\tmerge_text_nodes(/** @type {Text} */ (child));\n\t}\n\n\tset_hydrate_node(child);\n\treturn child;\n}\n\n/**\n * Don't mark this as side-effect-free, hydration needs to walk all nodes\n * @param {TemplateNode} node\n * @param {boolean} [is_text]\n * @returns {TemplateNode | null}\n */\nexport function first_child(node, is_text = false) {\n\tif (!hydrating) {\n\t\tvar first = get_first_child(node);\n\n\t\t// TODO prevent user comments with the empty string when preserveComments is true\n\t\tif (first instanceof Comment && first.data === '') return get_next_sibling(first);\n\n\t\treturn first;\n\t}\n\n\tif (is_text) {\n\t\t// if an {expression} is empty during SSR, there might be no\n\t\t// text node to hydrate — we must therefore create one\n\t\tif (hydrate_node?.nodeType !== TEXT_NODE) {\n\t\t\tvar text = create_text();\n\n\t\t\thydrate_node?.before(text);\n\t\t\tset_hydrate_node(text);\n\t\t\treturn text;\n\t\t}\n\n\t\tmerge_text_nodes(/** @type {Text} */ (hydrate_node));\n\t}\n\n\treturn hydrate_node;\n}\n\n/**\n * `child`, for the very common case of an element with exactly one child. Resetting the\n * hydration cursor is part of the same step, so the compiler doesn't have to emit a\n * separate `reset` call for every `

              {text}

              ` in an app.\n * Don't mark this as side-effect-free, hydration needs to walk all nodes\n * @param {TemplateNode} node\n * @param {boolean} [is_text]\n * @returns {TemplateNode | null}\n */\nexport function only_child(node, is_text = false) {\n\tif (!hydrating) {\n\t\treturn get_first_child(node);\n\t}\n\n\tvar first = child(node, is_text);\n\treset(node);\n\n\treturn first;\n}\n\n/**\n * Don't mark this as side-effect-free, hydration needs to walk all nodes\n * @param {TemplateNode} node\n * @param {number} count\n * @param {boolean} is_text\n * @returns {TemplateNode | null}\n */\nexport function sibling(node, count = 1, is_text = false) {\n\tlet next_sibling = hydrating ? hydrate_node : node;\n\tvar last_sibling;\n\n\twhile (count--) {\n\t\tlast_sibling = next_sibling;\n\t\tnext_sibling = /** @type {TemplateNode} */ (get_next_sibling(next_sibling));\n\t}\n\n\tif (!hydrating) {\n\t\treturn next_sibling;\n\t}\n\n\tif (is_text) {\n\t\t// if a sibling {expression} is empty during SSR, there might be no\n\t\t// text node to hydrate — we must therefore create one\n\t\tif (next_sibling?.nodeType !== TEXT_NODE) {\n\t\t\tvar text = create_text();\n\t\t\t// If the next sibling is `null` and we're handling text then it's because\n\t\t\t// the SSR content was empty for the text, so we need to generate a new text\n\t\t\t// node and insert it after the last sibling\n\t\t\tif (next_sibling === null) {\n\t\t\t\tlast_sibling?.after(text);\n\t\t\t} else {\n\t\t\t\tnext_sibling.before(text);\n\t\t\t}\n\t\t\tset_hydrate_node(text);\n\t\t\treturn text;\n\t\t}\n\n\t\tmerge_text_nodes(/** @type {Text} */ (next_sibling));\n\t}\n\n\tset_hydrate_node(next_sibling);\n\treturn next_sibling;\n}\n\n/**\n * @template {Node} N\n * @param {N} node\n * @returns {void}\n */\nexport function clear_text_content(node) {\n\tnode.textContent = '';\n}\n\n/**\n * Returns `true` if we're updating the current block, for example `condition` in\n * an `{#if condition}` block just changed. In this case, the branch should be\n * appended (or removed) at the same time as other updates within the\n * current ``\n */\nexport function should_defer_append() {\n\tif (!async_mode_flag) return false;\n\tif (eager_block_effects !== null) return false;\n\n\tvar flags = /** @type {Effect} */ (active_effect).f;\n\treturn (flags & REACTION_RAN) !== 0;\n}\n\n/**\n * Branching here is intentional and load-bearing for perf. `createElement(tag)`\n * hits a fast path in Blink that `createElementNS(NAMESPACE_HTML, tag)` doesn't,\n * and passing an explicit `undefined` as the trailing options arg measurably\n * slows both APIs. Funnelling every case through a single `createElementNS(ns,\n * tag, options)` call would be smaller but slower on the HTML path.\n *\n * @template {keyof HTMLElementTagNameMap | string} T\n * @param {T} tag\n * @param {string} [namespace]\n * @param {string} [is]\n * @returns {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element}\n */\nexport function create_element(tag, namespace, is) {\n\tif (namespace == null || namespace === NAMESPACE_HTML) {\n\t\treturn /** @type {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element} */ (\n\t\t\tis ? document.createElement(tag, { is }) : document.createElement(tag)\n\t\t);\n\t}\n\treturn /** @type {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element} */ (\n\t\tis ? document.createElementNS(namespace, tag, { is }) : document.createElementNS(namespace, tag)\n\t);\n}\n\nexport function create_fragment() {\n\treturn document.createDocumentFragment();\n}\n\n/**\n * @param {string} data\n * @returns\n */\nexport function create_comment(data = '') {\n\treturn document.createComment(data);\n}\n\n/**\n * @param {Element} element\n * @param {string} key\n * @param {string} value\n * @returns\n */\nexport function set_attribute(element, key, value = '') {\n\tif (key.startsWith('xlink:')) {\n\t\telement.setAttributeNS('http://www.w3.org/1999/xlink', key, value);\n\t\treturn;\n\t}\n\treturn element.setAttribute(key, value);\n}\n\n/**\n * Browsers split text nodes larger than 65536 bytes when parsing.\n * For hydration to succeed, we need to stitch them back together\n * @param {Text} text\n */\nexport function merge_text_nodes(text) {\n\tif (/** @type {string} */ (text.nodeValue).length < 65536) {\n\t\treturn;\n\t}\n\n\tlet next = text.nextSibling;\n\n\twhile (next !== null && next.nodeType === TEXT_NODE) {\n\t\tnext.remove();\n\n\t\t/** @type {string} */ (text.nodeValue) += /** @type {string} */ (next.nodeValue);\n\n\t\tnext = text.nextSibling;\n\t}\n}\n","/** @import { Derived, Effect } from '#client' */\n/** @import { Boundary } from './dom/blocks/boundary.js' */\nimport { DEV } from 'esm-env';\nimport { FILENAME, HYDRATION_ERROR } from '../../constants.js';\nimport { is_firefox } from './dom/operations.js';\nimport {\n\tERROR_VALUE,\n\tBOUNDARY_EFFECT,\n\tREACTION_RAN,\n\tEFFECT,\n\tDESTROYED,\n\tDESTROYING\n} from './constants.js';\nimport { define_property, get_descriptor } from '../shared/utils.js';\nimport { active_effect, active_reaction } from './runtime.js';\n\nconst adjustments = new WeakMap();\n\n/**\n * @param {unknown} error\n */\nexport function handle_error(error) {\n\tvar effect = active_effect;\n\n\t// for unowned deriveds, don't throw until we read the value\n\tif (effect === null) {\n\t\t/** @type {Derived} */ (active_reaction).f |= ERROR_VALUE;\n\t\treturn error;\n\t}\n\n\tif (DEV && error instanceof Error && !adjustments.has(error)) {\n\t\tadjustments.set(error, get_adjustments(error, effect));\n\t}\n\n\t// if the error occurred while creating this subtree, we let it\n\t// bubble up until it hits a boundary that can handle it, unless\n\t// it's an $effect in which case it doesn't run immediately\n\tif ((effect.f & REACTION_RAN) === 0 && (effect.f & EFFECT) === 0) {\n\t\tif (DEV && !effect.parent && error instanceof Error) {\n\t\t\tapply_adjustments(error);\n\t\t}\n\n\t\tthrow error;\n\t}\n\n\t// otherwise we bubble up the effect tree ourselves\n\tinvoke_error_boundary(error, effect);\n}\n\n/**\n * @param {unknown} error\n * @param {Effect | null} effect\n */\nexport function invoke_error_boundary(error, effect) {\n\tif (error === HYDRATION_ERROR) {\n\t\tthrow error;\n\t}\n\n\tif (effect !== null && (effect.f & DESTROYED) !== 0) {\n\t\treturn;\n\t}\n\n\twhile (effect !== null) {\n\t\t// Skip boundaries that are destroyed/destroying and cannot meaningfully handle the error.\n\t\tif ((effect.f & BOUNDARY_EFFECT) !== 0 && (effect.f & (DESTROYED | DESTROYING)) === 0) {\n\t\t\tif ((effect.f & REACTION_RAN) === 0) {\n\t\t\t\t// we are still creating the boundary effect\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t/** @type {Boundary} */ (effect.b).error(error);\n\t\t\t\treturn;\n\t\t\t} catch (e) {\n\t\t\t\terror = e;\n\t\t\t}\n\t\t}\n\n\t\teffect = effect.parent;\n\t}\n\n\tif (DEV && error instanceof Error) {\n\t\tapply_adjustments(error);\n\t}\n\n\tthrow error;\n}\n\n/**\n * Add useful information to the error message/stack in development\n * @param {Error} error\n * @param {Effect} effect\n */\nfunction get_adjustments(error, effect) {\n\tconst message_descriptor = get_descriptor(error, 'message');\n\n\t// if the message was already changed and it's not configurable we can't change it\n\t// or it will throw a different error swallowing the original error\n\tif (message_descriptor && !message_descriptor.configurable) return;\n\n\tvar indent = is_firefox ? ' ' : '\\t';\n\tvar component_stack = `\\n${indent}in ${effect.fn?.name || ''}`;\n\tvar context = effect.ctx;\n\n\twhile (context !== null) {\n\t\tcomponent_stack += `\\n${indent}in ${context.function?.[FILENAME].split('/').pop()}`;\n\t\tcontext = context.p;\n\t}\n\n\treturn {\n\t\tmessage: error.message + `\\n${component_stack}\\n`,\n\t\tstack: error.stack\n\t\t\t?.split('\\n')\n\t\t\t.filter((line) => !line.includes('svelte/src/internal'))\n\t\t\t.join('\\n')\n\t};\n}\n\n/**\n * @param {Error} error\n */\nfunction apply_adjustments(error) {\n\tconst adjusted = adjustments.get(error);\n\n\tif (adjusted) {\n\t\tdefine_property(error, 'message', {\n\t\t\tvalue: adjusted.message\n\t\t});\n\n\t\tdefine_property(error, 'stack', {\n\t\t\tvalue: adjusted.stack\n\t\t});\n\t}\n}\n","/** @import { Blocker, ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */\nimport {\n\tis_dirty,\n\tactive_effect,\n\tactive_reaction,\n\tupdate_effect,\n\tget,\n\tis_destroying_effect,\n\tremove_reactions,\n\tset_active_reaction,\n\tset_is_destroying_effect,\n\tuntrack,\n\tuntracking,\n\tset_active_effect\n} from '../runtime.js';\nimport {\n\tDIRTY,\n\tBRANCH_EFFECT,\n\tRENDER_EFFECT,\n\tEFFECT,\n\tDESTROYED,\n\tINERT,\n\tBLOCK_EFFECT,\n\tROOT_EFFECT,\n\tEFFECT_TRANSPARENT,\n\tDERIVED,\n\tCLEAN,\n\tEAGER_EFFECT,\n\tHEAD_EFFECT,\n\tMAYBE_DIRTY,\n\tEFFECT_PRESERVED,\n\tSTALE_REACTION,\n\tUSER_EFFECT,\n\tASYNC,\n\tCONNECTED,\n\tMANAGED_EFFECT,\n\tDESTROYING,\n\tPAUSED\n} from '#client/constants';\nimport { invoke_error_boundary } from '../error-handling.js';\nimport * as e from '../errors.js';\nimport { DEV } from 'esm-env';\nimport { define_property } from '../../shared/utils.js';\nimport { get_next_sibling } from '../dom/operations.js';\nimport { component_context, dev_current_component_function, dev_stack } from '../context.js';\nimport { Batch, collected_effects, current_batch } from './batch.js';\nimport { flatten } from './async.js';\nimport { without_reactive_context } from '../dom/elements/bindings/shared.js';\nimport { set_signal_status } from './status.js';\n\n/**\n * @param {'$effect' | '$effect.pre' | '$inspect'} rune\n */\nexport function validate_effect(rune) {\n\tif (active_effect === null) {\n\t\tif (active_reaction === null) {\n\t\t\te.effect_orphan(rune);\n\t\t}\n\n\t\te.effect_in_unowned_derived();\n\t}\n\n\tif (is_destroying_effect) {\n\t\te.effect_in_teardown(rune);\n\t}\n}\n\n/**\n * @param {Effect} effect\n * @param {Effect} parent_effect\n */\nfunction push_effect(effect, parent_effect) {\n\tvar parent_last = parent_effect.last;\n\tif (parent_last === null) {\n\t\tparent_effect.last = parent_effect.first = effect;\n\t} else {\n\t\tparent_last.next = effect;\n\t\teffect.prev = parent_last;\n\t\tparent_effect.last = effect;\n\t}\n}\n\n/**\n * @param {number} type\n * @param {null | (() => void | (() => void))} fn\n * @returns {Effect}\n */\nfunction create_effect(type, fn) {\n\tvar parent = active_effect;\n\n\tif (DEV) {\n\t\t// Ensure the parent is never an inspect effect\n\t\twhile (parent !== null && (parent.f & EAGER_EFFECT) !== 0) {\n\t\t\tparent = parent.parent;\n\t\t}\n\t}\n\n\tif (parent !== null && (parent.f & INERT) !== 0) {\n\t\ttype |= INERT;\n\t}\n\n\t/** @type {Effect} */\n\tvar effect = {\n\t\tctx: component_context,\n\t\tdeps: null,\n\t\tnodes: null,\n\t\tf: type | DIRTY | CONNECTED,\n\t\tfirst: null,\n\t\tfn,\n\t\tlast: null,\n\t\tnext: null,\n\t\tparent,\n\t\tb: parent && parent.b,\n\t\tprev: null,\n\t\tteardown: null,\n\t\twv: 0,\n\t\tac: null\n\t};\n\n\tif (DEV) {\n\t\teffect.component_function = dev_current_component_function;\n\t}\n\n\tcurrent_batch?.register_created_effect(effect);\n\n\t/** @type {Effect | null} */\n\tvar e = effect;\n\n\tif ((type & EFFECT) !== 0) {\n\t\tif (collected_effects !== null) {\n\t\t\t// created during traversal — collect and run afterwards\n\t\t\tcollected_effects.push(effect);\n\t\t} else {\n\t\t\t// schedule for later\n\t\t\tBatch.ensure().schedule(effect);\n\t\t}\n\t} else if (fn !== null) {\n\t\ttry {\n\t\t\tupdate_effect(effect);\n\t\t} catch (e) {\n\t\t\tdestroy_effect(effect);\n\t\t\tthrow e;\n\t\t}\n\n\t\t// if an effect doesn't need to be kept in the tree (because it\n\t\t// won't re-run, has no DOM, and has no teardown etc)\n\t\t// then we skip it and go to its child (if any)\n\t\tif (\n\t\t\te.deps === null &&\n\t\t\te.teardown === null &&\n\t\t\te.nodes === null &&\n\t\t\te.first === e.last && // either `null`, or a singular child\n\t\t\t(e.f & EFFECT_PRESERVED) === 0\n\t\t) {\n\t\t\te = e.first;\n\t\t\tif ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) {\n\t\t\t\te.f |= EFFECT_TRANSPARENT;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (e !== null) {\n\t\te.parent = parent;\n\n\t\tif (parent !== null) {\n\t\t\tpush_effect(e, parent);\n\t\t}\n\n\t\t// if we're in a derived, add the effect there too\n\t\tif (\n\t\t\tactive_reaction !== null &&\n\t\t\t(active_reaction.f & DERIVED) !== 0 &&\n\t\t\t(type & ROOT_EFFECT) === 0\n\t\t) {\n\t\t\tvar derived = /** @type {Derived} */ (active_reaction);\n\t\t\t(derived.effects ??= []).push(e);\n\t\t}\n\t}\n\n\treturn effect;\n}\n\n/**\n * Internal representation of `$effect.tracking()`\n * @returns {boolean}\n */\nexport function effect_tracking() {\n\treturn active_reaction !== null && !untracking;\n}\n\n/**\n * @param {() => void} fn\n */\nexport function teardown(fn) {\n\tconst effect = create_effect(RENDER_EFFECT, null);\n\tset_signal_status(effect, CLEAN);\n\teffect.teardown = fn;\n\treturn effect;\n}\n\n/**\n * Internal representation of `$effect(...)`\n * @param {() => void | (() => void)} fn\n */\nexport function user_effect(fn) {\n\tvalidate_effect('$effect');\n\n\tif (DEV) {\n\t\tdefine_property(fn, 'name', {\n\t\t\tvalue: '$effect'\n\t\t});\n\t}\n\n\t// Non-nested `$effect(...)` in a component should be deferred\n\t// until the component is mounted\n\tvar flags = /** @type {Effect} */ (active_effect).f;\n\tvar defer =\n\t\t!active_reaction &&\n\t\t(flags & BRANCH_EFFECT) !== 0 &&\n\t\tcomponent_context !== null &&\n\t\t!component_context.i;\n\n\tif (defer) {\n\t\t// Top-level `$effect(...)` in an unmounted component — defer until mount\n\t\tvar context = /** @type {ComponentContext} */ (component_context);\n\t\t(context.e ??= []).push(fn);\n\t} else {\n\t\t// Everything else — create immediately\n\t\treturn create_user_effect(fn);\n\t}\n}\n\n/**\n * @param {() => void | (() => void)} fn\n */\nexport function create_user_effect(fn) {\n\treturn create_effect(EFFECT | USER_EFFECT, fn);\n}\n\n/**\n * Internal representation of `$effect.pre(...)`\n * @param {() => void | (() => void)} fn\n * @returns {Effect}\n */\nexport function user_pre_effect(fn) {\n\tvalidate_effect('$effect.pre');\n\tif (DEV) {\n\t\tdefine_property(fn, 'name', {\n\t\t\tvalue: '$effect.pre'\n\t\t});\n\t}\n\treturn create_effect(RENDER_EFFECT | USER_EFFECT, fn);\n}\n\n/** @param {() => void | (() => void)} fn */\nexport function eager_effect(fn) {\n\treturn create_effect(EAGER_EFFECT, fn);\n}\n\n/**\n * Internal representation of `$effect.root(...)`\n * @param {() => void | (() => void)} fn\n * @returns {() => void}\n */\nexport function effect_root(fn) {\n\tBatch.ensure();\n\tconst effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn);\n\n\treturn () => {\n\t\tdestroy_effect(effect);\n\t};\n}\n\n/**\n * An effect root whose children can transition out\n * @param {() => void} fn\n * @returns {(options?: { outro?: boolean }) => Promise}\n */\nexport function component_root(fn) {\n\tBatch.ensure();\n\tconst effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn);\n\n\treturn (options = {}) => {\n\t\treturn new Promise((fulfil) => {\n\t\t\tif (options.outro) {\n\t\t\t\tpause_effect(effect, () => {\n\t\t\t\t\tdestroy_effect(effect);\n\t\t\t\t\tfulfil(undefined);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tdestroy_effect(effect);\n\t\t\t\tfulfil(undefined);\n\t\t\t}\n\t\t});\n\t};\n}\n\n/**\n * @param {() => void | (() => void)} fn\n * @returns {Effect}\n */\nexport function effect(fn) {\n\treturn create_effect(EFFECT, fn);\n}\n\n/**\n * Internal representation of `$: ..`\n * @param {() => any} deps\n * @param {() => void | (() => void)} fn\n */\nexport function legacy_pre_effect(deps, fn) {\n\tvar context = /** @type {ComponentContextLegacy} */ (component_context);\n\n\t/** @type {{ effect: null | Effect, ran: boolean, deps: () => any }} */\n\tvar token = { effect: null, ran: false, deps };\n\n\tcontext.l.$.push(token);\n\n\ttoken.effect = render_effect(() => {\n\t\tdeps();\n\n\t\t// If this legacy pre effect has already run before the end of the reset, then\n\t\t// bail out to emulate the same behavior.\n\t\tif (token.ran) return;\n\n\t\ttoken.ran = true;\n\n\t\tvar effect = /** @type {Effect} */ (active_effect);\n\n\t\t// here, we lie: by setting `active_effect` to be the parent branch, any writes\n\t\t// that happen inside `fn` will _not_ cause an unnecessary reschedule, because\n\t\t// the affected effects will be children of `active_effect`. this is safe\n\t\t// because these effects are known to run in the correct order\n\t\ttry {\n\t\t\tset_active_effect(effect.parent);\n\t\t\tuntrack(fn);\n\t\t} finally {\n\t\t\tset_active_effect(effect);\n\t\t}\n\t});\n}\n\nexport function legacy_pre_effect_reset() {\n\tvar context = /** @type {ComponentContextLegacy} */ (component_context);\n\n\trender_effect(() => {\n\t\t// Run dirty `$:` statements\n\t\tfor (var token of context.l.$) {\n\t\t\ttoken.deps();\n\n\t\t\tvar effect = token.effect;\n\n\t\t\t// If the effect is CLEAN, then make it MAYBE_DIRTY. This ensures we traverse through\n\t\t\t// the effects dependencies and correctly ensure each dependency is up-to-date.\n\t\t\tif ((effect.f & CLEAN) !== 0 && effect.deps !== null) {\n\t\t\t\tset_signal_status(effect, MAYBE_DIRTY);\n\t\t\t}\n\n\t\t\tif (is_dirty(effect)) {\n\t\t\t\tupdate_effect(effect);\n\t\t\t}\n\n\t\t\ttoken.ran = false;\n\t\t}\n\t});\n}\n\n/**\n * @param {() => void | (() => void)} fn\n * @returns {Effect}\n */\nexport function async_effect(fn) {\n\treturn create_effect(ASYNC | EFFECT_PRESERVED, fn);\n}\n\n/**\n * @param {() => void | (() => void)} fn\n * @returns {Effect}\n */\nexport function render_effect(fn, flags = 0) {\n\treturn create_effect(RENDER_EFFECT | flags, fn);\n}\n\n/**\n * @param {(...expressions: any) => void | (() => void)} fn\n * @param {Array<() => any>} sync\n * @param {Array<() => Promise>} async\n * @param {Blocker[]} blockers\n */\nexport function template_effect(fn, sync = [], async = [], blockers = []) {\n\tflatten(blockers, sync, async, (values) => {\n\t\tcreate_effect(RENDER_EFFECT, () => {\n\t\t\tfn(...values.map(get));\n\t\t});\n\t});\n}\n\n/**\n * Like `template_effect`, but with an effect which is deferred until the batch commits\n * @param {(...expressions: any) => void | (() => void)} fn\n * @param {Array<() => any>} sync\n * @param {Array<() => Promise>} async\n * @param {Blocker[]} blockers\n */\nexport function deferred_template_effect(fn, sync = [], async = [], blockers = []) {\n\tflatten(blockers, sync, async, (values) => {\n\t\tcreate_effect(EFFECT, () => fn(...values.map(get)));\n\t});\n}\n\n/**\n * @param {(() => void)} fn\n * @param {number} flags\n */\nexport function block(fn, flags = 0) {\n\tvar effect = create_effect(BLOCK_EFFECT | flags, fn);\n\tif (DEV) {\n\t\teffect.dev_stack = dev_stack;\n\t}\n\treturn effect;\n}\n\n/**\n * @param {(() => void)} fn\n * @param {number} flags\n */\nexport function managed(fn, flags = 0) {\n\tvar effect = create_effect(MANAGED_EFFECT | flags, fn);\n\tif (DEV) {\n\t\teffect.dev_stack = dev_stack;\n\t}\n\treturn effect;\n}\n\n/**\n * @param {(() => void)} fn\n */\nexport function branch(fn) {\n\treturn create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn);\n}\n\n/**\n * @param {Effect} effect\n */\nexport function execute_effect_teardown(effect) {\n\tvar teardown = effect.teardown;\n\tif (teardown !== null) {\n\t\tconst previously_destroying_effect = is_destroying_effect;\n\t\tconst previous_reaction = active_reaction;\n\t\tset_is_destroying_effect(true);\n\t\tset_active_reaction(null);\n\t\ttry {\n\t\t\tteardown.call(null);\n\t\t} catch (error) {\n\t\t\t// Route teardown errors through the boundary system so that a live\n\t\t\t// ancestor can handle them. Boundaries that are\n\t\t\t// themselves mid-teardown are skipped by invoke_error_boundary.\n\t\t\tinvoke_error_boundary(error, effect.parent);\n\t\t} finally {\n\t\t\tset_is_destroying_effect(previously_destroying_effect);\n\t\t\tset_active_reaction(previous_reaction);\n\t\t}\n\t}\n}\n\n/**\n * @param {Effect} signal\n * @param {boolean} remove_dom\n * @returns {void}\n */\nexport function destroy_effect_children(signal, remove_dom = false) {\n\tvar effect = signal.first;\n\tsignal.first = signal.last = null;\n\n\twhile (effect !== null) {\n\t\tconst controller = effect.ac;\n\n\t\tif (controller !== null) {\n\t\t\twithout_reactive_context(() => {\n\t\t\t\tcontroller.abort(STALE_REACTION);\n\t\t\t});\n\t\t}\n\n\t\tvar next = effect.next;\n\n\t\tif ((effect.f & ROOT_EFFECT) !== 0) {\n\t\t\t// this is now an independent root\n\t\t\teffect.parent = null;\n\t\t} else {\n\t\t\tdestroy_effect(effect, remove_dom);\n\t\t}\n\n\t\teffect = next;\n\t}\n}\n\n/**\n * @param {Effect} signal\n * @returns {void}\n */\nexport function destroy_block_effect_children(signal) {\n\tvar effect = signal.first;\n\n\twhile (effect !== null) {\n\t\tvar next = effect.next;\n\t\tif ((effect.f & BRANCH_EFFECT) === 0) {\n\t\t\tdestroy_effect(effect);\n\t\t}\n\t\teffect = next;\n\t}\n}\n\n/**\n * @param {Effect} effect\n * @param {boolean} [remove_dom]\n * @returns {void}\n */\nexport function destroy_effect(effect, remove_dom = true) {\n\tvar removed = false;\n\n\tif (\n\t\t(remove_dom || (effect.f & HEAD_EFFECT) !== 0) &&\n\t\teffect.nodes !== null &&\n\t\teffect.nodes.end !== null\n\t) {\n\t\tremove_effect_dom(effect.nodes.start, /** @type {TemplateNode} */ (effect.nodes.end));\n\t\tremoved = true;\n\t}\n\n\teffect.f |= DESTROYING;\n\tdestroy_effect_children(effect, remove_dom && !removed);\n\tremove_reactions(effect, 0);\n\n\tvar transitions = effect.nodes && effect.nodes.t;\n\n\tif (transitions !== null) {\n\t\tfor (const transition of transitions) {\n\t\t\ttransition.stop();\n\t\t}\n\t}\n\n\texecute_effect_teardown(effect);\n\n\teffect.f ^= DESTROYING;\n\teffect.f |= DESTROYED;\n\n\tvar parent = effect.parent;\n\n\t// If the parent doesn't have any children, then skip this work altogether\n\tif (parent !== null && parent.first !== null) {\n\t\tunlink_effect(effect);\n\t}\n\n\tif (DEV) {\n\t\teffect.component_function = null;\n\t}\n\n\t// `first` and `child` are nulled out in destroy_effect_children\n\t// we don't null out `parent` so that error propagation can work correctly\n\teffect.next =\n\t\teffect.prev =\n\t\teffect.teardown =\n\t\teffect.ctx =\n\t\teffect.deps =\n\t\teffect.fn =\n\t\teffect.nodes =\n\t\teffect.ac =\n\t\teffect.b =\n\t\t\tnull;\n}\n\n/**\n *\n * @param {TemplateNode | null} node\n * @param {TemplateNode} end\n */\nexport function remove_effect_dom(node, end) {\n\twhile (node !== null) {\n\t\t/** @type {TemplateNode | null} */\n\t\tvar next = node === end ? null : get_next_sibling(node);\n\n\t\tnode.remove();\n\t\tnode = next;\n\t}\n}\n\n/**\n * Detach an effect from the effect tree, freeing up memory and\n * reducing the amount of work that happens on subsequent traversals\n * @param {Effect} effect\n */\nexport function unlink_effect(effect) {\n\tvar parent = effect.parent;\n\tvar prev = effect.prev;\n\tvar next = effect.next;\n\n\tif (prev !== null) prev.next = next;\n\tif (next !== null) next.prev = prev;\n\n\tif (parent !== null) {\n\t\tif (parent.first === effect) parent.first = next;\n\t\tif (parent.last === effect) parent.last = prev;\n\t}\n}\n\n/**\n * When a block effect is removed, we don't immediately destroy it or yank it\n * out of the DOM, because it might have transitions. Instead, we 'pause' it.\n * It stays around (in memory, and in the DOM) until outro transitions have\n * completed, and if the state change is reversed then we _resume_ it.\n * A paused effect does not update, and the DOM subtree becomes inert.\n * @param {Effect} effect\n * @param {() => void} [callback]\n * @param {boolean} [destroy]\n */\nexport function pause_effect(effect, callback, destroy = true) {\n\t/** @type {TransitionManager[]} */\n\tvar transitions = [];\n\n\teffect.f |= PAUSED;\n\tpause_children(effect, transitions, true);\n\n\tvar fn = () => {\n\t\tif (destroy) destroy_effect(effect);\n\t\tif (callback) callback();\n\t};\n\n\tvar remaining = transitions.length;\n\tif (remaining > 0) {\n\t\tvar check = () => --remaining || fn();\n\t\tfor (var transition of transitions) {\n\t\t\ttransition.out(check);\n\t\t}\n\t} else {\n\t\tfn();\n\t}\n}\n\n/**\n * @param {Effect} effect\n * @param {TransitionManager[]} transitions\n * @param {boolean} local\n */\nfunction pause_children(effect, transitions, local) {\n\tif ((effect.f & INERT) !== 0) return;\n\teffect.f ^= INERT;\n\n\tvar t = effect.nodes && effect.nodes.t;\n\n\tif (t !== null) {\n\t\tfor (const transition of t) {\n\t\t\tif (transition.is_global || local) {\n\t\t\t\ttransitions.push(transition);\n\t\t\t}\n\t\t}\n\t}\n\n\tvar child = effect.first;\n\n\twhile (child !== null) {\n\t\tvar sibling = child.next;\n\n\t\t// If this child is a root effect, then it will become an independent root when its parent\n\t\t// is destroyed, it should therefore not become inert nor partake in transitions.\n\t\tif ((child.f & ROOT_EFFECT) === 0) {\n\t\t\tvar transparent =\n\t\t\t\t(child.f & EFFECT_TRANSPARENT) !== 0 ||\n\t\t\t\t// If this is a branch effect without a block effect parent,\n\t\t\t\t// it means the parent block effect was pruned. In that case,\n\t\t\t\t// transparency information was transferred to the branch effect.\n\t\t\t\t((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0);\n\t\t\t// TODO we don't need to call pause_children recursively with a linked list in place\n\t\t\t// it's slightly more involved though as we have to account for `transparent` changing\n\t\t\t// through the tree.\n\t\t\tpause_children(child, transitions, transparent ? local : false);\n\t\t}\n\n\t\tchild = sibling;\n\t}\n}\n\n/**\n * The opposite of `pause_effect`. We call this if (for example)\n * `x` becomes falsy then truthy: `{#if x}...{/if}`\n * @param {Effect} effect\n */\nexport function resume_effect(effect) {\n\teffect.f &= ~PAUSED;\n\tresume_children(effect, true);\n}\n\n/**\n * @param {Effect} effect\n * @param {boolean} local\n */\nfunction resume_children(effect, local) {\n\t// this subtree was paused for its own reasons (e.g. a block whose condition\n\t// is still false) — its controller will resume or destroy it\n\tif ((effect.f & PAUSED) !== 0) return;\n\n\tif ((effect.f & INERT) === 0) return;\n\teffect.f ^= INERT;\n\n\t// If a dependency of this effect changed while it was paused,\n\t// schedule the effect to update. we don't use `is_dirty`\n\t// here because we don't want to eagerly recompute a derived like\n\t// `{#if foo}{foo.bar()}{/if}` if `foo` is now `undefined\n\tif ((effect.f & CLEAN) === 0) {\n\t\tset_signal_status(effect, DIRTY);\n\t\tBatch.ensure().schedule(effect); // Assumption: This happens during the commit phase of the batch, causing another flush, but it's safe\n\t}\n\n\tvar child = effect.first;\n\n\twhile (child !== null) {\n\t\tvar sibling = child.next;\n\t\tvar transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0;\n\t\t// TODO we don't need to call resume_children recursively with a linked list in place\n\t\t// it's slightly more involved though as we have to account for `transparent` changing\n\t\t// through the tree.\n\t\tresume_children(child, transparent ? local : false);\n\t\tchild = sibling;\n\t}\n\n\tvar t = effect.nodes && effect.nodes.t;\n\n\tif (t !== null) {\n\t\tfor (const transition of t) {\n\t\t\tif (transition.is_global || local) {\n\t\t\t\ttransition.in();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function aborted(effect = /** @type {Effect} */ (active_effect)) {\n\treturn (effect.f & DESTROYED) !== 0;\n}\n\n/**\n * @param {Effect} effect\n * @param {DocumentFragment} fragment\n */\nexport function move_effect(effect, fragment) {\n\tif (!effect.nodes) return;\n\n\t/** @type {TemplateNode | null} */\n\tvar node = effect.nodes.start;\n\tvar end = effect.nodes.end;\n\n\twhile (node !== null) {\n\t\t/** @type {TemplateNode | null} */\n\t\tvar next = node === end ? null : get_next_sibling(node);\n\n\t\tfragment.append(node);\n\t\tnode = next;\n\t}\n}\n","/** @import { Value } from '#client' */\nimport { internal_set } from './reactivity/sources.js';\nimport { untrack } from './runtime.js';\n\n/**\n * @type {Set | null}\n * @deprecated\n */\nexport let captured_signals = null;\n\n/**\n * Capture an array of all the signals that are read when `fn` is called\n * @template T\n * @param {() => T} fn\n */\nfunction capture_signals(fn) {\n\tvar previous_captured_signals = captured_signals;\n\n\ttry {\n\t\tcaptured_signals = new Set();\n\n\t\tuntrack(fn);\n\n\t\tif (previous_captured_signals !== null) {\n\t\t\tfor (var signal of captured_signals) {\n\t\t\t\tprevious_captured_signals.add(signal);\n\t\t\t}\n\t\t}\n\n\t\treturn captured_signals;\n\t} finally {\n\t\tcaptured_signals = previous_captured_signals;\n\t}\n}\n\n/**\n * Invokes a function and captures all signals that are read during the invocation,\n * then invalidates them.\n * @param {() => any} fn\n * @deprecated\n */\nexport function invalidate_inner_signals(fn) {\n\tfor (var signal of capture_signals(fn)) {\n\t\tinternal_set(signal, signal.v);\n\t}\n}\n","/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */\nimport { DEV } from 'esm-env';\nimport { get_descriptors, get_prototype_of, includes, index_of } from '../shared/utils.js';\nimport {\n\tdestroy_block_effect_children,\n\tdestroy_effect_children,\n\teffect_tracking,\n\texecute_effect_teardown\n} from './reactivity/effects.js';\nimport {\n\tDIRTY,\n\tMAYBE_DIRTY,\n\tCLEAN,\n\tDERIVED,\n\tDESTROYED,\n\tBRANCH_EFFECT,\n\tSTATE_SYMBOL,\n\tBLOCK_EFFECT,\n\tROOT_EFFECT,\n\tCONNECTED,\n\tREACTION_IS_UPDATING,\n\tSTALE_REACTION,\n\tERROR_VALUE,\n\tMANAGED_EFFECT,\n\tREACTION_RAN\n} from './constants.js';\nimport { old_values } from './reactivity/sources.js';\nimport {\n\treactivity_loss_tracker,\n\texecute_derived,\n\tfreeze_derived_effects,\n\trecent_async_deriveds,\n\tunfreeze_derived_effects,\n\tupdate_derived\n} from './reactivity/deriveds.js';\nimport { async_mode_flag, tracing_mode_flag } from '../flags/index.js';\nimport { tracing_expressions } from './dev/tracing.js';\nimport { get_error } from '../shared/dev.js';\nimport {\n\tcomponent_context,\n\tdev_current_component_function,\n\tdev_stack,\n\tis_runes,\n\tset_component_context,\n\tset_dev_current_component_function,\n\tset_dev_stack\n} from './context.js';\nimport {\n\tBatch,\n\tbatch_values,\n\tcurrent_batch,\n\tflushSync,\n\tprevious_batch,\n\tschedule_effect\n} from './reactivity/batch.js';\nimport { handle_error } from './error-handling.js';\nimport { UNINITIALIZED } from '../../constants.js';\nimport { captured_signals } from './legacy.js';\nimport { without_reactive_context } from './dom/elements/bindings/shared.js';\nimport { set_signal_status, update_derived_status } from './reactivity/status.js';\nimport * as w from './warnings.js';\n\nexport let is_destroying_effect = false;\n\n/** @param {boolean} value */\nexport function set_is_destroying_effect(value) {\n\tis_destroying_effect = value;\n}\n\n/** @type {null | Reaction} */\nexport let active_reaction = null;\n\nexport let untracking = false;\n\n/** @param {null | Reaction} reaction */\nexport function set_active_reaction(reaction) {\n\tactive_reaction = reaction;\n}\n\n/** @type {null | Effect} */\nexport let active_effect = null;\n\n/** @param {null | Effect} effect */\nexport function set_active_effect(effect) {\n\tactive_effect = effect;\n}\n\n/**\n * When sources are created within a reaction, reading and writing\n * them within that reaction should not cause a re-run\n * @type {null | Set}\n */\nexport let current_sources = null;\n\n/** @param {Value} value */\nexport function push_reaction_value(value) {\n\tif (\n\t\tactive_reaction !== null &&\n\t\t((!async_mode_flag && (active_reaction.f & REACTION_IS_UPDATING) !== 0) ||\n\t\t\t(active_reaction.f & DERIVED) !== 0)\n\t) {\n\t\t(current_sources ??= new Set()).add(value);\n\t}\n}\n\n/**\n * The dependencies of the reaction that is currently being executed. In many cases,\n * the dependencies are unchanged between runs, and so this will be `null` unless\n * and until a new dependency is accessed — we track this via `skipped_deps`\n * @type {null | Value[]}\n */\nexport let new_deps = null;\n\nexport let skipped_deps = 0;\n\n/**\n * Tracks writes that the effect it's executed in doesn't listen to yet,\n * so that the dependency can be added to the effect later on if it then reads it\n * @type {null | Value[]}\n */\nexport let untracked_writes = null;\n\n/** @param {null | Value[]} value */\nexport function set_untracked_writes(value) {\n\tuntracked_writes = value;\n}\n\n/**\n * @type {number} Used by sources and deriveds for handling updates.\n * Version starts from 1 so that unowned deriveds differentiate between a created effect and a run one for tracing\n **/\nexport let write_version = 1;\n\n/** @type {number} Used to version each read of a source of derived to avoid duplicating dependencies inside a reaction */\nlet read_version = 0;\n\nexport let update_version = read_version;\n\n/** @param {number} value */\nexport function set_update_version(value) {\n\tupdate_version = value;\n}\n\nexport function increment_write_version() {\n\treturn ++write_version;\n}\n\n/**\n * Determines whether a derived or effect is dirty.\n * If it is MAYBE_DIRTY, will set the status to CLEAN\n * @param {Reaction} reaction\n * @returns {boolean}\n */\nexport function is_dirty(reaction) {\n\tvar flags = reaction.f;\n\n\tif ((flags & DIRTY) !== 0) {\n\t\treturn true;\n\t}\n\n\tif ((flags & MAYBE_DIRTY) !== 0) {\n\t\tvar dependencies = /** @type {Value[]} */ (reaction.deps);\n\t\tvar length = dependencies.length;\n\n\t\tfor (var i = 0; i < length; i++) {\n\t\t\tvar dependency = dependencies[i];\n\n\t\t\tif (is_dirty(/** @type {Derived} */ (dependency))) {\n\t\t\t\tupdate_derived(/** @type {Derived} */ (dependency));\n\t\t\t}\n\n\t\t\tif (dependency.wv > reaction.wv) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\t(flags & CONNECTED) !== 0 &&\n\t\t\t// During time traveling we don't want to reset the status so that\n\t\t\t// traversal of the graph in the other batches still happens\n\t\t\tbatch_values === null\n\t\t) {\n\t\t\tset_signal_status(reaction, CLEAN);\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * @param {Value} signal\n * @param {Effect} effect\n * @param {boolean} [root]\n */\nfunction schedule_possible_effect_self_invalidation(signal, effect, root = true) {\n\tvar reactions = signal.reactions;\n\tif (reactions === null) return;\n\n\tif (!async_mode_flag && current_sources !== null && current_sources.has(signal)) {\n\t\treturn;\n\t}\n\n\tfor (var i = 0; i < reactions.length; i++) {\n\t\tvar reaction = reactions[i];\n\n\t\tif ((reaction.f & DERIVED) !== 0) {\n\t\t\tschedule_possible_effect_self_invalidation(/** @type {Derived} */ (reaction), effect, false);\n\t\t} else if (effect === reaction) {\n\t\t\tif (root) {\n\t\t\t\tset_signal_status(reaction, DIRTY);\n\t\t\t} else if ((reaction.f & CLEAN) !== 0) {\n\t\t\t\tset_signal_status(reaction, MAYBE_DIRTY);\n\t\t\t}\n\t\t\tschedule_effect(/** @type {Effect} */ (reaction));\n\t\t}\n\t}\n}\n\n/** @param {Reaction} reaction */\nexport function update_reaction(reaction) {\n\tvar previous_deps = new_deps;\n\tvar previous_skipped_deps = skipped_deps;\n\tvar previous_untracked_writes = untracked_writes;\n\tvar previous_reaction = active_reaction;\n\tvar previous_sources = current_sources;\n\tvar previous_component_context = component_context;\n\tvar previous_untracking = untracking;\n\tvar previous_update_version = update_version;\n\n\tvar flags = reaction.f;\n\n\tnew_deps = /** @type {null | Value[]} */ (null);\n\tskipped_deps = 0;\n\tuntracked_writes = null;\n\tactive_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;\n\n\tcurrent_sources = null;\n\tset_component_context(reaction.ctx);\n\tuntracking = false;\n\tupdate_version = ++read_version;\n\n\tif (reaction.ac !== null) {\n\t\twithout_reactive_context(() => {\n\t\t\t/** @type {AbortController} */ (reaction.ac).abort(STALE_REACTION);\n\t\t});\n\n\t\treaction.ac = null;\n\t}\n\n\ttry {\n\t\treaction.f |= REACTION_IS_UPDATING;\n\t\tvar fn = /** @type {Function} */ (reaction.fn);\n\t\tvar result = fn();\n\t\treaction.f |= REACTION_RAN;\n\t\tvar deps = update_dependencies(reaction);\n\n\t\t// If we're inside an effect and we have untracked writes, then we need to\n\t\t// ensure that if any of those untracked writes result in re-invalidation\n\t\t// of the current effect, then that happens accordingly\n\t\tif (\n\t\t\tis_runes() &&\n\t\t\tuntracked_writes !== null &&\n\t\t\t!untracking &&\n\t\t\tdeps !== null &&\n\t\t\t(reaction.f & (DERIVED | MAYBE_DIRTY | DIRTY)) === 0\n\t\t) {\n\t\t\tfor (var i = 0; i < /** @type {Source[]} */ (untracked_writes).length; i++) {\n\t\t\t\tschedule_possible_effect_self_invalidation(\n\t\t\t\t\tuntracked_writes[i],\n\t\t\t\t\t/** @type {Effect} */ (reaction)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// If we are returning to an previous reaction then\n\t\t// we need to increment the read version to ensure that\n\t\t// any dependencies in this reaction aren't marked with\n\t\t// the same version\n\t\tif (previous_reaction !== null && previous_reaction !== reaction) {\n\t\t\tread_version++;\n\n\t\t\t// update the `rv` of the previous reaction's deps — both existing and new —\n\t\t\t// so that they are not added again\n\t\t\tif (previous_reaction.deps !== null) {\n\t\t\t\tfor (let i = 0; i < previous_skipped_deps; i += 1) {\n\t\t\t\t\tprevious_reaction.deps[i].rv = read_version;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (previous_deps !== null) {\n\t\t\t\tfor (const dep of previous_deps) {\n\t\t\t\t\tdep.rv = read_version;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (untracked_writes !== null) {\n\t\t\t\tif (previous_untracked_writes === null) {\n\t\t\t\t\tprevious_untracked_writes = untracked_writes;\n\t\t\t\t} else {\n\t\t\t\t\tprevious_untracked_writes.push(.../** @type {Source[]} */ (untracked_writes));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ((reaction.f & ERROR_VALUE) !== 0) {\n\t\t\treaction.f ^= ERROR_VALUE;\n\t\t}\n\n\t\treturn result;\n\t} catch (error) {\n\t\t// still commit the deps read before the throw, otherwise deriveds connected by this run keep no reader and the reaction never re-runs when they change\n\t\tupdate_dependencies(reaction);\n\n\t\treturn handle_error(error);\n\t} finally {\n\t\treaction.f ^= REACTION_IS_UPDATING;\n\t\tnew_deps = previous_deps;\n\t\tskipped_deps = previous_skipped_deps;\n\t\tuntracked_writes = previous_untracked_writes;\n\t\tactive_reaction = previous_reaction;\n\t\tcurrent_sources = previous_sources;\n\t\tset_component_context(previous_component_context);\n\t\tuntracking = previous_untracking;\n\t\tupdate_version = previous_update_version;\n\t}\n}\n\n/**\n * @param {Reaction} reaction\n */\nfunction update_dependencies(reaction) {\n\tvar deps = reaction.deps;\n\n\t// Don't remove reactions during fork;\n\t// they must remain for when fork is discarded\n\tvar is_fork = current_batch?.is_fork;\n\n\tif (new_deps !== null) {\n\t\tvar i;\n\n\t\tif (!is_fork) {\n\t\t\tremove_reactions(reaction, skipped_deps);\n\t\t}\n\n\t\tif (deps !== null && skipped_deps > 0) {\n\t\t\tdeps.length = skipped_deps + new_deps.length;\n\t\t\tfor (i = 0; i < new_deps.length; i++) {\n\t\t\t\tdeps[skipped_deps + i] = new_deps[i];\n\t\t\t}\n\t\t} else {\n\t\t\treaction.deps = deps = new_deps;\n\t\t}\n\n\t\tif (effect_tracking() && (reaction.f & CONNECTED) !== 0) {\n\t\t\tfor (i = skipped_deps; i < deps.length; i++) {\n\t\t\t\t(deps[i].reactions ??= []).push(reaction);\n\t\t\t}\n\t\t}\n\t} else if (!is_fork && deps !== null && skipped_deps < deps.length) {\n\t\tremove_reactions(reaction, skipped_deps);\n\t\tdeps.length = skipped_deps;\n\t}\n\n\treturn deps;\n}\n\n/**\n * @template V\n * @param {Reaction} signal\n * @param {Value} dependency\n * @returns {void}\n */\nfunction remove_reaction(signal, dependency) {\n\tlet reactions = dependency.reactions;\n\tif (reactions !== null) {\n\t\tvar index = index_of.call(reactions, signal);\n\t\tif (index !== -1) {\n\t\t\tvar new_length = reactions.length - 1;\n\t\t\tif (new_length === 0) {\n\t\t\t\treactions = dependency.reactions = null;\n\t\t\t} else {\n\t\t\t\t// Swap with last element and then remove.\n\t\t\t\treactions[index] = reactions[new_length];\n\t\t\t\treactions.pop();\n\t\t\t}\n\t\t}\n\t}\n\n\t// If the derived has no reactions, then we can disconnect it from the graph,\n\t// allowing it to either reconnect in the future, or be GC'd by the VM.\n\tif (\n\t\treactions === null &&\n\t\t(dependency.f & DERIVED) !== 0 &&\n\t\t// Destroying a child effect while updating a parent effect can cause a dependency to appear\n\t\t// to be unused, when in fact it is used by the currently-updating parent. Checking `new_deps`\n\t\t// allows us to skip the expensive work of disconnecting and immediately reconnecting it\n\t\t(new_deps === null || !includes.call(new_deps, dependency))\n\t) {\n\t\tvar derived = /** @type {Derived} */ (dependency);\n\n\t\tif ((derived.f & CONNECTED) !== 0) {\n\t\t\tderived.f ^= CONNECTED;\n\t\t}\n\n\t\t// In a fork it's possible that a derived is executed and gets reactions, then commits, but is\n\t\t// never re-executed. This is possible when the derived is only executed once in the context\n\t\t// of a new branch which happens before fork.commit() runs. In this case, the derived still has\n\t\t// UNINITIALIZED as its value, and then when it's losing its reactions we need to ensure it stays\n\t\t// DIRTY so it is reexecuted once someone wants its value again.\n\t\tif (derived.v !== UNINITIALIZED) {\n\t\t\tupdate_derived_status(derived);\n\t\t}\n\n\t\t// Call abort controller, noone's listening to this derived anymore\n\t\tif (derived.ac !== null) {\n\t\t\twithout_reactive_context(() => {\n\t\t\t\t/** @type {AbortController} */ (derived.ac).abort(STALE_REACTION);\n\t\t\t\tderived.ac = null;\n\t\t\t\t// ensure it reruns right away next time instead of potentially returning a rejected promise as its value\n\t\t\t\tset_signal_status(derived, DIRTY);\n\t\t\t});\n\t\t}\n\n\t\t// freeze any effects inside this derived\n\t\tfreeze_derived_effects(derived);\n\n\t\t// Disconnect any reactions owned by this reaction\n\t\tremove_reactions(derived, 0);\n\t}\n}\n\n/**\n * @param {Reaction} signal\n * @param {number} start_index\n * @returns {void}\n */\nexport function remove_reactions(signal, start_index) {\n\tvar dependencies = signal.deps;\n\tif (dependencies === null) return;\n\n\tfor (var i = start_index; i < dependencies.length; i++) {\n\t\tremove_reaction(signal, dependencies[i]);\n\t}\n}\n\n/**\n * @param {Effect} effect\n * @returns {void}\n */\nexport function update_effect(effect) {\n\tvar flags = effect.f;\n\n\tif ((flags & DESTROYED) !== 0) {\n\t\treturn;\n\t}\n\n\tset_signal_status(effect, CLEAN);\n\n\tvar previous_effect = active_effect;\n\n\tactive_effect = effect;\n\n\tif (DEV) {\n\t\tvar previous_component_fn = dev_current_component_function;\n\t\tset_dev_current_component_function(effect.component_function);\n\t\tvar previous_stack = /** @type {any} */ (dev_stack);\n\t\t// only block effects have a dev stack, keep the current one otherwise\n\t\tset_dev_stack(effect.dev_stack ?? dev_stack);\n\t}\n\n\ttry {\n\t\tif ((flags & (BLOCK_EFFECT | MANAGED_EFFECT)) !== 0) {\n\t\t\tdestroy_block_effect_children(effect);\n\t\t} else {\n\t\t\tdestroy_effect_children(effect);\n\t\t}\n\n\t\texecute_effect_teardown(effect);\n\t\tvar teardown = update_reaction(effect);\n\t\teffect.teardown = typeof teardown === 'function' ? teardown : null;\n\t\teffect.wv = write_version;\n\n\t\t// In DEV, increment versions of any sources that were written to during the effect,\n\t\t// so that they are correctly marked as dirty when the effect re-runs\n\t\tif (DEV && tracing_mode_flag && (effect.f & DIRTY) !== 0 && effect.deps !== null) {\n\t\t\tfor (var dep of effect.deps) {\n\t\t\t\tif (dep.set_during_effect) {\n\t\t\t\t\tdep.wv = increment_write_version();\n\t\t\t\t\tdep.set_during_effect = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tactive_effect = previous_effect;\n\n\t\tif (DEV) {\n\t\t\tset_dev_current_component_function(previous_component_fn);\n\t\t\tset_dev_stack(previous_stack);\n\t\t}\n\t}\n}\n\n/**\n * Returns a promise that resolves once any pending state changes have been applied.\n * @returns {Promise}\n */\nexport async function tick() {\n\tif (async_mode_flag) {\n\t\treturn new Promise((f) => {\n\t\t\t// Race them against each other - in almost all cases requestAnimationFrame will fire first,\n\t\t\t// but e.g. in case the window is not focused or a view transition happens, requestAnimationFrame\n\t\t\t// will be delayed and setTimeout helps us resolve fast enough in that case\n\t\t\trequestAnimationFrame(() => f());\n\t\t\tsetTimeout(() => f());\n\t\t});\n\t}\n\n\tawait Promise.resolve();\n\n\t// By calling flushSync we guarantee that any pending state changes are applied after one tick.\n\t// TODO look into whether we can make flushing subsequent updates synchronously in the future.\n\tflushSync();\n}\n\n/**\n * Returns a promise that resolves once any state changes, and asynchronous work resulting from them,\n * have resolved and the DOM has been updated\n * @returns {Promise}\n * @since 5.36\n */\nexport function settled() {\n\treturn Batch.ensure().settled();\n}\n\n/**\n * @template V\n * @param {Value} signal\n * @returns {V}\n */\nexport function get(signal) {\n\tvar flags = signal.f;\n\tvar is_derived = (flags & DERIVED) !== 0;\n\n\tcaptured_signals?.add(signal);\n\n\t// Register the dependency on the current reaction signal.\n\tif (active_reaction !== null && !untracking) {\n\t\t// if we're in a derived that is being read inside an _async_ derived,\n\t\t// it's possible that the effect was already destroyed. In this case,\n\t\t// we don't add the dependency, because that would create a memory leak\n\t\tvar destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0;\n\n\t\tif (!destroyed && (current_sources === null || !current_sources.has(signal))) {\n\t\t\tvar deps = active_reaction.deps;\n\n\t\t\tif ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {\n\t\t\t\t// we're in the effect init/update cycle\n\t\t\t\tif (signal.rv < read_version) {\n\t\t\t\t\tsignal.rv = read_version;\n\n\t\t\t\t\t// If the signal is accessing the same dependencies in the same\n\t\t\t\t\t// order as it did last time, increment `skipped_deps`\n\t\t\t\t\t// rather than updating `new_deps`, which creates GC cost\n\t\t\t\t\tif (new_deps === null && deps !== null && deps[skipped_deps] === signal) {\n\t\t\t\t\t\tskipped_deps++;\n\t\t\t\t\t} else if (new_deps === null) {\n\t\t\t\t\t\tnew_deps = [signal];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnew_deps.push(signal);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We're adding a dependency outside the init/update cycle (i.e. after an `await`).\n\t\t\t\t// We have to deduplicate deps/reactions in this case or remove_reactions could\n\t\t\t\t// disconnect deps/reactions that are actually still in use (if skip_deps says\n\t\t\t\t// \"disconnect all after this index\" and some of the signals are also present in\n\t\t\t\t// list prior to the cutoff index, i.e. that should be kept).\n\t\t\t\tactive_reaction.deps ??= [];\n\t\t\t\tif (!includes.call(active_reaction.deps, signal)) {\n\t\t\t\t\tactive_reaction.deps.push(signal);\n\t\t\t\t}\n\n\t\t\t\tvar reactions = signal.reactions;\n\n\t\t\t\tif (reactions === null) {\n\t\t\t\t\tsignal.reactions = [active_reaction];\n\t\t\t\t} else if (!includes.call(reactions, active_reaction)) {\n\t\t\t\t\treactions.push(active_reaction);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (DEV) {\n\t\tif (\n\t\t\t!untracking &&\n\t\t\treactivity_loss_tracker &&\n\t\t\t// By checking that current/previous batch are null we filter out false positives.\n\t\t\t// reactivity_loss_tracker is only reset after a microtask, so if a flush happens\n\t\t\t// before that, we get warnings for things we shouldn't warn on.\n\t\t\tcurrent_batch === null &&\n\t\t\tprevious_batch === null &&\n\t\t\t!reactivity_loss_tracker.warned &&\n\t\t\t(reactivity_loss_tracker.effect.f & REACTION_IS_UPDATING) === 0 &&\n\t\t\t!reactivity_loss_tracker.effect_deps.has(signal)\n\t\t) {\n\t\t\treactivity_loss_tracker.warned = true;\n\n\t\t\tw.await_reactivity_loss(/** @type {string} */ (signal.label));\n\n\t\t\tvar trace = get_error('traced at');\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tif (trace) console.warn(trace);\n\t\t}\n\n\t\trecent_async_deriveds.delete(signal);\n\n\t\tif (\n\t\t\ttracing_mode_flag &&\n\t\t\t!untracking &&\n\t\t\ttracing_expressions !== null &&\n\t\t\tactive_reaction !== null &&\n\t\t\ttracing_expressions.reaction === active_reaction\n\t\t) {\n\t\t\t// Used when mapping state between special blocks like `each`\n\t\t\tif (signal.trace) {\n\t\t\t\tsignal.trace();\n\t\t\t} else {\n\t\t\t\ttrace = get_error('traced at');\n\n\t\t\t\tif (trace) {\n\t\t\t\t\tvar entry = tracing_expressions.entries.get(signal);\n\n\t\t\t\t\tif (entry === undefined) {\n\t\t\t\t\t\tentry = { traces: [] };\n\t\t\t\t\t\ttracing_expressions.entries.set(signal, entry);\n\t\t\t\t\t}\n\n\t\t\t\t\tvar last = entry.traces[entry.traces.length - 1];\n\n\t\t\t\t\t// traces can be duplicated, e.g. by `snapshot` invoking both\n\t\t\t\t\t// both `getOwnPropertyDescriptor` and `get` traps at once\n\t\t\t\t\tif (trace.stack !== last?.stack) {\n\t\t\t\t\t\tentry.traces.push(trace);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (is_destroying_effect && old_values.has(signal)) {\n\t\treturn old_values.get(signal);\n\t}\n\n\tif (is_derived) {\n\t\tvar derived = /** @type {Derived} */ (signal);\n\n\t\tif (is_destroying_effect) {\n\t\t\tvar value = derived.v;\n\n\t\t\t// if the derived is dirty and has reactions, or depends on the values that just changed, re-execute\n\t\t\t// (a derived can be maybe_dirty due to the effect destroy removing its last reaction)\n\t\t\tif (\n\t\t\t\t((derived.f & CLEAN) === 0 && derived.reactions !== null) ||\n\t\t\t\tdepends_on_old_values(derived)\n\t\t\t) {\n\t\t\t\tvalue = execute_derived(derived);\n\t\t\t}\n\n\t\t\told_values.set(derived, value);\n\n\t\t\treturn value;\n\t\t}\n\n\t\t// connect disconnected deriveds when reading them inside a connected reaction\n\t\tvar should_connect =\n\t\t\t(derived.f & CONNECTED) === 0 &&\n\t\t\t!untracking &&\n\t\t\tactive_reaction !== null &&\n\t\t\t(active_reaction.f & CONNECTED) !== 0;\n\n\t\tvar is_new = (derived.f & REACTION_RAN) === 0;\n\n\t\tif (is_dirty(derived)) {\n\t\t\tif (should_connect) {\n\t\t\t\t// set the flag before `update_derived`, so that the derived\n\t\t\t\t// is added as a reaction to its dependencies\n\t\t\t\tderived.f |= CONNECTED;\n\t\t\t}\n\n\t\t\tupdate_derived(derived);\n\t\t}\n\n\t\tif (should_connect && !is_new) {\n\t\t\tunfreeze_derived_effects(derived);\n\t\t\treconnect(derived);\n\t\t}\n\t}\n\n\tif (batch_values?.has(signal)) {\n\t\treturn batch_values.get(signal);\n\t}\n\n\tif ((signal.f & ERROR_VALUE) !== 0) {\n\t\tthrow signal.v;\n\t}\n\n\treturn signal.v;\n}\n\n/**\n * (Re)connect a disconnected derived, so that it is notified\n * of changes in `mark_reactions`\n * @param {Derived} derived\n */\nfunction reconnect(derived) {\n\tderived.f |= CONNECTED;\n\n\tif (derived.deps === null) return;\n\n\tfor (const dep of derived.deps) {\n\t\tvar reactions = dep.reactions;\n\n\t\tif (reactions === null) {\n\t\t\tdep.reactions = [derived];\n\t\t} else if (!includes.call(reactions, derived)) {\n\t\t\treactions.push(derived);\n\t\t}\n\n\t\tif ((dep.f & DERIVED) !== 0 && (dep.f & CONNECTED) === 0) {\n\t\t\tunfreeze_derived_effects(/** @type {Derived} */ (dep));\n\t\t\treconnect(/** @type {Derived} */ (dep));\n\t\t}\n\t}\n}\n\n/** @param {Derived} derived */\nfunction depends_on_old_values(derived) {\n\tif (derived.v === UNINITIALIZED) return true; // we don't know, so assume the worst\n\tif (derived.deps === null) return false;\n\n\tfor (const dep of derived.deps) {\n\t\tif (old_values.has(dep)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ((dep.f & DERIVED) !== 0 && depends_on_old_values(/** @type {Derived} */ (dep))) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Like `get`, but checks for `undefined`. Used for `var` declarations because they can be accessed before being declared\n * @template V\n * @param {Value | undefined} signal\n * @returns {V | undefined}\n */\nexport function safe_get(signal) {\n\treturn signal && get(signal);\n}\n\n/**\n * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect),\n * any state read inside `fn` will not be treated as a dependency.\n *\n * ```ts\n * $effect(() => {\n * // this will run when `data` changes, but not when `time` changes\n * save(data, {\n * timestamp: untrack(() => time)\n * });\n * });\n * ```\n * @template T\n * @param {() => T} fn\n * @returns {T}\n */\nexport function untrack(fn) {\n\tvar previous_untracking = untracking;\n\ttry {\n\t\tuntracking = true;\n\t\treturn fn();\n\t} finally {\n\t\tuntracking = previous_untracking;\n\t}\n}\n\n/**\n * Possibly traverse an object and read all its properties so that they're all reactive in case this is `$state`.\n * Does only check first level of an object for performance reasons (heuristic should be good for 99% of all cases).\n * @param {any} value\n * @returns {void}\n */\nexport function deep_read_state(value) {\n\tif (typeof value !== 'object' || !value || value instanceof EventTarget) {\n\t\treturn;\n\t}\n\n\tif (STATE_SYMBOL in value) {\n\t\tdeep_read(value);\n\t} else if (!Array.isArray(value)) {\n\t\tfor (let key in value) {\n\t\t\tconst prop = value[key];\n\t\t\tif (typeof prop === 'object' && prop && STATE_SYMBOL in prop) {\n\t\t\t\tdeep_read(prop);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Deeply traverse an object and read all its properties\n * so that they're all reactive in case this is `$state`\n * @param {any} value\n * @param {Set} visited\n * @returns {void}\n */\nexport function deep_read(value, visited = new Set()) {\n\tif (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t// We don't want to traverse DOM elements\n\t\t!(value instanceof EventTarget) &&\n\t\t!visited.has(value)\n\t) {\n\t\tvisited.add(value);\n\t\t// When working with a possible SvelteDate, this\n\t\t// will ensure we capture changes to it.\n\t\tif (value instanceof Date) {\n\t\t\tvalue.getTime();\n\t\t}\n\t\tfor (let key in value) {\n\t\t\ttry {\n\t\t\t\tdeep_read(value[key], visited);\n\t\t\t} catch (e) {\n\t\t\t\t// continue\n\t\t\t}\n\t\t}\n\t\tconst proto = get_prototype_of(value);\n\t\tif (\n\t\t\tproto !== Object.prototype &&\n\t\t\tproto !== Array.prototype &&\n\t\t\tproto !== Map.prototype &&\n\t\t\tproto !== Set.prototype &&\n\t\t\tproto !== Date.prototype\n\t\t) {\n\t\t\tconst descriptors = get_descriptors(proto);\n\t\t\tfor (let key in descriptors) {\n\t\t\t\tconst get = descriptors[key].get;\n\t\t\t\tif (get) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tget.call(value);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t// continue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","const regex_return_characters = /\\r/g;\n\n/**\n * @param {string} str\n * @returns {string}\n */\nexport function hash(str) {\n\tstr = str.replace(regex_return_characters, '');\n\tlet hash = 5381;\n\tlet i = str.length;\n\n\twhile (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n\treturn (hash >>> 0).toString(36);\n}\n\nconst VOID_ELEMENT_NAMES = [\n\t'area',\n\t'base',\n\t'br',\n\t'col',\n\t'command',\n\t'embed',\n\t'hr',\n\t'img',\n\t'input',\n\t'keygen',\n\t'link',\n\t'meta',\n\t'param',\n\t'source',\n\t'track',\n\t'wbr'\n];\n\n/**\n * Returns `true` if `name` is of a void element\n * @param {string} name\n */\nexport function is_void(name) {\n\treturn VOID_ELEMENT_NAMES.includes(name) || name.toLowerCase() === '!doctype';\n}\n\nconst RESERVED_WORDS = [\n\t'arguments',\n\t'await',\n\t'break',\n\t'case',\n\t'catch',\n\t'class',\n\t'const',\n\t'continue',\n\t'debugger',\n\t'default',\n\t'delete',\n\t'do',\n\t'else',\n\t'enum',\n\t'eval',\n\t'export',\n\t'extends',\n\t'false',\n\t'finally',\n\t'for',\n\t'function',\n\t'if',\n\t'implements',\n\t'import',\n\t'in',\n\t'instanceof',\n\t'interface',\n\t'let',\n\t'new',\n\t'null',\n\t'package',\n\t'private',\n\t'protected',\n\t'public',\n\t'return',\n\t'static',\n\t'super',\n\t'switch',\n\t'this',\n\t'throw',\n\t'true',\n\t'try',\n\t'typeof',\n\t'var',\n\t'void',\n\t'while',\n\t'with',\n\t'yield'\n];\n\n/**\n * Returns `true` if `word` is a reserved JavaScript keyword\n * @param {string} word\n */\nexport function is_reserved(word) {\n\treturn RESERVED_WORDS.includes(word);\n}\n\n/**\n * @param {string} name\n */\nexport function is_capture_event(name) {\n\treturn name.endsWith('capture') && name !== 'gotpointercapture' && name !== 'lostpointercapture';\n}\n\n/** List of Element events that will be delegated */\nconst DELEGATED_EVENTS = [\n\t'beforeinput',\n\t'click',\n\t'change',\n\t'dblclick',\n\t'contextmenu',\n\t'focusin',\n\t'focusout',\n\t'input',\n\t'keydown',\n\t'keyup',\n\t'mousedown',\n\t'mousemove',\n\t'mouseout',\n\t'mouseover',\n\t'mouseup',\n\t'pointerdown',\n\t'pointermove',\n\t'pointerout',\n\t'pointerover',\n\t'pointerup',\n\t'touchend',\n\t'touchmove',\n\t'touchstart'\n];\n\n/**\n * Returns `true` if `event_name` is a delegated event\n * @param {string} event_name\n */\nexport function can_delegate_event(event_name) {\n\treturn DELEGATED_EVENTS.includes(event_name);\n}\n\n/**\n * Attributes that are boolean, i.e. they are present or not present.\n */\nconst DOM_BOOLEAN_ATTRIBUTES = [\n\t'allowfullscreen',\n\t'async',\n\t'autofocus',\n\t'autoplay',\n\t'checked',\n\t'controls',\n\t'default',\n\t'disabled',\n\t'formnovalidate',\n\t'indeterminate',\n\t'inert',\n\t'ismap',\n\t'loop',\n\t'multiple',\n\t'muted',\n\t'nomodule',\n\t'novalidate',\n\t'open',\n\t'playsinline',\n\t'readonly',\n\t'required',\n\t'reversed',\n\t'seamless',\n\t'selected',\n\t'webkitdirectory',\n\t'defer',\n\t'disablepictureinpicture',\n\t'disableremoteplayback'\n];\n\n/**\n * Returns `true` if `name` is a boolean attribute\n * @param {string} name\n */\nexport function is_boolean_attribute(name) {\n\treturn DOM_BOOLEAN_ATTRIBUTES.includes(name);\n}\n\n/**\n * @type {Record}\n * List of attribute names that should be aliased to their property names\n * because they behave differently between setting them as an attribute and\n * setting them as a property.\n */\nconst ATTRIBUTE_ALIASES = {\n\t// no `class: 'className'` because we handle that separately\n\tformnovalidate: 'formNoValidate',\n\tismap: 'isMap',\n\tnomodule: 'noModule',\n\tplaysinline: 'playsInline',\n\treadonly: 'readOnly',\n\tdefaultvalue: 'defaultValue',\n\tdefaultchecked: 'defaultChecked',\n\tsrcobject: 'srcObject',\n\tnovalidate: 'noValidate',\n\tallowfullscreen: 'allowFullscreen',\n\tdisablepictureinpicture: 'disablePictureInPicture',\n\tdisableremoteplayback: 'disableRemotePlayback'\n};\n\n/**\n * @param {string} name\n */\nexport function normalize_attribute(name) {\n\tname = name.toLowerCase();\n\treturn ATTRIBUTE_ALIASES[name] ?? name;\n}\n\nconst DOM_PROPERTIES = [\n\t...DOM_BOOLEAN_ATTRIBUTES,\n\t'formNoValidate',\n\t'isMap',\n\t'noModule',\n\t'playsInline',\n\t'readOnly',\n\t'value',\n\t'volume',\n\t'defaultValue',\n\t'defaultChecked',\n\t'srcObject',\n\t'noValidate',\n\t'allowFullscreen',\n\t'disablePictureInPicture',\n\t'disableRemotePlayback'\n];\n\n/**\n * @param {string} name\n */\nexport function is_dom_property(name) {\n\treturn DOM_PROPERTIES.includes(name);\n}\n\nconst NON_STATIC_PROPERTIES = ['autofocus', 'muted', 'defaultValue', 'defaultChecked'];\n\n/**\n * Returns `true` if the given attribute cannot be set through the template\n * string, i.e. needs some kind of JavaScript handling to work.\n * @param {string} name\n */\nexport function cannot_be_set_statically(name) {\n\treturn NON_STATIC_PROPERTIES.includes(name);\n}\n\n/**\n * Subset of delegated events which should be passive by default.\n * These two are already passive via browser defaults on window, document and body.\n * But since\n * - we're delegating them\n * - they happen often\n * - they apply to mobile which is generally less performant\n * we're marking them as passive by default for other elements, too.\n */\nconst PASSIVE_EVENTS = ['touchstart', 'touchmove'];\n\n/**\n * Returns `true` if `name` is a passive event\n * @param {string} name\n */\nexport function is_passive_event(name) {\n\treturn PASSIVE_EVENTS.includes(name);\n}\n\nconst CONTENT_EDITABLE_BINDINGS = ['textContent', 'innerHTML', 'innerText'];\n\n/** @param {string} name */\nexport function is_content_editable_binding(name) {\n\treturn CONTENT_EDITABLE_BINDINGS.includes(name);\n}\n\nconst LOAD_ERROR_ELEMENTS = [\n\t'body',\n\t'embed',\n\t'iframe',\n\t'img',\n\t'link',\n\t'object',\n\t'script',\n\t'style',\n\t'track'\n];\n\n/**\n * Returns `true` if the element emits `load` and `error` events\n * @param {string} name\n */\nexport function is_load_error_element(name) {\n\treturn LOAD_ERROR_ELEMENTS.includes(name);\n}\n\nconst SVG_ELEMENTS = [\n\t'altGlyph',\n\t'altGlyphDef',\n\t'altGlyphItem',\n\t'animate',\n\t'animateColor',\n\t'animateMotion',\n\t'animateTransform',\n\t'circle',\n\t'clipPath',\n\t'color-profile',\n\t'cursor',\n\t'defs',\n\t'desc',\n\t'discard',\n\t'ellipse',\n\t'feBlend',\n\t'feColorMatrix',\n\t'feComponentTransfer',\n\t'feComposite',\n\t'feConvolveMatrix',\n\t'feDiffuseLighting',\n\t'feDisplacementMap',\n\t'feDistantLight',\n\t'feDropShadow',\n\t'feFlood',\n\t'feFuncA',\n\t'feFuncB',\n\t'feFuncG',\n\t'feFuncR',\n\t'feGaussianBlur',\n\t'feImage',\n\t'feMerge',\n\t'feMergeNode',\n\t'feMorphology',\n\t'feOffset',\n\t'fePointLight',\n\t'feSpecularLighting',\n\t'feSpotLight',\n\t'feTile',\n\t'feTurbulence',\n\t'filter',\n\t'font',\n\t'font-face',\n\t'font-face-format',\n\t'font-face-name',\n\t'font-face-src',\n\t'font-face-uri',\n\t'foreignObject',\n\t'g',\n\t'glyph',\n\t'glyphRef',\n\t'hatch',\n\t'hatchpath',\n\t'hkern',\n\t'image',\n\t'line',\n\t'linearGradient',\n\t'marker',\n\t'mask',\n\t'mesh',\n\t'meshgradient',\n\t'meshpatch',\n\t'meshrow',\n\t'metadata',\n\t'missing-glyph',\n\t'mpath',\n\t'path',\n\t'pattern',\n\t'polygon',\n\t'polyline',\n\t'radialGradient',\n\t'rect',\n\t'set',\n\t'solidcolor',\n\t'stop',\n\t'svg',\n\t'switch',\n\t'symbol',\n\t'text',\n\t'textPath',\n\t'tref',\n\t'tspan',\n\t'unknown',\n\t'use',\n\t'view',\n\t'vkern'\n];\n\n/** @param {string} name */\nexport function is_svg(name) {\n\treturn SVG_ELEMENTS.includes(name);\n}\n\nconst MATHML_ELEMENTS = [\n\t'annotation',\n\t'annotation-xml',\n\t'maction',\n\t'math',\n\t'merror',\n\t'mfrac',\n\t'mi',\n\t'mmultiscripts',\n\t'mn',\n\t'mo',\n\t'mover',\n\t'mpadded',\n\t'mphantom',\n\t'mprescripts',\n\t'mroot',\n\t'mrow',\n\t'ms',\n\t'mspace',\n\t'msqrt',\n\t'mstyle',\n\t'msub',\n\t'msubsup',\n\t'msup',\n\t'mtable',\n\t'mtd',\n\t'mtext',\n\t'mtr',\n\t'munder',\n\t'munderover',\n\t'semantics'\n];\n\n/** @param {string} name */\nexport function is_mathml(name) {\n\treturn MATHML_ELEMENTS.includes(name);\n}\n\nconst STATE_CREATION_RUNES = /** @type {const} */ ([\n\t'$state',\n\t'$state.raw',\n\t'$derived',\n\t'$derived.by'\n]);\n\nexport const RUNES = /** @type {const} */ ([\n\t...STATE_CREATION_RUNES,\n\t'$state.eager',\n\t'$state.snapshot',\n\t'$props',\n\t'$props.id',\n\t'$bindable',\n\t'$effect',\n\t'$effect.pre',\n\t'$effect.tracking',\n\t'$effect.root',\n\t'$effect.pending',\n\t'$inspect',\n\t'$inspect().with',\n\t'$inspect.trace',\n\t'$host'\n]);\n\n/** @typedef {typeof RUNES[number]} RuneName */\n\n/**\n * @param {string} name\n * @returns {name is RuneName}\n */\nexport function is_rune(name) {\n\treturn RUNES.includes(/** @type {RuneName} */ (name));\n}\n\n/** @typedef {typeof STATE_CREATION_RUNES[number]} StateCreationRuneName */\n\n/**\n * @param {string} name\n * @returns {name is StateCreationRuneName}\n */\nexport function is_state_creation_rune(name) {\n\treturn STATE_CREATION_RUNES.includes(/** @type {StateCreationRuneName} */ (name));\n}\n\n/** List of elements that require raw contents and should not have SSR comments put in them */\nconst RAW_TEXT_ELEMENTS = /** @type {const} */ (['textarea', 'script', 'style', 'title']);\n\n/** @param {string} name */\nexport function is_raw_text_element(name) {\n\treturn RAW_TEXT_ELEMENTS.includes(/** @type {typeof RAW_TEXT_ELEMENTS[number]} */ (name));\n}\n\n// Matches valid HTML/SVG/MathML element names and custom element names.\n// https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name\n//\n// Standard elements: ASCII alpha start, followed by ASCII alphanumerics.\n// Custom elements: ASCII alpha start, followed by any mix of PCENChar (which\n// includes ASCII alphanumerics, `-`, `.`, `_`, and specified Unicode ranges),\n// with at least one hyphen required somewhere after the first character.\n//\n// Rejects strings containing whitespace, quotes, angle brackets, slashes, equals,\n// or other characters that could break out of a tag-name token and enable markup injection.\nexport const REGEX_VALID_TAG_NAME =\n\t/^[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9.\\-_\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u203F-\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\u{10000}-\\u{EFFFF}]*)?$/u;\n\n/**\n * Prevent devtools trying to make `location` a clickable link by inserting a zero-width space\n * @template {string | undefined} T\n * @param {T} location\n * @returns {T};\n */\nexport function sanitize_location(location) {\n\treturn /** @type {T} */ (location?.replace(/\\//g, '/\\u200b'));\n}\n","import { teardown } from '../../reactivity/effects.js';\nimport { define_property } from '../../../shared/utils.js';\nimport { hydrating } from '../hydration.js';\nimport { queue_micro_task } from '../task.js';\nimport { FILENAME } from '../../../../constants.js';\nimport * as w from '../../warnings.js';\nimport {\n\tactive_effect,\n\tactive_reaction,\n\tset_active_effect,\n\tset_active_reaction\n} from '../../runtime.js';\nimport { without_reactive_context } from './bindings/shared.js';\n\n/**\n * Used on elements, as a map of event type -> event handler,\n * and on events themselves to track which element handled an event\n */\nexport const event_symbol = Symbol('events');\n\n/** @type {Set} */\nexport const all_registered_events = new Set();\n\n/** @type {Set<(events: Array) => void>} */\nexport const root_event_handles = new Set();\n\n/**\n * SSR adds onload and onerror attributes to catch those events before the hydration.\n * This function detects those cases, removes the attributes and replays the events.\n * @param {HTMLElement} dom\n */\nexport function replay_events(dom) {\n\tif (!hydrating) return;\n\n\tdom.removeAttribute('onload');\n\tdom.removeAttribute('onerror');\n\t// @ts-expect-error\n\tconst event = dom.__e;\n\tif (event !== undefined) {\n\t\t// @ts-expect-error\n\t\tdom.__e = undefined;\n\t\tqueueMicrotask(() => {\n\t\t\tif (dom.isConnected) {\n\t\t\t\tdom.dispatchEvent(event);\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * @param {string} event_name\n * @param {EventTarget} dom\n * @param {EventListener} [handler]\n * @param {AddEventListenerOptions} [options]\n */\nexport function create_event(event_name, dom, handler, options = {}) {\n\t/**\n\t * @this {EventTarget}\n\t */\n\tfunction target_handler(/** @type {Event} */ event) {\n\t\tif (!options.capture) {\n\t\t\t// Only call in the bubble phase, else delegated events would be called before the capturing events\n\t\t\thandle_event_propagation.call(dom, event);\n\t\t}\n\t\tif (!event.cancelBubble) {\n\t\t\treturn without_reactive_context(() => {\n\t\t\t\treturn handler?.call(this, event);\n\t\t\t});\n\t\t}\n\t}\n\n\t// Chrome has a bug where pointer events don't work when attached to a DOM element that has been cloned\n\t// with cloneNode() and the DOM element is disconnected from the document. To ensure the event works, we\n\t// defer the attachment till after it's been appended to the document. TODO: remove this once Chrome fixes\n\t// this bug. The same applies to wheel events and touch events.\n\tif (\n\t\tevent_name.startsWith('pointer') ||\n\t\tevent_name.startsWith('touch') ||\n\t\tevent_name === 'wheel'\n\t) {\n\t\ttarget_handler.__removed = false;\n\t\tqueue_micro_task(() => {\n\t\t\tif (!target_handler.__removed) {\n\t\t\t\tdom.addEventListener(event_name, target_handler, options);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tdom.addEventListener(event_name, target_handler, options);\n\t}\n\n\treturn target_handler;\n}\n\n/**\n * Attaches an event handler to an element and returns a function that removes the handler. Using this\n * rather than `addEventListener` will preserve the correct order relative to handlers added declaratively\n * (with attributes like `onclick`), which use event delegation for performance reasons\n *\n * @param {EventTarget} element\n * @param {string} type\n * @param {EventListener} handler\n * @param {AddEventListenerOptions} [options]\n */\nexport function on(element, type, handler, options = {}) {\n\tvar target_handler = create_event(type, element, handler, options);\n\n\treturn () => {\n\t\ttarget_handler.__removed = true;\n\t\telement.removeEventListener(type, target_handler, options);\n\t};\n}\n\n/**\n * @param {string} event_name\n * @param {Element} dom\n * @param {EventListener} [handler]\n * @param {boolean} [capture]\n * @param {boolean} [passive]\n * @returns {void}\n */\nexport function event(event_name, dom, handler, capture, passive) {\n\tvar options = { capture, passive };\n\tvar target_handler = create_event(event_name, dom, handler, options);\n\n\tif (\n\t\tdom === document.body ||\n\t\t// @ts-ignore\n\t\tdom === window ||\n\t\t// @ts-ignore\n\t\tdom === document ||\n\t\t// Firefox has quirky behavior, it can happen that we still get \"canplay\" events when the element is already removed\n\t\tdom instanceof HTMLMediaElement\n\t) {\n\t\tteardown(() => {\n\t\t\ttarget_handler.__removed = true;\n\t\t\tdom.removeEventListener(event_name, target_handler, options);\n\t\t});\n\t}\n}\n\n/**\n * @param {string} event_name\n * @param {Element} element\n * @param {EventListener} [handler]\n * @returns {void}\n */\nexport function delegated(event_name, element, handler) {\n\t// @ts-expect-error\n\t(element[event_symbol] ??= {})[event_name] = handler;\n}\n\n/**\n * @param {Array} events\n * @returns {void}\n */\nexport function delegate(events) {\n\tfor (var i = 0; i < events.length; i++) {\n\t\tall_registered_events.add(events[i]);\n\t}\n\n\tfor (var fn of root_event_handles) {\n\t\tfn(events);\n\t}\n}\n\n// used to store the reference to the currently propagated event\n// to prevent garbage collection between microtasks in Firefox (<= 141)\n// If the event object is GCed too early, the expando __root property\n// set on the event object is lost, causing the event delegation\n// to process the event twice\nlet last_propagated_event = null;\n\n// whether a task is already queued to clear `last_propagated_event`\nlet last_propagated_event_clear_scheduled = false;\n\n/**\n * @this {EventTarget}\n * @param {Event} event\n * @returns {void}\n */\nexport function handle_event_propagation(event) {\n\tvar handler_element = this;\n\tvar owner_document = /** @type {Node} */ (handler_element).ownerDocument;\n\tvar event_name = event.type;\n\tvar path = event.composedPath?.() || [];\n\tvar current_target = /** @type {null | Element} */ (path[0] || event.target);\n\n\tlast_propagated_event = event;\n\n\t// The reference is only needed while the event can still reach another\n\t// delegated root, i.e. during the current (synchronous) dispatch and its\n\t// microtask checkpoints. Clearing it in a later task preserves the\n\t// Firefox workaround while making sure the slot doesn't retain the last\n\t// event forever — through `event.target` it would otherwise keep the\n\t// entire detached subtree of whatever the user last clicked in alive\n\t// until the next delegated event happens to arrive.\n\tif (!last_propagated_event_clear_scheduled) {\n\t\tlast_propagated_event_clear_scheduled = true;\n\t\tsetTimeout(() => {\n\t\t\tlast_propagated_event_clear_scheduled = false;\n\t\t\tlast_propagated_event = null;\n\t\t});\n\t}\n\n\t// composedPath contains list of nodes the event has propagated through.\n\t// We check `event_symbol` to skip all nodes below it in case this is a\n\t// parent of the `event_symbol` node, which indicates that there's nested\n\t// mounted apps. In this case we don't want to trigger events multiple times.\n\tvar path_idx = 0;\n\n\t// the `last_propagated_event === event` check is redundant, but\n\t// without it the variable will be DCE'd and things will\n\t// fail mysteriously in Firefox\n\t// @ts-expect-error is added below\n\tvar handled_at = last_propagated_event === event && event[event_symbol];\n\n\tif (handled_at) {\n\t\tvar at_idx = path.indexOf(handled_at);\n\t\tif (\n\t\t\tat_idx !== -1 &&\n\t\t\t(handler_element === document || handler_element === /** @type {any} */ (window))\n\t\t) {\n\t\t\t// This is the fallback document listener or a window listener, but the event was already handled\n\t\t\t// -> ignore, but set handle_at to document/window so that we're resetting the event\n\t\t\t// chain in case someone manually dispatches the same event object again.\n\t\t\t// @ts-expect-error\n\t\t\tevent[event_symbol] = handler_element;\n\t\t\treturn;\n\t\t}\n\n\t\t// We're deliberately not skipping if the index is higher, because\n\t\t// someone could create an event programmatically and emit it multiple times,\n\t\t// in which case we want to handle the whole propagation chain properly each time.\n\t\t// (this will only be a false negative if the event is dispatched multiple times and\n\t\t// the fallback document listener isn't reached in between, but that's super rare)\n\t\tvar handler_idx = path.indexOf(handler_element);\n\t\tif (handler_idx === -1) {\n\t\t\t// handle_idx can theoretically be -1 (happened in some JSDOM testing scenarios with an event listener on the window object)\n\t\t\t// so guard against that, too, and assume that everything was handled at this point.\n\t\t\treturn;\n\t\t}\n\n\t\tif (at_idx <= handler_idx) {\n\t\t\tpath_idx = at_idx;\n\t\t}\n\t}\n\n\tcurrent_target = /** @type {Element} */ (path[path_idx] || event.target);\n\t// there can only be one delegated event per element, and we either already handled the current target,\n\t// or this is the very first target in the chain which has a non-delegated listener, in which case it's safe\n\t// to handle a possible delegated event on it later (through the root delegation listener for example).\n\tif (current_target === handler_element) return;\n\n\t// Proxy currentTarget to correct target\n\tdefine_property(event, 'currentTarget', {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn current_target || owner_document;\n\t\t}\n\t});\n\n\t// This started because of Chromium issue https://chromestatus.com/feature/5128696823545856,\n\t// where removal or moving of the DOM can cause sync `blur` events to fire, which can cause logic\n\t// to run inside the current `active_reaction`, which isn't what we want at all. However, on reflection,\n\t// it's probably best that all events handled by Svelte have this behaviour, as we don't really want\n\t// an event handler to run in the context of another reaction or effect.\n\tvar previous_reaction = active_reaction;\n\tvar previous_effect = active_effect;\n\tset_active_reaction(null);\n\tset_active_effect(null);\n\n\ttry {\n\t\t/**\n\t\t * @type {unknown}\n\t\t */\n\t\tvar throw_error;\n\t\t/**\n\t\t * @type {unknown[]}\n\t\t */\n\t\tvar other_errors = [];\n\n\t\twhile (current_target !== null) {\n\t\t\tif (current_target === handler_element) break;\n\n\t\t\ttry {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tvar delegated = current_target[event_symbol]?.[event_name];\n\n\t\t\t\tif (\n\t\t\t\t\tdelegated != null &&\n\t\t\t\t\t(!(/** @type {any} */ (current_target).disabled) ||\n\t\t\t\t\t\t// DOM could've been updated already by the time this is reached, so we check this as well\n\t\t\t\t\t\t// -> the target could not have been disabled because it emits the event in the first place\n\t\t\t\t\t\tevent.target === current_target)\n\t\t\t\t) {\n\t\t\t\t\tdelegated.call(current_target, event);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (throw_error) {\n\t\t\t\t\tother_errors.push(error);\n\t\t\t\t} else {\n\t\t\t\t\tthrow_error = error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (event.cancelBubble) break;\n\n\t\t\tpath_idx++;\n\t\t\tcurrent_target = path_idx < path.length ? /** @type {Element} */ (path[path_idx]) : null;\n\t\t}\n\n\t\tif (throw_error) {\n\t\t\tfor (let error of other_errors) {\n\t\t\t\t// Throw the rest of the errors, one-by-one on a microtask\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow throw_error;\n\t\t}\n\t} finally {\n\t\t// @ts-expect-error is used above\n\t\tevent[event_symbol] = handler_element;\n\t\t// @ts-ignore remove proxy on currentTarget\n\t\tdelete event.currentTarget;\n\t\tset_active_reaction(previous_reaction);\n\t\tset_active_effect(previous_effect);\n\t}\n}\n\n/**\n * In dev, warn if an event handler is not a function, as it means the\n * user probably called the handler or forgot to add a `() =>`\n * @param {() => (event: Event, ...args: any) => void} thunk\n * @param {EventTarget} element\n * @param {[Event, ...any]} args\n * @param {any} component\n * @param {[number, number]} [loc]\n * @param {boolean} [remove_parens]\n */\nexport function apply(\n\tthunk,\n\telement,\n\targs,\n\tcomponent,\n\tloc,\n\thas_side_effects = false,\n\tremove_parens = false\n) {\n\tlet handler;\n\tlet error;\n\n\ttry {\n\t\thandler = thunk();\n\t} catch (e) {\n\t\terror = e;\n\t}\n\n\tif (typeof handler !== 'function' && (has_side_effects || handler != null || error)) {\n\t\tconst filename = component?.[FILENAME];\n\t\tconst location = loc ? ` at ${filename}:${loc[0]}:${loc[1]}` : ` in ${filename}`;\n\t\tconst phase = args[0]?.eventPhase < Event.BUBBLING_PHASE ? 'capture' : '';\n\t\tconst event_name = args[0]?.type + phase;\n\t\tconst description = `\\`${event_name}\\` handler${location}`;\n\t\tconst suggestion = remove_parens ? 'remove the trailing `()`' : 'add a leading `() =>`';\n\n\t\tw.event_handler_invalid(description, suggestion);\n\n\t\tif (error) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\thandler?.apply(element, args);\n}\n","import { create_element } from './operations.js';\n\nconst policy =\n\t// We gotta write it like this because after downleveling the pure comment may end up in the wrong location\n\tglobalThis?.window?.trustedTypes &&\n\t/* @__PURE__ */ globalThis.window.trustedTypes.createPolicy('svelte-trusted-html', {\n\t\t/** @param {string} html */\n\t\tcreateHTML: (html) => {\n\t\t\treturn html;\n\t\t}\n\t});\n\n/** @param {string} html */\nexport function create_trusted_html(html) {\n\treturn /** @type {string} */ (policy?.createHTML(html) ?? html);\n}\n\n/**\n * @param {string} html\n */\nexport function create_fragment_from_html(html) {\n\tvar elem = create_element('template');\n\telem.innerHTML = create_trusted_html(html.replaceAll('', '')); // XHTML compliance\n\treturn elem.content;\n}\n","/** @import { Effect, EffectNodes, TemplateNode } from '#client' */\n/** @import { TemplateStructure } from './types' */\nimport { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from './hydration.js';\nimport {\n\tcreate_text,\n\tget_first_child,\n\tget_next_sibling,\n\tis_firefox,\n\tcreate_element,\n\tcreate_fragment,\n\tcreate_comment,\n\tset_attribute,\n\tmerge_text_nodes\n} from './operations.js';\nimport { create_fragment_from_html } from './reconciler.js';\nimport { active_effect } from '../runtime.js';\nimport {\n\tNAMESPACE_MATHML,\n\tNAMESPACE_SVG,\n\tTEMPLATE_FRAGMENT,\n\tTEMPLATE_USE_IMPORT_NODE,\n\tTEMPLATE_USE_MATHML,\n\tTEMPLATE_USE_SVG\n} from '../../../constants.js';\nimport {\n\tCOMMENT_NODE,\n\tDOCUMENT_FRAGMENT_NODE,\n\tIS_XHTML,\n\tREACTION_RAN,\n\tTEXT_NODE\n} from '#client/constants';\n\nconst TEMPLATE_TAG = IS_XHTML ? 'template' : 'TEMPLATE';\nconst SCRIPT_TAG = IS_XHTML ? 'script' : 'SCRIPT';\n\n/**\n * @param {TemplateNode} start\n * @param {TemplateNode | null} end\n */\nexport function assign_nodes(start, end) {\n\tvar effect = /** @type {Effect} */ (active_effect);\n\tif (effect.nodes === null) {\n\t\teffect.nodes = { start, end, a: null, t: null };\n\t}\n}\n\n/**\n * @param {string} content\n * @param {number} flags\n * @returns {() => Node | Node[]}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function from_html(content, flags) {\n\tvar is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;\n\tvar use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0;\n\n\t/** @type {Node} */\n\tvar node;\n\n\t/**\n\t * Whether or not the first item is a text/element node. If not, we need to\n\t * create an additional comment node to act as `effect.nodes.start`\n\t */\n\tvar has_start = !content.startsWith('');\n\n\treturn () => {\n\t\tif (hydrating) {\n\t\t\tassign_nodes(hydrate_node, null);\n\t\t\treturn hydrate_node;\n\t\t}\n\n\t\tif (node === undefined) {\n\t\t\tnode = create_fragment_from_html(has_start ? content : '' + content);\n\t\t\tif (!is_fragment) node = /** @type {TemplateNode} */ (get_first_child(node));\n\t\t}\n\n\t\tvar clone = /** @type {TemplateNode} */ (\n\t\t\tuse_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true)\n\t\t);\n\n\t\tif (is_fragment) {\n\t\t\tvar start = /** @type {TemplateNode} */ (get_first_child(clone));\n\t\t\tvar end = /** @type {TemplateNode} */ (clone.lastChild);\n\n\t\t\tassign_nodes(start, end);\n\t\t} else {\n\t\t\tassign_nodes(clone, clone);\n\t\t}\n\n\t\treturn clone;\n\t};\n}\n\n/**\n * @param {string} content\n * @param {number} flags\n * @param {'svg' | 'math'} ns\n * @returns {() => Node | Node[]}\n */\n/*#__NO_SIDE_EFFECTS__*/\nfunction from_namespace(content, flags, ns = 'svg') {\n\t/**\n\t * Whether or not the first item is a text/element node. If not, we need to\n\t * create an additional comment node to act as `effect.nodes.start`\n\t */\n\tvar has_start = !content.startsWith('');\n\n\tvar is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;\n\tvar wrapped = `<${ns}>${has_start ? content : '' + content}`;\n\n\t/** @type {Element | DocumentFragment} */\n\tvar node;\n\n\treturn () => {\n\t\tif (hydrating) {\n\t\t\tassign_nodes(hydrate_node, null);\n\t\t\treturn hydrate_node;\n\t\t}\n\n\t\tif (!node) {\n\t\t\tvar fragment = /** @type {DocumentFragment} */ (create_fragment_from_html(wrapped));\n\t\t\tvar root = /** @type {Element} */ (get_first_child(fragment));\n\n\t\t\tif (is_fragment) {\n\t\t\t\tnode = document.createDocumentFragment();\n\t\t\t\twhile (get_first_child(root)) {\n\t\t\t\t\tnode.appendChild(/** @type {TemplateNode} */ (get_first_child(root)));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnode = /** @type {Element} */ (get_first_child(root));\n\t\t\t}\n\t\t}\n\n\t\tvar clone = /** @type {TemplateNode} */ (node.cloneNode(true));\n\n\t\tif (is_fragment) {\n\t\t\tvar start = /** @type {TemplateNode} */ (get_first_child(clone));\n\t\t\tvar end = /** @type {TemplateNode} */ (clone.lastChild);\n\n\t\t\tassign_nodes(start, end);\n\t\t} else {\n\t\t\tassign_nodes(clone, clone);\n\t\t}\n\n\t\treturn clone;\n\t};\n}\n\n/**\n * @param {string} content\n * @param {number} flags\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function from_svg(content, flags) {\n\treturn from_namespace(content, flags, 'svg');\n}\n\n/**\n * @param {string} content\n * @param {number} flags\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function from_mathml(content, flags) {\n\treturn from_namespace(content, flags, 'math');\n}\n\n/**\n * @param {TemplateStructure[]} structure\n * @param {typeof NAMESPACE_SVG | typeof NAMESPACE_MATHML | undefined} [ns]\n */\nfunction fragment_from_tree(structure, ns) {\n\tvar fragment = create_fragment();\n\n\tfor (var item of structure) {\n\t\tif (typeof item === 'string') {\n\t\t\tfragment.append(create_text(item));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// if `preserveComments === true`, comments are represented as `['// ']`\n\t\tif (item === undefined || item[0][0] === '/') {\n\t\t\tfragment.append(create_comment(item ? item[0].slice(3) : ''));\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst [name, attributes, ...children] = item;\n\n\t\tconst namespace = name === 'svg' ? NAMESPACE_SVG : name === 'math' ? NAMESPACE_MATHML : ns;\n\n\t\tvar element = create_element(name, namespace, attributes?.is);\n\n\t\tfor (var key in attributes) {\n\t\t\tset_attribute(element, key, attributes[key]);\n\t\t}\n\n\t\tif (children.length > 0) {\n\t\t\tvar target =\n\t\t\t\telement.nodeName === TEMPLATE_TAG\n\t\t\t\t\t? /** @type {HTMLTemplateElement} */ (element).content\n\t\t\t\t\t: element;\n\n\t\t\ttarget.append(\n\t\t\t\tfragment_from_tree(children, element.nodeName === 'foreignObject' ? undefined : namespace)\n\t\t\t);\n\t\t}\n\n\t\tfragment.append(element);\n\t}\n\n\treturn fragment;\n}\n\n/**\n * @param {TemplateStructure[]} structure\n * @param {number} flags\n * @returns {() => Node | Node[]}\n */\n/*#__NO_SIDE_EFFECTS__*/\nexport function from_tree(structure, flags) {\n\tvar is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;\n\tvar use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0;\n\n\t/** @type {Node} */\n\tvar node;\n\n\treturn () => {\n\t\tif (hydrating) {\n\t\t\tassign_nodes(hydrate_node, null);\n\t\t\treturn hydrate_node;\n\t\t}\n\n\t\tif (node === undefined) {\n\t\t\tconst ns =\n\t\t\t\t(flags & TEMPLATE_USE_SVG) !== 0\n\t\t\t\t\t? NAMESPACE_SVG\n\t\t\t\t\t: (flags & TEMPLATE_USE_MATHML) !== 0\n\t\t\t\t\t\t? NAMESPACE_MATHML\n\t\t\t\t\t\t: undefined;\n\n\t\t\tnode = fragment_from_tree(structure, ns);\n\t\t\tif (!is_fragment) node = /** @type {TemplateNode} */ (get_first_child(node));\n\t\t}\n\n\t\tvar clone = /** @type {TemplateNode} */ (\n\t\t\tuse_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true)\n\t\t);\n\n\t\tif (is_fragment) {\n\t\t\tvar start = /** @type {TemplateNode} */ (get_first_child(clone));\n\t\t\tvar end = /** @type {TemplateNode} */ (clone.lastChild);\n\n\t\t\tassign_nodes(start, end);\n\t\t} else {\n\t\t\tassign_nodes(clone, clone);\n\t\t}\n\n\t\treturn clone;\n\t};\n}\n\n/**\n * @param {() => Element | DocumentFragment} fn\n */\nexport function with_script(fn) {\n\treturn () => run_scripts(fn());\n}\n\n/**\n * Creating a document fragment from HTML that contains script tags will not execute\n * the scripts. We need to replace the script tags with new ones so that they are executed.\n * @param {Element | DocumentFragment} node\n * @returns {Node | Node[]}\n */\nfunction run_scripts(node) {\n\t// scripts were SSR'd, in which case they will run\n\tif (hydrating) return node;\n\n\tconst is_fragment = node.nodeType === DOCUMENT_FRAGMENT_NODE;\n\tconst scripts =\n\t\t/** @type {HTMLElement} */ (node).nodeName === SCRIPT_TAG\n\t\t\t? [/** @type {HTMLScriptElement} */ (node)]\n\t\t\t: node.querySelectorAll('script');\n\n\tconst effect = /** @type {Effect & { nodes: EffectNodes }} */ (active_effect);\n\n\tfor (const script of scripts) {\n\t\tconst clone = create_element('script');\n\t\tfor (var attribute of script.attributes) {\n\t\t\tclone.setAttribute(attribute.name, attribute.value);\n\t\t}\n\n\t\tclone.textContent = script.textContent;\n\n\t\t// The script has changed - if it's at the edges, the effect now points at dead nodes\n\t\tif (is_fragment ? node.firstChild === script : node === script) {\n\t\t\teffect.nodes.start = clone;\n\t\t}\n\t\tif (is_fragment ? node.lastChild === script : node === script) {\n\t\t\teffect.nodes.end = clone;\n\t\t}\n\n\t\tscript.replaceWith(clone);\n\t}\n\treturn node;\n}\n\n/**\n * Don't mark this as side-effect-free, hydration needs to walk all nodes\n * @param {any} value\n */\nexport function text(value = '') {\n\tif (!hydrating) {\n\t\tvar t = create_text(value + '');\n\t\tassign_nodes(t, t);\n\t\treturn t;\n\t}\n\n\tvar node = hydrate_node;\n\n\tif (node.nodeType !== TEXT_NODE) {\n\t\t// if an {expression} is empty during SSR, we need to insert an empty text node\n\t\tnode.before((node = create_text()));\n\t\tset_hydrate_node(node);\n\t} else {\n\t\tmerge_text_nodes(/** @type {Text} */ (node));\n\t}\n\n\tassign_nodes(node, node);\n\treturn node;\n}\n\n/**\n * @returns {TemplateNode | DocumentFragment}\n */\nexport function comment() {\n\t// we're not delegating to `template` here for performance reasons\n\tif (hydrating) {\n\t\tassign_nodes(hydrate_node, null);\n\t\treturn hydrate_node;\n\t}\n\n\tvar frag = document.createDocumentFragment();\n\tvar start = document.createComment('');\n\tvar anchor = create_text();\n\tfrag.append(start, anchor);\n\n\tassign_nodes(start, anchor);\n\n\treturn frag;\n}\n\n/**\n * Assign the created (or in hydration mode, traversed) dom elements to the current block\n * and insert the elements into the dom (in client mode).\n * @param {Text | Comment | Element} anchor\n * @param {DocumentFragment | Element} dom\n */\nexport function append(anchor, dom) {\n\tif (hydrating) {\n\t\tvar effect = /** @type {Effect & { nodes: EffectNodes }} */ (active_effect);\n\n\t\t// When hydrating and outer component and an inner component is async, i.e. blocked on a promise,\n\t\t// then by the time the inner resolves we have already advanced to the end of the hydrated nodes\n\t\t// of the parent component. Check for defined for that reason to avoid rewinding the parent's end marker.\n\t\tif ((effect.f & REACTION_RAN) === 0 || effect.nodes.end === null) {\n\t\t\teffect.nodes.end = hydrate_node;\n\t\t}\n\n\t\thydrate_next();\n\t\treturn;\n\t}\n\n\tif (anchor === null) {\n\t\t// edge case — void `` with content\n\t\treturn;\n\t}\n\n\tanchor.before(/** @type {Node} */ (dom));\n}\n\n/**\n * Create (or hydrate) an unique UID for the component instance.\n */\nexport function props_id() {\n\tif (\n\t\thydrating &&\n\t\thydrate_node &&\n\t\thydrate_node.nodeType === COMMENT_NODE &&\n\t\thydrate_node.textContent?.startsWith(`$`)\n\t) {\n\t\tconst id = hydrate_node.textContent.substring(1);\n\t\thydrate_next();\n\t\treturn id;\n\t}\n\n\t// @ts-expect-error This way we ensure the id is unique even across Svelte runtimes\n\t(window.__svelte ??= {}).uid ??= 1;\n\n\t// @ts-expect-error\n\treturn `c${window.__svelte.uid++}`;\n}\n","import { get, tick, untrack } from '../internal/client/runtime.js';\nimport { effect_tracking, render_effect } from '../internal/client/reactivity/effects.js';\nimport { source, increment } from '../internal/client/reactivity/sources.js';\nimport { tag } from '../internal/client/dev/tracing.js';\nimport { DEV } from 'esm-env';\nimport { queue_micro_task } from '../internal/client/dom/task.js';\n\n/**\n * Returns a `subscribe` function that integrates external event-based systems with Svelte's reactivity.\n * It's particularly useful for integrating with web APIs like `MediaQuery`, `IntersectionObserver`, or `WebSocket`.\n *\n * If `subscribe` is called inside an effect (including indirectly, for example inside a getter),\n * the `start` callback will be called with an `update` function. Whenever `update` is called, the effect re-runs.\n *\n * If `start` returns a cleanup function, it will be called when the effect is destroyed.\n *\n * If `subscribe` is called in multiple effects, `start` will only be called once as long as the effects\n * are active, and the returned teardown function will only be called when all effects are destroyed.\n *\n * It's best understood with an example. Here's an implementation of [`MediaQuery`](https://svelte.dev/docs/svelte/svelte-reactivity#MediaQuery):\n *\n * ```js\n * import { createSubscriber } from 'svelte/reactivity';\n * import { on } from 'svelte/events';\n *\n * export class MediaQuery {\n * \t#query;\n * \t#subscribe;\n *\n * \tconstructor(query) {\n * \t\tthis.#query = window.matchMedia(`(${query})`);\n *\n * \t\tthis.#subscribe = createSubscriber((update) => {\n * \t\t\t// when the `change` event occurs, re-run any effects that read `this.current`\n * \t\t\tconst off = on(this.#query, 'change', update);\n *\n * \t\t\t// stop listening when all the effects are destroyed\n * \t\t\treturn () => off();\n * \t\t});\n * \t}\n *\n * \tget current() {\n * \t\t// This makes the getter reactive, if read in an effect\n * \t\tthis.#subscribe();\n *\n * \t\t// Return the current state of the query, whether or not we're in an effect\n * \t\treturn this.#query.matches;\n * \t}\n * }\n * ```\n * @param {(update: () => void) => (() => void) | void} start\n * @since 5.7.0\n */\nexport function createSubscriber(start) {\n\tlet subscribers = 0;\n\tlet version = source(0);\n\t/** @type {(() => void) | void} */\n\tlet stop;\n\n\tif (DEV) {\n\t\ttag(version, 'createSubscriber version');\n\t}\n\n\treturn () => {\n\t\tif (effect_tracking()) {\n\t\t\tget(version);\n\n\t\t\trender_effect(() => {\n\t\t\t\tif (subscribers === 0) {\n\t\t\t\t\tstop = untrack(() => start(() => increment(version)));\n\t\t\t\t}\n\n\t\t\t\tsubscribers += 1;\n\n\t\t\t\treturn () => {\n\t\t\t\t\tqueue_micro_task(() => {\n\t\t\t\t\t\t// Only count down after a microtask, else we would reach 0 before our own render effect reruns,\n\t\t\t\t\t\t// but reach 1 again when the tick callback of the prior teardown runs. That would mean we\n\t\t\t\t\t\t// re-subcribe unnecessarily and create a memory leak because the old subscription is never cleaned up.\n\t\t\t\t\t\tsubscribers -= 1;\n\n\t\t\t\t\t\tif (subscribers === 0) {\n\t\t\t\t\t\t\tstop?.();\n\t\t\t\t\t\t\tstop = undefined;\n\t\t\t\t\t\t\t// Increment the version to ensure any dependent deriveds are marked dirty when the subscription is picked up again later.\n\t\t\t\t\t\t\t// If we didn't do this then the comparison of write versions would determine that the derived has a later version than\n\t\t\t\t\t\t\t// the subscriber, and it would not be re-run.\n\t\t\t\t\t\t\tincrement(version);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t};\n}\n","/** @import { Effect, Source, TemplateNode, } from '#client' */\nimport {\n\tBOUNDARY_EFFECT,\n\tDESTROYED,\n\tDESTROYING,\n\tEFFECT_PRESERVED,\n\tEFFECT_TRANSPARENT\n} from '#client/constants';\nimport {\n\tHYDRATION_ERROR,\n\tHYDRATION_START_ELSE,\n\tHYDRATION_START_FAILED\n} from '../../../../constants.js';\nimport { component_context, set_component_context } from '../../context.js';\nimport { invoke_error_boundary } from '../../error-handling.js';\nimport {\n\tblock,\n\tbranch,\n\tdestroy_effect,\n\tmove_effect,\n\tpause_effect\n} from '../../reactivity/effects.js';\nimport {\n\tactive_effect,\n\tactive_reaction,\n\tget,\n\tset_active_effect,\n\tset_active_reaction\n} from '../../runtime.js';\nimport {\n\thydrate_next,\n\thydrate_node,\n\thydrating,\n\tnext,\n\tread_hydration_instruction,\n\tskip_nodes,\n\tset_hydrate_node\n} from '../hydration.js';\nimport { queue_micro_task } from '../task.js';\nimport * as e from '../../errors.js';\nimport * as w from '../../warnings.js';\nimport { DEV } from 'esm-env';\nimport { Batch, current_batch } from '../../reactivity/batch.js';\nimport { internal_set, source } from '../../reactivity/sources.js';\nimport { tag } from '../../dev/tracing.js';\nimport { createSubscriber } from '../../../../reactivity/create-subscriber.js';\nimport { create_text } from '../operations.js';\nimport { defer_effect } from '../../reactivity/utils.js';\n\n/**\n * @typedef {{\n * \t onerror?: ((error: unknown, reset: () => void) => void) | null;\n * failed?: ((anchor: Node, error: () => unknown, reset: () => () => void) => void) | null;\n * pending?: ((anchor: Node) => void) | null;\n * }} BoundaryProps\n */\n\nvar flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;\n\n/**\n * @param {TemplateNode} node\n * @param {BoundaryProps} props\n * @param {((anchor: Node) => void)} children\n * @param {((error: unknown) => unknown) | undefined} [transform_error]\n * @returns {void}\n */\nexport function boundary(node, props, children, transform_error) {\n\tnew Boundary(node, props, children, transform_error);\n}\n\nexport class Boundary {\n\t/** @type {Boundary | null} */\n\tparent;\n\n\tis_pending = false;\n\n\t/**\n\t * API-level transformError transform function. Transforms errors before they reach the `failed` snippet.\n\t * Inherited from parent boundary, or defaults to identity.\n\t * @type {(error: unknown) => unknown}\n\t */\n\ttransform_error;\n\n\t/** @type {TemplateNode} */\n\t#anchor;\n\n\t/** @type {TemplateNode | null} */\n\t#hydrate_open = hydrating ? hydrate_node : null;\n\n\t/** @type {BoundaryProps} */\n\t#props;\n\n\t/** @type {((anchor: Node) => void)} */\n\t#children;\n\n\t/** @type {Effect} */\n\t#effect;\n\n\t/** @type {Effect | null} */\n\t#main_effect = null;\n\n\t/** @type {Effect | null} */\n\t#pending_effect = null;\n\n\t/** @type {Effect | null} */\n\t#failed_effect = null;\n\n\t/** @type {DocumentFragment | null} */\n\t#offscreen_fragment = null;\n\n\t#local_pending_count = 0;\n\t#pending_count = 0;\n\t#pending_count_update_queued = false;\n\n\t/** @type {Set} */\n\t#dirty_effects = new Set();\n\n\t/** @type {Set} */\n\t#maybe_dirty_effects = new Set();\n\n\t/**\n\t * A source containing the number of pending async deriveds/expressions.\n\t * Only created if `$effect.pending()` is used inside the boundary,\n\t * otherwise updating the source results in needless `Batch.ensure()`\n\t * calls followed by no-op flushes\n\t * @type {Source | null}\n\t */\n\t#effect_pending = null;\n\n\t#effect_pending_subscriber = createSubscriber(() => {\n\t\tthis.#effect_pending = source(this.#local_pending_count);\n\n\t\tif (DEV) {\n\t\t\ttag(this.#effect_pending, '$effect.pending()');\n\t\t}\n\n\t\treturn () => {\n\t\t\tthis.#effect_pending = null;\n\t\t};\n\t});\n\n\t/**\n\t * @param {TemplateNode} node\n\t * @param {BoundaryProps} props\n\t * @param {((anchor: Node) => void)} children\n\t * @param {((error: unknown) => unknown) | undefined} [transform_error]\n\t */\n\tconstructor(node, props, children, transform_error) {\n\t\tthis.#anchor = node;\n\t\tthis.#props = props;\n\n\t\tthis.#children = (anchor) => {\n\t\t\tvar effect = /** @type {Effect} */ (active_effect);\n\n\t\t\teffect.b = this;\n\t\t\teffect.f |= BOUNDARY_EFFECT;\n\n\t\t\tchildren(anchor);\n\t\t};\n\n\t\tthis.parent = /** @type {Effect} */ (active_effect).b;\n\n\t\t// Inherit transform_error from parent boundary, or use the provided one, or default to identity\n\t\tthis.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);\n\n\t\tthis.#effect = block(() => {\n\t\t\tif (hydrating) {\n\t\t\t\tconst comment_data = read_hydration_instruction(\n\t\t\t\t\t/** @type {TemplateNode} */ (this.#hydrate_open)\n\t\t\t\t);\n\t\t\t\thydrate_next();\n\n\t\t\t\tconst server_rendered_pending = comment_data === HYDRATION_START_ELSE;\n\t\t\t\tconst server_rendered_failed = comment_data.startsWith(HYDRATION_START_FAILED);\n\n\t\t\t\tif (server_rendered_failed) {\n\t\t\t\t\t// Server rendered the failed snippet - hydrate it.\n\t\t\t\t\t// The serialized error is embedded in the comment: \n\t\t\t\t\tconst serialized_error = JSON.parse(comment_data.slice(HYDRATION_START_FAILED.length));\n\t\t\t\t\tthis.#hydrate_failed_content(serialized_error);\n\t\t\t\t} else if (server_rendered_pending) {\n\t\t\t\t\tthis.#hydrate_pending_content();\n\t\t\t\t} else {\n\t\t\t\t\tthis.#hydrate_resolved_content();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.#render();\n\t\t\t}\n\t\t}, flags);\n\n\t\tif (hydrating) {\n\t\t\tthis.#anchor = hydrate_node;\n\t\t}\n\t}\n\n\t#hydrate_resolved_content() {\n\t\ttry {\n\t\t\tthis.#main_effect = branch(() => this.#children(this.#anchor));\n\t\t} catch (error) {\n\t\t\tthis.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * @param {unknown} error The deserialized error from the server's hydration comment\n\t */\n\t#hydrate_failed_content(error) {\n\t\tconst failed = this.#props.failed;\n\t\tconst { reset, invoke_onerror } = this.#create_reset(error);\n\n\t\t// `onerror` may mutate state, which is disallowed while hydrating\n\t\tqueue_micro_task(invoke_onerror);\n\n\t\tif (!failed) return;\n\n\t\tthis.#failed_effect = branch(() => {\n\t\t\tfailed(\n\t\t\t\tthis.#anchor,\n\t\t\t\t() => error,\n\t\t\t\t() => reset\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Creates the `reset` function for a failed boundary, along with a function\n\t * that invokes `onerror` with it (if provided)\n\t * @param {unknown} error\n\t * @returns {{ reset: () => void, invoke_onerror: () => void }}\n\t */\n\t#create_reset(error) {\n\t\tvar did_reset = false;\n\t\tvar calling_on_error = false;\n\n\t\tconst reset = () => {\n\t\t\tif (this.#is_destroyed()) return;\n\n\t\t\tif (did_reset) {\n\t\t\t\tw.svelte_boundary_reset_noop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdid_reset = true;\n\n\t\t\tif (calling_on_error) {\n\t\t\t\te.svelte_boundary_reset_onerror();\n\t\t\t}\n\n\t\t\tif (this.#failed_effect !== null) {\n\t\t\t\tpause_effect(this.#failed_effect, () => {\n\t\t\t\t\tthis.#failed_effect = null;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.#run(() => {\n\t\t\t\tthis.#render();\n\t\t\t});\n\t\t};\n\n\t\tconst invoke_onerror = () => {\n\t\t\tif (this.#is_destroyed()) return;\n\n\t\t\ttry {\n\t\t\t\tcalling_on_error = true;\n\t\t\t\tthis.#props.onerror?.(error, reset);\n\t\t\t\tcalling_on_error = false;\n\t\t\t} catch (err) {\n\t\t\t\tinvoke_error_boundary(err, this.#effect && this.#effect.parent);\n\t\t\t}\n\t\t};\n\n\t\treturn { reset, invoke_onerror };\n\t}\n\n\t#is_destroyed() {\n\t\treturn (this.#effect.f & (DESTROYED | DESTROYING)) !== 0;\n\t}\n\n\t#hydrate_pending_content() {\n\t\tconst pending = this.#props.pending;\n\t\tif (!pending) return;\n\n\t\tthis.is_pending = true;\n\t\tthis.#pending_effect = branch(() => pending(this.#anchor));\n\n\t\tqueue_micro_task(() => {\n\t\t\tif (this.#is_destroyed()) return;\n\n\t\t\tvar fragment = (this.#offscreen_fragment = document.createDocumentFragment());\n\t\t\tvar anchor = create_text();\n\t\t\tvar handled = false;\n\n\t\t\tfragment.append(anchor);\n\n\t\t\tthis.#main_effect = this.#run(() => {\n\t\t\t\ttry {\n\t\t\t\t\treturn branch(() => this.#children(anchor));\n\t\t\t\t} catch (error) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.error(error);\n\t\t\t\t\t\thandled = true;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tinvoke_error_boundary(error, this.#effect.parent);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (this.#main_effect === null) {\n\t\t\t\tthis.#offscreen_fragment = null;\n\t\t\t\tif (handled) this.#resolve(/** @type {Batch} */ (current_batch));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.#pending_count === 0) {\n\t\t\t\tthis.#anchor.before(fragment);\n\t\t\t\tthis.#offscreen_fragment = null;\n\n\t\t\t\tpause_effect(/** @type {Effect} */ (this.#pending_effect), () => {\n\t\t\t\t\tthis.#pending_effect = null;\n\t\t\t\t});\n\n\t\t\t\tthis.#resolve(/** @type {Batch} */ (current_batch));\n\t\t\t}\n\t\t});\n\t}\n\n\t#render() {\n\t\ttry {\n\t\t\tthis.is_pending = this.has_pending_snippet();\n\t\t\tthis.#pending_count = 0;\n\t\t\tthis.#local_pending_count = 0;\n\n\t\t\tthis.#main_effect = branch(() => {\n\t\t\t\tthis.#children(this.#anchor);\n\t\t\t});\n\n\t\t\tif (this.#pending_count > 0) {\n\t\t\t\tvar fragment = (this.#offscreen_fragment = document.createDocumentFragment());\n\t\t\t\tmove_effect(this.#main_effect, fragment);\n\n\t\t\t\tconst pending = /** @type {(anchor: Node) => void} */ (this.#props.pending);\n\t\t\t\tthis.#pending_effect = branch(() => pending(this.#anchor));\n\t\t\t} else {\n\t\t\t\tthis.#resolve(/** @type {Batch} */ (current_batch));\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * @param {Batch} batch\n\t */\n\t#resolve(batch) {\n\t\tthis.is_pending = false;\n\n\t\t// any effects that were previously deferred should be transferred\n\t\t// to the batch, which will flush in the next microtask\n\t\tbatch.transfer_effects(this.#dirty_effects, this.#maybe_dirty_effects);\n\t}\n\n\t/**\n\t * Defer an effect inside a pending boundary until the boundary resolves\n\t * @param {Effect} effect\n\t */\n\tdefer_effect(effect) {\n\t\tdefer_effect(effect, this.#dirty_effects, this.#maybe_dirty_effects);\n\t}\n\n\t/**\n\t * Returns `false` if the effect exists inside a boundary whose pending snippet is shown\n\t * @returns {boolean}\n\t */\n\tis_rendered() {\n\t\treturn !this.is_pending && (!this.parent || this.parent.is_rendered());\n\t}\n\n\thas_pending_snippet() {\n\t\treturn !!this.#props.pending;\n\t}\n\n\t/**\n\t * @template T\n\t * @param {() => T} fn\n\t */\n\t#run(fn) {\n\t\tvar previous_effect = active_effect;\n\t\tvar previous_reaction = active_reaction;\n\t\tvar previous_ctx = component_context;\n\n\t\tset_active_effect(this.#effect);\n\t\tset_active_reaction(this.#effect);\n\t\tset_component_context(this.#effect.ctx);\n\n\t\ttry {\n\t\t\tBatch.ensure();\n\t\t\treturn fn();\n\t\t} finally {\n\t\t\tset_active_effect(previous_effect);\n\t\t\tset_active_reaction(previous_reaction);\n\t\t\tset_component_context(previous_ctx);\n\t\t}\n\t}\n\n\t/**\n\t * Updates the pending count associated with the currently visible pending snippet,\n\t * if any, such that we can replace the snippet with content once work is done\n\t * @param {1 | -1} d\n\t * @param {Batch} batch\n\t */\n\t#update_pending_count(d, batch) {\n\t\tif (!this.has_pending_snippet()) {\n\t\t\tif (this.parent) {\n\t\t\t\tthis.parent.#update_pending_count(d, batch);\n\t\t\t}\n\n\t\t\t// if there's no parent, we're in a scope with no pending snippet\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#pending_count += d;\n\n\t\tif (this.#pending_count === 0) {\n\t\t\tthis.#resolve(batch);\n\n\t\t\tif (this.#pending_effect) {\n\t\t\t\tpause_effect(this.#pending_effect, () => {\n\t\t\t\t\tthis.#pending_effect = null;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (this.#offscreen_fragment) {\n\t\t\t\tthis.#anchor.before(this.#offscreen_fragment);\n\t\t\t\tthis.#offscreen_fragment = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update the source that powers `$effect.pending()` inside this boundary,\n\t * and controls when the current `pending` snippet (if any) is removed.\n\t * Do not call from inside the class\n\t * @param {1 | -1} d\n\t * @param {Batch} batch\n\t */\n\tupdate_pending_count(d, batch) {\n\t\tthis.#update_pending_count(d, batch);\n\n\t\tthis.#local_pending_count += d;\n\n\t\tif (!this.#effect_pending || this.#pending_count_update_queued) return;\n\t\tthis.#pending_count_update_queued = true;\n\n\t\tqueue_micro_task(() => {\n\t\t\tthis.#pending_count_update_queued = false;\n\t\t\tif (this.#effect_pending) {\n\t\t\t\tinternal_set(this.#effect_pending, this.#local_pending_count);\n\t\t\t}\n\t\t});\n\t}\n\n\tget_effect_pending() {\n\t\tthis.#effect_pending_subscriber();\n\t\treturn get(/** @type {Source} */ (this.#effect_pending));\n\t}\n\n\t/** @param {unknown} error */\n\terror(error) {\n\t\tif (error === HYDRATION_ERROR) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// If we have nothing to capture the error, or if we hit an error while\n\t\t// rendering the fallback, re-throw for another boundary to handle\n\t\tif (!this.#props.onerror && !this.#props.failed) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (current_batch?.is_fork) {\n\t\t\tif (this.#main_effect) current_batch.skip_effect(this.#main_effect);\n\t\t\tif (this.#pending_effect) current_batch.skip_effect(this.#pending_effect);\n\t\t\tif (this.#failed_effect) current_batch.skip_effect(this.#failed_effect);\n\n\t\t\tcurrent_batch.oncommit(() => {\n\t\t\t\tif (!this.#is_destroyed()) this.#handle_error(error);\n\t\t\t});\n\t\t} else {\n\t\t\tthis.#handle_error(error);\n\t\t}\n\t}\n\n\t/**\n\t * @param {unknown} error\n\t */\n\t#handle_error(error) {\n\t\tif (this.#main_effect) {\n\t\t\tdestroy_effect(this.#main_effect);\n\t\t\tthis.#main_effect = null;\n\t\t}\n\n\t\tif (this.#pending_effect) {\n\t\t\tdestroy_effect(this.#pending_effect);\n\t\t\tthis.#pending_effect = null;\n\t\t}\n\n\t\tif (this.#failed_effect) {\n\t\t\tdestroy_effect(this.#failed_effect);\n\t\t\tthis.#failed_effect = null;\n\t\t}\n\n\t\tif (hydrating) {\n\t\t\tset_hydrate_node(/** @type {TemplateNode} */ (this.#hydrate_open));\n\t\t\tnext();\n\t\t\tset_hydrate_node(skip_nodes());\n\t\t}\n\n\t\tlet failed = this.#props.failed;\n\n\t\t/** @param {unknown} transformed_error */\n\t\tconst handle_error_result = (transformed_error) => {\n\t\t\tif (this.#is_destroyed()) return;\n\n\t\t\tconst { reset, invoke_onerror } = this.#create_reset(transformed_error);\n\n\t\t\tinvoke_onerror();\n\n\t\t\tif (failed && !this.#is_destroyed()) {\n\t\t\t\tthis.#failed_effect = this.#run(() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn branch(() => {\n\t\t\t\t\t\t\t// errors in `failed` snippets cause the boundary to error again\n\t\t\t\t\t\t\t// TODO Svelte 6: revisit this decision, most likely better to go to parent boundary instead\n\t\t\t\t\t\t\tvar effect = /** @type {Effect} */ (active_effect);\n\n\t\t\t\t\t\t\teffect.b = this;\n\t\t\t\t\t\t\teffect.f |= BOUNDARY_EFFECT;\n\n\t\t\t\t\t\t\tfailed(\n\t\t\t\t\t\t\t\tthis.#anchor,\n\t\t\t\t\t\t\t\t() => transformed_error,\n\t\t\t\t\t\t\t\t() => reset\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tinvoke_error_boundary(error, /** @type {Effect} */ (this.#effect.parent));\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tqueue_micro_task(() => {\n\t\t\tif (this.#is_destroyed()) return;\n\n\t\t\t// Run the error through the API-level transformError transform (e.g. SvelteKit's handleError)\n\t\t\t/** @type {unknown} */\n\t\t\tvar result;\n\t\t\ttry {\n\t\t\t\tresult = this.transform_error(error);\n\t\t\t} catch (e) {\n\t\t\t\tinvoke_error_boundary(e, this.#effect && this.#effect.parent);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tresult !== null &&\n\t\t\t\ttypeof result === 'object' &&\n\t\t\t\ttypeof (/** @type {any} */ (result).then) === 'function'\n\t\t\t) {\n\t\t\t\t// transformError returned a Promise — wait for it\n\t\t\t\t/** @type {any} */ (result).then(\n\t\t\t\t\thandle_error_result,\n\t\t\t\t\t/** @param {unknown} e */\n\t\t\t\t\t(e) => invoke_error_boundary(e, this.#effect && this.#effect.parent)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Synchronous result — handle immediately\n\t\t\t\thandle_error_result(result);\n\t\t\t}\n\t\t});\n\t}\n}\n\nexport function pending() {\n\tif (active_effect === null) {\n\t\te.effect_pending_outside_reaction();\n\t}\n\n\tvar boundary = active_effect.b;\n\n\tif (boundary === null) {\n\t\treturn 0; // TODO eventually we will need this to be global\n\t}\n\n\treturn boundary.get_effect_pending();\n}\n","/** @import { ComponentContext, Effect, EffectNodes, TemplateNode } from '#client' */\n/** @import { Component, ComponentType, SvelteComponent, MountOptions } from '../../index.js' */\nimport { DEV } from 'esm-env';\nimport {\n\tclear_text_content,\n\tcreate_text,\n\tget_first_child,\n\tget_next_sibling,\n\tinit_operations\n} from './dom/operations.js';\nimport { HYDRATION_END, HYDRATION_ERROR, HYDRATION_START } from '../../constants.js';\nimport { active_effect } from './runtime.js';\nimport { push, pop, component_context, mark_as_component } from './context.js';\nimport { component_root } from './reactivity/effects.js';\nimport { hydrate_node, hydrating, set_hydrate_node, set_hydrating } from './dom/hydration.js';\nimport { array_from } from '../shared/utils.js';\nimport {\n\tall_registered_events,\n\thandle_event_propagation,\n\troot_event_handles\n} from './dom/elements/events.js';\nimport * as w from './warnings.js';\nimport * as e from './errors.js';\nimport { assign_nodes } from './dom/template.js';\nimport { is_passive_event } from '../../utils.js';\nimport { COMMENT_NODE, TEXT_CACHE } from './constants.js';\nimport { boundary } from './dom/blocks/boundary.js';\n\n/**\n * This is normally true — block effects should run their intro transitions —\n * but is false during hydration (unless `options.intro` is `true`) and\n * when creating the children of a `` that just changed tag\n */\nexport let should_intro = true;\n\n/** @param {boolean} value */\nexport function set_should_intro(value) {\n\tshould_intro = value;\n}\n\n/**\n * @param {Element} text\n * @param {string} value\n * @returns {void}\n */\nexport function set_text(text, value) {\n\t// For objects, we apply string coercion (which might make things like $state array references in the template reactive) before diffing\n\tvar str = value == null ? '' : typeof value === 'object' ? `${value}` : value;\n\t// prettier-ignore\n\tif (str !== (/** @type {any} */ (text)[TEXT_CACHE] ??= text.nodeValue)) {\n\t\t/** @type {any} */ (text)[TEXT_CACHE] = str;\n\t\ttext.nodeValue = `${str}`;\n\t}\n}\n\n/**\n * Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component.\n * Transitions will play during the initial render unless the `intro` option is set to `false`.\n *\n * @template {Record} Props\n * @template {Record} Exports\n * @param {ComponentType> | Component} component\n * @param {MountOptions} options\n * @returns {Exports}\n */\nexport function mount(component, options) {\n\treturn _mount(component, options);\n}\n\n/**\n * Hydrates a component on the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component\n *\n * @template {Record} Props\n * @template {Record} Exports\n * @param {ComponentType> | Component} component\n * @param {{} extends Props ? {\n * \t\ttarget: Document | Element | ShadowRoot;\n * \t\tprops?: Props;\n * \t\tevents?: Record any>;\n * \tcontext?: Map;\n * \t\tintro?: boolean;\n * \t\trecover?: boolean;\n *\t\ttransformError?: (error: unknown) => unknown;\n * \t} : {\n * \t\ttarget: Document | Element | ShadowRoot;\n * \t\tprops: Props;\n * \t\tevents?: Record any>;\n * \tcontext?: Map;\n * \t\tintro?: boolean;\n * \t\trecover?: boolean;\n *\t\ttransformError?: (error: unknown) => unknown;\n * \t}} options\n * @returns {Exports}\n */\nexport function hydrate(component, options) {\n\tinit_operations();\n\toptions.intro = options.intro ?? false;\n\tconst target = options.target;\n\tconst was_hydrating = hydrating;\n\tconst previous_hydrate_node = hydrate_node;\n\n\ttry {\n\t\tvar anchor = get_first_child(target);\n\n\t\twhile (\n\t\t\tanchor &&\n\t\t\t(anchor.nodeType !== COMMENT_NODE || /** @type {Comment} */ (anchor).data !== HYDRATION_START)\n\t\t) {\n\t\t\tanchor = get_next_sibling(anchor);\n\t\t}\n\n\t\tif (!anchor) {\n\t\t\tthrow HYDRATION_ERROR;\n\t\t}\n\n\t\tset_hydrating(true);\n\t\tset_hydrate_node(/** @type {Comment} */ (anchor));\n\n\t\tconst instance = _mount(component, { ...options, anchor });\n\n\t\tset_hydrating(false);\n\n\t\treturn /** @type {Exports} */ (instance);\n\t} catch (error) {\n\t\t// re-throw Svelte errors - they are certainly not related to hydration\n\t\tif (\n\t\t\terror instanceof Error &&\n\t\t\terror.message.split('\\n').some((line) => line.startsWith('https://svelte.dev/e/'))\n\t\t) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error !== HYDRATION_ERROR) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn('Failed to hydrate: ', error);\n\t\t}\n\n\t\tif (options.recover === false) {\n\t\t\te.hydration_failed();\n\t\t}\n\n\t\t// If an error occurred above, the operations might not yet have been initialised.\n\t\tinit_operations();\n\t\tclear_text_content(target);\n\n\t\tset_hydrating(false);\n\t\treturn mount(component, options);\n\t} finally {\n\t\tset_hydrating(was_hydrating);\n\t\tset_hydrate_node(previous_hydrate_node);\n\t}\n}\n\n/** @type {Map>} */\nconst listeners = new Map();\n\n/**\n * @template {Record} Exports\n * @param {ComponentType> | Component} Component\n * @param {MountOptions} options\n * @returns {Exports}\n */\nfunction _mount(\n\tComponent,\n\t{ target, anchor, props = {}, events, context, intro = true, transformError }\n) {\n\tinit_operations();\n\n\t/** @type {Exports} */\n\t// @ts-expect-error will be defined because the render effect runs synchronously\n\tvar component = undefined;\n\n\tvar unmount = component_root(() => {\n\t\tvar anchor_node = anchor ?? target.appendChild(create_text());\n\n\t\tboundary(\n\t\t\t/** @type {TemplateNode} */ (anchor_node),\n\t\t\t{\n\t\t\t\tpending: () => {}\n\t\t\t},\n\t\t\t(anchor_node) => {\n\t\t\t\tpush({});\n\t\t\t\tvar ctx = /** @type {ComponentContext} */ (component_context);\n\t\t\t\tif (context) ctx.c = context;\n\n\t\t\t\tif (events) {\n\t\t\t\t\t// We can't spread the object or else we'd lose the state proxy stuff, if it is one\n\t\t\t\t\t/** @type {any} */ (props).$$events = events;\n\t\t\t\t}\n\n\t\t\t\tif (hydrating) {\n\t\t\t\t\tassign_nodes(/** @type {TemplateNode} */ (anchor_node), null);\n\t\t\t\t}\n\n\t\t\t\tshould_intro = intro;\n\t\t\t\t// @ts-expect-error the public typings are not what the actual function looks like\n\t\t\t\tcomponent = Component(anchor_node, props) || mark_as_component();\n\t\t\t\tshould_intro = true;\n\n\t\t\t\tif (hydrating) {\n\t\t\t\t\t/** @type {Effect & { nodes: EffectNodes }} */ (active_effect).nodes.end = hydrate_node;\n\n\t\t\t\t\tif (\n\t\t\t\t\t\thydrate_node === null ||\n\t\t\t\t\t\thydrate_node.nodeType !== COMMENT_NODE ||\n\t\t\t\t\t\t/** @type {Comment} */ (hydrate_node).data !== HYDRATION_END\n\t\t\t\t\t) {\n\t\t\t\t\t\tw.hydration_mismatch();\n\t\t\t\t\t\tthrow HYDRATION_ERROR;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpop();\n\t\t\t},\n\t\t\ttransformError\n\t\t);\n\n\t\t// Setup event delegation _after_ component is mounted - if an error would happen during mount, it would otherwise not be cleaned up\n\t\t/** @type {Set} */\n\t\tvar registered_events = new Set();\n\n\t\t/** @param {Array} events */\n\t\tvar event_handle = (events) => {\n\t\t\tfor (var i = 0; i < events.length; i++) {\n\t\t\t\tvar event_name = events[i];\n\n\t\t\t\tif (registered_events.has(event_name)) continue;\n\t\t\t\tregistered_events.add(event_name);\n\n\t\t\t\tvar passive = is_passive_event(event_name);\n\n\t\t\t\t// Add the event listener to both the container and the document.\n\t\t\t\t// The container listener ensures we catch events from within in case\n\t\t\t\t// the outer content stops propagation of the event.\n\t\t\t\t//\n\t\t\t\t// The document listener ensures we catch events that originate from elements that were\n\t\t\t\t// manually moved outside of the container (e.g. via manual portals).\n\t\t\t\tfor (const node of [target, document]) {\n\t\t\t\t\tvar counts = listeners.get(node);\n\n\t\t\t\t\tif (counts === undefined) {\n\t\t\t\t\t\tcounts = new Map();\n\t\t\t\t\t\tlisteners.set(node, counts);\n\t\t\t\t\t}\n\n\t\t\t\t\tvar count = counts.get(event_name);\n\n\t\t\t\t\tif (count === undefined) {\n\t\t\t\t\t\tnode.addEventListener(event_name, handle_event_propagation, { passive });\n\t\t\t\t\t\tcounts.set(event_name, 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcounts.set(event_name, count + 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tevent_handle(array_from(all_registered_events));\n\t\troot_event_handles.add(event_handle);\n\n\t\treturn () => {\n\t\t\tfor (var event_name of registered_events) {\n\t\t\t\tfor (const node of [target, document]) {\n\t\t\t\t\tvar counts = /** @type {Map} */ (listeners.get(node));\n\t\t\t\t\tvar count = /** @type {number} */ (counts.get(event_name));\n\n\t\t\t\t\tif (--count == 0) {\n\t\t\t\t\t\tnode.removeEventListener(event_name, handle_event_propagation);\n\t\t\t\t\t\tcounts.delete(event_name);\n\n\t\t\t\t\t\tif (counts.size === 0) {\n\t\t\t\t\t\t\tlisteners.delete(node);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcounts.set(event_name, count);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\troot_event_handles.delete(event_handle);\n\n\t\t\tif (anchor_node !== anchor) {\n\t\t\t\tanchor_node.parentNode?.removeChild(anchor_node);\n\t\t\t}\n\t\t};\n\t});\n\n\tmounted_components.set(component, unmount);\n\treturn component;\n}\n\n/**\n * References of the components that were mounted or hydrated.\n * Uses a `WeakMap` to avoid memory leaks.\n */\nlet mounted_components = new WeakMap();\n\n/**\n * Unmounts a component that was previously mounted using `mount` or `hydrate`.\n *\n * Since 5.13.0, if `options.outro` is `true`, [transitions](https://svelte.dev/docs/svelte/transition) will play before the component is removed from the DOM.\n *\n * Returns a `Promise` that resolves after transitions have completed if `options.outro` is true, or immediately otherwise (prior to 5.13.0, returns `void`).\n *\n * ```js\n * import { mount, unmount } from 'svelte';\n * import App from './App.svelte';\n *\n * const app = mount(App, { target: document.body });\n *\n * // later...\n * unmount(app, { outro: true });\n * ```\n * @param {Record} component\n * @param {{ outro?: boolean }} [options]\n * @returns {Promise}\n */\nexport function unmount(component, options) {\n\tconst fn = mounted_components.get(component);\n\n\tif (fn) {\n\t\tmounted_components.delete(component);\n\t\treturn fn(options);\n\t}\n\n\tif (DEV) {\n\t\tw.lifecycle_double_unmount();\n\t}\n\n\treturn Promise.resolve();\n}\n","/** @import { Effect, TemplateNode } from '#client' */\nimport { Batch, current_batch } from '../../reactivity/batch.js';\nimport {\n\tbranch,\n\tdestroy_effect,\n\tmove_effect,\n\tpause_effect,\n\tresume_effect\n} from '../../reactivity/effects.js';\nimport { HMR_ANCHOR } from '../../constants.js';\nimport { hydrate_node, hydrating } from '../hydration.js';\nimport { create_text, should_defer_append } from '../operations.js';\nimport { DEV } from 'esm-env';\n\n/**\n * @typedef {{ effect: Effect, fragment: DocumentFragment }} Branch\n */\n\n/**\n * @template Key\n */\nexport class BranchManager {\n\t/** @type {TemplateNode} */\n\tanchor;\n\n\t/** @type {Map} */\n\t#batches = new Map();\n\n\t/**\n\t * Map of keys to effects that are currently rendered in the DOM.\n\t * These effects are visible and actively part of the document tree.\n\t * Example:\n\t * ```\n\t * {#if condition}\n\t * \tfoo\n\t * {:else}\n\t * \tbar\n\t * {/if}\n\t * ```\n\t * Can result in the entries `true->Effect` and `false->Effect`\n\t * @type {Map}\n\t */\n\t#onscreen = new Map();\n\n\t/**\n\t * Similar to #onscreen with respect to the keys, but contains branches that are not yet\n\t * in the DOM, because their insertion is deferred.\n\t * @type {Map}\n\t */\n\t#offscreen = new Map();\n\n\t/**\n\t * Keys of effects that are currently outroing\n\t * @type {Set}\n\t */\n\t#outroing = new Set();\n\n\t/**\n\t * Whether to pause (i.e. outro) on change, or destroy immediately.\n\t * This is necessary for ``\n\t */\n\t#transition = true;\n\n\t/**\n\t * @param {TemplateNode} anchor\n\t * @param {boolean} transition\n\t */\n\tconstructor(anchor, transition = true) {\n\t\tthis.anchor = anchor;\n\t\tthis.#transition = transition;\n\t}\n\n\t/**\n\t * @param {Batch} batch\n\t */\n\t#commit = (batch) => {\n\t\t// if this batch was made obsolete, bail\n\t\tif (!this.#batches.has(batch)) return;\n\n\t\tvar key = /** @type {Key} */ (this.#batches.get(batch));\n\n\t\tvar onscreen = this.#onscreen.get(key);\n\n\t\tif (onscreen) {\n\t\t\t// effect is already in the DOM — abort any current outro\n\t\t\tresume_effect(onscreen);\n\t\t\tthis.#outroing.delete(key);\n\t\t} else {\n\t\t\t// effect is currently offscreen. put it in the DOM\n\t\t\tvar offscreen = this.#offscreen.get(key);\n\n\t\t\tif (offscreen) {\n\t\t\t\t// effect could have been outro'ed before through a prior batch — resume if necessary\n\t\t\t\tresume_effect(offscreen.effect);\n\t\t\t\tthis.#onscreen.set(key, offscreen.effect);\n\t\t\t\tthis.#offscreen.delete(key);\n\n\t\t\t\tif (DEV) {\n\t\t\t\t\t// Tell hmr.js about the anchor it should use for updates,\n\t\t\t\t\t// since the initial one will be removed\n\t\t\t\t\t/** @type {any} */ (offscreen.fragment.lastChild)[HMR_ANCHOR] = this.anchor;\n\t\t\t\t}\n\n\t\t\t\t// remove the anchor...\n\t\t\t\t/** @type {TemplateNode} */ (offscreen.fragment.lastChild).remove();\n\n\t\t\t\t// ...and append the fragment\n\t\t\t\tthis.anchor.before(offscreen.fragment);\n\t\t\t\tonscreen = offscreen.effect;\n\t\t\t}\n\t\t}\n\n\t\tfor (const [b, k] of this.#batches) {\n\t\t\tthis.#batches.delete(b);\n\n\t\t\tif (b === batch) {\n\t\t\t\t// keep values for newer batches\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst offscreen = this.#offscreen.get(k);\n\n\t\t\tif (offscreen) {\n\t\t\t\t// for older batches, destroy offscreen effects\n\t\t\t\t// as they will never be committed\n\t\t\t\tdestroy_effect(offscreen.effect);\n\t\t\t\tthis.#offscreen.delete(k);\n\t\t\t}\n\t\t}\n\n\t\t// outro/destroy all onscreen effects...\n\t\tfor (const [k, effect] of this.#onscreen) {\n\t\t\t// ...except the one that was just committed\n\t\t\t// or those that are already outroing (else the transition is aborted and the effect destroyed right away)\n\t\t\tif (k === key || this.#outroing.has(k)) continue;\n\n\t\t\tconst on_destroy = () => {\n\t\t\t\tconst keys = Array.from(this.#batches.values());\n\n\t\t\t\tif (keys.includes(k)) {\n\t\t\t\t\t// keep the effect offscreen, as another batch will need it\n\t\t\t\t\tvar fragment = document.createDocumentFragment();\n\t\t\t\t\tmove_effect(effect, fragment);\n\n\t\t\t\t\tfragment.append(create_text()); // TODO can we avoid this?\n\n\t\t\t\t\tthis.#offscreen.set(k, { effect, fragment });\n\t\t\t\t} else {\n\t\t\t\t\tdestroy_effect(effect);\n\t\t\t\t}\n\n\t\t\t\tthis.#outroing.delete(k);\n\t\t\t\tthis.#onscreen.delete(k);\n\t\t\t};\n\n\t\t\tif (this.#transition || !onscreen) {\n\t\t\t\tthis.#outroing.add(k);\n\t\t\t\tpause_effect(effect, on_destroy, false);\n\t\t\t} else {\n\t\t\t\ton_destroy();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * @param {Batch} batch\n\t */\n\t#discard = (batch) => {\n\t\tthis.#batches.delete(batch);\n\n\t\tconst keys = Array.from(this.#batches.values());\n\n\t\tfor (const [k, branch] of this.#offscreen) {\n\t\t\tif (!keys.includes(k)) {\n\t\t\t\tdestroy_effect(branch.effect);\n\t\t\t\tthis.#offscreen.delete(k);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t *\n\t * @param {any} key\n\t * @param {null | ((target: TemplateNode) => void)} fn\n\t */\n\tensure(key, fn) {\n\t\tvar batch = /** @type {Batch} */ (current_batch);\n\t\tvar defer = should_defer_append();\n\n\t\tif (fn && !this.#onscreen.has(key) && !this.#offscreen.has(key)) {\n\t\t\tif (defer) {\n\t\t\t\tvar fragment = document.createDocumentFragment();\n\t\t\t\tvar target = create_text();\n\n\t\t\t\tfragment.append(target);\n\n\t\t\t\tthis.#offscreen.set(key, {\n\t\t\t\t\teffect: branch(() => fn(target)),\n\t\t\t\t\tfragment\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.#onscreen.set(\n\t\t\t\t\tkey,\n\t\t\t\t\tbranch(() => fn(this.anchor))\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.#batches.set(batch, key);\n\n\t\tif (defer) {\n\t\t\tfor (const [k, effect] of this.#onscreen) {\n\t\t\t\tif (k === key) {\n\t\t\t\t\tbatch.unskip_effect(effect);\n\t\t\t\t} else {\n\t\t\t\t\tbatch.skip_effect(effect);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const [k, branch] of this.#offscreen) {\n\t\t\t\tif (k === key) {\n\t\t\t\t\tbatch.unskip_effect(branch.effect);\n\t\t\t\t} else {\n\t\t\t\t\tbatch.skip_effect(branch.effect);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbatch.oncommit(this.#commit);\n\t\t\tbatch.ondiscard(this.#discard);\n\t\t} else {\n\t\t\tif (hydrating) {\n\t\t\t\tthis.anchor = hydrate_node;\n\t\t\t}\n\n\t\t\tthis.#commit(batch);\n\t\t}\n\t}\n}\n","/** @import { TemplateNode } from '#client' */\nimport { EFFECT_TRANSPARENT } from '#client/constants';\nimport {\n\thydrate_next,\n\thydrating,\n\tread_hydration_instruction,\n\tskip_nodes,\n\tset_hydrate_node,\n\tset_hydrating,\n\thydrate_node\n} from '../hydration.js';\nimport { block } from '../../reactivity/effects.js';\nimport { BranchManager } from './branches.js';\n\n/**\n * @param {TemplateNode} node\n * @param {(branch: (fn: (anchor: Node) => void, key?: number | false) => void) => void} fn\n * @param {boolean} [elseif] True if this is an `{:else if ...}` block rather than an `{#if ...}`, as that affects which transitions are considered 'local'\n * @returns {void}\n */\nexport function if_block(node, fn, elseif = false) {\n\t/** @type {TemplateNode | undefined} */\n\tvar marker;\n\tif (hydrating) {\n\t\tmarker = hydrate_node;\n\t\thydrate_next();\n\t}\n\n\tvar branches = new BranchManager(node);\n\tvar flags = elseif ? EFFECT_TRANSPARENT : 0;\n\n\t/**\n\t * @param {number | false} key\n\t * @param {null | ((anchor: Node) => void)} fn\n\t */\n\tfunction update_branch(key, fn) {\n\t\tif (hydrating) {\n\t\t\tvar data = read_hydration_instruction(/** @type {TemplateNode} */ (marker));\n\n\t\t\t// \"[n\" = branch n, \"[-1\" = else\n\t\t\tif (key !== parseInt(data.substring(1))) {\n\t\t\t\t// Hydration mismatch: remove everything inside the anchor and start fresh.\n\t\t\t\t// This could happen with `{#if browser}...{/if}`, for example\n\t\t\t\tvar anchor = skip_nodes();\n\n\t\t\t\tset_hydrate_node(anchor);\n\t\t\t\tbranches.anchor = anchor;\n\n\t\t\t\tset_hydrating(false);\n\t\t\t\tbranches.ensure(key, fn);\n\t\t\t\tset_hydrating(true);\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tbranches.ensure(key, fn);\n\t}\n\n\tblock(() => {\n\t\tvar has_branch = false;\n\n\t\tfn((fn, key = 0) => {\n\t\t\thas_branch = true;\n\t\t\tupdate_branch(key, fn);\n\t\t});\n\n\t\tif (!has_branch) {\n\t\t\tupdate_branch(-1, null);\n\t\t}\n\t}, flags);\n}\n","/** @import { TemplateNode } from '#client' */\nimport { is_runes } from '../../context.js';\nimport { block } from '../../reactivity/effects.js';\nimport { hydrate_next, hydrating } from '../hydration.js';\nimport { BranchManager } from './branches.js';\n\nconst NAN = Symbol('NaN');\n\n/**\n * @template V\n * @param {TemplateNode} node\n * @param {() => V} get_key\n * @param {(anchor: Node) => TemplateNode | void} render_fn\n * @returns {void}\n */\nexport function key(node, get_key, render_fn) {\n\tif (hydrating) {\n\t\thydrate_next();\n\t}\n\n\tvar branches = new BranchManager(node);\n\n\tvar legacy = !is_runes();\n\n\tblock(() => {\n\t\tvar key = get_key();\n\n\t\t// NaN !== NaN, hence we do this workaround to not trigger remounts unnecessarily\n\t\tif (key !== key) {\n\t\t\tkey = /** @type {any} */ (NAN);\n\t\t}\n\n\t\t// key blocks in Svelte <5 had stupid semantics\n\t\tif (legacy && key !== null && typeof key === 'object') {\n\t\t\tkey = /** @type {V} */ ({});\n\t\t}\n\n\t\tbranches.ensure(key, render_fn);\n\t});\n}\n","/** @import { EachItem, EachOutroGroup, EachState, Effect, EffectNodes, MaybeSource, TemplateNode, TransitionManager } from '#client' */\n/** @import { Batch } from '../../reactivity/batch.js'; */\nimport {\n\tEACH_INDEX_REACTIVE,\n\tEACH_IS_ANIMATED,\n\tEACH_IS_CONTROLLED,\n\tEACH_ITEM_IMMUTABLE,\n\tEACH_ITEM_REACTIVE,\n\tHYDRATION_END,\n\tHYDRATION_START_ELSE\n} from '../../../../constants.js';\nimport {\n\thydrate_next,\n\thydrate_node,\n\thydrating,\n\tread_hydration_instruction,\n\tskip_nodes,\n\tset_hydrate_node,\n\tset_hydrating\n} from '../hydration.js';\nimport {\n\tclear_text_content,\n\tcreate_text,\n\tget_first_child,\n\tget_next_sibling,\n\tshould_defer_append\n} from '../operations.js';\nimport {\n\tblock,\n\tbranch,\n\tdestroy_effect,\n\tmove_effect,\n\tpause_effect,\n\tresume_effect\n} from '../../reactivity/effects.js';\nimport { source, mutable_source, internal_set } from '../../reactivity/sources.js';\nimport { array_from, is_array } from '../../../shared/utils.js';\nimport { BRANCH_EFFECT, COMMENT_NODE, DESTROYED, EFFECT_OFFSCREEN, INERT } from '#client/constants';\nimport { queue_micro_task } from '../task.js';\nimport { get } from '../../runtime.js';\nimport { DEV } from 'esm-env';\nimport { derived_safe_equal } from '../../reactivity/deriveds.js';\nimport { current_batch } from '../../reactivity/batch.js';\nimport * as e from '../../errors.js';\nimport { tag } from '../../dev/tracing.js';\n\n// When making substantive changes to this file, validate them with the each block stress test:\n// https://svelte.dev/playground/1972b2cf46564476ad8c8c6405b23b7b\n// This test also exists in this repo, as `packages/svelte/tests/manual/each-stress-test`\n\n/**\n * @param {any} _\n * @param {number} i\n */\nexport function index(_, i) {\n\treturn i;\n}\n\n/**\n * Pause multiple effects simultaneously, and coordinate their\n * subsequent destruction. Used in each blocks\n * @param {EachState} state\n * @param {Effect[]} to_destroy\n * @param {null | Node} controlled_anchor\n */\nfunction pause_effects(state, to_destroy, controlled_anchor) {\n\t/** @type {TransitionManager[]} */\n\tvar transitions = [];\n\tvar length = to_destroy.length;\n\n\t/** @type {EachOutroGroup} */\n\tvar group;\n\tvar remaining = to_destroy.length;\n\n\tfor (var i = 0; i < length; i++) {\n\t\tlet effect = to_destroy[i];\n\n\t\tpause_effect(\n\t\t\teffect,\n\t\t\t() => {\n\t\t\t\tif (group) {\n\t\t\t\t\tgroup.pending.delete(effect);\n\t\t\t\t\tgroup.done.add(effect);\n\n\t\t\t\t\tif (group.pending.size === 0) {\n\t\t\t\t\t\tvar groups = /** @type {Set} */ (state.outrogroups);\n\n\t\t\t\t\t\tdestroy_effects(state, array_from(group.done));\n\t\t\t\t\t\tgroups.delete(group);\n\n\t\t\t\t\t\tif (groups.size === 0) {\n\t\t\t\t\t\t\tstate.outrogroups = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tremaining -= 1;\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse\n\t\t);\n\t}\n\n\tif (remaining === 0) {\n\t\t// If we're in a controlled each block (i.e. the block is the only child of an\n\t\t// element), and we are removing all items, _and_ there are no out transitions,\n\t\t// we can use the fast path — emptying the element and replacing the anchor.\n\t\t// Skip the fast path when another batch is still pending on this each block:\n\t\t// that batch's keys still reference EachItems in `state.items`, which\n\t\t// `destroy_effects` needs to preserve offscreen (see #18610).\n\t\tvar fast_path =\n\t\t\ttransitions.length === 0 && controlled_anchor !== null && state.pending.size === 0;\n\n\t\tif (fast_path) {\n\t\t\tvar anchor = /** @type {Element} */ (controlled_anchor);\n\t\t\tvar parent_node = /** @type {Element} */ (anchor.parentNode);\n\n\t\t\tclear_text_content(parent_node);\n\t\t\tparent_node.append(anchor);\n\n\t\t\tstate.items.clear();\n\t\t}\n\n\t\tdestroy_effects(state, to_destroy, !fast_path);\n\t} else {\n\t\tgroup = {\n\t\t\tpending: new Set(to_destroy),\n\t\t\tdone: new Set()\n\t\t};\n\n\t\t(state.outrogroups ??= new Set()).add(group);\n\t}\n}\n\n/**\n * @param {EachState} state\n * @param {Effect[]} to_destroy\n * @param {boolean} remove_dom\n */\nfunction destroy_effects(state, to_destroy, remove_dom = true) {\n\t/** @type {Set | undefined} */\n\tvar preserved_effects;\n\n\t// The loop-in-a-loop isn't ideal, but we should only hit this in relatively rare cases\n\tif (state.pending.size > 0) {\n\t\tpreserved_effects = new Set();\n\n\t\tfor (const keys of state.pending.values()) {\n\t\t\tfor (const key of keys) {\n\t\t\t\tpreserved_effects.add(/** @type {EachItem} */ (state.items.get(key)).e);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (var i = 0; i < to_destroy.length; i++) {\n\t\tvar e = to_destroy[i];\n\n\t\tif (preserved_effects?.has(e)) {\n\t\t\te.f |= EFFECT_OFFSCREEN;\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\t\t\tmove_effect(e, fragment);\n\t\t} else {\n\t\t\tdestroy_effect(to_destroy[i], remove_dom);\n\t\t}\n\t}\n}\n\n/** @type {TemplateNode} */\nvar offscreen_anchor;\n\n/**\n * @template V\n * @param {Element | Comment} node The next sibling node, or the parent node if this is a 'controlled' block\n * @param {number} flags\n * @param {() => V[]} get_collection\n * @param {(value: V, index: number) => any} get_key\n * @param {(anchor: Node, item: MaybeSource, index: MaybeSource) => void} render_fn\n * @param {null | ((anchor: Node) => void)} fallback_fn\n * @returns {void}\n */\nexport function each(node, flags, get_collection, get_key, render_fn, fallback_fn = null) {\n\tvar anchor = node;\n\n\t/** @type {Map} */\n\tvar items = new Map();\n\n\tvar is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;\n\n\tif (is_controlled) {\n\t\tvar parent_node = /** @type {Element} */ (node);\n\n\t\tanchor = hydrating\n\t\t\t? set_hydrate_node(get_first_child(parent_node))\n\t\t\t: parent_node.appendChild(create_text());\n\t}\n\n\tif (hydrating) {\n\t\thydrate_next();\n\t}\n\n\t/** @type {Effect | null} */\n\tvar fallback = null;\n\n\t// TODO: ideally we could use derived for runes mode but because of the ability\n\t// to use a store which can be mutated, we can't do that here as mutating a store\n\t// will still result in the collection array being the same from the store\n\tvar each_array = derived_safe_equal(() => {\n\t\tvar collection = get_collection();\n\n\t\treturn /** @type {V[]} */ (\n\t\t\tis_array(collection) ? collection : collection == null ? [] : array_from(collection)\n\t\t);\n\t});\n\n\tif (DEV) {\n\t\ttag(each_array, '{#each ...}');\n\t}\n\n\t/** @type {Map>} */\n\tvar pending = new Map();\n\n\tvar first_run = true;\n\n\t/**\n\t * @param {Batch} batch\n\t */\n\tfunction commit(batch) {\n\t\tif ((state.effect.f & DESTROYED) !== 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tstate.pending.delete(batch);\n\n\t\t// The effect doesn't necessarily re-run in a batch right before that batch commits\n\t\t// (its view of the collection may not have changed), so we read the collection\n\t\t// as the committing batch sees it rather than using the most recent block run's result\n\t\tvar array = get(each_array);\n\n\t\tstate.fallback = fallback;\n\t\treconcile(state, array, anchor, flags, get_key);\n\n\t\tif (fallback !== null) {\n\t\t\tif (array.length === 0) {\n\t\t\t\tif ((fallback.f & EFFECT_OFFSCREEN) === 0) {\n\t\t\t\t\tresume_effect(fallback);\n\t\t\t\t} else {\n\t\t\t\t\tfallback.f ^= EFFECT_OFFSCREEN;\n\t\t\t\t\tmove(fallback, null, anchor);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpause_effect(fallback, () => {\n\t\t\t\t\t// TODO only null out if no pending batch needs it,\n\t\t\t\t\t// otherwise re-add `fallback.fragment` and move the\n\t\t\t\t\t// effect into it\n\t\t\t\t\tfallback = null;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @param {Batch} batch\n\t */\n\tfunction discard(batch) {\n\t\tstate.pending.delete(batch);\n\t}\n\n\tvar effect = block(() => {\n\t\tvar array = /** @type {V[]} */ (get(each_array));\n\t\tvar length = array.length;\n\n\t\t/** `true` if there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */\n\t\tlet mismatch = false;\n\n\t\tif (hydrating) {\n\t\t\tvar is_else = read_hydration_instruction(anchor) === HYDRATION_START_ELSE;\n\n\t\t\tif (is_else !== (length === 0)) {\n\t\t\t\t// hydration mismatch — remove the server-rendered DOM and start over\n\t\t\t\tanchor = skip_nodes();\n\n\t\t\t\tset_hydrate_node(anchor);\n\t\t\t\tset_hydrating(false);\n\t\t\t\tmismatch = true;\n\t\t\t}\n\t\t}\n\n\t\tvar keys = new Set();\n\t\tvar batch = /** @type {Batch} */ (current_batch);\n\t\tvar defer = should_defer_append();\n\n\t\tfor (var index = 0; index < length; index += 1) {\n\t\t\tif (\n\t\t\t\thydrating &&\n\t\t\t\thydrate_node.nodeType === COMMENT_NODE &&\n\t\t\t\t/** @type {Comment} */ (hydrate_node).data === HYDRATION_END\n\t\t\t) {\n\t\t\t\t// The server rendered fewer items than expected,\n\t\t\t\t// so break out and continue appending non-hydrated items\n\t\t\t\tanchor = /** @type {Comment} */ (hydrate_node);\n\t\t\t\tmismatch = true;\n\t\t\t\tset_hydrating(false);\n\t\t\t}\n\n\t\t\tvar value = array[index];\n\t\t\tvar key = get_key(value, index);\n\n\t\t\tif (DEV) {\n\t\t\t\t// Check that the key function is idempotent (returns the same value when called twice)\n\t\t\t\tvar key_again = get_key(value, index);\n\t\t\t\tif (key !== key_again) {\n\t\t\t\t\te.each_key_volatile(String(index), String(key), String(key_again));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar item = first_run ? null : items.get(key);\n\n\t\t\tif (item) {\n\t\t\t\t// update before reconciliation, to trigger any async updates\n\t\t\t\tif (item.v) internal_set(item.v, value);\n\t\t\t\tif (item.i) internal_set(item.i, index);\n\n\t\t\t\tif (defer) {\n\t\t\t\t\tbatch.unskip_effect(item.e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\titem = create_item(\n\t\t\t\t\titems,\n\t\t\t\t\tfirst_run ? anchor : (offscreen_anchor ??= create_text()),\n\t\t\t\t\tvalue,\n\t\t\t\t\tkey,\n\t\t\t\t\tindex,\n\t\t\t\t\trender_fn,\n\t\t\t\t\tflags,\n\t\t\t\t\tget_collection\n\t\t\t\t);\n\n\t\t\t\tif (!first_run) {\n\t\t\t\t\titem.e.f |= EFFECT_OFFSCREEN;\n\t\t\t\t}\n\n\t\t\t\titems.set(key, item);\n\t\t\t}\n\n\t\t\tkeys.add(key);\n\t\t}\n\n\t\tif (length === 0 && fallback_fn && !fallback) {\n\t\t\tif (first_run) {\n\t\t\t\tfallback = branch(() => fallback_fn(anchor));\n\t\t\t} else {\n\t\t\t\tfallback = branch(() => fallback_fn((offscreen_anchor ??= create_text())));\n\t\t\t\tfallback.f |= EFFECT_OFFSCREEN;\n\t\t\t}\n\t\t}\n\n\t\tif (length > keys.size) {\n\t\t\tif (DEV) {\n\t\t\t\tvalidate_each_keys(array, get_key);\n\t\t\t} else {\n\t\t\t\t// in prod, the additional information isn't printed, so don't bother computing it\n\t\t\t\te.each_key_duplicate('', '', '');\n\t\t\t}\n\t\t}\n\n\t\t// remove excess nodes\n\t\tif (hydrating && length > 0) {\n\t\t\tset_hydrate_node(skip_nodes());\n\t\t}\n\n\t\tif (!first_run) {\n\t\t\tpending.set(batch, keys);\n\n\t\t\tif (defer) {\n\t\t\t\tfor (const [key, item] of items) {\n\t\t\t\t\tif (!keys.has(key)) {\n\t\t\t\t\t\tbatch.skip_effect(item.e);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbatch.oncommit(commit);\n\t\t\t\tbatch.ondiscard(discard);\n\t\t\t} else {\n\t\t\t\tcommit(batch);\n\t\t\t}\n\t\t}\n\n\t\tif (mismatch) {\n\t\t\t// continue in hydration mode\n\t\t\tset_hydrating(true);\n\t\t}\n\n\t\t// When we mount the each block for the first time, the collection won't be\n\t\t// connected to this effect as the effect hasn't finished running yet and its deps\n\t\t// won't be assigned. However, it's possible that when reconciling the each block\n\t\t// that a mutation occurred and it's made the collection MAYBE_DIRTY, so reading the\n\t\t// collection again can provide consistency to the reactive graph again as the deriveds\n\t\t// will now be `CLEAN`.\n\t\tget(each_array);\n\t});\n\n\t/** @type {EachState} */\n\tvar state = { effect, flags, items, pending, outrogroups: null, fallback };\n\n\tfirst_run = false;\n\n\tif (hydrating) {\n\t\tanchor = hydrate_node;\n\t}\n}\n\n/**\n * Skip past any non-branch effects (which could be created with `createSubscriber`, for example) to find the next branch effect\n * @param {Effect | null} effect\n * @returns {Effect | null}\n */\nfunction skip_to_branch(effect) {\n\twhile (effect !== null && (effect.f & BRANCH_EFFECT) === 0) {\n\t\teffect = effect.next;\n\t}\n\treturn effect;\n}\n\n/**\n * Add, remove, or reorder items output by an each block as its input changes\n * @template V\n * @param {EachState} state\n * @param {Array} array\n * @param {Element | Comment | Text} anchor\n * @param {number} flags\n * @param {(value: V, index: number) => any} get_key\n * @returns {void}\n */\nfunction reconcile(state, array, anchor, flags, get_key) {\n\tvar is_animated = (flags & EACH_IS_ANIMATED) !== 0;\n\n\tvar length = array.length;\n\tvar items = state.items;\n\tvar current = skip_to_branch(state.effect.first);\n\n\t/** @type {undefined | Set} */\n\tvar seen;\n\n\t/** @type {Effect | null} */\n\tvar prev = null;\n\n\t/** @type {undefined | Set} */\n\tvar to_animate;\n\n\t/** @type {Effect[]} */\n\tvar matched = [];\n\n\t/** @type {Effect[]} */\n\tvar stashed = [];\n\n\t/** @type {V} */\n\tvar value;\n\n\t/** @type {any} */\n\tvar key;\n\n\t/** @type {Effect | undefined} */\n\tvar effect;\n\n\t/** @type {number} */\n\tvar i;\n\n\tif (is_animated) {\n\t\tfor (i = 0; i < length; i += 1) {\n\t\t\tvalue = array[i];\n\t\t\tkey = get_key(value, i);\n\t\t\teffect = /** @type {EachItem} */ (items.get(key)).e;\n\n\t\t\t// offscreen == coming in now, no animation in that case,\n\t\t\t// else this would happen https://github.com/sveltejs/svelte/issues/17181\n\t\t\tif ((effect.f & EFFECT_OFFSCREEN) === 0) {\n\t\t\t\teffect.nodes?.a?.measure();\n\t\t\t\t(to_animate ??= new Set()).add(effect);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < length; i += 1) {\n\t\tvalue = array[i];\n\t\tkey = get_key(value, i);\n\n\t\teffect = /** @type {EachItem} */ (items.get(key)).e;\n\n\t\tif (state.outrogroups !== null) {\n\t\t\tfor (const group of state.outrogroups) {\n\t\t\t\tgroup.pending.delete(effect);\n\t\t\t\tgroup.done.delete(effect);\n\t\t\t}\n\t\t}\n\n\t\tif ((effect.f & INERT) !== 0) {\n\t\t\tresume_effect(effect);\n\t\t\tif (is_animated) {\n\t\t\t\teffect.nodes?.a?.unfix();\n\t\t\t\t(to_animate ??= new Set()).delete(effect);\n\t\t\t}\n\t\t}\n\n\t\tif ((effect.f & EFFECT_OFFSCREEN) !== 0) {\n\t\t\teffect.f ^= EFFECT_OFFSCREEN;\n\n\t\t\tif (effect === current) {\n\t\t\t\tmove(effect, null, anchor);\n\t\t\t} else {\n\t\t\t\tvar next = prev ? prev.next : current;\n\n\t\t\t\tif (effect === state.effect.last) {\n\t\t\t\t\tstate.effect.last = effect.prev;\n\t\t\t\t}\n\n\t\t\t\tif (effect.prev) effect.prev.next = effect.next;\n\t\t\t\tif (effect.next) effect.next.prev = effect.prev;\n\t\t\t\tlink(state, prev, effect);\n\t\t\t\tlink(state, effect, next);\n\n\t\t\t\tmove(effect, next, anchor);\n\t\t\t\tprev = effect;\n\n\t\t\t\tmatched = [];\n\t\t\t\tstashed = [];\n\n\t\t\t\tcurrent = skip_to_branch(prev.next);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (effect !== current) {\n\t\t\tif (seen !== undefined && seen.has(effect)) {\n\t\t\t\tif (matched.length < stashed.length) {\n\t\t\t\t\t// more efficient to move later items to the front\n\t\t\t\t\tvar start = stashed[0];\n\t\t\t\t\tvar j;\n\n\t\t\t\t\tprev = start.prev;\n\n\t\t\t\t\tvar a = matched[0];\n\t\t\t\t\tvar b = matched[matched.length - 1];\n\n\t\t\t\t\tfor (j = 0; j < matched.length; j += 1) {\n\t\t\t\t\t\tmove(matched[j], start, anchor);\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (j = 0; j < stashed.length; j += 1) {\n\t\t\t\t\t\tseen.delete(stashed[j]);\n\t\t\t\t\t}\n\n\t\t\t\t\tlink(state, a.prev, b.next);\n\t\t\t\t\tlink(state, prev, a);\n\t\t\t\t\tlink(state, b, start);\n\n\t\t\t\t\tcurrent = start;\n\t\t\t\t\tprev = b;\n\t\t\t\t\ti -= 1;\n\n\t\t\t\t\tmatched = [];\n\t\t\t\t\tstashed = [];\n\t\t\t\t} else {\n\t\t\t\t\t// more efficient to move earlier items to the back\n\t\t\t\t\tseen.delete(effect);\n\t\t\t\t\tmove(effect, current, anchor);\n\n\t\t\t\t\tlink(state, effect.prev, effect.next);\n\t\t\t\t\tlink(state, effect, prev === null ? state.effect.first : prev.next);\n\t\t\t\t\tlink(state, prev, effect);\n\n\t\t\t\t\tprev = effect;\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmatched = [];\n\t\t\tstashed = [];\n\n\t\t\twhile (current !== null && current !== effect) {\n\t\t\t\t(seen ??= new Set()).add(current);\n\t\t\t\tstashed.push(current);\n\t\t\t\tcurrent = skip_to_branch(current.next);\n\t\t\t}\n\n\t\t\tif (current === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif ((effect.f & EFFECT_OFFSCREEN) === 0) {\n\t\t\tmatched.push(effect);\n\t\t}\n\n\t\tprev = effect;\n\t\tcurrent = skip_to_branch(effect.next);\n\t}\n\n\tif (state.outrogroups !== null) {\n\t\tfor (const group of state.outrogroups) {\n\t\t\tif (group.pending.size === 0) {\n\t\t\t\tdestroy_effects(state, array_from(group.done));\n\t\t\t\tstate.outrogroups?.delete(group);\n\t\t\t}\n\t\t}\n\n\t\tif (state.outrogroups.size === 0) {\n\t\t\tstate.outrogroups = null;\n\t\t}\n\t}\n\n\tif (current !== null || seen !== undefined) {\n\t\t/** @type {Effect[]} */\n\t\tvar to_destroy = [];\n\n\t\tif (seen !== undefined) {\n\t\t\tfor (effect of seen) {\n\t\t\t\tif ((effect.f & INERT) === 0) {\n\t\t\t\t\tto_destroy.push(effect);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\twhile (current !== null) {\n\t\t\t// If the each block isn't inert, then inert effects are currently outroing and will be removed once the transition is finished\n\t\t\tif ((current.f & INERT) === 0 && current !== state.fallback) {\n\t\t\t\tto_destroy.push(current);\n\t\t\t}\n\n\t\t\tcurrent = skip_to_branch(current.next);\n\t\t}\n\n\t\tvar destroy_length = to_destroy.length;\n\n\t\tif (destroy_length > 0) {\n\t\t\tvar controlled_anchor = (flags & EACH_IS_CONTROLLED) !== 0 && length === 0 ? anchor : null;\n\n\t\t\tif (is_animated) {\n\t\t\t\tfor (i = 0; i < destroy_length; i += 1) {\n\t\t\t\t\tto_destroy[i].nodes?.a?.measure();\n\t\t\t\t}\n\n\t\t\t\tfor (i = 0; i < destroy_length; i += 1) {\n\t\t\t\t\tto_destroy[i].nodes?.a?.fix();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpause_effects(state, to_destroy, controlled_anchor);\n\t\t}\n\t}\n\n\tif (is_animated) {\n\t\tqueue_micro_task(() => {\n\t\t\tif (to_animate === undefined) return;\n\t\t\tfor (effect of to_animate) {\n\t\t\t\teffect.nodes?.a?.apply();\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * @template V\n * @param {Map} items\n * @param {Node} anchor\n * @param {V} value\n * @param {unknown} key\n * @param {number} index\n * @param {(anchor: Node, item: MaybeSource, index: MaybeSource, collection: () => V[]) => void} render_fn\n * @param {number} flags\n * @param {() => V[]} get_collection\n * @returns {EachItem}\n */\nfunction create_item(items, anchor, value, key, index, render_fn, flags, get_collection) {\n\tvar v =\n\t\t(flags & EACH_ITEM_REACTIVE) !== 0\n\t\t\t? (flags & EACH_ITEM_IMMUTABLE) === 0\n\t\t\t\t? mutable_source(value, false, false)\n\t\t\t\t: source(value)\n\t\t\t: null;\n\n\tvar i = (flags & EACH_INDEX_REACTIVE) !== 0 ? source(index) : null;\n\n\tif (DEV && v) {\n\t\t// For tracing purposes, we need to link the source signal we create with the\n\t\t// collection + index so that tracing works as intended\n\t\tv.trace = () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-expressions\n\t\t\tget_collection()[i?.v ?? index];\n\t\t};\n\t}\n\n\treturn {\n\t\tv,\n\t\ti,\n\t\te: branch(() => {\n\t\t\trender_fn(anchor, v ?? value, i ?? index, get_collection);\n\n\t\t\treturn () => {\n\t\t\t\titems.delete(key);\n\t\t\t};\n\t\t})\n\t};\n}\n\n/**\n * @param {Effect} effect\n * @param {Effect | null} next\n * @param {Text | Element | Comment} anchor\n */\nfunction move(effect, next, anchor) {\n\tif (!effect.nodes) return;\n\n\tvar node = effect.nodes.start;\n\tvar end = effect.nodes.end;\n\n\tvar dest =\n\t\tnext && (next.f & EFFECT_OFFSCREEN) === 0\n\t\t\t? /** @type {EffectNodes} */ (next.nodes).start\n\t\t\t: anchor;\n\n\twhile (node !== null) {\n\t\tvar next_node = /** @type {TemplateNode} */ (get_next_sibling(node));\n\t\tdest.before(node);\n\n\t\tif (node === end) {\n\t\t\treturn;\n\t\t}\n\n\t\tnode = next_node;\n\t}\n}\n\n/**\n * @param {EachState} state\n * @param {Effect | null} prev\n * @param {Effect | null} next\n */\nfunction link(state, prev, next) {\n\tif (prev === null) {\n\t\tstate.effect.first = next;\n\t} else {\n\t\tprev.next = next;\n\t}\n\n\tif (next === null) {\n\t\tstate.effect.last = prev;\n\t} else {\n\t\tnext.prev = prev;\n\t}\n}\n\n/**\n * @param {Array} array\n * @param {(item: any, index: number) => string} key_fn\n * @returns {void}\n */\nfunction validate_each_keys(array, key_fn) {\n\tconst keys = new Map();\n\tconst length = array.length;\n\n\tfor (let i = 0; i < length; i++) {\n\t\tconst key = key_fn(array[i], i);\n\n\t\tif (keys.has(key)) {\n\t\t\tconst a = String(keys.get(key));\n\t\t\tconst b = String(i);\n\n\t\t\t/** @type {string | null} */\n\t\t\tlet k = String(key);\n\t\t\tif (k.startsWith('[object ')) k = null;\n\n\t\t\te.each_key_duplicate(a, b, k);\n\t\t}\n\n\t\tkeys.set(key, i);\n\t}\n}\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t` should be rendered as `
              ` and _not_\n * `
              `, which is equivalent to `
              `. There\n * may be other odd cases that need to be added to this list in future\n * @type {Record>}\n */\nconst replacements = {\n\ttranslate: new Map([\n\t\t[true, 'yes'],\n\t\t[false, 'no']\n\t])\n};\n\n/**\n * @template V\n * @param {string} name\n * @param {V} value\n * @param {boolean} [is_boolean]\n * @returns {string}\n */\nexport function attr(name, value, is_boolean = false) {\n\t// attribute hidden for values other than \"until-found\" behaves like a boolean attribute\n\tif (name === 'hidden' && value !== 'until-found') {\n\t\tis_boolean = true;\n\t}\n\t// `''` is a present boolean attribute, as it is in markup and on the client\n\tif (value == null || (is_boolean && !value && value !== '')) return '';\n\tconst normalized =\n\t\t(has_own_property.call(replacements, name) && replacements[name].get(value)) || value;\n\tconst assignment = is_boolean ? `=\"\"` : `=\"${escape_html(normalized, true)}\"`;\n\treturn ` ${name}${assignment}`;\n}\n\n/**\n * Small wrapper around clsx to preserve Svelte's (weird) handling of falsy values.\n * TODO Svelte 6 revisit this, and likely turn all falsy values into the empty string (what clsx also does)\n * @param {any} value\n */\nexport function clsx(value) {\n\tif (typeof value === 'object') {\n\t\treturn _clsx(value);\n\t} else {\n\t\treturn value ?? '';\n\t}\n}\n\nconst whitespace = [...' \\t\\n\\r\\f\\u00a0\\u000b\\ufeff'];\n\n/**\n * @param {any} value\n * @param {string | null} [hash]\n * @param {Record} [directives]\n * @returns {string | null}\n */\nexport function to_class(value, hash, directives) {\n\tvar classname = value == null ? '' : '' + value;\n\n\tif (hash) {\n\t\tclassname = classname ? classname + ' ' + hash : hash;\n\t}\n\n\tif (directives) {\n\t\tfor (var key of Object.keys(directives)) {\n\t\t\tif (directives[key]) {\n\t\t\t\tclassname = classname ? classname + ' ' + key : key;\n\t\t\t} else if (classname.length) {\n\t\t\t\tvar len = key.length;\n\t\t\t\tvar a = 0;\n\n\t\t\t\twhile ((a = classname.indexOf(key, a)) >= 0) {\n\t\t\t\t\tvar b = a + len;\n\n\t\t\t\t\tif (\n\t\t\t\t\t\t(a === 0 || whitespace.includes(classname[a - 1])) &&\n\t\t\t\t\t\t(b === classname.length || whitespace.includes(classname[b]))\n\t\t\t\t\t) {\n\t\t\t\t\t\tclassname = (a === 0 ? '' : classname.substring(0, a)) + classname.substring(b + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ta = b;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn classname === '' ? null : classname;\n}\n\n/**\n *\n * @param {Record} styles\n * @param {boolean} important\n */\nfunction append_styles(styles, important = false) {\n\tvar separator = important ? ' !important;' : ';';\n\tvar css = '';\n\n\tfor (var key of Object.keys(styles)) {\n\t\tvar value = styles[key];\n\t\tif (value != null && value !== '') {\n\t\t\tcss += ' ' + key + ': ' + value + separator;\n\t\t}\n\t}\n\n\treturn css;\n}\n\n/**\n * @param {string} name\n * @returns {string}\n */\nfunction to_css_name(name) {\n\tif (name[0] !== '-' || name[1] !== '-') {\n\t\treturn name.toLowerCase();\n\t}\n\treturn name;\n}\n\n/**\n * @param {any} value\n * @param {Record | [Record, Record]} [styles]\n * @returns {string | null}\n */\nexport function to_style(value, styles) {\n\tif (styles) {\n\t\tvar new_style = '';\n\n\t\t/** @type {Record | undefined} */\n\t\tvar normal_styles;\n\n\t\t/** @type {Record | undefined} */\n\t\tvar important_styles;\n\n\t\tif (Array.isArray(styles)) {\n\t\t\tnormal_styles = styles[0];\n\t\t\timportant_styles = styles[1];\n\t\t} else {\n\t\t\tnormal_styles = styles;\n\t\t}\n\n\t\tif (value) {\n\t\t\t// strip comments; surrounding whitespace is handled by the trims below (which is much faster than doing it through regex)\n\t\t\tvalue = String(value)\n\t\t\t\t.replaceAll(/\\/\\*.*?\\*\\//g, '')\n\t\t\t\t.trim();\n\n\t\t\t/** @type {boolean | '\"' | \"'\"} */\n\t\t\tvar in_str = false;\n\t\t\tvar in_apo = 0;\n\t\t\tvar in_comment = false;\n\n\t\t\tvar reserved_names = [];\n\n\t\t\tif (normal_styles) {\n\t\t\t\treserved_names.push(...Object.keys(normal_styles).map(to_css_name));\n\t\t\t}\n\t\t\tif (important_styles) {\n\t\t\t\treserved_names.push(...Object.keys(important_styles).map(to_css_name));\n\t\t\t}\n\n\t\t\tvar start_index = 0;\n\t\t\tvar name_index = -1;\n\n\t\t\tconst len = value.length;\n\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\tvar c = value[i];\n\n\t\t\t\tif (in_comment) {\n\t\t\t\t\tif (c === '/' && value[i - 1] === '*') {\n\t\t\t\t\t\tin_comment = false;\n\t\t\t\t\t}\n\t\t\t\t} else if (in_str) {\n\t\t\t\t\tif (in_str === c) {\n\t\t\t\t\t\tin_str = false;\n\t\t\t\t\t}\n\t\t\t\t} else if (c === '/' && value[i + 1] === '*') {\n\t\t\t\t\tin_comment = true;\n\t\t\t\t} else if (c === '\"' || c === \"'\") {\n\t\t\t\t\tin_str = c;\n\t\t\t\t} else if (c === '(') {\n\t\t\t\t\tin_apo++;\n\t\t\t\t} else if (c === ')') {\n\t\t\t\t\tin_apo--;\n\t\t\t\t}\n\n\t\t\t\tif (!in_comment && in_str === false && in_apo === 0) {\n\t\t\t\t\tif (c === ':' && name_index === -1) {\n\t\t\t\t\t\tname_index = i;\n\t\t\t\t\t} else if (c === ';' || i === len - 1) {\n\t\t\t\t\t\tif (name_index !== -1) {\n\t\t\t\t\t\t\tvar name = to_css_name(value.substring(start_index, name_index).trim());\n\n\t\t\t\t\t\t\tif (!reserved_names.includes(name)) {\n\t\t\t\t\t\t\t\tif (c !== ';') {\n\t\t\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tvar property = value.substring(start_index, i).trim();\n\t\t\t\t\t\t\t\tnew_style += ' ' + property + ';';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart_index = i + 1;\n\t\t\t\t\t\tname_index = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (normal_styles) {\n\t\t\tnew_style += append_styles(normal_styles);\n\t\t}\n\n\t\tif (important_styles) {\n\t\t\tnew_style += append_styles(important_styles, true);\n\t\t}\n\n\t\tnew_style = new_style.trim();\n\t\treturn new_style === '' ? null : new_style;\n\t}\n\n\treturn value == null ? null : String(value);\n}\n","import { to_class } from '../../../shared/attributes.js';\nimport { CLASS_CACHE } from '../../constants.js';\nimport { hydrating } from '../hydration.js';\n\n/**\n * @param {Element} dom\n * @param {boolean | number} is_html\n * @param {string | null} value\n * @param {string} [hash]\n * @param {Record} [prev_classes]\n * @param {Record} [next_classes]\n * @returns {Record | undefined}\n */\nexport function set_class(dom, is_html, value, hash, prev_classes, next_classes) {\n\tvar prev = /** @type {any} */ (dom)[CLASS_CACHE];\n\n\tif (\n\t\thydrating ||\n\t\tprev !== value ||\n\t\tprev === undefined // for edge case of `class={undefined}`\n\t) {\n\t\tvar next_class_name = to_class(value, hash, next_classes);\n\n\t\tif (!hydrating || next_class_name !== dom.getAttribute('class')) {\n\t\t\t// Removing the attribute when the value is only an empty string causes\n\t\t\t// performance issues vs simply making the className an empty string. So\n\t\t\t// we should only remove the class if the value is nullish\n\t\t\t// and there no hash/directives :\n\t\t\tif (next_class_name == null) {\n\t\t\t\tdom.removeAttribute('class');\n\t\t\t} else if (is_html) {\n\t\t\t\tdom.className = next_class_name;\n\t\t\t} else {\n\t\t\t\tdom.setAttribute('class', next_class_name);\n\t\t\t}\n\t\t}\n\n\t\t/** @type {any} */ (dom)[CLASS_CACHE] = value;\n\t} else if (next_classes && prev_classes !== next_classes) {\n\t\tfor (var key in next_classes) {\n\t\t\tvar is_present = !!next_classes[key];\n\n\t\t\tif (prev_classes == null || is_present !== !!prev_classes[key]) {\n\t\t\t\tdom.classList.toggle(key, is_present);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn next_classes;\n}\n","import { to_style } from '../../../shared/attributes.js';\nimport { STYLE_CACHE } from '../../constants.js';\nimport { hydrating } from '../hydration.js';\n\n/**\n * @param {Element & ElementCSSInlineStyle} dom\n * @param {Record} prev\n * @param {Record} next\n * @param {string} [priority]\n */\nfunction update_styles(dom, prev = {}, next, priority) {\n\tfor (var key in next) {\n\t\tvar value = next[key];\n\n\t\tif (prev[key] !== value) {\n\t\t\tif (next[key] == null) {\n\t\t\t\tdom.style.removeProperty(key);\n\t\t\t} else {\n\t\t\t\tdom.style.setProperty(key, value, priority);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * @param {Element & ElementCSSInlineStyle} dom\n * @param {string | null} value\n * @param {Record | [Record, Record]} [prev_styles]\n * @param {Record | [Record, Record]} [next_styles]\n */\nexport function set_style(dom, value, prev_styles, next_styles) {\n\tvar prev = /** @type {any} */ (dom)[STYLE_CACHE];\n\n\tif (hydrating || prev !== value) {\n\t\tvar next_style_attr = to_style(value, next_styles);\n\n\t\tif (!hydrating || next_style_attr !== dom.getAttribute('style')) {\n\t\t\tif (next_style_attr == null) {\n\t\t\t\tdom.removeAttribute('style');\n\t\t\t} else {\n\t\t\t\tdom.style.cssText = next_style_attr;\n\t\t\t}\n\t\t}\n\n\t\t/** @type {any} */ (dom)[STYLE_CACHE] = value;\n\t} else if (next_styles) {\n\t\tif (Array.isArray(next_styles)) {\n\t\t\tupdate_styles(dom, prev_styles?.[0], next_styles[0]);\n\t\t\tupdate_styles(dom, prev_styles?.[1], next_styles[1], 'important');\n\t\t} else {\n\t\t\tupdate_styles(dom, prev_styles, next_styles);\n\t\t}\n\t}\n\n\treturn next_styles;\n}\n","/** @import { Blocker, Effect } from '#client' */\nimport { DEV } from 'esm-env';\nimport { hydrating, set_hydrating } from '../hydration.js';\nimport { get_descriptors, get_prototype_of } from '../../../shared/utils.js';\nimport { create_event, delegate, delegated, event, event_symbol } from './events.js';\nimport { add_form_reset_listener, autofocus } from './misc.js';\nimport * as w from '../../warnings.js';\nimport {\n\tATTRIBUTES_CACHE,\n\tFORM_RESET_HANDLER,\n\tIS_XHTML,\n\tLOADING_ATTR_SYMBOL\n} from '#client/constants';\nimport { queue_micro_task } from '../task.js';\nimport { is_capture_event, can_delegate_event, normalize_attribute } from '../../../../utils.js';\nimport {\n\tactive_effect,\n\tactive_reaction,\n\tget,\n\tset_active_effect,\n\tset_active_reaction\n} from '../../runtime.js';\nimport { attach } from './attachments.js';\nimport { clsx } from '../../../shared/attributes.js';\nimport { set_class } from './class.js';\nimport { set_style } from './style.js';\nimport { ATTACHMENT_KEY, NAMESPACE_HTML, UNINITIALIZED } from '../../../../constants.js';\nimport { branch, destroy_effect, effect, managed } from '../../reactivity/effects.js';\nimport {\n\tinit_select,\n\tselect_option,\n\tset_default_select_value,\n\tset_selected\n} from './bindings/select.js';\nimport { flatten } from '../../reactivity/async.js';\n\nexport const CLASS = Symbol('class');\nexport const STYLE = Symbol('style');\n\nconst IS_CUSTOM_ELEMENT = Symbol('is custom element');\nconst IS_HTML = Symbol('is html');\n\nconst LINK_TAG = IS_XHTML ? 'link' : 'LINK';\nconst INPUT_TAG = IS_XHTML ? 'input' : 'INPUT';\nconst OPTION_TAG = IS_XHTML ? 'option' : 'OPTION';\nconst SELECT_TAG = IS_XHTML ? 'select' : 'SELECT';\nconst PROGRESS_TAG = IS_XHTML ? 'progress' : 'PROGRESS';\n\n/**\n * The value/checked attribute in the template actually corresponds to the defaultValue property, so we need\n * to remove it upon hydration to avoid a bug when someone resets the form value.\n * @param {HTMLInputElement} input\n * @returns {void}\n */\nexport function remove_input_defaults(input) {\n\tif (!hydrating) return;\n\n\tvar already_removed = false;\n\n\t// We try and remove the default attributes later, rather than sync during hydration.\n\t// Doing it sync during hydration has a negative impact on performance, but deferring the\n\t// work in an idle task alleviates this greatly. If a form reset event comes in before\n\t// the idle callback, then we ensure the input defaults are cleared just before.\n\tvar remove_defaults = () => {\n\t\tif (already_removed) return;\n\t\talready_removed = true;\n\n\t\t// Remove the attributes but preserve the values\n\t\tif (input.hasAttribute('value')) {\n\t\t\tvar value = input.value;\n\t\t\tset_attribute(input, 'value', null);\n\t\t\tinput.value = value;\n\t\t}\n\n\t\tif (input.hasAttribute('checked')) {\n\t\t\tvar checked = input.checked;\n\t\t\tset_attribute(input, 'checked', null);\n\t\t\tinput.checked = checked;\n\t\t}\n\t};\n\n\t/** @type {any} */ (input)[FORM_RESET_HANDLER] = remove_defaults;\n\tqueue_micro_task(remove_defaults);\n\tadd_form_reset_listener();\n}\n\n/**\n * @param {Element} element\n * @param {any} value\n */\nexport function set_value(element, value) {\n\tvar attributes = get_attributes(element);\n\n\tif (\n\t\tattributes.value ===\n\t\t\t(attributes.value =\n\t\t\t\t// treat null and undefined the same for the initial value\n\t\t\t\tvalue ?? undefined) ||\n\t\t// @ts-expect-error\n\t\t// `progress` elements always need their value set when it's `0`\n\t\t(element.value === value && (value !== 0 || element.nodeName !== PROGRESS_TAG))\n\t) {\n\t\treturn;\n\t}\n\n\t// @ts-expect-error\n\telement.value = value ?? '';\n}\n\n/**\n * @param {Element} element\n * @param {boolean} checked\n */\nexport function set_checked(element, checked) {\n\tvar attributes = get_attributes(element);\n\n\tif (\n\t\tattributes.checked ===\n\t\t(attributes.checked =\n\t\t\t// treat null and undefined the same for the initial value\n\t\t\tchecked ?? undefined)\n\t) {\n\t\treturn;\n\t}\n\n\t// @ts-expect-error\n\telement.checked = checked;\n}\n\n/**\n * Applies the default checked property without influencing the current checked property.\n * @param {HTMLInputElement} element\n * @param {boolean} checked\n */\nexport function set_default_checked(element, checked) {\n\tconst existing_value = element.checked;\n\telement.defaultChecked = checked;\n\telement.checked = existing_value;\n}\n\n/**\n * Applies the default value property without influencing the current value property.\n * @param {HTMLInputElement | HTMLTextAreaElement} element\n * @param {string} value\n */\nexport function set_default_value(element, value) {\n\tconst existing_value = element.value;\n\telement.defaultValue = value;\n\telement.value = existing_value;\n}\n\n/**\n * @param {Element} element\n * @param {string} attribute\n * @param {string | null} value\n * @param {boolean} [skip_warning]\n */\nexport function set_attribute(element, attribute, value, skip_warning) {\n\tvar attributes = get_attributes(element);\n\n\tif (hydrating) {\n\t\tattributes[attribute] = element.getAttribute(attribute);\n\n\t\tif (\n\t\t\tattribute === 'src' ||\n\t\t\tattribute === 'srcset' ||\n\t\t\t(attribute === 'href' && element.nodeName === LINK_TAG)\n\t\t) {\n\t\t\tif (!skip_warning) {\n\t\t\t\tcheck_src_in_dev_hydration(element, attribute, value ?? '');\n\t\t\t}\n\n\t\t\t// If we reset these attributes, they would result in another network request, which we want to avoid.\n\t\t\t// We assume they are the same between client and server as checking if they are equal is expensive\n\t\t\t// (we can't just compare the strings as they can be different between client and server but result in the\n\t\t\t// same url, so we would need to create hidden anchor elements to compare them)\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (attributes[attribute] === (attributes[attribute] = value)) return;\n\n\tif (attribute === 'loading') {\n\t\t// @ts-expect-error\n\t\telement[LOADING_ATTR_SYMBOL] = value;\n\t}\n\n\tif (value == null) {\n\t\telement.removeAttribute(attribute);\n\t} else if (typeof value !== 'string' && get_setters(element).has(attribute)) {\n\t\t// @ts-ignore\n\t\telement[attribute] = value;\n\t} else {\n\t\telement.setAttribute(attribute, value);\n\t}\n}\n\n/**\n * @param {Element} dom\n * @param {string} attribute\n * @param {string} value\n */\nexport function set_xlink_attribute(dom, attribute, value) {\n\tdom.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\n\n/**\n * @param {HTMLElement} node\n * @param {string} prop\n * @param {any} value\n */\nexport function set_custom_element_data(node, prop, value) {\n\t// We need to ensure that setting custom element props, which can\n\t// invoke lifecycle methods on other custom elements, does not also\n\t// associate those lifecycle methods with the current active reaction\n\t// or effect\n\tvar previous_reaction = active_reaction;\n\tvar previous_effect = active_effect;\n\n\t// If we're hydrating but the custom element is from Svelte, and it already scaffolded,\n\t// then it might run block logic in hydration mode, which we have to prevent.\n\tlet was_hydrating = hydrating;\n\tif (hydrating) {\n\t\tset_hydrating(false);\n\t}\n\n\tset_active_reaction(null);\n\tset_active_effect(null);\n\n\ttry {\n\t\tif (\n\t\t\t// `style` should use `set_attribute` rather than the setter\n\t\t\tprop !== 'style' &&\n\t\t\t// Don't compute setters for custom elements while they aren't registered yet,\n\t\t\t// because during their upgrade/instantiation they might add more setters.\n\t\t\t// Instead, fall back to a simple \"an object, then set as property\" heuristic.\n\t\t\t(setters_cache.has(node.getAttribute('is') || node.nodeName) ||\n\t\t\t// customElements may not be available in browser extension contexts\n\t\t\t!customElements ||\n\t\t\tcustomElements.get(node.getAttribute('is') || node.nodeName.toLowerCase())\n\t\t\t\t? get_setters(node).has(prop)\n\t\t\t\t: value && typeof value === 'object')\n\t\t) {\n\t\t\t// @ts-expect-error\n\t\t\tnode[prop] = value;\n\t\t} else {\n\t\t\t// We did getters etc checks already, stringify before passing to set_attribute\n\t\t\t// to ensure it doesn't invoke the same logic again, and potentially populating\n\t\t\t// the setters cache too early.\n\t\t\tset_attribute(node, prop, value == null ? value : String(value));\n\t\t}\n\t} finally {\n\t\tset_active_reaction(previous_reaction);\n\t\tset_active_effect(previous_effect);\n\t\tif (was_hydrating) {\n\t\t\tset_hydrating(true);\n\t\t}\n\t}\n}\n\n/**\n * Spreads attributes onto a DOM element, taking into account the currently set attributes\n * @param {Element & ElementCSSInlineStyle} element\n * @param {Record | undefined} prev\n * @param {Record} next New attributes - this function mutates this object\n * @param {string} [css_hash]\n * @param {boolean} [should_remove_defaults]\n * @param {boolean} [skip_warning]\n * @returns {Record}\n */\nfunction set_attributes(\n\telement,\n\tprev,\n\tnext,\n\tcss_hash,\n\tshould_remove_defaults = false,\n\tskip_warning = false\n) {\n\tif (hydrating && should_remove_defaults && element.nodeName === INPUT_TAG) {\n\t\tif (!('defaultValue' in next || 'defaultChecked' in next)) {\n\t\t\tremove_input_defaults(/** @type {HTMLInputElement} */ (element));\n\t\t}\n\t}\n\n\tvar attributes = get_attributes(element);\n\n\tvar is_custom_element = attributes[IS_CUSTOM_ELEMENT];\n\tvar preserve_attribute_case = !attributes[IS_HTML];\n\n\t// If we're hydrating but the custom element is from Svelte, and it already scaffolded,\n\t// then it might run block logic in hydration mode, which we have to prevent.\n\tlet is_hydrating_custom_element = hydrating && is_custom_element;\n\tif (is_hydrating_custom_element) {\n\t\tset_hydrating(false);\n\t}\n\n\tvar current = prev || {};\n\tvar is_option_element = element.nodeName === OPTION_TAG;\n\tvar is_select_element = element.nodeName === SELECT_TAG;\n\n\ttry {\n\t\tfor (var key in prev) {\n\t\t\t// don't null our internal $$onX listeners\n\t\t\tif (!(key in next) && key[0] + key[1] !== '$$') {\n\t\t\t\tnext[key] = null;\n\t\t\t}\n\t\t}\n\n\t\tif (next.class) {\n\t\t\tnext.class = clsx(next.class);\n\t\t} else if (css_hash || next[CLASS]) {\n\t\t\tnext.class = null; /* force call to set_class() */\n\t\t}\n\n\t\tif (next[STYLE]) {\n\t\t\tnext.style ??= null; /* force call to set_style() */\n\t\t}\n\n\t\tvar setters = get_setters(element);\n\n\t\tif (\n\t\t\telement.nodeName === INPUT_TAG &&\n\t\t\t'type' in next &&\n\t\t\t('value' in next || '__value' in next)\n\t\t) {\n\t\t\tvar type = next.type;\n\n\t\t\tif (type !== current.type || (type === undefined && element.hasAttribute('type'))) {\n\t\t\t\tcurrent.type = type;\n\t\t\t\tset_attribute(element, 'type', type, skip_warning);\n\t\t\t}\n\t\t}\n\n\t\t// since key is captured we use const\n\t\tfor (const key in next) {\n\t\t\t// let instead of var because referenced in a closure\n\t\t\tlet value = next[key];\n\n\t\t\t// Up here because we want to do this for the initial value, too, even if it's undefined,\n\t\t\t// and this wouldn't be reached in case of undefined because of the equality check below\n\t\t\tif (is_option_element && key === 'value' && value == null) {\n\t\t\t\t// The