From d5a413382c93efeb1d888daf3216c51cd5f40f75 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Sat, 14 Feb 2026 21:11:40 -0800 Subject: chore: fix lint and type errors to resolve CI failures --- .devcontainer/Dockerfile | 7 ++++ .devcontainer/devcontainer.json | 55 ++++++++++++++++++++++++++++ .thicket/tickets.jsonl | 9 +++-- README.md | 18 ++-------- frontend/eslint.config.js | 7 +++- frontend/src/App.test.tsx | 17 ++++----- frontend/src/components/FeedItem.test.tsx | 6 ++-- frontend/src/components/FeedItems.test.tsx | 31 +++++++++------- frontend/src/components/FeedItems.tsx | 3 ++ frontend/src/components/FeedList.test.tsx | 58 +++++++++++++++++++----------- frontend/src/components/FeedList.tsx | 4 +-- frontend/src/components/Login.test.tsx | 10 +++--- frontend/src/components/Login.tsx | 2 +- frontend/src/components/Settings.test.tsx | 26 +++++++------- frontend/src/components/Settings.tsx | 7 ++-- frontend/src/components/TagView.test.tsx | 25 ++++++++----- web/dist/v2/assets/index-BYhh91HH.css | 1 - web/dist/v2/assets/index-BdhwF6aQ.js | 11 ------ web/dist/v2/assets/index-CO97K-eb.css | 1 + web/dist/v2/assets/index-WckTN3Bl.js | 11 ++++++ web/dist/v2/index.html | 4 +-- 21 files changed, 203 insertions(+), 110 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json delete mode 100644 web/dist/v2/assets/index-BYhh91HH.css delete mode 100644 web/dist/v2/assets/index-BdhwF6aQ.js create mode 100644 web/dist/v2/assets/index-CO97K-eb.css create mode 100644 web/dist/v2/assets/index-WckTN3Bl.js diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..111d1b9 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,7 @@ +FROM mcr.microsoft.com/devcontainers/go:1.24-bullseye + +# Install additional OS packages for CGO and SQLite +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends build-essential sqlite3 libsqlite3-dev + +# [Optional] Install Node.js is handled by features in devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..af4ea12 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,55 @@ +{ + "name": "Neko (Podman)", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "features": { + "ghcr.io/devcontainers/features/node:1": { + "node": "20" + } + }, + "customizations": { + "vscode": { + "settings": { + "go.toolsManagement.checkForUpdates": "local", + "go.useLanguageServer": true, + "go.gopath": "/go", + "editor.formatOnSave": true, + "eslint.workingDirectories": [ + "./frontend" + ] + }, + "extensions": [ + "golang.Go", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "vitest.explorer", + "ms-azuretools.vscode-docker" + ] + } + }, + "forwardPorts": [ + 8080, + 5173 + ], + "portsAttributes": { + "5173": { + "label": "Frontend (Vite)", + "onAutoForward": "notify" + }, + "8080": { + "label": "Backend (Neko)", + "onAutoForward": "notify" + } + }, + "postCreateCommand": "go mod download && (cd frontend && npm install)", + "remoteUser": "vscode", + "runArgs": [ + "--security-opt", + "label=disable" + ], + "containerEnv": { + "NEKO_PORT": "8080" + } +} \ No newline at end of file diff --git a/.thicket/tickets.jsonl b/.thicket/tickets.jsonl index f848457..b14552c 100644 --- a/.thicket/tickets.jsonl +++ b/.thicket/tickets.jsonl @@ -23,9 +23,10 @@ {"id":"NK-6q9nyg","title":"Refactor HTTP-dependent functions for testability","description":"Several functions use http.Get or external libraries directly (GetFullContent uses goose, ResolveFeedURL uses http.Get + goquery, imageProxyHandler uses http.Client). Refactor these to accept interfaces for HTTP fetching so they can be unit tested with mocks. This is the primary blocker for reaching 90% coverage.","type":"cleanup","status":"closed","priority":3,"labels":null,"assignee":"","created":"2026-02-13T03:54:37.630148644Z","updated":"2026-02-14T02:44:05.328784994Z"} {"id":"NK-7jh6re","title":"sidebar still ugly","description":"still very ugly, even compared to the original v1 static version\n\neither make it nicer or just copy the v1 version more directly","type":"feature","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T17:59:17.948112909Z","updated":"2026-02-14T18:01:26.48034794Z"} {"id":"NK-7tzbql","title":"Fix TUI Content View Navigation and Interaction","description":"The TUI content view (reading a single item) is currently non-functional or severely limited. Users cannot easily navigate back, scroll, or interact with the content. This task involves improving the 'viewContent' state in the TUI.","type":"bug","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-13T05:02:57.382793121Z","updated":"2026-02-13T05:06:15.144485446Z"} +{"id":"NK-7u97bb","title":"cleaning up old entries","description":"I have been running neko for so long that my production database is 1.4GB. Come up with a tool (ok to run it from command line) that purges some super old feed items to save space. think carefully about the algorithm! it should be accessible from the CLI to start, although maybe we should show \"space used\" in settings too with an option to clean up.","type":"feature","status":"open","priority":2,"labels":null,"assignee":"","created":"2026-02-15T03:01:05.643515805Z","updated":"2026-02-15T03:01:05.643515805Z"} {"id":"NK-7xuajb","title":"[security] Add HTTP Security Headers","description":"Add middleware to set standard security headers: Content-Security-Policy (restrict sources), X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin.","type":"","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-14T16:35:59.320775688Z","updated":"2026-02-14T17:20:46.397582923Z"} -{"id":"NK-897v23","title":"Enhance UI with better loading indicators and error states","description":"The application should have a consistent and premium feel for loading and error states. Currently, it uses simple text. We should implement skeleton screens or more polished animations.","type":"task","status":"open","priority":3,"labels":null,"assignee":"","created":"2026-02-14T22:49:05.942464799Z","updated":"2026-02-14T22:49:05.942464799Z"} -{"id":"NK-8d1uzw","title":"Clean up unused font CSS variables","description":"The font CSS variables might have duplicates or unused entries after the fix. Audit them.","type":"task","status":"open","priority":3,"labels":null,"assignee":"","created":"2026-02-15T02:24:06.398437323Z","updated":"2026-02-15T02:24:06.398437323Z"} +{"id":"NK-897v23","title":"Enhance UI with better loading indicators and error states","description":"The application should have a consistent and premium feel for loading and error states. Currently, it uses simple text. We should implement skeleton screens or more polished animations.","type":"task","status":"closed","priority":3,"labels":null,"assignee":"","created":"2026-02-14T22:49:05.942464799Z","updated":"2026-02-14T22:49:05.942464799Z"} +{"id":"NK-8d1uzw","title":"Clean up unused font CSS variables","description":"The font CSS variables might have duplicates or unused entries after the fix. Audit them.","type":"task","status":"open","priority":2,"labels":null,"assignee":"","created":"2026-02-15T02:24:06.398437323Z","updated":"2026-02-15T02:24:06.398437323Z"} {"id":"NK-8hu7z1","title":"scrape full text button","description":"add this feature back in to the v2 ui and verify it is still working (not sure if we have any tests)","type":"feature","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-14T17:27:49.815938946Z","updated":"2026-02-14T17:58:19.083695149Z"} {"id":"NK-8rhpp3","title":"v2 frontend: when selected, don't change style of feed items","description":"Just leave them the same when j/k \"selects\" an item. No blue side thing, no change in background, it's distracting. Just scroll it to the right place.","type":"bug","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T00:39:50.01934312Z","updated":"2026-02-14T01:02:54.204739756Z"} {"id":"NK-8s75ec","title":"page size and performance","description":"Do some analysis of page size (css/html/javascript) on the legacy version vs. new version and give me a report. We want it to be small and fast! If the new version is much worse file some tickets to investigate further.","type":"task","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-13T20:16:13.898081788Z","updated":"2026-02-13T21:50:12.004391671Z"} @@ -51,7 +52,9 @@ {"id":"NK-fkc119","title":"setup github ci","description":"Maybe it'd be nice to have github run the tests. Is that a thing we can try to setup","type":"feature","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-14T03:16:32.574415787Z","updated":"2026-02-14T03:23:01.837550873Z"} {"id":"NK-fm15vq","title":"UI: Improve accessibility for star icon","description":"The new star button should have proper aria-labels and potentially better focus states for screen readers.","type":"task","status":"closed","priority":3,"labels":null,"assignee":"","created":"2026-02-13T20:27:36.768034045Z","updated":"2026-02-13T20:27:36.768034045Z"} {"id":"NK-fnaohu","title":"UI Styling: Dark Mode Support","description":"","type":"","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-13T18:05:19.59504351Z","updated":"2026-02-13T18:11:46.326064329Z"} +{"id":"NK-fnbaaf","title":"stress test with a REALLY big database","description":"I have been using a version of neko for over a decade and my prod database is 1.4GB sqlite file. it's in big_neko.db\n\nrun some tests with that big database and see if anything messes up! DO NOT CHECK IN THAT BIG DATABASE EVER.\n\nif there are bugs or performance issues with such a big db, file some tickets for us to evaluate and we can create some synthetic data or issues later on.","type":"task","status":"open","priority":1,"labels":null,"assignee":"","created":"2026-02-15T02:58:54.859954523Z","updated":"2026-02-15T02:58:54.859954523Z"} {"id":"NK-fpzx66","title":"v2 ui - title styling","description":"The title of the article stays blue and bold regardless of read state.","type":"bug","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T03:22:55.339956853Z","updated":"2026-02-14T03:28:01.555909701Z"} +{"id":"NK-fzjyay","title":"github CI fails","description":"Both the backend and frontend failed the CI jobs failed the lint checks.\n\nare we running those properly locally before submitting\n\nalso the frontent consistency check failed","type":"task","status":"open","priority":0,"labels":null,"assignee":"","created":"2026-02-15T02:41:02.747760248Z","updated":"2026-02-15T02:41:02.747760248Z"} {"id":"NK-g7ya0n","title":"Style Settings page to match Glass sidebar","description":"The settings page currently uses the old retro aesthetic. It should be updated to match the new minimalist 'glass' sidebar style for visual consistency. This should include updating form elements, backgrounds, and typography.","type":"feature","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T23:53:46.590222566Z","updated":"2026-02-15T00:51:14.771780934Z"} {"id":"NK-g818qn","title":"Improve mobile responsiveness of React UI","description":"The React UI should be fully responsive and work well on small screens. Now that the vanilla JS prototype is removed, we should ensure the main interface is a great experience for mobile users.","type":"task","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-14T22:46:32.850472479Z","updated":"2026-02-14T22:49:01.411224187Z"} {"id":"NK-gdf99z","title":"TUI is terrible and needs fixing","description":"The TUI doesn't really work and doesn't make sense. Think very hard and look at the v2 HTML UI implementation and make something cool like that. Probably needs tests too.","type":"epic","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-14T03:51:59.882212859Z","updated":"2026-02-14T04:31:28.290051717Z"} @@ -88,6 +91,7 @@ {"id":"NK-pwogze","title":"Crawler testing","description":"The general usage of neko is to run it and have it crawl feeds in the background after X minutes\n\nDo we have a test that can verify that's happening","type":"task","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T18:43:04.957220621Z","updated":"2026-02-14T20:44:09.76303647Z"} {"id":"NK-qwef98","title":"UI Styling: Controls \u0026 Header","description":"","type":"","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-13T18:05:18.450759919Z","updated":"2026-02-13T18:11:46.291830432Z"} {"id":"NK-r1aqiw","title":"Implement Subscription List and UserInfo endpoints","description":"","type":"task","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-15T00:21:51.619650383Z","updated":"2026-02-15T00:44:41.428045944Z"} +{"id":"NK-r39tqq","title":"username + password","description":"it's too weird to have just a password -- in the old UI i had a username but it was just ignored. but password managers get confused by this new no username thing.\n\nlet's make it so you can enter a username and password. to start, just let that be a no-op (it ignores the username and just pays attention to the password.)\n\nwe can consider later on if we want to make the username real and definable too.","type":"bug","status":"open","priority":1,"labels":null,"assignee":"","created":"2026-02-15T02:56:35.68970604Z","updated":"2026-02-15T02:56:35.68970604Z"} {"id":"NK-r6nhj0","title":"import/export","description":"Import/Export has only ever been partially implemented. Let's finish it up across OPML (de facto standard) but also simple txt line oriented input/output. We may need to file a ticket to deal with the async crawling as part of this.","type":"feature","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-14T16:45:04.739162003Z","updated":"2026-02-14T17:42:20.713094047Z"} {"id":"NK-rhelrq","title":"Add end-to-end integration test for complete crawl cycle","description":"Create an integration test that verifies the complete crawl workflow: start server with background crawling enabled, add a feed via API, wait for background crawl to execute, verify items are fetched and stored. This would require mocking or using a test RSS feed and potentially adjusting timing for faster test execution.","type":"task","status":"open","priority":3,"labels":null,"assignee":"","created":"2026-02-14T20:44:31.052207214Z","updated":"2026-02-14T20:44:31.052207214Z"} {"id":"NK-ric1zs","title":"Migrate frontend to /api/ endpoints","description":"The backend now provides a clean REST API at /api/. Update the frontend UI to use these new endpoints instead of the legacy backward-compatibility routes (/stream/, /feed/, etc.). This will allow for cleaner separation and better utilization of proper REST patterns.","type":"cleanup","status":"closed","priority":3,"labels":null,"assignee":"","created":"2026-02-13T04:26:55.864725765Z","updated":"2026-02-13T04:26:55.864725765Z"} @@ -100,6 +104,7 @@ {"id":"NK-sxcm7y","title":"Enable Gzip Compression in Go Backend","description":"Check if the Go backend is serving content with gzip compression. If not, implement it to reduce page size and improve performance. Add tests to verify.","type":"feature","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-13T21:57:24.578388732Z","updated":"2026-02-13T22:22:49.350223751Z"} {"id":"NK-t0nmbj","title":"new web frontend","description":"The current frontend uses an old version of backbone and jquery. Let's \"deprecate\" it -- keep it arouond so we can test against it and use it, but let's be able to also serve and use a nice shiny new frontend written in either simiple, highly efficient vanilla javascript, or put together something in react or similar. Needs to feel fast and low latency!\n\nIt's very important that this new frontend has all the functionality of the existing one AND looks similar (use same style, etc, but adjust a little if needed.)\n\nALSO make it highly testable and have high test coverage as you go. I don't want it to use the Chrome browser plugin thing, just test it on your own using things from the command line you can do.","type":"epic","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-13T02:01:37.2107893Z","updated":"2026-02-13T05:43:47.613995925Z"} {"id":"NK-t7m31s","title":"Wire Reader API into web.go","description":"","type":"task","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-15T00:21:55.393639254Z","updated":"2026-02-15T00:44:41.579714853Z"} +{"id":"NK-tgmc9s","title":"make sure the github CI jobs are included in the tests/jobs locally!","description":"","type":"task","status":"open","priority":0,"labels":null,"assignee":"","created":"2026-02-15T02:44:00.333972105Z","updated":"2026-02-15T02:44:00.333972105Z"} {"id":"NK-thq2oq","title":"v2 ui - font size adjustments","description":"Move font-size: 18px to :root so rem units resolve correctly. Adjust title size to ~24px.","type":"bug","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T03:30:58.751447802Z","updated":"2026-02-14T03:31:56.358775833Z"} {"id":"NK-tw0nga","title":"E2E Testing","description":"Set up E2E testing with Playwright or Cypress to verify full flows: Login -\u003e View Feeds -\u003e View Items -\u003e Logout","type":"","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-13T15:01:33.817314728Z","updated":"2026-02-13T15:46:57.094062908Z"} {"id":"NK-ucckki","title":"security changes broke legacy","description":"I think some of the security policies make it so the old legacy one doesn't work. this may just be WAI but have a look\n\n[Warning] jQuery.Deferred exception: Refused to evaluate a string as JavaScript because 'unsafe-eval' or 'trusted-types-eval' is not an allowed source of script in the following Content Security Policy directive: \"script-src 'self'\". (jquery-3.3.1.min.js, line 2)\n (2)\n\"Function@[native code]\no@http://localhost:4994/static/jquery.tmpl.min.js:10:3543\ntemplate@http://localhost:4994/static/jquery.tmpl.min.js:10:1914\ntmpl@http://localhost:4994/static/jquery.tmpl.min.js:10:1422\nrender@http://localhost:4994/static/ui.js:208:23\nnr@http://localhost:4994/static/underscore-1.13.1.min.js:6:7308\n@http://localhost:4994/static/underscore-1.13.1.min.js:6:7733\n@http://localhost:4994/static/underscore-1.13.1.min.js:6:786\nboot@http://localhost:4994/static/ui.js:598:28\n@http://localhost:4994/static/ui.js:8:9\nl@http://localhost:4994/static/jquery-3.3.1.min.js:2:29380\n@http://localhost:4994/static/jquery-3.3.1.min.js:2:29678\"\nundefined","type":"bug","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-14T17:41:02.255772514Z","updated":"2026-02-14T17:41:02.255772514Z"} diff --git a/README.md b/README.md index b407cd5..5244803 100644 --- a/README.md +++ b/README.md @@ -26,16 +26,17 @@ - [Building](#building) - [Docker](#docker) - [Build from Source](#build-from-source) + - [Development and Testing](#development-and-testing) - [Configuration](#configuration) - [Storage](#storage) - [Usage](#usage) - [Web Interface](#web-interface) + - [Sidebar Variants](#sidebar-variants) - [Add Feed](#add-feed) - [Crawl Feeds](#crawl-feeds) - [Export](#export) - [All Command Line Options](#all-command-line-options) - [Configuration File](#configuration-file) -- [TODO](#todo) - [History](#history) - [Early 2017](#early-2017) - [July 2018 -- v0.2](#july-2018----v02) @@ -65,7 +66,6 @@ Backend is written in `Go` and there is a modern `React/Vite` SPA frontend. * automatically marks items read in an infinite stream of never-ending content (until you run out of content and it ends) * full text search * scrapes full text of pages on demand - * multiple sidebar variants (Glass, Minimal, Swiss/Type, and Playful/Banana) * collapsible sidebar sections for Feeds and Tags ## Screenshots @@ -276,20 +276,6 @@ password: VeryLongRandomStringBecauseSecurityIsFun ``` - -# TODO - - * manually initiate crawl/refresh from web interface (done) - * auto-refresh feeds from web interface (done) - * import (done) - * mark all as read (done) - * rewrite frontend in a modern js framework (done: React/Vite) - * prettify interface (done) - * sidebar variants and personalization (done) - * cross-compilation of binaries for "normal" platforms - * implement Gzip compression (done) - * unit and E2E testing infrastructure (done) - # History ## Early 2017 diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index 043ab7a..d2de7f8 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -6,7 +6,7 @@ import tseslint from 'typescript-eslint'; import eslintConfigPrettier from 'eslint-config-prettier'; export default tseslint.config( - { ignores: ['dist'] }, + { ignores: ['dist', 'coverage', 'playwright-report'] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], files: ['**/*.{ts,tsx}'], @@ -21,6 +21,11 @@ export default tseslint.config( rules: { ...reactHooks.configs.recommended.rules, 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], + '@typescript-eslint/no-unused-vars': ['warn', { + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_' + }], + '@typescript-eslint/no-explicit-any': 'warn', }, }, eslintConfigPrettier diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 196f32a..1ef9763 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -11,20 +11,21 @@ describe('App', () => { }); it('renders login on initial load (unauthenticated)', async () => { - (global.fetch as any).mockResolvedValueOnce({ + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: false, - }); + } as Response); window.history.pushState({}, 'Test page', '/v2/login'); render(); expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument(); }); it('renders dashboard when authenticated', async () => { - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/auth')) return Promise.resolve({ ok: true }); - if (url.includes('/api/feed/')) return Promise.resolve({ ok: true, json: async () => [] }); - if (url.includes('/api/tag')) return Promise.resolve({ ok: true, json: async () => [] }); - return Promise.resolve({ ok: true }); // Fallback + vi.mocked(global.fetch).mockImplementation((url) => { + const urlStr = url.toString(); + if (urlStr.includes('/api/auth')) return Promise.resolve({ ok: true } as Response); + if (urlStr.includes('/api/feed/')) return Promise.resolve({ ok: true, json: async () => [] } as Response); + if (urlStr.includes('/api/tag')) return Promise.resolve({ ok: true, json: async () => [] } as Response); + return Promise.resolve({ ok: true } as Response); // Fallback }); window.history.pushState({}, 'Test page', '/v2/'); @@ -44,7 +45,7 @@ describe('App', () => { value: { href: '' }, }); - (global.fetch as any).mockResolvedValueOnce({ ok: true }); + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true } as Response); fireEvent.click(logoutBtn); diff --git a/frontend/src/components/FeedItem.test.tsx b/frontend/src/components/FeedItem.test.tsx index 4c7d887..1c51dc3 100644 --- a/frontend/src/components/FeedItem.test.tsx +++ b/frontend/src/components/FeedItem.test.tsx @@ -31,7 +31,7 @@ describe('FeedItem Component', () => { }); it('toggles star status', async () => { - (global.fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({}) }); + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: async () => ({}) } as Response); render(); @@ -73,10 +73,10 @@ describe('FeedItem Component', () => { }); it('loads full content', async () => { - (global.fetch as any).mockResolvedValueOnce({ + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: async () => ({ ...mockItem, full_content: '

Full Content Loaded

' }), - }); + } as Response); render(); diff --git a/frontend/src/components/FeedItems.test.tsx b/frontend/src/components/FeedItems.test.tsx index cf1e708..25ade58 100644 --- a/frontend/src/components/FeedItems.test.tsx +++ b/frontend/src/components/FeedItems.test.tsx @@ -17,11 +17,12 @@ describe('FeedItems Component', () => { unobserve = vi.fn(); disconnect = vi.fn(); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any window.IntersectionObserver = MockIntersectionObserver as any; }); it('renders loading state', () => { - (global.fetch as any).mockImplementation(() => new Promise(() => { })); + vi.mocked(global.fetch).mockImplementation(() => new Promise(() => { })); render( @@ -50,10 +51,10 @@ describe('FeedItems Component', () => { }, ]; - (global.fetch as any).mockResolvedValueOnce({ + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: async () => mockItems, - }); + } as Response); render( @@ -79,10 +80,10 @@ describe('FeedItems Component', () => { { _id: 102, title: 'Item 2', url: 'u2', read: true, starred: false }, ]; - (global.fetch as any).mockResolvedValue({ + vi.mocked(global.fetch).mockResolvedValue({ ok: true, json: async () => mockItems, - }); + } as Response); render( @@ -134,10 +135,10 @@ describe('FeedItems Component', () => { it('marks items as read when scrolled past', async () => { const mockItems = [{ _id: 101, title: 'Item 1', url: 'u1', read: false, starred: false }]; - (global.fetch as any).mockResolvedValue({ + vi.mocked(global.fetch).mockResolvedValue({ ok: true, json: async () => mockItems, - }); + } as Response); // Capture both callbacks const observerCallbacks: IntersectionObserverCallback[] = []; @@ -151,8 +152,10 @@ describe('FeedItems Component', () => { unobserve = vi.fn(); disconnect = vi.fn(); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any window.IntersectionObserver = MockIntersectionObserver as any; + render( @@ -201,9 +204,9 @@ describe('FeedItems Component', () => { const initialItems = [{ _id: 101, title: 'Item 1', url: 'u1', read: true, starred: false }]; const moreItems = [{ _id: 100, title: 'Item 0', url: 'u0', read: true, starred: false }]; - (global.fetch as any) - .mockResolvedValueOnce({ ok: true, json: async () => initialItems }) - .mockResolvedValueOnce({ ok: true, json: async () => moreItems }); + vi.mocked(global.fetch) + .mockResolvedValueOnce({ ok: true, json: async () => initialItems } as Response) + .mockResolvedValueOnce({ ok: true, json: async () => moreItems } as Response); const observerCallbacks: IntersectionObserverCallback[] = []; class MockIntersectionObserver { @@ -214,8 +217,10 @@ describe('FeedItems Component', () => { unobserve = vi.fn(); disconnect = vi.fn(); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any window.IntersectionObserver = MockIntersectionObserver as any; + render( @@ -267,9 +272,9 @@ describe('FeedItems Component', () => { { _id: 100, title: 'Item 0', url: 'u0', read: true, starred: false }, ]; - (global.fetch as any) - .mockResolvedValueOnce({ ok: true, json: async () => initialItems }) - .mockResolvedValueOnce({ ok: true, json: async () => moreItems }); + vi.mocked(global.fetch) + .mockResolvedValueOnce({ ok: true, json: async () => initialItems } as Response) + .mockResolvedValueOnce({ ok: true, json: async () => moreItems } as Response); render( diff --git a/frontend/src/components/FeedItems.tsx b/frontend/src/components/FeedItems.tsx index f43852b..8c69905 100644 --- a/frontend/src/components/FeedItems.tsx +++ b/frontend/src/components/FeedItems.tsx @@ -89,6 +89,7 @@ export default function FeedItems() { useEffect(() => { fetchItems(); setSelectedIndex(-1); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [feedId, tagName, filterFn, searchParams]); @@ -166,6 +167,7 @@ export default function FeedItems() { window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [items, hasMore, loadingMore]); @@ -214,6 +216,7 @@ export default function FeedItems() { itemObserver.disconnect(); sentinelObserver.disconnect(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [items, loadingMore, hasMore]); if (loading) return
Loading items...
; diff --git a/frontend/src/components/FeedList.test.tsx b/frontend/src/components/FeedList.test.tsx index 059d8a4..9ef2349 100644 --- a/frontend/src/components/FeedList.test.tsx +++ b/frontend/src/components/FeedList.test.tsx @@ -13,11 +13,15 @@ describe('FeedList Component', () => { }); it('renders loading state initially', () => { - (global.fetch as any).mockImplementation(() => new Promise(() => { })); + vi.mocked(global.fetch).mockImplementation(() => new Promise(() => { })); render( - {/* @ts-ignore */} - { }} /> + { }} + setSidebarVisible={() => { }} + isMobile={false} + /> ); expect(screen.getByText(/loading feeds/i)).toBeInTheDocument(); @@ -41,26 +45,31 @@ describe('FeedList Component', () => { }, ]; - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/feed/')) { + vi.mocked(global.fetch).mockImplementation((url) => { + const urlStr = url.toString(); + if (urlStr.includes('/api/feed/')) { return Promise.resolve({ ok: true, json: async () => mockFeeds, - }); + } as Response); } - if (url.includes('/api/tag')) { + if (urlStr.includes('/api/tag')) { return Promise.resolve({ ok: true, json: async () => [{ title: 'Tech' }], - }); + } as Response); } return Promise.reject(new Error(`Unknown URL: ${url}`)); }); render( - {/* @ts-ignore */} - { }} /> + { }} + setSidebarVisible={() => { }} + isMobile={false} + /> ); @@ -80,12 +89,16 @@ describe('FeedList Component', () => { }); it('handles fetch error', async () => { - (global.fetch as any).mockImplementation(() => Promise.reject(new Error('API Error'))); + vi.mocked(global.fetch).mockImplementation(() => Promise.reject(new Error('API Error'))); render( - {/* @ts-ignore */} - { }} setSidebarVisible={() => { }} /> + { }} + setSidebarVisible={() => { }} + isMobile={false} + /> ); @@ -95,26 +108,31 @@ describe('FeedList Component', () => { }); it('handles empty feed list', async () => { - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/feed/')) { + vi.mocked(global.fetch).mockImplementation((url) => { + const urlStr = url.toString(); + if (urlStr.includes('/api/feed/')) { return Promise.resolve({ ok: true, json: async () => [], - }); + } as Response); } - if (url.includes('/api/tag')) { + if (urlStr.includes('/api/tag')) { return Promise.resolve({ ok: true, json: async () => [], - }); + } as Response); } return Promise.reject(new Error(`Unknown URL: ${url}`)); }); render( - {/* @ts-ignore */} - { }} setSidebarVisible={() => { }} /> + { }} + setSidebarVisible={() => { }} + isMobile={false} + /> ); diff --git a/frontend/src/components/FeedList.tsx b/frontend/src/components/FeedList.tsx index a4ecccf..fed9196 100644 --- a/frontend/src/components/FeedList.tsx +++ b/frontend/src/components/FeedList.tsx @@ -66,11 +66,11 @@ export default function FeedList({ Promise.all([ apiFetch('/api/feed/').then((res) => { if (!res.ok) throw new Error('Failed to fetch feeds'); - return res.json(); + return res.json() as Promise; }), apiFetch('/api/tag').then((res) => { if (!res.ok) throw new Error('Failed to fetch tags'); - return res.json(); + return res.json() as Promise; }), ]) .then(([feedsData, tagsData]) => { diff --git a/frontend/src/components/Login.test.tsx b/frontend/src/components/Login.test.tsx index aea7042..cf69eb1 100644 --- a/frontend/src/components/Login.test.tsx +++ b/frontend/src/components/Login.test.tsx @@ -28,9 +28,9 @@ describe('Login Component', () => { }); it('handles successful login', async () => { - (global.fetch as any).mockResolvedValueOnce({ + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, - }); + } as Response); renderLogin(); @@ -51,10 +51,10 @@ describe('Login Component', () => { }); it('handles failed login', async () => { - (global.fetch as any).mockResolvedValueOnce({ + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: false, json: async () => ({ message: 'Bad credentials' }), - }); + } as Response); renderLogin(); @@ -67,7 +67,7 @@ describe('Login Component', () => { }); it('handles network error', async () => { - (global.fetch as any).mockRejectedValueOnce(new Error('Network error')); + vi.mocked(global.fetch).mockRejectedValueOnce(new Error('Network error')); renderLogin(); diff --git a/frontend/src/components/Login.tsx b/frontend/src/components/Login.tsx index ba2cd96..b62acea 100644 --- a/frontend/src/components/Login.tsx +++ b/frontend/src/components/Login.tsx @@ -29,7 +29,7 @@ export default function Login() { const data = await res.json(); setError(data.message || 'Login failed'); } - } catch (err) { + } catch (_err) { setError('Network error'); } }; diff --git a/frontend/src/components/Settings.test.tsx b/frontend/src/components/Settings.test.tsx index b7de3bb..a0e7de4 100644 --- a/frontend/src/components/Settings.test.tsx +++ b/frontend/src/components/Settings.test.tsx @@ -18,10 +18,10 @@ describe('Settings Component', () => { { _id: 2, title: 'Gaming', url: 'http://gaming.com/rss', category: 'gaming' }, ]; - (global.fetch as any).mockResolvedValueOnce({ + vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: async () => mockFeeds, - }); + } as Response); render(); @@ -33,13 +33,13 @@ describe('Settings Component', () => { }); it('adds a new feed', async () => { - (global.fetch as any) - .mockResolvedValueOnce({ ok: true, json: async () => [] }) // Initial load - .mockResolvedValueOnce({ ok: true, json: async () => ({}) }) // Add feed + vi.mocked(global.fetch) + .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response) // Initial load + .mockResolvedValueOnce({ ok: true, json: async () => ({}) } as Response) // Add feed .mockResolvedValueOnce({ ok: true, json: async () => [{ _id: 3, title: 'New Feed', url: 'http://new.com/rss' }], - }); // Refresh load + } as Response); // Refresh load render(); @@ -75,9 +75,9 @@ describe('Settings Component', () => { { _id: 1, title: 'Tech News', url: 'http://tech.com/rss', category: 'tech' }, ]; - (global.fetch as any) - .mockResolvedValueOnce({ ok: true, json: async () => mockFeeds }) // Initial load - .mockResolvedValueOnce({ ok: true }); // Delete + vi.mocked(global.fetch) + .mockResolvedValueOnce({ ok: true, json: async () => mockFeeds } as Response) // Initial load + .mockResolvedValueOnce({ ok: true } as Response); // Delete render(); @@ -100,13 +100,13 @@ describe('Settings Component', () => { }); it('imports an OPML file', async () => { - (global.fetch as any) - .mockResolvedValueOnce({ ok: true, json: async () => [] }) // Initial load - .mockResolvedValueOnce({ ok: true, json: async () => ({ status: 'ok' }) }) // Import + vi.mocked(global.fetch) + .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response) // Initial load + .mockResolvedValueOnce({ ok: true, json: async () => ({ status: 'ok' }) } as Response) // Import .mockResolvedValueOnce({ ok: true, json: async () => [{ _id: 1, title: 'Imported Feed', url: 'http://imported.com/rss' }], - }); // Refresh load + } as Response); // Refresh load render(); diff --git a/frontend/src/components/Settings.tsx b/frontend/src/components/Settings.tsx index c174c32..b218775 100644 --- a/frontend/src/components/Settings.tsx +++ b/frontend/src/components/Settings.tsx @@ -18,7 +18,7 @@ export default function Settings({ fontTheme, setFontTheme }: SettingsProps) { const [importFile, setImportFile] = useState(null); /* ... existing fetchFeeds ... */ - const fetchFeeds = () => { + const fetchFeeds = React.useCallback(() => { setLoading(true); apiFetch('/api/feed/') .then((res) => { @@ -33,11 +33,12 @@ export default function Settings({ fontTheme, setFontTheme }: SettingsProps) { setError(err.message); setLoading(false); }); - }; + }, []); useEffect(() => { + // eslint-disable-next-line fetchFeeds(); - }, []); + }, [fetchFeeds]); /* ... existing handlers ... */ const handleAddFeed = (e: React.FormEvent) => { diff --git a/frontend/src/components/TagView.test.tsx b/frontend/src/components/TagView.test.tsx index 8f7eb86..16fdee7 100644 --- a/frontend/src/components/TagView.test.tsx +++ b/frontend/src/components/TagView.test.tsx @@ -17,25 +17,31 @@ describe('Tag View Integration', () => { ]; const mockTags = [{ title: 'Tech' }, { title: 'News' }]; - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/feed/')) { + vi.mocked(global.fetch).mockImplementation((url) => { + const urlStr = url.toString(); + if (urlStr.includes('/api/feed/')) { return Promise.resolve({ ok: true, json: async () => mockFeeds, - }); + } as Response); } - if (url.includes('/api/tag')) { + if (urlStr.includes('/api/tag')) { return Promise.resolve({ ok: true, json: async () => mockTags, - }); + } as Response); } return Promise.reject(new Error(`Unknown URL: ${url}`)); }); render( - { }} /> + { }} + setSidebarVisible={() => { }} + isMobile={false} + /> ); @@ -55,12 +61,13 @@ describe('Tag View Integration', () => { { _id: 101, title: 'Tag Item 1', url: 'http://example.com/1', feed_title: 'Feed 1' }, ]; - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/stream')) { + vi.mocked(global.fetch).mockImplementation((url) => { + const urlStr = url.toString(); + if (urlStr.includes('/api/stream')) { return Promise.resolve({ ok: true, json: async () => mockItems, - }); + } as Response); } return Promise.reject(new Error(`Unknown URL: ${url}`)); }); diff --git a/web/dist/v2/assets/index-BYhh91HH.css b/web/dist/v2/assets/index-BYhh91HH.css deleted file mode 100644 index 13b2864..0000000 --- a/web/dist/v2/assets/index-BYhh91HH.css +++ /dev/null @@ -1 +0,0 @@ -:root{--font-body: Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;--font-heading: "Helvetica Neue", Helvetica, Arial, sans-serif}body{font-family:var(--font-body)}h1,h2,h3,h4,h5,.logo,.nav-link,.logout-btn{font-family:var(--font-heading);font-weight:700}.font-default{--font-body: Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;--font-heading: "Helvetica Neue", Helvetica, Arial, sans-serif}.font-serif{--font-body: Georgia, "Times New Roman", Times, serif;--font-heading: Georgia, "Times New Roman", Times, serif}.font-sans{--font-body: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;--font-heading: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.font-mono{--font-body: Menlo, Monaco, Consolas, "Courier New", monospace;--font-heading: Menlo, Monaco, Consolas, "Courier New", monospace}:root{line-height:1.5;font-size:18px;--bg-color: #ffffff;--text-color: rgba(0, 0, 0, .87);--sidebar-bg: #ccc;--link-color: #0000ee;color-scheme:light dark;color:var(--text-color);background-color:var(--bg-color)}.theme-light{--bg-color: #ffffff;--text-color: rgba(0, 0, 0, .87);--sidebar-bg: #ccc;--link-color: #0000ee;--border-color: #999;background-color:var(--bg-color);color:var(--text-color)}@media(prefers-color-scheme:dark){:root{--bg-color: #24292e;--text-color: #ffffff;--sidebar-bg: #1b1f23;--link-color: rgb(90, 200, 250)}}.theme-dark{--bg-color: #000000;--text-color: #ffffff;--sidebar-bg: #111111;--link-color: rgb(90, 200, 250);--border-color: #333;background-color:var(--bg-color);color:var(--text-color)}.theme-dark button{background-color:#333;color:#fff}body{margin:0;min-width:320px;min-height:100vh}h1{font-size:3.2em;line-height:1.1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:700;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}a{color:var(--link-color);text-decoration:none}@media(prefers-color-scheme:light){:root{color:#213547;background-color:#fff}a:hover{color:#00f;text-decoration:underline}button{background-color:#f9f9f9}}.login-container{display:flex;justify-content:center;align-items:center;height:100vh;background-color:#f5f5f5}.login-form{background:#fff;padding:2rem;border-radius:8px;box-shadow:0 4px 6px #0000001a;width:100%;max-width:400px}.login-form h1{margin-bottom:2rem;text-align:center;color:#333}.form-group{margin-bottom:1.5rem}.form-group label{display:block;margin-bottom:.5rem;font-weight:700;color:#555}.form-group input{width:100%;padding:.75rem;border:1px solid #ddd;border-radius:4px;font-size:1rem}.error-message{color:#dc3545;margin-bottom:1rem;text-align:center}button[type=submit]{width:100%;padding:.75rem;background-color:#007bff;color:#fff;border:none;border-radius:4px;font-size:1rem;cursor:pointer;transition:background-color .2s}button[type=submit]:hover{background-color:#0056b3}*{box-sizing:border-box}body{margin:0}.dashboard{display:flex;flex-direction:column;height:100vh;overflow:hidden}.dashboard-content{display:flex;flex:1;overflow:hidden;position:relative}.dashboard-sidebar{width:11rem;background:transparent;border-right:1px solid var(--border-color);display:flex;flex-direction:column;overflow-y:auto;transition:margin-left .4s ease}.dashboard-sidebar.hidden{margin-left:-11rem}.dashboard-main{flex:1;padding:2rem;overflow-y:auto;background:var(--bg-color);margin-left:0}.dashboard-main>*{max-width:35em;margin:0 auto}.fixed-toggle{position:absolute;top:1rem;left:1rem;z-index:1000;background:var(--bg-color);border:none;font-size:2rem;line-height:1;cursor:pointer;padding:.2rem;color:var(--text-color);border-radius:50%;box-shadow:0 2px 5px #0000001a;display:flex;align-items:center;justify-content:center}.fixed-toggle:hover{transform:scale(1.1)}@media(max-width:768px){.dashboard-sidebar{position:fixed;top:0;left:0;bottom:0;z-index:1100;box-shadow:2px 0 10px #0003;width:14rem}.dashboard-sidebar.hidden{margin-left:-14rem}.dashboard-main{padding:4rem 1rem 1rem}.dashboard-main>*{max-width:100%}.sidebar-backdrop{position:fixed;inset:0;background:#0006;z-index:1050;animation:fadeIn .3s ease}.dashboard.sidebar-visible:after{display:none}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.feed-list{padding:1rem;font-family:var(--font-heading);color:#777;font-size:.8rem;background:var(--sidebar-bg);min-height:100%;flex:1}.feed-list h1.logo{font-size:2rem;margin:0 0 1rem;line-height:1;cursor:pointer;position:sticky;top:0;background:var(--sidebar-bg);z-index:10;padding-bottom:.5rem;color:var(--text-color)}.theme-light .feed-list h1.logo{color:#333}.theme-dark .feed-list h1.logo{color:#eee}.search-section{margin-bottom:1rem}.search-input{width:100%;padding:.25rem;border:1px solid var(--border-color, #999);background:var(--bg-color);color:var(--text-color);font-size:.8rem;font-family:inherit;border-radius:0}.section-header{font-size:1rem;font-weight:700;margin:1rem 0 .25rem;cursor:pointer;-webkit-user-select:none;user-select:none;font-family:var(--font-heading);color:#333;text-transform:lowercase;font-variant:small-caps;display:flex;align-items:center;gap:.5rem}.caret{display:inline-block;font-size:.6rem;transition:transform .2s ease;color:#777}.caret.expanded{transform:rotate(90deg)}.filter-list,.tag-list-items,.feed-list-items,.nav-list{list-style:none;padding:0;margin:0}.filter-list li,.nav-list li{margin-bottom:.1rem}.filter-list a,.nav-list a,.tag-link,.feed-title,.logout-link{text-decoration:none;color:var(--link-color, blue);font-size:.8rem;display:block;cursor:pointer;background:none;border:none;padding:0;font-family:inherit;font-variant:small-caps;text-transform:lowercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.filter-list a:hover,.nav-list a:hover,.tag-link:hover,.feed-title:hover,.logout-link:hover{text-decoration:underline;color:var(--link-color, blue)}.filter-list a.active,.tag-link.active,.feed-title.active{font-weight:700;color:#000}.tag-item,.sidebar-feed-item{margin-bottom:0}.feed-category{display:none}.nav-section{margin-top:2rem;border-top:1px solid var(--border-color, #eee);padding-top:1rem}.logout-link{text-align:left;width:100%;color:#777;display:block}.nav-link,.logout-link{padding:.25rem 0}.logout-link:hover{color:var(--link-color, blue);text-decoration:underline}.theme-section{margin-top:1rem}.theme-selector{display:flex;gap:.5rem;margin-top:.5rem}.theme-selector button{background:#0000000d;border:none;cursor:pointer;padding:.4rem;font-size:1rem;border-radius:8px;line-height:1;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.theme-selector button:hover{background:#0000001a;transform:translateY(-2px)}.theme-selector button.active{background:var(--border-color, #999);color:#fff;box-shadow:0 4px 8px #0000001a}.theme-dark .theme-selector button{background:#ffffff1a}.theme-dark .theme-selector button:hover{background:#fff3}.dashboard-sidebar::-webkit-scrollbar{width:4px}.dashboard-sidebar::-webkit-scrollbar-thumb{background-color:var(--border-color, #999)}.feed-list.variant-glass{background:#ffffff0d;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-right:1px solid rgba(255,255,255,.1);padding:1.5rem;font-family:system-ui,-apple-system,sans-serif;color:var(--text-color)}.feed-list.variant-glass .logo{font-size:1.5rem;background:transparent!important;margin-bottom:2rem;opacity:.8}.feed-list.variant-glass .section-header{font-size:.75rem;text-transform:uppercase;letter-spacing:.1em;color:var(--text-color);opacity:.5;margin-top:2rem;font-weight:600}.feed-list.variant-glass a,.feed-list.variant-glass .feed-title,.feed-list.variant-glass .tag-link{padding:.4rem .8rem;margin:.2rem 0;border-radius:8px;transition:all .2s ease;font-weight:500;text-decoration:none!important;color:var(--text-color);opacity:.8;border:none}.feed-list.variant-glass a:hover,.feed-list.variant-glass .feed-title:hover,.feed-list.variant-glass .tag-link:hover{background:#ffffff1a;opacity:1;transform:translate(4px);color:var(--text-color)}.feed-list.variant-glass a.active,.feed-list.variant-glass .feed-title.active,.feed-list.variant-glass .tag-link.active{background:#ffffff40;color:var(--text-color);font-weight:700;opacity:1;box-shadow:0 4px 12px #0000001a;border:1px solid rgba(255,255,255,.2)}.feed-list.variant-glass .search-input{border-radius:20px;background:#0000000d;border:1px solid rgba(255,255,255,.1);color:var(--text-color);padding:.5rem 1rem}.feed-list.variant-glass .nav-section{border-top:1px solid rgba(255,255,255,.1);margin-top:2rem;padding-top:1.5rem}.feed-list.variant-glass .nav-link,.feed-list.variant-glass .logout-link{opacity:.6;padding:.5rem .8rem;border-radius:8px}.feed-list.variant-glass .nav-link:hover,.feed-list.variant-glass .logout-link:hover{background:#ffffff0d;opacity:1;text-decoration:none}.feed-list.variant-glass .theme-selector button{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px}.feed-list.variant-glass .theme-selector button.active{background:#fff3;border-color:#ffffff4d}.feed-list.variant-banana{background:#fdfdfd;padding:1rem;font-family:Poppins,Verdana,sans-serif;border-right:none;box-shadow:4px 0 24px #0000000a}.theme-dark .feed-list.variant-banana{background:#111}.feed-list.variant-banana .logo{font-size:2.5rem;text-shadow:2px 2px 0px #FFD700;background:transparent;transform:rotate(-3deg);display:inline-block;margin-bottom:2rem}.feed-list.variant-banana .section-header{background:gold;color:#000;display:inline-block;padding:.2rem .5rem;transform:skew(-10deg);font-size:.8rem;font-weight:800;margin-bottom:1rem;border-radius:4px}.feed-list.variant-banana .search-input{border:2px solid #000;border-radius:8px;box-shadow:2px 2px #000;transition:all .2s}.feed-list.variant-banana .search-input:focus{transform:translate(1px,1px);box-shadow:1px 1px #000;outline:none}.theme-dark .feed-list.variant-banana .search-input{border-color:#fff;box-shadow:2px 2px #fff;background:#222;color:#fff}.feed-list.variant-banana a,.feed-list.variant-banana .feed-title,.feed-list.variant-banana .tag-link{border:1px solid transparent;padding:.5rem;border-radius:8px;transition:transform .2s cubic-bezier(.34,1.56,.64,1);font-weight:600;text-decoration:none!important;color:var(--text-color)}.feed-list.variant-banana a:hover,.feed-list.variant-banana .feed-title:hover,.feed-list.variant-banana .tag-link:hover{transform:scale(1.05) rotate(1deg);background:#fff9c4;color:#000;box-shadow:0 4px 12px #ffd7004d}.theme-dark .feed-list.variant-banana a:hover,.theme-dark .feed-list.variant-banana .feed-title:hover,.theme-dark .feed-list.variant-banana .tag-link:hover{background:#333;color:gold}.feed-list.variant-banana a.active,.feed-list.variant-banana .feed-title.active,.feed-list.variant-banana .tag-link.active{background:gold;color:#000!important;transform:scale(1.02);box-shadow:3px 3px #0000001a;border:2px solid #000}.feed-list.variant-banana .nav-section{border-top:2px dashed #FFD700;margin-top:2rem;padding-top:1rem}.feed-list.variant-banana .theme-selector button{border:2px solid #000;box-shadow:2px 2px #000;border-radius:4px}.feed-list.variant-banana .theme-selector button.active{background:gold;transform:translate(1px,1px);box-shadow:1px 1px #000}.feed-list.variant-type{background:var(--bg-color);padding:2rem 1rem;font-family:Helvetica Neue,Arial,sans-serif;border-right:4px solid var(--text-color)}.feed-list.variant-type .logo{font-size:3rem;letter-spacing:-2px;font-weight:900;background:transparent;line-height:.8;margin-bottom:3rem;color:var(--text-color)}.feed-list.variant-type .section-header{font-size:1.2rem;font-weight:900;border-bottom:2px solid var(--text-color);padding-bottom:.5rem;margin-top:3rem;margin-bottom:1rem;letter-spacing:-.5px;color:var(--text-color)}.feed-list.variant-type a,.feed-list.variant-type .feed-title,.feed-list.variant-type .tag-link{font-size:1rem;font-weight:700;text-decoration:none!important;border-left:0px solid var(--text-color);padding-left:0;transition:padding-left .2s,border-left-width .2s;opacity:.6;color:var(--text-color);padding:.5rem 0;display:block}.feed-list.variant-type a:hover,.feed-list.variant-type .feed-title:hover,.feed-list.variant-type .tag-link:hover{padding-left:1rem;border-left:4px solid var(--text-color);opacity:1;color:var(--text-color)}.feed-list.variant-type a.active,.feed-list.variant-type .feed-title.active,.feed-list.variant-type .tag-link.active{padding-left:1rem;border-left:8px solid var(--text-color);opacity:1;color:var(--text-color)}.feed-list.variant-type .search-input{border:none;border-bottom:2px solid var(--text-color);background:transparent;border-radius:0;padding:1rem 0;font-weight:700;font-size:1.2rem}.feed-list.variant-type .search-input:focus{outline:none;border-bottom-width:4px}.feed-list.variant-type .nav-section{border-top:4px solid var(--text-color);margin-top:4rem;padding-top:1rem}.feed-list.variant-type .nav-link,.feed-list.variant-type .logout-link{font-size:1.2rem;font-weight:900}.feed-list.variant-type .theme-selector button{border-radius:0;border:2px solid var(--text-color);background:transparent}.feed-list.variant-type .theme-selector button.active{background:var(--text-color);color:var(--bg-color)}.feed-item{padding:1rem;margin-top:5rem;list-style:none;border-bottom:none}.item-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:.5rem}.item-title{font-family:var(--font-heading);font-size:1.8rem;font-weight:700;text-decoration:none;color:var(--link-color);display:block;flex:1}.item-title:hover{text-decoration:none;color:var(--link-color)}.item-actions{display:flex;gap:.5rem;margin-left:1rem}.star-btn{background:none;border:none;cursor:pointer;font-size:1.25rem;padding:0 0 0 .5rem;vertical-align:middle;transition:color .2s;line-height:1}.star-btn.is-starred{color:#00f}.star-btn.is-unstarred{color:var(--text-color);opacity:.3}.star-btn:hover{color:#00f}.action-btn{background:var(--sidebar-bg);border:1px solid var(--border-color, #ccc);cursor:pointer;padding:2px 6px;font-size:1rem;color:#00f;font-weight:700}.action-btn:hover{background-color:#eee}.dateline{margin-top:0;font-weight:400;font-size:.75em;color:#ccc;margin-bottom:1rem}.dateline a{color:#ccc;text-decoration:none}.item-description{color:var(--text-color);line-height:1.5;font-size:1rem;margin-top:1rem}.item-description img{max-width:100%;height:auto;display:block;margin:1rem 0}.item-description blockquote{padding:1rem 1rem 0;border-left:4px solid var(--sidebar-bg);color:var(--text-color);opacity:.8;margin-left:0}.scrape-btn{background:var(--bg-color);border:1px solid var(--border-color, #ccc);color:#00f;cursor:pointer;font-family:var(--font-heading);font-weight:700;font-size:.8rem;padding:2px 6px;margin-left:.5rem}.scrape-btn:hover{background:var(--sidebar-bg)}@media(max-width:768px){.feed-item{margin-top:2rem;padding:.5rem}.item-title{font-size:1.4rem;word-break:break-word}.item-header{flex-direction:column;gap:.5rem}.item-actions{margin-left:0;margin-bottom:.5rem}}.feed-items{padding:1rem 0}.feed-items h2{margin-top:0;border-bottom:2px solid var(--border-color);padding-bottom:.5rem}.item-list{list-style:none;padding:0}.loading-more{padding:2rem;text-align:center;color:#888;font-size:.9rem;min-height:50px}.settings-page.variant-glass{padding:2.5rem;max-width:800px;margin:0 auto;background:#ffffff0d;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:24px;border:1px solid rgba(255,255,255,.1);font-family:system-ui,-apple-system,sans-serif;color:var(--text-color);margin-top:2rem;margin-bottom:2rem}.settings-page.variant-glass h2,.settings-page.variant-glass h3{font-weight:700;letter-spacing:-.02em;color:var(--text-color);opacity:.9}.add-feed-section,.appearance-section,.import-section,.export-section,.feed-list-section{background:#ffffff08;padding:1.5rem;border-radius:16px;margin-bottom:2rem;border:1px solid rgba(255,255,255,.05);transition:all .3s ease}.add-feed-section:hover,.appearance-section:hover,.import-section:hover,.export-section:hover,.feed-list-section:hover{background:#ffffff0f;border-color:#ffffff1a}.font-selector{display:flex;align-items:center;gap:1rem}.font-select{padding:.6rem 1rem;border:1px solid rgba(255,255,255,.1);background:#0000001a;color:var(--text-color);border-radius:20px;font-size:1rem;min-width:200px;cursor:pointer;outline:none;transition:border-color .2s}.font-select:focus{border-color:#ffffff4d}.add-feed-form{display:flex;gap:1rem}.feed-input{flex:1;padding:.6rem 1.2rem;border:1px solid rgba(255,255,255,.1);background:#0000001a;color:var(--text-color);border-radius:20px;font-size:1rem;outline:none;transition:border-color .2s}.feed-input:focus{border-color:#ffffff4d}.error-message{color:#ff5252;margin-top:1rem;font-weight:600}.settings-feed-list{list-style:none;padding:0;border:1px solid rgba(255,255,255,.05);border-radius:12px;overflow:hidden}.settings-feed-item{display:flex;justify-content:space-between;align-items:center;padding:1.2rem;border-bottom:1px solid rgba(255,255,255,.05);transition:background .2s}.settings-feed-item:hover{background:#ffffff05}.settings-feed-item:last-child{border-bottom:none}.feed-info{display:flex;flex-direction:column;gap:.2rem}.feed-title{font-weight:600;font-size:1.05rem;opacity:.9}.feed-url{color:var(--text-color);opacity:.5;font-size:.85rem}.delete-btn{background:#ff525226;color:#ff8a80;border:1px solid rgba(255,82,82,.2);padding:.5rem 1rem;border-radius:12px;cursor:pointer;font-weight:600;transition:all .2s}.delete-btn:hover:not(:disabled){background:#ff52524d;color:#fff;border-color:#ff525266;transform:scale(1.05)}.import-export-section{display:flex;gap:2rem}@media(max-width:600px){.settings-page.variant-glass{padding:1.5rem;margin-top:1rem}.add-feed-form{flex-direction:column}.import-export-section{flex-direction:column;gap:1rem}.settings-feed-item{flex-direction:column;align-items:flex-start;gap:1rem}}.import-form{display:flex;flex-direction:column;gap:1.2rem}.file-input{font-size:.9rem;max-width:100%;color:var(--text-color);opacity:.8}.export-buttons{display:flex;gap:.8rem;flex-wrap:wrap}.export-btn{display:inline-block;padding:.6rem 1.2rem;background:#ffffff0d;color:var(--text-color);text-decoration:none;border:1px solid rgba(255,255,255,.1);border-radius:12px;font-weight:600;transition:all .2s}.export-btn:hover{background:#ffffff1a;transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}button:not(.delete-btn){cursor:pointer;padding:.6rem 1.2rem;border-radius:12px;border:1px solid rgba(255,255,255,.1);background:#ffffff1a;color:var(--text-color);font-weight:600;transition:all .2s}button:not(.delete-btn):hover:not(:disabled){background:#fff3;transform:scale(1.02)}button:disabled{opacity:.4;cursor:not-allowed} diff --git a/web/dist/v2/assets/index-BdhwF6aQ.js b/web/dist/v2/assets/index-BdhwF6aQ.js deleted file mode 100644 index 3ea42da..0000000 --- a/web/dist/v2/assets/index-BdhwF6aQ.js +++ /dev/null @@ -1,11 +0,0 @@ -(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))f(d);new MutationObserver(d=>{for(const h of d)if(h.type==="childList")for(const p of h.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&f(p)}).observe(document,{childList:!0,subtree:!0});function o(d){const h={};return d.integrity&&(h.integrity=d.integrity),d.referrerPolicy&&(h.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?h.credentials="include":d.crossOrigin==="anonymous"?h.credentials="omit":h.credentials="same-origin",h}function f(d){if(d.ep)return;d.ep=!0;const h=o(d);fetch(d.href,h)}})();var Mf={exports:{}},Un={};var Id;function ay(){if(Id)return Un;Id=1;var c=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(f,d,h){var p=null;if(h!==void 0&&(p=""+h),d.key!==void 0&&(p=""+d.key),"key"in d){h={};for(var A in d)A!=="key"&&(h[A]=d[A])}else h=d;return d=h.ref,{$$typeof:c,type:f,key:p,ref:d!==void 0?d:null,props:h}}return Un.Fragment=r,Un.jsx=o,Un.jsxs=o,Un}var Pd;function ny(){return Pd||(Pd=1,Mf.exports=ay()),Mf.exports}var M=ny(),Nf={exports:{}},et={};var th;function uy(){if(th)return et;th=1;var c=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),f=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),h=Symbol.for("react.consumer"),p=Symbol.for("react.context"),A=Symbol.for("react.forward_ref"),S=Symbol.for("react.suspense"),v=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),R=Symbol.for("react.activity"),B=Symbol.iterator;function Z(g){return g===null||typeof g!="object"?null:(g=B&&g[B]||g["@@iterator"],typeof g=="function"?g:null)}var k={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Q=Object.assign,H={};function G(g,j,Y){this.props=g,this.context=j,this.refs=H,this.updater=Y||k}G.prototype.isReactComponent={},G.prototype.setState=function(g,j){if(typeof g!="object"&&typeof g!="function"&&g!=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,g,j,"setState")},G.prototype.forceUpdate=function(g){this.updater.enqueueForceUpdate(this,g,"forceUpdate")};function q(){}q.prototype=G.prototype;function $(g,j,Y){this.props=g,this.context=j,this.refs=H,this.updater=Y||k}var W=$.prototype=new q;W.constructor=$,Q(W,G.prototype),W.isPureReactComponent=!0;var I=Array.isArray;function J(){}var X={H:null,A:null,T:null,S:null},ut=Object.prototype.hasOwnProperty;function rt(g,j,Y){var w=Y.ref;return{$$typeof:c,type:g,key:j,ref:w!==void 0?w:null,props:Y}}function Gt(g,j){return rt(g.type,j,g.props)}function pe(g){return typeof g=="object"&&g!==null&&g.$$typeof===c}function Ct(g){var j={"=":"=0",":":"=2"};return"$"+g.replace(/[=:]/g,function(Y){return j[Y]})}var Ye=/\/+/g;function it(g,j){return typeof g=="object"&&g!==null&&g.key!=null?Ct(""+g.key):j.toString(36)}function ie(g){switch(g.status){case"fulfilled":return g.value;case"rejected":throw g.reason;default:switch(typeof g.status=="string"?g.then(J,J):(g.status="pending",g.then(function(j){g.status==="pending"&&(g.status="fulfilled",g.value=j)},function(j){g.status==="pending"&&(g.status="rejected",g.reason=j)})),g.status){case"fulfilled":return g.value;case"rejected":throw g.reason}}throw g}function D(g,j,Y,w,lt){var ct=typeof g;(ct==="undefined"||ct==="boolean")&&(g=null);var gt=!1;if(g===null)gt=!0;else switch(ct){case"bigint":case"string":case"number":gt=!0;break;case"object":switch(g.$$typeof){case c:case r:gt=!0;break;case x:return gt=g._init,D(gt(g._payload),j,Y,w,lt)}}if(gt)return lt=lt(g),gt=w===""?"."+it(g,0):w,I(lt)?(Y="",gt!=null&&(Y=gt.replace(Ye,"$&/")+"/"),D(lt,j,Y,"",function(Ya){return Ya})):lt!=null&&(pe(lt)&&(lt=Gt(lt,Y+(lt.key==null||g&&g.key===lt.key?"":(""+lt.key).replace(Ye,"$&/")+"/")+gt)),j.push(lt)),1;gt=0;var Wt=w===""?".":w+":";if(I(g))for(var Ut=0;Ut>>1,At=D[bt];if(0>>1;btd(Y,tt))wd(lt,Y)?(D[bt]=lt,D[w]=tt,bt=w):(D[bt]=Y,D[j]=tt,bt=j);else if(wd(lt,tt))D[bt]=lt,D[w]=tt,bt=w;else break t}}return L}function d(D,L){var tt=D.sortIndex-L.sortIndex;return tt!==0?tt:D.id-L.id}if(c.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var h=performance;c.unstable_now=function(){return h.now()}}else{var p=Date,A=p.now();c.unstable_now=function(){return p.now()-A}}var S=[],v=[],x=1,R=null,B=3,Z=!1,k=!1,Q=!1,H=!1,G=typeof setTimeout=="function"?setTimeout:null,q=typeof clearTimeout=="function"?clearTimeout:null,$=typeof setImmediate<"u"?setImmediate:null;function W(D){for(var L=o(v);L!==null;){if(L.callback===null)f(v);else if(L.startTime<=D)f(v),L.sortIndex=L.expirationTime,r(S,L);else break;L=o(v)}}function I(D){if(Q=!1,W(D),!k)if(o(S)!==null)k=!0,J||(J=!0,Ct());else{var L=o(v);L!==null&&ie(I,L.startTime-D)}}var J=!1,X=-1,ut=5,rt=-1;function Gt(){return H?!0:!(c.unstable_now()-rtD&&Gt());){var bt=R.callback;if(typeof bt=="function"){R.callback=null,B=R.priorityLevel;var At=bt(R.expirationTime<=D);if(D=c.unstable_now(),typeof At=="function"){R.callback=At,W(D),L=!0;break e}R===o(S)&&f(S),W(D)}else f(S);R=o(S)}if(R!==null)L=!0;else{var g=o(v);g!==null&&ie(I,g.startTime-D),L=!1}}break t}finally{R=null,B=tt,Z=!1}L=void 0}}finally{L?Ct():J=!1}}}var Ct;if(typeof $=="function")Ct=function(){$(pe)};else if(typeof MessageChannel<"u"){var Ye=new MessageChannel,it=Ye.port2;Ye.port1.onmessage=pe,Ct=function(){it.postMessage(null)}}else Ct=function(){G(pe,0)};function ie(D,L){X=G(function(){D(c.unstable_now())},L)}c.unstable_IdlePriority=5,c.unstable_ImmediatePriority=1,c.unstable_LowPriority=4,c.unstable_NormalPriority=3,c.unstable_Profiling=null,c.unstable_UserBlockingPriority=2,c.unstable_cancelCallback=function(D){D.callback=null},c.unstable_forceFrameRate=function(D){0>D||125bt?(D.sortIndex=tt,r(v,D),o(S)===null&&D===o(v)&&(Q?(q(X),X=-1):Q=!0,ie(I,tt-bt))):(D.sortIndex=At,r(S,D),k||Z||(k=!0,J||(J=!0,Ct()))),D},c.unstable_shouldYield=Gt,c.unstable_wrapCallback=function(D){var L=B;return function(){var tt=B;B=L;try{return D.apply(this,arguments)}finally{B=tt}}}})(Uf)),Uf}var ah;function cy(){return ah||(ah=1,Cf.exports=iy()),Cf.exports}var jf={exports:{}},kt={};var nh;function fy(){if(nh)return kt;nh=1;var c=Qf();function r(S){var v="https://react.dev/errors/"+S;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(c)}catch(r){console.error(r)}}return c(),jf.exports=fy(),jf.exports}var ih;function ry(){if(ih)return jn;ih=1;var c=cy(),r=Qf(),o=sy();function f(t){var e="https://react.dev/errors/"+t;if(1At||(t.current=bt[At],bt[At]=null,At--)}function Y(t,e){At++,bt[At]=t.current,t.current=e}var w=g(null),lt=g(null),ct=g(null),gt=g(null);function Wt(t,e){switch(Y(ct,e),Y(lt,t),Y(w,null),e.nodeType){case 9:case 11:t=(t=e.documentElement)&&(t=t.namespaceURI)?Ed(t):0;break;default:if(t=e.tagName,e=e.namespaceURI)e=Ed(e),t=Td(e,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}j(w),Y(w,t)}function Ut(){j(w),j(lt),j(ct)}function Ya(t){t.memoizedState!==null&&Y(gt,t);var e=w.current,l=Td(e,t.type);e!==l&&(Y(lt,t),Y(w,l))}function Gn(t){lt.current===t&&(j(w),j(lt)),gt.current===t&&(j(gt),Mn._currentValue=tt)}var ri,Wf;function Cl(t){if(ri===void 0)try{throw Error()}catch(l){var e=l.stack.trim().match(/\n( *(at )?)/);ri=e&&e[1]||"",Wf=-1)":-1n||m[a]!==z[n]){var N=` -`+m[a].replace(" at new "," at ");return t.displayName&&N.includes("")&&(N=N.replace("",t.displayName)),N}while(1<=a&&0<=n);break}}}finally{oi=!1,Error.prepareStackTrace=l}return(l=t?t.displayName||t.name:"")?Cl(l):""}function jh(t,e){switch(t.tag){case 26:case 27:case 5:return Cl(t.type);case 16:return Cl("Lazy");case 13:return t.child!==e&&e!==null?Cl("Suspense Fallback"):Cl("Suspense");case 19:return Cl("SuspenseList");case 0:case 15:return di(t.type,!1);case 11:return di(t.type.render,!1);case 1:return di(t.type,!0);case 31:return Cl("Activity");default:return""}}function Ff(t){try{var e="",l=null;do e+=jh(t,l),l=t,t=t.return;while(t);return e}catch(a){return` -Error generating stack: `+a.message+` -`+a.stack}}var hi=Object.prototype.hasOwnProperty,mi=c.unstable_scheduleCallback,vi=c.unstable_cancelCallback,Hh=c.unstable_shouldYield,Bh=c.unstable_requestPaint,ce=c.unstable_now,qh=c.unstable_getCurrentPriorityLevel,If=c.unstable_ImmediatePriority,Pf=c.unstable_UserBlockingPriority,Xn=c.unstable_NormalPriority,Lh=c.unstable_LowPriority,ts=c.unstable_IdlePriority,Yh=c.log,Gh=c.unstable_setDisableYieldValue,Ga=null,fe=null;function il(t){if(typeof Yh=="function"&&Gh(t),fe&&typeof fe.setStrictMode=="function")try{fe.setStrictMode(Ga,t)}catch{}}var se=Math.clz32?Math.clz32:Zh,Xh=Math.log,Qh=Math.LN2;function Zh(t){return t>>>=0,t===0?32:31-(Xh(t)/Qh|0)|0}var Qn=256,Zn=262144,Vn=4194304;function Ul(t){var e=t&42;if(e!==0)return e;switch(t&-t){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 t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function wn(t,e,l){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,i=t.pingedLanes;t=t.warmLanes;var s=a&134217727;return s!==0?(a=s&~u,a!==0?n=Ul(a):(i&=s,i!==0?n=Ul(i):l||(l=s&~t,l!==0&&(n=Ul(l))))):(s=a&~u,s!==0?n=Ul(s):i!==0?n=Ul(i):l||(l=a&~t,l!==0&&(n=Ul(l)))),n===0?0:e!==0&&e!==n&&(e&u)===0&&(u=n&-n,l=e&-e,u>=l||u===32&&(l&4194048)!==0)?e:n}function Xa(t,e){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&e)===0}function Vh(t,e){switch(t){case 1:case 2:case 4:case 8:case 64:return e+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 e+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 es(){var t=Vn;return Vn<<=1,(Vn&62914560)===0&&(Vn=4194304),t}function yi(t){for(var e=[],l=0;31>l;l++)e.push(t);return e}function Qa(t,e){t.pendingLanes|=e,e!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function wh(t,e,l,a,n,u){var i=t.pendingLanes;t.pendingLanes=l,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=l,t.entangledLanes&=l,t.errorRecoveryDisabledLanes&=l,t.shellSuspendCounter=0;var s=t.entanglements,m=t.expirationTimes,z=t.hiddenUpdates;for(l=i&~l;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var Fh=/[\n"\\]/g;function be(t){return t.replace(Fh,function(e){return"\\"+e.charCodeAt(0).toString(16)+" "})}function Ti(t,e,l,a,n,u,i,s){t.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?t.type=i:t.removeAttribute("type"),e!=null?i==="number"?(e===0&&t.value===""||t.value!=e)&&(t.value=""+Se(e)):t.value!==""+Se(e)&&(t.value=""+Se(e)):i!=="submit"&&i!=="reset"||t.removeAttribute("value"),e!=null?zi(t,i,Se(e)):l!=null?zi(t,i,Se(l)):a!=null&&t.removeAttribute("value"),n==null&&u!=null&&(t.defaultChecked=!!u),n!=null&&(t.checked=n&&typeof n!="function"&&typeof n!="symbol"),s!=null&&typeof s!="function"&&typeof s!="symbol"&&typeof s!="boolean"?t.name=""+Se(s):t.removeAttribute("name")}function ms(t,e,l,a,n,u,i,s){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(t.type=u),e!=null||l!=null){if(!(u!=="submit"&&u!=="reset"||e!=null)){Ei(t);return}l=l!=null?""+Se(l):"",e=e!=null?""+Se(e):l,s||e===t.value||(t.value=e),t.defaultValue=e}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,t.checked=s?t.checked:!!a,t.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.name=i),Ei(t)}function zi(t,e,l){e==="number"&&$n(t.ownerDocument)===t||t.defaultValue===""+l||(t.defaultValue=""+l)}function aa(t,e,l,a){if(t=t.options,e){e={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),xi=!1;if(Qe)try{var Ka={};Object.defineProperty(Ka,"passive",{get:function(){xi=!0}}),window.addEventListener("test",Ka,Ka),window.removeEventListener("test",Ka,Ka)}catch{xi=!1}var fl=null,Mi=null,Wn=null;function Es(){if(Wn)return Wn;var t,e=Mi,l=e.length,a,n="value"in fl?fl.value:fl.textContent,u=n.length;for(t=0;t=ka),Os=" ",xs=!1;function Ms(t,e){switch(t){case"keyup":return _m.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ns(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var ca=!1;function Om(t,e){switch(t){case"compositionend":return Ns(e);case"keypress":return e.which!==32?null:(xs=!0,Os);case"textInput":return t=e.data,t===Os&&xs?null:t;default:return null}}function xm(t,e){if(ca)return t==="compositionend"||!ji&&Ms(t,e)?(t=Es(),Wn=Mi=fl=null,ca=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1=e)return{node:l,offset:e-t};t=a}t:{for(;l;){if(l.nextSibling){l=l.nextSibling;break t}l=l.parentNode}l=void 0}l=Ls(l)}}function Gs(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?Gs(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function Xs(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var e=$n(t.document);e instanceof t.HTMLIFrameElement;){try{var l=typeof e.contentWindow.location.href=="string"}catch{l=!1}if(l)t=e.contentWindow;else break;e=$n(t.document)}return e}function qi(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}var Bm=Qe&&"documentMode"in document&&11>=document.documentMode,fa=null,Li=null,Pa=null,Yi=!1;function Qs(t,e,l){var a=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;Yi||fa==null||fa!==$n(a)||(a=fa,"selectionStart"in a&&qi(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Pa&&Ia(Pa,a)||(Pa=a,a=Zu(Li,"onSelect"),0>=i,n-=i,He=1<<32-se(e)+n|l<nt?(dt=K,K=null):dt=K.sibling;var vt=_(b,K,E[nt],C);if(vt===null){K===null&&(K=dt);break}t&&K&&vt.alternate===null&&e(b,K),y=u(vt,y,nt),mt===null?F=vt:mt.sibling=vt,mt=vt,K=dt}if(nt===E.length)return l(b,K),ht&&Ve(b,nt),F;if(K===null){for(;ntnt?(dt=K,K=null):dt=K.sibling;var Nl=_(b,K,vt.value,C);if(Nl===null){K===null&&(K=dt);break}t&&K&&Nl.alternate===null&&e(b,K),y=u(Nl,y,nt),mt===null?F=Nl:mt.sibling=Nl,mt=Nl,K=dt}if(vt.done)return l(b,K),ht&&Ve(b,nt),F;if(K===null){for(;!vt.done;nt++,vt=E.next())vt=U(b,vt.value,C),vt!==null&&(y=u(vt,y,nt),mt===null?F=vt:mt.sibling=vt,mt=vt);return ht&&Ve(b,nt),F}for(K=a(K);!vt.done;nt++,vt=E.next())vt=O(K,b,nt,vt.value,C),vt!==null&&(t&&vt.alternate!==null&&K.delete(vt.key===null?nt:vt.key),y=u(vt,y,nt),mt===null?F=vt:mt.sibling=vt,mt=vt);return t&&K.forEach(function(ly){return e(b,ly)}),ht&&Ve(b,nt),F}function zt(b,y,E,C){if(typeof E=="object"&&E!==null&&E.type===Q&&E.key===null&&(E=E.props.children),typeof E=="object"&&E!==null){switch(E.$$typeof){case Z:t:{for(var F=E.key;y!==null;){if(y.key===F){if(F=E.type,F===Q){if(y.tag===7){l(b,y.sibling),C=n(y,E.props.children),C.return=b,b=C;break t}}else if(y.elementType===F||typeof F=="object"&&F!==null&&F.$$typeof===ut&&Vl(F)===y.type){l(b,y.sibling),C=n(y,E.props),un(C,E),C.return=b,b=C;break t}l(b,y);break}else e(b,y);y=y.sibling}E.type===Q?(C=Yl(E.props.children,b.mode,C,E.key),C.return=b,b=C):(C=iu(E.type,E.key,E.props,null,b.mode,C),un(C,E),C.return=b,b=C)}return i(b);case k:t:{for(F=E.key;y!==null;){if(y.key===F)if(y.tag===4&&y.stateNode.containerInfo===E.containerInfo&&y.stateNode.implementation===E.implementation){l(b,y.sibling),C=n(y,E.children||[]),C.return=b,b=C;break t}else{l(b,y);break}else e(b,y);y=y.sibling}C=Ki(E,b.mode,C),C.return=b,b=C}return i(b);case ut:return E=Vl(E),zt(b,y,E,C)}if(ie(E))return V(b,y,E,C);if(Ct(E)){if(F=Ct(E),typeof F!="function")throw Error(f(150));return E=F.call(E),P(b,y,E,C)}if(typeof E.then=="function")return zt(b,y,hu(E),C);if(E.$$typeof===$)return zt(b,y,su(b,E),C);mu(b,E)}return typeof E=="string"&&E!==""||typeof E=="number"||typeof E=="bigint"?(E=""+E,y!==null&&y.tag===6?(l(b,y.sibling),C=n(y,E),C.return=b,b=C):(l(b,y),C=wi(E,b.mode,C),C.return=b,b=C),i(b)):l(b,y)}return function(b,y,E,C){try{nn=0;var F=zt(b,y,E,C);return Sa=null,F}catch(K){if(K===pa||K===ou)throw K;var mt=oe(29,K,null,b.mode);return mt.lanes=C,mt.return=b,mt}}}var Kl=or(!0),dr=or(!1),hl=!1;function nc(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function uc(t,e){t=t.updateQueue,e.updateQueue===t&&(e.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function ml(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function vl(t,e,l){var a=t.updateQueue;if(a===null)return null;if(a=a.shared,(yt&2)!==0){var n=a.pending;return n===null?e.next=e:(e.next=n.next,n.next=e),a.pending=e,e=uu(t),ks(t,null,l),e}return nu(t,a,e,l),uu(t)}function cn(t,e,l){if(e=e.updateQueue,e!==null&&(e=e.shared,(l&4194048)!==0)){var a=e.lanes;a&=t.pendingLanes,l|=a,e.lanes=l,as(t,l)}}function ic(t,e){var l=t.updateQueue,a=t.alternate;if(a!==null&&(a=a.updateQueue,l===a)){var n=null,u=null;if(l=l.firstBaseUpdate,l!==null){do{var i={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};u===null?n=u=i:u=u.next=i,l=l.next}while(l!==null);u===null?n=u=e:u=u.next=e}else n=u=e;l={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:u,shared:a.shared,callbacks:a.callbacks},t.updateQueue=l;return}t=l.lastBaseUpdate,t===null?l.firstBaseUpdate=e:t.next=e,l.lastBaseUpdate=e}var cc=!1;function fn(){if(cc){var t=ga;if(t!==null)throw t}}function sn(t,e,l,a){cc=!1;var n=t.updateQueue;hl=!1;var u=n.firstBaseUpdate,i=n.lastBaseUpdate,s=n.shared.pending;if(s!==null){n.shared.pending=null;var m=s,z=m.next;m.next=null,i===null?u=z:i.next=z,i=m;var N=t.alternate;N!==null&&(N=N.updateQueue,s=N.lastBaseUpdate,s!==i&&(s===null?N.firstBaseUpdate=z:s.next=z,N.lastBaseUpdate=m))}if(u!==null){var U=n.baseState;i=0,N=z=m=null,s=u;do{var _=s.lane&-536870913,O=_!==s.lane;if(O?(ot&_)===_:(a&_)===_){_!==0&&_===ya&&(cc=!0),N!==null&&(N=N.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});t:{var V=t,P=s;_=e;var zt=l;switch(P.tag){case 1:if(V=P.payload,typeof V=="function"){U=V.call(zt,U,_);break t}U=V;break t;case 3:V.flags=V.flags&-65537|128;case 0:if(V=P.payload,_=typeof V=="function"?V.call(zt,U,_):V,_==null)break t;U=R({},U,_);break t;case 2:hl=!0}}_=s.callback,_!==null&&(t.flags|=64,O&&(t.flags|=8192),O=n.callbacks,O===null?n.callbacks=[_]:O.push(_))}else O={lane:_,tag:s.tag,payload:s.payload,callback:s.callback,next:null},N===null?(z=N=O,m=U):N=N.next=O,i|=_;if(s=s.next,s===null){if(s=n.shared.pending,s===null)break;O=s,s=O.next,O.next=null,n.lastBaseUpdate=O,n.shared.pending=null}}while(!0);N===null&&(m=U),n.baseState=m,n.firstBaseUpdate=z,n.lastBaseUpdate=N,u===null&&(n.shared.lanes=0),bl|=i,t.lanes=i,t.memoizedState=U}}function hr(t,e){if(typeof t!="function")throw Error(f(191,t));t.call(e)}function mr(t,e){var l=t.callbacks;if(l!==null)for(t.callbacks=null,t=0;tu?u:8;var i=D.T,s={};D.T=s,Rc(t,!1,e,l);try{var m=n(),z=D.S;if(z!==null&&z(s,m),m!==null&&typeof m=="object"&&typeof m.then=="function"){var N=wm(m,a);dn(t,e,N,ye(t))}else dn(t,e,a,ye(t))}catch(U){dn(t,e,{then:function(){},status:"rejected",reason:U},ye())}finally{L.p=u,i!==null&&s.types!==null&&(i.types=s.types),D.T=i}}function Fm(){}function Ac(t,e,l,a){if(t.tag!==5)throw Error(f(476));var n=Kr(t).queue;wr(t,n,e,tt,l===null?Fm:function(){return Jr(t),l(a)})}function Kr(t){var e=t.memoizedState;if(e!==null)return e;e={memoizedState:tt,baseState:tt,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:$e,lastRenderedState:tt},next:null};var l={};return e.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:$e,lastRenderedState:l},next:null},t.memoizedState=e,t=t.alternate,t!==null&&(t.memoizedState=e),e}function Jr(t){var e=Kr(t);e.next===null&&(e=t.alternate.memoizedState),dn(t,e.next.queue,{},ye())}function _c(){return Kt(Mn)}function $r(){return Ht().memoizedState}function kr(){return Ht().memoizedState}function Im(t){for(var e=t.return;e!==null;){switch(e.tag){case 24:case 3:var l=ye();t=ml(l);var a=vl(e,t,l);a!==null&&(ne(a,e,l),cn(a,e,l)),e={cache:tc()},t.payload=e;return}e=e.return}}function Pm(t,e,l){var a=ye();l={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Au(t)?Fr(e,l):(l=Zi(t,e,l,a),l!==null&&(ne(l,t,a),Ir(l,e,a)))}function Wr(t,e,l){var a=ye();dn(t,e,l,a)}function dn(t,e,l,a){var n={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Au(t))Fr(e,n);else{var u=t.alternate;if(t.lanes===0&&(u===null||u.lanes===0)&&(u=e.lastRenderedReducer,u!==null))try{var i=e.lastRenderedState,s=u(i,l);if(n.hasEagerState=!0,n.eagerState=s,re(s,i))return nu(t,e,n,0),_t===null&&au(),!1}catch{}if(l=Zi(t,e,n,a),l!==null)return ne(l,t,a),Ir(l,e,a),!0}return!1}function Rc(t,e,l,a){if(a={lane:2,revertLane:nf(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Au(t)){if(e)throw Error(f(479))}else e=Zi(t,l,a,2),e!==null&&ne(e,t,2)}function Au(t){var e=t.alternate;return t===at||e!==null&&e===at}function Fr(t,e){Ea=gu=!0;var l=t.pending;l===null?e.next=e:(e.next=l.next,l.next=e),t.pending=e}function Ir(t,e,l){if((l&4194048)!==0){var a=e.lanes;a&=t.pendingLanes,l|=a,e.lanes=l,as(t,l)}}var hn={readContext:Kt,use:bu,useCallback:Nt,useContext:Nt,useEffect:Nt,useImperativeHandle:Nt,useLayoutEffect:Nt,useInsertionEffect:Nt,useMemo:Nt,useReducer:Nt,useRef:Nt,useState:Nt,useDebugValue:Nt,useDeferredValue:Nt,useTransition:Nt,useSyncExternalStore:Nt,useId:Nt,useHostTransitionStatus:Nt,useFormState:Nt,useActionState:Nt,useOptimistic:Nt,useMemoCache:Nt,useCacheRefresh:Nt};hn.useEffectEvent=Nt;var Pr={readContext:Kt,use:bu,useCallback:function(t,e){return Ft().memoizedState=[t,e===void 0?null:e],t},useContext:Kt,useEffect:Br,useImperativeHandle:function(t,e,l){l=l!=null?l.concat([t]):null,Tu(4194308,4,Gr.bind(null,e,t),l)},useLayoutEffect:function(t,e){return Tu(4194308,4,t,e)},useInsertionEffect:function(t,e){Tu(4,2,t,e)},useMemo:function(t,e){var l=Ft();e=e===void 0?null:e;var a=t();if(Jl){il(!0);try{t()}finally{il(!1)}}return l.memoizedState=[a,e],a},useReducer:function(t,e,l){var a=Ft();if(l!==void 0){var n=l(e);if(Jl){il(!0);try{l(e)}finally{il(!1)}}}else n=e;return a.memoizedState=a.baseState=n,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:n},a.queue=t,t=t.dispatch=Pm.bind(null,at,t),[a.memoizedState,t]},useRef:function(t){var e=Ft();return t={current:t},e.memoizedState=t},useState:function(t){t=Sc(t);var e=t.queue,l=Wr.bind(null,at,e);return e.dispatch=l,[t.memoizedState,l]},useDebugValue:Tc,useDeferredValue:function(t,e){var l=Ft();return zc(l,t,e)},useTransition:function(){var t=Sc(!1);return t=wr.bind(null,at,t.queue,!0,!1),Ft().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,e,l){var a=at,n=Ft();if(ht){if(l===void 0)throw Error(f(407));l=l()}else{if(l=e(),_t===null)throw Error(f(349));(ot&127)!==0||br(a,e,l)}n.memoizedState=l;var u={value:l,getSnapshot:e};return n.queue=u,Br(Tr.bind(null,a,u,t),[t]),a.flags|=2048,za(9,{destroy:void 0},Er.bind(null,a,u,l,e),null),l},useId:function(){var t=Ft(),e=_t.identifierPrefix;if(ht){var l=Be,a=He;l=(a&~(1<<32-se(a)-1)).toString(32)+l,e="_"+e+"R_"+l,l=pu++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof a.is=="string"?i.createElement("select",{is:a.is}):i.createElement("select"),a.multiple?u.multiple=!0:a.size&&(u.size=a.size);break;default:u=typeof a.is=="string"?i.createElement(n,{is:a.is}):i.createElement(n)}}u[Vt]=e,u[It]=a;t:for(i=e.child;i!==null;){if(i.tag===5||i.tag===6)u.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===e)break t;for(;i.sibling===null;){if(i.return===null||i.return===e)break t;i=i.return}i.sibling.return=i.return,i=i.sibling}e.stateNode=u;t:switch($t(u,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break t;case"img":a=!0;break t;default:a=!1}a&&We(e)}}return Ot(e),Gc(e,e.type,t===null?null:t.memoizedProps,e.pendingProps,l),null;case 6:if(t&&e.stateNode!=null)t.memoizedProps!==a&&We(e);else{if(typeof a!="string"&&e.stateNode===null)throw Error(f(166));if(t=ct.current,ma(e)){if(t=e.stateNode,l=e.memoizedProps,a=null,n=wt,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}t[Vt]=e,t=!!(t.nodeValue===l||a!==null&&a.suppressHydrationWarning===!0||Sd(t.nodeValue,l)),t||ol(e,!0)}else t=Vu(t).createTextNode(a),t[Vt]=e,e.stateNode=t}return Ot(e),null;case 31:if(l=e.memoizedState,t===null||t.memoizedState!==null){if(a=ma(e),l!==null){if(t===null){if(!a)throw Error(f(318));if(t=e.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(f(557));t[Vt]=e}else Gl(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Ot(e),t=!1}else l=Wi(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=l),t=!0;if(!t)return e.flags&256?(he(e),e):(he(e),null);if((e.flags&128)!==0)throw Error(f(558))}return Ot(e),null;case 13:if(a=e.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(n=ma(e),a!==null&&a.dehydrated!==null){if(t===null){if(!n)throw Error(f(318));if(n=e.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(f(317));n[Vt]=e}else Gl(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Ot(e),n=!1}else n=Wi(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=n),n=!0;if(!n)return e.flags&256?(he(e),e):(he(e),null)}return he(e),(e.flags&128)!==0?(e.lanes=l,e):(l=a!==null,t=t!==null&&t.memoizedState!==null,l&&(a=e.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)),l!==t&&l&&(e.child.flags|=8192),Mu(e,e.updateQueue),Ot(e),null);case 4:return Ut(),t===null&&sf(e.stateNode.containerInfo),Ot(e),null;case 10:return Ke(e.type),Ot(e),null;case 19:if(j(jt),a=e.memoizedState,a===null)return Ot(e),null;if(n=(e.flags&128)!==0,u=a.rendering,u===null)if(n)vn(a,!1);else{if(Dt!==0||t!==null&&(t.flags&128)!==0)for(t=e.child;t!==null;){if(u=yu(t),u!==null){for(e.flags|=128,vn(a,!1),t=u.updateQueue,e.updateQueue=t,Mu(e,t),e.subtreeFlags=0,t=l,l=e.child;l!==null;)Ws(l,t),l=l.sibling;return Y(jt,jt.current&1|2),ht&&Ve(e,a.treeForkCount),e.child}t=t.sibling}a.tail!==null&&ce()>ju&&(e.flags|=128,n=!0,vn(a,!1),e.lanes=4194304)}else{if(!n)if(t=yu(u),t!==null){if(e.flags|=128,n=!0,t=t.updateQueue,e.updateQueue=t,Mu(e,t),vn(a,!0),a.tail===null&&a.tailMode==="hidden"&&!u.alternate&&!ht)return Ot(e),null}else 2*ce()-a.renderingStartTime>ju&&l!==536870912&&(e.flags|=128,n=!0,vn(a,!1),e.lanes=4194304);a.isBackwards?(u.sibling=e.child,e.child=u):(t=a.last,t!==null?t.sibling=u:e.child=u,a.last=u)}return a.tail!==null?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=ce(),t.sibling=null,l=jt.current,Y(jt,n?l&1|2:l&1),ht&&Ve(e,a.treeForkCount),t):(Ot(e),null);case 22:case 23:return he(e),sc(),a=e.memoizedState!==null,t!==null?t.memoizedState!==null!==a&&(e.flags|=8192):a&&(e.flags|=8192),a?(l&536870912)!==0&&(e.flags&128)===0&&(Ot(e),e.subtreeFlags&6&&(e.flags|=8192)):Ot(e),l=e.updateQueue,l!==null&&Mu(e,l.retryQueue),l=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(l=t.memoizedState.cachePool.pool),a=null,e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(a=e.memoizedState.cachePool.pool),a!==l&&(e.flags|=2048),t!==null&&j(Zl),null;case 24:return l=null,t!==null&&(l=t.memoizedState.cache),e.memoizedState.cache!==l&&(e.flags|=2048),Ke(Bt),Ot(e),null;case 25:return null;case 30:return null}throw Error(f(156,e.tag))}function nv(t,e){switch($i(e),e.tag){case 1:return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return Ke(Bt),Ut(),t=e.flags,(t&65536)!==0&&(t&128)===0?(e.flags=t&-65537|128,e):null;case 26:case 27:case 5:return Gn(e),null;case 31:if(e.memoizedState!==null){if(he(e),e.alternate===null)throw Error(f(340));Gl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 13:if(he(e),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(f(340));Gl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return j(jt),null;case 4:return Ut(),null;case 10:return Ke(e.type),null;case 22:case 23:return he(e),sc(),t!==null&&j(Zl),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 24:return Ke(Bt),null;case 25:return null;default:return null}}function Ao(t,e){switch($i(e),e.tag){case 3:Ke(Bt),Ut();break;case 26:case 27:case 5:Gn(e);break;case 4:Ut();break;case 31:e.memoizedState!==null&&he(e);break;case 13:he(e);break;case 19:j(jt);break;case 10:Ke(e.type);break;case 22:case 23:he(e),sc(),t!==null&&j(Zl);break;case 24:Ke(Bt)}}function yn(t,e){try{var l=e.updateQueue,a=l!==null?l.lastEffect:null;if(a!==null){var n=a.next;l=n;do{if((l.tag&t)===t){a=void 0;var u=l.create,i=l.inst;a=u(),i.destroy=a}l=l.next}while(l!==n)}}catch(s){St(e,e.return,s)}}function pl(t,e,l){try{var a=e.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var u=n.next;a=u;do{if((a.tag&t)===t){var i=a.inst,s=i.destroy;if(s!==void 0){i.destroy=void 0,n=e;var m=l,z=s;try{z()}catch(N){St(n,m,N)}}}a=a.next}while(a!==u)}}catch(N){St(e,e.return,N)}}function _o(t){var e=t.updateQueue;if(e!==null){var l=t.stateNode;try{mr(e,l)}catch(a){St(t,t.return,a)}}}function Ro(t,e,l){l.props=$l(t.type,t.memoizedProps),l.state=t.memoizedState;try{l.componentWillUnmount()}catch(a){St(t,e,a)}}function gn(t,e){try{var l=t.ref;if(l!==null){switch(t.tag){case 26:case 27:case 5:var a=t.stateNode;break;case 30:a=t.stateNode;break;default:a=t.stateNode}typeof l=="function"?t.refCleanup=l(a):l.current=a}}catch(n){St(t,e,n)}}function qe(t,e){var l=t.ref,a=t.refCleanup;if(l!==null)if(typeof a=="function")try{a()}catch(n){St(t,e,n)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(n){St(t,e,n)}else l.current=null}function Oo(t){var e=t.type,l=t.memoizedProps,a=t.stateNode;try{t:switch(e){case"button":case"input":case"select":case"textarea":l.autoFocus&&a.focus();break t;case"img":l.src?a.src=l.src:l.srcSet&&(a.srcset=l.srcSet)}}catch(n){St(t,t.return,n)}}function Xc(t,e,l){try{var a=t.stateNode;Rv(a,t.type,l,e),a[It]=e}catch(n){St(t,t.return,n)}}function xo(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&_l(t.type)||t.tag===4}function Qc(t){t:for(;;){for(;t.sibling===null;){if(t.return===null||xo(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&_l(t.type)||t.flags&2||t.child===null||t.tag===4)continue t;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function Zc(t,e,l){var a=t.tag;if(a===5||a===6)t=t.stateNode,e?(l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l).insertBefore(t,e):(e=l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l,e.appendChild(t),l=l._reactRootContainer,l!=null||e.onclick!==null||(e.onclick=Xe));else if(a!==4&&(a===27&&_l(t.type)&&(l=t.stateNode,e=null),t=t.child,t!==null))for(Zc(t,e,l),t=t.sibling;t!==null;)Zc(t,e,l),t=t.sibling}function Nu(t,e,l){var a=t.tag;if(a===5||a===6)t=t.stateNode,e?l.insertBefore(t,e):l.appendChild(t);else if(a!==4&&(a===27&&_l(t.type)&&(l=t.stateNode),t=t.child,t!==null))for(Nu(t,e,l),t=t.sibling;t!==null;)Nu(t,e,l),t=t.sibling}function Mo(t){var e=t.stateNode,l=t.memoizedProps;try{for(var a=t.type,n=e.attributes;n.length;)e.removeAttributeNode(n[0]);$t(e,a,l),e[Vt]=t,e[It]=l}catch(u){St(t,t.return,u)}}var Fe=!1,Yt=!1,Vc=!1,No=typeof WeakSet=="function"?WeakSet:Set,Zt=null;function uv(t,e){if(t=t.containerInfo,df=Fu,t=Xs(t),qi(t)){if("selectionStart"in t)var l={start:t.selectionStart,end:t.selectionEnd};else t:{l=(l=t.ownerDocument)&&l.defaultView||window;var a=l.getSelection&&l.getSelection();if(a&&a.rangeCount!==0){l=a.anchorNode;var n=a.anchorOffset,u=a.focusNode;a=a.focusOffset;try{l.nodeType,u.nodeType}catch{l=null;break t}var i=0,s=-1,m=-1,z=0,N=0,U=t,_=null;e:for(;;){for(var O;U!==l||n!==0&&U.nodeType!==3||(s=i+n),U!==u||a!==0&&U.nodeType!==3||(m=i+a),U.nodeType===3&&(i+=U.nodeValue.length),(O=U.firstChild)!==null;)_=U,U=O;for(;;){if(U===t)break e;if(_===l&&++z===n&&(s=i),_===u&&++N===a&&(m=i),(O=U.nextSibling)!==null)break;U=_,_=U.parentNode}U=O}l=s===-1||m===-1?null:{start:s,end:m}}else l=null}l=l||{start:0,end:0}}else l=null;for(hf={focusedElem:t,selectionRange:l},Fu=!1,Zt=e;Zt!==null;)if(e=Zt,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,Zt=t;else for(;Zt!==null;){switch(e=Zt,u=e.alternate,t=e.flags,e.tag){case 0:if((t&4)!==0&&(t=e.updateQueue,t=t!==null?t.events:null,t!==null))for(l=0;l title"))),$t(u,a,l),u[Vt]=t,Qt(u),a=u;break t;case"link":var i=Bd("link","href",n).get(a+(l.href||""));if(i){for(var s=0;szt&&(i=zt,zt=P,P=i);var b=Ys(s,P),y=Ys(s,zt);if(b&&y&&(O.rangeCount!==1||O.anchorNode!==b.node||O.anchorOffset!==b.offset||O.focusNode!==y.node||O.focusOffset!==y.offset)){var E=U.createRange();E.setStart(b.node,b.offset),O.removeAllRanges(),P>zt?(O.addRange(E),O.extend(y.node,y.offset)):(E.setEnd(y.node,y.offset),O.addRange(E))}}}}for(U=[],O=s;O=O.parentNode;)O.nodeType===1&&U.push({element:O,left:O.scrollLeft,top:O.scrollTop});for(typeof s.focus=="function"&&s.focus(),s=0;sl?32:l,D.T=null,l=Fc,Fc=null;var u=Tl,i=ll;if(Xt=0,xa=Tl=null,ll=0,(yt&6)!==0)throw Error(f(331));var s=yt;if(yt|=4,Xo(u.current),Lo(u,u.current,i,l),yt=s,zn(0,!1),fe&&typeof fe.onPostCommitFiberRoot=="function")try{fe.onPostCommitFiberRoot(Ga,u)}catch{}return!0}finally{L.p=n,D.T=a,ud(t,e)}}function cd(t,e,l){e=Te(l,e),e=Nc(t.stateNode,e,2),t=vl(t,e,2),t!==null&&(Qa(t,2),Le(t))}function St(t,e,l){if(t.tag===3)cd(t,t,l);else for(;e!==null;){if(e.tag===3){cd(e,t,l);break}else if(e.tag===1){var a=e.stateNode;if(typeof e.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(El===null||!El.has(a))){t=Te(l,t),l=co(2),a=vl(e,l,2),a!==null&&(fo(l,a,e,t),Qa(a,2),Le(a));break}}e=e.return}}function ef(t,e,l){var a=t.pingCache;if(a===null){a=t.pingCache=new fv;var n=new Set;a.set(e,n)}else n=a.get(e),n===void 0&&(n=new Set,a.set(e,n));n.has(l)||(Jc=!0,n.add(l),t=hv.bind(null,t,e,l),e.then(t,t))}function hv(t,e,l){var a=t.pingCache;a!==null&&a.delete(e),t.pingedLanes|=t.suspendedLanes&l,t.warmLanes&=~l,_t===t&&(ot&l)===l&&(Dt===4||Dt===3&&(ot&62914560)===ot&&300>ce()-Uu?(yt&2)===0&&Ma(t,0):$c|=l,Oa===ot&&(Oa=0)),Le(t)}function fd(t,e){e===0&&(e=es()),t=Ll(t,e),t!==null&&(Qa(t,e),Le(t))}function mv(t){var e=t.memoizedState,l=0;e!==null&&(l=e.retryLane),fd(t,l)}function vv(t,e){var l=0;switch(t.tag){case 31:case 13:var a=t.stateNode,n=t.memoizedState;n!==null&&(l=n.retryLane);break;case 19:a=t.stateNode;break;case 22:a=t.stateNode._retryCache;break;default:throw Error(f(314))}a!==null&&a.delete(e),fd(t,l)}function yv(t,e){return mi(t,e)}var Gu=null,Da=null,lf=!1,Xu=!1,af=!1,Al=0;function Le(t){t!==Da&&t.next===null&&(Da===null?Gu=Da=t:Da=Da.next=t),Xu=!0,lf||(lf=!0,pv())}function zn(t,e){if(!af&&Xu){af=!0;do for(var l=!1,a=Gu;a!==null;){if(t!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var i=a.suspendedLanes,s=a.pingedLanes;u=(1<<31-se(42|t)+1)-1,u&=n&~(i&~s),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(l=!0,dd(a,u))}else u=ot,u=wn(a,a===_t?u:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(u&3)===0||Xa(a,u)||(l=!0,dd(a,u));a=a.next}while(l);af=!1}}function gv(){sd()}function sd(){Xu=lf=!1;var t=0;Al!==0&&xv()&&(t=Al);for(var e=ce(),l=null,a=Gu;a!==null;){var n=a.next,u=rd(a,e);u===0?(a.next=null,l===null?Gu=n:l.next=n,n===null&&(Da=l)):(l=a,(t!==0||(u&3)!==0)&&(Xu=!0)),a=n}Xt!==0&&Xt!==5||zn(t),Al!==0&&(Al=0)}function rd(t,e){for(var l=t.suspendedLanes,a=t.pingedLanes,n=t.expirationTimes,u=t.pendingLanes&-62914561;0s)break;var N=m.transferSize,U=m.initiatorType;N&&bd(U)&&(m=m.responseEnd,i+=N*(m"u"?null:document;function Cd(t,e,l){var a=Ca;if(a&&typeof e=="string"&&e){var n=be(e);n='link[rel="'+t+'"][href="'+n+'"]',typeof l=="string"&&(n+='[crossorigin="'+l+'"]'),Dd.has(n)||(Dd.add(n),t={rel:t,crossOrigin:l,href:e},a.querySelector(n)===null&&(e=a.createElement("link"),$t(e,"link",t),Qt(e),a.head.appendChild(e)))}}function qv(t){al.D(t),Cd("dns-prefetch",t,null)}function Lv(t,e){al.C(t,e),Cd("preconnect",t,e)}function Yv(t,e,l){al.L(t,e,l);var a=Ca;if(a&&t&&e){var n='link[rel="preload"][as="'+be(e)+'"]';e==="image"&&l&&l.imageSrcSet?(n+='[imagesrcset="'+be(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(n+='[imagesizes="'+be(l.imageSizes)+'"]')):n+='[href="'+be(t)+'"]';var u=n;switch(e){case"style":u=Ua(t);break;case"script":u=ja(t)}xe.has(u)||(t=R({rel:"preload",href:e==="image"&&l&&l.imageSrcSet?void 0:t,as:e},l),xe.set(u,t),a.querySelector(n)!==null||e==="style"&&a.querySelector(On(u))||e==="script"&&a.querySelector(xn(u))||(e=a.createElement("link"),$t(e,"link",t),Qt(e),a.head.appendChild(e)))}}function Gv(t,e){al.m(t,e);var l=Ca;if(l&&t){var a=e&&typeof e.as=="string"?e.as:"script",n='link[rel="modulepreload"][as="'+be(a)+'"][href="'+be(t)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=ja(t)}if(!xe.has(u)&&(t=R({rel:"modulepreload",href:t},e),xe.set(u,t),l.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(xn(u)))return}a=l.createElement("link"),$t(a,"link",t),Qt(a),l.head.appendChild(a)}}}function Xv(t,e,l){al.S(t,e,l);var a=Ca;if(a&&t){var n=ea(a).hoistableStyles,u=Ua(t);e=e||"default";var i=n.get(u);if(!i){var s={loading:0,preload:null};if(i=a.querySelector(On(u)))s.loading=5;else{t=R({rel:"stylesheet",href:t,"data-precedence":e},l),(l=xe.get(u))&&bf(t,l);var m=i=a.createElement("link");Qt(m),$t(m,"link",t),m._p=new Promise(function(z,N){m.onload=z,m.onerror=N}),m.addEventListener("load",function(){s.loading|=1}),m.addEventListener("error",function(){s.loading|=2}),s.loading|=4,Ku(i,e,a)}i={type:"stylesheet",instance:i,count:1,state:s},n.set(u,i)}}}function Qv(t,e){al.X(t,e);var l=Ca;if(l&&t){var a=ea(l).hoistableScripts,n=ja(t),u=a.get(n);u||(u=l.querySelector(xn(n)),u||(t=R({src:t,async:!0},e),(e=xe.get(n))&&Ef(t,e),u=l.createElement("script"),Qt(u),$t(u,"link",t),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Zv(t,e){al.M(t,e);var l=Ca;if(l&&t){var a=ea(l).hoistableScripts,n=ja(t),u=a.get(n);u||(u=l.querySelector(xn(n)),u||(t=R({src:t,async:!0,type:"module"},e),(e=xe.get(n))&&Ef(t,e),u=l.createElement("script"),Qt(u),$t(u,"link",t),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Ud(t,e,l,a){var n=(n=ct.current)?wu(n):null;if(!n)throw Error(f(446));switch(t){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(e=Ua(l.href),l=ea(n).hoistableStyles,a=l.get(e),a||(a={type:"style",instance:null,count:0,state:null},l.set(e,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){t=Ua(l.href);var u=ea(n).hoistableStyles,i=u.get(t);if(i||(n=n.ownerDocument||n,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(t,i),(u=n.querySelector(On(t)))&&!u._p&&(i.instance=u,i.state.loading=5),xe.has(t)||(l={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},xe.set(t,l),u||Vv(n,t,l,i.state))),e&&a===null)throw Error(f(528,""));return i}if(e&&a!==null)throw Error(f(529,""));return null;case"script":return e=l.async,l=l.src,typeof l=="string"&&e&&typeof e!="function"&&typeof e!="symbol"?(e=ja(l),l=ea(n).hoistableScripts,a=l.get(e),a||(a={type:"script",instance:null,count:0,state:null},l.set(e,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(f(444,t))}}function Ua(t){return'href="'+be(t)+'"'}function On(t){return'link[rel="stylesheet"]['+t+"]"}function jd(t){return R({},t,{"data-precedence":t.precedence,precedence:null})}function Vv(t,e,l,a){t.querySelector('link[rel="preload"][as="style"]['+e+"]")?a.loading=1:(e=t.createElement("link"),a.preload=e,e.addEventListener("load",function(){return a.loading|=1}),e.addEventListener("error",function(){return a.loading|=2}),$t(e,"link",l),Qt(e),t.head.appendChild(e))}function ja(t){return'[src="'+be(t)+'"]'}function xn(t){return"script[async]"+t}function Hd(t,e,l){if(e.count++,e.instance===null)switch(e.type){case"style":var a=t.querySelector('style[data-href~="'+be(l.href)+'"]');if(a)return e.instance=a,Qt(a),a;var n=R({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return a=(t.ownerDocument||t).createElement("style"),Qt(a),$t(a,"style",n),Ku(a,l.precedence,t),e.instance=a;case"stylesheet":n=Ua(l.href);var u=t.querySelector(On(n));if(u)return e.state.loading|=4,e.instance=u,Qt(u),u;a=jd(l),(n=xe.get(n))&&bf(a,n),u=(t.ownerDocument||t).createElement("link"),Qt(u);var i=u;return i._p=new Promise(function(s,m){i.onload=s,i.onerror=m}),$t(u,"link",a),e.state.loading|=4,Ku(u,l.precedence,t),e.instance=u;case"script":return u=ja(l.src),(n=t.querySelector(xn(u)))?(e.instance=n,Qt(n),n):(a=l,(n=xe.get(u))&&(a=R({},l),Ef(a,n)),t=t.ownerDocument||t,n=t.createElement("script"),Qt(n),$t(n,"link",a),t.head.appendChild(n),e.instance=n);case"void":return null;default:throw Error(f(443,e.type))}else e.type==="stylesheet"&&(e.state.loading&4)===0&&(a=e.instance,e.state.loading|=4,Ku(a,l.precedence,t));return e.instance}function Ku(t,e,l){for(var a=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,i=0;i title"):null)}function wv(t,e,l){if(l===1||e.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof e.precedence!="string"||typeof e.href!="string"||e.href==="")break;return!0;case"link":if(typeof e.rel!="string"||typeof e.href!="string"||e.href===""||e.onLoad||e.onError)break;return e.rel==="stylesheet"?(t=e.disabled,typeof e.precedence=="string"&&t==null):!0;case"script":if(e.async&&typeof e.async!="function"&&typeof e.async!="symbol"&&!e.onLoad&&!e.onError&&e.src&&typeof e.src=="string")return!0}return!1}function Ld(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function Kv(t,e,l,a){if(l.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var n=Ua(a.href),u=e.querySelector(On(n));if(u){e=u._p,e!==null&&typeof e=="object"&&typeof e.then=="function"&&(t.count++,t=$u.bind(t),e.then(t,t)),l.state.loading|=4,l.instance=u,Qt(u);return}u=e.ownerDocument||e,a=jd(a),(n=xe.get(n))&&bf(a,n),u=u.createElement("link"),Qt(u);var i=u;i._p=new Promise(function(s,m){i.onload=s,i.onerror=m}),$t(u,"link",a),l.instance=u}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(l,e),(e=l.state.preload)&&(l.state.loading&3)===0&&(t.count++,l=$u.bind(t),e.addEventListener("load",l),e.addEventListener("error",l))}}var Tf=0;function Jv(t,e){return t.stylesheets&&t.count===0&&Wu(t,t.stylesheets),0Tf?50:800)+e);return t.unsuspend=l,function(){t.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function $u(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Wu(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var ku=null;function Wu(t,e){t.stylesheets=null,t.unsuspend!==null&&(t.count++,ku=new Map,e.forEach($v,t),ku=null,$u.call(t))}function $v(t,e){if(!(e.state.loading&4)){var l=ku.get(t);if(l)var a=l.get(null);else{l=new Map,ku.set(t,l);for(var n=t.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(c)}catch(r){console.error(r)}}return c(),Df.exports=ry(),Df.exports}var dy=oy();var fh="popstate";function hy(c={}){function r(f,d){let{pathname:h,search:p,hash:A}=f.location;return Yf("",{pathname:h,search:p,hash:A},d.state&&d.state.usr||null,d.state&&d.state.key||"default")}function o(f,d){return typeof d=="string"?d:Bn(d)}return vy(r,o,null,c)}function Mt(c,r){if(c===!1||c===null||typeof c>"u")throw new Error(r)}function Me(c,r){if(!c){typeof console<"u"&&console.warn(r);try{throw new Error(r)}catch{}}}function my(){return Math.random().toString(36).substring(2,10)}function sh(c,r){return{usr:c.state,key:c.key,idx:r}}function Yf(c,r,o=null,f){return{pathname:typeof c=="string"?c:c.pathname,search:"",hash:"",...typeof r=="string"?Ba(r):r,state:o,key:r&&r.key||f||my()}}function Bn({pathname:c="/",search:r="",hash:o=""}){return r&&r!=="?"&&(c+=r.charAt(0)==="?"?r:"?"+r),o&&o!=="#"&&(c+=o.charAt(0)==="#"?o:"#"+o),c}function Ba(c){let r={};if(c){let o=c.indexOf("#");o>=0&&(r.hash=c.substring(o),c=c.substring(0,o));let f=c.indexOf("?");f>=0&&(r.search=c.substring(f),c=c.substring(0,f)),c&&(r.pathname=c)}return r}function vy(c,r,o,f={}){let{window:d=document.defaultView,v5Compat:h=!1}=f,p=d.history,A="POP",S=null,v=x();v==null&&(v=0,p.replaceState({...p.state,idx:v},""));function x(){return(p.state||{idx:null}).idx}function R(){A="POP";let H=x(),G=H==null?null:H-v;v=H,S&&S({action:A,location:Q.location,delta:G})}function B(H,G){A="PUSH";let q=Yf(Q.location,H,G);v=x()+1;let $=sh(q,v),W=Q.createHref(q);try{p.pushState($,"",W)}catch(I){if(I instanceof DOMException&&I.name==="DataCloneError")throw I;d.location.assign(W)}h&&S&&S({action:A,location:Q.location,delta:1})}function Z(H,G){A="REPLACE";let q=Yf(Q.location,H,G);v=x();let $=sh(q,v),W=Q.createHref(q);p.replaceState($,"",W),h&&S&&S({action:A,location:Q.location,delta:0})}function k(H){return yy(H)}let Q={get action(){return A},get location(){return c(d,p)},listen(H){if(S)throw new Error("A history only accepts one active listener");return d.addEventListener(fh,R),S=H,()=>{d.removeEventListener(fh,R),S=null}},createHref(H){return r(d,H)},createURL:k,encodeLocation(H){let G=k(H);return{pathname:G.pathname,search:G.search,hash:G.hash}},push:B,replace:Z,go(H){return p.go(H)}};return Q}function yy(c,r=!1){let o="http://localhost";typeof window<"u"&&(o=window.location.origin!=="null"?window.location.origin:window.location.href),Mt(o,"No window.location.(origin|href) available to create URL");let f=typeof c=="string"?c:Bn(c);return f=f.replace(/ $/,"%20"),!r&&f.startsWith("//")&&(f=o+f),new URL(f,o)}function mh(c,r,o="/"){return gy(c,r,o,!1)}function gy(c,r,o,f){let d=typeof r=="string"?Ba(r):r,h=ul(d.pathname||"/",o);if(h==null)return null;let p=vh(c);py(p);let A=null;for(let S=0;A==null&&S{let x={relativePath:v===void 0?p.path||"":v,caseSensitive:p.caseSensitive===!0,childrenIndex:A,route:p};if(x.relativePath.startsWith("/")){if(!x.relativePath.startsWith(f)&&S)return;Mt(x.relativePath.startsWith(f),`Absolute route path "${x.relativePath}" nested under path "${f}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),x.relativePath=x.relativePath.slice(f.length)}let R=nl([f,x.relativePath]),B=o.concat(x);p.children&&p.children.length>0&&(Mt(p.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${R}".`),vh(p.children,r,B,R,S)),!(p.path==null&&!p.index)&&r.push({path:R,score:_y(R,p.index),routesMeta:B})};return c.forEach((p,A)=>{if(p.path===""||!p.path?.includes("?"))h(p,A);else for(let S of yh(p.path))h(p,A,!0,S)}),r}function yh(c){let r=c.split("/");if(r.length===0)return[];let[o,...f]=r,d=o.endsWith("?"),h=o.replace(/\?$/,"");if(f.length===0)return d?[h,""]:[h];let p=yh(f.join("/")),A=[];return A.push(...p.map(S=>S===""?h:[h,S].join("/"))),d&&A.push(...p),A.map(S=>c.startsWith("/")&&S===""?"/":S)}function py(c){c.sort((r,o)=>r.score!==o.score?o.score-r.score:Ry(r.routesMeta.map(f=>f.childrenIndex),o.routesMeta.map(f=>f.childrenIndex)))}var Sy=/^:[\w-]+$/,by=3,Ey=2,Ty=1,zy=10,Ay=-2,rh=c=>c==="*";function _y(c,r){let o=c.split("/"),f=o.length;return o.some(rh)&&(f+=Ay),r&&(f+=Ey),o.filter(d=>!rh(d)).reduce((d,h)=>d+(Sy.test(h)?by:h===""?Ty:zy),f)}function Ry(c,r){return c.length===r.length&&c.slice(0,-1).every((f,d)=>f===r[d])?c[c.length-1]-r[r.length-1]:0}function Oy(c,r,o=!1){let{routesMeta:f}=c,d={},h="/",p=[];for(let A=0;A{if(x==="*"){let k=A[B]||"";p=h.slice(0,h.length-k.length).replace(/(.)\/+$/,"$1")}const Z=A[B];return R&&!Z?v[x]=void 0:v[x]=(Z||"").replace(/%2F/g,"/"),v},{}),pathname:h,pathnameBase:p,pattern:c}}function xy(c,r=!1,o=!0){Me(c==="*"||!c.endsWith("*")||c.endsWith("/*"),`Route path "${c}" will be treated as if it were "${c.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${c.replace(/\*$/,"/*")}".`);let f=[],d="^"+c.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(p,A,S)=>(f.push({paramName:A,isOptional:S!=null}),S?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return c.endsWith("*")?(f.push({paramName:"*"}),d+=c==="*"||c==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):o?d+="\\/*$":c!==""&&c!=="/"&&(d+="(?:(?=\\/|$))"),[new RegExp(d,r?void 0:"i"),f]}function My(c){try{return c.split("/").map(r=>decodeURIComponent(r).replace(/\//g,"%2F")).join("/")}catch(r){return Me(!1,`The URL path "${c}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${r}).`),c}}function ul(c,r){if(r==="/")return c;if(!c.toLowerCase().startsWith(r.toLowerCase()))return null;let o=r.endsWith("/")?r.length-1:r.length,f=c.charAt(o);return f&&f!=="/"?null:c.slice(o)||"/"}var Ny=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function Dy(c,r="/"){let{pathname:o,search:f="",hash:d=""}=typeof c=="string"?Ba(c):c,h;return o?(o=o.replace(/\/\/+/g,"/"),o.startsWith("/")?h=oh(o.substring(1),"/"):h=oh(o,r)):h=r,{pathname:h,search:jy(f),hash:Hy(d)}}function oh(c,r){let o=r.replace(/\/+$/,"").split("/");return c.split("/").forEach(d=>{d===".."?o.length>1&&o.pop():d!=="."&&o.push(d)}),o.length>1?o.join("/"):"/"}function Hf(c,r,o,f){return`Cannot include a '${c}' character in a manually specified \`to.${r}\` field [${JSON.stringify(f)}]. Please separate it out to the \`to.${o}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function Cy(c){return c.filter((r,o)=>o===0||r.route.path&&r.route.path.length>0)}function Zf(c){let r=Cy(c);return r.map((o,f)=>f===r.length-1?o.pathname:o.pathnameBase)}function Vf(c,r,o,f=!1){let d;typeof c=="string"?d=Ba(c):(d={...c},Mt(!d.pathname||!d.pathname.includes("?"),Hf("?","pathname","search",d)),Mt(!d.pathname||!d.pathname.includes("#"),Hf("#","pathname","hash",d)),Mt(!d.search||!d.search.includes("#"),Hf("#","search","hash",d)));let h=c===""||d.pathname==="",p=h?"/":d.pathname,A;if(p==null)A=o;else{let R=r.length-1;if(!f&&p.startsWith("..")){let B=p.split("/");for(;B[0]==="..";)B.shift(),R-=1;d.pathname=B.join("/")}A=R>=0?r[R]:"/"}let S=Dy(d,A),v=p&&p!=="/"&&p.endsWith("/"),x=(h||p===".")&&o.endsWith("/");return!S.pathname.endsWith("/")&&(v||x)&&(S.pathname+="/"),S}var nl=c=>c.join("/").replace(/\/\/+/g,"/"),Uy=c=>c.replace(/\/+$/,"").replace(/^\/*/,"/"),jy=c=>!c||c==="?"?"":c.startsWith("?")?c:"?"+c,Hy=c=>!c||c==="#"?"":c.startsWith("#")?c:"#"+c,By=class{constructor(c,r,o,f=!1){this.status=c,this.statusText=r||"",this.internal=f,o instanceof Error?(this.data=o.toString(),this.error=o):this.data=o}};function qy(c){return c!=null&&typeof c.status=="number"&&typeof c.statusText=="string"&&typeof c.internal=="boolean"&&"data"in c}function Ly(c){return c.map(r=>r.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var gh=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function ph(c,r){let o=c;if(typeof o!="string"||!Ny.test(o))return{absoluteURL:void 0,isExternal:!1,to:o};let f=o,d=!1;if(gh)try{let h=new URL(window.location.href),p=o.startsWith("//")?new URL(h.protocol+o):new URL(o),A=ul(p.pathname,r);p.origin===h.origin&&A!=null?o=A+p.search+p.hash:d=!0}catch{Me(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:f,isExternal:d,to:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Sh=["POST","PUT","PATCH","DELETE"];new Set(Sh);var Yy=["GET",...Sh];new Set(Yy);var qa=T.createContext(null);qa.displayName="DataRouter";var fi=T.createContext(null);fi.displayName="DataRouterState";var Gy=T.createContext(!1),bh=T.createContext({isTransitioning:!1});bh.displayName="ViewTransition";var Xy=T.createContext(new Map);Xy.displayName="Fetchers";var Qy=T.createContext(null);Qy.displayName="Await";var ge=T.createContext(null);ge.displayName="Navigation";var qn=T.createContext(null);qn.displayName="Location";var Ue=T.createContext({outlet:null,matches:[],isDataRoute:!1});Ue.displayName="Route";var wf=T.createContext(null);wf.displayName="RouteError";var Eh="REACT_ROUTER_ERROR",Zy="REDIRECT",Vy="ROUTE_ERROR_RESPONSE";function wy(c){if(c.startsWith(`${Eh}:${Zy}:{`))try{let r=JSON.parse(c.slice(28));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string"&&typeof r.location=="string"&&typeof r.reloadDocument=="boolean"&&typeof r.replace=="boolean")return r}catch{}}function Ky(c){if(c.startsWith(`${Eh}:${Vy}:{`))try{let r=JSON.parse(c.slice(40));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string")return new By(r.status,r.statusText,r.data)}catch{}}function Jy(c,{relative:r}={}){Mt(La(),"useHref() may be used only in the context of a component.");let{basename:o,navigator:f}=T.useContext(ge),{hash:d,pathname:h,search:p}=Yn(c,{relative:r}),A=h;return o!=="/"&&(A=h==="/"?o:nl([o,h])),f.createHref({pathname:A,search:p,hash:d})}function La(){return T.useContext(qn)!=null}function je(){return Mt(La(),"useLocation() may be used only in the context of a component."),T.useContext(qn).location}var Th="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function zh(c){T.useContext(ge).static||T.useLayoutEffect(c)}function Ln(){let{isDataRoute:c}=T.useContext(Ue);return c?i0():$y()}function $y(){Mt(La(),"useNavigate() may be used only in the context of a component.");let c=T.useContext(qa),{basename:r,navigator:o}=T.useContext(ge),{matches:f}=T.useContext(Ue),{pathname:d}=je(),h=JSON.stringify(Zf(f)),p=T.useRef(!1);return zh(()=>{p.current=!0}),T.useCallback((S,v={})=>{if(Me(p.current,Th),!p.current)return;if(typeof S=="number"){o.go(S);return}let x=Vf(S,JSON.parse(h),d,v.relative==="path");c==null&&r!=="/"&&(x.pathname=x.pathname==="/"?r:nl([r,x.pathname])),(v.replace?o.replace:o.push)(x,v.state,v)},[r,o,h,d,c])}T.createContext(null);function Ah(){let{matches:c}=T.useContext(Ue),r=c[c.length-1];return r?r.params:{}}function Yn(c,{relative:r}={}){let{matches:o}=T.useContext(Ue),{pathname:f}=je(),d=JSON.stringify(Zf(o));return T.useMemo(()=>Vf(c,JSON.parse(d),f,r==="path"),[c,d,f,r])}function ky(c,r){return _h(c,r)}function _h(c,r,o,f,d){Mt(La(),"useRoutes() may be used only in the context of a component.");let{navigator:h}=T.useContext(ge),{matches:p}=T.useContext(Ue),A=p[p.length-1],S=A?A.params:{},v=A?A.pathname:"/",x=A?A.pathnameBase:"/",R=A&&A.route;{let q=R&&R.path||"";Oh(v,!R||q.endsWith("*")||q.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${v}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. - -Please change the parent to .`)}let B=je(),Z;if(r){let q=typeof r=="string"?Ba(r):r;Mt(x==="/"||q.pathname?.startsWith(x),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${x}" but pathname "${q.pathname}" was given in the \`location\` prop.`),Z=q}else Z=B;let k=Z.pathname||"/",Q=k;if(x!=="/"){let q=x.replace(/^\//,"").split("/");Q="/"+k.replace(/^\//,"").split("/").slice(q.length).join("/")}let H=mh(c,{pathname:Q});Me(R||H!=null,`No routes matched location "${Z.pathname}${Z.search}${Z.hash}" `),Me(H==null||H[H.length-1].route.element!==void 0||H[H.length-1].route.Component!==void 0||H[H.length-1].route.lazy!==void 0,`Matched leaf route at location "${Z.pathname}${Z.search}${Z.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let G=t0(H&&H.map(q=>Object.assign({},q,{params:Object.assign({},S,q.params),pathname:nl([x,h.encodeLocation?h.encodeLocation(q.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:q.pathname]),pathnameBase:q.pathnameBase==="/"?x:nl([x,h.encodeLocation?h.encodeLocation(q.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:q.pathnameBase])})),p,o,f,d);return r&&G?T.createElement(qn.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...Z},navigationType:"POP"}},G):G}function Wy(){let c=u0(),r=qy(c)?`${c.status} ${c.statusText}`:c instanceof Error?c.message:JSON.stringify(c),o=c instanceof Error?c.stack:null,f="rgba(200,200,200, 0.5)",d={padding:"0.5rem",backgroundColor:f},h={padding:"2px 4px",backgroundColor:f},p=null;return console.error("Error handled by React Router default ErrorBoundary:",c),p=T.createElement(T.Fragment,null,T.createElement("p",null,"💿 Hey developer 👋"),T.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",T.createElement("code",{style:h},"ErrorBoundary")," or"," ",T.createElement("code",{style:h},"errorElement")," prop on your route.")),T.createElement(T.Fragment,null,T.createElement("h2",null,"Unexpected Application Error!"),T.createElement("h3",{style:{fontStyle:"italic"}},r),o?T.createElement("pre",{style:d},o):null,p)}var Fy=T.createElement(Wy,null),Rh=class extends T.Component{constructor(c){super(c),this.state={location:c.location,revalidation:c.revalidation,error:c.error}}static getDerivedStateFromError(c){return{error:c}}static getDerivedStateFromProps(c,r){return r.location!==c.location||r.revalidation!=="idle"&&c.revalidation==="idle"?{error:c.error,location:c.location,revalidation:c.revalidation}:{error:c.error!==void 0?c.error:r.error,location:r.location,revalidation:c.revalidation||r.revalidation}}componentDidCatch(c,r){this.props.onError?this.props.onError(c,r):console.error("React Router caught the following error during render",c)}render(){let c=this.state.error;if(this.context&&typeof c=="object"&&c&&"digest"in c&&typeof c.digest=="string"){const o=Ky(c.digest);o&&(c=o)}let r=c!==void 0?T.createElement(Ue.Provider,{value:this.props.routeContext},T.createElement(wf.Provider,{value:c,children:this.props.component})):this.props.children;return this.context?T.createElement(Iy,{error:c},r):r}};Rh.contextType=Gy;var Bf=new WeakMap;function Iy({children:c,error:r}){let{basename:o}=T.useContext(ge);if(typeof r=="object"&&r&&"digest"in r&&typeof r.digest=="string"){let f=wy(r.digest);if(f){let d=Bf.get(r);if(d)throw d;let h=ph(f.location,o);if(gh&&!Bf.get(r))if(h.isExternal||f.reloadDocument)window.location.href=h.absoluteURL||h.to;else{const p=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(h.to,{replace:f.replace}));throw Bf.set(r,p),p}return T.createElement("meta",{httpEquiv:"refresh",content:`0;url=${h.absoluteURL||h.to}`})}}return c}function Py({routeContext:c,match:r,children:o}){let f=T.useContext(qa);return f&&f.static&&f.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(f.staticContext._deepestRenderedBoundaryId=r.route.id),T.createElement(Ue.Provider,{value:c},o)}function t0(c,r=[],o=null,f=null,d=null){if(c==null){if(!o)return null;if(o.errors)c=o.matches;else if(r.length===0&&!o.initialized&&o.matches.length>0)c=o.matches;else return null}let h=c,p=o?.errors;if(p!=null){let x=h.findIndex(R=>R.route.id&&p?.[R.route.id]!==void 0);Mt(x>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(p).join(",")}`),h=h.slice(0,Math.min(h.length,x+1))}let A=!1,S=-1;if(o)for(let x=0;x=0?h=h.slice(0,S+1):h=[h[0]];break}}}let v=o&&f?(x,R)=>{f(x,{location:o.location,params:o.matches?.[0]?.params??{},unstable_pattern:Ly(o.matches),errorInfo:R})}:void 0;return h.reduceRight((x,R,B)=>{let Z,k=!1,Q=null,H=null;o&&(Z=p&&R.route.id?p[R.route.id]:void 0,Q=R.route.errorElement||Fy,A&&(S<0&&B===0?(Oh("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),k=!0,H=null):S===B&&(k=!0,H=R.route.hydrateFallbackElement||null)));let G=r.concat(h.slice(0,B+1)),q=()=>{let $;return Z?$=Q:k?$=H:R.route.Component?$=T.createElement(R.route.Component,null):R.route.element?$=R.route.element:$=x,T.createElement(Py,{match:R,routeContext:{outlet:x,matches:G,isDataRoute:o!=null},children:$})};return o&&(R.route.ErrorBoundary||R.route.errorElement||B===0)?T.createElement(Rh,{location:o.location,revalidation:o.revalidation,component:Q,error:Z,children:q(),routeContext:{outlet:null,matches:G,isDataRoute:!0},onError:v}):q()},null)}function Kf(c){return`${c} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function e0(c){let r=T.useContext(qa);return Mt(r,Kf(c)),r}function l0(c){let r=T.useContext(fi);return Mt(r,Kf(c)),r}function a0(c){let r=T.useContext(Ue);return Mt(r,Kf(c)),r}function Jf(c){let r=a0(c),o=r.matches[r.matches.length-1];return Mt(o.route.id,`${c} can only be used on routes that contain a unique "id"`),o.route.id}function n0(){return Jf("useRouteId")}function u0(){let c=T.useContext(wf),r=l0("useRouteError"),o=Jf("useRouteError");return c!==void 0?c:r.errors?.[o]}function i0(){let{router:c}=e0("useNavigate"),r=Jf("useNavigate"),o=T.useRef(!1);return zh(()=>{o.current=!0}),T.useCallback(async(d,h={})=>{Me(o.current,Th),o.current&&(typeof d=="number"?await c.navigate(d):await c.navigate(d,{fromRouteId:r,...h}))},[c,r])}var dh={};function Oh(c,r,o){!r&&!dh[c]&&(dh[c]=!0,Me(!1,o))}T.memo(c0);function c0({routes:c,future:r,state:o,onError:f}){return _h(c,void 0,o,f,r)}function f0({to:c,replace:r,state:o,relative:f}){Mt(La()," may be used only in the context of a component.");let{static:d}=T.useContext(ge);Me(!d," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:h}=T.useContext(Ue),{pathname:p}=je(),A=Ln(),S=Vf(c,Zf(h),p,f==="path"),v=JSON.stringify(S);return T.useEffect(()=>{A(JSON.parse(v),{replace:r,state:o,relative:f})},[A,v,f,r,o]),null}function Fl(c){Mt(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function s0({basename:c="/",children:r=null,location:o,navigationType:f="POP",navigator:d,static:h=!1,unstable_useTransitions:p}){Mt(!La(),"You cannot render a inside another . You should never have more than one in your app.");let A=c.replace(/^\/*/,"/"),S=T.useMemo(()=>({basename:A,navigator:d,static:h,unstable_useTransitions:p,future:{}}),[A,d,h,p]);typeof o=="string"&&(o=Ba(o));let{pathname:v="/",search:x="",hash:R="",state:B=null,key:Z="default"}=o,k=T.useMemo(()=>{let Q=ul(v,A);return Q==null?null:{location:{pathname:Q,search:x,hash:R,state:B,key:Z},navigationType:f}},[A,v,x,R,B,Z,f]);return Me(k!=null,` is not able to match the URL "${v}${x}${R}" because it does not start with the basename, so the won't render anything.`),k==null?null:T.createElement(ge.Provider,{value:S},T.createElement(qn.Provider,{children:r,value:k}))}function xh({children:c,location:r}){return ky(Gf(c),r)}function Gf(c,r=[]){let o=[];return T.Children.forEach(c,(f,d)=>{if(!T.isValidElement(f))return;let h=[...r,d];if(f.type===T.Fragment){o.push.apply(o,Gf(f.props.children,h));return}Mt(f.type===Fl,`[${typeof f.type=="string"?f.type:f.type.name}] is not a component. All component children of must be a or `),Mt(!f.props.index||!f.props.children,"An index route cannot have child routes.");let p={id:f.props.id||h.join("-"),caseSensitive:f.props.caseSensitive,element:f.props.element,Component:f.props.Component,index:f.props.index,path:f.props.path,middleware:f.props.middleware,loader:f.props.loader,action:f.props.action,hydrateFallbackElement:f.props.hydrateFallbackElement,HydrateFallback:f.props.HydrateFallback,errorElement:f.props.errorElement,ErrorBoundary:f.props.ErrorBoundary,hasErrorBoundary:f.props.hasErrorBoundary===!0||f.props.ErrorBoundary!=null||f.props.errorElement!=null,shouldRevalidate:f.props.shouldRevalidate,handle:f.props.handle,lazy:f.props.lazy};f.props.children&&(p.children=Gf(f.props.children,h)),o.push(p)}),o}var ui="get",ii="application/x-www-form-urlencoded";function si(c){return typeof HTMLElement<"u"&&c instanceof HTMLElement}function r0(c){return si(c)&&c.tagName.toLowerCase()==="button"}function o0(c){return si(c)&&c.tagName.toLowerCase()==="form"}function d0(c){return si(c)&&c.tagName.toLowerCase()==="input"}function h0(c){return!!(c.metaKey||c.altKey||c.ctrlKey||c.shiftKey)}function m0(c,r){return c.button===0&&(!r||r==="_self")&&!h0(c)}function Xf(c=""){return new URLSearchParams(typeof c=="string"||Array.isArray(c)||c instanceof URLSearchParams?c:Object.keys(c).reduce((r,o)=>{let f=c[o];return r.concat(Array.isArray(f)?f.map(d=>[o,d]):[[o,f]])},[]))}function v0(c,r){let o=Xf(c);return r&&r.forEach((f,d)=>{o.has(d)||r.getAll(d).forEach(h=>{o.append(d,h)})}),o}var ni=null;function y0(){if(ni===null)try{new FormData(document.createElement("form"),0),ni=!1}catch{ni=!0}return ni}var g0=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function qf(c){return c!=null&&!g0.has(c)?(Me(!1,`"${c}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${ii}"`),null):c}function p0(c,r){let o,f,d,h,p;if(o0(c)){let A=c.getAttribute("action");f=A?ul(A,r):null,o=c.getAttribute("method")||ui,d=qf(c.getAttribute("enctype"))||ii,h=new FormData(c)}else if(r0(c)||d0(c)&&(c.type==="submit"||c.type==="image")){let A=c.form;if(A==null)throw new Error('Cannot submit a