diff --git a/.github/workflows/hacs-validate.yml b/.github/workflows/hacs-validate.yml new file mode 100644 index 000000000..111ead4d9 --- /dev/null +++ b/.github/workflows/hacs-validate.yml @@ -0,0 +1,17 @@ +name: Validate HACS + +on: + push: + pull_request: + workflow_dispatch: + +permissions: {} + +jobs: + validate-hacs: + runs-on: ubuntu-latest + steps: + - name: HACS validation + uses: hacs/action@main + with: + category: plugin diff --git a/.gitignore b/.gitignore index d01fc0bdd..d47dff39c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ package-lock.json # Testing coverage +test-results/ # Turbo .turbo @@ -30,7 +31,9 @@ supabase/.temp/ .next/ out/ build -dist +**/dist/ +!/dist/ +!/dist/pascal-viewer-card.js *.tsbuildinfo diff --git a/apps/editor/app/api/home-assistant/connect/route.ts b/apps/editor/app/api/home-assistant/connect/route.ts new file mode 100644 index 000000000..772e46a70 --- /dev/null +++ b/apps/editor/app/api/home-assistant/connect/route.ts @@ -0,0 +1,32 @@ +import { + resolveHomeAssistantServerConfig, + validateHomeAssistantConnection, +} from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +export async function GET() { + try { + const result = await validateHomeAssistantConnection(await resolveHomeAssistantServerConfig()) + return Response.json(result, { status: result.success ? 200 : 200 }) + } catch (error) { + const message = error instanceof Error ? error.message : 'Failed to connect to Home Assistant.' + return Response.json( + { + baseUrl: null, + castEntityId: null, + castFriendlyName: null, + clientId: null, + entityCount: 0, + error: message, + externalUrl: null, + instanceUrl: null, + linked: false, + message, + mode: 'unlinked', + success: false, + }, + { status: 500 }, + ) + } +} diff --git a/apps/editor/app/api/home-assistant/connection-status/route.ts b/apps/editor/app/api/home-assistant/connection-status/route.ts new file mode 100644 index 000000000..283e0f2fc --- /dev/null +++ b/apps/editor/app/api/home-assistant/connection-status/route.ts @@ -0,0 +1,32 @@ +import { + resolveHomeAssistantServerConfig, + validateHomeAssistantConnection, +} from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +export async function GET() { + try { + const result = await validateHomeAssistantConnection(await resolveHomeAssistantServerConfig()) + return Response.json(result, { status: result.success ? 200 : 200 }) + } catch (error) { + const message = error instanceof Error ? error.message : 'Failed to connect to Home Assistant.' + return Response.json( + { + baseUrl: null, + castEntityId: null, + castFriendlyName: null, + clientId: null, + entityCount: 0, + error: message, + externalUrl: null, + instanceUrl: null, + linked: false, + message, + mode: 'unlinked', + success: false, + }, + { status: 200 }, + ) + } +} diff --git a/apps/editor/app/api/home-assistant/device-action/route.ts b/apps/editor/app/api/home-assistant/device-action/route.ts new file mode 100644 index 000000000..8afd4e0b0 --- /dev/null +++ b/apps/editor/app/api/home-assistant/device-action/route.ts @@ -0,0 +1,70 @@ +import type { + HomeAssistantActionRequest, + HomeAssistantCollectionBinding, +} from '@pascal-app/home-assistant' +import { getHomeAssistantLink } from '@pascal-app/home-assistant' +import { + resolveHomeAssistantServerConfig, + runHomeAssistantCollectionAction, + runHomeAssistantDeviceAction, +} from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +type DeviceActionRequestBody = { + binding?: HomeAssistantCollectionBinding + collectionName?: string + itemName?: string + link?: unknown + request?: HomeAssistantActionRequest +} + +export async function POST(request: Request) { + try { + const body = (await request.json()) as DeviceActionRequestBody + if ( + body.binding && + typeof body.binding === 'object' && + body.request && + typeof body.request === 'object' + ) { + const collectionName = + typeof body.collectionName === 'string' && body.collectionName.trim().length > 0 + ? body.collectionName.trim() + : 'Linked collection' + + const result = await runHomeAssistantCollectionAction( + await resolveHomeAssistantServerConfig(), + collectionName, + body.binding, + body.request, + ) + return Response.json(result) + } + + const itemName = + typeof body.itemName === 'string' && body.itemName.trim().length > 0 + ? body.itemName.trim() + : 'Linked item' + const link = getHomeAssistantLink({ + homeAssistantLink: body.link, + }) + + if (!link) { + return Response.json( + { error: 'Missing or invalid Home Assistant link payload.' }, + { status: 400 }, + ) + } + + const result = await runHomeAssistantDeviceAction( + await resolveHomeAssistantServerConfig(), + itemName, + link, + ) + return Response.json(result) + } catch (error) { + const message = error instanceof Error ? error.message : 'Unknown Home Assistant action error.' + return Response.json({ error: message }, { status: 500 }) + } +} diff --git a/apps/editor/app/api/home-assistant/discover-devices/route.ts b/apps/editor/app/api/home-assistant/discover-devices/route.ts new file mode 100644 index 000000000..5dc8d8f60 --- /dev/null +++ b/apps/editor/app/api/home-assistant/discover-devices/route.ts @@ -0,0 +1,38 @@ +import { discoverHomeAssistantDevices } from '@pascal-app/home-assistant/server' +import { + hasHomeAssistantServerConfig, + resolveHomeAssistantServerConfig, +} from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +export async function GET() { + try { + const config = await resolveHomeAssistantServerConfig() + if (!hasHomeAssistantServerConfig(config)) { + return Response.json( + { + devices: [], + error: 'Home Assistant is not linked yet.', + }, + { status: 412 }, + ) + } + + const devices = await discoverHomeAssistantDevices(config) + return Response.json({ + devices, + scannedAt: new Date().toISOString(), + }) + } catch (error) { + const message = + error instanceof Error ? error.message : 'Unknown Home Assistant discovery error.' + return Response.json( + { + devices: [], + error: message, + }, + { status: 500 }, + ) + } +} diff --git a/apps/editor/app/api/home-assistant/discover-instances/route.ts b/apps/editor/app/api/home-assistant/discover-instances/route.ts new file mode 100644 index 000000000..e6ded6b6f --- /dev/null +++ b/apps/editor/app/api/home-assistant/discover-instances/route.ts @@ -0,0 +1,24 @@ +import { discoverHomeAssistantInstances } from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +export async function GET() { + try { + const instances = await discoverHomeAssistantInstances() + return Response.json({ + instances, + scannedAt: new Date().toISOString(), + }) + } catch (error) { + const message = + error instanceof Error ? error.message : 'Unknown Home Assistant discovery error.' + + return Response.json( + { + error: message, + instances: [], + }, + { status: 500 }, + ) + } +} diff --git a/apps/editor/app/api/home-assistant/import-resources/route.ts b/apps/editor/app/api/home-assistant/import-resources/route.ts new file mode 100644 index 000000000..40fefc416 --- /dev/null +++ b/apps/editor/app/api/home-assistant/import-resources/route.ts @@ -0,0 +1,37 @@ +import { listImportableHomeAssistantResources } from '@pascal-app/home-assistant/server' +import { + hasHomeAssistantServerConfig, + resolveHomeAssistantServerConfig, +} from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +export async function GET() { + try { + const config = await resolveHomeAssistantServerConfig() + if (!hasHomeAssistantServerConfig(config)) { + return Response.json( + { + error: 'Home Assistant is not linked yet.', + resources: [], + }, + { status: 412 }, + ) + } + + const resources = await listImportableHomeAssistantResources(config) + return Response.json({ + importedAt: new Date().toISOString(), + resources, + }) + } catch (error) { + const message = error instanceof Error ? error.message : 'Unknown Home Assistant import error.' + return Response.json( + { + error: message, + resources: [], + }, + { status: 500 }, + ) + } +} diff --git a/apps/editor/app/api/home-assistant/oauth/callback/route.ts b/apps/editor/app/api/home-assistant/oauth/callback/route.ts new file mode 100644 index 000000000..8320af37f --- /dev/null +++ b/apps/editor/app/api/home-assistant/oauth/callback/route.ts @@ -0,0 +1,81 @@ +import type { NextRequest } from 'next/server' +import { NextResponse } from 'next/server' +import { + exchangeAuthorizationCode, + HOME_ASSISTANT_OAUTH_COOKIE, +} from '@pascal-app/home-assistant/server' +import { writeLinkedHomeAssistantProfile } from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +function buildRedirectUrl(base: string, status: 'success' | 'error', message?: string) { + const redirectUrl = new URL('/', base) + redirectUrl.searchParams.set('ha_link', status) + if (message) { + redirectUrl.searchParams.set('ha_message', message) + } + return redirectUrl +} + +export async function GET(request: NextRequest) { + const oauthCookie = request.cookies.get(HOME_ASSISTANT_OAUTH_COOKIE)?.value + const fallbackBase = request.nextUrl.origin + + if (!oauthCookie) { + return NextResponse.redirect( + buildRedirectUrl(fallbackBase, 'error', 'Missing Home Assistant OAuth state.'), + ) + } + + try { + const oauthState = JSON.parse(oauthCookie) as { + clientId?: string + externalUrl?: string | null + instanceUrl?: string + state?: string + } + const code = request.nextUrl.searchParams.get('code') + const state = request.nextUrl.searchParams.get('state') + + if (!(oauthState.clientId && oauthState.instanceUrl && oauthState.state && code && state)) { + throw new Error('Missing OAuth callback parameters.') + } + + if (state !== oauthState.state) { + throw new Error('Home Assistant OAuth state did not match.') + } + + const tokens = await exchangeAuthorizationCode( + oauthState.instanceUrl, + oauthState.clientId, + code, + oauthState.externalUrl, + ) + + await writeLinkedHomeAssistantProfile({ + accessToken: tokens.access_token, + accessTokenExpiresAt: new Date(Date.now() + tokens.expires_in * 1000).toISOString(), + clientId: oauthState.clientId, + externalUrl: + typeof oauthState.externalUrl === 'string' && oauthState.externalUrl.trim().length > 0 + ? oauthState.externalUrl + : null, + instanceUrl: oauthState.instanceUrl, + linkedAt: new Date().toISOString(), + refreshToken: tokens.refresh_token ?? '', + }) + + const response = NextResponse.redirect(buildRedirectUrl(oauthState.clientId, 'success')) + response.cookies.delete(HOME_ASSISTANT_OAUTH_COOKIE) + return response + } catch (error) { + const message = + error instanceof Error ? error.message : 'Failed to complete Home Assistant sign-in.' + const parsedCookie = JSON.parse(oauthCookie) as { clientId?: string } + const response = NextResponse.redirect( + buildRedirectUrl(parsedCookie.clientId ?? fallbackBase, 'error', message), + ) + response.cookies.delete(HOME_ASSISTANT_OAUTH_COOKIE) + return response + } +} diff --git a/apps/editor/app/api/home-assistant/oauth/start/route.ts b/apps/editor/app/api/home-assistant/oauth/start/route.ts new file mode 100644 index 000000000..4b0593378 --- /dev/null +++ b/apps/editor/app/api/home-assistant/oauth/start/route.ts @@ -0,0 +1,51 @@ +import type { NextRequest } from 'next/server' +import { NextResponse } from 'next/server' +import { + buildHomeAssistantAuthorizeUrl, + buildHomeAssistantOauthState, + HOME_ASSISTANT_OAUTH_COOKIE, + normalizeOptionalHomeAssistantUrl, +} from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +type StartOauthRequestBody = { + externalUrl?: string + instanceUrl?: string +} + +export async function POST(request: NextRequest) { + try { + const body = (await request.json()) as StartOauthRequestBody + const instanceUrl = normalizeOptionalHomeAssistantUrl(body.instanceUrl) + const externalUrl = normalizeOptionalHomeAssistantUrl(body.externalUrl) + const resolvedInstanceUrl = instanceUrl ?? externalUrl + + if (!resolvedInstanceUrl) { + return Response.json( + { error: 'A Home Assistant local or remote URL is required.' }, + { status: 400 }, + ) + } + + const oauthState = buildHomeAssistantOauthState(request, resolvedInstanceUrl, externalUrl) + + const response = NextResponse.json({ + authorizeUrl: buildHomeAssistantAuthorizeUrl(oauthState), + }) + + response.cookies.set(HOME_ASSISTANT_OAUTH_COOKIE, JSON.stringify(oauthState), { + httpOnly: true, + maxAge: 10 * 60, + path: '/', + sameSite: 'lax', + secure: request.nextUrl.protocol === 'https:', + }) + + return response + } catch (error) { + const message = + error instanceof Error ? error.message : 'Failed to start Home Assistant sign-in.' + return Response.json({ error: message }, { status: 500 }) + } +} diff --git a/apps/editor/app/api/home-assistant/unlink/route.ts b/apps/editor/app/api/home-assistant/unlink/route.ts new file mode 100644 index 000000000..990b02d1d --- /dev/null +++ b/apps/editor/app/api/home-assistant/unlink/route.ts @@ -0,0 +1,13 @@ +import { clearLinkedHomeAssistantProfile } from '@pascal-app/home-assistant/server' + +export const runtime = 'nodejs' + +export async function DELETE() { + try { + await clearLinkedHomeAssistantProfile() + return Response.json({ success: true }) + } catch (error) { + const message = error instanceof Error ? error.message : 'Failed to unlink Home Assistant.' + return Response.json({ error: message, success: false }, { status: 500 }) + } +} diff --git a/apps/editor/app/globals.css b/apps/editor/app/globals.css index 78ca5812e..643487698 100644 --- a/apps/editor/app/globals.css +++ b/apps/editor/app/globals.css @@ -1,6 +1,7 @@ @import "tailwindcss"; @import "tw-animate-css"; @source "../../../packages/editor/src"; +@source "../../../packages/home-assistant/src"; @custom-variant dark (&:is(.dark *)); diff --git a/apps/editor/next.config.ts b/apps/editor/next.config.mjs similarity index 57% rename from apps/editor/next.config.ts rename to apps/editor/next.config.mjs index 6c684f1bf..6bf3a4216 100644 --- a/apps/editor/next.config.ts +++ b/apps/editor/next.config.mjs @@ -1,6 +1,10 @@ -import type { NextConfig } from 'next' +import path from 'node:path' +import { fileURLToPath } from 'node:url' -const nextConfig: NextConfig = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +/** @type {import('next').NextConfig} */ +const nextConfig = { typescript: { ignoreBuildErrors: true, }, @@ -12,13 +16,22 @@ const nextConfig: NextConfig = { '@pascal-app/mcp', ], turbopack: { + root: path.resolve(__dirname, '../..'), resolveAlias: { - react: './node_modules/react', - three: './node_modules/three', '@react-three/fiber': './node_modules/@react-three/fiber', '@react-three/drei': './node_modules/@react-three/drei', }, }, + webpack: (config) => { + config.resolve ??= {} + config.resolve.alias = { + ...(config.resolve.alias ?? {}), + '@react-three/fiber': path.resolve(__dirname, 'node_modules/@react-three/fiber'), + '@react-three/drei': path.resolve(__dirname, 'node_modules/@react-three/drei'), + } + + return config + }, experimental: { serverActions: { bodySizeLimit: '100mb', diff --git a/apps/editor/package.json b/apps/editor/package.json index e8b713347..789b12724 100644 --- a/apps/editor/package.json +++ b/apps/editor/package.json @@ -14,6 +14,7 @@ "@number-flow/react": "^0.5.14", "@pascal-app/core": "*", "@pascal-app/editor": "*", + "@pascal-app/home-assistant": "*", "@pascal-app/mcp": "*", "@pascal-app/viewer": "*", "@react-three/drei": "^10.7.7", diff --git a/bun.lock b/bun.lock index c0e5fbbea..eb848ea7f 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "editor", @@ -19,6 +18,7 @@ "@number-flow/react": "^0.5.14", "@pascal-app/core": "*", "@pascal-app/editor": "*", + "@pascal-app/home-assistant": "*", "@pascal-app/mcp": "*", "@pascal-app/viewer": "*", "@react-three/drei": "^10.7.7", @@ -82,6 +82,7 @@ "@dnd-kit/utilities": "^3.2.2", "@iconify/react": "^6.0.2", "@number-flow/react": "^0.5.14", + "@pascal-app/home-assistant": "*", "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dialog": "^1.1.15", @@ -148,6 +149,52 @@ "typescript-eslint": "^8.50.0", }, }, + "packages/home-assistant": { + "name": "@pascal-app/home-assistant", + "version": "0.1.0", + "devDependencies": { + "@pascal-app/core": "^0.6.0", + "@pascal-app/viewer": "^0.6.0", + "@pascal/typescript-config": "*", + "@types/node": "^22.19.12", + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2", + "@types/three": "^0.184.0", + "typescript": "5.9.3", + "zod": "^4.3.5", + }, + "peerDependencies": { + "@pascal-app/core": "^0.6.0", + "@pascal-app/viewer": "^0.6.0", + "@react-three/fiber": "^9", + "lucide-react": "^0.562.0", + "react": "^18 || ^19", + "react-dom": "^18 || ^19", + "three": "^0.184", + }, + }, + "packages/lovelace-card": { + "name": "@pascal-app/lovelace-card", + "version": "0.1.0", + "dependencies": { + "@pascal-app/core": "*", + "@pascal-app/home-assistant": "*", + "@pascal-app/viewer": "*", + "@react-three/drei": "^10.7.7", + "@react-three/fiber": "^9.5.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "three": "^0.184.0", + "zustand": "^5.0.11", + }, + "devDependencies": { + "@pascal/typescript-config": "*", + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2", + "@types/three": "^0.184.0", + "typescript": "5.9.3", + }, + }, "packages/mcp": { "name": "@pascal-app/mcp", "version": "0.1.0", @@ -483,6 +530,10 @@ "@pascal-app/editor": ["@pascal-app/editor@workspace:packages/editor"], + "@pascal-app/home-assistant": ["@pascal-app/home-assistant@workspace:packages/home-assistant"], + + "@pascal-app/lovelace-card": ["@pascal-app/lovelace-card@workspace:packages/lovelace-card"], + "@pascal-app/mcp": ["@pascal-app/mcp@workspace:packages/mcp"], "@pascal-app/viewer": ["@pascal-app/viewer@workspace:packages/viewer"], @@ -1567,6 +1618,10 @@ "@pascal-app/editor/@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="], + "@pascal-app/home-assistant/@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="], + + "@pascal-app/lovelace-card/@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="], + "@pascal-app/mcp/@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], "@pascal-app/viewer/@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], diff --git a/dist/pascal-viewer-card.js b/dist/pascal-viewer-card.js new file mode 100644 index 000000000..3d2d01e49 --- /dev/null +++ b/dist/pascal-viewer-card.js @@ -0,0 +1,5548 @@ +var process = { env: { NEXT_PUBLIC_ASSETS_CDN_URL: 'https://editor.pascal.app', NODE_ENV: 'production' } }; +var BkA=Object.create;var{getPrototypeOf:qkA,defineProperty:Do,getOwnPropertyNames:YkA}=Object;var GkA=Object.prototype.hasOwnProperty;var u0=(A,Q,$)=>{$=A!=null?BkA(qkA(A)):{};let J=Q||!A||!A.__esModule?Do($,"default",{value:A,enumerable:!0}):$;for(let U of YkA(A))if(!GkA.call(J,U))Do(J,U,{get:()=>A[U],enumerable:!0});return J};var pG=(A,Q)=>()=>(Q||A((Q={exports:{}}).exports,Q),Q.exports);var uG=(A,Q)=>{for(var $ in Q)Do(A,$,{get:Q[$],enumerable:!0,configurable:!0,set:(J)=>Q[$]=()=>J})};var TQ=pG((XkA,Yg)=>{(function(){function A(l,BA){Object.defineProperty(J.prototype,l,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",BA[0],BA[1])}})}function Q(l){if(l===null||typeof l!=="object")return null;return l=x0&&l[x0]||l["@@iterator"],typeof l==="function"?l:null}function $(l,BA){l=(l=l.constructor)&&(l.displayName||l.name)||"ReactClass";var WA=l+"."+BA;vA[WA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",BA,l),vA[WA]=!0)}function J(l,BA,WA){this.props=l,this.context=BA,this.refs=E0,this.updater=WA||c0}function U(){}function K(l,BA,WA){this.props=l,this.context=BA,this.refs=E0,this.updater=WA||c0}function E(){}function B(l){return""+l}function Y(l){try{B(l);var BA=!1}catch(yA){BA=!0}if(BA){BA=console;var WA=BA.error,IA=typeof Symbol==="function"&&Symbol.toStringTag&&l[Symbol.toStringTag]||l.constructor.name||"Object";return WA.call(BA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",IA),B(l)}}function X(l){if(l==null)return null;if(typeof l==="function")return l.$$typeof===C0?null:l.displayName||l.name||null;if(typeof l==="string")return l;switch(l){case MA:return"Fragment";case FA:return"Profiler";case JA:return"StrictMode";case TA:return"Suspense";case nA:return"SuspenseList";case q0:return"Activity"}if(typeof l==="object")switch(typeof l.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),l.$$typeof){case XA:return"Portal";case bA:return l.displayName||"Context";case OA:return(l._context.displayName||"Context")+".Consumer";case rA:var BA=l.render;return l=l.displayName,l||(l=BA.displayName||BA.name||"",l=l!==""?"ForwardRef("+l+")":"ForwardRef"),l;case K0:return BA=l.displayName||null,BA!==null?BA:X(l.type)||"Memo";case A0:BA=l._payload,l=l._init;try{return X(l(BA))}catch(WA){}}return null}function Z(l){if(l===MA)return"<>";if(typeof l==="object"&&l!==null&&l.$$typeof===A0)return"<...>";try{var BA=X(l);return BA?"<"+BA+">":"<...>"}catch(WA){return"<...>"}}function C(){var l=k0.A;return l===null?null:l.getOwner()}function W(){return Error("react-stack-top-frame")}function N(l){if(VA.call(l,"key")){var BA=Object.getOwnPropertyDescriptor(l,"key").get;if(BA&&BA.isReactWarning)return!1}return l.key!==void 0}function V(l,BA){function WA(){m0||(m0=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",BA))}WA.isReactWarning=!0,Object.defineProperty(l,"key",{get:WA,configurable:!0})}function z(){var l=X(this.type);return N0[l]||(N0[l]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),l=this.props.ref,l!==void 0?l:null}function D(l,BA,WA,IA,yA,uA){var GA=WA.ref;return l={$$typeof:UA,type:l,key:BA,props:WA,_owner:IA},(GA!==void 0?GA:null)!==null?Object.defineProperty(l,"ref",{enumerable:!1,get:z}):Object.defineProperty(l,"ref",{enumerable:!1,value:null}),l._store={},Object.defineProperty(l._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(l,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(l,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:yA}),Object.defineProperty(l,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:uA}),Object.freeze&&(Object.freeze(l.props),Object.freeze(l)),l}function k(l,BA){return BA=D(l.type,BA,l.props,l._owner,l._debugStack,l._debugTask),l._store&&(BA._store.validated=l._store.validated),BA}function P(l){R(l)?l._store&&(l._store.validated=1):typeof l==="object"&&l!==null&&l.$$typeof===A0&&(l._payload.status==="fulfilled"?R(l._payload.value)&&l._payload.value._store&&(l._payload.value._store.validated=1):l._store&&(l._store.validated=1))}function R(l){return typeof l==="object"&&l!==null&&l.$$typeof===UA}function L(l){var BA={"=":"=0",":":"=2"};return"$"+l.replace(/[=:]/g,function(WA){return BA[WA]})}function w(l,BA){return typeof l==="object"&&l!==null&&l.key!=null?(Y(l.key),L(""+l.key)):BA.toString(36)}function _(l){switch(l.status){case"fulfilled":return l.value;case"rejected":throw l.reason;default:switch(typeof l.status==="string"?l.then(E,E):(l.status="pending",l.then(function(BA){l.status==="pending"&&(l.status="fulfilled",l.value=BA)},function(BA){l.status==="pending"&&(l.status="rejected",l.reason=BA)})),l.status){case"fulfilled":return l.value;case"rejected":throw l.reason}}throw l}function b(l,BA,WA,IA,yA){var uA=typeof l;if(uA==="undefined"||uA==="boolean")l=null;var GA=!1;if(l===null)GA=!0;else switch(uA){case"bigint":case"string":case"number":GA=!0;break;case"object":switch(l.$$typeof){case UA:case XA:GA=!0;break;case A0:return GA=l._init,b(GA(l._payload),BA,WA,IA,yA)}}if(GA){GA=l,yA=yA(GA);var wA=IA===""?"."+w(GA,0):IA;return B0(yA)?(WA="",wA!=null&&(WA=wA.replace(KA,"$&/")+"/"),b(yA,BA,WA,"",function(H0){return H0})):yA!=null&&(R(yA)&&(yA.key!=null&&(GA&&GA.key===yA.key||Y(yA.key)),WA=k(yA,WA+(yA.key==null||GA&&GA.key===yA.key?"":(""+yA.key).replace(KA,"$&/")+"/")+wA),IA!==""&&GA!=null&&R(GA)&&GA.key==null&&GA._store&&!GA._store.validated&&(WA._store.validated=2),yA=WA),BA.push(yA)),1}if(GA=0,wA=IA===""?".":IA+":",B0(l))for(var RA=0;RA import('./MyComponent')) + +Did you accidentally put curly braces around the import?`,BA),"default"in BA||console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s + +Your code should look like: + const MyComponent = lazy(() => import('./MyComponent'))`,BA),BA.default;throw l._result}function x(){var l=k0.H;return l===null&&console.error(`Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: +1. You might have mismatching versions of React and the renderer (such as React DOM) +2. You might be breaking the Rules of Hooks +3. You might have more than one copy of React in the same app +See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.`),l}function f(){k0.asyncTransitions--}function p(l){if(_0===null)try{var BA=("require"+Math.random()).slice(0,7);_0=(Yg&&Yg[BA]).call(Yg,"timers").setImmediate}catch(WA){_0=function(IA){J0===!1&&(J0=!0,typeof MessageChannel>"u"&&console.error("This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning."));var yA=new MessageChannel;yA.port1.onmessage=IA,yA.port2.postMessage(void 0)}}return _0(l)}function m(l){return 1 ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"))}),{then:function(RA,H0){yA=!0,GA.then(function(P0){if(d(BA,WA),WA===0){try{t(IA),p(function(){return o(P0,RA,H0)})}catch(o0){k0.thrownErrors.push(o0)}if(0 ...)"))}),k0.actQueue=null),0k0.recentlyCreatedOwnerStacks++;return D(l,yA,IA,C(),RA?Error("react-stack-top-frame"):xQ,RA?g0(Z(l)):p0)},XkA.createRef=function(){var l={current:null};return Object.seal(l),l},XkA.forwardRef=function(l){l!=null&&l.$$typeof===K0?console.error("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):typeof l!=="function"?console.error("forwardRef requires a render function but was given %s.",l===null?"null":typeof l):l.length!==0&&l.length!==2&&console.error("forwardRef render functions accept exactly two parameters: props and ref. %s",l.length===1?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined."),l!=null&&l.defaultProps!=null&&console.error("forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?");var BA={$$typeof:rA,render:l},WA;return Object.defineProperty(BA,"displayName",{enumerable:!1,configurable:!0,get:function(){return WA},set:function(IA){WA=IA,l.name||l.displayName||(Object.defineProperty(l,"name",{value:IA}),l.displayName=IA)}}),BA},XkA.isValidElement=R,XkA.lazy=function(l){l={_status:-1,_result:l};var BA={$$typeof:A0,_payload:l,_init:y},WA={name:"lazy",start:-1,end:-1,value:null,owner:null,debugStack:Error("react-stack-top-frame"),debugTask:console.createTask?console.createTask("lazy()"):null};return l._ioInfo=WA,BA._debugInfo=[{awaited:WA}],BA},XkA.memo=function(l,BA){l==null&&console.error("memo: The first argument must be a component. Instead received: %s",l===null?"null":typeof l),BA={$$typeof:K0,type:l,compare:BA===void 0?null:BA};var WA;return Object.defineProperty(BA,"displayName",{enumerable:!1,configurable:!0,get:function(){return WA},set:function(IA){WA=IA,l.name||l.displayName||(Object.defineProperty(l,"name",{value:IA}),l.displayName=IA)}}),BA},XkA.startTransition=function(l){var BA=k0.T,WA={};WA._updatedFibers=new Set,k0.T=WA;try{var IA=l(),yA=k0.S;yA!==null&&yA(WA,IA),typeof IA==="object"&&IA!==null&&typeof IA.then==="function"&&(k0.asyncTransitions++,IA.then(f,f),IA.then(E,xA))}catch(uA){xA(uA)}finally{BA===null&&WA._updatedFibers&&(l=WA._updatedFibers.size,WA._updatedFibers.clear(),10{(function(){function A(){if(L=!1,T){var o=ZkA.unstable_now();f=o;var t=!0;try{A:{P=!1,R&&(R=!1,_(y),y=-1),k=!0;var UA=D;try{Q:{K(o);for(z=$(W);z!==null&&!(z.expirationTime>o&&B());){var XA=z.callback;if(typeof XA==="function"){z.callback=null,D=z.priorityLevel;var MA=XA(z.expirationTime<=o);if(o=ZkA.unstable_now(),typeof MA==="function"){z.callback=MA,K(o),t=!0;break Q}z===$(W)&&J(W),K(o)}else J(W);z=$(W)}if(z!==null)t=!0;else{var JA=$(N);JA!==null&&Y(E,JA.startTime-o),t=!1}}break A}finally{z=null,D=UA,k=!1}t=void 0}}finally{t?p():T=!1}}}function Q(o,t){var UA=o.length;o.push(t);A:for(;0>>1,MA=o[XA];if(0>>1;XAU(OA,UA))bAU(rA,OA)?(o[XA]=rA,o[bA]=UA,XA=bA):(o[XA]=OA,o[FA]=UA,XA=FA);else if(bAU(rA,UA))o[XA]=rA,o[bA]=UA,XA=bA;else break A}}return t}function U(o,t){var UA=o.sortIndex-t.sortIndex;return UA!==0?UA:o.id-t.id}function K(o){for(var t=$(N);t!==null;){if(t.callback===null)J(N);else if(t.startTime<=o)J(N),t.sortIndex=t.expirationTime,Q(W,t);else break;t=$(N)}}function E(o){if(R=!1,K(o),!P)if($(W)!==null)P=!0,T||(T=!0,p());else{var t=$(N);t!==null&&Y(E,t.startTime-o)}}function B(){return L?!0:ZkA.unstable_now()-fo||125XA?(o.sortIndex=UA,Q(N,o),$(W)===null&&o===$(N)&&(R?(_(y),y=-1):R=!0,Y(E,UA-XA))):(o.sortIndex=MA,Q(W,o),P||k||(P=!0,T||(T=!0,p()))),o},ZkA.unstable_shouldYield=B,ZkA.unstable_wrapCallback=function(o){var t=D;return function(){var UA=D;D=t;try{return o.apply(this,arguments)}finally{D=UA}}},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop==="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()});var U1A=pG((FkA)=>{var Ro=u0(TQ());(function(){function A(){}function Q(Z){return""+Z}function $(Z,C,W){var N=3` tag.%s',W),typeof Z==="string"&&typeof C==="object"&&C!==null&&typeof C.as==="string"){W=C.as;var N=J(W,C.crossOrigin);B.d.L(Z,W,{crossOrigin:N,integrity:typeof C.integrity==="string"?C.integrity:void 0,nonce:typeof C.nonce==="string"?C.nonce:void 0,type:typeof C.type==="string"?C.type:void 0,fetchPriority:typeof C.fetchPriority==="string"?C.fetchPriority:void 0,referrerPolicy:typeof C.referrerPolicy==="string"?C.referrerPolicy:void 0,imageSrcSet:typeof C.imageSrcSet==="string"?C.imageSrcSet:void 0,imageSizes:typeof C.imageSizes==="string"?C.imageSizes:void 0,media:typeof C.media==="string"?C.media:void 0})}},FkA.preloadModule=function(Z,C){var W="";typeof Z==="string"&&Z||(W+=" The `href` argument encountered was "+U(Z)+"."),C!==void 0&&typeof C!=="object"?W+=" The `options` argument encountered was "+U(C)+".":C&&("as"in C)&&typeof C.as!=="string"&&(W+=" The `as` option encountered was "+U(C.as)+"."),W&&console.error('ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `` tag.%s',W),typeof Z==="string"&&(C?(W=J(C.as,C.crossOrigin),B.d.m(Z,{as:typeof C.as==="string"&&C.as!=="script"?C.as:void 0,crossOrigin:W,integrity:typeof C.integrity==="string"?C.integrity:void 0})):B.d.m(Z))},FkA.requestFormReset=function(Z){B.d.r(Z)},FkA.unstable_batchedUpdates=function(Z,C){return Z(C)},FkA.useFormState=function(Z,C,W){return E().useFormState(Z,C,W)},FkA.useFormStatus=function(){return E().useHostTransitionStatus()},FkA.version="19.2.4",typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop==="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()});var _o=pG((BQ0,K1A)=>{K1A.exports=U1A()});var E1A=pG((CkA)=>{var l8=u0(Gg()),Fz=u0(TQ()),zo=u0(_o());(function(){function A(q,G){for(q=q.memoizedState;q!==null&&0=G.length)return I;var S=G[M],v=s8(q)?q.slice():R$({},q);return v[S]=Q(q[S],G,M+1,I),v}function $(q,G,M){if(G.length!==M.length)console.warn("copyWithRename() expects paths of the same length");else{for(var I=0;IVB?console.error("Unexpected pop."):(G!==ZW[VB]&&console.error("Unexpected Fiber popped."),q.current=$$[VB],$$[VB]=null,ZW[VB]=null,VB--)}function m(q,G,M){VB++,$$[VB]=q.current,ZW[VB]=M,q.current=G}function d(q){return q===null&&console.error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."),q}function o(q,G){m(OB,G,q),m(IZ,q,q),m(KY,null,q);var M=G.nodeType;switch(M){case 9:case 11:M=M===9?"#document":"#fragment",G=(G=G.documentElement)?(G=G.namespaceURI)?hb(G):pC:pC;break;default:if(M=G.tagName,G=G.namespaceURI)G=hb(G),G=pb(G,M);else switch(M){case"svg":G=Xz;break;case"math":G=$g;break;default:G=pC}}M=M.toLowerCase(),M=X6(null,M),M={context:G,ancestorInfo:M},p(KY,q),m(KY,M,q)}function t(q){p(KY,q),p(IZ,q),p(OB,q)}function UA(){return d(KY.current)}function XA(q){q.memoizedState!==null&&m(DG,q,q);var G=d(KY.current),M=q.type,I=pb(G.context,M);M=X6(G.ancestorInfo,M),I={context:I,ancestorInfo:M},G!==I&&(m(IZ,q,q),m(KY,I,q))}function MA(q){IZ.current===q&&(p(KY,q),p(IZ,q)),DG.current===q&&(p(DG,q),TS._currentValue=fO)}function JA(){}function FA(){if(EY===0){Kx=console.log,Ex=console.info,Bx=console.warn,ZJ=console.error,Q9=console.group,UO=console.groupCollapsed,yU=console.groupEnd;var q={configurable:!0,enumerable:!0,value:JA,writable:!0};Object.defineProperties(console,{info:q,log:q,warn:q,error:q,group:q,groupCollapsed:q,groupEnd:q})}EY++}function OA(){if(EY--,EY===0){var q={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:R$({},q,{value:Kx}),info:R$({},q,{value:Ex}),warn:R$({},q,{value:Bx}),error:R$({},q,{value:ZJ}),group:R$({},q,{value:Q9}),groupCollapsed:R$({},q,{value:UO}),groupEnd:R$({},q,{value:yU})})}0>EY&&console.error("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}function bA(q){var G=Error.prepareStackTrace;if(Error.prepareStackTrace=void 0,q=q.stack,Error.prepareStackTrace=G,q.startsWith(`Error: react-stack-top-frame +`)&&(q=q.slice(29)),G=q.indexOf(` +`),G!==-1&&(q=q.slice(G+1)),G=q.indexOf("react_stack_bottom_frame"),G!==-1&&(G=q.lastIndexOf(` +`,G)),G!==-1)q=q.slice(0,G);else return"";return q}function rA(q){if(BY===void 0)try{throw Error()}catch(M){var G=M.stack.trim().match(/\n( *(at )?)/);BY=G&&G[1]||"",qY=-1)":-1u||YA[v]!==lA[u]){var dA=` +`+YA[v].replace(" at new "," at ");return q.displayName&&dA.includes("")&&(dA=dA.replace("",q.displayName)),typeof q==="function"&&bU.set(q,dA),dA}while(1<=v&&0<=u);break}}}finally{LB=!1,W0.H=I,OA(),Error.prepareStackTrace=M}return YA=(YA=q?q.displayName||q.name:"")?rA(YA):"",typeof q==="function"&&bU.set(q,YA),YA}function nA(q,G){switch(q.tag){case 26:case 27:case 5:return rA(q.type);case 16:return rA("Lazy");case 13:return q.child!==G&&G!==null?rA("Suspense Fallback"):rA("Suspense");case 19:return rA("SuspenseList");case 0:case 15:return TA(q.type,!1);case 11:return TA(q.type.render,!1);case 1:return TA(q.type,!0);case 31:return rA("Activity");default:return""}}function K0(q){try{var G="",M=null;do{G+=nA(q,M);var I=q._debugInfo;if(I)for(var S=I.length-1;0<=S;S--){var v=I[S];if(typeof v.name==="string"){var u=G;A:{var{name:c,env:$A,debugLocation:YA}=v;if(YA!=null){var lA=bA(YA),dA=lA.lastIndexOf(` +`),kA=dA===-1?lA:lA.slice(dA+1);if(kA.indexOf(c)!==-1){var G0=` +`+kA;break A}}G0=rA(c+($A?" ["+$A+"]":""))}G=u+G0}}M=q,q=q.return}while(q);return G}catch(ZQ){return` +Error generating stack: `+ZQ.message+` +`+ZQ.stack}}function A0(q){return(q=q?q.displayName||q.name:"")?rA(q):""}function q0(){if(f9===null)return null;var q=f9._debugOwner;return q!=null?y(q):null}function x0(){if(f9===null)return"";var q=f9;try{var G="";switch(q.tag===6&&(q=q.return),q.tag){case 26:case 27:case 5:G+=rA(q.type);break;case 13:G+=rA("Suspense");break;case 19:G+=rA("SuspenseList");break;case 31:G+=rA("Activity");break;case 30:case 0:case 15:case 1:q._debugOwner||G!==""||(G+=A0(q.type));break;case 11:q._debugOwner||G!==""||(G+=A0(q.type.render))}for(;q;)if(typeof q.tag==="number"){var M=q;q=M._debugOwner;var I=M._debugStack;if(q&&I){var S=bA(I);S!==""&&(G+=` +`+S)}}else if(q.debugStack!=null){var v=q.debugStack;(q=q.owner)&&v&&(G+=` +`+bA(v))}else break;var u=G}catch(c){u=` +Error generating stack: `+c.message+` +`+c.stack}return u}function vA(q,G,M,I,S,v,u){var c=f9;c0(q);try{return q!==null&&q._debugTask?q._debugTask.run(G.bind(null,M,I,S,v,u)):G(M,I,S,v,u)}finally{c0(c)}throw Error("runWithFiberInDEV should never be called in production. This is a bug in React.")}function c0(q){W0.getCurrentStack=q===null?null:x0,y8=!1,f9=q}function tA(q){return typeof Symbol==="function"&&Symbol.toStringTag&&q[Symbol.toStringTag]||q.constructor.name||"Object"}function E0(q){try{return fA(q),!1}catch(G){return!0}}function fA(q){return""+q}function B0(q,G){if(E0(q))return console.error("The provided `%s` attribute is an unsupported type %s. This value must be coerced to a string before using it here.",G,tA(q)),fA(q)}function C0(q,G){if(E0(q))return console.error("The provided `%s` CSS property is an unsupported type %s. This value must be coerced to a string before using it here.",G,tA(q)),fA(q)}function k0(q){if(E0(q))return console.error("Form field values (value, checked, defaultValue, or defaultChecked props) must be strings, not %s. This value must be coerced to a string before using it here.",tA(q)),fA(q)}function VA(q){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u")return!1;var G=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(G.isDisabled)return!0;if(!G.supportsFiber)return console.error("The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://react.dev/link/react-devtools"),!0;try{OE=G.inject(q),FJ=G}catch(M){console.error("React instrumentation encountered an error: %o.",M)}return G.checkDCE?!0:!1}function g0(q){if(typeof FW==="function"&&P_(q),FJ&&typeof FJ.setStrictMode==="function")try{FJ.setStrictMode(OE,q)}catch(G){$9||($9=!0,console.error("React instrumentation encountered an error: %o",G))}}function m0(q){return q>>>=0,q===0?32:31-(qx(q)/Yx|0)|0}function R0(q){var G=q&42;if(G!==0)return G;switch(q&-q){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 q&261888;case 262144:case 524288:case 1048576:case 2097152:return q&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return q&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return console.error("Should have found matching lanes. This is a bug in React."),q}}function N0(q,G,M){var I=q.pendingLanes;if(I===0)return 0;var S=0,v=q.suspendedLanes,u=q.pingedLanes;q=q.warmLanes;var c=I&134217727;return c!==0?(I=c&~v,I!==0?S=R0(I):(u&=c,u!==0?S=R0(u):M||(M=c&~q,M!==0&&(S=R0(M))))):(c=I&~v,c!==0?S=R0(c):u!==0?S=R0(u):M||(M=I&~q,M!==0&&(S=R0(M)))),S===0?0:G!==0&&G!==S&&(G&v)===0&&(v=S&-S,M=G&-G,v>=M||v===32&&(M&4194048)!==0)?G:S}function xQ(q,G){return(q.pendingLanes&~(q.suspendedLanes&~q.pingedLanes)&G)===0}function p0(q,G){switch(q){case 1:case 2:case 4:case 8:case 64:return G+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 G+5000;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return console.error("Should have found matching lanes. This is a bug in React."),-1}}function HA(){var q=DB;return DB<<=1,(DB&62914560)===0&&(DB=4194304),q}function KA(q){for(var G=[],M=0;31>M;M++)G.push(q);return G}function xA(q,G){q.pendingLanes|=G,G!==268435456&&(q.suspendedLanes=0,q.pingedLanes=0,q.warmLanes=0)}function J0(q,G,M,I,S,v){var u=q.pendingLanes;q.pendingLanes=M,q.suspendedLanes=0,q.pingedLanes=0,q.warmLanes=0,q.expiredLanes&=M,q.entangledLanes&=M,q.errorRecoveryDisabledLanes&=M,q.shellSuspendCounter=0;var{entanglements:c,expirationTimes:$A,hiddenUpdates:YA}=q;for(M=u&~M;0"u")return null;try{return q.activeElement||q.body}catch(G){return q.body}}function T8(q){return q.replace(PB,function(G){return"\\"+G.charCodeAt(0).toString(16)+" "})}function H9(q,G){G.checked===void 0||G.defaultChecked===void 0||WW||(console.error("%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://react.dev/link/controlled-components",q0()||"A component",G.type),WW=!0),G.value===void 0||G.defaultValue===void 0||HW||(console.error("%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://react.dev/link/controlled-components",q0()||"A component",G.type),HW=!0)}function sJ(q,G,M,I,S,v,u,c){if(q.name="",u!=null&&typeof u!=="function"&&typeof u!=="symbol"&&typeof u!=="boolean"?(B0(u,"type"),q.type=u):q.removeAttribute("type"),G!=null)if(u==="number"){if(G===0&&q.value===""||q.value!=G)q.value=""+B$(G)}else q.value!==""+B$(G)&&(q.value=""+B$(G));else u!=="submit"&&u!=="reset"||q.removeAttribute("value");G!=null?xK(q,u,B$(G)):M!=null?xK(q,u,B$(M)):I!=null&&q.removeAttribute("value"),S==null&&v!=null&&(q.defaultChecked=!!v),S!=null&&(q.checked=S&&typeof S!=="function"&&typeof S!=="symbol"),c!=null&&typeof c!=="function"&&typeof c!=="symbol"&&typeof c!=="boolean"?(B0(c,"name"),q.name=""+B$(c)):q.removeAttribute("name")}function bK(q,G,M,I,S,v,u,c){if(v!=null&&typeof v!=="function"&&typeof v!=="symbol"&&typeof v!=="boolean"&&(B0(v,"type"),q.type=v),G!=null||M!=null){if(!(v!=="submit"&&v!=="reset"||G!==void 0&&G!==null)){T6(q);return}M=M!=null?""+B$(M):"",G=G!=null?""+B$(G):M,c||G===q.value||(q.value=G),q.defaultValue=G}I=I!=null?I:S,I=typeof I!=="function"&&typeof I!=="symbol"&&!!I,q.checked=c?q.checked:!!I,q.defaultChecked=!!I,u!=null&&typeof u!=="function"&&typeof u!=="symbol"&&typeof u!=="boolean"&&(B0(u,"name"),q.name=u),T6(q)}function xK(q,G,M){G==="number"&&G6(q.ownerDocument)===q||q.defaultValue===""+M||(q.defaultValue=""+M)}function yq(q,G){G.value==null&&(typeof G.children==="object"&&G.children!==null?Fz.Children.forEach(G.children,function(M){M==null||typeof M==="string"||typeof M==="number"||typeof M==="bigint"||NW||(NW=!0,console.error("Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to