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..6f9e6e50f 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,51 @@ "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", + "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 +529,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 +1617,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..9289cb2bf --- /dev/null +++ b/dist/pascal-viewer-card.js @@ -0,0 +1,5537 @@ +var process = { env: { NEXT_PUBLIC_ASSETS_CDN_URL: 'https://editor.pascal.app', NODE_ENV: 'production' } }; +var N4A=Object.create;var{getPrototypeOf:V4A,defineProperty:Zo,getOwnPropertyNames:O4A}=Object;var I4A=Object.prototype.hasOwnProperty;var u0=(A,Q,$)=>{$=A!=null?N4A(V4A(A)):{};let J=Q||!A||!A.__esModule?Zo($,"default",{value:A,enumerable:!0}):$;for(let U of O4A(A))if(!I4A.call(J,U))Zo(J,U,{get:()=>A[U],enumerable:!0});return J};var xG=(A,Q)=>()=>(Q||A((Q={exports:{}}).exports,Q),Q.exports);var gG=(A,Q)=>{for(var $ in Q)Zo(A,$,{get:Q[$],enumerable:!0,configurable:!0,set:(J)=>Q[$]=()=>J})};var TQ=xG((L4A,ex)=>{(function(){function A(l,qA){Object.defineProperty(J.prototype,l,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",qA[0],qA[1])}})}function Q(l){if(l===null||typeof l!=="object")return null;return l=a0&&l[a0]||l["@@iterator"],typeof l==="function"?l:null}function $(l,qA){l=(l=l.constructor)&&(l.displayName||l.name)||"ReactClass";var WA=l+"."+qA;TA[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.",qA,l),TA[WA]=!0)}function J(l,qA,WA){this.props=l,this.context=qA,this.refs=lA,this.updater=WA||c0}function U(){}function K(l,qA,WA){this.props=l,this.context=qA,this.refs=lA,this.updater=WA||c0}function E(){}function B(l){return""+l}function Y(l){try{B(l);var qA=!1}catch(bA){qA=!0}if(qA){qA=console;var WA=qA.error,LA=typeof Symbol==="function"&&Symbol.toStringTag&&l[Symbol.toStringTag]||l.constructor.name||"Object";return WA.call(qA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",LA),B(l)}}function X(l){if(l==null)return null;if(typeof l==="function")return l.$$typeof===H0?null:l.displayName||l.name||null;if(typeof l==="string")return l;switch(l){case MA:return"Fragment";case CA:return"Profiler";case KA:return"StrictMode";case jA: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 gA:return l.displayName||"Context";case OA:return(l._context.displayName||"Context")+".Consumer";case rA:var qA=l.render;return l=l.displayName,l||(l=qA.displayName||qA.name||"",l=l!==""?"ForwardRef("+l+")":"ForwardRef"),l;case A0:return qA=l.displayName||null,qA!==null?qA:X(l.type)||"Memo";case eA:qA=l._payload,l=l._init;try{return X(l(qA))}catch(WA){}}return null}function Z(l){if(l===MA)return"<>";if(typeof l==="object"&&l!==null&&l.$$typeof===eA)return"<...>";try{var qA=X(l);return qA?"<"+qA+">":"<...>"}catch(WA){return"<...>"}}function F(){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 qA=Object.getOwnPropertyDescriptor(l,"key").get;if(qA&&qA.isReactWarning)return!1}return l.key!==void 0}function V(l,qA){function WA(){l0||(l0=!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)",qA))}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 L(l,qA,WA,LA,bA,uA){var GA=WA.ref;return l={$$typeof:$A,type:l,key:qA,props:WA,_owner:LA},(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:bA}),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,qA){return qA=L(l.type,qA,l.props,l._owner,l._debugStack,l._debugTask),l._store&&(qA._store.validated=l._store.validated),qA}function P(l){R(l)?l._store&&(l._store.validated=1):typeof l==="object"&&l!==null&&l.$$typeof===eA&&(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===$A}function D(l){var qA={"=":"=0",":":"=2"};return"$"+l.replace(/[=:]/g,function(WA){return qA[WA]})}function w(l,qA){return typeof l==="object"&&l!==null&&l.key!=null?(Y(l.key),D(""+l.key)):qA.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(qA){l.status==="pending"&&(l.status="fulfilled",l.value=qA)},function(qA){l.status==="pending"&&(l.status="rejected",l.reason=qA)})),l.status){case"fulfilled":return l.value;case"rejected":throw l.reason}}throw l}function x(l,qA,WA,LA,bA){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 $A:case XA:GA=!0;break;case eA:return GA=l._init,x(GA(l._payload),qA,WA,LA,bA)}}if(GA){GA=l,bA=bA(GA);var xA=LA===""?"."+w(GA,0):LA;return Y0(bA)?(WA="",xA!=null&&(WA=xA.replace(EA,"$&/")+"/"),x(bA,qA,WA,"",function(G0){return G0})):bA!=null&&(R(bA)&&(bA.key!=null&&(GA&&GA.key===bA.key||Y(bA.key)),WA=k(bA,WA+(bA.key==null||GA&&GA.key===bA.key?"":(""+bA.key).replace(EA,"$&/")+"/")+xA),LA!==""&&GA!=null&&R(GA)&&GA.key==null&&GA._store&&!GA._store.validated&&(WA._store.validated=2),bA=WA),qA.push(bA)),1}if(GA=0,xA=LA===""?".":LA+":",Y0(l))for(var zA=0;zA import('./MyComponent')) + +Did you accidentally put curly braces around the import?`,qA),"default"in qA||console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s + +Your code should look like: + const MyComponent = lazy(() => import('./MyComponent'))`,qA),qA.default;throw l._result}function b(){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 g(){k0.asyncTransitions--}function u(l){if(_0===null)try{var qA=("require"+Math.random()).slice(0,7);_0=(ex&&ex[qA]).call(ex,"timers").setImmediate}catch(WA){_0=function(LA){E0===!1&&(E0=!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 bA=new MessageChannel;bA.port1.onmessage=LA,bA.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(zA,G0){bA=!0,GA.then(function(w0){if(o(qA,WA),WA===0){try{t(LA),u(function(){return n(w0,zA,G0)})}catch(i0){k0.thrownErrors.push(i0)}if(0 ...)"))}),k0.actQueue=null),0k0.recentlyCreatedOwnerStacks++;return L(l,bA,LA,F(),zA?Error("react-stack-top-frame"):bQ,zA?v0(Z(l)):g0)},L4A.createRef=function(){var l={current:null};return Object.seal(l),l},L4A.forwardRef=function(l){l!=null&&l.$$typeof===A0?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 qA={$$typeof:rA,render:l},WA;return Object.defineProperty(qA,"displayName",{enumerable:!1,configurable:!0,get:function(){return WA},set:function(LA){WA=LA,l.name||l.displayName||(Object.defineProperty(l,"name",{value:LA}),l.displayName=LA)}}),qA},L4A.isValidElement=R,L4A.lazy=function(l){l={_status:-1,_result:l};var qA={$$typeof:eA,_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,qA._debugInfo=[{awaited:WA}],qA},L4A.memo=function(l,qA){l==null&&console.error("memo: The first argument must be a component. Instead received: %s",l===null?"null":typeof l),qA={$$typeof:A0,type:l,compare:qA===void 0?null:qA};var WA;return Object.defineProperty(qA,"displayName",{enumerable:!1,configurable:!0,get:function(){return WA},set:function(LA){WA=LA,l.name||l.displayName||(Object.defineProperty(l,"name",{value:LA}),l.displayName=LA)}}),qA},L4A.startTransition=function(l){var qA=k0.T,WA={};WA._updatedFibers=new Set,k0.T=WA;try{var LA=l(),bA=k0.S;bA!==null&&bA(WA,LA),typeof LA==="object"&&LA!==null&&typeof LA.then==="function"&&(k0.asyncTransitions++,LA.then(g,g),LA.then(E,yA))}catch(uA){yA(uA)}finally{qA===null&&WA._updatedFibers&&(l=WA._updatedFibers.size,WA._updatedFibers.clear(),10{(function(){function A(){if(D=!1,T){var n=D4A.unstable_now();g=n;var t=!0;try{A:{P=!1,R&&(R=!1,_(y),y=-1),k=!0;var $A=L;try{Q:{K(n);for(z=$(W);z!==null&&!(z.expirationTime>n&&B());){var XA=z.callback;if(typeof XA==="function"){z.callback=null,L=z.priorityLevel;var MA=XA(z.expirationTime<=n);if(n=D4A.unstable_now(),typeof MA==="function"){z.callback=MA,K(n),t=!0;break Q}z===$(W)&&J(W),K(n)}else J(W);z=$(W)}if(z!==null)t=!0;else{var KA=$(N);KA!==null&&Y(E,KA.startTime-n),t=!1}}break A}finally{z=null,L=$A,k=!1}t=void 0}}finally{t?u():T=!1}}}function Q(n,t){var $A=n.length;n.push(t);A:for(;0<$A;){var XA=$A-1>>>1,MA=n[XA];if(0>>1;XAU(OA,$A))gAU(rA,OA)?(n[XA]=rA,n[gA]=$A,XA=gA):(n[XA]=OA,n[CA]=$A,XA=CA);else if(gAU(rA,$A))n[XA]=rA,n[gA]=$A,XA=gA;else break A}}return t}function U(n,t){var $A=n.sortIndex-t.sortIndex;return $A!==0?$A:n.id-t.id}function K(n){for(var t=$(N);t!==null;){if(t.callback===null)J(N);else if(t.startTime<=n)J(N),t.sortIndex=t.expirationTime,Q(W,t);else break;t=$(N)}}function E(n){if(R=!1,K(n),!P)if($(W)!==null)P=!0,T||(T=!0,u());else{var t=$(N);t!==null&&Y(E,t.startTime-n)}}function B(){return D?!0:D4A.unstable_now()-gn||125XA?(n.sortIndex=$A,Q(N,n),$(W)===null&&n===$(N)&&(R?(_(y),y=-1):R=!0,Y(E,$A-XA))):(n.sortIndex=MA,Q(W,n),P||k||(P=!0,T||(T=!0,u()))),n},D4A.unstable_shouldYield=B,D4A.unstable_wrapCallback=function(n){var t=L;return function(){var $A=L;L=t;try{return n.apply(this,arguments)}finally{L=$A}}},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop==="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()});var u7A=xG((R4A)=>{var Co=u0(TQ());(function(){function A(){}function Q(Z){return""+Z}function $(Z,F,W){var N=3` tag.%s',W),typeof Z==="string"&&typeof F==="object"&&F!==null&&typeof F.as==="string"){W=F.as;var N=J(W,F.crossOrigin);B.d.L(Z,W,{crossOrigin:N,integrity:typeof F.integrity==="string"?F.integrity:void 0,nonce:typeof F.nonce==="string"?F.nonce:void 0,type:typeof F.type==="string"?F.type:void 0,fetchPriority:typeof F.fetchPriority==="string"?F.fetchPriority:void 0,referrerPolicy:typeof F.referrerPolicy==="string"?F.referrerPolicy:void 0,imageSrcSet:typeof F.imageSrcSet==="string"?F.imageSrcSet:void 0,imageSizes:typeof F.imageSizes==="string"?F.imageSizes:void 0,media:typeof F.media==="string"?F.media:void 0})}},R4A.preloadModule=function(Z,F){var W="";typeof Z==="string"&&Z||(W+=" The `href` argument encountered was "+U(Z)+"."),F!==void 0&&typeof F!=="object"?W+=" The `options` argument encountered was "+U(F)+".":F&&("as"in F)&&typeof F.as!=="string"&&(W+=" The `as` option encountered was "+U(F.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"&&(F?(W=J(F.as,F.crossOrigin),B.d.m(Z,{as:typeof F.as==="string"&&F.as!=="script"?F.as:void 0,crossOrigin:W,integrity:typeof F.integrity==="string"?F.integrity:void 0})):B.d.m(Z))},R4A.requestFormReset=function(Z){B.d.r(Z)},R4A.unstable_batchedUpdates=function(Z,F){return Z(F)},R4A.useFormState=function(Z,F,W){return E().useFormState(Z,F,W)},R4A.useFormStatus=function(){return E().useHostTransitionStatus()},R4A.version="19.2.4",typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop==="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()});var Fo=xG((MA0,p7A)=>{p7A.exports=u7A()});var m7A=xG((_4A)=>{var u8=u0(Ag()),Yz=u0(TQ()),Ho=u0(Fo());(function(){function A(q,G){for(q=q.memoizedState;q!==null&&0=G.length)return I;var S=G[M],v=d8(q)?q.slice():_$({},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;IFB?console.error("Unexpected pop."):(G!==KW[FB]&&console.error("Unexpected Fiber popped."),q.current=Q$[FB],Q$[FB]=null,KW[FB]=null,FB--)}function m(q,G,M){FB++,Q$[FB]=q.current,KW[FB]=M,q.current=G}function o(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 n(q,G){m(HB,G,q),m(FZ,q,q),m(eq,null,q);var M=G.nodeType;switch(M){case 9:case 11:M=M===9?"#document":"#fragment",G=(G=G.documentElement)?(G=G.namespaceURI)?wb(G):yF:yF;break;default:if(M=G.tagName,G=G.namespaceURI)G=wb(G),G=Sb(G,M);else switch(M){case"svg":G=Bz;break;case"math":G=ix;break;default:G=yF}}M=M.toLowerCase(),M=T6(null,M),M={context:G,ancestorInfo:M},u(eq,q),m(eq,M,q)}function t(q){u(eq,q),u(FZ,q),u(HB,q)}function $A(){return o(eq.current)}function XA(q){q.memoizedState!==null&&m(VG,q,q);var G=o(eq.current),M=q.type,I=Sb(G.context,M);M=T6(G.ancestorInfo,M),I={context:I,ancestorInfo:M},G!==I&&(m(FZ,q,q),m(eq,I,q))}function MA(q){FZ.current===q&&(u(eq,q),u(FZ,q)),VG.current===q&&(u(VG,q),zS._currentValue=TO)}function KA(){}function CA(){if(AY===0){sb=console.log,ab=console.info,rb=console.warn,ZJ=console.error,Q9=console.group,tV=console.groupCollapsed,TU=console.groupEnd;var q={configurable:!0,enumerable:!0,value:KA,writable:!0};Object.defineProperties(console,{info:q,log:q,warn:q,error:q,group:q,groupCollapsed:q,groupEnd:q})}AY++}function OA(){if(AY--,AY===0){var q={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:_$({},q,{value:sb}),info:_$({},q,{value:ab}),warn:_$({},q,{value:rb}),error:_$({},q,{value:ZJ}),group:_$({},q,{value:Q9}),groupCollapsed:_$({},q,{value:tV}),groupEnd:_$({},q,{value:TU})})}0>AY&&console.error("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}function gA(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(QY===void 0)try{throw Error()}catch(M){var G=M.stack.trim().match(/\n( *(at )?)/);QY=G&&G[1]||"",$Y=-1)":-1p||YA[v]!==cA[p]){var dA=` +`+YA[v].replace(" at new "," at ");return q.displayName&&dA.includes("")&&(dA=dA.replace("",q.displayName)),typeof q==="function"&&vU.set(q,dA),dA}while(1<=v&&0<=p);break}}}finally{WB=!1,W0.H=I,OA(),Error.prepareStackTrace=M}return YA=(YA=q?q.displayName||q.name:"")?rA(YA):"",typeof q==="function"&&vU.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 jA(q.type,!1);case 11:return jA(q.type.render,!1);case 1:return jA(q.type,!0);case 31:return rA("Activity");default:return""}}function A0(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 p=G;A:{var{name:c,env:JA,debugLocation:YA}=v;if(YA!=null){var cA=gA(YA),dA=cA.lastIndexOf(` +`),PA=dA===-1?cA:cA.slice(dA+1);if(PA.indexOf(c)!==-1){var X0=` +`+PA;break A}}X0=rA(c+(JA?" ["+JA+"]":""))}G=p+X0}}M=q,q=q.return}while(q);return G}catch(HQ){return` +Error generating stack: `+HQ.message+` +`+HQ.stack}}function eA(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 a0(){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+=eA(q.type));break;case 11:q._debugOwner||G!==""||(G+=eA(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=gA(I);S!==""&&(G+=` +`+S)}}else if(q.debugStack!=null){var v=q.debugStack;(q=q.owner)&&v&&(G+=` +`+gA(v))}else break;var p=G}catch(c){p=` +Error generating stack: `+c.message+` +`+c.stack}return p}function TA(q,G,M,I,S,v,p){var c=f9;c0(q);try{return q!==null&&q._debugTask?q._debugTask.run(G.bind(null,M,I,S,v,p)):G(M,I,S,v,p)}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:a0,S8=!1,f9=q}function J0(q){return typeof Symbol==="function"&&Symbol.toStringTag&&q[Symbol.toStringTag]||q.constructor.name||"Object"}function lA(q){try{return sA(q),!1}catch(G){return!0}}function sA(q){return""+q}function Y0(q,G){if(lA(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,J0(q)),sA(q)}function H0(q,G){if(lA(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,J0(q)),sA(q)}function k0(q){if(lA(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.",J0(q)),sA(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{NE=G.inject(q),CJ=G}catch(M){console.error("React instrumentation encountered an error: %o.",M)}return G.checkDCE?!0:!1}function v0(q){if(typeof EW==="function"&&R_(q),CJ&&typeof CJ.setStrictMode==="function")try{CJ.setStrictMode(NE,q)}catch(G){$9||($9=!0,console.error("React instrumentation encountered an error: %o",G))}}function l0(q){return q>>>=0,q===0?32:31-(tb(q)/eb|0)|0}function z0(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,p=q.pingedLanes;q=q.warmLanes;var c=I&134217727;return c!==0?(I=c&~v,I!==0?S=z0(I):(p&=c,p!==0?S=z0(p):M||(M=c&~q,M!==0&&(S=z0(M))))):(c=I&~v,c!==0?S=z0(c):p!==0?S=z0(p):M||(M=I&~q,M!==0&&(S=z0(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 bQ(q,G){return(q.pendingLanes&~(q.suspendedLanes&~q.pingedLanes)&G)===0}function g0(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=NB;return NB<<=1,(NB&62914560)===0&&(NB=4194304),q}function EA(q){for(var G=[],M=0;31>M;M++)G.push(q);return G}function yA(q,G){q.pendingLanes|=G,G!==268435456&&(q.suspendedLanes=0,q.pingedLanes=0,q.warmLanes=0)}function E0(q,G,M,I,S,v){var p=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:JA,hiddenUpdates:YA}=q;for(M=p&~M;0"u")return null;try{return q.activeElement||q.body}catch(G){return q.body}}function P8(q){return q.replace(DB,function(G){return"\\"+G.charCodeAt(0).toString(16)+" "})}function H9(q,G){G.checked===void 0||G.defaultChecked===void 0||YW||(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),YW=!0),G.value===void 0||G.defaultValue===void 0||qW||(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),qW=!0)}function sJ(q,G,M,I,S,v,p,c){if(q.name="",p!=null&&typeof p!=="function"&&typeof p!=="symbol"&&typeof p!=="boolean"?(Y0(p,"type"),q.type=p):q.removeAttribute("type"),G!=null)if(p==="number"){if(G===0&&q.value===""||q.value!=G)q.value=""+B$(G)}else q.value!==""+B$(G)&&(q.value=""+B$(G));else p!=="submit"&&p!=="reset"||q.removeAttribute("value");G!=null?yK(q,p,B$(G)):M!=null?yK(q,p,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"?(Y0(c,"name"),q.name=""+B$(c)):q.removeAttribute("name")}function vK(q,G,M,I,S,v,p,c){if(v!=null&&typeof v!=="function"&&typeof v!=="symbol"&&typeof v!=="boolean"&&(Y0(v,"type"),q.type=v),G!=null||M!=null){if(!(v!=="submit"&&v!=="reset"||G!==void 0&&G!==null)){S6(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,p!=null&&typeof p!=="function"&&typeof p!=="symbol"&&typeof p!=="boolean"&&(Y0(p,"name"),q.name=p),S6(q)}function yK(q,G,M){G==="number"&&j6(q.ownerDocument)===q||q.defaultValue===""+M||(q.defaultValue=""+M)}function wq(q,G){G.value==null&&(typeof G.children==="object"&&G.children!==null?Yz.Children.forEach(G.children,function(M){M==null||typeof M==="string"||typeof M==="number"||typeof M==="bigint"||XW||(XW=!0,console.error("Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to