From 172ac0db55b9f606083648abed1aba072fbbd700 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 22 Aug 2026 02:05:01 +0200 Subject: [PATCH] Lower Ghostlight as one Eve-native surface --- README.md | 32 +- .../ghostlight-eve-native-interface.md | 83 +++++ notes/fresh-workspace-handoff.md | 9 + notes/ghostlight-current-system-map.md | 73 ++-- notes/ghostlight-implementation-plan.md | 13 + state/map.yaml | 4 + vendor/eve | 2 +- ...{index-CYZ4YyRa.css => index-0xx6l_wS.css} | 2 +- web/dist/assets/index-BHkI62J0.js | 153 -------- web/dist/assets/index-BuuhLtYk.js | 160 +++++++++ web/dist/index.html | 47 +-- web/index.html | 43 +-- web/package-lock.json | 82 ++++- web/package.json | 7 +- web/src/heimdall-access-adapter.provenance.md | 11 + web/src/heimdall-access-adapter.ts | 78 ++++ web/src/main.ts | 340 ++++++------------ web/src/style.css | 28 +- web/test/static-boundary.mjs | 36 ++ web/vite.config.mjs | 15 + 20 files changed, 706 insertions(+), 512 deletions(-) create mode 100644 docs/architecture/ghostlight-eve-native-interface.md rename web/dist/assets/{index-CYZ4YyRa.css => index-0xx6l_wS.css} (81%) delete mode 100644 web/dist/assets/index-BHkI62J0.js create mode 100644 web/dist/assets/index-BuuhLtYk.js create mode 100644 web/src/heimdall-access-adapter.provenance.md create mode 100644 web/src/heimdall-access-adapter.ts create mode 100644 web/test/static-boundary.mjs create mode 100644 web/vite.config.mjs diff --git a/README.md b/README.md index fce1f73..78cf169 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,31 @@ multiresolution agency graph for keeping large settings active at finite cost. - CultMesh publishes typed service and Eve/CultUI state; the browser lowers that surface and does not become a second state authority. +## Eve-native interface + +Ghostlight publishes one stable logical surface, `ghostlight.play`, for +anonymous entry, Session Zero, Contract Review, and campaign play. The browser +contains Eve's canonical provider host and lowering package plus Heimdall's +access-plugin adapter. It does not contain Ghostlight-specific screen renderers +or domain API routing. + +Editable Eve bindings are the input model. Text, number, and choice controls +bind either provider-owned typed state or renderer-local draft state; an +operation captures named bindings and submits one canonical Eve command. +Rejected or stale commands preserve local drafts, while an accepted receipt may +clear named bindings before the host refetches the authoritative surface. A +browser may lower this interaction to an HTML form for accessibility, but forms +are not part of Eve's state or command ontology. + +Heimdall authentication is composed as the required +`gamecult.heimdall.access` Eve plugin. Heimdall owns OAuth attempts, provider +callbacks, claims, entitlements, and single-use completion redemption. +Ghostlight owns only its hashed HttpOnly app session and derives campaign +authority from canonical membership. The browser sees an opaque attempt handle, +never a claim, refresh credential, account hash, member ID, or actor authority. +See +[`docs/architecture/ghostlight-eve-native-interface.md`](docs/architecture/ghostlight-eve-native-interface.md). + ## Current Status Ghostlight Dungeon is implemented and deployed as a native Yggdrasil, @@ -101,14 +126,15 @@ The shortest reliable re-entry path is: - [`docs/architecture/ghostlight-dungeon-mvp.md`](docs/architecture/ghostlight-dungeon-mvp.md): runtime authority, compiler, action loop, persistence, hosting, and security; - [`docs/architecture/ghostlight-dungeon-session-zero.md`](docs/architecture/ghostlight-dungeon-session-zero.md): campaign negotiation, privacy, publication, membership, and bounded co-op; - [`docs/architecture/ghostlight-multiresolution-agency.md`](docs/architecture/ghostlight-multiresolution-agency.md): dynamic Gestalt partitioning, cohesive and arena cells, fairness, and atomic strategic waves; +- [`docs/architecture/ghostlight-eve-native-interface.md`](docs/architecture/ghostlight-eve-native-interface.md): Eve bindings, the stable provider surface, private Heimdall command plane, app-session custody, and browser cut line; - [`notes/ghostlight-current-system-map.md`](notes/ghostlight-current-system-map.md): current implemented pipeline; - [`notes/ghostlight-implementation-plan.md`](notes/ghostlight-implementation-plan.md): live sequence and next pressure tests; - [`state/map.yaml`](state/map.yaml): canonical human-readable project state. ## Repository Shape -- `crates/ghostlight-dungeon/`: Rust daemon, kernel, compiler, persistence, - provider stages, web lowerer, and acceptance harnesses; +- `crates/ghostlight-dungeon/`: Rust daemon, kernels, compiler, persistence, + provider stages, Eve projection/command ingress, and acceptance harnesses; - `crates/ghostlight-persona-projection/`: generalized projection membrane owned by Ghostlight and consumed by Epiphany; - `docs/architecture/`: durable contracts and authority maps; @@ -118,6 +144,8 @@ The shortest reliable re-entry path is: - `examples/`: earlier fixtures and regression material; - `state/`: human-readable project memory plus older research-pipeline state; - `tools/`: state, validation, and fixture helpers. +- `web/`: thin Eve browser host, Ghostlight transport, and Heimdall plugin + adapter; product state and product-specific rendering remain server-owned. Runtime documents and campaign exports use MessagePack-backed CultCache `.cc`. JSON exists at schema publication, browser, MCP, model-provider, and diagnostic diff --git a/docs/architecture/ghostlight-eve-native-interface.md b/docs/architecture/ghostlight-eve-native-interface.md new file mode 100644 index 0000000..0331163 --- /dev/null +++ b/docs/architecture/ghostlight-eve-native-interface.md @@ -0,0 +1,83 @@ +# Ghostlight Eve-native interface + +## Objective + +Ghostlight exposes one actor-filtered logical surface, `ghostlight.play`. Eve +owns its editable bindings, command invocation, receipts, plugin composition, +and browser lowering. Ghostlight continues to own Session Zero and world +admission; Heimdall continues to own authentication and entitlement decisions. + +```text +Ghostlight projection + -> EveBrowserProviderHost + -> canonical Eve lowering + -> gamecult.eve.command_invocation.v1 + -> Ghostlight ingress or Heimdall private command plane + -> gamecult.eve.command_result.v1 + -> authoritative surface refresh +``` + +## Authority map + +- Owner: `SessionZeroKernel` owns draft changes, `WorldKernel` owns campaign + changes, Heimdall owns OAuth attempts and claims, and Ghostlight's app-session + owner binds a verified Heimdall subject to a local cookie. +- Inputs: the provider projector reads only the caller's app session, + membership, actor-filtered campaign or Session Zero slice, and public + Heimdall gate state. Command ingress reads one canonical Eve invocation and + derives member and actor identity server-side. +- Outputs: one `gamecult.eve.surface.v1` document and one persisted + `gamecult.eve.command_receipt.v1` inside a command result. Invitation links + may appear only in a transient projection. +- Derived state: browser drafts, tab selection, focus, command status, the + selected campaign card, and rendered HTML are projections or local + interaction state. None grants access or mutates fiction. +- Forbidden writers: the browser, Eve lowerer, Heimdall plugin, SSE stream, + account preferences, and old auth store cannot choose an actor, establish + membership, approve a Session Zero decision, or commit world state. +- Shared paths: every UI operation resolves the authenticated account and + exact membership, then calls the existing Session Zero or world mailbox. + SSE carries invalidation only and the host refetches the same surface. +- Cut line: the bespoke browser renderers and product-specific API routes are + removed from the public router. Ghostlight's backend callback and local + OAuth-attempt store stop participating. `service/auth.cc` is migration and + rollback evidence only; `service/app-sessions.cc` owns new local sessions and + account preferences. + +## Editable values + +Eve bindings are the input model. A component binds a typed value by stable +binding name, document identity, field path, value kind, access mode, +authority, and optional write command. Renderer-local composers use +`local-draft`; direct edits name provider-owned state and an advertised write +command. An operation captures one or more named binding values atomically. + +The browser lowerer may use an HTML form for keyboard and accessibility +behavior. HTML form structure never enters Eve state or command payload +semantics. Accepted receipts may clear named drafts; rejection and stale +conflict preserve them. + +## Authentication membrane + +Anonymous projection contains only `heimdall.access_gate`. Its begin and +complete operations cross Heimdall's encrypted, loopback-only CultNet boundary. +The browser retains only the opaque attempt handle. Discord returns to +Heimdall; Ghostlight redeems the completion, validates the access claim and +`app_access`, and creates a local HttpOnly session. + +Routine requests use local verified session state. The cookie hash, stable +account-subject hash, Heimdall session/revision, capabilities, expiries, and +wrapped refresh claim persist in `app-sessions.cc`. Campaign authorization is +always derived from `campaign_membership.v1`; account preferences contain only +the selected campaign. + +## Public boundary + +- `GET /api/eve/provider` +- `GET /api/eve/surfaces/ghostlight.play` +- `POST /api/eve/commands` +- `GET /api/eve/events` + +`/health` remains a probe of the service's typed CultMesh health. Static assets +contain only the provider host, transport, Heimdall adapter, status mount, and +SSE invalidation. Hermodr is not a runtime dependency. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 0df0ec5..cd49fd5 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -55,6 +55,14 @@ rewrite. Arena cells never become synthetic collective actors or union knowledge. - Heimdall owns account identity. `campaign_membership.v1` binds an authenticated member to exactly one canonical actor. +- Eve owns editable bindings, command invocation, command receipts, plugin + composition, and lowering. Ghostlight publishes one stable + `ghostlight.play` surface; the browser is a thin provider host and never owns + login, Session Zero, campaign, governance, or receipt semantics. +- Heimdall's `gamecult.heimdall.access` plugin renders anonymous and identity + state. Sensitive begin, completion, refresh, and logout operations cross its + private CultNet command plane; the browser retains only an opaque attempt + handle and Ghostlight retains only its own hashed app session. - VoidBot owns Vault retrieval and evidence. Ghostlight stores exact evidence receipts, not a rival semantic index. - Idunn owns deployment and same-release daemon continuity. Odin owns discovery. @@ -158,6 +166,7 @@ capacity. ## Essential references - MVP authority: `docs/architecture/ghostlight-dungeon-mvp.md` +- Interface authority: `docs/architecture/ghostlight-eve-native-interface.md` - Gestalt authority: `docs/architecture/ghostlight-multiresolution-agency.md` - Live system map: `notes/ghostlight-current-system-map.md` - Implementation program: `notes/ghostlight-implementation-plan.md` diff --git a/notes/ghostlight-current-system-map.md b/notes/ghostlight-current-system-map.md index 618f9c9..20ebd17 100644 --- a/notes/ghostlight-current-system-map.md +++ b/notes/ghostlight-current-system-map.md @@ -389,25 +389,48 @@ advancing world revision or fictional time. Provider concurrency increments only `provider_configuration_epoch`; it batches the same cover and cannot repartition the world. See `docs/architecture/ghostlight-multiresolution-agency.md`. -The browser command boundary is deliberately smaller than `WorldCommand`. -Authenticated HTTP admits only player-owned Speak, unfilled Assess, Attempt, -Wait, and active-cell-budget requests. Actor identity must match the campaign player. Compiler -approval has its own route. Strategic ticks, region commits, gestalt presence, -reaction waves, NPC initiative, and campaign creation are internal mailbox -commands and cannot be invoked through `/api/command`. +The public application boundary is one stable Eve provider surface: +`GET /api/eve/provider`, `GET /api/eve/surfaces/ghostlight.play`, +`POST /api/eve/commands`, and revision-only `GET /api/eve/events`. Anonymous +surface requests return an Eve Heimdall access gate without campaign, +membership, actor, account, boundary, or Session Zero state. Authenticated +surface requests derive account, selected campaign, membership, and exact actor +from Ghostlight-owned app-session and campaign records before projection. -Authentication owns entry to the complete `/api` router before request-body -extraction. Axum's protected-route middleware reads only headers and durable -session authority; an invalid session receives `401` before JSON parsing, -schema rejection, campaign lookup, inference, or mutation. Handlers repeat the -session lookup where they need the session identity, so revocation between the -perimeter check and a handler cannot leave stale authority alive. Public -`/health`, the Heimdall login-attempt boundary, and static browser assets remain -outside this middleware. Login attempts carry no campaign authority: only a -JWKS-verified successful Heimdall callback can bind one to an account, and only -one browser adoption can mint its HttpOnly session alias. Regressions prove malformed anonymous JSON is refused -at the perimeter while the same malformed body under a valid session reaches -the ordinary `400` extractor response. +Command ingress accepts only `gamecult.eve.command_invocation.v1`. It validates +provider, logical surface, command boundary, operation schema, source version, +and idempotency before resolving the caller's authority server-side. Browser +payloads containing account, member, or actor authority fields are rejected. +Every admitted operation then uses the existing `SessionZeroKernel` or +`WorldKernel` mailbox and returns a persisted Eve command receipt. Strategic +ticks, region commits, NPC initiative, and raw kernel commands remain outside +the browser capability surface. + +The browser is `EveBrowserProviderHost`, Ghostlight transport, Heimdall access +adapter, status mount, and SSE invalidation. Eve owns editable bindings and +operation capture: renderer-local drafts survive authoritative refreshes and +stale refusals, and only an accepted result may request named draft clearance. +HTML forms may appear as an accessibility lowering detail but are absent from +Eve documents and command payload semantics. Session Zero, campaign, +governance, receipt, and login DOM renderers are not product authorities. + +Heimdall owns OAuth attempts, Discord callbacks, entitlement evaluation, claim +issuance, and single-use completion. Anonymous Eve operations cross Heimdall's +authenticated CultNet operation boundary on Yggdrasil loopback. Sensitive +completion and refresh fields are message-wrapped and never enter the public +CultMesh catalog, Odin records, Eve surfaces, logs, or browser responses. +Ghostlight validates the exact issuer, audience, app, profile, access revision, +session identity, expiry, and `app_access` before creating a local app session. + +`ghostlight.app_session.v1` stores a hash of the random cookie, stable Heimdall +subject hash, exact Heimdall session and access revision, verified capabilities, +expiries, and a locally wrapped refresh claim. Routine requests verify that +state locally. Claim refresh and logout revalidate exact Heimdall session +custody through the private boundary; a stale refresh cannot resurrect a +logged-out session. Heimdall outages leave valid local sessions usable only +until their verified expiry. Campaign access always comes from +`campaign_membership.v1`; account preferences remember only selection. The old +auth store is frozen rollback evidence and does not participate in admission. That boundary also projects less state outward than the kernel returns inward. Player HTTP responses contain only assessment, public commit/roll receipts, and @@ -421,7 +444,7 @@ before generation. Only direct-seed source text enters causal world compilation; background and excluded sources remain coverage provenance and cannot donate story incidents or cast. -The player Eve surface follows the same membrane. It renders the player-owned +The actor-filtered Eve surface follows the same membrane. It renders the player-owned ledger—including that actor's own relationships—and already filtered news, but does not enumerate canonical institution postures or raw world clocks. Those remain operator state until narration or an exact information channel makes a @@ -432,13 +455,11 @@ It likewise exposes only the number of operator pins and local active population leaves eligible for a fission preview. Pin bodies, remote population names, and `ReplaceResolutionPins` remain outside the player boundary. -HTTP operator inspection and provider-parallelism mutation require both an -authenticated campaign session and an actual loopback TCP peer. The daemon uses -Axum connection metadata from its direct listener; forwarded address headers do -not grant authority. LAN and WireGuard peers receive `403` before spoiler state -or controls are read. The browser operator panel is present only when loaded -from `127.0.0.1`, `localhost`, or `::1`; this mirrors the server boundary and is -not itself treated as security. +Exact private per-member and operator projections remain CultMesh documents for +authorized Verse consumers. The public provider advertisement exposes only the +subject-scoped logical surface and Heimdall plugin requirement. Hermodr may +materialize that provider for inspection when its plugin is installed; it is +not a Ghostlight runtime dependency and owns no application state. Global strategic context has a separate non-causal lane. Two stable broad Vault queries run alongside local retrieval, and a Flash extraction stage proposes a diff --git a/notes/ghostlight-implementation-plan.md b/notes/ghostlight-implementation-plan.md index 3d2d90d..ed767b2 100644 --- a/notes/ghostlight-implementation-plan.md +++ b/notes/ghostlight-implementation-plan.md @@ -31,6 +31,19 @@ persistent pins, approval-gated gestalt fission, graph and cover receipts, and a separate operator provider-concurrency limit. The specific authority map is `docs/architecture/ghostlight-multiresolution-agency.md`. + +The current interface cut makes that Eve publication the browser's actual +product boundary. `ghostlight.play` is one stable actor-filtered surface across +anonymous entry, Session Zero, Contract Review, and play. The browser embeds +Eve's canonical provider host and lowering package; text, numeric, and choice +input uses typed Eve bindings and renderer-local drafts, and operations capture +named bindings into canonical command invocations. There is no Eve form +ontology or generic `payload.fields` dialect. Heimdall supplies the required +`gamecult.heimdall.access` plugin and owns authentication attempts, Discord +callbacks, claims, entitlements, and completion redemption through its private +loopback CultNet command plane. Ghostlight owns hashed local sessions and +derives campaign authority only from canonical membership. The exact cut is +`docs/architecture/ghostlight-eve-native-interface.md`. The accepted implementation is hosted natively on Yggdrasil as immutable release `10b638e45756e5210aaee1efb5dcf74dbebf83c0`. Exact checkout, embedded commit, release manifest, binary hash, systemd process, typed health, diff --git a/state/map.yaml b/state/map.yaml index 55eddf4..c7810fc 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -90,6 +90,10 @@ live_architecture: - SessionZeroKernel is the sole pre-world owner of persistent shared/private negotiation, typed contracts, character drafts, boundaries, decisions, invitations, and approvals. The WorldKernel receives only an unanimously approved brief at atomic publication. - Bounded co-op uses campaign_membership.v1 to bind one to eight authenticated members to exact actors in the existing campaign mailbox. Sequential public actions, actor-filtered surfaces, unanimous time/travel/cell-budget changes, and non-simulatable human actors are implemented; split parties, PvP, private play actions, delegation, late joining, and group lifecycle commands remain unsupported. - Contract Review reuses Session Zero against an exact world revision. Unanimous publication may amend forward-looking contract and approved actor ledger fields but cannot rewrite custody, location, topology, knowledge, memory, canon, or history. Boundary tightening becomes immediate anonymous aggregate policy; relaxation waits for publication. + - `ghostlight.play` is the one stable Eve provider surface across anonymous entry, Session Zero, Contract Review, and campaign play. The browser embeds Eve's canonical provider host and lowering package; it owns only ephemeral drafts, tabs, focus, and rendering. + - Eve editable bindings are the input model. Operations capture named bindings into `gamecult.eve.command_invocation.v1`; rejected or stale receipts preserve drafts, and accepted receipts may clear exact binding names. HTML forms are lowering detail, not Eve state or payload semantics. + - Heimdall owns OAuth attempts, Discord callbacks, entitlement evaluation, claims, single-use completion, refresh, and logout. Its required Eve access plugin crosses a private loopback CultNet operation boundary; Ghostlight validates the exact claim and owns only its hashed app session before deriving actor authority from campaign membership. + - Public Ghostlight HTTP exposes only the Eve provider, logical surface, command, and invalidation endpoints plus the typed health probe and static assets. Exact private per-member and operator surfaces remain CultMesh documents; Hermodr is an optional generic materializer, not a runtime dependency. - Yggdrasil release admission resolves the newest executable- or build-affecting commit from the admitted ref. Later documentation, notes, state receipts, and root Markdown do not become runtime authority or cause a redeploy; Idunn proves the selected commit is an ancestor of the admitted ref and verifies the exact witness after activation. - Idunn owns Ghostlight deployment and same-release continuity, Odin owns discovery, Heimdall owns account identity, and VoidBot owns Vault retrieval. None can write campaign state. Epiphany is an adjacent consumer and future swarm-capacity provider, not a Ghostlight runtime dependency or authority. persistence_spine: diff --git a/vendor/eve b/vendor/eve index 076d212..6766bee 160000 --- a/vendor/eve +++ b/vendor/eve @@ -1 +1 @@ -Subproject commit 076d2124ed476cdaeff540c9d24c2d4fb57d04cf +Subproject commit 6766bee7c14a47144191475e2f35b0343b647b45 diff --git a/web/dist/assets/index-CYZ4YyRa.css b/web/dist/assets/index-0xx6l_wS.css similarity index 81% rename from web/dist/assets/index-CYZ4YyRa.css rename to web/dist/assets/index-0xx6l_wS.css index 8518f3e..2c37a19 100644 --- a/web/dist/assets/index-CYZ4YyRa.css +++ b/web/dist/assets/index-0xx6l_wS.css @@ -1 +1 @@ -@import"https://fonts.googleapis.com/css2?family=M+PLUS+1:wght@100;300;400;500;700&family=Montserrat:wght@100;300;400;500;700&family=Ubuntu+Sans:wght@300;400;500;700&family=Zen+Kaku+Gothic+New:wght@300;400;500;700&display=swap";@import"https://fonts.googleapis.com/css2?family=Crimson+Pro:opsz,wght@8..144,400;8..144,600&family=IBM+Plex+Mono:wght@400;600&display=swap";:root{color-scheme:dark;--bg: #020909;--bg-top: var(--bg);--bg-mid: var(--bg);--bg-bottom: var(--bg);--shell-top: #010707;--shell-bottom: #010707;--panel: #071918;--panel-2: #0a2423;--line: rgba(103, 240, 228, .28);--line-deep: rgba(103, 240, 228, .18);--line-hot: rgba(142, 252, 255, .72);--text: #e7f1f1;--text-bright: var(--text);--quiet: #8ba5a3;--accent: #ffb84f;--accent-strong: var(--accent);--corner-accent: var(--accent);--cyan: #8efcff;--shadow: rgba(0, 0, 0, .35);--pixel-grid: rgba(142, 252, 255, .04);--border-width: 1px;--border-bottom-width: var(--border-width);--corner-accent-size: 0;--font-body: "M PLUS 1", "Ubuntu Sans", Ubuntu, "Noto Sans JP", system-ui, sans-serif;--font-title: "Montserrat", "Zen Kaku Gothic New", "M PLUS 1", "Ubuntu Sans", system-ui, sans-serif;--font-mono: "Ubuntu Sans Mono", "M PLUS 1 Code", "Cascadia Mono", Consolas, monospace}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:linear-gradient(180deg,var(--bg-top),var(--bg-mid),var(--bg-bottom));color:var(--text);font-family:var(--font-body)}.topbar{height:84px;display:flex;justify-content:space-between;align-items:center;padding:10px 16px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,var(--shell-top),var(--shell-bottom))}h1{margin:0;font-size:20px;letter-spacing:0}p{margin:4px 0 0;color:var(--quiet);font-size:13px}.hud{min-width:168px;padding:8px;border:1px solid var(--line-hot);border-radius:6px;background:#071918e0;color:var(--accent);font-family:Cascadia Mono,Consolas,monospace;font-size:11px;display:grid;gap:2px}.provider-bar{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--line-deep);background:color-mix(in srgb,var(--panel) 70%,transparent)}.provider-bar label{color:var(--quiet);font:700 11px var(--font-mono);text-transform:uppercase}.provider-bar select{border:1px solid var(--line);border-radius:6px;background:var(--panel);color:var(--text);padding:8px 12px;font:700 13px var(--font-mono);min-width:min(28rem,52vw)}.provider-meta{color:var(--quiet);font:600 11px var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.surface{padding:10px 16px 16px}.cockpit{display:grid;grid-template-columns:.78fr 1.08fr 1.34fr;gap:10px;min-height:calc(100vh - 138px)}.ctb{grid-column:1 / -1;min-height:88px;overflow-x:auto;display:flex;gap:8px;padding-bottom:8px}.pane{min-height:0;border:1px solid var(--line);border-radius:6px;background:#071918eb;padding:12px;box-shadow:0 12px 26px var(--shadow)}.pane h2{margin:0 0 10px;color:var(--quiet);font-size:12px;font-weight:500;text-transform:uppercase}.card{border:1px solid var(--line);border-radius:6px;background:#0a2423f5;padding:10px;box-shadow:0 8px 20px var(--shadow)}.cultui-card[data-command-id]{cursor:pointer;border-bottom-width:var(--border-bottom-width)}.cultui-card-button{display:block;width:100%;color:inherit;font:inherit;text-align:left}.ctb .card{flex:0 0 96px;min-height:76px;padding:6px}.avatar{width:34px;height:34px;border-radius:50%;border:1px solid var(--line-hot);object-fit:cover;background:#123}.card-title{white-space:pre-line;margin-top:4px;font:700 11px var(--font-mono)}.health{color:var(--accent);font:700 10px var(--font-mono)}.detail{white-space:pre-wrap;font:600 12px var(--font-mono);line-height:1.45}.list{display:grid;gap:8px}.metrics{display:grid;gap:9px;margin:12px 0}.metric label{display:flex;justify-content:space-between;color:var(--quiet);font:700 10px var(--font-mono)}.bar{height:7px;border-radius:7px;background:#010707;border:1px solid rgba(255,255,255,.12);overflow:hidden}.bar span{display:block;height:100%;background:linear-gradient(90deg,#bca8ff,#8efcff)}.graph{position:relative;min-height:calc(100vh - 166px);border:1px solid var(--line);border-radius:6px;background:linear-gradient(var(--pixel-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pixel-grid) 1px,transparent 1px),#030f11f0;background-size:44px 44px}.node{position:absolute;transform:translate(-50%,-50%);border:1px solid var(--line);border-radius:7px;background:#0a2423f2;padding:10px;overflow:hidden}.node.selected{border-color:var(--line-hot);box-shadow:0 0 0 1px #8efcff61}.node .detail{margin-top:6px;color:var(--quiet);font-size:10px}@media(max-width:900px){.cockpit{grid-template-columns:1fr}}.cultui-vn-stage{position:relative;min-height:calc(100vh - 138px);overflow:hidden;border:1px solid var(--line);border-radius:6px;background:var(--bg)}.cultui-grid{min-height:calc(100vh - 138px);display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px;align-content:start}.cultui-surface-root{min-height:calc(100vh - 150px);display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;align-content:start}.cultui-surface-root[data-direction=vertical]{grid-template-columns:minmax(0,1fr)}.cultui-surface-root[data-direction=horizontal]{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.cultui-embedded-slot .cultui-surface-root{min-height:0;grid-template-columns:minmax(0,1fr)}@media(max-width:900px){.cultui-pane[data-span=wide]{grid-column:1 / -1}}.cultui-pane{border-width:var(--border-width);border-bottom-width:var(--border-bottom-width);min-width:0}.cultui-pane[data-span=wide]{grid-column:span 2}.cultui-pane .cultui-pane{box-shadow:none;background:#030f1161}.cultui-pane[data-density=compact]{padding:8px}.cultui-pane[data-density=compact] h2{margin-bottom:6px}.cultui-partition{min-width:0;min-height:0;display:flex;gap:10px}.cultui-partition[data-direction=horizontal]{flex-direction:row}.cultui-partition[data-direction=vertical]{flex-direction:column}.cultui-partition[data-overflow=x]{overflow-x:auto;padding-bottom:4px}.cultui-partition.split-x{flex-direction:row}.cultui-partition.split-y,.cultui-partition.split-none{flex-direction:column}.cultui-partition.split-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.cultui-partition[data-role="inspector.row"]{min-height:34px;border:1px solid rgba(255,255,255,.06);border-radius:4px;background:linear-gradient(180deg,#201f2bf5,#13141df5);box-shadow:inset 0 1px #ffffff0d,0 2px 8px #0006}.cultui-partition[data-role="inspector.label"]{justify-content:center}.cultui-label{color:var(--accent);font:700 13px var(--font-mono);line-height:1.15;text-transform:uppercase}.cultui-slider{--cultui-slider-value: 0%;--part-bleed: 0px;position:relative;display:grid;align-items:center;width:100%;min-height:18px;overflow:visible}.cultui-slider-visual{position:absolute;inset:0;overflow:visible;pointer-events:none}.cultui-slider-input{position:absolute;inset:0;opacity:0;cursor:pointer}.cultui-slider-part{position:absolute;top:50%;display:block;transform:translateY(-50%)}.cultui-slider-part.track{right:0;left:0;height:6px;border-radius:2px;background:#00000057}.cultui-slider-part.fill{left:0;width:var(--cultui-slider-value);height:6px;border-radius:2px;background:var(--accent)}.cultui-slider-part.thumb{left:var(--cultui-slider-value);width:12px;height:12px;border-radius:999px;background:var(--accent);transform:translate(-50%,-50%);box-shadow:0 0 7px color-mix(in srgb,var(--accent) 45%,transparent)}.cultui-slider-part[data-anchor-value=true]{left:var(--cultui-slider-value);transform:translate(-50%,-50%)}@media(max-width:520px){.cultui-partition[data-role="inspector.row"]{flex-direction:column;align-items:stretch}.cultui-partition[data-role="inspector.label"]{flex:0 0 auto!important}}body[data-provider=repixelizer] .surface{position:relative}body[data-provider=repixelizer] .surface:after{content:"";pointer-events:none;position:fixed;inset:0;background:repeating-linear-gradient(0deg,rgba(255,255,255,.035) 0 1px,transparent 1px 4px);opacity:.28;mix-blend-mode:screen}body[data-pixel-art=true] img,body[data-pixel-art=true] .cultui-background{image-rendering:pixelated}.cultui-title{color:var(--accent);font:100 18px var(--font-title);line-height:1.35}.mono{color:var(--accent);font-family:var(--font-mono)}.cultui-reactive-metric{margin-top:8px}.cultui-reactive-list{display:grid;gap:8px}.cultui-list{display:grid;gap:8px;min-width:0}.cultui-list-title{margin:0;color:var(--quiet);font:700 10px var(--font-mono);letter-spacing:0;text-transform:uppercase}.cultui-list-item{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid var(--line);border-radius:6px;background:var(--panel)}.cultui-list-item-heading,.cultui-list-item-badges{display:flex;gap:6px;align-items:center;flex-wrap:wrap;min-width:0}.cultui-list-item-label{min-width:0;overflow-wrap:anywhere}.cultui-list-item-status,.cultui-list-item-badge{padding:2px 5px;border:1px solid var(--line-hot);border-radius:4px;color:var(--quiet);font:600 10px var(--font-mono)}.cultui-list-item-detail{color:var(--quiet);font-size:12px;overflow-wrap:anywhere}.cultui-avatar-card{flex:0 0 104px;display:grid;gap:4px;align-content:start;min-height:92px;margin:0;padding:8px;border:1px solid var(--line);border-radius:6px;background:#0a2423f0;box-shadow:0 8px 20px var(--shadow)}.cultui-avatar-card img,.cultui-avatar-fallback{width:34px;height:34px;border:1px solid var(--line-hot);border-radius:50%;object-fit:cover;background:#010707db}.cultui-avatar-fallback{display:grid;place-items:center;color:var(--accent);font:700 12px var(--font-mono)}.cultui-avatar-name{color:var(--text-bright);font:700 11px var(--font-mono);line-height:1.15}.cultui-avatar-status,.cultui-avatar-detail{color:var(--quiet);font:700 10px var(--font-mono);line-height:1.2}.cultui-avatar-status{color:var(--accent)}.cultui-meter{display:grid;gap:4px}.cultui-meter-head{display:flex;justify-content:space-between;gap:8px;color:var(--quiet);font:700 10px var(--font-mono)}.cultui-meter-track{height:7px;overflow:hidden;border:1px solid rgba(255,255,255,.12);border-radius:7px;background:#010707e0}.cultui-meter-fill{display:block;height:100%;background:linear-gradient(90deg,#ffb84f,#8efcff)}.cultui-stream-item{border-left:2px solid var(--line-hot);padding-left:8px}.cultui-background{position:absolute;inset:0;background-size:cover;background-position:center;image-rendering:pixelated;opacity:.72}.cultui-graph{position:absolute;top:18px;left:18px;width:min(48rem,46vw);height:min(29rem,52vh);z-index:4}.cultui-placed{position:absolute;transform-origin:center}.cultui-placed[data-placement-mode=keystone],.cultui-placed[data-placement-mode=skew],.cultui-placed[data-placement-mode=sprite-chromakey]{box-shadow:0 12px 26px #00000047}.cultui-placed[data-chroma-key]{outline:1px dashed rgba(0,255,120,.45)}.cultui-node{position:absolute;transform:translate(-50%,-50%);border:2px solid var(--cyan);border-radius:999px;background:#07111ac2;color:var(--text);min-width:68px;min-height:44px;padding:8px 10px;font:700 12px Cascadia Mono,Consolas,monospace}.cultui-node.selected{border-color:var(--accent);box-shadow:0 0 0 2px #ffb84f47}.cultui-graph svg{position:absolute;inset:0;overflow:visible}.cultui-graph line{stroke:#8efcff5c;stroke-width:.006;stroke-linecap:round}.cultui-layer-embedded-surfaces{position:absolute;inset:0;z-index:5;pointer-events:none}.cultui-layer-embedded-surfaces>*{pointer-events:auto}.cultui-tex{min-width:12rem;min-height:3.2rem;border:1px solid rgba(142,252,255,.34);border-radius:6px;background:#07111ac7;color:var(--text);padding:10px 12px}.cultui-tex-label{color:var(--accent);font:700 10px Cascadia Mono,Consolas,monospace;text-transform:uppercase}.cultui-tex-source{margin-top:4px;font:700 15px "Cambria Math","STIX Two Math",Georgia,serif;white-space:pre-wrap}.cultui-layer-cards{position:absolute;top:18px;right:18px;left:calc(min(48rem,46vw) + 36px);z-index:3;display:grid;gap:10px}.cultui-dialogue{position:absolute;right:0;bottom:0;left:0;z-index:5;min-height:128px;border-right:0;border-bottom:0;border-left:0;border-radius:0;background:#05080deb}.cultui-rail-actions{position:absolute;right:18px;bottom:18px;z-index:6;display:grid;gap:8px;width:min(28rem,42vw)}.cultui-button{border:1px solid var(--line);border-radius:6px;background:#0a2423f0;color:var(--text);padding:9px 10px;text-align:left;font:700 12px Cascadia Mono,Consolas,monospace}.cultui-button:hover,.cultui-button:focus-visible{border-color:var(--line-hot);color:var(--accent)}.cultui-image-preview{display:grid;gap:8px;margin:0}.cultui-image-frame,.cultui-canvas-grid{display:grid;place-items:center;min-height:160px;border:2px solid var(--panel-border);background:repeating-linear-gradient(45deg,#f7efd80f 0 8px,#0000002e 8px 16px),linear-gradient(180deg,#07172c,#0a2039);overflow:hidden}.cultui-image-frame{aspect-ratio:1 / 1}.cultui-image-frame img{width:100%;height:100%;object-fit:cover}.cultui-image-preview figcaption,.cultui-canvas-grid{color:var(--muted);font-size:.75rem;line-height:1.25}.cultui-canvas-placeholder{display:grid;gap:8px}.cultui-canvas-placeholder.editor .cultui-canvas-grid{min-height:280px;background:linear-gradient(45deg,rgba(255,255,255,.08) 25%,transparent 25% 75%,rgba(255,255,255,.08) 75%),linear-gradient(45deg,rgba(255,255,255,.08) 25%,transparent 25% 75%,rgba(255,255,255,.08) 75%),#142033;background-position:0 0,8px 8px;background-size:16px 16px}.cultui-status-stage{display:grid;gap:8px;padding:12px;border:2px solid var(--panel-border);background:#061627eb}.cultui-field{display:grid;gap:4px}.cultui-field-value{display:block;border:2px solid var(--panel-border);background:#01040b94;padding:6px 8px}.cultui-world-scene{position:relative;z-index:2;width:100%;min-height:min(72vh,760px);overflow:hidden;outline:none;background:#02080c80}.cultui-world-scene:focus-visible{box-shadow:inset 0 0 0 2px var(--accent)}.cultui-world-heading{position:absolute;z-index:3;top:12px;left:12px;display:flex;gap:12px;align-items:baseline;color:var(--text);font-family:var(--font-mono);font-size:.75rem;pointer-events:none}.cultui-world-heading span{color:var(--quiet)}.cultui-world-plane{position:absolute;inset:0;background:linear-gradient(var(--pixel-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pixel-grid) 1px,transparent 1px);background-size:48px 48px}.cultui-world-entity{position:absolute;display:grid;justify-items:center;width:34px;height:34px;padding:0;border:1px solid rgba(224,238,240,.65);border-radius:50%;color:#f1f5f4;background:#182226eb;transform:translate(-50%,-50%);cursor:pointer}.cultui-world-entity.faction-player{border-color:#54d9c7;color:#9ff8e8}.cultui-world-entity.faction-raider,.cultui-world-entity.faction-hostile{border-color:#ff695f;color:#ffaaa3}.cultui-world-entity[data-controlled=true]{box-shadow:0 0 0 3px #ffbe4866}.cultui-world-entity-glyph{align-self:center;font:700 16px/1 var(--font-mono)}.cultui-world-entity-label{position:absolute;top:38px;width:max-content;max-width:132px;overflow:hidden;color:var(--text);font:600 11px/1.2 var(--font-body);text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.cultui-swatch{width:36px;min-height:36px;border:2px solid var(--accent);box-shadow:inset 0 0 0 2px #00000073}.cultui-binding-map{position:relative;min-height:510px;border:1px solid var(--line);border-radius:6px;background:linear-gradient(var(--pixel-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pixel-grid) 1px,transparent 1px),#030f11eb;background-size:28px 28px;overflow:hidden}.cultui-xbox-controller{position:absolute;inset:18px;width:calc(100% - 36px);height:calc(100% - 36px)}.cultui-xbox-controller .shell,.cultui-xbox-controller .stick,.cultui-xbox-controller .dpad,.cultui-xbox-controller .face,.cultui-xbox-controller .menu,.cultui-xbox-controller .guide,.cultui-xbox-controller .bumper,.cultui-xbox-controller .trigger{fill:#0a2423f0;stroke:var(--line);stroke-width:3}.cultui-xbox-controller .stick-dot,.cultui-xbox-controller .guide{fill:#8efcff1f}.cultui-xbox-controller .face{fill:#ffb84f29}.cultui-xbox-controller text{fill:var(--text);font:700 16px var(--font-mono);text-anchor:middle}.cultui-binding-line{stroke:var(--accent);stroke-width:2;stroke-dasharray:5 6;opacity:.78}.cultui-binding-overlay{position:absolute;inset:0}.cultui-binding-box{position:absolute;width:clamp(112px,12vw,138px);min-height:50px;transform:translate(-50%,-50%);display:grid;gap:4px;border:1px solid var(--line-hot);border-radius:6px;background:#071918f5;color:var(--text);padding:8px;text-align:left;box-shadow:0 10px 20px var(--shadow)}.cultui-binding-box:hover,.cultui-binding-box:focus-visible{border-color:var(--accent);color:var(--accent)}.cultui-binding-target{font:700 11px var(--font-mono);text-transform:uppercase}.cultui-binding-source{color:var(--quiet);font:600 11px var(--font-mono);overflow-wrap:anywhere}.cultui-modal-backdrop{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;background:#00000094;padding:20px}.cultui-modal{width:min(680px,96vw);max-height:min(780px,92vh);display:grid;grid-template-rows:auto minmax(0,1fr);border:1px solid var(--line-hot);border-radius:6px;background:var(--panel);box-shadow:0 18px 42px #00000085;overflow:hidden}.cultui-modal-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line);background:var(--shell-top)}.cultui-modal-header h2{margin:0;color:var(--accent);font:700 13px var(--font-mono);text-transform:uppercase}.cultui-modal-close{border:1px solid var(--line);border-radius:6px;background:var(--panel-2);color:var(--text);padding:7px 10px;font:700 11px var(--font-mono)}.cultui-modal-body{min-height:0;overflow:auto;padding:14px}@media(max-width:900px){.cultui-graph{right:12px;left:12px;width:auto;height:min(18rem,34vh)}.cultui-layer-cards{top:calc(30px + min(18rem,34vh));right:12px;left:12px}.cultui-rail-actions{left:12px;width:auto}}:root{color-scheme:dark;font-family:Crimson Pro,serif;background:#0c1110;color:#e8e1cf}body{margin:0;min-height:100vh;background:radial-gradient(circle at 15% 0,#253229 0,transparent 38rem),linear-gradient(145deg,#0c1110,#111513)}header,main{width:min(1180px,calc(100% - 2rem));margin:auto}header{padding:3rem 0 1.25rem;border-bottom:1px solid #66543d}h1{font-size:clamp(2.6rem,8vw,5.5rem);font-weight:400;letter-spacing:-.045em;margin:.1rem 0}.eyebrow,#status,label,button,pre,.state-pill,dt{font-family:IBM Plex Mono,monospace}.eyebrow{color:#d49b58;letter-spacing:.18em;font-size:.72rem}#status{color:#9aa69f;font-size:.78rem}main{padding:1.5rem 0 5rem}#surface{min-height:8rem}form,.card{margin-top:1rem;padding:1rem;border:1px solid #66543d;background:#17201ddd}label{display:block;font-size:.72rem;text-transform:uppercase;letter-spacing:.12em;margin:.65rem 0 .25rem}textarea,input,select{box-sizing:border-box;width:100%;resize:vertical;background:#0b0f0d;color:#f2e7d0;border:1px solid #4a5148;padding:.8rem;margin:.15rem 0;font:1.05rem/1.4 Crimson Pro,serif}input[type=radio]{width:auto}input[type=range]{padding:.25rem;accent-color:#d49b58}textarea{min-height:7rem}button{margin:.8rem .5rem 0 0;padding:.65rem 1rem;border:1px solid #d49b58;background:#d49b58;color:#17120c;cursor:pointer}button+button,.channel-tabs button[aria-pressed=false]{background:transparent;color:#d49b58}button:disabled,input:disabled,textarea:disabled,select:disabled{cursor:not-allowed;opacity:.5}pre{white-space:pre-wrap;padding:1rem;background:#080b09;color:#aeb9af;overflow:auto;font-size:.72rem}.card h3{margin:.1rem 0}.card p{color:#b9c0b7}.warning{color:#e4a86a!important}code{font-family:IBM Plex Mono,monospace;color:#d49b58}.skip-link{position:absolute;left:-10000px}.skip-link:focus{left:1rem;top:1rem;background:#d49b58;color:#111;padding:.5rem;z-index:9}.session-heading{display:flex;justify-content:space-between;align-items:end;gap:1rem}.state-pill{padding:.4rem .65rem;border:1px solid #66543d;color:#d49b58;font-size:.72rem}.channel-tabs{position:sticky;top:0;z-index:2;padding:.35rem 0;background:#0c1110e8}.session-grid{display:grid;grid-template-columns:minmax(0,1.65fr) minmax(18rem,1fr);gap:1rem}.session-grid aside{min-width:0}.transcript{list-style:none;padding:0;max-height:34rem;overflow:auto}.message{border-left:2px solid #59675e;padding:.6rem .8rem;margin:.65rem 0;background:#0b0f0d}.message.dm{border-color:#d49b58}.message p{white-space:pre-wrap;margin:.25rem 0}.message strong,dt{color:#d49b58;font-size:.72rem;text-transform:uppercase;letter-spacing:.08em}.decision{border-top:1px solid #354039;padding:.8rem 0}dl{display:grid;grid-template-columns:minmax(7rem,.7fr) minmax(0,1.3fr);gap:.45rem .75rem}dt,dd{margin:0;overflow-wrap:anywhere}fieldset{border:1px solid #4a5148;margin:1rem 0}fieldset label{display:inline-block;margin-right:1rem}.button-row{display:flex;flex-wrap:wrap}.governance{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.governance h2{grid-column:1/-1}.quiet{color:#9aa69f!important}.session-actions button{display:block;width:100%}.card a{color:#d49b58;overflow-wrap:anywhere}@media(max-width:820px){.session-grid,.governance{grid-template-columns:1fr}.session-grid aside{display:contents}.channel-tabs{display:flex}.channel-tabs button{flex:1}.session-heading{align-items:start;flex-direction:column}dl{grid-template-columns:1fr}.message{padding:.5rem}}@media(max-width:600px){header{padding-top:2rem}h1{font-size:3rem}header,main{width:min(100% - 1rem,1180px)}form,.card{padding:.75rem}.state-pill{margin:0}}.form-heading{font:600 .72rem IBM Plex Mono,monospace;text-transform:uppercase;letter-spacing:.12em;color:#d49b58}.card details{margin:.65rem 0;border-top:1px solid #354039;padding-top:.65rem}.card summary{cursor:pointer;font:600 .76rem IBM Plex Mono,monospace;color:#d49b58}.card ul{margin:.6rem 0;padding-left:1.25rem}.card li{margin:.25rem 0;color:#c8d0c8}#receipt h3{margin:.1rem 0 .75rem} +@import"https://fonts.googleapis.com/css2?family=M+PLUS+1:wght@100;300;400;500;700&family=Montserrat:wght@100;300;400;500;700&family=Ubuntu+Sans:wght@300;400;500;700&family=Zen+Kaku+Gothic+New:wght@300;400;500;700&display=swap";@import"https://fonts.googleapis.com/css2?family=Crimson+Pro:opsz,wght@8..144,400;8..144,600&family=IBM+Plex+Mono:wght@400;600&display=swap";:root{color-scheme:dark;--bg: #020909;--bg-top: var(--bg);--bg-mid: var(--bg);--bg-bottom: var(--bg);--shell-top: #010707;--shell-bottom: #010707;--panel: #071918;--panel-2: #0a2423;--line: rgba(103, 240, 228, .28);--line-deep: rgba(103, 240, 228, .18);--line-hot: rgba(142, 252, 255, .72);--text: #e7f1f1;--text-bright: var(--text);--quiet: #8ba5a3;--accent: #ffb84f;--accent-strong: var(--accent);--corner-accent: var(--accent);--cyan: #8efcff;--shadow: rgba(0, 0, 0, .35);--pixel-grid: rgba(142, 252, 255, .04);--border-width: 1px;--border-bottom-width: var(--border-width);--corner-accent-size: 0;--font-body: "M PLUS 1", "Ubuntu Sans", Ubuntu, "Noto Sans JP", system-ui, sans-serif;--font-title: "Montserrat", "Zen Kaku Gothic New", "M PLUS 1", "Ubuntu Sans", system-ui, sans-serif;--font-mono: "Ubuntu Sans Mono", "M PLUS 1 Code", "Cascadia Mono", Consolas, monospace}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:linear-gradient(180deg,var(--bg-top),var(--bg-mid),var(--bg-bottom));color:var(--text);font-family:var(--font-body)}.topbar{height:84px;display:flex;justify-content:space-between;align-items:center;padding:10px 16px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,var(--shell-top),var(--shell-bottom))}h1{margin:0;font-size:20px;letter-spacing:0}p{margin:4px 0 0;color:var(--quiet);font-size:13px}.hud{min-width:168px;padding:8px;border:1px solid var(--line-hot);border-radius:6px;background:#071918e0;color:var(--accent);font-family:Cascadia Mono,Consolas,monospace;font-size:11px;display:grid;gap:2px}.provider-bar{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--line-deep);background:color-mix(in srgb,var(--panel) 70%,transparent)}.provider-bar label{color:var(--quiet);font:700 11px var(--font-mono);text-transform:uppercase}.provider-bar select{border:1px solid var(--line);border-radius:6px;background:var(--panel);color:var(--text);padding:8px 12px;font:700 13px var(--font-mono);min-width:min(28rem,52vw)}.provider-meta{color:var(--quiet);font:600 11px var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.surface{padding:10px 16px 16px}.cockpit{display:grid;grid-template-columns:.78fr 1.08fr 1.34fr;gap:10px;min-height:calc(100vh - 138px)}.ctb{grid-column:1 / -1;min-height:88px;overflow-x:auto;display:flex;gap:8px;padding-bottom:8px}.pane{min-height:0;border:1px solid var(--line);border-radius:6px;background:#071918eb;padding:12px;box-shadow:0 12px 26px var(--shadow)}.pane h2{margin:0 0 10px;color:var(--quiet);font-size:12px;font-weight:500;text-transform:uppercase}.card{border:1px solid var(--line);border-radius:6px;background:#0a2423f5;padding:10px;box-shadow:0 8px 20px var(--shadow)}.cultui-card[data-command-id]{cursor:pointer;border-bottom-width:var(--border-bottom-width)}.cultui-card-button{display:block;width:100%;color:inherit;font:inherit;text-align:left}.ctb .card{flex:0 0 96px;min-height:76px;padding:6px}.avatar{width:34px;height:34px;border-radius:50%;border:1px solid var(--line-hot);object-fit:cover;background:#123}.card-title{white-space:pre-line;margin-top:4px;font:700 11px var(--font-mono)}.health{color:var(--accent);font:700 10px var(--font-mono)}.detail{white-space:pre-wrap;font:600 12px var(--font-mono);line-height:1.45}.list{display:grid;gap:8px}.metrics{display:grid;gap:9px;margin:12px 0}.metric label{display:flex;justify-content:space-between;color:var(--quiet);font:700 10px var(--font-mono)}.bar{height:7px;border-radius:7px;background:#010707;border:1px solid rgba(255,255,255,.12);overflow:hidden}.bar span{display:block;height:100%;background:linear-gradient(90deg,#bca8ff,#8efcff)}.graph{position:relative;min-height:calc(100vh - 166px);border:1px solid var(--line);border-radius:6px;background:linear-gradient(var(--pixel-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pixel-grid) 1px,transparent 1px),#030f11f0;background-size:44px 44px}.node{position:absolute;transform:translate(-50%,-50%);border:1px solid var(--line);border-radius:7px;background:#0a2423f2;padding:10px;overflow:hidden}.node.selected{border-color:var(--line-hot);box-shadow:0 0 0 1px #8efcff61}.node .detail{margin-top:6px;color:var(--quiet);font-size:10px}@media(max-width:900px){.cockpit{grid-template-columns:1fr}}.cultui-vn-stage{position:relative;min-height:calc(100vh - 138px);overflow:hidden;border:1px solid var(--line);border-radius:6px;background:var(--bg)}.cultui-grid{min-height:calc(100vh - 138px);display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px;align-content:start}.cultui-surface-root{min-height:calc(100vh - 150px);display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;align-content:start}.cultui-surface-root[data-direction=vertical]{grid-template-columns:minmax(0,1fr)}.cultui-surface-root[data-direction=horizontal]{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.cultui-embedded-slot .cultui-surface-root{min-height:0;grid-template-columns:minmax(0,1fr)}@media(max-width:900px){.cultui-pane[data-span=wide]{grid-column:1 / -1}}.cultui-pane{border-width:var(--border-width);border-bottom-width:var(--border-bottom-width);min-width:0}.cultui-pane[data-span=wide]{grid-column:span 2}.cultui-pane .cultui-pane{box-shadow:none;background:#030f1161}.cultui-pane[data-density=compact]{padding:8px}.cultui-pane[data-density=compact] h2{margin-bottom:6px}.cultui-partition{min-width:0;min-height:0;display:flex;gap:10px}.cultui-partition[data-direction=horizontal]{flex-direction:row}.cultui-partition[data-direction=vertical]{flex-direction:column}.cultui-partition[data-overflow=x]{overflow-x:auto;padding-bottom:4px}.cultui-partition.split-x{flex-direction:row}.cultui-partition.split-y,.cultui-partition.split-none{flex-direction:column}.cultui-partition.split-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.cultui-partition[data-role="inspector.row"]{min-height:34px;border:1px solid rgba(255,255,255,.06);border-radius:4px;background:linear-gradient(180deg,#201f2bf5,#13141df5);box-shadow:inset 0 1px #ffffff0d,0 2px 8px #0006}.cultui-partition[data-role="inspector.label"]{justify-content:center}.cultui-label{color:var(--accent);font:700 13px var(--font-mono);line-height:1.15;text-transform:uppercase}.cultui-slider{--cultui-slider-value: 0%;--part-bleed: 0px;position:relative;display:grid;align-items:center;width:100%;min-height:18px;overflow:visible}.cultui-slider-visual{position:absolute;inset:0;overflow:visible;pointer-events:none}.cultui-slider-input{position:absolute;inset:0;opacity:0;cursor:pointer}.cultui-slider-part{position:absolute;top:50%;display:block;transform:translateY(-50%)}.cultui-slider-part.track{right:0;left:0;height:6px;border-radius:2px;background:#00000057}.cultui-slider-part.fill{left:0;width:var(--cultui-slider-value);height:6px;border-radius:2px;background:var(--accent)}.cultui-slider-part.thumb{left:var(--cultui-slider-value);width:12px;height:12px;border-radius:999px;background:var(--accent);transform:translate(-50%,-50%);box-shadow:0 0 7px color-mix(in srgb,var(--accent) 45%,transparent)}.cultui-slider-part[data-anchor-value=true]{left:var(--cultui-slider-value);transform:translate(-50%,-50%)}@media(max-width:520px){.cultui-partition[data-role="inspector.row"]{flex-direction:column;align-items:stretch}.cultui-partition[data-role="inspector.label"]{flex:0 0 auto!important}}body[data-provider=repixelizer] .surface{position:relative}body[data-provider=repixelizer] .surface:after{content:"";pointer-events:none;position:fixed;inset:0;background:repeating-linear-gradient(0deg,rgba(255,255,255,.035) 0 1px,transparent 1px 4px);opacity:.28;mix-blend-mode:screen}body[data-pixel-art=true] img,body[data-pixel-art=true] .cultui-background{image-rendering:pixelated}.cultui-title{color:var(--accent);font:100 18px var(--font-title);line-height:1.35}.mono{color:var(--accent);font-family:var(--font-mono)}.cultui-reactive-metric{margin-top:8px}.cultui-reactive-list{display:grid;gap:8px}.cultui-list{display:grid;gap:8px;min-width:0}.cultui-list-title{margin:0;color:var(--quiet);font:700 10px var(--font-mono);letter-spacing:0;text-transform:uppercase}.cultui-list-item{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid var(--line);border-radius:6px;background:var(--panel)}.cultui-list-item-heading,.cultui-list-item-badges{display:flex;gap:6px;align-items:center;flex-wrap:wrap;min-width:0}.cultui-list-item-label{min-width:0;overflow-wrap:anywhere}.cultui-list-item-status,.cultui-list-item-badge{padding:2px 5px;border:1px solid var(--line-hot);border-radius:4px;color:var(--quiet);font:600 10px var(--font-mono)}.cultui-list-item-detail{color:var(--quiet);font-size:12px;overflow-wrap:anywhere}.cultui-avatar-card{flex:0 0 104px;display:grid;gap:4px;align-content:start;min-height:92px;margin:0;padding:8px;border:1px solid var(--line);border-radius:6px;background:#0a2423f0;box-shadow:0 8px 20px var(--shadow)}.cultui-avatar-card img,.cultui-avatar-fallback{width:34px;height:34px;border:1px solid var(--line-hot);border-radius:50%;object-fit:cover;background:#010707db}.cultui-avatar-fallback{display:grid;place-items:center;color:var(--accent);font:700 12px var(--font-mono)}.cultui-avatar-name{color:var(--text-bright);font:700 11px var(--font-mono);line-height:1.15}.cultui-avatar-status,.cultui-avatar-detail{color:var(--quiet);font:700 10px var(--font-mono);line-height:1.2}.cultui-avatar-status{color:var(--accent)}.cultui-meter{display:grid;gap:4px}.cultui-meter-head{display:flex;justify-content:space-between;gap:8px;color:var(--quiet);font:700 10px var(--font-mono)}.cultui-meter-track{height:7px;overflow:hidden;border:1px solid rgba(255,255,255,.12);border-radius:7px;background:#010707e0}.cultui-meter-fill{display:block;height:100%;background:linear-gradient(90deg,#ffb84f,#8efcff)}.cultui-stream-item{border-left:2px solid var(--line-hot);padding-left:8px}.cultui-background{position:absolute;inset:0;background-size:cover;background-position:center;image-rendering:pixelated;opacity:.72}.cultui-graph{position:absolute;top:18px;left:18px;width:min(48rem,46vw);height:min(29rem,52vh);z-index:4}.cultui-placed{position:absolute;transform-origin:center}.cultui-placed[data-placement-mode=keystone],.cultui-placed[data-placement-mode=skew],.cultui-placed[data-placement-mode=sprite-chromakey]{box-shadow:0 12px 26px #00000047}.cultui-placed[data-chroma-key]{outline:1px dashed rgba(0,255,120,.45)}.cultui-node{position:absolute;transform:translate(-50%,-50%);border:2px solid var(--cyan);border-radius:999px;background:#07111ac2;color:var(--text);min-width:68px;min-height:44px;padding:8px 10px;font:700 12px Cascadia Mono,Consolas,monospace}.cultui-node.selected{border-color:var(--accent);box-shadow:0 0 0 2px #ffb84f47}.cultui-graph svg{position:absolute;inset:0;overflow:visible}.cultui-graph line{stroke:#8efcff5c;stroke-width:.006;stroke-linecap:round}.cultui-layer-embedded-surfaces{position:absolute;inset:0;z-index:5;pointer-events:none}.cultui-layer-embedded-surfaces>*{pointer-events:auto}.cultui-tex{min-width:12rem;min-height:3.2rem;border:1px solid rgba(142,252,255,.34);border-radius:6px;background:#07111ac7;color:var(--text);padding:10px 12px}.cultui-tex-label{color:var(--accent);font:700 10px Cascadia Mono,Consolas,monospace;text-transform:uppercase}.cultui-tex-source{margin-top:4px;font:700 15px "Cambria Math","STIX Two Math",Georgia,serif;white-space:pre-wrap}.cultui-layer-cards{position:absolute;top:18px;right:18px;left:calc(min(48rem,46vw) + 36px);z-index:3;display:grid;gap:10px}.cultui-dialogue{position:absolute;right:0;bottom:0;left:0;z-index:5;min-height:128px;border-right:0;border-bottom:0;border-left:0;border-radius:0;background:#05080deb}.cultui-rail-actions{position:absolute;right:18px;bottom:18px;z-index:6;display:grid;gap:8px;width:min(28rem,42vw)}.cultui-button{border:1px solid var(--line);border-radius:6px;background:#0a2423f0;color:var(--text);padding:9px 10px;text-align:left;font:700 12px Cascadia Mono,Consolas,monospace}.cultui-button:hover,.cultui-button:focus-visible{border-color:var(--line-hot);color:var(--accent)}.cultui-image-preview{display:grid;gap:8px;margin:0}.cultui-image-frame,.cultui-canvas-grid{display:grid;place-items:center;min-height:160px;border:2px solid var(--panel-border);background:repeating-linear-gradient(45deg,#f7efd80f 0 8px,#0000002e 8px 16px),linear-gradient(180deg,#07172c,#0a2039);overflow:hidden}.cultui-image-frame{aspect-ratio:1 / 1}.cultui-image-frame img{width:100%;height:100%;object-fit:cover}.cultui-image-preview figcaption,.cultui-canvas-grid{color:var(--muted);font-size:.75rem;line-height:1.25}.cultui-canvas-placeholder{display:grid;gap:8px}.cultui-canvas-placeholder.editor .cultui-canvas-grid{min-height:280px;background:linear-gradient(45deg,rgba(255,255,255,.08) 25%,transparent 25% 75%,rgba(255,255,255,.08) 75%),linear-gradient(45deg,rgba(255,255,255,.08) 25%,transparent 25% 75%,rgba(255,255,255,.08) 75%),#142033;background-position:0 0,8px 8px;background-size:16px 16px}.cultui-status-stage{display:grid;gap:8px;padding:12px;border:2px solid var(--panel-border);background:#061627eb}.cultui-field{display:grid;gap:4px}.cultui-field-value{display:block;border:2px solid var(--panel-border);background:#01040b94;padding:6px 8px}.cultui-world-scene{position:relative;z-index:2;width:100%;min-height:min(72vh,760px);overflow:hidden;outline:none;background:#02080c80}.cultui-world-scene:focus-visible{box-shadow:inset 0 0 0 2px var(--accent)}.cultui-world-heading{position:absolute;z-index:3;top:12px;left:12px;display:flex;gap:12px;align-items:baseline;color:var(--text);font-family:var(--font-mono);font-size:.75rem;pointer-events:none}.cultui-world-heading span{color:var(--quiet)}.cultui-world-plane{position:absolute;inset:0;background:linear-gradient(var(--pixel-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pixel-grid) 1px,transparent 1px);background-size:48px 48px}.cultui-world-entity{position:absolute;display:grid;justify-items:center;width:34px;height:34px;padding:0;border:1px solid rgba(224,238,240,.65);border-radius:50%;color:#f1f5f4;background:#182226eb;transform:translate(-50%,-50%);cursor:pointer}.cultui-world-entity.faction-player{border-color:#54d9c7;color:#9ff8e8}.cultui-world-entity.faction-raider,.cultui-world-entity.faction-hostile{border-color:#ff695f;color:#ffaaa3}.cultui-world-entity[data-controlled=true]{box-shadow:0 0 0 3px #ffbe4866}.cultui-world-entity-glyph{align-self:center;font:700 16px/1 var(--font-mono)}.cultui-world-entity-label{position:absolute;top:38px;width:max-content;max-width:132px;overflow:hidden;color:var(--text);font:600 11px/1.2 var(--font-body);text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.cultui-swatch{width:36px;min-height:36px;border:2px solid var(--accent);box-shadow:inset 0 0 0 2px #00000073}.cultui-binding-map{position:relative;min-height:510px;border:1px solid var(--line);border-radius:6px;background:linear-gradient(var(--pixel-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pixel-grid) 1px,transparent 1px),#030f11eb;background-size:28px 28px;overflow:hidden}.cultui-xbox-controller{position:absolute;inset:18px;width:calc(100% - 36px);height:calc(100% - 36px)}.cultui-xbox-controller .shell,.cultui-xbox-controller .stick,.cultui-xbox-controller .dpad,.cultui-xbox-controller .face,.cultui-xbox-controller .menu,.cultui-xbox-controller .guide,.cultui-xbox-controller .bumper,.cultui-xbox-controller .trigger{fill:#0a2423f0;stroke:var(--line);stroke-width:3}.cultui-xbox-controller .stick-dot,.cultui-xbox-controller .guide{fill:#8efcff1f}.cultui-xbox-controller .face{fill:#ffb84f29}.cultui-xbox-controller text{fill:var(--text);font:700 16px var(--font-mono);text-anchor:middle}.cultui-binding-line{stroke:var(--accent);stroke-width:2;stroke-dasharray:5 6;opacity:.78}.cultui-binding-overlay{position:absolute;inset:0}.cultui-binding-box{position:absolute;width:clamp(112px,12vw,138px);min-height:50px;transform:translate(-50%,-50%);display:grid;gap:4px;border:1px solid var(--line-hot);border-radius:6px;background:#071918f5;color:var(--text);padding:8px;text-align:left;box-shadow:0 10px 20px var(--shadow)}.cultui-binding-box:hover,.cultui-binding-box:focus-visible{border-color:var(--accent);color:var(--accent)}.cultui-binding-target{font:700 11px var(--font-mono);text-transform:uppercase}.cultui-binding-source{color:var(--quiet);font:600 11px var(--font-mono);overflow-wrap:anywhere}.cultui-modal-backdrop{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;background:#00000094;padding:20px}.cultui-modal{width:min(680px,96vw);max-height:min(780px,92vh);display:grid;grid-template-rows:auto minmax(0,1fr);border:1px solid var(--line-hot);border-radius:6px;background:var(--panel);box-shadow:0 18px 42px #00000085;overflow:hidden}.cultui-modal-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line);background:var(--shell-top)}.cultui-modal-header h2{margin:0;color:var(--accent);font:700 13px var(--font-mono);text-transform:uppercase}.cultui-modal-close{border:1px solid var(--line);border-radius:6px;background:var(--panel-2);color:var(--text);padding:7px 10px;font:700 11px var(--font-mono)}.cultui-modal-body{min-height:0;overflow:auto;padding:14px}.cultui-inventory-placement-preview{z-index:20;border:1px solid currentColor;box-sizing:border-box}.cultui-inventory-placement-preview.is-valid{color:#45e6a8;background:#45e6a857}.cultui-inventory-placement-preview.is-invalid{color:#ff5148;background:#ff514861}@media(max-width:900px){.cultui-graph{right:12px;left:12px;width:auto;height:min(18rem,34vh)}.cultui-layer-cards{top:calc(30px + min(18rem,34vh));right:12px;left:12px}.cultui-rail-actions{left:12px;width:auto}}.cultui-field-input,.cultui-field-select{box-sizing:border-box;width:100%;min-width:0;padding:.65rem .75rem;color:var(--text, inherit);background:var(--panel-inset, rgba(0, 0, 0, .25));border:1px solid var(--border, currentColor);border-radius:.25rem;font:inherit}textarea.cultui-field-input{resize:vertical}.cultui-field-validation{display:block;color:var(--danger, #ff8e8e);margin-top:.25rem}.cultui-choice-group{border:0;padding:0}.cultui-choice{display:flex;gap:.5rem;align-items:baseline}.cultui-tab-list{display:flex;gap:.25rem;overflow-x:auto}.cultui-tab[aria-selected=true]{border-bottom-color:var(--accent, currentColor)}.eve-command-result-region{margin-top:.75rem}:root{color-scheme:dark;font-family:Crimson Pro,serif;background:#0c1110;color:#e8e1cf}body{margin:0;min-height:100vh;background:radial-gradient(circle at 15% 0,#253229 0,transparent 38rem),linear-gradient(145deg,#0c1110,#111513)}header,#surface{width:min(1180px,calc(100% - 2rem));margin:auto}header{padding:3rem 0 1.25rem;border-bottom:1px solid #66543d}h1{font-size:clamp(2.6rem,8vw,5.5rem);font-weight:400;letter-spacing:-.045em;margin:.1rem 0}.eyebrow,#status,.field-label,button,pre{font-family:IBM Plex Mono,monospace}.eyebrow{color:#d49b58;letter-spacing:.18em;font-size:.72rem}#status{color:#9aa69f;font-size:.78rem}#surface{padding:1.5rem 0 5rem;min-height:12rem}.eve-surface{display:grid;gap:1rem}.card,.pane,.heimdall-access{padding:1rem;border:1px solid #66543d;background:#17201ddd}.cultui-field{display:block;margin:.75rem 0}.field-label{display:block;font-size:.72rem;text-transform:uppercase;letter-spacing:.12em;margin:.65rem 0 .25rem}textarea,input,select{box-sizing:border-box;width:100%;resize:vertical;background:#0b0f0d;color:#f2e7d0;border:1px solid #4a5148;padding:.8rem;margin:.15rem 0;font:1.05rem/1.4 Crimson Pro,serif}textarea{min-height:7rem}button{margin:.8rem .5rem 0 0;padding:.65rem 1rem;border:1px solid #d49b58;background:#d49b58;color:#17120c;cursor:pointer}button:disabled,input:disabled,textarea:disabled,select:disabled{cursor:not-allowed;opacity:.5}pre,.cultui-code{white-space:pre-wrap;padding:1rem;background:#080b09;color:#aeb9af;overflow:auto;font:.72rem/1.5 IBM Plex Mono,monospace}.skip-link{position:absolute;left:-10000px}.skip-link:focus{left:1rem;top:1rem;background:#d49b58;color:#111;padding:.5rem;z-index:9}.cultui-list-item{border-top:1px solid #354039;padding:.8rem 0}.cultui-list-item-label,.cultui-list-item-status{font-family:IBM Plex Mono,monospace;color:#d49b58;font-size:.72rem;text-transform:uppercase;letter-spacing:.08em}.cultui-tabs [role=tablist]{display:flex;gap:.4rem;position:sticky;top:0;background:#0c1110e8;z-index:2}.eve-command-result{margin:1rem 0;padding:1rem;border:1px solid #66543d;background:#17201d}@media(max-width:600px){header{padding-top:2rem}h1{font-size:3rem}header,#surface{width:min(100% - 1rem,1180px)}.card,.pane,.heimdall-access{padding:.75rem}} diff --git a/web/dist/assets/index-BHkI62J0.js b/web/dist/assets/index-BHkI62J0.js deleted file mode 100644 index b55fb99..0000000 --- a/web/dist/assets/index-BHkI62J0.js +++ /dev/null @@ -1,153 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))i(a);new MutationObserver(a=>{for(const s of a)if(s.type==="childList")for(const c of s.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&i(c)}).observe(document,{childList:!0,subtree:!0});function n(a){const s={};return a.integrity&&(s.integrity=a.integrity),a.referrerPolicy&&(s.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?s.credentials="include":a.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function i(a){if(a.ep)return;a.ep=!0;const s=n(a);fetch(a.href,s)}})();const q=new WeakMap,$e=20;function bt(e,t,n,i,a,s,c,l){const f=St(e.canvas);if(!f)return!1;const o=f.gl;if(!Et(f,s,c))return q.set(e.canvas,null),!1;const r=wt(t,n,i,a,l);o.bindFramebuffer(o.FRAMEBUFFER,f.framebuffer),o.viewport(0,0,s,c),o.disable(o.DEPTH_TEST),o.disable(o.CULL_FACE),o.enable(o.BLEND),o.blendFunc(o.ONE,o.ONE),o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),r.gravity.length>0&&(o.useProgram(f.splatProgram),o.uniform4f(o.getUniformLocation(f.splatProgram,"u_viewport"),a.minX,a.minY,a.maxX,a.maxY),o.uniform1f(o.getUniformLocation(f.splatProgram,"u_time"),C(t.simulationTimeSeconds,0)),o.bindBuffer(o.ARRAY_BUFFER,f.splatBuffer),o.bufferData(o.ARRAY_BUFFER,r.gravity,o.DYNAMIC_DRAW),qe(o,f.splatProgram),o.drawArrays(o.TRIANGLES,0,r.gravity.length/$e)),o.bindFramebuffer(o.FRAMEBUFFER,f.tintFramebuffer),o.clearColor(0,0,0,0),o.clear(o.COLOR_BUFFER_BIT),r.tint.length>0&&(o.useProgram(f.splatProgram),o.uniform4f(o.getUniformLocation(f.splatProgram,"u_viewport"),a.minX,a.minY,a.maxX,a.maxY),o.uniform1f(o.getUniformLocation(f.splatProgram,"u_time"),C(t.simulationTimeSeconds,0)),o.bindBuffer(o.ARRAY_BUFFER,f.splatBuffer),o.bufferData(o.ARRAY_BUFFER,r.tint,o.DYNAMIC_DRAW),qe(o,f.splatProgram),o.drawArrays(o.TRIANGLES,0,r.tint.length/$e)),o.disable(o.BLEND),o.bindFramebuffer(o.FRAMEBUFFER,null),o.viewport(0,0,s,c),o.useProgram(f.shadeProgram),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,f.fieldTexture),o.uniform1i(o.getUniformLocation(f.shadeProgram,"u_field"),0),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,f.tintTexture),o.uniform1i(o.getUniformLocation(f.shadeProgram,"u_tint"),1),o.uniform2f(o.getUniformLocation(f.shadeProgram,"u_resolution"),s,c),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_time"),C(n.simulationTimeSeconds,C(t.simulationTimeSeconds,0))),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_lineInterval"),C(t.lineInterval,C(t.scalarFieldLineInterval,C(t.depthRange,228.79605)/20))),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_lineOffset"),C(t.lineOffset,C(t.startDepth,2.310401))),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_lineWidth"),C(t.lineWidth,.3)),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_lineFade"),C(t.lineFade,5)),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_angleWidth"),C(t.angleWidth,.05)),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_angleFade"),C(t.angleFade,1.15)),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_dangerSteepness"),C(t.dangerSteepness,1.5)),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_scale"),C(t.isolineScale,2.6924083)),ae(o,f.shadeProgram,"u_baseColor",oe(t.scalarFieldBaseColor,[.002,.006,.012])),ae(o,f.shadeProgram,"u_fieldGlowColor",oe(t.scalarFieldGlowColor,[.018,.05,.075])),ae(o,f.shadeProgram,"u_lineLowColor",oe(t.scalarFieldLowLineColor,[0,.34,.52])),ae(o,f.shadeProgram,"u_lineHighColor",oe(t.scalarFieldHighLineColor,[1.45,.3,.05])),ae(o,f.shadeProgram,"u_angleLowColor",oe(t.scalarFieldLowAngleColor,[.06,.16,.24])),ae(o,f.shadeProgram,"u_angleHighColor",oe(t.scalarFieldHighAngleColor,[1.1,.24,.04])),o.uniform1f(o.getUniformLocation(f.shadeProgram,"u_tintScale"),C(t.vectorFieldTintScale,.45)),o.bindBuffer(o.ARRAY_BUFFER,f.quadBuffer);const d=o.getAttribLocation(f.shadeProgram,"a_position");return o.enableVertexAttribArray(d),o.vertexAttribPointer(d,2,o.FLOAT,!1,0,0),o.drawArrays(o.TRIANGLES,0,6),e.drawImage(f.canvas,0,0,s,c),!0}function wt(e,t,n,i,a){const s=[],c=[];return xt(s,e,t,n),_t(c,e,a),{gravity:new Float32Array(s),tint:new Float32Array(c)}}function xt(e,t,n,i,a){const s=C(n.terrainRadius,C(t.terrainRadius,1200)),c=C(n.terrainDepth,C(t.terrainDepth,-8));c!==0&&we(e,0,0,Math.max(1,s*2),Math.max(1,s*2),-c,0,0,1,Math.max(1e-4,C(n.terrainDepthExponent,C(t.terrainDepthExponent,1.2))),0,1,0,0);for(const l of i)we(e,l.x,l.y,Math.max(1,l.radius),Math.max(1,l.radius),-l.depth,0,0,1,Math.max(1e-4,l.exponent),0,1,0,0),l.waveRadius>0&&l.waveDepth!==0&&we(e,l.x,l.y,l.waveRadius,l.waveRadius,-l.waveDepth,0,0,1,8,4,C(n.terrainWaveFrequency,C(t.terrainWaveFrequency,.6)),l.waveSpeed,0)}function _t(e,t,n){const i=It(n?.splats),a=Array.isArray(n?.layers)?n.layers:[],s=new Set,c=Ct(t.vectorFieldLayer,t.tintFieldLayer,"fog.tint");a.forEach((k,re)=>{const pe=At(k?.layerKey,"");C(k?.channel,-1)===4&&pe===c&&s.add(re)});const l=Math.max(0,kt(i.count,0));if(l<=0||s.size===0)return;const f=D(i.centerX),o=D(i.centerY),r=D(i.halfExtentX),d=D(i.halfExtentY),u=D(i.rotationCos),h=D(i.rotationSin),g=D(i.channel),b=D(i.falloff),x=D(i.valueR),T=D(i.valueG),A=D(i.valueB),z=D(i.valueA),te=D(i.sourceKind),j=D(i.frequencyX),ne=D(i.animationSpeed),ie=D(i.sourceFlags),Y=D(i.layerIndex);for(let k=0;kNumber(i));if(n.length>=3&&n.slice(0,3).every(Number.isFinite))return[n[0],n[1],n[2]]}if(typeof e=="string"){const n=e.split(/[,\s]+/).map(i=>Number(i)).filter(Number.isFinite);if(n.length>=3)return[n[0],n[1],n[2]]}return t}function ae(e,t,n,i){e.uniform3f(e.getUniformLocation(t,n),i[0],i[1],i[2])}function D(e){return Array.isArray(e)?e.map(t=>C(t,0)):[]}function It(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function At(e,t){return e==null?t:String(e)}function Ct(...e){for(const t of e){if(typeof t=="string"&&t.trim())return t;if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function kt(e,t){const n=Number(e);return Number.isFinite(n)?Math.max(0,Math.floor(n)):t}const Tt=`#version 300 es -in vec2 a_corner; -in vec2 a_center; -in vec2 a_half; -in vec2 a_rot; -in vec4 a_meta; -in vec4 a_source; -in vec4 a_value; -uniform vec4 u_viewport; -out vec2 v_local; -out vec4 v_meta; -out vec4 v_source; -out vec4 v_value; -void main() { - vec2 scaled = a_corner * a_half; - vec2 world = a_center + vec2( - scaled.x * a_rot.x - scaled.y * a_rot.y, - scaled.x * a_rot.y + scaled.y * a_rot.x - ); - vec2 clip = vec2( - ((world.x - u_viewport.x) / max(0.0001, u_viewport.z - u_viewport.x)) * 2.0 - 1.0, - ((world.y - u_viewport.y) / max(0.0001, u_viewport.w - u_viewport.y)) * 2.0 - 1.0 - ); - gl_Position = vec4(clip, 0.0, 1.0); - v_local = a_corner; - v_meta = a_meta; - v_source = a_source; - v_value = a_value; -}`,Rt=`#version 300 es -precision highp float; -in vec2 v_local; -in vec4 v_meta; -in vec4 v_source; -in vec4 v_value; -uniform float u_time; -out vec4 outColor; -float hash21(vec2 p) { - p = fract(p * vec2(123.34, 456.21)); - p += dot(p, p + 45.32); - return fract(p.x * p.y); -} -float valueNoise(vec2 p) { - vec2 i = floor(p); - vec2 f = fract(p); - float a = hash21(i); - float b = hash21(i + vec2(1.0, 0.0)); - float c = hash21(i + vec2(0.0, 1.0)); - float d = hash21(i + vec2(1.0, 1.0)); - vec2 u = f * f * (3.0 - 2.0 * f); - return mix(mix(a, b, u.x), mix(c, d, u.x), u.y) * 2.0 - 1.0; -} -float powerPulse(float x, float power) { - x = clamp(abs(x), 0.0, 1.0); - return pow((x + 1.0) * (1.0 - x), max(0.0001, power)); -} -void main() { - float d = length(v_local); - if (d > 1.0) discard; - float alpha = powerPulse(d, v_meta.x); - if (alpha <= 0.0001) discard; - float source = 1.0; - if (v_source.x > 0.5 && v_source.x < 2.5) { - float timeOffset = v_source.x > 1.5 ? u_time * v_source.z : 0.0; - source = valueNoise(v_local * v_source.y + timeOffset); - if (v_source.w != 0.0) source = abs(source); - } else if (v_source.x > 3.5) { - source = cos(pow(d * 2.0, 1.25) * v_source.y + u_time * v_source.z); - } - outColor = v_value * alpha * source; -}`,Lt=`#version 300 es -in vec2 a_position; -out vec2 v_uv; -void main() { - v_uv = a_position * 0.5 + 0.5; - gl_Position = vec4(a_position, 0.0, 1.0); -}`,Ft=`#version 300 es -precision highp float; -uniform sampler2D u_field; -uniform sampler2D u_tint; -uniform vec2 u_resolution; -uniform float u_time; -uniform float u_lineInterval; -uniform float u_lineOffset; -uniform float u_lineWidth; -uniform float u_lineFade; -uniform float u_angleWidth; -uniform float u_angleFade; -uniform float u_dangerSteepness; -uniform float u_scale; -uniform vec3 u_baseColor; -uniform vec3 u_fieldGlowColor; -uniform vec3 u_lineLowColor; -uniform vec3 u_lineHighColor; -uniform vec3 u_angleLowColor; -uniform vec3 u_angleHighColor; -uniform float u_tintScale; -in vec2 v_uv; -out vec4 outColor; -vec2 calcGrad(vec2 uv, float me) { - vec2 texel = 1.0 / max(vec2(1.0), u_resolution); - float n = -texture(u_field, vec2(uv.x, uv.y + texel.y)).r; - float e = -texture(u_field, vec2(uv.x + texel.x, uv.y)).r; - return vec2(e - me, n - me); -} -void main() { - float height = -texture(u_field, v_uv).r; - vec4 tint = texture(u_tint, v_uv); - vec2 plan = calcGrad(v_uv, height); - float slope = max(length(plan), 0.00001); - vec3 color = u_baseColor; - float fieldGlow = smoothstep(0.0, u_lineInterval * 7.0, abs(height)); - color += u_fieldGlowColor * fieldGlow; - color += tint.rgb * clamp(tint.a, 0.0, 1.0) * u_tintScale; - - float dangerBlend = smoothstep(0.0, u_dangerSteepness, pow(slope / max(0.0001, u_scale), 2.0)); - vec3 baseLine = mix(u_lineLowColor, u_lineHighColor, dangerBlend); - vec3 angleLine = mix(u_angleLowColor, u_angleHighColor, dangerBlend) * clamp(slope / max(0.0001, u_scale), 0.0, 1.0); - - vec3 lines = vec3(0.0); - float interval = max(0.0001, abs(u_lineInterval)); - float nearestLine = abs(fract((height + u_lineOffset) / interval) - 0.5) * interval; - float lineDistance = nearestLine / slope; - float line = 1.0 - smoothstep(u_lineWidth, u_lineWidth * u_lineFade, lineDistance); - lines += line * baseLine; - - float angle = atan(plan.y, plan.x) / 3.1415926536 + 1.0; - float nearestAngle = abs(fract(angle * 6.0) - 0.5) / 6.0; - float angleMask = smoothstep(interval * 0.25, interval * 1.5, abs(height)); - float angleLineAmount = 1.0 - smoothstep(u_angleWidth, u_angleWidth * u_angleFade, nearestAngle); - lines += angleLineAmount * angleMask * angleLine; - - color += clamp(lines, 0.0, 1.7); - outColor = vec4(color, 1.0); -}`,at=new Set(["gamecult.fields.splats.v1","gamecult.fields.gravity.v1","gamecult.fields.objects.v1"]),Pt={pluginId:"fields.surface",capabilities:["field.surface2d","gravity.surface","field.scalar","field.vector","field.objects"],componentKinds:["field.surface2d","gravity.surface"],schemas:[...at],normalizeDocument:Ne,renderComponent:Mt};function Mt(e,t,n,i,a,s){const c=document.createElement("canvas");c.className="cultui-gravity-surface",e.id&&(c.id=e.id),c.setAttribute("role","img"),c.setAttribute("aria-label",on(t.label,"gravity surface")),c.style.display="block",c.style.width="100%",c.style.height="100%",c.style.pointerEvents="none",s.applyGeneratedLayout(c,n,i);let l=!1;const f={},o=()=>Dt(c,t,f,s.resolveAssetUrl),r=()=>{!c.isConnected||l||(l=!0,requestAnimationFrame(()=>{l=!1,c.isConnected&&o()}))};c.addEventListener("cultui:asset-loaded",r);let d=0,u;const h=()=>{d&&window.clearInterval(d),u?.disconnect(),c.removeEventListener("cultui:asset-loaded",r)},g=()=>{if(!c.isConnected){h();return}$t(e,t,a,s.providerId,f).then(x=>{x&&c.isConnected&&r()}).catch(x=>{f.lastError=x instanceof Error?x.message:String(x)})};typeof ResizeObserver<"u"&&(u=new ResizeObserver(r),u.observe(c)),r();const b=Math.max(33,Math.min(1e3,an(t.stateRefreshMs,100)));return d=window.setInterval(g,b),queueMicrotask(g),window.setTimeout(r,300),window.setTimeout(r,1e3),c}async function $t(e,t,n,i,a){if(a.loading)return!1;const s=[Le(e,t,"renderSplats","renderSplatsDocumentId","renderSplatsSchemaId"),Le(e,t,"gravity","gravityDocumentId","gravitySchemaId"),Le(e,t,"objects","objectsDocumentId","objectsSchemaId")].filter(c=>!!c?.documentId);if(s.length===0)return!1;a.loading=!0;try{let c=!1;for(const l of s){const f=await n.documentResolver?.(l,e);let o=Se(Ne(f?.schemaId||l.schemaId,f?.document));if(Object.keys(o).length===0&&(o=Se(Ne(l.schemaId,await Nt(l,i||n.provider?.providerId)))),Object.keys(o).length===0)continue;const r=l.slotId==="renderSplats"?"renderSplats":l.slotId==="gravity"?"gravity":"objects",d=Be(a[r]?.frameId,-1),u=Be(o.frameId,d);a[r]=o,c||=u!==d}return a.lastLoadedAt=Date.now(),c}finally{a.loading=!1}}async function Nt(e,t){if(typeof fetch!="function"||typeof window>"u"||!t)return;const n=new URLSearchParams({documentId:e.documentId});e.schemaId&&n.set("schemaId",e.schemaId),e.slotId&&n.set("slotId",e.slotId);const i=await fetch(`/eir/document/${encodeURIComponent(t)}?${n.toString()}`,{cache:"no-store",headers:{Accept:"application/json"}});if(i.ok)return Se(await i.json()).document}function Le(e,t,n,i,a){const s=(e.embeddedDocuments||[]).find(l=>String(l?.slotId||"")===n),c=L(t[i],s?.documentId);if(c)return{documentId:c,schemaId:L(t[a],s?.schemaId),presentationKind:L(s?.presentationKind)||"data",slotId:n}}function Ne(e,t){const n=Array.isArray(t)?t:void 0,i=n?n[0]:t?.schema,a=String(e||i||"");return!n||!at.has(a)?t:a==="gamecult.fields.splats.v1"?qt(n):a==="gamecult.fields.gravity.v1"?Vt(n):Zt(n)}function Dt(e,t,n,i){const a=e.getBoundingClientRect(),s=Math.max(1,Math.floor(a.width||e.clientWidth||1)),c=Math.max(1,Math.floor(a.height||e.clientHeight||1)),l=Math.max(1,Math.min(2,window.devicePixelRatio||1)),f=Math.max(1,Math.floor(s*l)),o=Math.max(1,Math.floor(c*l));(e.width!==f||e.height!==o)&&(e.width=f,e.height=o);const r=e.getContext("2d");if(!r)return;r.setTransform(l,0,0,l,0,0),r.clearRect(0,0,s,c);const d=Ht(Yt(t),s,c),u=lt(n?.gravity),h=Xt(n?.gravity)||Kt(L(t.bodies,"")),g=jt(n?.objects)||Ot(L(t.objects,""));bt(r,t,u,h,d,s,c,n?.renderSplats)||Bt(r,t,s,c,"field.surface2d requires WebGL2 float render targets"),Ut(r,h,t,d,s,c,i),Wt(r,g,t,d,s,c,i)}function Bt(e,t,n,i,a){e.save(),e.fillStyle=L(t.failureBackground,"rgba(0, 0, 0, 0.72)"),e.fillRect(0,0,n,i),e.font=L(t.failureFont,"700 13px Cascadia Mono, Consolas, monospace"),e.fillStyle=L(t.failureColor,"rgba(255, 184, 79, 0.95)"),e.fillText(a,16,28),e.restore()}function Ut(e,t,n,i,a,s,c){for(const l of t){const f=ct(i,l.x,l.y,a,s),o=Math.max(18,Math.min(190,l.radius/Math.max(1,i.maxX-i.minX)*a*.32)),r=c(l.icon),d=l.kind.toLowerCase().includes("sun")?Math.max(I(n.sunIconMinPx,34),o*I(n.sunIconScale,.72)):Math.max(I(n.bodyIconMinPx,24),o*I(n.bodyIconScale,.48)),u=l.iconSize>0?l.iconSize:d;r&&zt(e,r,f.x,f.y,u,.92),l.key&&st(e,n,l.key.replace(/^local\./,""),f.x+o*.44,f.y-o*.48,L(n.bodyLabelColor,"rgba(226, 244, 255, 0.82)"))}}const _e=new Map;function zt(e,t,n,i,a,s){let c=_e.get(t);c||(c=new Image,c.decoding="async",c.onload=()=>requestAnimationFrame(()=>{e.canvas.dispatchEvent(new CustomEvent("cultui:asset-loaded"))}),c.src=t,_e.set(t,c)),!(!c.complete||c.naturalWidth===0)&&(e.save(),e.globalAlpha=s,e.drawImage(c,n-a/2,i-a/2,a,a),e.restore())}function Wt(e,t,n,i,a,s,c){for(const l of t){const f=ct(i,l.x,l.y,a,s);if(f.x<-40||f.x>a+40||f.y<-40||f.y>s+40)continue;const o=l.kind.toLowerCase().includes("station")?I(n.stationIconSizePx,34):l.controlled?I(n.shipIconSizePx,22):I(n.remoteShipIconSizePx,18),r=Gt(n,l.faction,l.controlled,l.visibility),d=c(l.icon);e.save(),e.globalAlpha=Math.max(.25,Math.min(1,l.visibility)),e.translate(f.x,f.y);const u=Math.atan2(l.directionY,l.directionX)+Math.PI/2;if(l.kind.toLowerCase().includes("ship")&&e.rotate(u),d){const h=_e.get(d);if(h)h.complete&&h.naturalWidth>0&&e.drawImage(h,-o/2,-o/2,o,o);else{const g=new Image;g.decoding="async",g.onload=()=>e.canvas.dispatchEvent(new CustomEvent("cultui:asset-loaded")),g.src=d,_e.set(d,g)}}e.restore(),st(e,n,l.label,f.x+o*.55,f.y-o*.45,r)}}function st(e,t,n,i,a,s){n&&(e.save(),e.font=L(t.objectLabelFont,"700 12px Ubuntu, system-ui, sans-serif"),e.textBaseline="middle",e.lineWidth=I(t.objectLabelStrokeWidth,3),e.strokeStyle=L(t.objectLabelStroke,"rgba(0, 0, 0, 0.72)"),e.fillStyle=s,e.strokeText(n,i,a),e.fillText(n,i,a),e.restore())}function Gt(e,t,n,i){const a=Math.max(.25,Math.min(1,i));if(n)return he(L(e.objectControlledColor,"rgba(122, 240, 255, {alpha})"),a);const s=t.toLowerCase();return s.includes("raider")?he(L(e.objectRaiderColor,"rgba(255, 143, 74, {alpha})"),a):s.includes("neutral")?he(L(e.objectNeutralColor,"rgba(232, 232, 224, {alpha})"),a):he(L(e.objectDefaultColor,"rgba(214, 244, 255, {alpha})"),a)}function he(e,t){return e.replaceAll("{alpha}",String(t))}function Kt(e){return e.split(";").map(t=>t.trim()).filter(Boolean).map(t=>{const n=t.split("|");return{key:n[0]??"",kind:n[1]??"",x:Number(n[2])||0,y:Number(n[3])||0,radius:Math.max(1,Number(n[4])||1),depth:Number(n[5])||0,exponent:Number(n[6])||1,waveRadius:Number(n[7])||0,waveDepth:Number(n[8])||0,waveSpeed:Number(n[9])||0,icon:n[10]??"",iconSize:Number(n[12])||0,tint:n[11]??""}})}function Ot(e){return e.split(";").map(t=>t.trim()).filter(Boolean).map(t=>{const n=t.split("|");return{key:n[0]??"",kind:n[1]??"",label:n[2]??"",x:Number(n[3])||0,y:Number(n[4])||0,directionX:Number(n[5])||0,directionY:Number(n[6])||1,faction:n[7]??"",controlled:n[8]==="1"||n[8]==="true",visibility:Number(n[9])||1,icon:n[10]??""}})}function Xt(e){const t=Array.isArray(e?.gravityInfluences)?e.gravityInfluences:[],n=Array.isArray(e?.bodies)?e.bodies:[];if(t.length===0&&n.length===0)return;const i=new Map;for(const a of n){const s=L(a.bodyKey,a.name,"");s&&i.set(s,a)}return(t.length>0?t:n).map(a=>{const s=L(a.bodyKey,a.name,"body"),c=i.get(s),l=L(a.kind,"Body");return{key:s,kind:l,x:I(a.x,0),y:I(a.y,0),radius:Math.max(1,I(a.radius,80)),depth:I(a.gravityDepth,0),exponent:I(a.gravityDepthExponent,1),waveRadius:I(a.waveRadius,0),waveDepth:I(a.waveDepth,0),waveSpeed:I(a.waveSpeed,0),icon:De(a.iconAsset)||De(c?.iconAsset),iconSize:I(c?.iconSize,I(a.iconSize,0)),tint:""}})}function jt(e){const t=Array.isArray(e?.objects)?e.objects:[];if(t.length!==0)return t.map(n=>{const i=L(n.kind,"object");return{key:L(n.entityKey,String(n.entityIndex??""),"object"),kind:i,label:L(n.displayName,n.entityKey,"object"),x:I(n.x,0),y:I(n.y,0),directionX:I(n.directionX,1),directionY:I(n.directionY,0),faction:L(n.factionKey,""),controlled:sn(n.controlled),visibility:I(n.visibility,1),icon:De(n.iconAsset)}})}function De(e){const t=lt(e);return L(t.uri,"")}function Yt(e){const t=Math.max(1,I(e.viewRadius,Math.max(1200,I(e.terrainRadius,1200))));return{minX:I(e.minX,-t),minY:I(e.minY,-t),maxX:I(e.maxX,t),maxY:I(e.maxY,t)}}function Ht(e,t,n){const i=Math.max(1e-4,e.maxX-e.minX),a=Math.max(1e-4,e.maxY-e.minY),s=Math.max(1e-4,t/Math.max(1,n)),c=i/a,l=(e.minX+e.maxX)*.5,f=(e.minY+e.maxY)*.5;if(s>c){const r=a*s;return{minX:l-r*.5,maxX:l+r*.5,minY:e.minY,maxY:e.maxY}}const o=i/s;return{minX:e.minX,maxX:e.maxX,minY:f-o*.5,maxY:f+o*.5}}function ct(e,t,n,i,a){return{x:(t-e.minX)/Math.max(1,e.maxX-e.minX)*i,y:(n-e.minY)/Math.max(1,e.maxY-e.minY)*a}}function qt(e){const t=U(e[9]);return{schema:e[0],frameId:e[1],publishedAtUtc:e[2],simulationTimeSeconds:e[3],runId:e[4],zoneIndex:e[5],zoneName:e[6],viewport:ze(e[7]),layers:U(e[8]).map(Jt),splats:{count:t[0]??0,centerX:t[1]||[],centerY:t[2]||[],halfExtentX:t[3]||[],halfExtentY:t[4]||[],rotationCos:t[5]||[],rotationSin:t[6]||[],channel:t[7]||[],falloff:t[8]||[],valueR:t[9]||[],valueG:t[10]||[],valueB:t[11]||[],valueA:t[12]||[],sourceKey:t[13]||[],layerIndex:t[14]||[],sourceKind:t[15]||[],frequencyX:t[16]||[],frequencyY:t[17]||[],phaseX:t[18]||[],phaseY:t[19]||[],animationSpeed:t[20]||[],sourceFlags:t[21]||[]}}}function Vt(e){return{schema:e[0],frameId:e[1],publishedAtUtc:e[2],simulationTimeSeconds:e[3],runId:e[4],zoneIndex:e[5],zoneName:e[6],viewport:ze(e[7]),gravityInfluences:U(e[8]).map(Qt),bodies:U(e[9]).map(en),terrainRadius:e[10],terrainDepth:e[11],terrainDepthExponent:e[12],terrainWaveFrequency:e[13]}}function Zt(e){return{schema:e[0],frameId:e[1],publishedAtUtc:e[2],simulationTimeSeconds:e[3],runId:e[4],zoneIndex:e[5],zoneName:e[6],currentEntityKey:e[7],viewport:ze(e[8]),controlledEntityIndices:U(e[9]),objects:U(e[10]).map(tn)}}function ze(e){const t=U(e);return t.length?{minX:t[0],minY:t[1],maxX:t[2],maxY:t[3]}:e}function Jt(e){const t=U(e);return t.length?{layerKey:t[0],displayName:t[1],channel:t[2],blendMode:t[3],graphicsFormat:t[4],clearBeforeDraw:t[5],clearR:t[6],clearG:t[7],clearB:t[8],clearA:t[9]}:e}function Qt(e){const t=U(e);return t.length?{bodyKey:t[0],orbitKey:t[1],kind:t[2],x:t[3],y:t[4],radius:t[5],gravityDepth:t[6],gravityDepthExponent:t[7],waveRadius:t[8],waveDepth:t[9],waveSpeed:t[10]}:e}function en(e){const t=U(e);return t.length?{bodyKey:t[0],orbitKey:t[1],name:t[2],kind:t[3],x:t[4],y:t[5],radius:t[6],isAsteroidBelt:t[7],body:t[8],iconAsset:We(t[9])}:e}function tn(e){const t=U(e);return t.length?{entityIndex:t[0],entityKey:t[1],displayName:t[2],kind:t[3],factionKey:t[4],x:t[5],y:t[6],z:t[7],directionX:t[8],directionY:t[9],velocityX:t[10],velocityY:t[11],controlled:t[12],targetEntityIndex:t[13],isActive:t[14],visibility:t[15],status:nn(t[16]),inventory:U(t[17]).map(rn),iconAsset:We(t[18])}:e}function nn(e){const t=U(e);return t.length?{hull:t[0],shield:t[1],heat:t[2]}:e||{}}function rn(e){const t=U(e);return t.length?{source:t[0],itemKey:t[1],quantity:t[2],quality:t[3],durability:t[4],enabled:t[5],sourceIndex:t[6],x:t[7],y:t[8],iconAsset:We(t[9])}:e}function We(e){const t=U(e);return t.length?{assetKey:t[0],kind:t[1],uri:t[2],transport:t[3],contentHash:t[4],mimeType:t[5],metadata:t[6]||{}}:e||{}}function U(e){return Array.isArray(e)?e:[]}function Se(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function L(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function on(e,t){return typeof e=="string"&&e?e:t}function an(e,t){const n=Number(e);return Number.isFinite(n)&&n>0?Math.floor(n):t}function Be(e,t){const n=Number(e);return Number.isFinite(n)?n:t}const lt=Se,I=Be;function sn(e){return typeof e=="boolean"?e:typeof e=="number"?e!==0:typeof e=="string"&&["1","true","yes","on"].includes(e.trim().toLowerCase())}const cn=[Pt],ln={"--bg":"#020909","--bg-top":"#020909","--bg-mid":"#020909","--bg-bottom":"#020909","--shell-top":"#010707","--shell-bottom":"#010707","--panel":"#071918","--panel-2":"#0a2423","--line":"rgba(103, 240, 228, 0.28)","--line-deep":"rgba(103, 240, 228, 0.18)","--text":"#e7f1f1","--text-bright":"#e7f1f1","--quiet":"#8ba5a3","--accent":"#ffb84f","--accent-strong":"#ffb84f","--corner-accent":"#ffb84f","--cyan":"#8efcff","--shadow":"rgba(0, 0, 0, 0.35)","--pixel-grid":"rgba(142, 252, 255, 0.04)","--border-width":"1px","--border-bottom-width":"1px","--corner-accent-size":"0","--font-body":'"M PLUS 1", "Ubuntu Sans", Ubuntu, "Noto Sans JP", system-ui, sans-serif',"--font-title":'"Montserrat", "Zen Kaku Gothic New", "M PLUS 1", "Ubuntu Sans", system-ui, sans-serif',"--font-mono":'"Ubuntu Sans Mono", "M PLUS 1 Code", "Cascadia Mono", Consolas, monospace'};let ge,dt=Ge(void 0),de,X={};const Je=new WeakMap;function dn(e,t,n={}){if(Je.get(t)?.dispose(),de=e,X=n,dt=Ge(e.surface?.styles),globalThis.__eveCurrentMesh=e.mesh,kn(e.surface?.styles,n.body??document.body),n.body&&(n.body.dataset.provider=e.providerId||n.provider?.providerId||""),n.statusElement&&(n.statusElement.textContent=`${e.title||e.surface?.title||"surface"}${n.source?` (${n.source})`:""}`),e.surface?.root){if(t.replaceChildren(N(e.surface.root,n)),n.stateBindingResolver){const i=new fn(e,t,n);Je.set(t,i),i.start()}}else t.replaceChildren(Q("No surface root"));return t}function un(e,t,n){const i=t.targetProp.split(".").filter(Boolean);if(i.length===0)throw new Error("Eve state binding targetProp must not be empty.");e.props||={};let a=e.props;for(const s of i.slice(0,-1)){const c=a[s];(!c||typeof c!="object"||Array.isArray(c))&&(a[s]={}),a=a[s]}a[i[i.length-1]]=n}class fn{surface;host;options;disposed=!1;unsubscribers=[];constructor(t,n,i){this.surface=t,this.host=n,this.options=i}async start(){const t=this.options.stateBindingResolver,n=this.surface.surface?.root;if(!(!t||!n))for(const i of ut(n))for(const a of i.stateBindings||[]){if(this.disposed)return;const s=await t(a,i);if(!s||this.disposed)continue;const c=l=>{this.disposed||(un(i,a,l),this.renderCanonicalProjection())};if(c(await s.latest()),this.disposed)return;this.unsubscribers.push(s.watch(c))}}dispose(){this.disposed=!0;for(const t of this.unsubscribers.splice(0))t()}renderCanonicalProjection(){const t=this.surface.surface?.root;t&&this.host.replaceChildren(N(t,this.options))}}function*ut(e){yield e;for(const t of e.children||[])yield*ut(t)}function N(e,t=X){const n=e.kind||"panel",i=_(e.props),a=_(e.layout),s=_(e.style),c=e.children||[],l=e.embeddedDocuments||[];if(n==="surface"||n==="cockpit"||n==="dashboard"){const r=m("section","cultui-surface-root eve-surface");S(r,e),typeof a.direction=="string"?r.dataset.direction=a.direction:typeof i.layout=="object"&&i.layout&&typeof i.layout.direction=="string"&&(r.dataset.direction=String(i.layout.direction)),n!=="surface"&&(r.dataset.surfaceKind=n),E(r,a,s);for(const d of c)r.append(N(d,t));return r}if(n==="column"||n==="row"||n==="form"||n==="rail"){const r=m("div",`cultui-partition eve-${n}`);S(r,e),r.dataset.direction=n==="row"||n==="rail"?"horizontal":"vertical",n==="rail"&&(r.dataset.overflow="x"),ye(r,{...a,...i}),E(r,a,s);for(const d of c)r.append(N(d,t));return r}if(n==="grid"){const r=m("section","cultui-grid"),d=G(i.columns,0);d>0?r.style.gridTemplateColumns=`repeat(${d}, minmax(0, 1fr))`:typeof i.columns=="string"&&(r.style.gridTemplateColumns=i.columns);const u=G(i.rows,0);u>0&&(r.style.gridTemplateRows=`repeat(${u}, minmax(0, auto))`),E(r,a,s);for(const h of c)r.append(N(h,t));return r}if(n==="partition"){const r=m("section",`cultui-partition split-${v(i.split,"none")}`);S(r,e),ye(r,i),E(r,a,s),r.style.minWidth="0",v(i.split,"none")==="x"&&!p(i.flexWrap,a.flexWrap,"")&&(r.style.flexWrap="wrap"),typeof i.role=="string"&&(r.dataset.role=i.role);for(const d of c)r.append(N(d,t));return r}if(n==="input.binding-map")return En(e,i,t);if(n==="inventory.drag_session")return bn(e,i,a,s);if(n==="inventory.grid")return wn(e,i,a,s,t);if(n==="inventory.item")return xn(e,i,a,s);const f=(t.pluginAdapters||cn).find(r=>r.componentKinds.includes(n));if(f?.renderComponent)return f.renderComponent(e,i,a,s,t,{applyGeneratedLayout:E,providerId:de?.providerId||t.provider?.providerId,resolveAssetUrl:le});if(n==="world.scene3d"||n==="world.scene2d")return pn(e,i,a,s,t);if(n==="image.background"){const r=m("div","cultui-background"),d=le(p(i.src,i.assetUri,i.assetRef,""));return d&&(r.style.backgroundImage=`url("${d}")`),r.setAttribute("aria-label",v(i.label,"background")),r}if(n==="image.sprite"){const r=m("figure",`cultui-sprite ${v(i.slot,"center")}`);S(r,e);const d=le(p(i.src,i.assetUri,i.assetRef,""));if(d){const u=m("img");u.src=d,u.alt=v(i.alt,v(i.actor,v(i.label,""))),r.append(u)}return r}if(n==="avatar"){const r=m("figure","cultui-avatar-card");S(r,e);const d=le(p(i.src,i.assetUri,i.assetRef,""));if(d){const b=m("img");b.src=d,b.alt=v(i.alt,v(i.text,v(i.label,""))),r.append(b)}else r.append(m("div","cultui-avatar-fallback",zn(p(i.text,i.label,i.actor,"?"))));const u=p(i.text,i.label,i.actor,"");u&&r.append(m("figcaption","cultui-avatar-name",u));const h=p(i.status,"");h&&r.append(m("div","cultui-avatar-status",h));const g=p(i.detail,"");return g&&r.append(m("div","cultui-avatar-detail",g)),r}if(n==="pane"||n==="panel"){const r=m("section","pane cultui-pane");S(r,e);const d=v(i.span,"");d&&(r.dataset.span=d);const u=v(i.density,"");u&&(r.dataset.density=u);const h=v(i.title,e.text||"");h&&r.append(m("h2","",h));for(const g of c)r.append(N(g,t));return r}if(n==="list"||n.endsWith(".roster")){const r=m("section","cultui-list");S(r,e),r.dataset.componentKind=n;const d=v(i.title,"");d&&r.append(m("h3","cultui-list-title",d));for(const[u,h]of Bn(i.items).entries())r.append(N({id:`${e.id||"list"}-item-${u}`,kind:"list.item",props:{...h}},t));for(const u of c)r.append(N(u,t));return r}if(n==="list.item"||n.endsWith(".item")){const r=ft(e),d=m("article","cultui-list-item");S(d,e),d.dataset.componentKind=n;const u=m("div","cultui-list-item-heading");if(u.append(m("strong","cultui-list-item-label",r.label)),r.status&&u.append(m("span","cultui-list-item-status",r.status)),d.append(u),r.detail&&d.append(m("div","cultui-list-item-detail",r.detail)),r.badges.length){const h=m("div","cultui-list-item-badges");for(const g of r.badges)h.append(m("span","cultui-list-item-badge",g));d.append(h)}for(const h of c)d.append(N(h,t));return d}if(n==="bar"){const r=m("div","cultui-meter");S(r,e);const d=v(i.label,""),u=v(i.value,"");if(d||u){const b=m("div","cultui-meter-head");b.append(m("span","",d)),b.append(m("strong","",u)),r.append(b)}const h=m("div","cultui-meter-track"),g=m("span","cultui-meter-fill");return g.style.width=`${rt(i.percent)}%`,h.append(g),r.append(h),r}if(n==="card"){const r=nt(i,e),d=r?m("button","card cultui-card cultui-card-button"):m("article","card cultui-card");S(d,e),E(d,a,s),d instanceof HTMLButtonElement&&(d.type="button");const u=v(i.title,e.text||"");u&&d.append(m("div","card-title",u));for(const h of c)d.append(N(h,t));return r&&it(d,e,r,i,t),d}if(n==="control.button"){const r=m("button","cultui-button eve-control-button",v(i.label,"Action"));return S(r,e),r.type="button",E(r,a,s),it(r,e,nt(i,e),i,t),r}if(n==="control.popup"){const r=m("button","cultui-button eve-control-popup",v(i.label,"Open"));return S(r,e),r.type="button",E(r,a,s),r.addEventListener("click",d=>{In(e,t,r,d.clientX,d.clientY)}),r}if(n==="text.dialogue"||n==="text"||n==="text.title"||n==="text.subtitle"||n==="label"){const r=m("div",Pn(n,i),v(i.value,v(i.text,e.text||"")));return S(r,e),ye(r,i),E(r,a,s),r}if(n==="metric"){const r=m("dl","metric cultui-reactive-metric eve-metric");return S(r,e),E(r,a,s),r.append(m("dt","",v(i.label,"Metric"))),r.append(m("dd","metric-value",v(i.value,""))),r}if(n==="progress"){const r=m("div","cultui-meter eve-progress");S(r,e),E(r,a,s);const d=v(i.label,""),u=v(i.value,""),h=Number(i.min??0),g=Number(i.max??1),b=Number(i.value??0),x=Number.isFinite(b)&&Number.isFinite(h)&&Number.isFinite(g)&&g!==h?(b-h)/(g-h)*100:rt(i.percent);if(d||u){const z=m("div","cultui-meter-head");z.append(m("span","",d)),z.append(m("strong","",u)),r.append(z)}const T=m("div","cultui-meter-track"),A=m("span","cultui-meter-fill");return A.style.width=`${Math.max(0,Math.min(100,x))}%`,T.append(A),r.append(T),r}if(n==="modal"){const r=m("section","cultui-modal-surface");S(r,e),E(r,a,s);const d=v(i.title,"");d&&r.append(m("h2","cultui-modal-surface-title",d));for(const u of c)r.append(N(u,t));return r}if(n==="options"){const r=m("section","cultui-options");S(r,e),E(r,a,s);const d=v(i.label,"");d&&r.append(m("h3","cultui-list-title",d));for(const u of c)r.append(N(u,t));return c.length===0&&r.append(Q("waiting for options")),r}if(n==="image.preview"){const r=m("figure","cultui-image-preview");S(r,e);const d=m("div","cultui-image-frame"),u=le(p(i.src,i.assetUri,i.assetRef,""));if(u){const h=m("img");h.src=u,h.alt=v(i.label,""),h.style.imageRendering=v(i.imageRendering,"auto"),i.zoom!==void 0&&(h.style.transform=`scale(${i.zoom})`,h.style.transformOrigin=v(i.crop,"50% 50%")),d.append(h)}else d.append(m("span","",v(i.label,"image")));return r.append(d),i.label&&r.append(m("figcaption","",String(i.label))),r}if(n==="canvas.preview"||n==="canvas.editor"){const r=m("div",`cultui-canvas-placeholder ${n==="canvas.editor"?"editor":"preview"}`);return S(r,e),r.append(m("div","viz-label",v(i.label,"Canvas"))),r.append(m("div","cultui-canvas-grid",i.state==="empty"?"waiting for pixels":v(i.state,""))),r}if(n==="surface.slot"){const r=m("section","cultui-embedded-slot");S(r,e),E(r,a,s),r.dataset.slotId=v(i.slotId,v(l[0]?.slotId,"")),r.dataset.documentId=v(i.documentId,v(l[0]?.documentId,"")),r.dataset.schemaId=v(i.schemaId,v(l[0]?.schemaId,"")),r.dataset.presentationKind=v(i.presentationKind,v(l[0]?.presentationKind,""));const d=l.map(h=>_(h.surface)).find(h=>_(h.root).kind||h.root),u=i.modal===!0||r.dataset.presentationKind.includes("modal");if((d||r.dataset.documentId)&&u){const h=m("button","cultui-button cultui-modal-trigger",v(i.label,r.dataset.slotId||"Configure"));h.type="button",h.addEventListener("click",()=>ht(Ue(e,t),t)),r.append(h)}else if(d||r.dataset.documentId){const h=m("div","cultui-embedded-slot-body");h.append(m("div","detail","materializing surface")),r.append(h),Ue(e,t).then(g=>{h.replaceChildren(g?.root?N(g.root,t):Q("Embedded surface unavailable"))}).catch(g=>{h.replaceChildren(Q(`Embedded surface failed: ${g instanceof Error?g.message:String(g)}`))})}else r.append(m("div","detail",r.dataset.presentationKind||r.dataset.slotId||"embedded surface"));return r}if(n==="control.slider")return Rn(i,c,t);if(n==="control.toggle"){const r=m("label","toggle-row cultui-toggle");return S(r,e),r.append(m("span","field-control",i.value?"on":"off")),r.append(m("span","toggle-copy",v(i.label,"Toggle"))),r}if(n==="input.number"||n==="input.select"||n==="control.range"||n==="control.input.text"||n==="control.select"){const r=m("label","field cultui-field");return S(r,e),ye(r,i),E(r,a,s),r.append(m("span","field-label",v(i.label,""))),r.append(m("span","field-control cultui-field-value",i.value===void 0?"":String(i.value))),r}if(n==="color.swatch"){const r=m("div","paint-swatch cultui-swatch");return S(r,e),r.style.background=v(i.value,v(i.color,"currentColor")),r.title=v(i.label,"Color"),r}const o=m("section","pane");S(o,e),o.append(m("h2","",n));for(const r of c)o.append(N(r,t));return o}function ft(e){const t=_(e.props);return{label:p(t.label,t.title,t.displayName,e.text,e.kind,"item"),status:p(t.status,t.state,""),detail:p(t.detail,t.phase,t.repoName,""),badges:Array.isArray(t.badges)?t.badges.map(n=>String(n).trim()).filter(Boolean):p(t.badges,"").split(",").map(n=>n.trim()).filter(Boolean)}}function E(e,t,n={}){const i=p(t.display,"");i&&(e.style.display=i);const a=p(t.direction,"");a&&(e.style.flexDirection=a==="horizontal"?"row":a==="vertical"?"column":a);const s=p(t.flexWrap,"");s&&(e.style.flexWrap=s);const c=p(t.gridTemplateColumns,"");c&&(e.style.gridTemplateColumns=c);const l=p(t.gridTemplateRows,"");l&&(e.style.gridTemplateRows=l);const f=p(t.gridTemplateAreas,"");f&&(e.style.gridTemplateAreas=f);const o=p(t.gridArea,"");o&&(e.style.gridArea=o);const r=p(t.placeItems,"");r&&(e.style.placeItems=r),B(e,"gap",p(t.gap,"")),B(e,"padding",p(t.padding,"")),B(e,"margin",p(t.margin,"")),B(e,"top",p(t.top,"")),B(e,"right",p(t.right,"")),B(e,"bottom",p(t.bottom,"")),B(e,"left",p(t.left,"")),B(e,"width",p(t.width,"")),B(e,"minWidth",p(t.minWidth,"")),B(e,"maxWidth",p(t.maxWidth,"")),B(e,"height",p(t.height,"")),B(e,"minHeight",p(t.minHeight,"")),B(e,"maxHeight",p(t.maxHeight,""));const d=p(t.alignItems,"");d&&(e.style.alignItems=d);const u=p(t.justifyContent,"");u&&(e.style.justifyContent=u);const h=p(t.alignSelf,"");h&&(e.style.alignSelf=h);const g=p(t.overflow,"");g&&(e.style.overflow=g);const b=p(t.overflowX,"");b&&(e.style.overflowX=b);const x=p(t.overflowY,"");x&&(e.style.overflowY=x);const T=p(t.position,"");T&&(e.style.position=T);const A=p(t.cursor,"");A&&(e.style.cursor=A);const z=p(n.background,"");z&&(e.style.background=xe(z));const te=p(n.color,"");te&&(e.style.color=xe(te)),B(e,"borderWidth",p(n.borderWidth,""));const j=p(n.borderColor,"");j&&(e.style.borderColor=xe(j));const ne=p(n.borderStyle,"");ne&&(e.style.borderStyle=ne),B(e,"borderRadius",p(n.borderRadius,""));const ie=p(n.boxShadow,"");ie&&(e.style.boxShadow=ie);const Y=p(n.font,"");Y&&(e.style.font=Y),B(e,"fontSize",p(n.fontSize,""));const k=p(n.fontWeight,"");k&&(e.style.fontWeight=k);const re=p(n.textTransform,"");re&&(e.style.textTransform=re);const pe=p(n.textAlign,"");pe&&(e.style.textAlign=pe);const Re=p(n.whiteSpace,"");Re&&(e.style.whiteSpace=Re);const je=p(n.overflow,"");je&&(e.style.overflow=je);const Ye=p(n.textOverflow,"");Ye&&(e.style.textOverflow=Ye),B(e,"lineHeight",p(n.lineHeight,""))}function B(e,t,n){n&&(e.style[t]=F(n))}function M(e,t){const n={};for(const[i,a]of Object.entries(e))i.startsWith(t)&&(n[i.slice(t.length)]=a);return n}function mn(e){const t=(e.children||[]).filter(u=>u.kind==="world.entity3d"),n=t.map(u=>yn(_(u.props).position,[0,0,0])),i=n.map(u=>u[0]),a=n.map(u=>u[2]),s=Math.min(...i,-1),c=Math.max(...i,1),l=Math.min(...a,-1),f=Math.max(...a,1),o=Math.max(1,c-s),r=Math.max(1,f-l),d=6;return t.map((u,h)=>{const g=_(u.props);return{entityId:p(g.entityId,u.id),faction:v(g.faction,"neutral"),kind:v(g.entityKind,"entity"),label:p(g.label,g.entityId,u.id,"Entity"),controlled:Ke(g.controllable),xPercent:d+(n[h][0]-s)/o*(100-d*2),yPercent:d+(1-(n[h][2]-l)/r)*(100-d*2),source:u}})}function pn(e,t,n,i,a){const s=m("section","cultui-world-scene");S(s,e),E(s,n,i),s.tabIndex=0,s.setAttribute("aria-label",v(t.label,"Interactive world"));const c=mn(e),l=c.find(r=>r.controlled),f=m("div","cultui-world-heading");f.append(m("strong","",v(t.label,"World"))),f.append(m("span","",`${c.length} entities`)),s.append(f);const o=m("div","cultui-world-plane");for(const r of c){const d=m("button",`cultui-world-entity faction-${Qe(r.faction)} kind-${Qe(r.kind)}`);d.type="button",d.style.left=`${r.xPercent}%`,d.style.top=`${r.yPercent}%`,d.dataset.entityId=r.entityId,d.dataset.controlled=r.controlled?"true":"false",d.title=r.label,d.setAttribute("aria-label",`${r.label}, ${r.kind}, ${r.faction}`),d.append(m("span","cultui-world-entity-glyph",vn(r.kind))),d.append(m("span","cultui-world-entity-label",r.label));const u=_(r.source.props),h=p(u.targetCommand,t.targetCommand,u.focusCommand,t.focusCommand);h&&d.addEventListener("click",()=>Fe(h,{actorEntityId:l?.entityId||p(t.playerEntityId),entityId:r.entityId,targetEntityId:r.entityId,targetEntityKey:r.entityId},r.source,a)),o.append(d)}return s.append(o),s.addEventListener("keydown",r=>{const d=gn(r.key);if(d){r.preventDefault();const h=p(t.movementCommand,_(l?.source.props).moveCommand);h&&Fe(h,{actorEntityId:l?.entityId||p(t.playerEntityId),actorEntityKey:l?.entityId||p(t.playerEntityId),directionX:d[0],directionY:d[1],scalar:1},e,a);return}const u=r.key===" "?p(t.actionCommand,_(l?.source.props).actionCommand):r.key.toLowerCase()==="f"?p(t.focusCommand,_(l?.source.props).focusCommand):"";u&&(r.preventDefault(),Fe(u,{actionId:r.key===" "?"0":"focus",actorEntityId:l?.entityId||p(t.playerEntityId),actorEntityKey:l?.entityId||p(t.playerEntityId)},e,a))}),s}function Fe(e,t,n,i){i.commandSink?.(hn(e,t,i),n)}function hn(e,t,n=X){return me(e,{action:t},n)}function gn(e){switch(e.toLowerCase()){case"w":case"arrowup":return[0,1];case"s":case"arrowdown":return[0,-1];case"a":case"arrowleft":return[-1,0];case"d":case"arrowright":return[1,0];default:return}}function vn(e){return e.includes("station")?"S":e.includes("projectile")?".":e.includes("ship")?"^":"+"}function Qe(e){return e.toLowerCase().replace(/[^a-z0-9_-]+/g,"-")}function V(e,t){const n=Number(e);return Number.isFinite(n)?n:t}function yn(e,t){if(Array.isArray(e)){const n=e.map(i=>Number(i));if(n.length>=3&&n.slice(0,3).every(Number.isFinite))return[n[0],n[1],n[2]]}if(typeof e=="string"){const n=e.split(/[,\s]+/).map(i=>Number(i)).filter(Number.isFinite);if(n.length>=3)return[n[0],n[1],n[2]]}return t}function bn(e,t,n,i){const a=Ke(t.active),s=m("section","cultui-inventory-drag");S(s,e),E(s,n,i),s.dataset.active=a?"true":"false";const c=m("div","cultui-inventory-section-label","Drag");if(E(c,M(n,"sectionLabel."),M(i,"sectionLabel.")),s.append(c),!a){const d=m("div","cultui-inventory-empty","None");return E(d,M(n,"empty."),M(i,"empty.")),s.append(d),s}const l=p(t.itemKey,t.item,"item"),f=m("div","cultui-inventory-drag-chip",l);E(f,M(n,"dragChip."),M(i,"dragChip.")),s.append(f);const o=[t.originOffsetX,t.originOffsetY].map(d=>Number(d)).map(d=>Number.isFinite(d)?d:0),r=m("div","cultui-inventory-meta",`origin ${o[0]}, ${o[1]}`);return E(r,M(n,"meta."),M(i,"meta.")),s.append(r),s}function wn(e,t,n,i,a){const s=m("section","cultui-inventory-grid");S(s,e),E(s,n,i);const c=G(p(t.columns,t.gridColumns,t.widthCells,""),0),l=c>0?c:6,f=G(t.rows,0),o=f>0?f:Math.max(3,Math.ceil(Math.max((e.children||[]).length,1)/l));s.style.setProperty("--inventory-columns",String(l)),s.style.setProperty("--inventory-rows",String(o)),s.dataset.cellSpriteMode=v(t.cellSpriteMode,"");const r=p(t.title,t.label,"Inventory"),d=m("div","cultui-inventory-section-label",r);E(d,M(n,"sectionLabel."),M(i,"sectionLabel.")),s.append(d);const u=m("div","cultui-inventory-board");u.style.display="grid",u.style.gridTemplateColumns=`repeat(${l}, ${F(p(t.cellSize,"72"))})`,u.style.gridTemplateRows=`repeat(${o}, ${F(p(t.cellSize,"72"))})`,u.style.gap=F(p(t.cellGap,"4")),u.style.overflow=p(t.boardOverflow,"auto"),u.style.padding=F(p(t.boardPadding,"4")),E(u,M(n,"board."),M(i,"board.")),u.addEventListener("dragover",b=>{_n(t)&&(b.preventDefault(),b.dataTransfer&&(b.dataTransfer.dropEffect="move"))}),u.addEventListener("drop",b=>{const x=b.dataTransfer?.getData("application/vnd.gamecult.eve.inventory-item+json")||"";if(!x)return;let T;try{T=JSON.parse(x)}catch{return}const A=u.getBoundingClientRect(),z=Math.max(1,V(t.cellSize,72)),te=Math.max(0,V(t.cellGap,4)),j=z+te,ne=Math.max(0,Math.min(l-1,Math.floor((b.clientX-A.left)/j))),ie=Math.max(0,Math.min(o-1,Math.floor((b.clientY-A.top)/j))),Y=Sn(T,t,ne,ie,a);Y&&(b.preventDefault(),a.commandSink?.(Y,e))});const h=new Set;for(const b of e.children||[]){const x=_(b.props),T=G(x.x,0),A=G(x.y,0);h.add(`${T}:${A}`),u.append(N(b,a))}const g=Math.min(l*o,256);for(let b=0;b{!s.draggable||!g.dataTransfer||(g.dataTransfer.effectAllowed="move",g.dataTransfer.setData("application/vnd.gamecult.eve.inventory-item+json",JSON.stringify(t)))});let f=G(t.shapeWidth,1),o=G(t.shapeHeight,1);const r=p(t.rotation,"").toLowerCase();["clockwise","counterclockwise","right","left","rotate90","rotate270"].includes(r)&&([f,o]=[o,f]),s.style.gridColumn=`${c+1} / span ${f}`,s.style.gridRow=`${l+1} / span ${o}`;const d=m("span","cultui-inventory-item-icon");E(d,M(n,"icon."),M(i,"icon.")),d.textContent=Un(p(t.iconAssetUri,t.iconAssetKey,t.itemKey,t.label,"")),s.append(d);const u=p(t.label,t.itemKey,"");if(u){const g=m("span","cultui-inventory-item-label",u);E(g,M(n,"label."),M(i,"label.")),s.append(g)}const h=Number(t.quantity);if(Number.isFinite(h)&&h>1){const g=m("span","cultui-inventory-item-quantity",String(h));E(g,M(n,"quantity."),M(i,"quantity.")),s.append(g)}return s.title=[u,p(t.source,""),p(t.quality,"")?`quality ${t.quality}`:"",p(t.durability,"")?`durability ${t.durability}`:""].filter(Boolean).join(" | "),s}function _n(e){return Object.entries(e).some(([t,n])=>(t==="dropCommand"||t.startsWith("dropCommand."))&&typeof n=="string"&&n.length>0)}function Sn(e,t,n,i,a=X){const s=p(e.sourceKind,e.source,""),c=p(t[`dropCommand.${s}`],t.dropCommand,"");if(!s||!c)return;const l=V(e.sourceIndex,-1),f=V(t.targetIndex,-1),o=p(t.targetKind,""),r={sourceKind:s,originEntityKey:p(e.sourceEntityKey,e.entityKey,""),originIndex:l,originCargoIndex:s==="cargo"?l:-1,itemKey:p(e.itemKey,""),quantity:Math.max(1,V(e.quantity,1)),sourceX:V(e.x,-2147483648),sourceY:V(e.y,-2147483648),destinationKind:o,destinationEntityKey:p(t.targetEntityKey,t.entityKey,""),destinationIndex:f,destinationCargoIndex:o==="cargo"?f:-1,destinationX:Math.trunc(n),destinationY:Math.trunc(i),hasDestinationPosition:!0};return me(c,{action:r},a)}function En(e,t,n){const i=m("section","cultui-binding-map");S(i,e);const a=document.createElementNS("http://www.w3.org/2000/svg","svg");a.setAttribute("class","cultui-xbox-controller"),a.setAttribute("viewBox","0 0 780 420"),a.setAttribute("role","img"),a.setAttribute("aria-label",v(t.label,"Xbox controller remapping")),a.innerHTML=Cn(),i.append(a);const s=m("div","cultui-binding-overlay");for(const c of e.children||[]){const l=_(c.props),f=v(l.target,c.id||""),o=m("button","cultui-binding-box");S(o,c),o.type="button",o.dataset.target=f,o.dataset.kind=v(l.bindingKind,"button"),o.style.left=F(l.x??"50%"),o.style.top=F(l.y??"50%"),o.append(m("span","cultui-binding-target",v(l.label,f))),o.append(m("span","cultui-binding-source",v(l.current,"unmapped"))),o.addEventListener("click",()=>{const d=pt(c);if(mt(c)||d?.documentId)ht(Ue(c,n),n);else{const u=v(l.commandId,"");u&&n.commandSink?.(me(u,l,n),c)}}),s.append(o);const r=document.createElementNS("http://www.w3.org/2000/svg","line");r.setAttribute("class","cultui-binding-line"),r.setAttribute("x1",v(l.anchorX,"390")),r.setAttribute("y1",v(l.anchorY,"210")),r.setAttribute("x2",String(tt(l.x,780))),r.setAttribute("y2",String(tt(l.y,420))),a.append(r)}return i.append(s),i}function mt(e){for(const t of e.embeddedDocuments||[]){const n=_(t.surface);if(n.root)return n}}function pt(e){const t=(e.embeddedDocuments||[])[0],n=_(e.props),i=p(n.documentId,t?.documentId,"");if(i)return{documentId:i,presentationKind:p(n.presentationKind,t?.presentationKind,""),schemaId:p(n.schemaId,t?.schemaId,""),slotId:p(n.slotId,t?.slotId,"")}}async function Ue(e,t){const n=mt(e);if(n)return n;const i=pt(e);if(!i?.documentId||!t.documentResolver)return;const a=await t.documentResolver(i,e);if(a)return _(a.surface).root?a.surface:a}function ht(e,t){const n=m("div","cultui-modal-backdrop"),i=m("section","cultui-modal");i.setAttribute("role","dialog"),i.setAttribute("aria-modal","true");const a=m("header","cultui-modal-header");a.append(m("h2","","Configure Binding"));const s=m("button","cultui-modal-close","Close");s.type="button",s.addEventListener("click",()=>n.remove()),a.append(s);const c=m("div","cultui-modal-body");i.append(a,c),n.append(i),n.addEventListener("click",l=>{l.target===n&&n.remove()}),document.body.append(n),c.append(m("div","detail","materializing document")),Promise.resolve(e).then(l=>{a.querySelector("h2").textContent=l?.title||"Configure Binding",c.replaceChildren(l?.root?N(l.root,t):Q("Embedded document unavailable"))}).catch(l=>{c.replaceChildren(Q(`Embedded document failed: ${l instanceof Error?l.message:String(l)}`))})}function In(e,t,n,i,a){const s=_(e.props),c=(e.children||[])[0],l=_(c?.props),f=p(l.anchor,s.anchor,"trigger"),o=p(l.placement,s.placement,"below-start"),r=Number(p(l.offsetX,s.offsetX,"0"))||0,d=Number(p(l.offsetY,s.offsetY,"4"))||0,u=m("div","cultui-modal-backdrop");u.style.background="transparent",u.style.placeItems="start";const h=m("section","cultui-modal");h.setAttribute("role","dialog"),h.setAttribute("aria-modal","true"),h.style.position="fixed",h.style.width="min(420px, calc(100vw - 24px))",h.style.maxHeight="min(620px, calc(100vh - 24px))";const g=m("header","cultui-modal-header");g.append(m("h2","",p(l.title,s.title,s.label,"Options")));const b=m("button","cultui-modal-close","Close");b.type="button",b.addEventListener("click",()=>u.remove()),g.append(b);const x=m("div","cultui-modal-body");if(c){const A=c.children||[];A.length>0?x.replaceChildren(...A.map(z=>N(z,t))):x.append(N(c,t))}else x.append(Q("Popup has no content"));h.append(g,x),u.append(h),u.addEventListener("click",A=>{A.target===u&&u.remove()}),document.body.append(u);const T=An(f,o,n,h,i,a,r,d);h.style.left=`${T.left}px`,h.style.top=`${T.top}px`}function An(e,t,n,i,a,s,c,l){const f=n.getBoundingClientRect(),o=i.getBoundingClientRect(),r=o.width||420,d=o.height||320,u=e==="cursor"?{left:a,right:a,top:s,bottom:s}:f;if(t==="right-down"||t==="dropdown")return ve(u,r,d,c,l,"right","down");if(t==="left-down")return ve(u,r,d,c,l,"left","down");if(t==="right-up")return ve(u,r,d,c,l,"right","up");if(t==="left-up")return ve(u,r,d,c,l,"left","up");switch(t){case"above-start":return O(u.left+c,u.top-d-l,r,d);case"above-end":return O(u.right-r+c,u.top-d-l,r,d);case"below-end":return O(u.right-r+c,u.bottom+l,r,d);case"right-start":return O(u.right+c,u.top+l,r,d);case"left-start":return O(u.left-r-c,u.top+l,r,d);case"center":return O((window.innerWidth-r)/2+c,(window.innerHeight-d)/2+l,r,d);default:return O(u.left+c,u.bottom+l,r,d)}}function ve(e,t,n,i,a,s,c){const f=window.innerWidth-e.right-i-12,o=e.left-i-12,r=window.innerHeight-e.top-a-12,d=e.bottom-a-12,u=s==="right"?f>=t||f>=o:!(o>=t||o>=f),h=c==="down"?r>=n||r>=d:!(d>=n||d>=r),g=u?e.right+i:e.left-t-i,b=h?e.top+a:e.bottom-n-a;return O(g,b,t,n)}function O(e,t,n,i){return{left:et(e,12,window.innerWidth-n-12),top:et(t,12,window.innerHeight-i-12)}}function et(e,t,n){return n - - - - - - - - - - - - - - - - - YBXA - `}function kn(e,t=document.body){const n=Ge(e),i=document.documentElement.style;Fn(n.assets.fontCss);for(const[o,r]of Object.entries(ln))i.setProperty(o,r);const a={colorBackground:"--bg",colorBackgroundTop:"--bg-top",colorBackgroundMid:"--bg-mid",colorBackgroundBottom:"--bg-bottom",colorShellSurfaceTop:"--shell-top",colorShellSurfaceBottom:"--shell-bottom",colorPanel:"--panel",colorPanelAlt:"--panel-2",colorPanelBorder:"--line",colorPanelBorderDeep:"--line-deep",colorText:"--text",colorTextBright:"--text-bright",colorMuted:"--quiet",colorAccent:"--accent",colorAccentStrong:"--accent-strong",colorCornerAccent:"--corner-accent",colorLink:"--cyan",colorShadow:"--shadow",colorPixelGrid:"--pixel-grid"};for(const[o,r]of Object.entries(a)){const d=n.tokens[o];d!==void 0&&i.setProperty(r,String(d))}const s=n.tokens.fontBody,c=n.tokens.fontDisplay,l=n.tokens.fontTitle,f=n.tokens.fontMono;s&&i.setProperty("--font-body",be(String(s))),c&&i.setProperty("--font-title",be(String(c))),l&&i.setProperty("--font-title",be(String(l))),f&&i.setProperty("--font-mono",be(String(f))),n.tokens.borderWidthPx&&i.setProperty("--border-width",`${n.tokens.borderWidthPx}px`),n.tokens.borderBottomWidthPx&&i.setProperty("--border-bottom-width",`${n.tokens.borderBottomWidthPx}px`),n.tokens.cornerAccentPx&&i.setProperty("--corner-accent-size",`${n.tokens.cornerAccentPx}px`),t.dataset.pixelArt=n.tokens.pixelArt||n.tokens.imageRendering==="pixelated"?"true":"false",t.dataset.scanlines=n.tokens.scanlineOverlay?"true":"false"}function me(e,t={},n=X){const i=_(t.action),a=n.provider?.providerId||de?.providerId||"surface unknown",s=n.activeSurfaceId||de?.surface?.id||n.provider?.surfaces?.[0]?.surfaceId||a,c=Tn(n,s),l=p(c.commandBoundary,t.commandBoundary,i.commandBoundary,i.target),f=p(c.receiptSchema,t.receiptSchema,i.receiptSchema),o={type:"surface-command",schema:"gamecult.eve.command_invocation.v1",providerId:a,surfaceId:s,command:e||v(i.type,"invoke"),payload:{...i,transport:t.transport??null},issuedAt:new Date().toISOString(),clientId:n.clientId||"eve.browser"};return l&&(o.commandBoundary=l),f&&(o.receiptSchema=f),o}function Tn(e,t){const n=[...e.provider?.surfaces||[],...e.provider?.localAdvertisement?.surfaces||[]];return n.find(i=>i.surfaceId===t&&i.worldInteraction)?.worldInteraction||n.find(i=>i.worldInteraction)?.worldInteraction||{}}function nt(e,t){const n=_(e.action);return v(e.command,v(e.commandId,v(n.command,v(n.target,v(n.type,t?.commandId||"")))))}function Q(e){const t=m("section","pane");return t.append(m("h2","","No Surface")),t.append(m("div","detail",e)),t}function it(e,t,n,i,a){e.dataset.commandId=n,e.tabIndex=e instanceof HTMLButtonElement?e.tabIndex:0;const s=()=>{const c=me(n,i,a);a.commandSink?.(c,t)};e.addEventListener("click",s),e.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),s())})}function Rn(e,t,n){const i=Ln(e,t),a=_(i.find(u=>u.kind==="control.box")?.props),s=i.filter(u=>u.kind==="control.part"),c=Number(e.min??0),l=Number(e.max??1),f=m("div","cultui-slider");f.dataset.skin=v(e.skin,"default"),f.dataset.bind=v(e.bind,""),Mn(f,a);const o=m("div","cultui-slider-visual"),r=m("input","cultui-slider-input");r.type="range",r.min=String(c),r.max=String(l),r.step=String(e.step??.01),r.setAttribute("aria-label",v(e.bind,"slider"));for(const u of s){const h=_(u.props),g=m("span",`cultui-slider-part ${v(h.name,"part")}`);$n(g,h),o.append(g)}return s.some(u=>_(u.props).name==="track")||o.append(m("span","cultui-slider-part track")),s.some(u=>_(u.props).name==="fill")||o.append(m("span","cultui-slider-part fill")),s.some(u=>_(u.props).name==="thumb")||o.append(m("span","cultui-slider-part thumb")),f.append(o,r),(u=>{const h=Number(u??c),g=Math.max(c,Math.min(l,Number.isFinite(h)?h:c)),b=l===c?0:(g-c)/(l-c)*100;r.value=String(g),f.style.setProperty("--cultui-slider-value",`${b}%`),f.dataset.value=String(g)})(e.value??c),r.addEventListener("input",()=>{const u=me(v(e.command,"control.slider.input"),{...e,action:{..._(e.action),value:Number(r.value)},value:Number(r.value)},n);n.commandSink?.(u,{kind:"control.slider",props:e})}),f}function Ln(e,t){const n=typeof e.skin=="string"?e.skin:"",a=[...n?dt.controlSkins[n]?.children||[]:[],...t];return a.length?a:[{kind:"control.box",props:{height:18,overflow:"visible"}},{kind:"control.part",props:{name:"track",anchor:"center",size:["100%",6],radius:2,fill:"color.panelInset"}},{kind:"control.part",props:{name:"fill",anchor:["left","center"],size:["value%",6],radius:2,fill:"color.accent"}},{kind:"control.part",props:{name:"thumb",anchor:["value","center"],size:[12,12],bleed:3,radius:999,fill:"color.accent"}}]}function Ge(e){if(Array.isArray(e)){const t={},n={};for(const i of e)i?.name&&(i.name==="font.web.google"&&typeof i.value=="string"?n.fontCss=i.value:t[i.name]=i.value);return{tokens:t,assets:n,controlSkins:{}}}return{tokens:_(e?.tokens),assets:_(e?.assets),controlSkins:_(e?.controlSkins)}}function le(e){if(!e)return"";const t=X.assetUrlResolver;return t?t(e,de):/^(https?:|data:|blob:)/i.test(e)?e:X.assetBaseUrl&&e.startsWith("/")?`${X.assetBaseUrl.replace(/\/+$/,"")}${e}`:e}function Fn(e){const t=typeof e=="string"?e.trim():"";if(ge?.dataset.href===t||(ge?.remove(),ge=void 0,!t))return;const n=document.createElement("link");n.rel="preconnect",n.href="https://fonts.gstatic.com",n.crossOrigin="anonymous",document.head.append(n);const i=document.createElement("link");i.rel="stylesheet",i.href=t,i.dataset.href=t,document.head.append(i),ge=i}function Pn(e,t,n){const i=[];return(e==="text.title"||t.role==="title")&&i.push("cultui-title","eve-text-title"),e==="text.subtitle"&&i.push("eve-text-subtitle"),e==="label"&&i.push("cultui-label"),t.role==="mono"&&i.push("detail","mono"),i.length===0&&i.push("detail","eve-text"),i.join(" ")}function Mn(e,t){t.height!==void 0&&(e.style.minHeight=F(t.height)),t.width!==void 0&&(e.style.width=F(t.width)),typeof t.overflow=="string"&&(e.style.overflow=t.overflow)}function $n(e,t){const n=Array.isArray(t.size)?t.size:[t.size,void 0];n[0]!==void 0&&n[0]!=="value%"&&(e.style.width=F(n[0])),n[1]!==void 0&&(e.style.height=F(n[1])),t.radius!==void 0&&(e.style.borderRadius=F(t.radius)),t.fill!==void 0&&(e.style.background=xe(String(t.fill))),t.bleed!==void 0&&e.style.setProperty("--part-bleed",F(t.bleed)),(Array.isArray(t.anchor)?t.anchor:[t.anchor]).includes("value")&&(e.dataset.anchorValue="true")}function ye(e,t){t.gap!==void 0&&(e.style.gap=F(t.gap)),t.padding!==void 0&&(e.style.padding=F(t.padding)),t.size!==void 0&&(e.style.flex=Nn(t.size)),t.min!==void 0&&(e.style.minWidth=F(t.min)),t.max!==void 0&&(e.style.maxWidth=F(t.max)),t.align!==void 0&&(e.style.alignItems=t.align==="end"?"flex-end":String(t.align)),(t.clip==="true"||t.clip===!0)&&(e.style.overflow="hidden"),t.scroll==="y"&&(e.style.overflowY="auto"),t.scroll==="x"&&(e.style.overflowX="auto")}function Nn(e){return typeof e=="string"&&e.endsWith("fr")?`${Number(e.slice(0,-2))||1} 1 0`:e==="auto"||e==="content"?"0 0 auto":`0 0 ${F(e)}`}function F(e){return Array.isArray(e)?e.map(F).join(" "):typeof e=="number"?`${e}px`:typeof e=="string"&&/^-?\d+(\.\d+)?$/.test(e)?`${e}px`:String(e??"")}function xe(e){return{"color.accent":"var(--accent)","color.panelInset":"rgba(0, 0, 0, 0.34)","color.panel":"var(--panel)","color.text":"var(--text)"}[e]||e}function be(e){return e.includes("Zen Kaku Gothic New")||e.includes("M PLUS 1")?e:e.includes("Montserrat")?`${e}, "Zen Kaku Gothic New", "M PLUS 1", "Noto Sans JP", "Hiragino Sans", "Yu Gothic", sans-serif`:e.includes("Ubuntu")?`${e}, "M PLUS 1", "Noto Sans JP", "Hiragino Sans", "Yu Gothic", sans-serif`:`${e}, "Noto Sans JP", "Hiragino Sans", "Yu Gothic", sans-serif`}function S(e,t){t.id&&(e.id=t.id),t.id&&(e.dataset.eveNodeId=t.id),t.kind&&(e.dataset.eveKind=t.kind)}function _(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function Dn(e){return Array.isArray(e)?e:[]}function Bn(e){return Dn(e).map((t,n)=>ft({kind:"list.item",props:_(t)}))}function v(e,t){return e==null?t:String(e)}function p(...e){for(const t of e){if(typeof t=="string"&&t.trim())return t;if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function Ke(e){return typeof e=="boolean"?e:typeof e=="number"?e!==0:typeof e=="string"?["1","true","yes","on"].includes(e.trim().toLowerCase()):!1}function G(e,t){const n=Number(e);return Number.isFinite(n)?Math.max(0,Math.floor(n)):t}function Un(e){const t=e.toLowerCase();return t.includes("sensor")?"S":t.includes("thermal")?"T":t.includes("fuel")?"F":t.includes("cargo")?"C":t.includes("weapon")?"W":e.trim().slice(0,1).toUpperCase()||"?"}function zn(e){const t=e.trim().split(/\s+/).filter(Boolean);return t.length&&t.slice(0,2).map(n=>n[0]?.toUpperCase()||"").join("")||"?"}function rt(e){const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(100,t)):0}function m(e,t="",n=""){const i=document.createElement(e);return t&&(i.className=t),n&&(i.textContent=n),i}const y=e=>document.querySelector(e),K=y("#status"),Ee=y("#entry"),Ie=y("#session-zero"),ce=y("#surface"),Ae=y("#play-controls"),Z=y("#receipt");let R=0,gt=0,se="",W="",vt="",J="shared:table",Ce=null,Pe=!1;class ee extends Error{}function w(e,t,n){const i=document.createElement(e);return t!==void 0&&(i.textContent=t),n&&(i.className=n),i}async function ue(e){return e.status===204?null:(e.headers.get("content-type")??"").includes("json")?e.json():e.text()}function fe(e,t){return typeof e=="string"&&e.trim()?e.trim():typeof e?.error=="string"?e.error:t}async function P(e,t){if(Pe)throw new Error("Another table command is still being admitted.");Pe=!0,document.body.setAttribute("aria-busy","true");try{const n=await fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)}),i=await ue(n);if(!n.ok)throw new ee(fe(i,"The server refused the command."));return i}finally{Pe=!1,document.body.removeAttribute("aria-busy")}}function ke(e){const t=e instanceof Error?e.message:"The connection failed.";K.textContent=t,Z.hidden=!1,Z.replaceChildren(w("h2",e instanceof ee?"Request refused":"Request interrupted"),w("p",t),w("p","The server remains authoritative. Refresh before retrying.","quiet"))}window.addEventListener("unhandledrejection",e=>{e.preventDefault(),ke(e.reason)});function Wn(){Ee.hidden=!0,Ie.hidden=!0,Ae.hidden=!0,ce.hidden=!1;const e=w("article",void 0,"card");e.append(w("h2","Ghostlight Dungeon playtest"),w("p","Sign in through Heimdall with an eligible Discord account."));const t=w("button","Continue with Discord");t.addEventListener("click",()=>{Gn().catch(ke)}),e.append(t),ce.replaceChildren(e)}async function Gn(){const e=await fetch("/api/auth/heimdall/start",{method:"POST"}),t=await ue(e);if(!e.ok)throw new ee(fe(t,"Heimdall could not begin sign-in."));sessionStorage.setItem("ghostlight_heimdall_attempt",t.attempt_id),window.location.assign(t.authorization_url)}async function Kn(){const e=sessionStorage.getItem("ghostlight_heimdall_attempt");if(!e)return;const t=Date.now()+6e5;for(;Date.now()window.setTimeout(s,900));const n=await fetch(`/api/auth/heimdall/attempt/${encodeURIComponent(e)}`,{cache:"no-store"}),i=await ue(n);if(!n.ok)throw new ee(fe(i,"Heimdall sign-in expired."));if(i.status==="pending")continue;if(i.status!=="succeeded")throw new ee(i.error??"Discord access was not admitted.");const a=await fetch(`/api/auth/heimdall/attempt/${encodeURIComponent(e)}/adopt`,{method:"POST"});if(!a.ok)throw new ee(fe(await ue(a),"Heimdall session adoption failed."));sessionStorage.removeItem("ghostlight_heimdall_attempt");return}throw new Error("Heimdall sign-in timed out.")}async function $(){const e=await fetch("/api/surface",{cache:"no-store"});if(e.status===401)return Wn();const t=await ue(e);if(!e.ok)throw new ee(fe(t,"The table surface is unavailable."));if(Ce=t,t.surface_id==="ghostlight.session-zero-entry")return On();if(t.session_zero)return Oe(t.session_zero);Xn(t)}function On(){K.textContent="No campaign is selected. Begin or join a Session Zero.",Ee.hidden=!1,Ie.hidden=!0,ce.hidden=!0,Ae.hidden=!0;const e=new URLSearchParams(location.search).get("invite");e&&(y("#join-token").value=e)}function ot(e,t){e.replaceChildren();for(const[n,i]of Object.entries(t)){const a=Array.isArray(i)?i.join(" · "):String(i||"Not decided yet");e.append(w("dt",n.replaceAll("_"," ")),w("dd",a))}}function Oe(e){Ee.hidden=!0,Ie.hidden=!1,ce.hidden=!0,Ae.hidden=!0,W=e.id,R=Number(e.revision),vt=e.viewer_member_id,e.channels.some(o=>o.id===J)||(J="shared:table"),y("#session-title").textContent=Ce.title,y("#session-state").textContent=`${String(e.status).replaceAll("_"," ")} · revision ${R}`,K.textContent=e.status==="compiling"?"The DM is compiling the agreed brief. You can leave this page.":"Session Zero is persistent. Conversation is not world truth until unanimous publication.";const t=J==="shared:table";y("#tab-shared").setAttribute("aria-pressed",String(t)),y("#tab-private").setAttribute("aria-pressed",String(!t));const n=e.channels.find(o=>o.id===J)??e.channels[0],i=y("#session-transcript");i.replaceChildren();for(const o of n?.messages??[]){const r=w("li",void 0,`message ${o.speaker}`);r.append(w("strong",o.speaker==="dm"?"DM":o.speaker==="system"?"Table":"Player"),w("p",o.text)),i.append(r)}const a=y("#roster");a.replaceChildren();for(const o of e.public_party){const r=w("p",`${o.approved?"Ready":"Not ready"} · ${o.display_name} as ${o.name||"undecided"}${o.is_host?" · host":""}`);if(e.viewer_is_host&&!e.roster_locked&&!o.is_host){const d=w("button","Remove");d.addEventListener("click",async()=>{await P(`/api/session-zero/${W}/remove-member`,{expected_revision:R,member_id:o.member_id}),await $()}),r.append(" ",d)}a.append(r)}y("#cell-pool").textContent=`${e.pooled_cell_allowance} pooled active Persona cells · ${e.active_members}/8 players`,ot(y("#contract-ledger"),e.contract),ot(y("#character-ledger"),e.private_character),y("#boundary-list").replaceChildren(...e.private_boundaries.map(o=>{const r=w("li",`${o.level.replaceAll("_"," ")} · ${o.topic} `),d=w("button","Remove");return d.addEventListener("click",async()=>{await P(`/api/session-zero/${W}/boundary/${encodeURIComponent(o.id)}/remove`,{expected_revision:R}),await $()}),r.append(d),r}));const c=y("#decision-list");c.replaceChildren();for(const o of e.decisions.filter(r=>!r.resolved)){const r=w("article",void 0,"decision");r.append(w("h4",o.prompt),w("p",o.proposed_resolution));const d=w("button","Accept");d.addEventListener("click",()=>{Yn(o.id,!0)});const u=w("button","Counter");u.addEventListener("click",async()=>{const g=window.prompt("What should the DM propose instead?",o.proposed_resolution);g?.trim()&&(await P(`/api/session-zero/${W}/decision`,{expected_revision:R,decision_id:o.id,accept:!1,counter:g.trim()}),await $())});const h=w("button","Discuss");h.addEventListener("click",()=>{y("#session-message").value=`I'd like to discuss: ${o.prompt}`,y("#session-message").focus()}),r.append(d,u,h),c.append(r)}const l=y("#review-card");if(l.hidden=!e.preview,e.preview){const o=y("#review-content");o.replaceChildren(w("p",e.preview.title)),e.preview.branch_assumptions?.length&&o.append(w("p",`Branch-local assumptions: ${e.preview.branch_assumptions.join("; ")}`)),o.append(w("p",`${Object.keys(e.preview.topology??{}).length} locations · ${Object.keys(e.preview.institutions??{}).length} institutions · ${Object.keys(e.preview.clocks??{}).length} clocks`))}const f=!!e.viewer_is_host;y("#invite-form").hidden=!f||e.roster_locked,y("#lock-roster").disabled=!f||e.roster_locked,y("#compile-session").disabled=!f||!e.roster_locked||["compiling","review","published"].includes(e.status),y("#approve-session").disabled=e.status!=="review"||e.approved,y("#publish-session").disabled=!f||!e.publish_ready}function Xn(e){if(Ee.hidden=!0,Ie.hidden=!0,ce.hidden=!1,Ae.hidden=!1,R=Number(e.world_revision),gt=Number(e.resolution?.policy?.resolution_epoch??0),se=e.viewer_actor_id,!se)throw new Error("Actor-filtered campaign surface omitted the viewer actor binding.");dn(e,ce,{body:document.body,clientId:"ghostlight.browser",statusElement:K}),K.textContent=`World revision ${R}. Your surface contains only ${se}'s permitted state.`;const t=Number(e.resolution?.policy?.active_cell_budget??8);y("#active-cell-budget").value=String(t),y("#active-cell-budget-value").value=String(t),y("#travel-destination").replaceChildren(...(e.reachable_destinations??[]).map(i=>{const a=document.createElement("option");return a.value=i.id,a.textContent=`${i.name} · ${i.travel_minutes} minutes`,a})),jn(e.governance??{})}function jn(e){const t=y("#time-form"),n=y("#travel-form"),i=y("#resolution-form"),a=e.time_proposals?.[0],s=e.travel_proposals?.[0],c=e.cell_budget_proposals?.[0],l=t.querySelector("button"),f=n.querySelector("button"),o=i.querySelector("button");l.textContent=a?`Approve ${a.minutes} minute advance (${a.approvals.length}/${e.active_member_count})`:"Propose time",f.textContent=s?`Approve group travel (${s.approvals.length}/${e.active_member_count})`:"Propose travel",o.textContent=c?`Approve ${c.active_cell_budget} cells (${c.approvals.length}/${e.active_member_count})`:"Propose budget",t.dataset.proposalId=a?.id??"",n.dataset.proposalId=s?.id??"",i.dataset.proposalId=c?.id??""}async function Yn(e,t){await P(`/api/session-zero/${W}/decision`,{expected_revision:R,decision_id:e,accept:t,counter:null}),await $()}function Te(e){if(Z.hidden=!1,e.kind==="assessed"){const t=e.assessment;if(Z.replaceChildren(w("h2",t.admissible?`Assessment · DC ${t.dc}`:"Attempt not admitted"),w("p",t.admissible?`Success: ${t.success_stake}`:t.missing_permission)),t.admissible){const n=w("button","Confirm server roll");n.addEventListener("click",()=>{Xe({type:"attempt",actor_id:se,assessment_digest:t.digest})}),Z.append(n)}}else e.kind?.includes("pending")?Z.replaceChildren(w("h2","Waiting for the table"),w("p","The proposal is revision-bound and will commit only after every active member approves.")):Z.replaceChildren(w("h2","World committed"),w("p",e.receipt?.roll?`d20 ${e.receipt.roll.d20} · ${String(e.receipt.roll.outcome).replaceAll("_"," ")}`:`Revision ${e.revision??R}`))}async function Xe(e){const t=await P("/api/command",e);return Te(t),await $(),t}y("#session-entry-form").addEventListener("submit",async e=>{e.preventDefault();const t=Object.fromEntries(new FormData(e.currentTarget));delete t.mode,await P("/api/session-zero",t),await $()});y("#join-form").addEventListener("submit",async e=>{e.preventDefault();const t=y("#join-token").value.trim();await P(`/api/session-zero/join/${encodeURIComponent(t)}`,{display_name:y("#join-name").value.trim()}),history.replaceState({},"",location.pathname),await $()});y("#tab-shared").addEventListener("click",()=>{J="shared:table",Oe(Ce.session_zero)});y("#tab-private").addEventListener("click",()=>{J=`private:${vt}`,Oe(Ce.session_zero)});y("#session-message-form").addEventListener("submit",async e=>{e.preventDefault();const t=y("#session-message");await P(`/api/session-zero/${W}/message`,{expected_revision:R,channel_id:J,text:t.value.trim()}),t.value="",K.textContent="Your message is durable. The DM is considering it.",await $()});y("#invite-form").addEventListener("submit",async e=>{e.preventDefault();const t=await P(`/api/session-zero/${W}/invites`,{count:Number(y("#invite-count").value)}),n=y("#invite-output");n.replaceChildren();for(const i of t.invite_tokens){const a=`${location.origin}${location.pathname}?invite=${encodeURIComponent(i)}`,s=w("p"),c=w("a",a);c.href=a,s.append(c),n.append(s)}await $()});y("#boundary-form").addEventListener("submit",async e=>{e.preventDefault(),await P(`/api/session-zero/${W}/boundary`,{expected_revision:R,boundary_id:null,topic:y("#boundary-topic").value.trim(),level:y("#boundary-level").value}),y("#boundary-topic").value="",await $()});y("#lock-roster").addEventListener("click",async()=>{await P(`/api/session-zero/${W}/lock`,{expected_revision:R}),await $()});y("#compile-session").addEventListener("click",async()=>{await P(`/api/session-zero/${W}/compile`,{expected_revision:R}),await $()});y("#approve-session").addEventListener("click",async()=>{await P(`/api/session-zero/${W}/approve`,{expected_revision:R}),await $()});y("#publish-session").addEventListener("click",async()=>{await P(`/api/session-zero/${W}/publish`,{expected_revision:R}),await $()});y("#composer").addEventListener("submit",async e=>{e.preventDefault();const t=y("#attempt").value.trim(),n=y("#intended-effect").value.trim();if(!n)return void(K.textContent="Name the uncertain effect, or use Speak.");await Xe({type:"assess",expected_revision:R,intent:{actor_id:se,description:t,intended_effect:n}})});y("#speak").addEventListener("click",async()=>{const e=y("#attempt");await Xe({type:"speak",expected_revision:R,actor_id:se,text:e.value.trim(),intended_effect:null}),e.value=""});y("#contract-review").addEventListener("click",async()=>{await P("/api/campaigns/contract-review",{}),await $()});y("#active-cell-budget").addEventListener("input",e=>{y("#active-cell-budget-value").value=e.currentTarget.value});y("#time-form").addEventListener("submit",async e=>{e.preventDefault();const n=e.currentTarget.dataset.proposalId,i=n?await P(`/api/governance/time/${encodeURIComponent(n)}/approve`,{expected_revision:R}):await P("/api/governance/time",{expected_revision:R,minutes:Number(y("#time-minutes").value)});Te(i),await $()});y("#travel-form").addEventListener("submit",async e=>{e.preventDefault();const n=e.currentTarget.dataset.proposalId,i=y("#travel-destination").value;if(!n&&!i)return void(K.textContent="No reachable destination is compiled from this scene.");const a=n?await P(`/api/governance/travel/${encodeURIComponent(n)}/approve`,{expected_revision:R}):await P("/api/governance/travel",{expected_revision:R,destination_location_id:i});Te(a),await $()});y("#resolution-form").addEventListener("submit",async e=>{e.preventDefault();const n=e.currentTarget.dataset.proposalId,i=n?await P(`/api/governance/cell-budget/${encodeURIComponent(n)}/approve`,{expected_revision:R}):await P("/api/governance/cell-budget",{expected_revision:R,expected_resolution_epoch:gt,active_cell_budget:Number(y("#active-cell-budget").value)});Te(i),await $()});const yt=new EventSource("/api/events");let Me=!1;yt.addEventListener("revision",()=>{Me||(Me=!0,window.setTimeout(()=>{Me=!1,$().catch(ke)},100))});yt.onerror=()=>{K.textContent="Realtime revision notices are reconnecting; the server remains authoritative."};Kn().then($).catch(ke); diff --git a/web/dist/assets/index-BuuhLtYk.js b/web/dist/assets/index-BuuhLtYk.js new file mode 100644 index 0000000..c32bde0 --- /dev/null +++ b/web/dist/assets/index-BuuhLtYk.js @@ -0,0 +1,160 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const c of i.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&n(c)}).observe(document,{childList:!0,subtree:!0});function r(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(o){if(o.ep)return;o.ep=!0;const i=r(o);fetch(o.href,i)}})();const Ve=new WeakMap,jr=20;function ba(e,t,r,n,o,i,c,s){const d=Sa(e.canvas);if(!d)return!1;const u=d.gl;if(!Ea(d,i,c))return Ve.set(e.canvas,null),!1;const a=_a(t,r,n,o,s);u.bindFramebuffer(u.FRAMEBUFFER,d.framebuffer),u.viewport(0,0,i,c),u.disable(u.DEPTH_TEST),u.disable(u.CULL_FACE),u.enable(u.BLEND),u.blendFunc(u.ONE,u.ONE),u.clearColor(0,0,0,1),u.clear(u.COLOR_BUFFER_BIT),a.gravity.length>0&&(u.useProgram(d.splatProgram),u.uniform4f(u.getUniformLocation(d.splatProgram,"u_viewport"),o.minX,o.minY,o.maxX,o.maxY),u.uniform1f(u.getUniformLocation(d.splatProgram,"u_time"),se(t.simulationTimeSeconds,0)),u.bindBuffer(u.ARRAY_BUFFER,d.splatBuffer),u.bufferData(u.ARRAY_BUFFER,a.gravity,u.DYNAMIC_DRAW),tn(u,d.splatProgram),u.drawArrays(u.TRIANGLES,0,a.gravity.length/jr)),u.bindFramebuffer(u.FRAMEBUFFER,d.tintFramebuffer),u.clearColor(0,0,0,0),u.clear(u.COLOR_BUFFER_BIT),a.tint.length>0&&(u.useProgram(d.splatProgram),u.uniform4f(u.getUniformLocation(d.splatProgram,"u_viewport"),o.minX,o.minY,o.maxX,o.maxY),u.uniform1f(u.getUniformLocation(d.splatProgram,"u_time"),se(t.simulationTimeSeconds,0)),u.bindBuffer(u.ARRAY_BUFFER,d.splatBuffer),u.bufferData(u.ARRAY_BUFFER,a.tint,u.DYNAMIC_DRAW),tn(u,d.splatProgram),u.drawArrays(u.TRIANGLES,0,a.tint.length/jr)),u.disable(u.BLEND),u.bindFramebuffer(u.FRAMEBUFFER,null),u.viewport(0,0,i,c),u.useProgram(d.shadeProgram),u.activeTexture(u.TEXTURE0),u.bindTexture(u.TEXTURE_2D,d.fieldTexture),u.uniform1i(u.getUniformLocation(d.shadeProgram,"u_field"),0),u.activeTexture(u.TEXTURE1),u.bindTexture(u.TEXTURE_2D,d.tintTexture),u.uniform1i(u.getUniformLocation(d.shadeProgram,"u_tint"),1),u.uniform2f(u.getUniformLocation(d.shadeProgram,"u_resolution"),i,c),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_time"),se(r.simulationTimeSeconds,se(t.simulationTimeSeconds,0))),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_lineInterval"),se(t.lineInterval,se(t.scalarFieldLineInterval,se(t.depthRange,228.79605)/20))),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_lineOffset"),se(t.lineOffset,se(t.startDepth,2.310401))),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_lineWidth"),se(t.lineWidth,.3)),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_lineFade"),se(t.lineFade,5)),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_angleWidth"),se(t.angleWidth,.05)),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_angleFade"),se(t.angleFade,1.15)),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_dangerSteepness"),se(t.dangerSteepness,1.5)),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_scale"),se(t.isolineScale,2.6924083)),We(u,d.shadeProgram,"u_baseColor",Ge(t.scalarFieldBaseColor,[.002,.006,.012])),We(u,d.shadeProgram,"u_fieldGlowColor",Ge(t.scalarFieldGlowColor,[.018,.05,.075])),We(u,d.shadeProgram,"u_lineLowColor",Ge(t.scalarFieldLowLineColor,[0,.34,.52])),We(u,d.shadeProgram,"u_lineHighColor",Ge(t.scalarFieldHighLineColor,[1.45,.3,.05])),We(u,d.shadeProgram,"u_angleLowColor",Ge(t.scalarFieldLowAngleColor,[.06,.16,.24])),We(u,d.shadeProgram,"u_angleHighColor",Ge(t.scalarFieldHighAngleColor,[1.1,.24,.04])),u.uniform1f(u.getUniformLocation(d.shadeProgram,"u_tintScale"),se(t.vectorFieldTintScale,.45)),u.bindBuffer(u.ARRAY_BUFFER,d.quadBuffer);const f=u.getAttribLocation(d.shadeProgram,"a_position");return u.enableVertexAttribArray(f),u.vertexAttribPointer(f,2,u.FLOAT,!1,0,0),u.drawArrays(u.TRIANGLES,0,6),e.drawImage(d.canvas,0,0,i,c),!0}function _a(e,t,r,n,o){const i=[],c=[];return $a(i,e,t,r),wa(c,e,o),{gravity:new Float32Array(i),tint:new Float32Array(c)}}function $a(e,t,r,n,o){const i=se(r.terrainRadius,se(t.terrainRadius,1200)),c=se(r.terrainDepth,se(t.terrainDepth,-8));c!==0&&ir(e,0,0,Math.max(1,i*2),Math.max(1,i*2),-c,0,0,1,Math.max(1e-4,se(r.terrainDepthExponent,se(t.terrainDepthExponent,1.2))),0,1,0,0);for(const s of n)ir(e,s.x,s.y,Math.max(1,s.radius),Math.max(1,s.radius),-s.depth,0,0,1,Math.max(1e-4,s.exponent),0,1,0,0),s.waveRadius>0&&s.waveDepth!==0&&ir(e,s.x,s.y,s.waveRadius,s.waveRadius,-s.waveDepth,0,0,1,8,4,se(r.terrainWaveFrequency,se(t.terrainWaveFrequency,.6)),s.waveSpeed,0)}function wa(e,t,r){const n=Pa(r?.splats),o=Array.isArray(r?.layers)?r.layers:[],i=new Set,c=Ra(t.vectorFieldLayer,t.tintFieldLayer,"fog.tint");o.forEach((O,A)=>{const M=Ia(O?.layerKey,"");se(O?.channel,-1)===4&&M===c&&i.add(A)});const s=Math.max(0,Aa(n.count,0));if(s<=0||i.size===0)return;const d=ye(n.centerX),u=ye(n.centerY),a=ye(n.halfExtentX),f=ye(n.halfExtentY),m=ye(n.rotationCos),y=ye(n.rotationSin),$=ye(n.channel),S=ye(n.falloff),g=ye(n.valueR),_=ye(n.valueG),p=ye(n.valueB),w=ye(n.valueA),E=ye(n.sourceKind),l=ye(n.frequencyX),h=ye(n.animationSpeed),v=ye(n.sourceFlags),I=ye(n.layerIndex);for(let O=0;ONumber(n));if(r.length>=3&&r.slice(0,3).every(Number.isFinite))return[r[0],r[1],r[2]]}if(typeof e=="string"){const r=e.split(/[,\s]+/).map(n=>Number(n)).filter(Number.isFinite);if(r.length>=3)return[r[0],r[1],r[2]]}return t}function We(e,t,r,n){e.uniform3f(e.getUniformLocation(t,r),n[0],n[1],n[2])}function ye(e){return Array.isArray(e)?e.map(t=>se(t,0)):[]}function Pa(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function Ia(e,t){return e==null?t:String(e)}function Ra(...e){for(const t of e){if(typeof t=="string"&&t.trim())return t;if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function Aa(e,t){const r=Number(e);return Number.isFinite(r)?Math.max(0,Math.floor(r)):t}const ka=`#version 300 es +in vec2 a_corner; +in vec2 a_center; +in vec2 a_half; +in vec2 a_rot; +in vec4 a_meta; +in vec4 a_source; +in vec4 a_value; +uniform vec4 u_viewport; +out vec2 v_local; +out vec4 v_meta; +out vec4 v_source; +out vec4 v_value; +void main() { + vec2 scaled = a_corner * a_half; + vec2 world = a_center + vec2( + scaled.x * a_rot.x - scaled.y * a_rot.y, + scaled.x * a_rot.y + scaled.y * a_rot.x + ); + vec2 clip = vec2( + ((world.x - u_viewport.x) / max(0.0001, u_viewport.z - u_viewport.x)) * 2.0 - 1.0, + ((world.y - u_viewport.y) / max(0.0001, u_viewport.w - u_viewport.y)) * 2.0 - 1.0 + ); + gl_Position = vec4(clip, 0.0, 1.0); + v_local = a_corner; + v_meta = a_meta; + v_source = a_source; + v_value = a_value; +}`,Ca=`#version 300 es +precision highp float; +in vec2 v_local; +in vec4 v_meta; +in vec4 v_source; +in vec4 v_value; +uniform float u_time; +out vec4 outColor; +float hash21(vec2 p) { + p = fract(p * vec2(123.34, 456.21)); + p += dot(p, p + 45.32); + return fract(p.x * p.y); +} +float valueNoise(vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + float a = hash21(i); + float b = hash21(i + vec2(1.0, 0.0)); + float c = hash21(i + vec2(0.0, 1.0)); + float d = hash21(i + vec2(1.0, 1.0)); + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(mix(a, b, u.x), mix(c, d, u.x), u.y) * 2.0 - 1.0; +} +float powerPulse(float x, float power) { + x = clamp(abs(x), 0.0, 1.0); + return pow((x + 1.0) * (1.0 - x), max(0.0001, power)); +} +void main() { + float d = length(v_local); + if (d > 1.0) discard; + float alpha = powerPulse(d, v_meta.x); + if (alpha <= 0.0001) discard; + float source = 1.0; + if (v_source.x > 0.5 && v_source.x < 2.5) { + float timeOffset = v_source.x > 1.5 ? u_time * v_source.z : 0.0; + source = valueNoise(v_local * v_source.y + timeOffset); + if (v_source.w != 0.0) source = abs(source); + } else if (v_source.x > 3.5) { + source = cos(pow(d * 2.0, 1.25) * v_source.y + u_time * v_source.z); + } + outColor = v_value * alpha * source; +}`,Na=`#version 300 es +in vec2 a_position; +out vec2 v_uv; +void main() { + v_uv = a_position * 0.5 + 0.5; + gl_Position = vec4(a_position, 0.0, 1.0); +}`,Ta=`#version 300 es +precision highp float; +uniform sampler2D u_field; +uniform sampler2D u_tint; +uniform vec2 u_resolution; +uniform float u_time; +uniform float u_lineInterval; +uniform float u_lineOffset; +uniform float u_lineWidth; +uniform float u_lineFade; +uniform float u_angleWidth; +uniform float u_angleFade; +uniform float u_dangerSteepness; +uniform float u_scale; +uniform vec3 u_baseColor; +uniform vec3 u_fieldGlowColor; +uniform vec3 u_lineLowColor; +uniform vec3 u_lineHighColor; +uniform vec3 u_angleLowColor; +uniform vec3 u_angleHighColor; +uniform float u_tintScale; +in vec2 v_uv; +out vec4 outColor; +vec2 calcGrad(vec2 uv, float me) { + vec2 texel = 1.0 / max(vec2(1.0), u_resolution); + float n = -texture(u_field, vec2(uv.x, uv.y + texel.y)).r; + float e = -texture(u_field, vec2(uv.x + texel.x, uv.y)).r; + return vec2(e - me, n - me); +} +void main() { + float height = -texture(u_field, v_uv).r; + vec4 tint = texture(u_tint, v_uv); + vec2 plan = calcGrad(v_uv, height); + float slope = max(length(plan), 0.00001); + vec3 color = u_baseColor; + float fieldGlow = smoothstep(0.0, u_lineInterval * 7.0, abs(height)); + color += u_fieldGlowColor * fieldGlow; + color += tint.rgb * clamp(tint.a, 0.0, 1.0) * u_tintScale; + + float dangerBlend = smoothstep(0.0, u_dangerSteepness, pow(slope / max(0.0001, u_scale), 2.0)); + vec3 baseLine = mix(u_lineLowColor, u_lineHighColor, dangerBlend); + vec3 angleLine = mix(u_angleLowColor, u_angleHighColor, dangerBlend) * clamp(slope / max(0.0001, u_scale), 0.0, 1.0); + + vec3 lines = vec3(0.0); + float interval = max(0.0001, abs(u_lineInterval)); + float nearestLine = abs(fract((height + u_lineOffset) / interval) - 0.5) * interval; + float lineDistance = nearestLine / slope; + float line = 1.0 - smoothstep(u_lineWidth, u_lineWidth * u_lineFade, lineDistance); + lines += line * baseLine; + + float angle = atan(plan.y, plan.x) / 3.1415926536 + 1.0; + float nearestAngle = abs(fract(angle * 6.0) - 0.5) / 6.0; + float angleMask = smoothstep(interval * 0.25, interval * 1.5, abs(height)); + float angleLineAmount = 1.0 - smoothstep(u_angleWidth, u_angleWidth * u_angleFade, nearestAngle); + lines += angleLineAmount * angleMask * angleLine; + + color += clamp(lines, 0.0, 1.7); + outColor = vec4(color, 1.0); +}`,Vi=new Set(["gamecult.fields.splats.v1","gamecult.fields.gravity.v1","gamecult.fields.objects.v1"]),ja={pluginId:"fields.surface",capabilities:["field.surface2d","gravity.surface","field.scalar","field.vector","field.objects"],componentKinds:["field.surface2d","gravity.surface"],schemas:[...Vi],normalizeDocument:Or,renderComponent:Oa};function Oa(e,t,r,n,o,i){const c=document.createElement("canvas");c.className="cultui-gravity-surface",e.id&&(c.id=e.id),c.setAttribute("role","img"),c.setAttribute("aria-label",io(t.label,"gravity surface")),c.style.display="block",c.style.width="100%",c.style.height="100%",c.style.pointerEvents="none",i.applyGeneratedLayout(c,r,n);let s=!1;const d={},u=()=>xa(c,t,d,i.resolveAssetUrl),a=()=>{!c.isConnected||s||(s=!0,requestAnimationFrame(()=>{s=!1,c.isConnected&&u()}))};c.addEventListener("cultui:asset-loaded",a);let f=0,m;const y=()=>{f&&window.clearInterval(f),m?.disconnect(),c.removeEventListener("cultui:asset-loaded",a)},$=()=>{if(!c.isConnected){y();return}Ma(e,t,o,i.providerId,d).then(g=>{g&&c.isConnected&&a()}).catch(g=>{d.lastError=g instanceof Error?g.message:String(g)})};typeof ResizeObserver<"u"&&(m=new ResizeObserver(a),m.observe(c)),a();const S=Math.max(33,Math.min(1e3,ao(t.stateRefreshMs,100)));return f=window.setInterval($,S),queueMicrotask($),window.setTimeout(a,300),window.setTimeout(a,1e3),c}async function Ma(e,t,r,n,o){if(o.loading)return!1;const i=[_r(e,t,"renderSplats","renderSplatsDocumentId","renderSplatsSchemaId"),_r(e,t,"gravity","gravityDocumentId","gravitySchemaId"),_r(e,t,"objects","objectsDocumentId","objectsSchemaId")].filter(c=>!!c?.documentId);if(i.length===0)return!1;o.loading=!0;try{let c=!1;for(const s of i){const d=await r.documentResolver?.(s,e);let u=cr(Or(d?.schemaId||s.schemaId,d?.document));if(Object.keys(u).length===0&&(u=cr(Or(s.schemaId,await qa(s,n||r.provider?.providerId)))),Object.keys(u).length===0)continue;const a=s.slotId==="renderSplats"?"renderSplats":s.slotId==="gravity"?"gravity":"objects",f=qr(o[a]?.frameId,-1),m=qr(u.frameId,f);o[a]=u,c||=m!==f}return o.lastLoadedAt=Date.now(),c}finally{o.loading=!1}}async function qa(e,t){if(typeof fetch!="function"||typeof window>"u"||!t)return;const r=new URLSearchParams({documentId:e.documentId});e.schemaId&&r.set("schemaId",e.schemaId),e.slotId&&r.set("slotId",e.slotId);const n=await fetch(`/eir/document/${encodeURIComponent(t)}?${r.toString()}`,{cache:"no-store",headers:{Accept:"application/json"}});if(n.ok)return cr(await n.json()).document}function _r(e,t,r,n,o){const i=(e.embeddedDocuments||[]).find(s=>String(s?.slotId||"")===r),c=ue(t[n],i?.documentId);if(c)return{documentId:c,schemaId:ue(t[o],i?.schemaId),presentationKind:ue(i?.presentationKind)||"data",slotId:r}}function Or(e,t){const r=Array.isArray(t)?t:void 0,n=r?r[0]:t?.schema,o=String(e||n||"");return!r||!Vi.has(o)?t:o==="gamecult.fields.splats.v1"?Xa(r):o==="gamecult.fields.gravity.v1"?Ya(r):Ja(r)}function xa(e,t,r,n){const o=e.getBoundingClientRect(),i=Math.max(1,Math.floor(o.width||e.clientWidth||1)),c=Math.max(1,Math.floor(o.height||e.clientHeight||1)),s=Math.max(1,Math.min(2,window.devicePixelRatio||1)),d=Math.max(1,Math.floor(i*s)),u=Math.max(1,Math.floor(c*s));(e.width!==d||e.height!==u)&&(e.width=d,e.height=u);const a=e.getContext("2d");if(!a)return;a.setTransform(s,0,0,s,0,0),a.clearRect(0,0,i,c);const f=Wa(Ga(t),i,c),m=Hi(r?.gravity),y=Ba(r?.gravity)||Va(ue(t.bodies,"")),$=Ha(r?.objects)||Ka(ue(t.objects,""));ba(a,t,m,y,f,i,c,r?.renderSplats)||La(a,t,i,c,"field.surface2d requires WebGL2 float render targets"),Da(a,y,t,f,i,c,n),Ua(a,$,t,f,i,c,n)}function La(e,t,r,n,o){e.save(),e.fillStyle=ue(t.failureBackground,"rgba(0, 0, 0, 0.72)"),e.fillRect(0,0,r,n),e.font=ue(t.failureFont,"700 13px Cascadia Mono, Consolas, monospace"),e.fillStyle=ue(t.failureColor,"rgba(255, 184, 79, 0.95)"),e.fillText(o,16,28),e.restore()}function Da(e,t,r,n,o,i,c){for(const s of t){const d=Bi(n,s.x,s.y,o,i),u=Math.max(18,Math.min(190,s.radius/Math.max(1,n.maxX-n.minX)*o*.32)),a=c(s.icon),f=s.kind.toLowerCase().includes("sun")?Math.max(oe(r.sunIconMinPx,34),u*oe(r.sunIconScale,.72)):Math.max(oe(r.bodyIconMinPx,24),u*oe(r.bodyIconScale,.48)),m=s.iconSize>0?s.iconSize:f;a&&Fa(e,a,d.x,d.y,m,.92),s.key&&Ki(e,r,s.key.replace(/^local\./,""),d.x+u*.44,d.y-u*.48,ue(r.bodyLabelColor,"rgba(226, 244, 255, 0.82)"))}}const sr=new Map;function Fa(e,t,r,n,o,i){let c=sr.get(t);c||(c=new Image,c.decoding="async",c.onload=()=>requestAnimationFrame(()=>{e.canvas.dispatchEvent(new CustomEvent("cultui:asset-loaded"))}),c.src=t,sr.set(t,c)),!(!c.complete||c.naturalWidth===0)&&(e.save(),e.globalAlpha=i,e.drawImage(c,r-o/2,n-o/2,o,o),e.restore())}function Ua(e,t,r,n,o,i,c){for(const s of t){const d=Bi(n,s.x,s.y,o,i);if(d.x<-40||d.x>o+40||d.y<-40||d.y>i+40)continue;const u=s.kind.toLowerCase().includes("station")?oe(r.stationIconSizePx,34):s.controlled?oe(r.shipIconSizePx,22):oe(r.remoteShipIconSizePx,18),a=za(r,s.faction,s.controlled,s.visibility),f=c(s.icon);e.save(),e.globalAlpha=Math.max(.25,Math.min(1,s.visibility)),e.translate(d.x,d.y);const m=Math.atan2(s.directionY,s.directionX)+Math.PI/2;if(s.kind.toLowerCase().includes("ship")&&e.rotate(m),f){const y=sr.get(f);if(y)y.complete&&y.naturalWidth>0&&e.drawImage(y,-u/2,-u/2,u,u);else{const $=new Image;$.decoding="async",$.onload=()=>e.canvas.dispatchEvent(new CustomEvent("cultui:asset-loaded")),$.src=f,sr.set(f,$)}}e.restore(),Ki(e,r,s.label,d.x+u*.55,d.y-u*.45,a)}}function Ki(e,t,r,n,o,i){r&&(e.save(),e.font=ue(t.objectLabelFont,"700 12px Ubuntu, system-ui, sans-serif"),e.textBaseline="middle",e.lineWidth=oe(t.objectLabelStrokeWidth,3),e.strokeStyle=ue(t.objectLabelStroke,"rgba(0, 0, 0, 0.72)"),e.fillStyle=i,e.strokeText(r,n,o),e.fillText(r,n,o),e.restore())}function za(e,t,r,n){const o=Math.max(.25,Math.min(1,n));if(r)return ot(ue(e.objectControlledColor,"rgba(122, 240, 255, {alpha})"),o);const i=t.toLowerCase();return i.includes("raider")?ot(ue(e.objectRaiderColor,"rgba(255, 143, 74, {alpha})"),o):i.includes("neutral")?ot(ue(e.objectNeutralColor,"rgba(232, 232, 224, {alpha})"),o):ot(ue(e.objectDefaultColor,"rgba(214, 244, 255, {alpha})"),o)}function ot(e,t){return e.replaceAll("{alpha}",String(t))}function Va(e){return e.split(";").map(t=>t.trim()).filter(Boolean).map(t=>{const r=t.split("|");return{key:r[0]??"",kind:r[1]??"",x:Number(r[2])||0,y:Number(r[3])||0,radius:Math.max(1,Number(r[4])||1),depth:Number(r[5])||0,exponent:Number(r[6])||1,waveRadius:Number(r[7])||0,waveDepth:Number(r[8])||0,waveSpeed:Number(r[9])||0,icon:r[10]??"",iconSize:Number(r[12])||0,tint:r[11]??""}})}function Ka(e){return e.split(";").map(t=>t.trim()).filter(Boolean).map(t=>{const r=t.split("|");return{key:r[0]??"",kind:r[1]??"",label:r[2]??"",x:Number(r[3])||0,y:Number(r[4])||0,directionX:Number(r[5])||0,directionY:Number(r[6])||1,faction:r[7]??"",controlled:r[8]==="1"||r[8]==="true",visibility:Number(r[9])||1,icon:r[10]??""}})}function Ba(e){const t=Array.isArray(e?.gravityInfluences)?e.gravityInfluences:[],r=Array.isArray(e?.bodies)?e.bodies:[];if(t.length===0&&r.length===0)return;const n=new Map;for(const o of r){const i=ue(o.bodyKey,o.name,"");i&&n.set(i,o)}return(t.length>0?t:r).map(o=>{const i=ue(o.bodyKey,o.name,"body"),c=n.get(i),s=ue(o.kind,"Body");return{key:i,kind:s,x:oe(o.x,0),y:oe(o.y,0),radius:Math.max(1,oe(o.radius,80)),depth:oe(o.gravityDepth,0),exponent:oe(o.gravityDepthExponent,1),waveRadius:oe(o.waveRadius,0),waveDepth:oe(o.waveDepth,0),waveSpeed:oe(o.waveSpeed,0),icon:Mr(o.iconAsset)||Mr(c?.iconAsset),iconSize:oe(c?.iconSize,oe(o.iconSize,0)),tint:""}})}function Ha(e){const t=Array.isArray(e?.objects)?e.objects:[];if(t.length!==0)return t.map(r=>{const n=ue(r.kind,"object");return{key:ue(r.entityKey,String(r.entityIndex??""),"object"),kind:n,label:ue(r.displayName,r.entityKey,"object"),x:oe(r.x,0),y:oe(r.y,0),directionX:oe(r.directionX,1),directionY:oe(r.directionY,0),faction:ue(r.factionKey,""),controlled:oo(r.controlled),visibility:oe(r.visibility,1),icon:Mr(r.iconAsset)}})}function Mr(e){const t=Hi(e);return ue(t.uri,"")}function Ga(e){const t=Math.max(1,oe(e.viewRadius,Math.max(1200,oe(e.terrainRadius,1200))));return{minX:oe(e.minX,-t),minY:oe(e.minY,-t),maxX:oe(e.maxX,t),maxY:oe(e.maxY,t)}}function Wa(e,t,r){const n=Math.max(1e-4,e.maxX-e.minX),o=Math.max(1e-4,e.maxY-e.minY),i=Math.max(1e-4,t/Math.max(1,r)),c=n/o,s=(e.minX+e.maxX)*.5,d=(e.minY+e.maxY)*.5;if(i>c){const a=o*i;return{minX:s-a*.5,maxX:s+a*.5,minY:e.minY,maxY:e.maxY}}const u=n/i;return{minX:e.minX,maxX:e.maxX,minY:d-u*.5,maxY:d+u*.5}}function Bi(e,t,r,n,o){return{x:(t-e.minX)/Math.max(1,e.maxX-e.minX)*n,y:(r-e.minY)/Math.max(1,e.maxY-e.minY)*o}}function Xa(e){const t=$e(e[9]);return{schema:e[0],frameId:e[1],publishedAtUtc:e[2],simulationTimeSeconds:e[3],runId:e[4],zoneIndex:e[5],zoneName:e[6],viewport:Ur(e[7]),layers:$e(e[8]).map(Qa),splats:{count:t[0]??0,centerX:t[1]||[],centerY:t[2]||[],halfExtentX:t[3]||[],halfExtentY:t[4]||[],rotationCos:t[5]||[],rotationSin:t[6]||[],channel:t[7]||[],falloff:t[8]||[],valueR:t[9]||[],valueG:t[10]||[],valueB:t[11]||[],valueA:t[12]||[],sourceKey:t[13]||[],layerIndex:t[14]||[],sourceKind:t[15]||[],frequencyX:t[16]||[],frequencyY:t[17]||[],phaseX:t[18]||[],phaseY:t[19]||[],animationSpeed:t[20]||[],sourceFlags:t[21]||[]}}}function Ya(e){return{schema:e[0],frameId:e[1],publishedAtUtc:e[2],simulationTimeSeconds:e[3],runId:e[4],zoneIndex:e[5],zoneName:e[6],viewport:Ur(e[7]),gravityInfluences:$e(e[8]).map(Za),bodies:$e(e[9]).map(eo),terrainRadius:e[10],terrainDepth:e[11],terrainDepthExponent:e[12],terrainWaveFrequency:e[13]}}function Ja(e){return{schema:e[0],frameId:e[1],publishedAtUtc:e[2],simulationTimeSeconds:e[3],runId:e[4],zoneIndex:e[5],zoneName:e[6],currentEntityKey:e[7],viewport:Ur(e[8]),controlledEntityIndices:$e(e[9]),objects:$e(e[10]).map(to)}}function Ur(e){const t=$e(e);return t.length?{minX:t[0],minY:t[1],maxX:t[2],maxY:t[3]}:e}function Qa(e){const t=$e(e);return t.length?{layerKey:t[0],displayName:t[1],channel:t[2],blendMode:t[3],graphicsFormat:t[4],clearBeforeDraw:t[5],clearR:t[6],clearG:t[7],clearB:t[8],clearA:t[9]}:e}function Za(e){const t=$e(e);return t.length?{bodyKey:t[0],orbitKey:t[1],kind:t[2],x:t[3],y:t[4],radius:t[5],gravityDepth:t[6],gravityDepthExponent:t[7],waveRadius:t[8],waveDepth:t[9],waveSpeed:t[10]}:e}function eo(e){const t=$e(e);return t.length?{bodyKey:t[0],orbitKey:t[1],name:t[2],kind:t[3],x:t[4],y:t[5],radius:t[6],isAsteroidBelt:t[7],body:t[8],iconAsset:zr(t[9])}:e}function to(e){const t=$e(e);return t.length?{entityIndex:t[0],entityKey:t[1],displayName:t[2],kind:t[3],factionKey:t[4],x:t[5],y:t[6],z:t[7],directionX:t[8],directionY:t[9],velocityX:t[10],velocityY:t[11],controlled:t[12],targetEntityIndex:t[13],isActive:t[14],visibility:t[15],status:ro(t[16]),inventory:$e(t[17]).map(no),iconAsset:zr(t[18])}:e}function ro(e){const t=$e(e);return t.length?{hull:t[0],shield:t[1],heat:t[2]}:e||{}}function no(e){const t=$e(e);return t.length?{source:t[0],itemKey:t[1],quantity:t[2],quality:t[3],durability:t[4],enabled:t[5],sourceIndex:t[6],x:t[7],y:t[8],iconAsset:zr(t[9])}:e}function zr(e){const t=$e(e);return t.length?{assetKey:t[0],kind:t[1],uri:t[2],transport:t[3],contentHash:t[4],mimeType:t[5],metadata:t[6]||{}}:e||{}}function $e(e){return Array.isArray(e)?e:[]}function cr(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function ue(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function io(e,t){return typeof e=="string"&&e?e:t}function ao(e,t){const r=Number(e);return Number.isFinite(r)&&r>0?Math.floor(r):t}function qr(e,t){const r=Number(e);return Number.isFinite(r)?r:t}const Hi=cr,oe=qr;function oo(e){return typeof e=="boolean"?e:typeof e=="number"?e!==0:typeof e=="string"&&["1","true","yes","on"].includes(e.trim().toLowerCase())}function so(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var st={exports:{}},$r={},je={},Fe={},wr={},Sr={},Er={},an;function ur(){return an||(an=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.regexpCode=e.getEsmExportName=e.getProperty=e.safeStringify=e.stringify=e.strConcat=e.addCodeArg=e.str=e._=e.nil=e._Code=e.Name=e.IDENTIFIER=e._CodeOrName=void 0;class t{}e._CodeOrName=t,e.IDENTIFIER=/^[a-z$_][a-z$_0-9]*$/i;class r extends t{constructor(p){if(super(),!e.IDENTIFIER.test(p))throw new Error("CodeGen: name must be a valid identifier");this.str=p}toString(){return this.str}emptyStr(){return!1}get names(){return{[this.str]:1}}}e.Name=r;class n extends t{constructor(p){super(),this._items=typeof p=="string"?[p]:p}toString(){return this.str}emptyStr(){if(this._items.length>1)return!1;const p=this._items[0];return p===""||p==='""'}get str(){var p;return(p=this._str)!==null&&p!==void 0?p:this._str=this._items.reduce((w,E)=>`${w}${E}`,"")}get names(){var p;return(p=this._names)!==null&&p!==void 0?p:this._names=this._items.reduce((w,E)=>(E instanceof r&&(w[E.str]=(w[E.str]||0)+1),w),{})}}e._Code=n,e.nil=new n("");function o(_,...p){const w=[_[0]];let E=0;for(;E{if(f.scopePath===void 0)throw new Error(`CodeGen: name "${f}" has no value`);return(0,t._)`${u}${f.scopePath}`})}scopeCode(u=this._values,a,f){return this._reduceValues(u,m=>{if(m.value===void 0)throw new Error(`CodeGen: name "${m}" has no value`);return m.value.code},a,f)}_reduceValues(u,a,f={},m){let y=t.nil;for(const $ in u){const S=u[$];if(!S)continue;const g=f[$]=f[$]||new Map;S.forEach(_=>{if(g.has(_))return;g.set(_,n.Started);let p=a(_);if(p){const w=this.opts.es5?e.varKinds.var:e.varKinds.const;y=(0,t._)`${y}${w} ${_} = ${p};${this.opts._n}`}else if(p=m?.(_))y=(0,t._)`${y}${p}${this.opts._n}`;else throw new r(_);g.set(_,n.Completed)})}return y}}e.ValueScope=s})(Pr)),Pr}var cn;function W(){return cn||(cn=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.or=e.and=e.not=e.CodeGen=e.operators=e.varKinds=e.ValueScopeName=e.ValueScope=e.Scope=e.Name=e.regexpCode=e.stringify=e.getProperty=e.nil=e.strConcat=e.str=e._=void 0;const t=ur(),r=sn();var n=ur();Object.defineProperty(e,"_",{enumerable:!0,get:function(){return n._}}),Object.defineProperty(e,"str",{enumerable:!0,get:function(){return n.str}}),Object.defineProperty(e,"strConcat",{enumerable:!0,get:function(){return n.strConcat}}),Object.defineProperty(e,"nil",{enumerable:!0,get:function(){return n.nil}}),Object.defineProperty(e,"getProperty",{enumerable:!0,get:function(){return n.getProperty}}),Object.defineProperty(e,"stringify",{enumerable:!0,get:function(){return n.stringify}}),Object.defineProperty(e,"regexpCode",{enumerable:!0,get:function(){return n.regexpCode}}),Object.defineProperty(e,"Name",{enumerable:!0,get:function(){return n.Name}});var o=sn();Object.defineProperty(e,"Scope",{enumerable:!0,get:function(){return o.Scope}}),Object.defineProperty(e,"ValueScope",{enumerable:!0,get:function(){return o.ValueScope}}),Object.defineProperty(e,"ValueScopeName",{enumerable:!0,get:function(){return o.ValueScopeName}}),Object.defineProperty(e,"varKinds",{enumerable:!0,get:function(){return o.varKinds}}),e.operators={GT:new t._Code(">"),GTE:new t._Code(">="),LT:new t._Code("<"),LTE:new t._Code("<="),EQ:new t._Code("==="),NEQ:new t._Code("!=="),NOT:new t._Code("!"),OR:new t._Code("||"),AND:new t._Code("&&"),ADD:new t._Code("+")};class i{optimizeNodes(){return this}optimizeNames(b,P){return this}}class c extends i{constructor(b,P,q){super(),this.varKind=b,this.name=P,this.rhs=q}render({es5:b,_n:P}){const q=b?r.varKinds.var:this.varKind,B=this.rhs===void 0?"":` = ${this.rhs}`;return`${q} ${this.name}${B};`+P}optimizeNames(b,P){if(b[this.name.str])return this.rhs&&(this.rhs=z(this.rhs,b,P)),this}get names(){return this.rhs instanceof t._CodeOrName?this.rhs.names:{}}}class s extends i{constructor(b,P,q){super(),this.lhs=b,this.rhs=P,this.sideEffects=q}render({_n:b}){return`${this.lhs} = ${this.rhs};`+b}optimizeNames(b,P){if(!(this.lhs instanceof t.Name&&!b[this.lhs.str]&&!this.sideEffects))return this.rhs=z(this.rhs,b,P),this}get names(){const b=this.lhs instanceof t.Name?{}:{...this.lhs.names};return N(b,this.rhs)}}class d extends s{constructor(b,P,q,B){super(b,q,B),this.op=P}render({_n:b}){return`${this.lhs} ${this.op}= ${this.rhs};`+b}}class u extends i{constructor(b){super(),this.label=b,this.names={}}render({_n:b}){return`${this.label}:`+b}}class a extends i{constructor(b){super(),this.label=b,this.names={}}render({_n:b}){return`break${this.label?` ${this.label}`:""};`+b}}class f extends i{constructor(b){super(),this.error=b}render({_n:b}){return`throw ${this.error};`+b}get names(){return this.error.names}}class m extends i{constructor(b){super(),this.code=b}render({_n:b}){return`${this.code};`+b}optimizeNodes(){return`${this.code}`?this:void 0}optimizeNames(b,P){return this.code=z(this.code,b,P),this}get names(){return this.code instanceof t._CodeOrName?this.code.names:{}}}class y extends i{constructor(b=[]){super(),this.nodes=b}render(b){return this.nodes.reduce((P,q)=>P+q.render(b),"")}optimizeNodes(){const{nodes:b}=this;let P=b.length;for(;P--;){const q=b[P].optimizeNodes();Array.isArray(q)?b.splice(P,1,...q):q?b[P]=q:b.splice(P,1)}return b.length>0?this:void 0}optimizeNames(b,P){const{nodes:q}=this;let B=q.length;for(;B--;){const G=q[B];G.optimizeNames(b,P)||(ne(b,G.names),q.splice(B,1))}return q.length>0?this:void 0}get names(){return this.nodes.reduce((b,P)=>L(b,P.names),{})}}class $ extends y{render(b){return"{"+b._n+super.render(b)+"}"+b._n}}class S extends y{}class g extends ${}g.kind="else";class _ extends ${constructor(b,P){super(P),this.condition=b}render(b){let P=`if(${this.condition})`+super.render(b);return this.else&&(P+="else "+this.else.render(b)),P}optimizeNodes(){super.optimizeNodes();const b=this.condition;if(b===!0)return this.nodes;let P=this.else;if(P){const q=P.optimizeNodes();P=this.else=Array.isArray(q)?new g(q):q}if(P)return b===!1?P instanceof _?P:P.nodes:this.nodes.length?this:new _(fe(b),P instanceof _?[P]:P.nodes);if(!(b===!1||!this.nodes.length))return this}optimizeNames(b,P){var q;if(this.else=(q=this.else)===null||q===void 0?void 0:q.optimizeNames(b,P),!!(super.optimizeNames(b,P)||this.else))return this.condition=z(this.condition,b,P),this}get names(){const b=super.names;return N(b,this.condition),this.else&&L(b,this.else.names),b}}_.kind="if";class p extends ${}p.kind="for";class w extends p{constructor(b){super(),this.iteration=b}render(b){return`for(${this.iteration})`+super.render(b)}optimizeNames(b,P){if(super.optimizeNames(b,P))return this.iteration=z(this.iteration,b,P),this}get names(){return L(super.names,this.iteration.names)}}class E extends p{constructor(b,P,q,B){super(),this.varKind=b,this.name=P,this.from=q,this.to=B}render(b){const P=b.es5?r.varKinds.var:this.varKind,{name:q,from:B,to:G}=this;return`for(${P} ${q}=${B}; ${q}<${G}; ${q}++)`+super.render(b)}get names(){const b=N(super.names,this.from);return N(b,this.to)}}class l extends p{constructor(b,P,q,B){super(),this.loop=b,this.varKind=P,this.name=q,this.iterable=B}render(b){return`for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})`+super.render(b)}optimizeNames(b,P){if(super.optimizeNames(b,P))return this.iterable=z(this.iterable,b,P),this}get names(){return L(super.names,this.iterable.names)}}class h extends ${constructor(b,P,q){super(),this.name=b,this.args=P,this.async=q}render(b){return`${this.async?"async ":""}function ${this.name}(${this.args})`+super.render(b)}}h.kind="func";class v extends y{render(b){return"return "+super.render(b)}}v.kind="return";class I extends ${render(b){let P="try"+super.render(b);return this.catch&&(P+=this.catch.render(b)),this.finally&&(P+=this.finally.render(b)),P}optimizeNodes(){var b,P;return super.optimizeNodes(),(b=this.catch)===null||b===void 0||b.optimizeNodes(),(P=this.finally)===null||P===void 0||P.optimizeNodes(),this}optimizeNames(b,P){var q,B;return super.optimizeNames(b,P),(q=this.catch)===null||q===void 0||q.optimizeNames(b,P),(B=this.finally)===null||B===void 0||B.optimizeNames(b,P),this}get names(){const b=super.names;return this.catch&&L(b,this.catch.names),this.finally&&L(b,this.finally.names),b}}class O extends ${constructor(b){super(),this.error=b}render(b){return`catch(${this.error})`+super.render(b)}}O.kind="catch";class A extends ${render(b){return"finally"+super.render(b)}}A.kind="finally";class M{constructor(b,P={}){this._values={},this._blockStarts=[],this._constants={},this.opts={...P,_n:P.lines?` +`:""},this._extScope=b,this._scope=new r.Scope({parent:b}),this._nodes=[new S]}toString(){return this._root.render(this.opts)}name(b){return this._scope.name(b)}scopeName(b){return this._extScope.name(b)}scopeValue(b,P){const q=this._extScope.value(b,P);return(this._values[q.prefix]||(this._values[q.prefix]=new Set)).add(q),q}getScopeValue(b,P){return this._extScope.getValue(b,P)}scopeRefs(b){return this._extScope.scopeRefs(b,this._values)}scopeCode(){return this._extScope.scopeCode(this._values)}_def(b,P,q,B){const G=this._scope.toName(P);return q!==void 0&&B&&(this._constants[G.str]=q),this._leafNode(new c(b,G,q)),G}const(b,P,q){return this._def(r.varKinds.const,b,P,q)}let(b,P,q){return this._def(r.varKinds.let,b,P,q)}var(b,P,q){return this._def(r.varKinds.var,b,P,q)}assign(b,P,q){return this._leafNode(new s(b,P,q))}add(b,P){return this._leafNode(new d(b,e.operators.ADD,P))}code(b){return typeof b=="function"?b():b!==t.nil&&this._leafNode(new m(b)),this}object(...b){const P=["{"];for(const[q,B]of b)P.length>1&&P.push(","),P.push(q),(q!==B||this.opts.es5)&&(P.push(":"),(0,t.addCodeArg)(P,B));return P.push("}"),new t._Code(P)}if(b,P,q){if(this._blockNode(new _(b)),P&&q)this.code(P).else().code(q).endIf();else if(P)this.code(P).endIf();else if(q)throw new Error('CodeGen: "else" body without "then" body');return this}elseIf(b){return this._elseNode(new _(b))}else(){return this._elseNode(new g)}endIf(){return this._endBlockNode(_,g)}_for(b,P){return this._blockNode(b),P&&this.code(P).endFor(),this}for(b,P){return this._for(new w(b),P)}forRange(b,P,q,B,G=this.opts.es5?r.varKinds.var:r.varKinds.let){const ie=this._scope.toName(b);return this._for(new E(G,ie,P,q),()=>B(ie))}forOf(b,P,q,B=r.varKinds.const){const G=this._scope.toName(b);if(this.opts.es5){const ie=P instanceof t.Name?P:this.var("_arr",P);return this.forRange("_i",0,(0,t._)`${ie}.length`,ee=>{this.var(G,(0,t._)`${ie}[${ee}]`),q(G)})}return this._for(new l("of",B,G,P),()=>q(G))}forIn(b,P,q,B=this.opts.es5?r.varKinds.var:r.varKinds.const){if(this.opts.ownProperties)return this.forOf(b,(0,t._)`Object.keys(${P})`,q);const G=this._scope.toName(b);return this._for(new l("in",B,G,P),()=>q(G))}endFor(){return this._endBlockNode(p)}label(b){return this._leafNode(new u(b))}break(b){return this._leafNode(new a(b))}return(b){const P=new v;if(this._blockNode(P),this.code(b),P.nodes.length!==1)throw new Error('CodeGen: "return" should have one node');return this._endBlockNode(v)}try(b,P,q){if(!P&&!q)throw new Error('CodeGen: "try" without "catch" and "finally"');const B=new I;if(this._blockNode(B),this.code(b),P){const G=this.name("e");this._currNode=B.catch=new O(G),P(G)}return q&&(this._currNode=B.finally=new A,this.code(q)),this._endBlockNode(O,A)}throw(b){return this._leafNode(new f(b))}block(b,P){return this._blockStarts.push(this._nodes.length),b&&this.code(b).endBlock(P),this}endBlock(b){const P=this._blockStarts.pop();if(P===void 0)throw new Error("CodeGen: not in self-balancing block");const q=this._nodes.length-P;if(q<0||b!==void 0&&q!==b)throw new Error(`CodeGen: wrong number of nodes: ${q} vs ${b} expected`);return this._nodes.length=P,this}func(b,P=t.nil,q,B){return this._blockNode(new h(b,P,q)),B&&this.code(B).endFunc(),this}endFunc(){return this._endBlockNode(h)}optimize(b=1){for(;b-- >0;)this._root.optimizeNodes(),this._root.optimizeNames(this._root.names,this._constants)}_leafNode(b){return this._currNode.nodes.push(b),this}_blockNode(b){this._currNode.nodes.push(b),this._nodes.push(b)}_endBlockNode(b,P){const q=this._currNode;if(q instanceof b||P&&q instanceof P)return this._nodes.pop(),this;throw new Error(`CodeGen: not in block "${P?`${b.kind}/${P.kind}`:b.kind}"`)}_elseNode(b){const P=this._currNode;if(!(P instanceof _))throw new Error('CodeGen: "else" without "if"');return this._currNode=P.else=b,this}get _root(){return this._nodes[0]}get _currNode(){const b=this._nodes;return b[b.length-1]}set _currNode(b){const P=this._nodes;P[P.length-1]=b}}e.CodeGen=M;function L(T,b){for(const P in b)T[P]=(T[P]||0)+(b[P]||0);return T}function N(T,b){return b instanceof t._CodeOrName?L(T,b.names):T}function z(T,b,P){if(T instanceof t.Name)return q(T);if(!B(T))return T;return new t._Code(T._items.reduce((G,ie)=>(ie instanceof t.Name&&(ie=q(ie)),ie instanceof t._Code?G.push(...ie._items):G.push(ie),G),[]));function q(G){const ie=P[G.str];return ie===void 0||b[G.str]!==1?G:(delete b[G.str],ie)}function B(G){return G instanceof t._Code&&G._items.some(ie=>ie instanceof t.Name&&b[ie.str]===1&&P[ie.str]!==void 0)}}function ne(T,b){for(const P in b)T[P]=(T[P]||0)-(b[P]||0)}function fe(T){return typeof T=="boolean"||typeof T=="number"||T===null?!T:(0,t._)`!${F(T)}`}e.not=fe;const de=k(e.operators.AND);function X(...T){return T.reduce(de)}e.and=X;const we=k(e.operators.OR);function U(...T){return T.reduce(we)}e.or=U;function k(T){return(b,P)=>b===t.nil?P:P===t.nil?b:(0,t._)`${F(b)} ${T} ${F(P)}`}function F(T){return T instanceof t.Name?T:(0,t._)`(${T})`}})(Sr)),Sr}var Y={},un;function Z(){if(un)return Y;un=1,Object.defineProperty(Y,"__esModule",{value:!0}),Y.checkStrictMode=Y.getErrorPath=Y.Type=Y.useFunc=Y.setEvaluated=Y.evaluatedPropsToName=Y.mergeEvaluated=Y.eachItem=Y.unescapeJsonPointer=Y.escapeJsonPointer=Y.escapeFragment=Y.unescapeFragment=Y.schemaRefOrVal=Y.schemaHasRulesButRef=Y.schemaHasRules=Y.checkUnknownRules=Y.alwaysValidSchema=Y.toHash=void 0;const e=W(),t=ur();function r(l){const h={};for(const v of l)h[v]=!0;return h}Y.toHash=r;function n(l,h){return typeof h=="boolean"?h:Object.keys(h).length===0?!0:(o(l,h),!i(h,l.self.RULES.all))}Y.alwaysValidSchema=n;function o(l,h=l.schema){const{opts:v,self:I}=l;if(!v.strictSchema||typeof h=="boolean")return;const O=I.RULES.keywords;for(const A in h)O[A]||E(l,`unknown keyword: "${A}"`)}Y.checkUnknownRules=o;function i(l,h){if(typeof l=="boolean")return!l;for(const v in l)if(h[v])return!0;return!1}Y.schemaHasRules=i;function c(l,h){if(typeof l=="boolean")return!l;for(const v in l)if(v!=="$ref"&&h.all[v])return!0;return!1}Y.schemaHasRulesButRef=c;function s({topSchemaRef:l,schemaPath:h},v,I,O){if(!O){if(typeof v=="number"||typeof v=="boolean")return v;if(typeof v=="string")return(0,e._)`${v}`}return(0,e._)`${l}${h}${(0,e.getProperty)(I)}`}Y.schemaRefOrVal=s;function d(l){return f(decodeURIComponent(l))}Y.unescapeFragment=d;function u(l){return encodeURIComponent(a(l))}Y.escapeFragment=u;function a(l){return typeof l=="number"?`${l}`:l.replace(/~/g,"~0").replace(/\//g,"~1")}Y.escapeJsonPointer=a;function f(l){return l.replace(/~1/g,"/").replace(/~0/g,"~")}Y.unescapeJsonPointer=f;function m(l,h){if(Array.isArray(l))for(const v of l)h(v);else h(l)}Y.eachItem=m;function y({mergeNames:l,mergeToName:h,mergeValues:v,resultToName:I}){return(O,A,M,L)=>{const N=M===void 0?A:M instanceof e.Name?(A instanceof e.Name?l(O,A,M):h(O,A,M),M):A instanceof e.Name?(h(O,M,A),A):v(A,M);return L===e.Name&&!(N instanceof e.Name)?I(O,N):N}}Y.mergeEvaluated={props:y({mergeNames:(l,h,v)=>l.if((0,e._)`${v} !== true && ${h} !== undefined`,()=>{l.if((0,e._)`${h} === true`,()=>l.assign(v,!0),()=>l.assign(v,(0,e._)`${v} || {}`).code((0,e._)`Object.assign(${v}, ${h})`))}),mergeToName:(l,h,v)=>l.if((0,e._)`${v} !== true`,()=>{h===!0?l.assign(v,!0):(l.assign(v,(0,e._)`${v} || {}`),S(l,v,h))}),mergeValues:(l,h)=>l===!0?!0:{...l,...h},resultToName:$}),items:y({mergeNames:(l,h,v)=>l.if((0,e._)`${v} !== true && ${h} !== undefined`,()=>l.assign(v,(0,e._)`${h} === true ? true : ${v} > ${h} ? ${v} : ${h}`)),mergeToName:(l,h,v)=>l.if((0,e._)`${v} !== true`,()=>l.assign(v,h===!0?!0:(0,e._)`${v} > ${h} ? ${v} : ${h}`)),mergeValues:(l,h)=>l===!0?!0:Math.max(l,h),resultToName:(l,h)=>l.var("items",h)})};function $(l,h){if(h===!0)return l.var("props",!0);const v=l.var("props",(0,e._)`{}`);return h!==void 0&&S(l,v,h),v}Y.evaluatedPropsToName=$;function S(l,h,v){Object.keys(v).forEach(I=>l.assign((0,e._)`${h}${(0,e.getProperty)(I)}`,!0))}Y.setEvaluated=S;const g={};function _(l,h){return l.scopeValue("func",{ref:h,code:g[h.code]||(g[h.code]=new t._Code(h.code))})}Y.useFunc=_;var p;(function(l){l[l.Num=0]="Num",l[l.Str=1]="Str"})(p||(Y.Type=p={}));function w(l,h,v){if(l instanceof e.Name){const I=h===p.Num;return v?I?(0,e._)`"[" + ${l} + "]"`:(0,e._)`"['" + ${l} + "']"`:I?(0,e._)`"/" + ${l}`:(0,e._)`"/" + ${l}.replace(/~/g, "~0").replace(/\\//g, "~1")`}return v?(0,e.getProperty)(l).toString():"/"+a(l)}Y.getErrorPath=w;function E(l,h,v=l.opts.strictSchema){if(v){if(h=`strict mode: ${h}`,v===!0)throw new Error(h);l.self.logger.warn(h)}}return Y.checkStrictMode=E,Y}var ct={},dn;function Ce(){if(dn)return ct;dn=1,Object.defineProperty(ct,"__esModule",{value:!0});const e=W(),t={data:new e.Name("data"),valCxt:new e.Name("valCxt"),instancePath:new e.Name("instancePath"),parentData:new e.Name("parentData"),parentDataProperty:new e.Name("parentDataProperty"),rootData:new e.Name("rootData"),dynamicAnchors:new e.Name("dynamicAnchors"),vErrors:new e.Name("vErrors"),errors:new e.Name("errors"),this:new e.Name("this"),self:new e.Name("self"),scope:new e.Name("scope"),json:new e.Name("json"),jsonPos:new e.Name("jsonPos"),jsonLen:new e.Name("jsonLen"),jsonPart:new e.Name("jsonPart")};return ct.default=t,ct}var ln;function lr(){return ln||(ln=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.extendErrors=e.resetErrorsCount=e.reportExtraError=e.reportError=e.keyword$DataError=e.keywordError=void 0;const t=W(),r=Z(),n=Ce();e.keywordError={message:({keyword:g})=>(0,t.str)`must pass "${g}" keyword validation`},e.keyword$DataError={message:({keyword:g,schemaType:_})=>_?(0,t.str)`"${g}" keyword must be ${_} ($data)`:(0,t.str)`"${g}" keyword is invalid ($data)`};function o(g,_=e.keywordError,p,w){const{it:E}=g,{gen:l,compositeRule:h,allErrors:v}=E,I=f(g,_,p);w??(h||v)?d(l,I):u(E,(0,t._)`[${I}]`)}e.reportError=o;function i(g,_=e.keywordError,p){const{it:w}=g,{gen:E,compositeRule:l,allErrors:h}=w,v=f(g,_,p);d(E,v),l||h||u(w,n.default.vErrors)}e.reportExtraError=i;function c(g,_){g.assign(n.default.errors,_),g.if((0,t._)`${n.default.vErrors} !== null`,()=>g.if(_,()=>g.assign((0,t._)`${n.default.vErrors}.length`,_),()=>g.assign(n.default.vErrors,null)))}e.resetErrorsCount=c;function s({gen:g,keyword:_,schemaValue:p,data:w,errsCount:E,it:l}){if(E===void 0)throw new Error("ajv implementation error");const h=g.name("err");g.forRange("i",E,n.default.errors,v=>{g.const(h,(0,t._)`${n.default.vErrors}[${v}]`),g.if((0,t._)`${h}.instancePath === undefined`,()=>g.assign((0,t._)`${h}.instancePath`,(0,t.strConcat)(n.default.instancePath,l.errorPath))),g.assign((0,t._)`${h}.schemaPath`,(0,t.str)`${l.errSchemaPath}/${_}`),l.opts.verbose&&(g.assign((0,t._)`${h}.schema`,p),g.assign((0,t._)`${h}.data`,w))})}e.extendErrors=s;function d(g,_){const p=g.const("err",_);g.if((0,t._)`${n.default.vErrors} === null`,()=>g.assign(n.default.vErrors,(0,t._)`[${p}]`),(0,t._)`${n.default.vErrors}.push(${p})`),g.code((0,t._)`${n.default.errors}++`)}function u(g,_){const{gen:p,validateName:w,schemaEnv:E}=g;E.$async?p.throw((0,t._)`new ${g.ValidationError}(${_})`):(p.assign((0,t._)`${w}.errors`,_),p.return(!1))}const a={keyword:new t.Name("keyword"),schemaPath:new t.Name("schemaPath"),params:new t.Name("params"),propertyName:new t.Name("propertyName"),message:new t.Name("message"),schema:new t.Name("schema"),parentSchema:new t.Name("parentSchema")};function f(g,_,p){const{createErrors:w}=g.it;return w===!1?(0,t._)`{}`:m(g,_,p)}function m(g,_,p={}){const{gen:w,it:E}=g,l=[y(E,p),$(g,p)];return S(g,_,l),w.object(...l)}function y({errorPath:g},{instancePath:_}){const p=_?(0,t.str)`${g}${(0,r.getErrorPath)(_,r.Type.Str)}`:g;return[n.default.instancePath,(0,t.strConcat)(n.default.instancePath,p)]}function $({keyword:g,it:{errSchemaPath:_}},{schemaPath:p,parentSchema:w}){let E=w?_:(0,t.str)`${_}/${g}`;return p&&(E=(0,t.str)`${E}${(0,r.getErrorPath)(p,r.Type.Str)}`),[a.schemaPath,E]}function S(g,{params:_,message:p},w){const{keyword:E,data:l,schemaValue:h,it:v}=g,{opts:I,propertyName:O,topSchemaRef:A,schemaPath:M}=v;w.push([a.keyword,E],[a.params,typeof _=="function"?_(g):_||(0,t._)`{}`]),I.messages&&w.push([a.message,typeof p=="function"?p(g):p]),I.verbose&&w.push([a.schema,h],[a.parentSchema,(0,t._)`${A}${M}`],[n.default.data,l]),O&&w.push([a.propertyName,O])}})(wr)),wr}var fn;function co(){if(fn)return Fe;fn=1,Object.defineProperty(Fe,"__esModule",{value:!0}),Fe.boolOrEmptySchema=Fe.topBoolOrEmptySchema=void 0;const e=lr(),t=W(),r=Ce(),n={message:"boolean schema is false"};function o(s){const{gen:d,schema:u,validateName:a}=s;u===!1?c(s,!1):typeof u=="object"&&u.$async===!0?d.return(r.default.data):(d.assign((0,t._)`${a}.errors`,null),d.return(!0))}Fe.topBoolOrEmptySchema=o;function i(s,d){const{gen:u,schema:a}=s;a===!1?(u.var(d,!1),c(s)):u.var(d,!0)}Fe.boolOrEmptySchema=i;function c(s,d){const{gen:u,data:a}=s,f={gen:u,keyword:"false schema",data:a,schema:!1,schemaCode:!1,schemaValue:!1,params:{},it:s};(0,e.reportError)(f,n,void 0,d)}return Fe}var ge={},Ue={},mn;function Gi(){if(mn)return Ue;mn=1,Object.defineProperty(Ue,"__esModule",{value:!0}),Ue.getRules=Ue.isJSONType=void 0;const e=["string","number","integer","boolean","null","object","array"],t=new Set(e);function r(o){return typeof o=="string"&&t.has(o)}Ue.isJSONType=r;function n(){const o={number:{type:"number",rules:[]},string:{type:"string",rules:[]},array:{type:"array",rules:[]},object:{type:"object",rules:[]}};return{types:{...o,integer:!0,boolean:!0,null:!0},rules:[{rules:[]},o.number,o.string,o.array,o.object],post:{rules:[]},all:{},keywords:{}}}return Ue.getRules=n,Ue}var Oe={},pn;function Wi(){if(pn)return Oe;pn=1,Object.defineProperty(Oe,"__esModule",{value:!0}),Oe.shouldUseRule=Oe.shouldUseGroup=Oe.schemaHasRulesForType=void 0;function e({schema:n,self:o},i){const c=o.RULES.types[i];return c&&c!==!0&&t(n,c)}Oe.schemaHasRulesForType=e;function t(n,o){return o.rules.some(i=>r(n,i))}Oe.shouldUseGroup=t;function r(n,o){var i;return n[o.keyword]!==void 0||((i=o.definition.implements)===null||i===void 0?void 0:i.some(c=>n[c]!==void 0))}return Oe.shouldUseRule=r,Oe}var hn;function dr(){if(hn)return ge;hn=1,Object.defineProperty(ge,"__esModule",{value:!0}),ge.reportTypeError=ge.checkDataTypes=ge.checkDataType=ge.coerceAndCheckDataType=ge.getJSONTypes=ge.getSchemaTypes=ge.DataType=void 0;const e=Gi(),t=Wi(),r=lr(),n=W(),o=Z();var i;(function(p){p[p.Correct=0]="Correct",p[p.Wrong=1]="Wrong"})(i||(ge.DataType=i={}));function c(p){const w=s(p.type);if(w.includes("null")){if(p.nullable===!1)throw new Error("type: null contradicts nullable: false")}else{if(!w.length&&p.nullable!==void 0)throw new Error('"nullable" cannot be used without "type"');p.nullable===!0&&w.push("null")}return w}ge.getSchemaTypes=c;function s(p){const w=Array.isArray(p)?p:p?[p]:[];if(w.every(e.isJSONType))return w;throw new Error("type must be JSONType or JSONType[]: "+w.join(","))}ge.getJSONTypes=s;function d(p,w){const{gen:E,data:l,opts:h}=p,v=a(w,h.coerceTypes),I=w.length>0&&!(v.length===0&&w.length===1&&(0,t.schemaHasRulesForType)(p,w[0]));if(I){const O=$(w,l,h.strictNumbers,i.Wrong);E.if(O,()=>{v.length?f(p,w,v):g(p)})}return I}ge.coerceAndCheckDataType=d;const u=new Set(["string","number","integer","boolean","null"]);function a(p,w){return w?p.filter(E=>u.has(E)||w==="array"&&E==="array"):[]}function f(p,w,E){const{gen:l,data:h,opts:v}=p,I=l.let("dataType",(0,n._)`typeof ${h}`),O=l.let("coerced",(0,n._)`undefined`);v.coerceTypes==="array"&&l.if((0,n._)`${I} == 'object' && Array.isArray(${h}) && ${h}.length == 1`,()=>l.assign(h,(0,n._)`${h}[0]`).assign(I,(0,n._)`typeof ${h}`).if($(w,h,v.strictNumbers),()=>l.assign(O,h))),l.if((0,n._)`${O} !== undefined`);for(const M of E)(u.has(M)||M==="array"&&v.coerceTypes==="array")&&A(M);l.else(),g(p),l.endIf(),l.if((0,n._)`${O} !== undefined`,()=>{l.assign(h,O),m(p,O)});function A(M){switch(M){case"string":l.elseIf((0,n._)`${I} == "number" || ${I} == "boolean"`).assign(O,(0,n._)`"" + ${h}`).elseIf((0,n._)`${h} === null`).assign(O,(0,n._)`""`);return;case"number":l.elseIf((0,n._)`${I} == "boolean" || ${h} === null + || (${I} == "string" && ${h} && ${h} == +${h})`).assign(O,(0,n._)`+${h}`);return;case"integer":l.elseIf((0,n._)`${I} === "boolean" || ${h} === null + || (${I} === "string" && ${h} && ${h} == +${h} && !(${h} % 1))`).assign(O,(0,n._)`+${h}`);return;case"boolean":l.elseIf((0,n._)`${h} === "false" || ${h} === 0 || ${h} === null`).assign(O,!1).elseIf((0,n._)`${h} === "true" || ${h} === 1`).assign(O,!0);return;case"null":l.elseIf((0,n._)`${h} === "" || ${h} === 0 || ${h} === false`),l.assign(O,null);return;case"array":l.elseIf((0,n._)`${I} === "string" || ${I} === "number" + || ${I} === "boolean" || ${h} === null`).assign(O,(0,n._)`[${h}]`)}}}function m({gen:p,parentData:w,parentDataProperty:E},l){p.if((0,n._)`${w} !== undefined`,()=>p.assign((0,n._)`${w}[${E}]`,l))}function y(p,w,E,l=i.Correct){const h=l===i.Correct?n.operators.EQ:n.operators.NEQ;let v;switch(p){case"null":return(0,n._)`${w} ${h} null`;case"array":v=(0,n._)`Array.isArray(${w})`;break;case"object":v=(0,n._)`${w} && typeof ${w} == "object" && !Array.isArray(${w})`;break;case"integer":v=I((0,n._)`!(${w} % 1) && !isNaN(${w})`);break;case"number":v=I();break;default:return(0,n._)`typeof ${w} ${h} ${p}`}return l===i.Correct?v:(0,n.not)(v);function I(O=n.nil){return(0,n.and)((0,n._)`typeof ${w} == "number"`,O,E?(0,n._)`isFinite(${w})`:n.nil)}}ge.checkDataType=y;function $(p,w,E,l){if(p.length===1)return y(p[0],w,E,l);let h;const v=(0,o.toHash)(p);if(v.array&&v.object){const I=(0,n._)`typeof ${w} != "object"`;h=v.null?I:(0,n._)`!${w} || ${I}`,delete v.null,delete v.array,delete v.object}else h=n.nil;v.number&&delete v.integer;for(const I in v)h=(0,n.and)(h,y(I,w,E,l));return h}ge.checkDataTypes=$;const S={message:({schema:p})=>`must be ${p}`,params:({schema:p,schemaValue:w})=>typeof p=="string"?(0,n._)`{type: ${p}}`:(0,n._)`{type: ${w}}`};function g(p){const w=_(p);(0,r.reportError)(w,S)}ge.reportTypeError=g;function _(p){const{gen:w,data:E,schema:l}=p,h=(0,o.schemaRefOrVal)(p,l,"type");return{gen:w,keyword:"type",data:E,schema:l.type,schemaCode:h,schemaValue:h,parentSchema:l,params:{},it:p}}return ge}var et={},yn;function uo(){if(yn)return et;yn=1,Object.defineProperty(et,"__esModule",{value:!0}),et.assignDefaults=void 0;const e=W(),t=Z();function r(o,i){const{properties:c,items:s}=o.schema;if(i==="object"&&c)for(const d in c)n(o,d,c[d].default);else i==="array"&&Array.isArray(s)&&s.forEach((d,u)=>n(o,u,d.default))}et.assignDefaults=r;function n(o,i,c){const{gen:s,compositeRule:d,data:u,opts:a}=o;if(c===void 0)return;const f=(0,e._)`${u}${(0,e.getProperty)(i)}`;if(d){(0,t.checkStrictMode)(o,`default is ignored for: ${f}`);return}let m=(0,e._)`${f} === undefined`;a.useDefaults==="empty"&&(m=(0,e._)`${m} || ${f} === null || ${f} === ""`),s.if(m,(0,e._)`${f} = ${(0,e.stringify)(c)}`)}return et}var Ae={},ae={},gn;function Ne(){if(gn)return ae;gn=1,Object.defineProperty(ae,"__esModule",{value:!0}),ae.validateUnion=ae.validateArray=ae.usePattern=ae.callValidateCode=ae.schemaProperties=ae.allSchemaProperties=ae.noPropertyInData=ae.propertyInData=ae.isOwnProperty=ae.hasPropFunc=ae.reportMissingProp=ae.checkMissingProp=ae.checkReportMissingProp=void 0;const e=W(),t=Z(),r=Ce(),n=Z();function o(p,w){const{gen:E,data:l,it:h}=p;E.if(a(E,l,w,h.opts.ownProperties),()=>{p.setParams({missingProperty:(0,e._)`${w}`},!0),p.error()})}ae.checkReportMissingProp=o;function i({gen:p,data:w,it:{opts:E}},l,h){return(0,e.or)(...l.map(v=>(0,e.and)(a(p,w,v,E.ownProperties),(0,e._)`${h} = ${v}`)))}ae.checkMissingProp=i;function c(p,w){p.setParams({missingProperty:w},!0),p.error()}ae.reportMissingProp=c;function s(p){return p.scopeValue("func",{ref:Object.prototype.hasOwnProperty,code:(0,e._)`Object.prototype.hasOwnProperty`})}ae.hasPropFunc=s;function d(p,w,E){return(0,e._)`${s(p)}.call(${w}, ${E})`}ae.isOwnProperty=d;function u(p,w,E,l){const h=(0,e._)`${w}${(0,e.getProperty)(E)} !== undefined`;return l?(0,e._)`${h} && ${d(p,w,E)}`:h}ae.propertyInData=u;function a(p,w,E,l){const h=(0,e._)`${w}${(0,e.getProperty)(E)} === undefined`;return l?(0,e.or)(h,(0,e.not)(d(p,w,E))):h}ae.noPropertyInData=a;function f(p){return p?Object.keys(p).filter(w=>w!=="__proto__"):[]}ae.allSchemaProperties=f;function m(p,w){return f(w).filter(E=>!(0,t.alwaysValidSchema)(p,w[E]))}ae.schemaProperties=m;function y({schemaCode:p,data:w,it:{gen:E,topSchemaRef:l,schemaPath:h,errorPath:v},it:I},O,A,M){const L=M?(0,e._)`${p}, ${w}, ${l}${h}`:w,N=[[r.default.instancePath,(0,e.strConcat)(r.default.instancePath,v)],[r.default.parentData,I.parentData],[r.default.parentDataProperty,I.parentDataProperty],[r.default.rootData,r.default.rootData]];I.opts.dynamicRef&&N.push([r.default.dynamicAnchors,r.default.dynamicAnchors]);const z=(0,e._)`${L}, ${E.object(...N)}`;return A!==e.nil?(0,e._)`${O}.call(${A}, ${z})`:(0,e._)`${O}(${z})`}ae.callValidateCode=y;const $=(0,e._)`new RegExp`;function S({gen:p,it:{opts:w}},E){const l=w.unicodeRegExp?"u":"",{regExp:h}=w.code,v=h(E,l);return p.scopeValue("pattern",{key:v.toString(),ref:v,code:(0,e._)`${h.code==="new RegExp"?$:(0,n.useFunc)(p,h)}(${E}, ${l})`})}ae.usePattern=S;function g(p){const{gen:w,data:E,keyword:l,it:h}=p,v=w.name("valid");if(h.allErrors){const O=w.let("valid",!0);return I(()=>w.assign(O,!1)),O}return w.var(v,!0),I(()=>w.break()),v;function I(O){const A=w.const("len",(0,e._)`${E}.length`);w.forRange("i",0,A,M=>{p.subschema({keyword:l,dataProp:M,dataPropType:t.Type.Num},v),w.if((0,e.not)(v),O)})}}ae.validateArray=g;function _(p){const{gen:w,schema:E,keyword:l,it:h}=p;if(!Array.isArray(E))throw new Error("ajv implementation error");if(E.some(A=>(0,t.alwaysValidSchema)(h,A))&&!h.opts.unevaluated)return;const I=w.let("valid",!1),O=w.name("_valid");w.block(()=>E.forEach((A,M)=>{const L=p.subschema({keyword:l,schemaProp:M,compositeRule:!0},O);w.assign(I,(0,e._)`${I} || ${O}`),p.mergeValidEvaluated(L,O)||w.if((0,e.not)(I))})),p.result(I,()=>p.reset(),()=>p.error(!0))}return ae.validateUnion=_,ae}var vn;function lo(){if(vn)return Ae;vn=1,Object.defineProperty(Ae,"__esModule",{value:!0}),Ae.validateKeywordUsage=Ae.validSchemaType=Ae.funcKeywordCode=Ae.macroKeywordCode=void 0;const e=W(),t=Ce(),r=Ne(),n=lr();function o(m,y){const{gen:$,keyword:S,schema:g,parentSchema:_,it:p}=m,w=y.macro.call(p.self,g,_,p),E=u($,S,w);p.opts.validateSchema!==!1&&p.self.validateSchema(w,!0);const l=$.name("valid");m.subschema({schema:w,schemaPath:e.nil,errSchemaPath:`${p.errSchemaPath}/${S}`,topSchemaRef:E,compositeRule:!0},l),m.pass(l,()=>m.error(!0))}Ae.macroKeywordCode=o;function i(m,y){var $;const{gen:S,keyword:g,schema:_,parentSchema:p,$data:w,it:E}=m;d(E,y);const l=!w&&y.compile?y.compile.call(E.self,_,p,E):y.validate,h=u(S,g,l),v=S.let("valid");m.block$data(v,I),m.ok(($=y.valid)!==null&&$!==void 0?$:v);function I(){if(y.errors===!1)M(),y.modifying&&c(m),L(()=>m.error());else{const N=y.async?O():A();y.modifying&&c(m),L(()=>s(m,N))}}function O(){const N=S.let("ruleErrs",null);return S.try(()=>M((0,e._)`await `),z=>S.assign(v,!1).if((0,e._)`${z} instanceof ${E.ValidationError}`,()=>S.assign(N,(0,e._)`${z}.errors`),()=>S.throw(z))),N}function A(){const N=(0,e._)`${h}.errors`;return S.assign(N,null),M(e.nil),N}function M(N=y.async?(0,e._)`await `:e.nil){const z=E.opts.passContext?t.default.this:t.default.self,ne=!("compile"in y&&!w||y.schema===!1);S.assign(v,(0,e._)`${N}${(0,r.callValidateCode)(m,h,z,ne)}`,y.modifying)}function L(N){var z;S.if((0,e.not)((z=y.valid)!==null&&z!==void 0?z:v),N)}}Ae.funcKeywordCode=i;function c(m){const{gen:y,data:$,it:S}=m;y.if(S.parentData,()=>y.assign($,(0,e._)`${S.parentData}[${S.parentDataProperty}]`))}function s(m,y){const{gen:$}=m;$.if((0,e._)`Array.isArray(${y})`,()=>{$.assign(t.default.vErrors,(0,e._)`${t.default.vErrors} === null ? ${y} : ${t.default.vErrors}.concat(${y})`).assign(t.default.errors,(0,e._)`${t.default.vErrors}.length`),(0,n.extendErrors)(m)},()=>m.error())}function d({schemaEnv:m},y){if(y.async&&!m.$async)throw new Error("async keyword in sync schema")}function u(m,y,$){if($===void 0)throw new Error(`keyword "${y}" failed to compile`);return m.scopeValue("keyword",typeof $=="function"?{ref:$}:{ref:$,code:(0,e.stringify)($)})}function a(m,y,$=!1){return!y.length||y.some(S=>S==="array"?Array.isArray(m):S==="object"?m&&typeof m=="object"&&!Array.isArray(m):typeof m==S||$&&typeof m>"u")}Ae.validSchemaType=a;function f({schema:m,opts:y,self:$,errSchemaPath:S},g,_){if(Array.isArray(g.keyword)?!g.keyword.includes(_):g.keyword!==_)throw new Error("ajv implementation error");const p=g.dependencies;if(p?.some(w=>!Object.prototype.hasOwnProperty.call(m,w)))throw new Error(`parent schema must have dependencies of ${_}: ${p.join(",")}`);if(g.validateSchema&&!g.validateSchema(m[_])){const E=`keyword "${_}" value is invalid at path "${S}": `+$.errorsText(g.validateSchema.errors);if(y.validateSchema==="log")$.logger.error(E);else throw new Error(E)}}return Ae.validateKeywordUsage=f,Ae}var Me={},bn;function fo(){if(bn)return Me;bn=1,Object.defineProperty(Me,"__esModule",{value:!0}),Me.extendSubschemaMode=Me.extendSubschemaData=Me.getSubschema=void 0;const e=W(),t=Z();function r(i,{keyword:c,schemaProp:s,schema:d,schemaPath:u,errSchemaPath:a,topSchemaRef:f}){if(c!==void 0&&d!==void 0)throw new Error('both "keyword" and "schema" passed, only one allowed');if(c!==void 0){const m=i.schema[c];return s===void 0?{schema:m,schemaPath:(0,e._)`${i.schemaPath}${(0,e.getProperty)(c)}`,errSchemaPath:`${i.errSchemaPath}/${c}`}:{schema:m[s],schemaPath:(0,e._)`${i.schemaPath}${(0,e.getProperty)(c)}${(0,e.getProperty)(s)}`,errSchemaPath:`${i.errSchemaPath}/${c}/${(0,t.escapeFragment)(s)}`}}if(d!==void 0){if(u===void 0||a===void 0||f===void 0)throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"');return{schema:d,schemaPath:u,topSchemaRef:f,errSchemaPath:a}}throw new Error('either "keyword" or "schema" must be passed')}Me.getSubschema=r;function n(i,c,{dataProp:s,dataPropType:d,data:u,dataTypes:a,propertyName:f}){if(u!==void 0&&s!==void 0)throw new Error('both "data" and "dataProp" passed, only one allowed');const{gen:m}=c;if(s!==void 0){const{errorPath:$,dataPathArr:S,opts:g}=c,_=m.let("data",(0,e._)`${c.data}${(0,e.getProperty)(s)}`,!0);y(_),i.errorPath=(0,e.str)`${$}${(0,t.getErrorPath)(s,d,g.jsPropertySyntax)}`,i.parentDataProperty=(0,e._)`${s}`,i.dataPathArr=[...S,i.parentDataProperty]}if(u!==void 0){const $=u instanceof e.Name?u:m.let("data",u,!0);y($),f!==void 0&&(i.propertyName=f)}a&&(i.dataTypes=a);function y($){i.data=$,i.dataLevel=c.dataLevel+1,i.dataTypes=[],c.definedProperties=new Set,i.parentData=c.data,i.dataNames=[...c.dataNames,$]}}Me.extendSubschemaData=n;function o(i,{jtdDiscriminator:c,jtdMetadata:s,compositeRule:d,createErrors:u,allErrors:a}){d!==void 0&&(i.compositeRule=d),u!==void 0&&(i.createErrors=u),a!==void 0&&(i.allErrors=a),i.jtdDiscriminator=c,i.jtdMetadata=s}return Me.extendSubschemaMode=o,Me}var be={},Ir,_n;function Xi(){return _n||(_n=1,Ir=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var n,o,i;if(Array.isArray(t)){if(n=t.length,n!=r.length)return!1;for(o=n;o--!==0;)if(!e(t[o],r[o]))return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if(i=Object.keys(t),n=i.length,n!==Object.keys(r).length)return!1;for(o=n;o--!==0;)if(!Object.prototype.hasOwnProperty.call(r,i[o]))return!1;for(o=n;o--!==0;){var c=i[o];if(!e(t[c],r[c]))return!1}return!0}return t!==t&&r!==r}),Ir}var Rr={exports:{}},$n;function mo(){if($n)return Rr.exports;$n=1;var e=Rr.exports=function(n,o,i){typeof o=="function"&&(i=o,o={}),i=o.cb||i;var c=typeof i=="function"?i:i.pre||function(){},s=i.post||function(){};t(o,c,s,n,"",n)};e.keywords={additionalItems:!0,items:!0,contains:!0,additionalProperties:!0,propertyNames:!0,not:!0,if:!0,then:!0,else:!0},e.arrayKeywords={items:!0,allOf:!0,anyOf:!0,oneOf:!0},e.propsKeywords={$defs:!0,definitions:!0,properties:!0,patternProperties:!0,dependencies:!0},e.skipKeywords={default:!0,enum:!0,const:!0,required:!0,maximum:!0,minimum:!0,exclusiveMaximum:!0,exclusiveMinimum:!0,multipleOf:!0,maxLength:!0,minLength:!0,pattern:!0,format:!0,maxItems:!0,minItems:!0,uniqueItems:!0,maxProperties:!0,minProperties:!0};function t(n,o,i,c,s,d,u,a,f,m){if(c&&typeof c=="object"&&!Array.isArray(c)){o(c,s,d,u,a,f,m);for(var y in c){var $=c[y];if(Array.isArray($)){if(y in e.arrayKeywords)for(var S=0;S<$.length;S++)t(n,o,i,$[S],s+"/"+y+"/"+S,d,s,y,c,S)}else if(y in e.propsKeywords){if($&&typeof $=="object")for(var g in $)t(n,o,i,$[g],s+"/"+y+"/"+r(g),d,s,y,c,g)}else(y in e.keywords||n.allKeys&&!(y in e.skipKeywords))&&t(n,o,i,$,s+"/"+y,d,s,y,c)}i(c,s,d,u,a,f,m)}}function r(n){return n.replace(/~/g,"~0").replace(/\//g,"~1")}return Rr.exports}var wn;function fr(){if(wn)return be;wn=1,Object.defineProperty(be,"__esModule",{value:!0}),be.getSchemaRefs=be.resolveUrl=be.normalizeId=be._getFullPath=be.getFullPath=be.inlineRef=void 0;const e=Z(),t=Xi(),r=mo(),n=new Set(["type","format","pattern","maxLength","minLength","maxProperties","minProperties","maxItems","minItems","maximum","minimum","uniqueItems","multipleOf","required","enum","const"]);function o(S,g=!0){return typeof S=="boolean"?!0:g===!0?!c(S):g?s(S)<=g:!1}be.inlineRef=o;const i=new Set(["$ref","$recursiveRef","$recursiveAnchor","$dynamicRef","$dynamicAnchor"]);function c(S){for(const g in S){if(i.has(g))return!0;const _=S[g];if(Array.isArray(_)&&_.some(c)||typeof _=="object"&&c(_))return!0}return!1}function s(S){let g=0;for(const _ in S){if(_==="$ref")return 1/0;if(g++,!n.has(_)&&(typeof S[_]=="object"&&(0,e.eachItem)(S[_],p=>g+=s(p)),g===1/0))return 1/0}return g}function d(S,g="",_){_!==!1&&(g=f(g));const p=S.parse(g);return u(S,p)}be.getFullPath=d;function u(S,g){return S.serialize(g).split("#")[0]+"#"}be._getFullPath=u;const a=/#\/?$/;function f(S){return S?S.replace(a,""):""}be.normalizeId=f;function m(S,g,_){return _=f(_),S.resolve(g,_)}be.resolveUrl=m;const y=/^[a-z_][-a-z0-9._]*$/i;function $(S,g){if(typeof S=="boolean")return{};const{schemaId:_,uriResolver:p}=this.opts,w=f(S[_]||g),E={"":w},l=d(p,w,!1),h={},v=new Set;return r(S,{allKeys:!0},(A,M,L,N)=>{if(N===void 0)return;const z=l+M;let ne=E[N];typeof A[_]=="string"&&(ne=fe.call(this,A[_])),de.call(this,A.$anchor),de.call(this,A.$dynamicAnchor),E[M]=ne;function fe(X){const we=this.opts.uriResolver.resolve;if(X=f(ne?we(ne,X):X),v.has(X))throw O(X);v.add(X);let U=this.refs[X];return typeof U=="string"&&(U=this.refs[U]),typeof U=="object"?I(A,U.schema,X):X!==f(z)&&(X[0]==="#"?(I(A,h[X],X),h[X]=A):this.refs[X]=z),X}function de(X){if(typeof X=="string"){if(!y.test(X))throw new Error(`invalid anchor "${X}"`);fe.call(this,`#${X}`)}}}),h;function I(A,M,L){if(M!==void 0&&!t(A,M))throw O(L)}function O(A){return new Error(`reference "${A}" resolves to more than one schema`)}}return be.getSchemaRefs=$,be}var Sn;function mr(){if(Sn)return je;Sn=1,Object.defineProperty(je,"__esModule",{value:!0}),je.getData=je.KeywordCxt=je.validateFunctionCode=void 0;const e=co(),t=dr(),r=Wi(),n=dr(),o=uo(),i=lo(),c=fo(),s=W(),d=Ce(),u=fr(),a=Z(),f=lr();function m(R){if(l(R)&&(v(R),E(R))){g(R);return}y(R,()=>(0,e.topBoolOrEmptySchema)(R))}je.validateFunctionCode=m;function y({gen:R,validateName:C,schema:D,schemaEnv:V,opts:H},J){H.code.es5?R.func(C,(0,s._)`${d.default.data}, ${d.default.valCxt}`,V.$async,()=>{R.code((0,s._)`"use strict"; ${p(D,H)}`),S(R,H),R.code(J)}):R.func(C,(0,s._)`${d.default.data}, ${$(H)}`,V.$async,()=>R.code(p(D,H)).code(J))}function $(R){return(0,s._)`{${d.default.instancePath}="", ${d.default.parentData}, ${d.default.parentDataProperty}, ${d.default.rootData}=${d.default.data}${R.dynamicRef?(0,s._)`, ${d.default.dynamicAnchors}={}`:s.nil}}={}`}function S(R,C){R.if(d.default.valCxt,()=>{R.var(d.default.instancePath,(0,s._)`${d.default.valCxt}.${d.default.instancePath}`),R.var(d.default.parentData,(0,s._)`${d.default.valCxt}.${d.default.parentData}`),R.var(d.default.parentDataProperty,(0,s._)`${d.default.valCxt}.${d.default.parentDataProperty}`),R.var(d.default.rootData,(0,s._)`${d.default.valCxt}.${d.default.rootData}`),C.dynamicRef&&R.var(d.default.dynamicAnchors,(0,s._)`${d.default.valCxt}.${d.default.dynamicAnchors}`)},()=>{R.var(d.default.instancePath,(0,s._)`""`),R.var(d.default.parentData,(0,s._)`undefined`),R.var(d.default.parentDataProperty,(0,s._)`undefined`),R.var(d.default.rootData,d.default.data),C.dynamicRef&&R.var(d.default.dynamicAnchors,(0,s._)`{}`)})}function g(R){const{schema:C,opts:D,gen:V}=R;y(R,()=>{D.$comment&&C.$comment&&N(R),A(R),V.let(d.default.vErrors,null),V.let(d.default.errors,0),D.unevaluated&&_(R),I(R),z(R)})}function _(R){const{gen:C,validateName:D}=R;R.evaluated=C.const("evaluated",(0,s._)`${D}.evaluated`),C.if((0,s._)`${R.evaluated}.dynamicProps`,()=>C.assign((0,s._)`${R.evaluated}.props`,(0,s._)`undefined`)),C.if((0,s._)`${R.evaluated}.dynamicItems`,()=>C.assign((0,s._)`${R.evaluated}.items`,(0,s._)`undefined`))}function p(R,C){const D=typeof R=="object"&&R[C.schemaId];return D&&(C.code.source||C.code.process)?(0,s._)`/*# sourceURL=${D} */`:s.nil}function w(R,C){if(l(R)&&(v(R),E(R))){h(R,C);return}(0,e.boolOrEmptySchema)(R,C)}function E({schema:R,self:C}){if(typeof R=="boolean")return!R;for(const D in R)if(C.RULES.all[D])return!0;return!1}function l(R){return typeof R.schema!="boolean"}function h(R,C){const{schema:D,gen:V,opts:H}=R;H.$comment&&D.$comment&&N(R),M(R),L(R);const J=V.const("_errs",d.default.errors);I(R,J),V.var(C,(0,s._)`${J} === ${d.default.errors}`)}function v(R){(0,a.checkUnknownRules)(R),O(R)}function I(R,C){if(R.opts.jtd)return fe(R,[],!1,C);const D=(0,t.getSchemaTypes)(R.schema),V=(0,t.coerceAndCheckDataType)(R,D);fe(R,D,!V,C)}function O(R){const{schema:C,errSchemaPath:D,opts:V,self:H}=R;C.$ref&&V.ignoreKeywordsWithRef&&(0,a.schemaHasRulesButRef)(C,H.RULES)&&H.logger.warn(`$ref: keywords ignored in schema at path "${D}"`)}function A(R){const{schema:C,opts:D}=R;C.default!==void 0&&D.useDefaults&&D.strictSchema&&(0,a.checkStrictMode)(R,"default is ignored in the schema root")}function M(R){const C=R.schema[R.opts.schemaId];C&&(R.baseId=(0,u.resolveUrl)(R.opts.uriResolver,R.baseId,C))}function L(R){if(R.schema.$async&&!R.schemaEnv.$async)throw new Error("async schema in sync schema")}function N({gen:R,schemaEnv:C,schema:D,errSchemaPath:V,opts:H}){const J=D.$comment;if(H.$comment===!0)R.code((0,s._)`${d.default.self}.logger.log(${J})`);else if(typeof H.$comment=="function"){const pe=(0,s.str)`${V}/$comment`,Re=R.scopeValue("root",{ref:C.root});R.code((0,s._)`${d.default.self}.opts.$comment(${J}, ${pe}, ${Re}.schema)`)}}function z(R){const{gen:C,schemaEnv:D,validateName:V,ValidationError:H,opts:J}=R;D.$async?C.if((0,s._)`${d.default.errors} === 0`,()=>C.return(d.default.data),()=>C.throw((0,s._)`new ${H}(${d.default.vErrors})`)):(C.assign((0,s._)`${V}.errors`,d.default.vErrors),J.unevaluated&&ne(R),C.return((0,s._)`${d.default.errors} === 0`))}function ne({gen:R,evaluated:C,props:D,items:V}){D instanceof s.Name&&R.assign((0,s._)`${C}.props`,D),V instanceof s.Name&&R.assign((0,s._)`${C}.items`,V)}function fe(R,C,D,V){const{gen:H,schema:J,data:pe,allErrors:Re,opts:Se,self:Ee}=R,{RULES:he}=Ee;if(J.$ref&&(Se.ignoreKeywordsWithRef||!(0,a.schemaHasRulesButRef)(J,he))){H.block(()=>B(R,"$ref",he.all.$ref.definition));return}Se.jtd||X(R,C),H.block(()=>{for(const Ie of he.rules)He(Ie);He(he.post)});function He(Ie){(0,r.shouldUseGroup)(J,Ie)&&(Ie.type?(H.if((0,n.checkDataType)(Ie.type,pe,Se.strictNumbers)),de(R,Ie),C.length===1&&C[0]===Ie.type&&D&&(H.else(),(0,n.reportTypeError)(R)),H.endIf()):de(R,Ie),Re||H.if((0,s._)`${d.default.errors} === ${V||0}`))}}function de(R,C){const{gen:D,schema:V,opts:{useDefaults:H}}=R;H&&(0,o.assignDefaults)(R,C.type),D.block(()=>{for(const J of C.rules)(0,r.shouldUseRule)(V,J)&&B(R,J.keyword,J.definition,C.type)})}function X(R,C){R.schemaEnv.meta||!R.opts.strictTypes||(we(R,C),R.opts.allowUnionTypes||U(R,C),k(R,R.dataTypes))}function we(R,C){if(C.length){if(!R.dataTypes.length){R.dataTypes=C;return}C.forEach(D=>{T(R.dataTypes,D)||P(R,`type "${D}" not allowed by context "${R.dataTypes.join(",")}"`)}),b(R,C)}}function U(R,C){C.length>1&&!(C.length===2&&C.includes("null"))&&P(R,"use allowUnionTypes to allow union type keyword")}function k(R,C){const D=R.self.RULES.all;for(const V in D){const H=D[V];if(typeof H=="object"&&(0,r.shouldUseRule)(R.schema,H)){const{type:J}=H.definition;J.length&&!J.some(pe=>F(C,pe))&&P(R,`missing type "${J.join(",")}" for keyword "${V}"`)}}}function F(R,C){return R.includes(C)||C==="number"&&R.includes("integer")}function T(R,C){return R.includes(C)||C==="integer"&&R.includes("number")}function b(R,C){const D=[];for(const V of R.dataTypes)T(C,V)?D.push(V):C.includes("integer")&&V==="number"&&D.push("integer");R.dataTypes=D}function P(R,C){const D=R.schemaEnv.baseId+R.errSchemaPath;C+=` at "${D}" (strictTypes)`,(0,a.checkStrictMode)(R,C,R.opts.strictTypes)}class q{constructor(C,D,V){if((0,i.validateKeywordUsage)(C,D,V),this.gen=C.gen,this.allErrors=C.allErrors,this.keyword=V,this.data=C.data,this.schema=C.schema[V],this.$data=D.$data&&C.opts.$data&&this.schema&&this.schema.$data,this.schemaValue=(0,a.schemaRefOrVal)(C,this.schema,V,this.$data),this.schemaType=D.schemaType,this.parentSchema=C.schema,this.params={},this.it=C,this.def=D,this.$data)this.schemaCode=C.gen.const("vSchema",ee(this.$data,C));else if(this.schemaCode=this.schemaValue,!(0,i.validSchemaType)(this.schema,D.schemaType,D.allowUndefined))throw new Error(`${V} value must be ${JSON.stringify(D.schemaType)}`);("code"in D?D.trackErrors:D.errors!==!1)&&(this.errsCount=C.gen.const("_errs",d.default.errors))}result(C,D,V){this.failResult((0,s.not)(C),D,V)}failResult(C,D,V){this.gen.if(C),V?V():this.error(),D?(this.gen.else(),D(),this.allErrors&&this.gen.endIf()):this.allErrors?this.gen.endIf():this.gen.else()}pass(C,D){this.failResult((0,s.not)(C),void 0,D)}fail(C){if(C===void 0){this.error(),this.allErrors||this.gen.if(!1);return}this.gen.if(C),this.error(),this.allErrors?this.gen.endIf():this.gen.else()}fail$data(C){if(!this.$data)return this.fail(C);const{schemaCode:D}=this;this.fail((0,s._)`${D} !== undefined && (${(0,s.or)(this.invalid$data(),C)})`)}error(C,D,V){if(D){this.setParams(D),this._error(C,V),this.setParams({});return}this._error(C,V)}_error(C,D){(C?f.reportExtraError:f.reportError)(this,this.def.error,D)}$dataError(){(0,f.reportError)(this,this.def.$dataError||f.keyword$DataError)}reset(){if(this.errsCount===void 0)throw new Error('add "trackErrors" to keyword definition');(0,f.resetErrorsCount)(this.gen,this.errsCount)}ok(C){this.allErrors||this.gen.if(C)}setParams(C,D){D?Object.assign(this.params,C):this.params=C}block$data(C,D,V=s.nil){this.gen.block(()=>{this.check$data(C,V),D()})}check$data(C=s.nil,D=s.nil){if(!this.$data)return;const{gen:V,schemaCode:H,schemaType:J,def:pe}=this;V.if((0,s.or)((0,s._)`${H} === undefined`,D)),C!==s.nil&&V.assign(C,!0),(J.length||pe.validateSchema)&&(V.elseIf(this.invalid$data()),this.$dataError(),C!==s.nil&&V.assign(C,!1)),V.else()}invalid$data(){const{gen:C,schemaCode:D,schemaType:V,def:H,it:J}=this;return(0,s.or)(pe(),Re());function pe(){if(V.length){if(!(D instanceof s.Name))throw new Error("ajv implementation error");const Se=Array.isArray(V)?V:[V];return(0,s._)`${(0,n.checkDataTypes)(Se,D,J.opts.strictNumbers,n.DataType.Wrong)}`}return s.nil}function Re(){if(H.validateSchema){const Se=C.scopeValue("validate$data",{ref:H.validateSchema});return(0,s._)`!${Se}(${D})`}return s.nil}}subschema(C,D){const V=(0,c.getSubschema)(this.it,C);(0,c.extendSubschemaData)(V,this.it,C),(0,c.extendSubschemaMode)(V,C);const H={...this.it,...V,items:void 0,props:void 0};return w(H,D),H}mergeEvaluated(C,D){const{it:V,gen:H}=this;V.opts.unevaluated&&(V.props!==!0&&C.props!==void 0&&(V.props=a.mergeEvaluated.props(H,C.props,V.props,D)),V.items!==!0&&C.items!==void 0&&(V.items=a.mergeEvaluated.items(H,C.items,V.items,D)))}mergeValidEvaluated(C,D){const{it:V,gen:H}=this;if(V.opts.unevaluated&&(V.props!==!0||V.items!==!0))return H.if(D,()=>this.mergeEvaluated(C,s.Name)),!0}}je.KeywordCxt=q;function B(R,C,D,V){const H=new q(R,D,C);"code"in D?D.code(H,V):H.$data&&D.validate?(0,i.funcKeywordCode)(H,D):"macro"in D?(0,i.macroKeywordCode)(H,D):(D.compile||D.validate)&&(0,i.funcKeywordCode)(H,D)}const G=/^\/(?:[^~]|~0|~1)*$/,ie=/^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;function ee(R,{dataLevel:C,dataNames:D,dataPathArr:V}){let H,J;if(R==="")return d.default.rootData;if(R[0]==="/"){if(!G.test(R))throw new Error(`Invalid JSON-pointer: ${R}`);H=R,J=d.default.rootData}else{const Ee=ie.exec(R);if(!Ee)throw new Error(`Invalid JSON-pointer: ${R}`);const he=+Ee[1];if(H=Ee[2],H==="#"){if(he>=C)throw new Error(Se("property/index",he));return V[C-he]}if(he>C)throw new Error(Se("data",he));if(J=D[C-he],!H)return J}let pe=J;const Re=H.split("/");for(const Ee of Re)Ee&&(J=(0,s._)`${J}${(0,s.getProperty)((0,a.unescapeJsonPointer)(Ee))}`,pe=(0,s._)`${pe} && ${J}`);return pe;function Se(Ee,he){return`Cannot access ${Ee} ${he} levels up, current level is ${C}`}}return je.getData=ee,je}var ut={},En;function Vr(){if(En)return ut;En=1,Object.defineProperty(ut,"__esModule",{value:!0});class e extends Error{constructor(r){super("validation failed"),this.errors=r,this.ajv=this.validation=!0}}return ut.default=e,ut}var dt={},Pn;function pr(){if(Pn)return dt;Pn=1,Object.defineProperty(dt,"__esModule",{value:!0});const e=fr();class t extends Error{constructor(n,o,i,c){super(c||`can't resolve reference ${i} from id ${o}`),this.missingRef=(0,e.resolveUrl)(n,o,i),this.missingSchema=(0,e.normalizeId)((0,e.getFullPath)(n,this.missingRef))}}return dt.default=t,dt}var Pe={},In;function hr(){if(In)return Pe;In=1,Object.defineProperty(Pe,"__esModule",{value:!0}),Pe.resolveSchema=Pe.getCompilingSchema=Pe.resolveRef=Pe.compileSchema=Pe.SchemaEnv=void 0;const e=W(),t=Vr(),r=Ce(),n=fr(),o=Z(),i=mr();class c{constructor(_){var p;this.refs={},this.dynamicAnchors={};let w;typeof _.schema=="object"&&(w=_.schema),this.schema=_.schema,this.schemaId=_.schemaId,this.root=_.root||this,this.baseId=(p=_.baseId)!==null&&p!==void 0?p:(0,n.normalizeId)(w?.[_.schemaId||"$id"]),this.schemaPath=_.schemaPath,this.localRefs=_.localRefs,this.meta=_.meta,this.$async=w?.$async,this.refs={}}}Pe.SchemaEnv=c;function s(g){const _=a.call(this,g);if(_)return _;const p=(0,n.getFullPath)(this.opts.uriResolver,g.root.baseId),{es5:w,lines:E}=this.opts.code,{ownProperties:l}=this.opts,h=new e.CodeGen(this.scope,{es5:w,lines:E,ownProperties:l});let v;g.$async&&(v=h.scopeValue("Error",{ref:t.default,code:(0,e._)`require("ajv/dist/runtime/validation_error").default`}));const I=h.scopeName("validate");g.validateName=I;const O={gen:h,allErrors:this.opts.allErrors,data:r.default.data,parentData:r.default.parentData,parentDataProperty:r.default.parentDataProperty,dataNames:[r.default.data],dataPathArr:[e.nil],dataLevel:0,dataTypes:[],definedProperties:new Set,topSchemaRef:h.scopeValue("schema",this.opts.code.source===!0?{ref:g.schema,code:(0,e.stringify)(g.schema)}:{ref:g.schema}),validateName:I,ValidationError:v,schema:g.schema,schemaEnv:g,rootId:p,baseId:g.baseId||p,schemaPath:e.nil,errSchemaPath:g.schemaPath||(this.opts.jtd?"":"#"),errorPath:(0,e._)`""`,opts:this.opts,self:this};let A;try{this._compilations.add(g),(0,i.validateFunctionCode)(O),h.optimize(this.opts.code.optimize);const M=h.toString();A=`${h.scopeRefs(r.default.scope)}return ${M}`,this.opts.code.process&&(A=this.opts.code.process(A,g));const N=new Function(`${r.default.self}`,`${r.default.scope}`,A)(this,this.scope.get());if(this.scope.value(I,{ref:N}),N.errors=null,N.schema=g.schema,N.schemaEnv=g,g.$async&&(N.$async=!0),this.opts.code.source===!0&&(N.source={validateName:I,validateCode:M,scopeValues:h._values}),this.opts.unevaluated){const{props:z,items:ne}=O;N.evaluated={props:z instanceof e.Name?void 0:z,items:ne instanceof e.Name?void 0:ne,dynamicProps:z instanceof e.Name,dynamicItems:ne instanceof e.Name},N.source&&(N.source.evaluated=(0,e.stringify)(N.evaluated))}return g.validate=N,g}catch(M){throw delete g.validate,delete g.validateName,A&&this.logger.error("Error compiling schema, function code:",A),M}finally{this._compilations.delete(g)}}Pe.compileSchema=s;function d(g,_,p){var w;p=(0,n.resolveUrl)(this.opts.uriResolver,_,p);const E=g.refs[p];if(E)return E;let l=m.call(this,g,p);if(l===void 0){const h=(w=g.localRefs)===null||w===void 0?void 0:w[p],{schemaId:v}=this.opts;h&&(l=new c({schema:h,schemaId:v,root:g,baseId:_}))}if(l!==void 0)return g.refs[p]=u.call(this,l)}Pe.resolveRef=d;function u(g){return(0,n.inlineRef)(g.schema,this.opts.inlineRefs)?g.schema:g.validate?g:s.call(this,g)}function a(g){for(const _ of this._compilations)if(f(_,g))return _}Pe.getCompilingSchema=a;function f(g,_){return g.schema===_.schema&&g.root===_.root&&g.baseId===_.baseId}function m(g,_){let p;for(;typeof(p=this.refs[_])=="string";)_=p;return p||this.schemas[_]||y.call(this,g,_)}function y(g,_){const p=this.opts.uriResolver.parse(_),w=(0,n._getFullPath)(this.opts.uriResolver,p);let E=(0,n.getFullPath)(this.opts.uriResolver,g.baseId,void 0);if(Object.keys(g.schema).length>0&&w===E)return S.call(this,p,g);const l=(0,n.normalizeId)(w),h=this.refs[l]||this.schemas[l];if(typeof h=="string"){const v=y.call(this,g,h);return typeof v?.schema!="object"?void 0:S.call(this,p,v)}if(typeof h?.schema=="object"){if(h.validate||s.call(this,h),l===(0,n.normalizeId)(_)){const{schema:v}=h,{schemaId:I}=this.opts,O=v[I];return O&&(E=(0,n.resolveUrl)(this.opts.uriResolver,E,O)),new c({schema:v,schemaId:I,root:g,baseId:E})}return S.call(this,p,h)}}Pe.resolveSchema=y;const $=new Set(["properties","patternProperties","enum","dependencies","definitions"]);function S(g,{baseId:_,schema:p,root:w}){var E;if(((E=g.fragment)===null||E===void 0?void 0:E[0])!=="/")return;for(const v of g.fragment.slice(1).split("/")){if(typeof p=="boolean")return;const I=p[(0,o.unescapeFragment)(v)];if(I===void 0)return;p=I;const O=typeof p=="object"&&p[this.opts.schemaId];!$.has(v)&&O&&(_=(0,n.resolveUrl)(this.opts.uriResolver,_,O))}let l;if(typeof p!="boolean"&&p.$ref&&!(0,o.schemaHasRulesButRef)(p,this.RULES)){const v=(0,n.resolveUrl)(this.opts.uriResolver,_,p.$ref);l=y.call(this,w,v)}const{schemaId:h}=this.opts;if(l=l||new c({schema:p,schemaId:h,root:w,baseId:_}),l.schema!==l.root.schema)return l}return Pe}const po="https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",ho="Meta-schema for $data reference (JSON AnySchema extension proposal)",yo="object",go=["$data"],vo={$data:{type:"string",anyOf:[{format:"relative-json-pointer"},{format:"json-pointer"}]}},bo=!1,_o={$id:po,description:ho,type:yo,required:go,properties:vo,additionalProperties:bo};var lt={},tt={exports:{}},Ar,Rn;function Yi(){if(Rn)return Ar;Rn=1;const e=RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu),t=RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u),r=RegExp.prototype.test.bind(/^[\da-f]{2}$/iu),n=RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu),o=RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);function i(l){let h="",v=0,I=0;for(I=0;I=48&&v<=57||v>=65&&v<=70||v>=97&&v<=102))return"";h+=l[I];break}for(I+=1;I=48&&v<=57||v>=65&&v<=70||v>=97&&v<=102))return"";h+=l[I]}return h}const c=RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);function s(l){return l.length=0,!0}function d(l,h,v){if(l.length){const I=i(l);if(I!=="")h.push(I);else return v.error=!0,!1;l.length=0}return!0}function u(l){let h=0;const v={error:!1,address:"",zone:""},I=[],O=[];let A=!1,M=!1,L=d;for(let N=0;N7){v.error=!0;break}N>0&&l[N-1]===":"&&(A=!0),I.push(":");continue}else if(z==="%"){if(!L(O,I,v))break;L=s}else{O.push(z);continue}}return O.length&&(L===s?v.zone=O.join(""):M?I.push(O.join("")):I.push(i(O))),v.address=I.join(""),v}function a(l){if(f(l,":")<2)return{host:l,isIPV6:!1};const h=u(l);if(h.error)return{host:l,isIPV6:!1};{let v=h.address,I=h.address;return h.zone&&(v+="%"+h.zone,I+="%25"+h.zone),{host:v,isIPV6:!0,escapedHost:I}}}function f(l,h){let v=0;for(let I=0;Iy[I])}function _(l,h=!1){if(l.indexOf("%")===-1)return l;let v="";for(let I=0;I65535))return"URI port is malformed."}function E(A,M){const L=Object.assign({},M),N={scheme:void 0,userinfo:void 0,host:"",port:void 0,path:"",query:void 0,fragment:void 0};let z=!1,ne=!1;L.reference==="suffix"&&(L.scheme?A=L.scheme+":"+A:A="//"+A);const fe=A.match(_);fe!==null&&fe[1].indexOf("\\")!==-1&&(N.error="URI authority must not contain a literal backslash.",z=!0);const de=A.match(p);if(de!==null){const we=de[1],U=we.replace(/[\t\n\r]/g,"");U.length>=2&&(U.slice(0,2)!=="//"?(N.error=N.error||"URI authority must not contain a literal backslash.",z=!0):we.length!==U.length&&(N.error=N.error||"URI authority introducer must not contain whitespace.",z=!0))}const X=A.match(g);if(X){N.scheme=X[1],N.userinfo=X[3],N.host=X[4],N.port=parseInt(X[5],10),N.path=X[6]||"",N.query=X[7],N.fragment=X[8],isNaN(N.port)&&(N.port=X[5]);const we=w(N,X);if(we!==void 0&&(N.error=N.error||we,z=!0),N.host)if(s(N.host)===!1){const F=e(N.host);N.host=F.host.toLowerCase(),ne=F.isIPV6}else ne=!0;N.scheme===void 0&&N.userinfo===void 0&&N.host===void 0&&N.port===void 0&&N.query===void 0&&!N.path?N.reference="same-document":N.scheme===void 0?N.reference="relative":N.fragment===void 0?N.reference="absolute":N.reference="uri",L.reference&&L.reference!=="suffix"&&L.reference!==N.reference&&(N.error=N.error||"URI is not a "+L.reference+" reference.");const U=a(L.scheme||N.scheme);if(!L.unicodeSupport&&(!U||!U.unicodeSupport)&&N.host&&(L.domainHost||U&&U.domainHost)&&ne===!1&&d(N.host))try{N.host=new URL("http://"+N.host).hostname}catch(k){N.error=N.error||"Host's domain name can not be converted to ASCII: "+k}if((!U||U&&!U.skipNormalize)&&(A.indexOf("%")!==-1&&(N.scheme!==void 0&&(N.scheme=unescape(N.scheme)),N.host!==void 0&&(N.host=c(unescape(N.host),ne))),N.path&&(N.path=o(N.path)),N.fragment))try{N.fragment=encodeURI(decodeURIComponent(N.fragment))}catch{N.error=N.error||"URI malformed"}U&&U.parse&&U.parse(N,L)}else N.error=N.error||"URI can not be parsed.";return{parsed:N,malformedAuthorityOrPort:z}}function l(A,M){return E(A,M).parsed}function h(A,M){return v(A,M).normalized}function v(A,M){const{parsed:L,malformedAuthorityOrPort:N}=E(A,M);return{normalized:N?A:S(L,M),malformedAuthorityOrPort:N}}function I(A,M){if(typeof A=="string"){const{normalized:L,malformedAuthorityOrPort:N}=v(A,M);return N?void 0:L}if(typeof A=="object")return S(A,M)}const O={SCHEMES:u,normalize:f,resolve:m,resolveComponent:y,equal:$,serialize:S,parse:l};return tt.exports=O,tt.exports.default=O,tt.exports.fastUri=O,tt.exports}var Cn;function So(){if(Cn)return lt;Cn=1,Object.defineProperty(lt,"__esModule",{value:!0});const e=wo();return e.code='require("ajv/dist/runtime/uri").default',lt.default=e,lt}var Nn;function Eo(){return Nn||(Nn=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.CodeGen=e.Name=e.nil=e.stringify=e.str=e._=e.KeywordCxt=void 0;var t=mr();Object.defineProperty(e,"KeywordCxt",{enumerable:!0,get:function(){return t.KeywordCxt}});var r=W();Object.defineProperty(e,"_",{enumerable:!0,get:function(){return r._}}),Object.defineProperty(e,"str",{enumerable:!0,get:function(){return r.str}}),Object.defineProperty(e,"stringify",{enumerable:!0,get:function(){return r.stringify}}),Object.defineProperty(e,"nil",{enumerable:!0,get:function(){return r.nil}}),Object.defineProperty(e,"Name",{enumerable:!0,get:function(){return r.Name}}),Object.defineProperty(e,"CodeGen",{enumerable:!0,get:function(){return r.CodeGen}});const n=Vr(),o=pr(),i=Gi(),c=hr(),s=W(),d=fr(),u=dr(),a=Z(),f=_o,m=So(),y=(U,k)=>new RegExp(U,k);y.code="new RegExp";const $=["removeAdditional","useDefaults","coerceTypes"],S=new Set(["validate","serialize","parse","wrapper","root","schema","keyword","pattern","formats","validate$data","func","obj","Error"]),g={errorDataPath:"",format:"`validateFormats: false` can be used instead.",nullable:'"nullable" keyword is supported by default.',jsonPointers:"Deprecated jsPropertySyntax can be used instead.",extendRefs:"Deprecated ignoreKeywordsWithRef can be used instead.",missingRefs:"Pass empty schema with $id that should be ignored to ajv.addSchema.",processCode:"Use option `code: {process: (code, schemaEnv: object) => string}`",sourceCode:"Use option `code: {source: true}`",strictDefaults:"It is default now, see option `strict`.",strictKeywords:"It is default now, see option `strict`.",uniqueItems:'"uniqueItems" keyword is always validated.',unknownFormats:"Disable strict mode or pass `true` to `ajv.addFormat` (or `formats` option).",cache:"Map is used as cache, schema object as key.",serialize:"Map is used as cache, schema object as key.",ajvErrors:"It is default now."},_={ignoreKeywordsWithRef:"",jsPropertySyntax:"",unicode:'"minLength"/"maxLength" account for unicode characters by default.'},p=200;function w(U){var k,F,T,b,P,q,B,G,ie,ee,R,C,D,V,H,J,pe,Re,Se,Ee,he,He,Ie,gr,vr;const Ze=U.strict,br=(k=U.code)===null||k===void 0?void 0:k.optimize,Qr=br===!0||br===void 0?1:br||0,Zr=(T=(F=U.code)===null||F===void 0?void 0:F.regExp)!==null&&T!==void 0?T:y,va=(b=U.uriResolver)!==null&&b!==void 0?b:m.default;return{strictSchema:(q=(P=U.strictSchema)!==null&&P!==void 0?P:Ze)!==null&&q!==void 0?q:!0,strictNumbers:(G=(B=U.strictNumbers)!==null&&B!==void 0?B:Ze)!==null&&G!==void 0?G:!0,strictTypes:(ee=(ie=U.strictTypes)!==null&&ie!==void 0?ie:Ze)!==null&&ee!==void 0?ee:"log",strictTuples:(C=(R=U.strictTuples)!==null&&R!==void 0?R:Ze)!==null&&C!==void 0?C:"log",strictRequired:(V=(D=U.strictRequired)!==null&&D!==void 0?D:Ze)!==null&&V!==void 0?V:!1,code:U.code?{...U.code,optimize:Qr,regExp:Zr}:{optimize:Qr,regExp:Zr},loopRequired:(H=U.loopRequired)!==null&&H!==void 0?H:p,loopEnum:(J=U.loopEnum)!==null&&J!==void 0?J:p,meta:(pe=U.meta)!==null&&pe!==void 0?pe:!0,messages:(Re=U.messages)!==null&&Re!==void 0?Re:!0,inlineRefs:(Se=U.inlineRefs)!==null&&Se!==void 0?Se:!0,schemaId:(Ee=U.schemaId)!==null&&Ee!==void 0?Ee:"$id",addUsedSchema:(he=U.addUsedSchema)!==null&&he!==void 0?he:!0,validateSchema:(He=U.validateSchema)!==null&&He!==void 0?He:!0,validateFormats:(Ie=U.validateFormats)!==null&&Ie!==void 0?Ie:!0,unicodeRegExp:(gr=U.unicodeRegExp)!==null&&gr!==void 0?gr:!0,int32range:(vr=U.int32range)!==null&&vr!==void 0?vr:!0,uriResolver:va}}class E{constructor(k={}){this.schemas={},this.refs={},this.formats=Object.create(null),this._compilations=new Set,this._loading={},this._cache=new Map,k=this.opts={...k,...w(k)};const{es5:F,lines:T}=this.opts.code;this.scope=new s.ValueScope({scope:{},prefixes:S,es5:F,lines:T}),this.logger=L(k.logger);const b=k.validateFormats;k.validateFormats=!1,this.RULES=(0,i.getRules)(),l.call(this,g,k,"NOT SUPPORTED"),l.call(this,_,k,"DEPRECATED","warn"),this._metaOpts=A.call(this),k.formats&&I.call(this),this._addVocabularies(),this._addDefaultMetaSchema(),k.keywords&&O.call(this,k.keywords),typeof k.meta=="object"&&this.addMetaSchema(k.meta),v.call(this),k.validateFormats=b}_addVocabularies(){this.addKeyword("$async")}_addDefaultMetaSchema(){const{$data:k,meta:F,schemaId:T}=this.opts;let b=f;T==="id"&&(b={...f},b.id=b.$id,delete b.$id),F&&k&&this.addMetaSchema(b,b[T],!1)}defaultMeta(){const{meta:k,schemaId:F}=this.opts;return this.opts.defaultMeta=typeof k=="object"?k[F]||k:void 0}validate(k,F){let T;if(typeof k=="string"){if(T=this.getSchema(k),!T)throw new Error(`no schema with key or ref "${k}"`)}else T=this.compile(k);const b=T(F);return"$async"in T||(this.errors=T.errors),b}compile(k,F){const T=this._addSchema(k,F);return T.validate||this._compileSchemaEnv(T)}compileAsync(k,F){if(typeof this.opts.loadSchema!="function")throw new Error("options.loadSchema should be a function");const{loadSchema:T}=this.opts;return b.call(this,k,F);async function b(ee,R){await P.call(this,ee.$schema);const C=this._addSchema(ee,R);return C.validate||q.call(this,C)}async function P(ee){ee&&!this.getSchema(ee)&&await b.call(this,{$ref:ee},!0)}async function q(ee){try{return this._compileSchemaEnv(ee)}catch(R){if(!(R instanceof o.default))throw R;return B.call(this,R),await G.call(this,R.missingSchema),q.call(this,ee)}}function B({missingSchema:ee,missingRef:R}){if(this.refs[ee])throw new Error(`AnySchema ${ee} is loaded but ${R} cannot be resolved`)}async function G(ee){const R=await ie.call(this,ee);this.refs[ee]||await P.call(this,R.$schema),this.refs[ee]||this.addSchema(R,ee,F)}async function ie(ee){const R=this._loading[ee];if(R)return R;try{return await(this._loading[ee]=T(ee))}finally{delete this._loading[ee]}}}addSchema(k,F,T,b=this.opts.validateSchema){if(Array.isArray(k)){for(const q of k)this.addSchema(q,void 0,T,b);return this}let P;if(typeof k=="object"){const{schemaId:q}=this.opts;if(P=k[q],P!==void 0&&typeof P!="string")throw new Error(`schema ${q} must be string`)}return F=(0,d.normalizeId)(F||P),this._checkUnique(F),this.schemas[F]=this._addSchema(k,T,F,b,!0),this}addMetaSchema(k,F,T=this.opts.validateSchema){return this.addSchema(k,F,!0,T),this}validateSchema(k,F){if(typeof k=="boolean")return!0;let T;if(T=k.$schema,T!==void 0&&typeof T!="string")throw new Error("$schema must be a string");if(T=T||this.opts.defaultMeta||this.defaultMeta(),!T)return this.logger.warn("meta-schema not available"),this.errors=null,!0;const b=this.validate(T,k);if(!b&&F){const P="schema is invalid: "+this.errorsText();if(this.opts.validateSchema==="log")this.logger.error(P);else throw new Error(P)}return b}getSchema(k){let F;for(;typeof(F=h.call(this,k))=="string";)k=F;if(F===void 0){const{schemaId:T}=this.opts,b=new c.SchemaEnv({schema:{},schemaId:T});if(F=c.resolveSchema.call(this,b,k),!F)return;this.refs[k]=F}return F.validate||this._compileSchemaEnv(F)}removeSchema(k){if(k instanceof RegExp)return this._removeAllSchemas(this.schemas,k),this._removeAllSchemas(this.refs,k),this;switch(typeof k){case"undefined":return this._removeAllSchemas(this.schemas),this._removeAllSchemas(this.refs),this._cache.clear(),this;case"string":{const F=h.call(this,k);return typeof F=="object"&&this._cache.delete(F.schema),delete this.schemas[k],delete this.refs[k],this}case"object":{const F=k;this._cache.delete(F);let T=k[this.opts.schemaId];return T&&(T=(0,d.normalizeId)(T),delete this.schemas[T],delete this.refs[T]),this}default:throw new Error("ajv.removeSchema: invalid parameter")}}addVocabulary(k){for(const F of k)this.addKeyword(F);return this}addKeyword(k,F){let T;if(typeof k=="string")T=k,typeof F=="object"&&(this.logger.warn("these parameters are deprecated, see docs for addKeyword"),F.keyword=T);else if(typeof k=="object"&&F===void 0){if(F=k,T=F.keyword,Array.isArray(T)&&!T.length)throw new Error("addKeywords: keyword must be string or non-empty array")}else throw new Error("invalid addKeywords parameters");if(z.call(this,T,F),!F)return(0,a.eachItem)(T,P=>ne.call(this,P)),this;de.call(this,F);const b={...F,type:(0,u.getJSONTypes)(F.type),schemaType:(0,u.getJSONTypes)(F.schemaType)};return(0,a.eachItem)(T,b.type.length===0?P=>ne.call(this,P,b):P=>b.type.forEach(q=>ne.call(this,P,b,q))),this}getKeyword(k){const F=this.RULES.all[k];return typeof F=="object"?F.definition:!!F}removeKeyword(k){const{RULES:F}=this;delete F.keywords[k],delete F.all[k];for(const T of F.rules){const b=T.rules.findIndex(P=>P.keyword===k);b>=0&&T.rules.splice(b,1)}return this}addFormat(k,F){return typeof F=="string"&&(F=new RegExp(F)),this.formats[k]=F,this}errorsText(k=this.errors,{separator:F=", ",dataVar:T="data"}={}){return!k||k.length===0?"No errors":k.map(b=>`${T}${b.instancePath} ${b.message}`).reduce((b,P)=>b+F+P)}$dataMetaSchema(k,F){const T=this.RULES.all;k=JSON.parse(JSON.stringify(k));for(const b of F){const P=b.split("/").slice(1);let q=k;for(const B of P)q=q[B];for(const B in T){const G=T[B];if(typeof G!="object")continue;const{$data:ie}=G.definition,ee=q[B];ie&&ee&&(q[B]=we(ee))}}return k}_removeAllSchemas(k,F){for(const T in k){const b=k[T];(!F||F.test(T))&&(typeof b=="string"?delete k[T]:b&&!b.meta&&(this._cache.delete(b.schema),delete k[T]))}}_addSchema(k,F,T,b=this.opts.validateSchema,P=this.opts.addUsedSchema){let q;const{schemaId:B}=this.opts;if(typeof k=="object")q=k[B];else{if(this.opts.jtd)throw new Error("schema must be object");if(typeof k!="boolean")throw new Error("schema must be object or boolean")}let G=this._cache.get(k);if(G!==void 0)return G;T=(0,d.normalizeId)(q||T);const ie=d.getSchemaRefs.call(this,k,T);return G=new c.SchemaEnv({schema:k,schemaId:B,meta:F,baseId:T,localRefs:ie}),this._cache.set(G.schema,G),P&&!T.startsWith("#")&&(T&&this._checkUnique(T),this.refs[T]=G),b&&this.validateSchema(k,!0),G}_checkUnique(k){if(this.schemas[k]||this.refs[k])throw new Error(`schema with key or id "${k}" already exists`)}_compileSchemaEnv(k){if(k.meta?this._compileMetaSchema(k):c.compileSchema.call(this,k),!k.validate)throw new Error("ajv implementation error");return k.validate}_compileMetaSchema(k){const F=this.opts;this.opts=this._metaOpts;try{c.compileSchema.call(this,k)}finally{this.opts=F}}}E.ValidationError=n.default,E.MissingRefError=o.default,e.default=E;function l(U,k,F,T="error"){for(const b in U){const P=b;P in k&&this.logger[T](`${F}: option ${b}. ${U[P]}`)}}function h(U){return U=(0,d.normalizeId)(U),this.schemas[U]||this.refs[U]}function v(){const U=this.opts.schemas;if(U)if(Array.isArray(U))this.addSchema(U);else for(const k in U)this.addSchema(U[k],k)}function I(){for(const U in this.opts.formats){const k=this.opts.formats[U];k&&this.addFormat(U,k)}}function O(U){if(Array.isArray(U)){this.addVocabulary(U);return}this.logger.warn("keywords option as map is deprecated, pass array");for(const k in U){const F=U[k];F.keyword||(F.keyword=k),this.addKeyword(F)}}function A(){const U={...this.opts};for(const k of $)delete U[k];return U}const M={log(){},warn(){},error(){}};function L(U){if(U===!1)return M;if(U===void 0)return console;if(U.log&&U.warn&&U.error)return U;throw new Error("logger must implement log, warn and error methods")}const N=/^[a-z_$][a-z0-9_$:-]*$/i;function z(U,k){const{RULES:F}=this;if((0,a.eachItem)(U,T=>{if(F.keywords[T])throw new Error(`Keyword ${T} is already defined`);if(!N.test(T))throw new Error(`Keyword ${T} has invalid name`)}),!!k&&k.$data&&!("code"in k||"validate"in k))throw new Error('$data keyword must have "code" or "validate" function')}function ne(U,k,F){var T;const b=k?.post;if(F&&b)throw new Error('keyword with "post" flag cannot have "type"');const{RULES:P}=this;let q=b?P.post:P.rules.find(({type:G})=>G===F);if(q||(q={type:F,rules:[]},P.rules.push(q)),P.keywords[U]=!0,!k)return;const B={keyword:U,definition:{...k,type:(0,u.getJSONTypes)(k.type),schemaType:(0,u.getJSONTypes)(k.schemaType)}};k.before?fe.call(this,q,B,k.before):q.rules.push(B),P.all[U]=B,(T=k.implements)===null||T===void 0||T.forEach(G=>this.addKeyword(G))}function fe(U,k,F){const T=U.rules.findIndex(b=>b.keyword===F);T>=0?U.rules.splice(T,0,k):(U.rules.push(k),this.logger.warn(`rule ${F} is not defined`))}function de(U){let{metaSchema:k}=U;k!==void 0&&(U.$data&&this.opts.$data&&(k=we(k)),U.validateSchema=this.compile(k,!0))}const X={$ref:"https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#"};function we(U){return{anyOf:[U,X]}}})($r)),$r}var ft={},mt={},pt={},Tn;function Po(){if(Tn)return pt;Tn=1,Object.defineProperty(pt,"__esModule",{value:!0});const e={keyword:"id",code(){throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schema ID')}};return pt.default=e,pt}var qe={},jn;function Kr(){if(jn)return qe;jn=1,Object.defineProperty(qe,"__esModule",{value:!0}),qe.callRef=qe.getValidate=void 0;const e=pr(),t=Ne(),r=W(),n=Ce(),o=hr(),i=Z(),c={keyword:"$ref",schemaType:"string",code(u){const{gen:a,schema:f,it:m}=u,{baseId:y,schemaEnv:$,validateName:S,opts:g,self:_}=m,{root:p}=$;if((f==="#"||f==="#/")&&y===p.baseId)return E();const w=o.resolveRef.call(_,p,y,f);if(w===void 0)throw new e.default(m.opts.uriResolver,y,f);if(w instanceof o.SchemaEnv)return l(w);return h(w);function E(){if($===p)return d(u,S,$,$.$async);const v=a.scopeValue("root",{ref:p});return d(u,(0,r._)`${v}.validate`,p,p.$async)}function l(v){const I=s(u,v);d(u,I,v,v.$async)}function h(v){const I=a.scopeValue("schema",g.code.source===!0?{ref:v,code:(0,r.stringify)(v)}:{ref:v}),O=a.name("valid"),A=u.subschema({schema:v,dataTypes:[],schemaPath:r.nil,topSchemaRef:I,errSchemaPath:f},O);u.mergeEvaluated(A),u.ok(O)}}};function s(u,a){const{gen:f}=u;return a.validate?f.scopeValue("validate",{ref:a.validate}):(0,r._)`${f.scopeValue("wrapper",{ref:a})}.validate`}qe.getValidate=s;function d(u,a,f,m){const{gen:y,it:$}=u,{allErrors:S,schemaEnv:g,opts:_}=$,p=_.passContext?n.default.this:r.nil;m?w():E();function w(){if(!g.$async)throw new Error("async schema referenced by sync schema");const v=y.let("valid");y.try(()=>{y.code((0,r._)`await ${(0,t.callValidateCode)(u,a,p)}`),h(a),S||y.assign(v,!0)},I=>{y.if((0,r._)`!(${I} instanceof ${$.ValidationError})`,()=>y.throw(I)),l(I),S||y.assign(v,!1)}),u.ok(v)}function E(){u.result((0,t.callValidateCode)(u,a,p),()=>h(a),()=>l(a))}function l(v){const I=(0,r._)`${v}.errors`;y.assign(n.default.vErrors,(0,r._)`${n.default.vErrors} === null ? ${I} : ${n.default.vErrors}.concat(${I})`),y.assign(n.default.errors,(0,r._)`${n.default.vErrors}.length`)}function h(v){var I;if(!$.opts.unevaluated)return;const O=(I=f?.validate)===null||I===void 0?void 0:I.evaluated;if($.props!==!0)if(O&&!O.dynamicProps)O.props!==void 0&&($.props=i.mergeEvaluated.props(y,O.props,$.props));else{const A=y.var("props",(0,r._)`${v}.evaluated.props`);$.props=i.mergeEvaluated.props(y,A,$.props,r.Name)}if($.items!==!0)if(O&&!O.dynamicItems)O.items!==void 0&&($.items=i.mergeEvaluated.items(y,O.items,$.items));else{const A=y.var("items",(0,r._)`${v}.evaluated.items`);$.items=i.mergeEvaluated.items(y,A,$.items,r.Name)}}}return qe.callRef=d,qe.default=c,qe}var On;function Io(){if(On)return mt;On=1,Object.defineProperty(mt,"__esModule",{value:!0});const e=Po(),t=Kr(),r=["$schema","$id","$defs","$vocabulary",{keyword:"$comment"},"definitions",e.default,t.default];return mt.default=r,mt}var ht={},yt={},Mn;function Ro(){if(Mn)return yt;Mn=1,Object.defineProperty(yt,"__esModule",{value:!0});const e=W(),t=e.operators,r={maximum:{okStr:"<=",ok:t.LTE,fail:t.GT},minimum:{okStr:">=",ok:t.GTE,fail:t.LT},exclusiveMaximum:{okStr:"<",ok:t.LT,fail:t.GTE},exclusiveMinimum:{okStr:">",ok:t.GT,fail:t.LTE}},n={message:({keyword:i,schemaCode:c})=>(0,e.str)`must be ${r[i].okStr} ${c}`,params:({keyword:i,schemaCode:c})=>(0,e._)`{comparison: ${r[i].okStr}, limit: ${c}}`},o={keyword:Object.keys(r),type:"number",schemaType:"number",$data:!0,error:n,code(i){const{keyword:c,data:s,schemaCode:d}=i;i.fail$data((0,e._)`${s} ${r[c].fail} ${d} || isNaN(${s})`)}};return yt.default=o,yt}var gt={},qn;function Ao(){if(qn)return gt;qn=1,Object.defineProperty(gt,"__esModule",{value:!0});const e=W(),r={keyword:"multipleOf",type:"number",schemaType:"number",$data:!0,error:{message:({schemaCode:n})=>(0,e.str)`must be multiple of ${n}`,params:({schemaCode:n})=>(0,e._)`{multipleOf: ${n}}`},code(n){const{gen:o,data:i,schemaCode:c,it:s}=n,d=s.opts.multipleOfPrecision,u=o.let("res"),a=d?(0,e._)`Math.abs(Math.round(${u}) - ${u}) > 1e-${d}`:(0,e._)`${u} !== parseInt(${u})`;n.fail$data((0,e._)`(${c} === 0 || (${u} = ${i}/${c}, ${a}))`)}};return gt.default=r,gt}var vt={},bt={},xn;function ko(){if(xn)return bt;xn=1,Object.defineProperty(bt,"__esModule",{value:!0});function e(t){const r=t.length;let n=0,o=0,i;for(;o=55296&&i<=56319&&o(0,e._)`{limit: ${i}}`},code(i){const{keyword:c,data:s,schemaCode:d,it:u}=i,a=c==="maxLength"?e.operators.GT:e.operators.LT,f=u.opts.unicode===!1?(0,e._)`${s}.length`:(0,e._)`${(0,t.useFunc)(i.gen,r.default)}(${s})`;i.fail$data((0,e._)`${f} ${a} ${d}`)}};return vt.default=o,vt}var _t={},Dn;function No(){if(Dn)return _t;Dn=1,Object.defineProperty(_t,"__esModule",{value:!0});const e=Ne(),t=Z(),r=W(),o={keyword:"pattern",type:"string",schemaType:"string",$data:!0,error:{message:({schemaCode:i})=>(0,r.str)`must match pattern "${i}"`,params:({schemaCode:i})=>(0,r._)`{pattern: ${i}}`},code(i){const{gen:c,data:s,$data:d,schema:u,schemaCode:a,it:f}=i,m=f.opts.unicodeRegExp?"u":"";if(d){const{regExp:y}=f.opts.code,$=y.code==="new RegExp"?(0,r._)`new RegExp`:(0,t.useFunc)(c,y),S=c.let("valid");c.try(()=>c.assign(S,(0,r._)`${$}(${a}, ${m}).test(${s})`),()=>c.assign(S,!1)),i.fail$data((0,r._)`!${S}`)}else{const y=(0,e.usePattern)(i,u);i.fail$data((0,r._)`!${y}.test(${s})`)}}};return _t.default=o,_t}var $t={},Fn;function To(){if(Fn)return $t;Fn=1,Object.defineProperty($t,"__esModule",{value:!0});const e=W(),r={keyword:["maxProperties","minProperties"],type:"object",schemaType:"number",$data:!0,error:{message({keyword:n,schemaCode:o}){const i=n==="maxProperties"?"more":"fewer";return(0,e.str)`must NOT have ${i} than ${o} properties`},params:({schemaCode:n})=>(0,e._)`{limit: ${n}}`},code(n){const{keyword:o,data:i,schemaCode:c}=n,s=o==="maxProperties"?e.operators.GT:e.operators.LT;n.fail$data((0,e._)`Object.keys(${i}).length ${s} ${c}`)}};return $t.default=r,$t}var wt={},Un;function jo(){if(Un)return wt;Un=1,Object.defineProperty(wt,"__esModule",{value:!0});const e=Ne(),t=W(),r=Z(),o={keyword:"required",type:"object",schemaType:"array",$data:!0,error:{message:({params:{missingProperty:i}})=>(0,t.str)`must have required property '${i}'`,params:({params:{missingProperty:i}})=>(0,t._)`{missingProperty: ${i}}`},code(i){const{gen:c,schema:s,schemaCode:d,data:u,$data:a,it:f}=i,{opts:m}=f;if(!a&&s.length===0)return;const y=s.length>=m.loopRequired;if(f.allErrors?$():S(),m.strictRequired){const p=i.parentSchema.properties,{definedProperties:w}=i.it;for(const E of s)if(p?.[E]===void 0&&!w.has(E)){const l=f.schemaEnv.baseId+f.errSchemaPath,h=`required property "${E}" is not defined at "${l}" (strictRequired)`;(0,r.checkStrictMode)(f,h,f.opts.strictRequired)}}function $(){if(y||a)i.block$data(t.nil,g);else for(const p of s)(0,e.checkReportMissingProp)(i,p)}function S(){const p=c.let("missing");if(y||a){const w=c.let("valid",!0);i.block$data(w,()=>_(p,w)),i.ok(w)}else c.if((0,e.checkMissingProp)(i,s,p)),(0,e.reportMissingProp)(i,p),c.else()}function g(){c.forOf("prop",d,p=>{i.setParams({missingProperty:p}),c.if((0,e.noPropertyInData)(c,u,p,m.ownProperties),()=>i.error())})}function _(p,w){i.setParams({missingProperty:p}),c.forOf(p,d,()=>{c.assign(w,(0,e.propertyInData)(c,u,p,m.ownProperties)),c.if((0,t.not)(w),()=>{i.error(),c.break()})},t.nil)}}};return wt.default=o,wt}var St={},zn;function Oo(){if(zn)return St;zn=1,Object.defineProperty(St,"__esModule",{value:!0});const e=W(),r={keyword:["maxItems","minItems"],type:"array",schemaType:"number",$data:!0,error:{message({keyword:n,schemaCode:o}){const i=n==="maxItems"?"more":"fewer";return(0,e.str)`must NOT have ${i} than ${o} items`},params:({schemaCode:n})=>(0,e._)`{limit: ${n}}`},code(n){const{keyword:o,data:i,schemaCode:c}=n,s=o==="maxItems"?e.operators.GT:e.operators.LT;n.fail$data((0,e._)`${i}.length ${s} ${c}`)}};return St.default=r,St}var Et={},Pt={},Vn;function Br(){if(Vn)return Pt;Vn=1,Object.defineProperty(Pt,"__esModule",{value:!0});const e=Xi();return e.code='require("ajv/dist/runtime/equal").default',Pt.default=e,Pt}var Kn;function Mo(){if(Kn)return Et;Kn=1,Object.defineProperty(Et,"__esModule",{value:!0});const e=dr(),t=W(),r=Z(),n=Br(),i={keyword:"uniqueItems",type:"array",schemaType:"boolean",$data:!0,error:{message:({params:{i:c,j:s}})=>(0,t.str)`must NOT have duplicate items (items ## ${s} and ${c} are identical)`,params:({params:{i:c,j:s}})=>(0,t._)`{i: ${c}, j: ${s}}`},code(c){const{gen:s,data:d,$data:u,schema:a,parentSchema:f,schemaCode:m,it:y}=c;if(!u&&!a)return;const $=s.let("valid"),S=f.items?(0,e.getSchemaTypes)(f.items):[];c.block$data($,g,(0,t._)`${m} === false`),c.ok($);function g(){const E=s.let("i",(0,t._)`${d}.length`),l=s.let("j");c.setParams({i:E,j:l}),s.assign($,!0),s.if((0,t._)`${E} > 1`,()=>(_()?p:w)(E,l))}function _(){return S.length>0&&!S.some(E=>E==="object"||E==="array")}function p(E,l){const h=s.name("item"),v=(0,e.checkDataTypes)(S,h,y.opts.strictNumbers,e.DataType.Wrong),I=s.const("indices",(0,t._)`{}`);s.for((0,t._)`;${E}--;`,()=>{s.let(h,(0,t._)`${d}[${E}]`),s.if(v,(0,t._)`continue`),S.length>1&&s.if((0,t._)`typeof ${h} == "string"`,(0,t._)`${h} += "_"`),s.if((0,t._)`typeof ${I}[${h}] == "number"`,()=>{s.assign(l,(0,t._)`${I}[${h}]`),c.error(),s.assign($,!1).break()}).code((0,t._)`${I}[${h}] = ${E}`)})}function w(E,l){const h=(0,r.useFunc)(s,n.default),v=s.name("outer");s.label(v).for((0,t._)`;${E}--;`,()=>s.for((0,t._)`${l} = ${E}; ${l}--;`,()=>s.if((0,t._)`${h}(${d}[${E}], ${d}[${l}])`,()=>{c.error(),s.assign($,!1).break(v)})))}}};return Et.default=i,Et}var It={},Bn;function qo(){if(Bn)return It;Bn=1,Object.defineProperty(It,"__esModule",{value:!0});const e=W(),t=Z(),r=Br(),o={keyword:"const",$data:!0,error:{message:"must be equal to constant",params:({schemaCode:i})=>(0,e._)`{allowedValue: ${i}}`},code(i){const{gen:c,data:s,$data:d,schemaCode:u,schema:a}=i;d||a&&typeof a=="object"?i.fail$data((0,e._)`!${(0,t.useFunc)(c,r.default)}(${s}, ${u})`):i.fail((0,e._)`${a} !== ${s}`)}};return It.default=o,It}var Rt={},Hn;function xo(){if(Hn)return Rt;Hn=1,Object.defineProperty(Rt,"__esModule",{value:!0});const e=W(),t=Z(),r=Br(),o={keyword:"enum",schemaType:"array",$data:!0,error:{message:"must be equal to one of the allowed values",params:({schemaCode:i})=>(0,e._)`{allowedValues: ${i}}`},code(i){const{gen:c,data:s,$data:d,schema:u,schemaCode:a,it:f}=i;if(!d&&u.length===0)throw new Error("enum must have non-empty array");const m=u.length>=f.opts.loopEnum;let y;const $=()=>y??(y=(0,t.useFunc)(c,r.default));let S;if(m||d)S=c.let("valid"),i.block$data(S,g);else{if(!Array.isArray(u))throw new Error("ajv implementation error");const p=c.const("vSchema",a);S=(0,e.or)(...u.map((w,E)=>_(p,E)))}i.pass(S);function g(){c.assign(S,!1),c.forOf("v",a,p=>c.if((0,e._)`${$()}(${s}, ${p})`,()=>c.assign(S,!0).break()))}function _(p,w){const E=u[w];return typeof E=="object"&&E!==null?(0,e._)`${$()}(${s}, ${p}[${w}])`:(0,e._)`${s} === ${E}`}}};return Rt.default=o,Rt}var Gn;function Lo(){if(Gn)return ht;Gn=1,Object.defineProperty(ht,"__esModule",{value:!0});const e=Ro(),t=Ao(),r=Co(),n=No(),o=To(),i=jo(),c=Oo(),s=Mo(),d=qo(),u=xo(),a=[e.default,t.default,r.default,n.default,o.default,i.default,c.default,s.default,{keyword:"type",schemaType:["string","array"]},{keyword:"nullable",schemaType:"boolean"},d.default,u.default];return ht.default=a,ht}var At={},Xe={},Wn;function Ji(){if(Wn)return Xe;Wn=1,Object.defineProperty(Xe,"__esModule",{value:!0}),Xe.validateAdditionalItems=void 0;const e=W(),t=Z(),n={keyword:"additionalItems",type:"array",schemaType:["boolean","object"],before:"uniqueItems",error:{message:({params:{len:i}})=>(0,e.str)`must NOT have more than ${i} items`,params:({params:{len:i}})=>(0,e._)`{limit: ${i}}`},code(i){const{parentSchema:c,it:s}=i,{items:d}=c;if(!Array.isArray(d)){(0,t.checkStrictMode)(s,'"additionalItems" is ignored when "items" is not an array of schemas');return}o(i,d)}};function o(i,c){const{gen:s,schema:d,data:u,keyword:a,it:f}=i;f.items=!0;const m=s.const("len",(0,e._)`${u}.length`);if(d===!1)i.setParams({len:c.length}),i.pass((0,e._)`${m} <= ${c.length}`);else if(typeof d=="object"&&!(0,t.alwaysValidSchema)(f,d)){const $=s.var("valid",(0,e._)`${m} <= ${c.length}`);s.if((0,e.not)($),()=>y($)),i.ok($)}function y($){s.forRange("i",c.length,m,S=>{i.subschema({keyword:a,dataProp:S,dataPropType:t.Type.Num},$),f.allErrors||s.if((0,e.not)($),()=>s.break())})}}return Xe.validateAdditionalItems=o,Xe.default=n,Xe}var kt={},Ye={},Xn;function Qi(){if(Xn)return Ye;Xn=1,Object.defineProperty(Ye,"__esModule",{value:!0}),Ye.validateTuple=void 0;const e=W(),t=Z(),r=Ne(),n={keyword:"items",type:"array",schemaType:["object","array","boolean"],before:"uniqueItems",code(i){const{schema:c,it:s}=i;if(Array.isArray(c))return o(i,"additionalItems",c);s.items=!0,!(0,t.alwaysValidSchema)(s,c)&&i.ok((0,r.validateArray)(i))}};function o(i,c,s=i.schema){const{gen:d,parentSchema:u,data:a,keyword:f,it:m}=i;S(u),m.opts.unevaluated&&s.length&&m.items!==!0&&(m.items=t.mergeEvaluated.items(d,s.length,m.items));const y=d.name("valid"),$=d.const("len",(0,e._)`${a}.length`);s.forEach((g,_)=>{(0,t.alwaysValidSchema)(m,g)||(d.if((0,e._)`${$} > ${_}`,()=>i.subschema({keyword:f,schemaProp:_,dataProp:_},y)),i.ok(y))});function S(g){const{opts:_,errSchemaPath:p}=m,w=s.length,E=w===g.minItems&&(w===g.maxItems||g[c]===!1);if(_.strictTuples&&!E){const l=`"${f}" is ${w}-tuple, but minItems or maxItems/${c} are not specified or different at path "${p}"`;(0,t.checkStrictMode)(m,l,_.strictTuples)}}}return Ye.validateTuple=o,Ye.default=n,Ye}var Yn;function Do(){if(Yn)return kt;Yn=1,Object.defineProperty(kt,"__esModule",{value:!0});const e=Qi(),t={keyword:"prefixItems",type:"array",schemaType:["array"],before:"uniqueItems",code:r=>(0,e.validateTuple)(r,"items")};return kt.default=t,kt}var Ct={},Jn;function Fo(){if(Jn)return Ct;Jn=1,Object.defineProperty(Ct,"__esModule",{value:!0});const e=W(),t=Z(),r=Ne(),n=Ji(),i={keyword:"items",type:"array",schemaType:["object","boolean"],before:"uniqueItems",error:{message:({params:{len:c}})=>(0,e.str)`must NOT have more than ${c} items`,params:({params:{len:c}})=>(0,e._)`{limit: ${c}}`},code(c){const{schema:s,parentSchema:d,it:u}=c,{prefixItems:a}=d;u.items=!0,!(0,t.alwaysValidSchema)(u,s)&&(a?(0,n.validateAdditionalItems)(c,a):c.ok((0,r.validateArray)(c)))}};return Ct.default=i,Ct}var Nt={},Qn;function Uo(){if(Qn)return Nt;Qn=1,Object.defineProperty(Nt,"__esModule",{value:!0});const e=W(),t=Z(),n={keyword:"contains",type:"array",schemaType:["object","boolean"],before:"uniqueItems",trackErrors:!0,error:{message:({params:{min:o,max:i}})=>i===void 0?(0,e.str)`must contain at least ${o} valid item(s)`:(0,e.str)`must contain at least ${o} and no more than ${i} valid item(s)`,params:({params:{min:o,max:i}})=>i===void 0?(0,e._)`{minContains: ${o}}`:(0,e._)`{minContains: ${o}, maxContains: ${i}}`},code(o){const{gen:i,schema:c,parentSchema:s,data:d,it:u}=o;let a,f;const{minContains:m,maxContains:y}=s;u.opts.next?(a=m===void 0?1:m,f=y):a=1;const $=i.const("len",(0,e._)`${d}.length`);if(o.setParams({min:a,max:f}),f===void 0&&a===0){(0,t.checkStrictMode)(u,'"minContains" == 0 without "maxContains": "contains" keyword ignored');return}if(f!==void 0&&a>f){(0,t.checkStrictMode)(u,'"minContains" > "maxContains" is always invalid'),o.fail();return}if((0,t.alwaysValidSchema)(u,c)){let w=(0,e._)`${$} >= ${a}`;f!==void 0&&(w=(0,e._)`${w} && ${$} <= ${f}`),o.pass(w);return}u.items=!0;const S=i.name("valid");f===void 0&&a===1?_(S,()=>i.if(S,()=>i.break())):a===0?(i.let(S,!0),f!==void 0&&i.if((0,e._)`${d}.length > 0`,g)):(i.let(S,!1),g()),o.result(S,()=>o.reset());function g(){const w=i.name("_valid"),E=i.let("count",0);_(w,()=>i.if(w,()=>p(E)))}function _(w,E){i.forRange("i",0,$,l=>{o.subschema({keyword:"contains",dataProp:l,dataPropType:t.Type.Num,compositeRule:!0},w),E()})}function p(w){i.code((0,e._)`${w}++`),f===void 0?i.if((0,e._)`${w} >= ${a}`,()=>i.assign(S,!0).break()):(i.if((0,e._)`${w} > ${f}`,()=>i.assign(S,!1).break()),a===1?i.assign(S,!0):i.if((0,e._)`${w} >= ${a}`,()=>i.assign(S,!0)))}}};return Nt.default=n,Nt}var Cr={},Zn;function Hr(){return Zn||(Zn=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.validateSchemaDeps=e.validatePropertyDeps=e.error=void 0;const t=W(),r=Z(),n=Ne();e.error={message:({params:{property:d,depsCount:u,deps:a}})=>{const f=u===1?"property":"properties";return(0,t.str)`must have ${f} ${a} when property ${d} is present`},params:({params:{property:d,depsCount:u,deps:a,missingProperty:f}})=>(0,t._)`{property: ${d}, + missingProperty: ${f}, + depsCount: ${u}, + deps: ${a}}`};const o={keyword:"dependencies",type:"object",schemaType:"object",error:e.error,code(d){const[u,a]=i(d);c(d,u),s(d,a)}};function i({schema:d}){const u={},a={};for(const f in d){if(f==="__proto__")continue;const m=Array.isArray(d[f])?u:a;m[f]=d[f]}return[u,a]}function c(d,u=d.schema){const{gen:a,data:f,it:m}=d;if(Object.keys(u).length===0)return;const y=a.let("missing");for(const $ in u){const S=u[$];if(S.length===0)continue;const g=(0,n.propertyInData)(a,f,$,m.opts.ownProperties);d.setParams({property:$,depsCount:S.length,deps:S.join(", ")}),m.allErrors?a.if(g,()=>{for(const _ of S)(0,n.checkReportMissingProp)(d,_)}):(a.if((0,t._)`${g} && (${(0,n.checkMissingProp)(d,S,y)})`),(0,n.reportMissingProp)(d,y),a.else())}}e.validatePropertyDeps=c;function s(d,u=d.schema){const{gen:a,data:f,keyword:m,it:y}=d,$=a.name("valid");for(const S in u)(0,r.alwaysValidSchema)(y,u[S])||(a.if((0,n.propertyInData)(a,f,S,y.opts.ownProperties),()=>{const g=d.subschema({keyword:m,schemaProp:S},$);d.mergeValidEvaluated(g,$)},()=>a.var($,!0)),d.ok($))}e.validateSchemaDeps=s,e.default=o})(Cr)),Cr}var Tt={},ei;function zo(){if(ei)return Tt;ei=1,Object.defineProperty(Tt,"__esModule",{value:!0});const e=W(),t=Z(),n={keyword:"propertyNames",type:"object",schemaType:["object","boolean"],error:{message:"property name must be valid",params:({params:o})=>(0,e._)`{propertyName: ${o.propertyName}}`},code(o){const{gen:i,schema:c,data:s,it:d}=o;if((0,t.alwaysValidSchema)(d,c))return;const u=i.name("valid");i.forIn("key",s,a=>{o.setParams({propertyName:a}),o.subschema({keyword:"propertyNames",data:a,dataTypes:["string"],propertyName:a,compositeRule:!0},u),i.if((0,e.not)(u),()=>{o.error(!0),d.allErrors||i.break()})}),o.ok(u)}};return Tt.default=n,Tt}var jt={},ti;function Zi(){if(ti)return jt;ti=1,Object.defineProperty(jt,"__esModule",{value:!0});const e=Ne(),t=W(),r=Ce(),n=Z(),i={keyword:"additionalProperties",type:["object"],schemaType:["boolean","object"],allowUndefined:!0,trackErrors:!0,error:{message:"must NOT have additional properties",params:({params:c})=>(0,t._)`{additionalProperty: ${c.additionalProperty}}`},code(c){const{gen:s,schema:d,parentSchema:u,data:a,errsCount:f,it:m}=c;if(!f)throw new Error("ajv implementation error");const{allErrors:y,opts:$}=m;if(m.props=!0,$.removeAdditional!=="all"&&(0,n.alwaysValidSchema)(m,d))return;const S=(0,e.allSchemaProperties)(u.properties),g=(0,e.allSchemaProperties)(u.patternProperties);_(),c.ok((0,t._)`${f} === ${r.default.errors}`);function _(){s.forIn("key",a,h=>{!S.length&&!g.length?E(h):s.if(p(h),()=>E(h))})}function p(h){let v;if(S.length>8){const I=(0,n.schemaRefOrVal)(m,u.properties,"properties");v=(0,e.isOwnProperty)(s,I,h)}else S.length?v=(0,t.or)(...S.map(I=>(0,t._)`${h} === ${I}`)):v=t.nil;return g.length&&(v=(0,t.or)(v,...g.map(I=>(0,t._)`${(0,e.usePattern)(c,I)}.test(${h})`))),(0,t.not)(v)}function w(h){s.code((0,t._)`delete ${a}[${h}]`)}function E(h){if($.removeAdditional==="all"||$.removeAdditional&&d===!1){w(h);return}if(d===!1){c.setParams({additionalProperty:h}),c.error(),y||s.break();return}if(typeof d=="object"&&!(0,n.alwaysValidSchema)(m,d)){const v=s.name("valid");$.removeAdditional==="failing"?(l(h,v,!1),s.if((0,t.not)(v),()=>{c.reset(),w(h)})):(l(h,v),y||s.if((0,t.not)(v),()=>s.break()))}}function l(h,v,I){const O={keyword:"additionalProperties",dataProp:h,dataPropType:n.Type.Str};I===!1&&Object.assign(O,{compositeRule:!0,createErrors:!1,allErrors:!1}),c.subschema(O,v)}}};return jt.default=i,jt}var Ot={},ri;function Vo(){if(ri)return Ot;ri=1,Object.defineProperty(Ot,"__esModule",{value:!0});const e=mr(),t=Ne(),r=Z(),n=Zi(),o={keyword:"properties",type:"object",schemaType:"object",code(i){const{gen:c,schema:s,parentSchema:d,data:u,it:a}=i;a.opts.removeAdditional==="all"&&d.additionalProperties===void 0&&n.default.code(new e.KeywordCxt(a,n.default,"additionalProperties"));const f=(0,t.allSchemaProperties)(s);for(const g of f)a.definedProperties.add(g);a.opts.unevaluated&&f.length&&a.props!==!0&&(a.props=r.mergeEvaluated.props(c,(0,r.toHash)(f),a.props));const m=f.filter(g=>!(0,r.alwaysValidSchema)(a,s[g]));if(m.length===0)return;const y=c.name("valid");for(const g of m)$(g)?S(g):(c.if((0,t.propertyInData)(c,u,g,a.opts.ownProperties)),S(g),a.allErrors||c.else().var(y,!0),c.endIf()),i.it.definedProperties.add(g),i.ok(y);function $(g){return a.opts.useDefaults&&!a.compositeRule&&s[g].default!==void 0}function S(g){i.subschema({keyword:"properties",schemaProp:g,dataProp:g},y)}}};return Ot.default=o,Ot}var Mt={},ni;function Ko(){if(ni)return Mt;ni=1,Object.defineProperty(Mt,"__esModule",{value:!0});const e=Ne(),t=W(),r=Z(),n=Z(),o={keyword:"patternProperties",type:"object",schemaType:"object",code(i){const{gen:c,schema:s,data:d,parentSchema:u,it:a}=i,{opts:f}=a,m=(0,e.allSchemaProperties)(s),y=m.filter(E=>(0,r.alwaysValidSchema)(a,s[E]));if(m.length===0||y.length===m.length&&(!a.opts.unevaluated||a.props===!0))return;const $=f.strictSchema&&!f.allowMatchingProperties&&u.properties,S=c.name("valid");a.props!==!0&&!(a.props instanceof t.Name)&&(a.props=(0,n.evaluatedPropsToName)(c,a.props));const{props:g}=a;_();function _(){for(const E of m)$&&p(E),a.allErrors?w(E):(c.var(S,!0),w(E),c.if(S))}function p(E){for(const l in $)new RegExp(E).test(l)&&(0,r.checkStrictMode)(a,`property ${l} matches pattern ${E} (use allowMatchingProperties)`)}function w(E){c.forIn("key",d,l=>{c.if((0,t._)`${(0,e.usePattern)(i,E)}.test(${l})`,()=>{const h=y.includes(E);h||i.subschema({keyword:"patternProperties",schemaProp:E,dataProp:l,dataPropType:n.Type.Str},S),a.opts.unevaluated&&g!==!0?c.assign((0,t._)`${g}[${l}]`,!0):!h&&!a.allErrors&&c.if((0,t.not)(S),()=>c.break())})})}}};return Mt.default=o,Mt}var qt={},ii;function Bo(){if(ii)return qt;ii=1,Object.defineProperty(qt,"__esModule",{value:!0});const e=Z(),t={keyword:"not",schemaType:["object","boolean"],trackErrors:!0,code(r){const{gen:n,schema:o,it:i}=r;if((0,e.alwaysValidSchema)(i,o)){r.fail();return}const c=n.name("valid");r.subschema({keyword:"not",compositeRule:!0,createErrors:!1,allErrors:!1},c),r.failResult(c,()=>r.reset(),()=>r.error())},error:{message:"must NOT be valid"}};return qt.default=t,qt}var xt={},ai;function Ho(){if(ai)return xt;ai=1,Object.defineProperty(xt,"__esModule",{value:!0});const t={keyword:"anyOf",schemaType:"array",trackErrors:!0,code:Ne().validateUnion,error:{message:"must match a schema in anyOf"}};return xt.default=t,xt}var Lt={},oi;function Go(){if(oi)return Lt;oi=1,Object.defineProperty(Lt,"__esModule",{value:!0});const e=W(),t=Z(),n={keyword:"oneOf",schemaType:"array",trackErrors:!0,error:{message:"must match exactly one schema in oneOf",params:({params:o})=>(0,e._)`{passingSchemas: ${o.passing}}`},code(o){const{gen:i,schema:c,parentSchema:s,it:d}=o;if(!Array.isArray(c))throw new Error("ajv implementation error");if(d.opts.discriminator&&s.discriminator)return;const u=c,a=i.let("valid",!1),f=i.let("passing",null),m=i.name("_valid");o.setParams({passing:f}),i.block(y),o.result(a,()=>o.reset(),()=>o.error(!0));function y(){u.forEach(($,S)=>{let g;(0,t.alwaysValidSchema)(d,$)?i.var(m,!0):g=o.subschema({keyword:"oneOf",schemaProp:S,compositeRule:!0},m),S>0&&i.if((0,e._)`${m} && ${a}`).assign(a,!1).assign(f,(0,e._)`[${f}, ${S}]`).else(),i.if(m,()=>{i.assign(a,!0),i.assign(f,S),g&&o.mergeEvaluated(g,e.Name)})})}}};return Lt.default=n,Lt}var Dt={},si;function Wo(){if(si)return Dt;si=1,Object.defineProperty(Dt,"__esModule",{value:!0});const e=Z(),t={keyword:"allOf",schemaType:"array",code(r){const{gen:n,schema:o,it:i}=r;if(!Array.isArray(o))throw new Error("ajv implementation error");const c=n.name("valid");o.forEach((s,d)=>{if((0,e.alwaysValidSchema)(i,s))return;const u=r.subschema({keyword:"allOf",schemaProp:d},c);r.ok(c),r.mergeEvaluated(u)})}};return Dt.default=t,Dt}var Ft={},ci;function Xo(){if(ci)return Ft;ci=1,Object.defineProperty(Ft,"__esModule",{value:!0});const e=W(),t=Z(),n={keyword:"if",schemaType:["object","boolean"],trackErrors:!0,error:{message:({params:i})=>(0,e.str)`must match "${i.ifClause}" schema`,params:({params:i})=>(0,e._)`{failingKeyword: ${i.ifClause}}`},code(i){const{gen:c,parentSchema:s,it:d}=i;s.then===void 0&&s.else===void 0&&(0,t.checkStrictMode)(d,'"if" without "then" and "else" is ignored');const u=o(d,"then"),a=o(d,"else");if(!u&&!a)return;const f=c.let("valid",!0),m=c.name("_valid");if(y(),i.reset(),u&&a){const S=c.let("ifClause");i.setParams({ifClause:S}),c.if(m,$("then",S),$("else",S))}else u?c.if(m,$("then")):c.if((0,e.not)(m),$("else"));i.pass(f,()=>i.error(!0));function y(){const S=i.subschema({keyword:"if",compositeRule:!0,createErrors:!1,allErrors:!1},m);i.mergeEvaluated(S)}function $(S,g){return()=>{const _=i.subschema({keyword:S},m);c.assign(f,m),i.mergeValidEvaluated(_,f),g?c.assign(g,(0,e._)`${S}`):i.setParams({ifClause:S})}}}};function o(i,c){const s=i.schema[c];return s!==void 0&&!(0,t.alwaysValidSchema)(i,s)}return Ft.default=n,Ft}var Ut={},ui;function Yo(){if(ui)return Ut;ui=1,Object.defineProperty(Ut,"__esModule",{value:!0});const e=Z(),t={keyword:["then","else"],schemaType:["object","boolean"],code({keyword:r,parentSchema:n,it:o}){n.if===void 0&&(0,e.checkStrictMode)(o,`"${r}" without "if" is ignored`)}};return Ut.default=t,Ut}var di;function Jo(){if(di)return At;di=1,Object.defineProperty(At,"__esModule",{value:!0});const e=Ji(),t=Do(),r=Qi(),n=Fo(),o=Uo(),i=Hr(),c=zo(),s=Zi(),d=Vo(),u=Ko(),a=Bo(),f=Ho(),m=Go(),y=Wo(),$=Xo(),S=Yo();function g(_=!1){const p=[a.default,f.default,m.default,y.default,$.default,S.default,c.default,s.default,i.default,d.default,u.default];return _?p.push(t.default,n.default):p.push(e.default,r.default),p.push(o.default),p}return At.default=g,At}var zt={},Je={},li;function ea(){if(li)return Je;li=1,Object.defineProperty(Je,"__esModule",{value:!0}),Je.dynamicAnchor=void 0;const e=W(),t=Ce(),r=hr(),n=Kr(),o={keyword:"$dynamicAnchor",schemaType:"string",code:s=>i(s,s.schema)};function i(s,d){const{gen:u,it:a}=s;a.schemaEnv.root.dynamicAnchors[d]=!0;const f=(0,e._)`${t.default.dynamicAnchors}${(0,e.getProperty)(d)}`,m=a.errSchemaPath==="#"?a.validateName:c(s);u.if((0,e._)`!${f}`,()=>u.assign(f,m))}Je.dynamicAnchor=i;function c(s){const{schemaEnv:d,schema:u,self:a}=s.it,{root:f,baseId:m,localRefs:y,meta:$}=d.root,{schemaId:S}=a.opts,g=new r.SchemaEnv({schema:u,schemaId:S,root:f,baseId:m,localRefs:y,meta:$});return r.compileSchema.call(a,g),(0,n.getValidate)(s,g)}return Je.default=o,Je}var Qe={},fi;function ta(){if(fi)return Qe;fi=1,Object.defineProperty(Qe,"__esModule",{value:!0}),Qe.dynamicRef=void 0;const e=W(),t=Ce(),r=Kr(),n={keyword:"$dynamicRef",schemaType:"string",code:i=>o(i,i.schema)};function o(i,c){const{gen:s,keyword:d,it:u}=i;if(c[0]!=="#")throw new Error(`"${d}" only supports hash fragment reference`);const a=c.slice(1);if(u.allErrors)f();else{const y=s.let("valid",!1);f(y),i.ok(y)}function f(y){if(u.schemaEnv.root.dynamicAnchors[a]){const $=s.let("_v",(0,e._)`${t.default.dynamicAnchors}${(0,e.getProperty)(a)}`);s.if($,m($,y),m(u.validateName,y))}else m(u.validateName,y)()}function m(y,$){return $?()=>s.block(()=>{(0,r.callRef)(i,y),s.let($,!0)}):()=>(0,r.callRef)(i,y)}}return Qe.dynamicRef=o,Qe.default=n,Qe}var Vt={},mi;function Qo(){if(mi)return Vt;mi=1,Object.defineProperty(Vt,"__esModule",{value:!0});const e=ea(),t=Z(),r={keyword:"$recursiveAnchor",schemaType:"boolean",code(n){n.schema?(0,e.dynamicAnchor)(n,""):(0,t.checkStrictMode)(n.it,"$recursiveAnchor: false is ignored")}};return Vt.default=r,Vt}var Kt={},pi;function Zo(){if(pi)return Kt;pi=1,Object.defineProperty(Kt,"__esModule",{value:!0});const e=ta(),t={keyword:"$recursiveRef",schemaType:"string",code:r=>(0,e.dynamicRef)(r,r.schema)};return Kt.default=t,Kt}var hi;function es(){if(hi)return zt;hi=1,Object.defineProperty(zt,"__esModule",{value:!0});const e=ea(),t=ta(),r=Qo(),n=Zo(),o=[e.default,t.default,r.default,n.default];return zt.default=o,zt}var Bt={},Ht={},yi;function ts(){if(yi)return Ht;yi=1,Object.defineProperty(Ht,"__esModule",{value:!0});const e=Hr(),t={keyword:"dependentRequired",type:"object",schemaType:"object",error:e.error,code:r=>(0,e.validatePropertyDeps)(r)};return Ht.default=t,Ht}var Gt={},gi;function rs(){if(gi)return Gt;gi=1,Object.defineProperty(Gt,"__esModule",{value:!0});const e=Hr(),t={keyword:"dependentSchemas",type:"object",schemaType:"object",code:r=>(0,e.validateSchemaDeps)(r)};return Gt.default=t,Gt}var Wt={},vi;function ns(){if(vi)return Wt;vi=1,Object.defineProperty(Wt,"__esModule",{value:!0});const e=Z(),t={keyword:["maxContains","minContains"],type:"array",schemaType:"number",code({keyword:r,parentSchema:n,it:o}){n.contains===void 0&&(0,e.checkStrictMode)(o,`"${r}" without "contains" is ignored`)}};return Wt.default=t,Wt}var bi;function is(){if(bi)return Bt;bi=1,Object.defineProperty(Bt,"__esModule",{value:!0});const e=ts(),t=rs(),r=ns(),n=[e.default,t.default,r.default];return Bt.default=n,Bt}var Xt={},Yt={},_i;function as(){if(_i)return Yt;_i=1,Object.defineProperty(Yt,"__esModule",{value:!0});const e=W(),t=Z(),r=Ce(),o={keyword:"unevaluatedProperties",type:"object",schemaType:["boolean","object"],trackErrors:!0,error:{message:"must NOT have unevaluated properties",params:({params:i})=>(0,e._)`{unevaluatedProperty: ${i.unevaluatedProperty}}`},code(i){const{gen:c,schema:s,data:d,errsCount:u,it:a}=i;if(!u)throw new Error("ajv implementation error");const{allErrors:f,props:m}=a;m instanceof e.Name?c.if((0,e._)`${m} !== true`,()=>c.forIn("key",d,g=>c.if($(m,g),()=>y(g)))):m!==!0&&c.forIn("key",d,g=>m===void 0?y(g):c.if(S(m,g),()=>y(g))),a.props=!0,i.ok((0,e._)`${u} === ${r.default.errors}`);function y(g){if(s===!1){i.setParams({unevaluatedProperty:g}),i.error(),f||c.break();return}if(!(0,t.alwaysValidSchema)(a,s)){const _=c.name("valid");i.subschema({keyword:"unevaluatedProperties",dataProp:g,dataPropType:t.Type.Str},_),f||c.if((0,e.not)(_),()=>c.break())}}function $(g,_){return(0,e._)`!${g} || !${g}[${_}]`}function S(g,_){const p=[];for(const w in g)g[w]===!0&&p.push((0,e._)`${_} !== ${w}`);return(0,e.and)(...p)}}};return Yt.default=o,Yt}var Jt={},$i;function os(){if($i)return Jt;$i=1,Object.defineProperty(Jt,"__esModule",{value:!0});const e=W(),t=Z(),n={keyword:"unevaluatedItems",type:"array",schemaType:["boolean","object"],error:{message:({params:{len:o}})=>(0,e.str)`must NOT have more than ${o} items`,params:({params:{len:o}})=>(0,e._)`{limit: ${o}}`},code(o){const{gen:i,schema:c,data:s,it:d}=o,u=d.items||0;if(u===!0)return;const a=i.const("len",(0,e._)`${s}.length`);if(c===!1)o.setParams({len:u}),o.fail((0,e._)`${a} > ${u}`);else if(typeof c=="object"&&!(0,t.alwaysValidSchema)(d,c)){const m=i.var("valid",(0,e._)`${a} <= ${u}`);i.if((0,e.not)(m),()=>f(m,u)),o.ok(m)}d.items=!0;function f(m,y){i.forRange("i",y,a,$=>{o.subschema({keyword:"unevaluatedItems",dataProp:$,dataPropType:t.Type.Num},m),d.allErrors||i.if((0,e.not)(m),()=>i.break())})}}};return Jt.default=n,Jt}var wi;function ss(){if(wi)return Xt;wi=1,Object.defineProperty(Xt,"__esModule",{value:!0});const e=as(),t=os(),r=[e.default,t.default];return Xt.default=r,Xt}var Qt={},Zt={},Si;function cs(){if(Si)return Zt;Si=1,Object.defineProperty(Zt,"__esModule",{value:!0});const e=W(),r={keyword:"format",type:["number","string"],schemaType:"string",$data:!0,error:{message:({schemaCode:n})=>(0,e.str)`must match format "${n}"`,params:({schemaCode:n})=>(0,e._)`{format: ${n}}`},code(n,o){const{gen:i,data:c,$data:s,schema:d,schemaCode:u,it:a}=n,{opts:f,errSchemaPath:m,schemaEnv:y,self:$}=a;if(!f.validateFormats)return;s?S():g();function S(){const _=i.scopeValue("formats",{ref:$.formats,code:f.code.formats}),p=i.const("fDef",(0,e._)`${_}[${u}]`),w=i.let("fType"),E=i.let("format");i.if((0,e._)`typeof ${p} == "object" && !(${p} instanceof RegExp)`,()=>i.assign(w,(0,e._)`${p}.type || "string"`).assign(E,(0,e._)`${p}.validate`),()=>i.assign(w,(0,e._)`"string"`).assign(E,p)),n.fail$data((0,e.or)(l(),h()));function l(){return f.strictSchema===!1?e.nil:(0,e._)`${u} && !${E}`}function h(){const v=y.$async?(0,e._)`(${p}.async ? await ${E}(${c}) : ${E}(${c}))`:(0,e._)`${E}(${c})`,I=(0,e._)`(typeof ${E} == "function" ? ${v} : ${E}.test(${c}))`;return(0,e._)`${E} && ${E} !== true && ${w} === ${o} && !${I}`}}function g(){const _=$.formats[d];if(!_){l();return}if(_===!0)return;const[p,w,E]=h(_);p===o&&n.pass(v());function l(){if(f.strictSchema===!1){$.logger.warn(I());return}throw new Error(I());function I(){return`unknown format "${d}" ignored in schema at path "${m}"`}}function h(I){const O=I instanceof RegExp?(0,e.regexpCode)(I):f.code.formats?(0,e._)`${f.code.formats}${(0,e.getProperty)(d)}`:void 0,A=i.scopeValue("formats",{key:d,ref:I,code:O});return typeof I=="object"&&!(I instanceof RegExp)?[I.type||"string",I.validate,(0,e._)`${A}.validate`]:["string",I,A]}function v(){if(typeof _=="object"&&!(_ instanceof RegExp)&&_.async){if(!y.$async)throw new Error("async format in sync schema");return(0,e._)`await ${E}(${c})`}return typeof w=="function"?(0,e._)`${E}(${c})`:(0,e._)`${E}.test(${c})`}}}};return Zt.default=r,Zt}var Ei;function us(){if(Ei)return Qt;Ei=1,Object.defineProperty(Qt,"__esModule",{value:!0});const t=[cs().default];return Qt.default=t,Qt}var ze={},Pi;function ds(){return Pi||(Pi=1,Object.defineProperty(ze,"__esModule",{value:!0}),ze.contentVocabulary=ze.metadataVocabulary=void 0,ze.metadataVocabulary=["title","description","default","deprecated","readOnly","writeOnly","examples"],ze.contentVocabulary=["contentMediaType","contentEncoding","contentSchema"]),ze}var Ii;function ls(){if(Ii)return ft;Ii=1,Object.defineProperty(ft,"__esModule",{value:!0});const e=Io(),t=Lo(),r=Jo(),n=es(),o=is(),i=ss(),c=us(),s=ds(),d=[n.default,e.default,t.default,(0,r.default)(!0),c.default,s.metadataVocabulary,s.contentVocabulary,o.default,i.default];return ft.default=d,ft}var er={},rt={},Ri;function fs(){if(Ri)return rt;Ri=1,Object.defineProperty(rt,"__esModule",{value:!0}),rt.DiscrError=void 0;var e;return(function(t){t.Tag="tag",t.Mapping="mapping"})(e||(rt.DiscrError=e={})),rt}var Ai;function ms(){if(Ai)return er;Ai=1,Object.defineProperty(er,"__esModule",{value:!0});const e=W(),t=fs(),r=hr(),n=pr(),o=Z(),c={keyword:"discriminator",type:"object",schemaType:"object",error:{message:({params:{discrError:s,tagName:d}})=>s===t.DiscrError.Tag?`tag "${d}" must be string`:`value of tag "${d}" must be in oneOf`,params:({params:{discrError:s,tag:d,tagName:u}})=>(0,e._)`{error: ${s}, tag: ${u}, tagValue: ${d}}`},code(s){const{gen:d,data:u,schema:a,parentSchema:f,it:m}=s,{oneOf:y}=f;if(!m.opts.discriminator)throw new Error("discriminator: requires discriminator option");const $=a.propertyName;if(typeof $!="string")throw new Error("discriminator: requires propertyName");if(a.mapping)throw new Error("discriminator: mapping is not supported");if(!y)throw new Error("discriminator: requires oneOf keyword");const S=d.let("valid",!1),g=d.const("tag",(0,e._)`${u}${(0,e.getProperty)($)}`);d.if((0,e._)`typeof ${g} == "string"`,()=>_(),()=>s.error(!1,{discrError:t.DiscrError.Tag,tag:g,tagName:$})),s.ok(S);function _(){const E=w();d.if(!1);for(const l in E)d.elseIf((0,e._)`${g} === ${l}`),d.assign(S,p(E[l]));d.else(),s.error(!1,{discrError:t.DiscrError.Mapping,tag:g,tagName:$}),d.endIf()}function p(E){const l=d.name("valid"),h=s.subschema({keyword:"oneOf",schemaProp:E},l);return s.mergeEvaluated(h,e.Name),l}function w(){var E;const l={},h=I(f);let v=!0;for(let M=0;Mthis.addMetaSchema(m,void 0,!1)),this;function f(m,y){return a?m.$dataMetaSchema(y,d):y}}return tr.default=u,tr}var Ci;function Cc(){return Ci||(Ci=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MissingRefError=t.ValidationError=t.CodeGen=t.Name=t.nil=t.stringify=t.str=t._=t.KeywordCxt=t.Ajv2020=void 0;const r=Eo(),n=ls(),o=ms(),i=kc(),c="https://json-schema.org/draft/2020-12/schema";class s extends r.default{constructor(y={}){super({...y,dynamicRef:!0,next:!0,unevaluated:!0})}_addVocabularies(){super._addVocabularies(),n.default.forEach(y=>this.addVocabulary(y)),this.opts.discriminator&&this.addKeyword(o.default)}_addDefaultMetaSchema(){super._addDefaultMetaSchema();const{$data:y,meta:$}=this.opts;$&&(i.default.call(this,y),this.refs["http://json-schema.org/schema"]=c)}defaultMeta(){return this.opts.defaultMeta=super.defaultMeta()||(this.getSchema(c)?c:void 0)}}t.Ajv2020=s,e.exports=t=s,e.exports.Ajv2020=s,Object.defineProperty(t,"__esModule",{value:!0}),t.default=s;var d=mr();Object.defineProperty(t,"KeywordCxt",{enumerable:!0,get:function(){return d.KeywordCxt}});var u=W();Object.defineProperty(t,"_",{enumerable:!0,get:function(){return u._}}),Object.defineProperty(t,"str",{enumerable:!0,get:function(){return u.str}}),Object.defineProperty(t,"stringify",{enumerable:!0,get:function(){return u.stringify}}),Object.defineProperty(t,"nil",{enumerable:!0,get:function(){return u.nil}}),Object.defineProperty(t,"Name",{enumerable:!0,get:function(){return u.Name}}),Object.defineProperty(t,"CodeGen",{enumerable:!0,get:function(){return u.CodeGen}});var a=Vr();Object.defineProperty(t,"ValidationError",{enumerable:!0,get:function(){return a.default}});var f=pr();Object.defineProperty(t,"MissingRefError",{enumerable:!0,get:function(){return f.default}})})(st,st.exports)),st.exports}var Nc=Cc();const Tc=so(Nc),ra={providerAdvertisement:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.provider_advertisement.v1",title:"Eve Provider Advertisement",type:"object",required:["schema","providerId","serviceId","verseId","title","kind","freshness","schemas","witnesses","surfaces","commands"],properties:{schema:{const:"gamecult.eve.provider_advertisement.v1"},providerId:{type:"string",minLength:1},serviceId:{type:"string",minLength:1},verseId:{type:"string",minLength:1},rootVerse:{type:"string",minLength:1},canonicalService:{type:"string"},locatedService:{type:"string"},cultMeshAddress:{type:"string"},title:{type:"string",minLength:1},kind:{type:"string",minLength:1},updatedAt:{type:"string"},updatedAtUtc:{type:"string"},freshness:{type:"object",required:["state"],properties:{state:{type:"string",minLength:1},lastSeenAt:{type:"string"},lastSeenAtUtc:{type:"string"},maxAgeMs:{type:"number"}},additionalProperties:!0},schemas:{type:"array",items:{type:["string","object"]}},witnesses:{type:"array",items:{type:"object",required:["kind"],properties:{kind:{type:"string",minLength:1},ref:{type:"string"},path:{type:"string"},summary:{type:"string"}},additionalProperties:!0}},surfaces:{type:"array",items:{type:"object",required:["surfaceId","schema","transport"],properties:{surfaceId:{type:"string",minLength:1},schema:{type:"string",minLength:1},key:{type:"string"},recordRef:{type:"string"},url:{type:"string"},transport:{type:"string",minLength:1},status:{type:"string",minLength:1},surfaceKind:{type:"string",minLength:1},interactionModel:{type:"string",minLength:1},worldInteraction:{type:"object",required:["projectionKind","stateSchemas","commandBoundary","receiptSchema","loweringTargets","ownership"],properties:{projectionKind:{type:"string",minLength:1},stateSchemas:{type:"array",items:{type:"string",minLength:1}},commandBoundary:{type:"string",minLength:1},commandRecordRef:{type:"string"},receiptSchema:{type:"string",minLength:1},receiptRecordRef:{type:"string"},assetManifestRecordRef:{type:"string"},loweringTargets:{type:"array",items:{type:"string",minLength:1}},ownership:{type:"string",minLength:1}},additionalProperties:!0},requiresPlugins:{type:"array",items:{type:"object",required:["pluginId","requiredCapabilities"],properties:{pluginId:{type:"string",minLength:1},versionRange:{type:"string"},availability:{type:"string",enum:["required","optional","optional-nested"]},requiredCapabilities:{type:"array",items:{type:"string",minLength:1}},optionalCapabilities:{type:"array",items:{type:"string",minLength:1}}},allOf:[{if:{properties:{availability:{const:"required"}}},then:{properties:{requiredCapabilities:{minItems:1}}}},{if:{required:["availability"],properties:{availability:{const:"optional-nested"}}},then:{required:["optionalCapabilities"],properties:{requiredCapabilities:{maxItems:0},optionalCapabilities:{minItems:1}}}}],additionalProperties:!0}}},additionalProperties:!0}},commands:{type:"array",items:{type:"object",required:["command","transport"],properties:{command:{type:"string",minLength:1},transport:{type:"string",minLength:1},summary:{type:"string"}},additionalProperties:!0}},conformanceScenarios:{type:"array",items:{type:"object",required:["scenarioId","schema","path"],properties:{scenarioId:{type:"string",minLength:1},schema:{type:"string",minLength:1},path:{type:"string",minLength:1},summary:{type:"string"}},additionalProperties:!0}}},additionalProperties:!0},surface:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.surface.v1",title:"Eve Surface Document",type:"object",required:["type","schema","providerId","providerKind","title","version","surface","commands"],properties:{type:{const:"surface-state"},schema:{const:"gamecult.eve.surface.v1"},providerId:{type:"string",minLength:1},providerKind:{type:"string",minLength:1},title:{type:"string",minLength:1},version:{type:"integer",minimum:0},updatedAt:{type:"string",minLength:1},updatedAtUtc:{type:"string",minLength:1},surface:{type:"object",required:["root","styles"],properties:{id:{type:"string"},title:{type:"string"},root:{$ref:"#/$defs/component"},styles:{type:["object","array"]}},additionalProperties:!0},commands:{type:"array",items:{$ref:"gamecult.eve.command.v1"}},nodes:{type:"array",items:{type:"object"}},selectedNodeId:{type:"string"}},$defs:{component:{type:"object",required:["id","kind","props","children"],properties:{id:{type:"string",minLength:1},kind:{type:"string",minLength:1},props:{type:"object"},children:{type:"array",items:{$ref:"#/$defs/component"}},stateBindings:{type:"array",items:{type:"object",required:["targetProp","pointerId","sourceId","schemaId","routeKind"],properties:{targetProp:{type:"string",minLength:1},pointerId:{type:"string",minLength:1},sourceId:{type:"string",minLength:1},schemaId:{type:"string",minLength:1},routeKind:{type:"string",minLength:1},routeDescription:{type:"string"},bindingName:{type:"string",minLength:1},documentId:{type:"string"},fieldPath:{type:"string"},valueKind:{type:"string",enum:["string","number","boolean","choice","string-list"]},accessMode:{type:"string",enum:["read","write","read-write","local-draft"]},authority:{type:"string"},writeCommand:{type:"string"}},additionalProperties:!0}},embeddedDocuments:{type:"array",items:{type:"object",required:["slotId","documentId","schemaId","presentationKind"],properties:{slotId:{type:"string",minLength:1},documentId:{type:"string",minLength:1},schemaId:{type:"string",minLength:1},presentationKind:{type:"string",minLength:1},routeHint:{type:["string","object"]}},additionalProperties:!0}}},additionalProperties:!0}},anyOf:[{required:["updatedAt"]},{required:["updatedAtUtc"]}],additionalProperties:!0},commandDescriptor:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.command.v1",title:"Eve Command Descriptor",type:"object",required:["schema","command"],properties:{schema:{const:"gamecult.eve.command.v1"},command:{type:"string",minLength:1},label:{type:"string"},surfaceId:{type:"string"},transport:{type:"string"},authority:{type:"string"},result:{type:"string"},payloadSchema:{type:"string"},captureBindings:{type:"array",items:{type:"string",minLength:1},uniqueItems:!0}},additionalProperties:!0},commandInvocation:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.command_invocation.v1",title:"Eve Command Invocation",type:"object",required:["schema","providerId","surfaceId","operation","payload","issuedAt","clientId","commandBoundary","receiptSchema"],properties:{schema:{const:"gamecult.eve.command_invocation.v1"},providerId:{type:"string",minLength:1},surfaceId:{type:"string",minLength:1},operation:{type:"object",required:["operationId"],properties:{operationId:{type:"string",minLength:1},schemaId:{type:"string"},idempotencyKey:{type:"string"},routeHint:{type:"object"}},additionalProperties:!0},payload:{type:"object"},issuedAt:{type:"string"},clientId:{type:"string",minLength:1},commandBoundary:{type:"string",minLength:1},receiptSchema:{type:"string",minLength:1}},additionalProperties:!1},commandReceipt:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.command_receipt.v1",title:"Eve Command Receipt",type:"object",required:["schema","receiptId","commandId","command","state","ownerRepo","authority","providerId","surfaceId","sourceVersion"],properties:{schema:{const:"gamecult.eve.command_receipt.v1"},receiptId:{type:"string",minLength:1},commandId:{type:"string"},command:{type:"string",minLength:1},state:{type:"string",enum:["accepted","denied","pending","reconciled"]},ownerRepo:{type:"string",minLength:1},authority:{type:"string",minLength:1},providerId:{type:"string"},surfaceId:{type:"string"},message:{type:"string"},diagnostics:{type:"array",items:{type:"object"}},issuedAtUtc:{type:"string"},sourceVersion:{type:"integer",minimum:0},navigation:{type:"object",required:["verseId","surfaceId"],properties:{verseId:{type:"string",minLength:1},providerId:{type:"string"},surfaceId:{type:"string",minLength:1},surfaceKind:{type:"string"},rendezvousEndpoints:{type:"array",items:{type:"string",minLength:1},uniqueItems:!0}},additionalProperties:!1}},additionalProperties:!0},commandResult:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.command_result.v1",title:"Eve Command Result",type:"object",required:["schema","receipt"],properties:{schema:{const:"gamecult.eve.command_result.v1"},receipt:{$ref:"gamecult.eve.command_receipt.v1"},transientProjection:{type:"object",required:["schema"],properties:{schema:{const:"gamecult.eve.surface.v1"}},additionalProperties:!0},pluginPayload:{type:"object",required:["pluginId","schemaId","payload"],properties:{pluginId:{type:"string",minLength:1},schemaId:{type:"string",minLength:1},payload:{type:"object"}},additionalProperties:!1},draftDirective:{type:"object",required:["clear"],properties:{clear:{type:"boolean"},bindingNames:{type:"array",items:{type:"string",minLength:1},uniqueItems:!0}},additionalProperties:!1}},additionalProperties:!1},inputCapability:{$schema:"https://json-schema.org/draft/2020-12/schema",$id:"gamecult.eve.input_capability.v1",title:"Eve Input Capability",type:"object",required:["schema","providerId","capabilityId","actions","defaultProfiles"],properties:{schema:{const:"gamecult.eve.input_capability.v1"},providerId:{type:"string",minLength:1},capabilityId:{type:"string",minLength:1},version:{type:"integer",minimum:0},actions:{type:"array",items:{type:"object",required:["actionId","label","operation","availability"],properties:{actionId:{type:"string",minLength:1},label:{type:"string",minLength:1},operation:{type:"string",minLength:1},context:{type:"string"},category:{type:"string"},iconRef:{type:"string"},actionBar:{type:"boolean"},availability:{enum:["available","dormant","unavailable"]},sourceRef:{type:"string"},payload:{type:"object",additionalProperties:{type:"string"}},inputValue:{$ref:"#/$defs/inputValue"}},additionalProperties:!1}},defaultProfiles:{type:"array",items:{type:"object",required:["profileId","deviceClass","bindings"],properties:{profileId:{type:"string",minLength:1},deviceClass:{enum:["keyboard-mouse","gamepad"]},bindings:{type:"array",items:{$ref:"#/$defs/binding"}}},additionalProperties:!1}}},$defs:{inputValue:{type:"object",required:["model"],properties:{model:{enum:["button-hold.v1","axis.v1","scalar.v1","view-direction.v1"]},payloadKey:{type:"string",minLength:1},currentValue:{type:"number"},minimumValue:{type:"number"},maximumValue:{type:"number"},stepValue:{type:"number",exclusiveMinimum:0},unit:{type:"string",minLength:1},payloadKeys:{type:"array",minItems:3,maxItems:3,uniqueItems:!0,items:{type:"string",minLength:1}}},allOf:[{if:{properties:{model:{const:"view-direction.v1"}},required:["model"]},then:{required:["payloadKeys"]},else:{required:["payloadKey"]}},{if:{properties:{model:{const:"scalar.v1"}},required:["model"]},then:{required:["currentValue"]}}],additionalProperties:!1},gesture:{type:"object",required:["kind","controls"],properties:{kind:{enum:["direct","chord","sequence","axis"]},controls:{type:"array",minItems:1,items:{type:"string",minLength:1}},maxStepIntervalMs:{type:"integer",minimum:50},completionControl:{type:"string"}},additionalProperties:!1},binding:{type:"object",required:["bindingId","actionId","gesture"],properties:{bindingId:{type:"string",minLength:1},actionId:{type:"string",minLength:1},gesture:{$ref:"#/$defs/gesture"},actionBar:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1}},Gr=new Tc({allErrors:!0,allowUnionTypes:!0,strict:!0,strictRequired:!1,strictTypes:!1});for(const e of Object.values(ra))Gr.addSchema(e);const jc=Object.fromEntries(Object.entries(ra).map(([e,t])=>[e,xc(t.$id)]));class Oc extends TypeError{contract;errors;constructor(t,r){super(`Invalid Eve ${t}: ${Gr.errorsText(r,{separator:"; "})}`),this.name="EveContractValidationError",this.contract=t,this.errors=r}}function na(e,t){const r=jc[e];if(!r(t))throw new Oc(e,r.errors??[]);return t}const Mc=e=>na("surface",e),qc=e=>{const t=na("commandResult",e);return t.transientProjection&&Mc(t.transientProjection),t};function xc(e){const t=Gr.getSchema(e);if(!t)throw new Error(`Eve contract schema ${e} was not registered.`);return t}class ia{values=new Map;key(t,r,n){return`${t}${r}${n}`}has(t,r,n){return this.values.has(this.key(t,r,n))}get(t,r,n){return this.values.get(this.key(t,r,n))}set(t,r,n,o){this.values.set(this.key(t,r,n),o)}clear(t,r,n){if(n?.length){for(const i of n)this.values.delete(this.key(t,r,i));return}const o=`${t}${r}`;for(const i of this.values.keys())i.startsWith(o)&&this.values.delete(i)}capture(t,r,n){return Object.fromEntries(n.map(o=>[o,this.get(t,r,o)]))}}const Wr=[ja];function Lc(e,t=Wr){const r=[];for(const n of e.requiresPlugins||[]){const o=t.find(c=>c.pluginId===n.pluginId);if(!o){if((n.availability||"required")==="required")throw new Error(`Missing required Eve plugin adapter ${n.pluginId}.`);continue}const i=(n.requiredCapabilities||[]).filter(c=>!o.capabilities.includes(c));if(i.length>0)throw new Error(`Eve plugin adapter ${n.pluginId} lacks required capabilities: ${i.join(", ")}.`);r.push(o)}return r}function Dc(e,t=""){const r=e.surfaces||e.localAdvertisement?.surfaces||[],n=t?r.find(o=>o.surfaceId===t):r.find(o=>o.status!=="unavailable")??r[0];if(!n?.surfaceId)throw new Error(`Provider ${e.providerId||"(unknown)"} does not advertise surface ${t||"(first available)"}.`);return n}class Fc{host;transport;options;active=!1;lastSurfaceVersion="";pollHandle;provider;selected;pluginAdapters=[];draftStore=new ia;constructor(t,r,n={}){this.host=t,this.transport=r,this.options=n}async start(){try{this.provider=await this.transport.providerAdvertisement(),this.selected=Dc(this.provider,this.options.requestedSurfaceId),Uc(this.selected),this.pluginAdapters=Lc(this.selected,this.options.pluginAdapters||Wr)}catch(r){const n=r instanceof Error?r.message:"Eve provider capabilities are unavailable.";throw this.host.replaceChildren(Le(n)),this.options.statusElement&&(this.options.statusElement.textContent=n),r}this.active=!0,await this.refresh();const t=Math.max(0,this.options.pollMs??250);t>0&&(this.pollHandle=window.setInterval(()=>{this.refresh()},t))}stop(){this.active=!1,this.pollHandle!==void 0&&window.clearInterval(this.pollHandle),this.pollHandle=void 0}async refresh(){if(!(!this.active||!this.provider||!this.selected))try{const t=await this.transport.surface(this.selected),r=`${t.providerId||""}:${t.surface?.id||""}:${t.version??""}`;if(r===this.lastSurfaceVersion)return;this.lastSurfaceVersion=r,Kc(t,this.host,{activeSurfaceId:this.selected.surfaceId,assetUrlResolver:this.transport.resolveAssetUrl,body:this.options.body,clientId:this.options.clientId||"eve-browser",commandSink:n=>this.submit(n),documentResolver:this.transport.resolveDocument,provider:this.provider,pluginAdapters:this.pluginAdapters,source:this.options.source,statusElement:this.options.statusElement,draftStore:this.draftStore})}catch(t){this.options.statusElement&&(this.options.statusElement.textContent=t instanceof Error?t.message:"Eve surface unavailable.")}}async submit(t){try{const r=qc(await this.transport.submitCommand(t));await this.consumeCommandResult(t,r)}catch(r){this.presentCommandStatus(r instanceof Error?r.message:"Command failed.","error");return}this.lastSurfaceVersion="",window.setTimeout(()=>{this.refresh()},100)}async consumeCommandResult(t,r){const n=r.receipt.state==="accepted"||r.receipt.state==="reconciled";if(n&&r.draftDirective?.clear&&this.draftStore.clear(t.providerId,t.surfaceId,r.draftDirective.bindingNames),r.pluginPayload){const o=this.pluginAdapters.find(i=>i.pluginId===r.pluginPayload?.pluginId);if(!o?.consumeCommandResult)throw new Error(`No Eve plugin adapter can consume ${r.pluginPayload.pluginId}.`);await o.consumeCommandResult(r.pluginPayload,r,{provider:this.provider,surface:this.selected})}this.presentCommandStatus(r.receipt.message||r.receipt.state,n?"status":"error",r.transientProjection)}presentCommandStatus(t,r,n){let o=this.host.querySelector(":scope > .eve-command-result-region");o||(o=j("section","eve-command-result-region"),o.setAttribute("aria-live","polite"),this.host.append(o)),o.setAttribute("role",r),o.replaceChildren(j("p","eve-command-result-message",t));const i=n;i?.surface?.root&&o.append(le(i.surface.root,{activeSurfaceId:i.surface.id||this.selected?.surfaceId,clientId:this.options.clientId,draftStore:this.draftStore,pluginAdapters:this.pluginAdapters,provider:this.provider}))}}function Uc(e){if(!e.worldInteraction?.commandBoundary||!e.worldInteraction.receiptSchema)throw new Error(`Eve surface ${e.surfaceId||"(unknown)"} does not advertise a command boundary and receipt schema.`)}const zc={"--bg":"#020909","--bg-top":"#020909","--bg-mid":"#020909","--bg-bottom":"#020909","--shell-top":"#010707","--shell-bottom":"#010707","--panel":"#071918","--panel-2":"#0a2423","--line":"rgba(103, 240, 228, 0.28)","--line-deep":"rgba(103, 240, 228, 0.18)","--text":"#e7f1f1","--text-bright":"#e7f1f1","--quiet":"#8ba5a3","--accent":"#ffb84f","--accent-strong":"#ffb84f","--corner-accent":"#ffb84f","--cyan":"#8efcff","--shadow":"rgba(0, 0, 0, 0.35)","--pixel-grid":"rgba(142, 252, 255, 0.04)","--border-width":"1px","--border-bottom-width":"1px","--corner-accent-size":"0","--font-body":'"M PLUS 1", "Ubuntu Sans", Ubuntu, "Noto Sans JP", system-ui, sans-serif',"--font-title":'"Montserrat", "Zen Kaku Gothic New", "M PLUS 1", "Ubuntu Sans", system-ui, sans-serif',"--font-mono":'"Ubuntu Sans Mono", "M PLUS 1 Code", "Cascadia Mono", Consolas, monospace'},Ni=new Map,Ti=new WeakMap,ji=new WeakMap,aa=Symbol("eve.browser.render-context");function Vc(e,t){return{...t,[aa]:{surface:e,styles:ma(e.surface?.styles),elements:new WeakMap}}}function Ke(e){return e[aa]}function Kc(e,t,r={}){Ti.get(t)?.dispose();let n=r.draftStore||ji.get(t);n||(n=new ia,ji.set(t,n));const o=Vc(e,{...r,draftStore:n});if(fu(e.surface?.styles,r.body??t),t.dataset.provider=e.providerId||r.provider?.providerId||"",r.body&&(r.body.dataset.provider=e.providerId||r.provider?.providerId||""),r.statusElement&&(r.statusElement.textContent=`${e.title||e.surface?.title||"surface"}${r.source?` (${r.source})`:""}`),e.surface?.root){if(t.replaceChildren(le(e.surface.root,o)),r.stateBindingResolver){const i=new Bc(e,t,o);Ti.set(t,i),i.start()}}else t.replaceChildren(Le("No surface root"));return t}function Oi(e,t,r){const n=t.targetProp.split(".").filter(Boolean);if(n.length===0)throw new Error("Eve state binding targetProp must not be empty.");e.props||={};let o=e.props;for(const i of n.slice(0,-1)){const c=o[i];(!c||typeof c!="object"||Array.isArray(c))&&(o[i]={}),o=o[i]}o[n[n.length-1]]=r}class Bc{surface;host;options;disposed=!1;unsubscribers=[];pendingComponents=new Set;projectionQueued=!1;constructor(t,r,n){this.surface=t,this.host=r,this.options=n}async start(){const t=this.options.stateBindingResolver,r=this.surface.surface?.root;if(!t||!r)return;const n=new Set;for(const o of oa(r))for(const i of o.stateBindings||[]){if(this.disposed)return;const c=await t(i,o);if(!c||this.disposed)continue;const s=d=>{this.disposed||(Oi(o,i,d),this.queueComponentProjection(o))};if(Oi(o,i,await c.latest()),n.add(o),this.disposed)return;this.unsubscribers.push(c.watch(s))}for(const o of n){if(this.disposed)return;this.renderComponentProjection(o)}}dispose(){this.disposed=!0,this.pendingComponents.clear();for(const t of this.unsubscribers.splice(0))t()}queueComponentProjection(t){this.pendingComponents.add(t),!this.projectionQueued&&(this.projectionQueued=!0,queueMicrotask(()=>{if(this.projectionQueued=!1,!this.disposed){for(const r of this.pendingComponents)this.renderComponentProjection(r);this.pendingComponents.clear()}}))}renderComponentProjection(t){const r=Ke(this.options)?.elements.get(t);r?.isConnected&&Hc(r,le(t,this.options),this.host)}}function Hc(e,t,r){const n=e.ownerDocument.activeElement,o=n instanceof HTMLElement&&e.contains(n)?n:void 0,i=o?Gc(e,o):void 0,c=o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement?{start:o.selectionStart,end:o.selectionEnd,direction:o.selectionDirection}:void 0,s={left:r.scrollLeft,top:r.scrollTop};if(e.replaceWith(t),r.scrollLeft=s.left,r.scrollTop=s.top,!i)return;const d=Wc(t,i);d?.focus({preventScroll:!0}),c&&(d instanceof HTMLInputElement||d instanceof HTMLTextAreaElement)&&d.setSelectionRange(c.start,c.end,c.direction??void 0)}function Gc(e,t){if(e===t)return[];const r=[];let n=t;for(;n&&n!==e;){const o=n.parentElement;if(!o)return;r.unshift(Array.prototype.indexOf.call(o.children,n)),n=o}return n===e?r:void 0}function Wc(e,t){let r=e;for(const n of t){const o=r.children.item(n);if(!(o instanceof HTMLElement))return;r=o}return r instanceof HTMLElement?r:void 0}function*oa(e){yield e;for(const t of e.children||[])yield*oa(t)}function le(e,t={}){const r=Xc(e,t);return Ke(t)?.elements.set(e,r),r}function Xc(e,t){const r=e.kind||"panel",n=Q(e.props),o=Q(e.layout),i=Q(e.style),c=e.children||[],s=e.embeddedDocuments||[];if(r==="surface"||r==="cockpit"||r==="dashboard"){const a=j("section","cultui-surface-root eve-surface");te(a,e),typeof o.direction=="string"?a.dataset.direction=o.direction:typeof n.layout=="object"&&n.layout&&typeof n.layout.direction=="string"&&(a.dataset.direction=String(n.layout.direction)),r!=="surface"&&(a.dataset.surfaceKind=r),re(a,o,i);for(const f of c)a.append(le(f,t));return a}if(r==="column"||r==="row"||r==="form"||r==="rail"){const a=j("div",`cultui-partition eve-${r}`);te(a,e),a.dataset.direction=r==="row"||r==="rail"?"horizontal":"vertical",r==="rail"&&(a.dataset.overflow="x"),it(a,{...o,...n}),re(a,o,i);for(const f of c)a.append(le(f,t));return a}if(r==="grid"){const a=j("section","cultui-grid"),f=_e(n.columns,0);f>0?a.style.gridTemplateColumns=`repeat(${f}, minmax(0, 1fr))`:typeof n.columns=="string"&&(a.style.gridTemplateColumns=n.columns);const m=_e(n.rows,0);m>0&&(a.style.gridTemplateRows=`repeat(${m}, minmax(0, auto))`),re(a,o,i);for(const y of c)a.append(le(y,t));return a}if(r==="partition"){const a=j("section",`cultui-partition split-${K(n.split,"none")}`);te(a,e),it(a,n),re(a,o,i),a.style.minWidth="0",K(n.split,"none")==="x"&&!x(n.flexWrap,o.flexWrap,"")&&(a.style.flexWrap="wrap"),typeof n.role=="string"&&(a.dataset.role=n.role);for(const f of c)a.append(le(f,t));return a}if(r==="input.binding-map")return cu(e,n,t);if(r==="inventory.drag_session")return ru(e,n,o,i);if(r==="inventory.grid")return nu(e,n,o,i,t);if(r==="inventory.item")return iu(e,n,o,i);const d=(t.pluginAdapters||Wr).find(a=>a.componentKinds.includes(r));if(d?.renderComponent)return d.renderComponent(e,n,o,i,t,{applyGeneratedLayout:re,providerId:Ke(t)?.surface.providerId||t.provider?.providerId,resolveAssetUrl:a=>nt(a,t)});if(r==="world.scene3d"||r==="world.scene2d")return Jc(e,n,o,i,t);if(r==="image.background"){const a=j("div","cultui-background"),f=nt(x(n.src,n.assetUri,n.assetRef,""),t);return f&&(a.style.backgroundImage=`url("${f}")`),a.setAttribute("aria-label",K(n.label,"background")),a}if(r==="image.sprite"){const a=j("figure",`cultui-sprite ${K(n.slot,"center")}`);te(a,e);const f=nt(x(n.src,n.assetUri,n.assetRef,""),t);if(f){const m=j("img");m.src=f,m.alt=K(n.alt,K(n.actor,K(n.label,""))),a.append(m)}return a}if(r==="avatar"){const a=j("figure","cultui-avatar-card");te(a,e);const f=nt(x(n.src,n.assetUri,n.assetRef,""),t);if(f){const S=j("img");S.src=f,S.alt=K(n.alt,K(n.text,K(n.label,""))),a.append(S)}else a.append(j("div","cultui-avatar-fallback",Cu(x(n.text,n.label,n.actor,"?"))));const m=x(n.text,n.label,n.actor,"");m&&a.append(j("figcaption","cultui-avatar-name",m));const y=x(n.status,"");y&&a.append(j("div","cultui-avatar-status",y));const $=x(n.detail,"");return $&&a.append(j("div","cultui-avatar-detail",$)),a}if(r==="pane"||r==="panel"){const a=j("section","pane cultui-pane");te(a,e);const f=K(n.span,"");f&&(a.dataset.span=f);const m=K(n.density,"");m&&(a.dataset.density=m);const y=K(n.title,e.text||"");y&&a.append(j("h2","",y));for(const $ of c)a.append(le($,t));return a}if(r==="list"||r.endsWith(".roster")){const a=j("section","cultui-list");te(a,e),a.dataset.componentKind=r;const f=K(n.title,"");f&&a.append(j("h3","cultui-list-title",f));for(const[m,y]of Au(n.items).entries())a.append(le({id:`${e.id||"list"}-item-${m}`,kind:"list.item",props:{...y}},t));for(const m of c)a.append(le(m,t));return a}if(r==="list.item"||r.endsWith(".item")){const a=sa(e),f=j("article","cultui-list-item");te(f,e),f.dataset.componentKind=r;const m=j("div","cultui-list-item-heading");if(m.append(j("strong","cultui-list-item-label",a.label)),a.status&&m.append(j("span","cultui-list-item-status",a.status)),f.append(m),a.detail&&f.append(j("div","cultui-list-item-detail",a.detail)),a.badges.length){const y=j("div","cultui-list-item-badges");for(const $ of a.badges)y.append(j("span","cultui-list-item-badge",$));f.append(y)}for(const y of c)f.append(le(y,t));return f}if(r==="bar"){const a=j("div","cultui-meter");te(a,e);const f=K(n.label,""),m=K(n.value,"");if(f||m){const S=j("div","cultui-meter-head");S.append(j("span","",f)),S.append(j("strong","",m)),a.append(S)}const y=j("div","cultui-meter-track"),$=j("span","cultui-meter-fill");return $.style.width=`${Ui(n.percent)}%`,y.append($),a.append(y),a}if(r==="card"){const a=Lr(n,e),f=a?j("button","card cultui-card cultui-card-button"):j("article","card cultui-card");te(f,e),re(f,o,i),f instanceof HTMLButtonElement&&(f.type="button");const m=K(n.title,e.text||"");m&&f.append(j("div","card-title",m));for(const y of c)f.append(le(y,t));return a&&Fi(f,e,a,n,t),f}if(r==="control.button"){const a=j("button","cultui-button eve-control-button",K(n.label,"Action"));return te(a,e),a.type="button",re(a,o,i),Fi(a,e,Lr(n,e),n,t),a}if(r==="control.popup"){const a=j("button","cultui-button eve-control-popup",K(n.label,"Open"));return te(a,e),a.type="button",re(a,o,i),a.addEventListener("click",f=>{uu(e,t,a,f.clientX,f.clientY)}),a}if(r==="text.dialogue"||r==="text"||r==="text.title"||r==="text.subtitle"||r==="label"){const a=j("div",Su(r,n),K(n.value,K(n.text,e.text||"")));return te(a,e),it(a,n),re(a,o,i),a}if(r==="metric"){const a=j("dl","metric cultui-reactive-metric eve-metric");return te(a,e),re(a,o,i),a.append(j("dt","",K(n.label,"Metric"))),a.append(j("dd","metric-value",K(n.value,""))),a}if(r==="progress"){const a=j("div","cultui-meter eve-progress");te(a,e),re(a,o,i);const f=K(n.label,""),m=K(n.value,""),y=Number(n.min??0),$=Number(n.max??1),S=Number(n.value??0),g=Number.isFinite(S)&&Number.isFinite(y)&&Number.isFinite($)&&$!==y?(S-y)/($-y)*100:Ui(n.percent);if(f||m){const w=j("div","cultui-meter-head");w.append(j("span","",f)),w.append(j("strong","",m)),a.append(w)}const _=j("div","cultui-meter-track"),p=j("span","cultui-meter-fill");return p.style.width=`${Math.max(0,Math.min(100,g))}%`,_.append(p),a.append(_),a}if(r==="modal"){const a=j("section","cultui-modal-surface");te(a,e),re(a,o,i);const f=K(n.title,"");f&&a.append(j("h2","cultui-modal-surface-title",f));for(const m of c)a.append(le(m,t));return a}if(r==="options"){const a=j("section","cultui-options");te(a,e),re(a,o,i);const f=K(n.label,"");f&&a.append(j("h3","cultui-list-title",f));for(const m of c)a.append(le(m,t));return c.length===0&&a.append(Le("waiting for options")),a}if(r==="image.preview"){const a=j("figure","cultui-image-preview");te(a,e);const f=j("div","cultui-image-frame"),m=nt(x(n.src,n.assetUri,n.assetRef,""),t);if(m){const y=j("img");y.src=m,y.alt=K(n.label,""),y.style.imageRendering=K(n.imageRendering,"auto"),n.zoom!==void 0&&(y.style.transform=`scale(${n.zoom})`,y.style.transformOrigin=K(n.crop,"50% 50%")),f.append(y)}else f.append(j("span","",K(n.label,"image")));return a.append(f),n.label&&a.append(j("figcaption","",String(n.label))),a}if(r==="canvas.preview"||r==="canvas.editor"){const a=j("div",`cultui-canvas-placeholder ${r==="canvas.editor"?"editor":"preview"}`);return te(a,e),a.append(j("div","viz-label",K(n.label,"Canvas"))),a.append(j("div","cultui-canvas-grid",n.state==="empty"?"waiting for pixels":K(n.state,""))),a}if(r==="surface.slot"){const a=j("section","cultui-embedded-slot");te(a,e),re(a,o,i),a.dataset.slotId=K(n.slotId,K(s[0]?.slotId,"")),a.dataset.documentId=K(n.documentId,K(s[0]?.documentId,"")),a.dataset.schemaId=K(n.schemaId,K(s[0]?.schemaId,"")),a.dataset.presentationKind=K(n.presentationKind,K(s[0]?.presentationKind,""));const f=s.map(y=>Q(y.surface)).find(y=>Q(y.root).kind||y.root),m=n.modal===!0||a.dataset.presentationKind.includes("modal");if((f||a.dataset.documentId)&&m){const y=j("button","cultui-button cultui-modal-trigger",K(n.label,a.dataset.slotId||"Configure"));y.type="button",y.addEventListener("click",()=>fa(xr(e,t),t)),a.append(y)}else if(f||a.dataset.documentId){const y=j("div","cultui-embedded-slot-body");y.append(j("div","detail","materializing surface")),a.append(y),xr(e,t).then($=>{y.replaceChildren($?.root?le($.root,t):Le("Embedded surface unavailable"))}).catch($=>{y.replaceChildren(Le(`Embedded surface failed: ${$ instanceof Error?$.message:String($)}`))})}else a.append(j("div","detail",a.dataset.presentationKind||a.dataset.slotId||"embedded surface"));return a}if(r==="control.slider")return _u(n,c,t);if(r==="control.toggle"){const a=j("label","toggle-row cultui-toggle");return te(a,e),a.append(j("span","field-control",n.value?"on":"off")),a.append(j("span","toggle-copy",K(n.label,"Toggle"))),a}if(r==="input.select"||r==="control.select")return bu(e,n,c,o,i,t);if(r==="control.choice-group")return gu(e,n,c,o,i,t);if(r==="input.number"||r==="control.range"||r==="control.input.number"||r==="control.input.text"||r==="control.input.textarea")return yu(e,r,n,o,i,t);if(r==="control.tabs")return vu(e,n,c,o,i,t);if(r==="color.swatch"){const a=j("div","paint-swatch cultui-swatch");return te(a,e),a.style.background=K(n.value,K(n.color,"currentColor")),a.title=K(n.label,"Color"),a}const u=j("section","pane");te(u,e),u.append(j("h2","",r));for(const a of c)u.append(le(a,t));return u}function sa(e){const t=Q(e.props);return{label:x(t.label,t.title,t.displayName,e.text,e.kind,"item"),status:x(t.status,t.state,""),detail:x(t.detail,t.phase,t.repoName,""),badges:Array.isArray(t.badges)?t.badges.map(r=>String(r).trim()).filter(Boolean):x(t.badges,"").split(",").map(r=>r.trim()).filter(Boolean)}}function re(e,t,r={}){const n=x(t.display,"");n&&(e.style.display=n);const o=x(t.direction,"");o&&(e.style.flexDirection=o==="horizontal"?"row":o==="vertical"?"column":o);const i=x(t.flexWrap,"");i&&(e.style.flexWrap=i);const c=x(t.gridTemplateColumns,"");c&&(e.style.gridTemplateColumns=c);const s=x(t.gridTemplateRows,"");s&&(e.style.gridTemplateRows=s);const d=x(t.gridTemplateAreas,"");d&&(e.style.gridTemplateAreas=d);const u=x(t.gridArea,"");u&&(e.style.gridArea=u);const a=x(t.placeItems,"");a&&(e.style.placeItems=a),ve(e,"gap",x(t.gap,"")),ve(e,"padding",x(t.padding,"")),ve(e,"margin",x(t.margin,"")),ve(e,"top",x(t.top,"")),ve(e,"right",x(t.right,"")),ve(e,"bottom",x(t.bottom,"")),ve(e,"left",x(t.left,"")),ve(e,"width",x(t.width,"")),ve(e,"minWidth",x(t.minWidth,"")),ve(e,"maxWidth",x(t.maxWidth,"")),ve(e,"height",x(t.height,"")),ve(e,"minHeight",x(t.minHeight,"")),ve(e,"maxHeight",x(t.maxHeight,""));const f=x(t.alignItems,"");f&&(e.style.alignItems=f);const m=x(t.justifyContent,"");m&&(e.style.justifyContent=m);const y=x(t.alignSelf,"");y&&(e.style.alignSelf=y);const $=x(t.overflow,"");$&&(e.style.overflow=$);const S=x(t.overflowX,"");S&&(e.style.overflowX=S);const g=x(t.overflowY,"");g&&(e.style.overflowY=g);const _=x(t.position,"");_&&(e.style.position=_);const p=x(t.cursor,"");p&&(e.style.cursor=p);const w=x(r.background,"");w&&(e.style.background=or(w));const E=x(r.color,"");E&&(e.style.color=or(E)),ve(e,"borderWidth",x(r.borderWidth,""));const l=x(r.borderColor,"");l&&(e.style.borderColor=or(l));const h=x(r.borderStyle,"");h&&(e.style.borderStyle=h),ve(e,"borderRadius",x(r.borderRadius,""));const v=x(r.boxShadow,"");v&&(e.style.boxShadow=v);const I=x(r.font,"");I&&(e.style.font=I),ve(e,"fontSize",x(r.fontSize,""));const O=x(r.fontWeight,"");O&&(e.style.fontWeight=O);const A=x(r.textTransform,"");A&&(e.style.textTransform=A);const M=x(r.textAlign,"");M&&(e.style.textAlign=M);const L=x(r.whiteSpace,"");L&&(e.style.whiteSpace=L);const N=x(r.overflow,"");N&&(e.style.overflow=N);const z=x(r.textOverflow,"");z&&(e.style.textOverflow=z),ve(e,"lineHeight",x(r.lineHeight,""))}function ve(e,t,r){r&&(e.style[t]=ce(r))}function me(e,t){const r={};for(const[n,o]of Object.entries(e))n.startsWith(t)&&(r[n.slice(t.length)]=o);return r}function Yc(e){const t=(e.children||[]).filter(m=>m.kind==="world.entity3d"),r=t.map(m=>tu(Q(m.props).position,[0,0,0])),n=r.map(m=>m[0]),o=r.map(m=>m[2]),i=Math.min(...n,-1),c=Math.max(...n,1),s=Math.min(...o,-1),d=Math.max(...o,1),u=Math.max(1,c-i),a=Math.max(1,d-s),f=6;return t.map((m,y)=>{const $=Q(m.props);return{entityId:x($.entityId,m.id),faction:K($.faction,"neutral"),kind:K($.entityKind,"entity"),label:x($.label,$.entityId,m.id,"Entity"),controlled:Te($.controllable),xPercent:f+(r[y][0]-i)/u*(100-f*2),yPercent:f+(1-(r[y][2]-s)/a)*(100-f*2),source:m}})}function Jc(e,t,r,n,o){const i=j("section","cultui-world-scene");te(i,e),re(i,r,n),i.tabIndex=0,i.setAttribute("aria-label",K(t.label,"Interactive world"));const c=Yc(e),s=c.find(a=>a.controlled),d=j("div","cultui-world-heading");d.append(j("strong","",K(t.label,"World"))),d.append(j("span","",`${c.length} entities`)),i.append(d);const u=j("div","cultui-world-plane");for(const a of c){const f=j("button",`cultui-world-entity faction-${Mi(a.faction)} kind-${Mi(a.kind)}`);f.type="button",f.style.left=`${a.xPercent}%`,f.style.top=`${a.yPercent}%`,f.dataset.entityId=a.entityId,f.dataset.controlled=a.controlled?"true":"false",f.title=a.label,f.setAttribute("aria-label",`${a.label}, ${a.kind}, ${a.faction}`),f.append(j("span","cultui-world-entity-glyph",eu(a.kind))),f.append(j("span","cultui-world-entity-label",a.label));const m=Q(a.source.props),y=x(m.targetCommand,t.targetCommand,m.focusCommand,t.focusCommand);y&&f.addEventListener("click",()=>Nr(y,{actorEntityId:s?.entityId||x(t.playerEntityId),entityId:a.entityId,targetEntityId:a.entityId,targetEntityKey:a.entityId},a.source,o)),u.append(f)}return i.append(u),i.addEventListener("keydown",a=>{const f=Zc(a.key);if(f){a.preventDefault();const y=x(t.movementCommand,Q(s?.source.props).moveCommand);y&&Nr(y,{actorEntityId:s?.entityId||x(t.playerEntityId),actorEntityKey:s?.entityId||x(t.playerEntityId),directionX:f[0],directionY:f[1],scalar:1},e,o);return}const m=a.key===" "?x(t.actionCommand,Q(s?.source.props).actionCommand):a.key.toLowerCase()==="f"?x(t.focusCommand,Q(s?.source.props).focusCommand):"";m&&(a.preventDefault(),Nr(m,{actionId:a.key===" "?"0":"focus",actorEntityId:s?.entityId||x(t.playerEntityId),actorEntityKey:s?.entityId||x(t.playerEntityId)},e,o))}),i}function Nr(e,t,r,n){n.commandSink?.(Qc(e,t,n),r)}function Qc(e,t,r={}){return Be(e,{action:t},r)}function Zc(e){switch(e.toLowerCase()){case"w":case"arrowup":return[0,1];case"s":case"arrowdown":return[0,-1];case"a":case"arrowleft":return[-1,0];case"d":case"arrowright":return[1,0];default:return}}function eu(e){return e.includes("station")?"S":e.includes("projectile")?".":e.includes("ship")?"^":"+"}function Mi(e){return e.toLowerCase().replace(/[^a-z0-9_-]+/g,"-")}function ke(e,t){const r=Number(e);return Number.isFinite(r)?r:t}function tu(e,t){if(Array.isArray(e)){const r=e.map(n=>Number(n));if(r.length>=3&&r.slice(0,3).every(Number.isFinite))return[r[0],r[1],r[2]]}if(typeof e=="string"){const r=e.split(/[,\s]+/).map(n=>Number(n)).filter(Number.isFinite);if(r.length>=3)return[r[0],r[1],r[2]]}return t}function ru(e,t,r,n){const o=Te(t.active),i=j("section","cultui-inventory-drag");te(i,e),re(i,r,n),i.dataset.active=o?"true":"false";const c=j("div","cultui-inventory-section-label","Drag");if(re(c,me(r,"sectionLabel."),me(n,"sectionLabel.")),i.append(c),!o){const f=j("div","cultui-inventory-empty","None");return re(f,me(r,"empty."),me(n,"empty.")),i.append(f),i}const s=x(t.itemKey,t.item,"item"),d=j("div","cultui-inventory-drag-chip",s);re(d,me(r,"dragChip."),me(n,"dragChip.")),i.append(d);const u=[t.originOffsetX,t.originOffsetY].map(f=>Number(f)).map(f=>Number.isFinite(f)?f:0),a=j("div","cultui-inventory-meta",`origin ${u[0]}, ${u[1]}`);return re(a,me(r,"meta."),me(n,"meta.")),i.append(a),i}function nu(e,t,r,n,o){const i=j("section","cultui-inventory-grid");te(i,e),re(i,r,n);const c=_e(x(t.columns,t.gridColumns,t.widthCells,""),0),s=c>0?c:6,d=_e(t.rows,0),u=d>0?d:Math.max(3,Math.ceil(Math.max((e.children||[]).length,1)/s));i.style.setProperty("--inventory-columns",String(s)),i.style.setProperty("--inventory-rows",String(u)),i.dataset.cellSpriteMode=K(t.cellSpriteMode,"");const a=x(t.title,t.label,"Inventory"),f=j("div","cultui-inventory-section-label",a);re(f,me(r,"sectionLabel."),me(n,"sectionLabel.")),i.append(f);const m=j("div","cultui-inventory-board");m.style.display="grid",m.style.gridTemplateColumns=`repeat(${s}, ${ce(x(t.cellSize,"72"))})`,m.style.gridTemplateRows=`repeat(${u}, ${ce(x(t.cellSize,"72"))})`,m.style.gap=ce(x(t.cellGap,"4")),m.style.overflow=x(t.boardOverflow,"auto"),m.style.padding=ce(x(t.boardPadding,"4")),re(m,me(r,"board."),me(n,"board.")),m.addEventListener("dragover",S=>{if(!au(t))return;S.preventDefault(),S.dataTransfer&&(S.dataTransfer.dropEffect="move");const g=S.dataTransfer?.getData("application/vnd.gamecult.eve.inventory-item+json")||"";if(g)try{const _=JSON.parse(g),p=m.getBoundingClientRect(),w=Math.max(1,ke(t.cellSize,72)),E=Math.max(0,ke(t.cellGap,4)),l=w+E,h=Math.max(0,Math.floor((S.clientX-p.left)/l)),v=Math.max(0,Math.floor((S.clientY-p.top)/l));su(m,_,t,e.children||[],h,v,w)}catch{ar(m)}}),m.addEventListener("dragleave",S=>{S.relatedTarget instanceof Node&&m.contains(S.relatedTarget)||ar(m)}),m.addEventListener("drop",S=>{ar(m);const g=S.dataTransfer?.getData("application/vnd.gamecult.eve.inventory-item+json")||"";if(!g)return;let _;try{_=JSON.parse(g)}catch{return}const p=m.getBoundingClientRect(),w=Math.max(1,ke(t.cellSize,72)),E=Math.max(0,ke(t.cellGap,4)),l=w+E,h=Math.max(0,Math.min(s-1,Math.floor((S.clientX-p.left)/l))),v=Math.max(0,Math.min(u-1,Math.floor((S.clientY-p.top)/l)));if(!ca(_,t,e.children||[],h,v).valid)return;const I=ou(_,t,h,v,o);I&&(S.preventDefault(),o.commandSink?.(I,e))});const y=new Set;for(const S of e.children||[]){const g=Q(S.props),_=_e(g.x,0),p=_e(g.y,0);y.add(`${_}:${p}`),m.append(le(S,o))}const $=Math.min(s*u,256);for(let S=0;S<$;S+=1){const g=S%s,_=Math.floor(S/s);if(y.has(`${g}:${_}`))continue;const p=j("div","cultui-inventory-cell");p.dataset.x=String(g),p.dataset.y=String(_),p.style.gridColumn=String(g+1),p.style.gridRow=String(_+1),p.style.width=ce(x(t.cellSize,"72")),p.style.height=ce(x(t.cellSize,"72")),re(p,me(r,"cell."),me(n,"cell.")),m.append(p)}return i.append(m),i}function iu(e,t,r,n,o){const i=j("button","cultui-inventory-item");te(i,e),i.type="button",re(i,r,n);const c=_e(t.x,0),s=_e(t.y,0);i.dataset.itemKey=x(t.itemKey,t.label,e.id,"item"),i.dataset.source=x(t.source,""),i.draggable=(t.draggable===void 0||Te(t.draggable))&&!!x(t.sourceKind,t.source,""),i.addEventListener("dragstart",$=>{!i.draggable||!$.dataTransfer||($.dataTransfer.effectAllowed="move",$.dataTransfer.setData("application/vnd.gamecult.eve.inventory-item+json",JSON.stringify({...t,id:e.id})))});let d=_e(t.shapeWidth,1),u=_e(t.shapeHeight,1);const a=x(t.rotation,"").toLowerCase();["clockwise","counterclockwise","right","left","rotate90","rotate270"].includes(a)&&([d,u]=[u,d]),i.style.gridColumn=`${c+1} / span ${d}`,i.style.gridRow=`${s+1} / span ${u}`;const f=j("span","cultui-inventory-item-icon");re(f,me(r,"icon."),me(n,"icon.")),f.textContent=ku(x(t.iconAssetUri,t.iconAssetKey,t.itemKey,t.label,"")),i.append(f);const m=x(t.label,t.itemKey,"");if(m){const $=j("span","cultui-inventory-item-label",m);re($,me(r,"label."),me(n,"label.")),i.append($)}const y=Number(t.quantity);if(Number.isFinite(y)&&y>1){const $=j("span","cultui-inventory-item-quantity",String(y));re($,me(r,"quantity."),me(n,"quantity.")),i.append($)}return i.title=[m,x(t.source,""),x(t.quality,"")?`quality ${t.quality}`:"",x(t.durability,"")?`durability ${t.durability}`:""].filter(Boolean).join(" | "),i}function au(e){return Object.entries(e).some(([t,r])=>(t==="dropCommand"||t.startsWith("dropCommand."))&&typeof r=="string"&&r.length>0)}function ou(e,t,r,n,o={}){const i=x(e.sourceKind,e.source,""),c=x(t[`dropCommand.${i}`],t.dropCommand,"");if(!i||!c)return;const s=ke(e.sourceIndex,-1),d=ke(t.targetIndex,-1),u=x(t.targetKind,""),a={};return xi(e,a),xi(t,a),Object.assign(a,{sourceKind:i,originEntityKey:x(e.sourceEntityKey,e.entityKey,""),originIndex:s,originCargoIndex:i==="cargo"?s:-1,itemKey:x(e.itemKey,""),quantity:Math.max(1,ke(e.quantity,1)),sourceX:ke(e.x,-2147483648),sourceY:ke(e.y,-2147483648),sourceRotation:x(e.rotation,"None"),destinationKind:u,destinationEntityKey:x(t.targetEntityKey,t.entityKey,""),destinationIndex:d,destinationCargoIndex:u==="cargo"?d:-1,destinationX:Math.trunc(r),destinationY:Math.trunc(n),destinationRotation:x(t.dropRotation,e.rotation,"None"),hasDestinationPosition:!0}),Be(c,{action:a},o)}function ca(e,t,r,n,o){const i=Math.max(1,_e(t.columns,1)),c=Math.max(1,_e(t.rows,1)),s=qi(e).map(m=>({x:Math.trunc(n)+m.x,y:Math.trunc(o)+m.y})),d=new Set(ua(t.validCells).map(m=>`${m.x}:${m.y}`)),u=x(e.id,""),a=new Set;for(const m of r||[]){if(m.kind!=="inventory.item"||u&&m.id===u)continue;const y=Q(m.props),$=Math.trunc(ke(y.x,0)),S=Math.trunc(ke(y.y,0));for(const g of qi(y))a.add(`${$+g.x}:${S+g.y}`)}let f="valid";return s.some(m=>m.x<0||m.y<0||m.x>=i||m.y>=c)?f="outside-grid":d.size>0&&s.some(m=>!d.has(`${m.x}:${m.y}`))?f="outside-valid-shape":s.some(m=>a.has(`${m.x}:${m.y}`))&&(f="occupied"),{valid:f==="valid",reason:f,cells:s}}function qi(e){const t=ua(e.shapeCells);if(t.length>0)return t;let r=Math.max(1,_e(e.shapeWidth,1)),n=Math.max(1,_e(e.shapeHeight,1));const o=x(e.rotation,"").toLowerCase();return["clockwise","counterclockwise","right","left","rotate90","rotate270","clockwise90","clockwise270"].includes(o)&&([r,n]=[n,r]),Array.from({length:r*n},(i,c)=>({x:c%r,y:Math.floor(c/r)}))}function ua(e){return typeof e!="string"?[]:e.split(";").flatMap(t=>{const[r,n]=t.split(",").map(Number);return Number.isInteger(r)&&Number.isInteger(n)?[{x:r,y:n}]:[]})}function xi(e,t){for(const[r,n]of Object.entries(e))r.startsWith("payload.")&&r.length>8&&(t[r.slice(8)]=n)}function ar(e){e.querySelectorAll(".cultui-inventory-placement-preview").forEach(t=>t.remove())}function su(e,t,r,n,o,i,c){ar(e);const s=ca(t,r,n,o,i);for(const d of s.cells){const u=j("div",`cultui-inventory-placement-preview ${s.valid?"is-valid":"is-invalid"}`);u.style.gridColumn=String(d.x+1),u.style.gridRow=String(d.y+1),u.style.width=ce(String(c)),u.style.height=ce(String(c)),u.style.pointerEvents="none",e.append(u)}}function cu(e,t,r){const n=j("section","cultui-binding-map");te(n,e);const o=document.createElementNS("http://www.w3.org/2000/svg","svg");o.setAttribute("class","cultui-xbox-controller"),o.setAttribute("viewBox","0 0 780 420"),o.setAttribute("role","img"),o.setAttribute("aria-label",K(t.label,"Xbox controller remapping")),o.innerHTML=lu(),n.append(o);const i=j("div","cultui-binding-overlay");for(const c of e.children||[]){const s=Q(c.props),d=K(s.target,c.id||""),u=j("button","cultui-binding-box");te(u,c),u.type="button",u.dataset.target=d,u.dataset.kind=K(s.bindingKind,"button"),u.style.left=ce(s.x??"50%"),u.style.top=ce(s.y??"50%"),u.append(j("span","cultui-binding-target",K(s.label,d))),u.append(j("span","cultui-binding-source",K(s.current,"unmapped"))),u.addEventListener("click",()=>{const f=la(c);if(da(c)||f?.documentId)fa(xr(c,r),r);else{const m=K(s.commandId,"");m&&r.commandSink?.(Be(m,s,r),c)}}),i.append(u);const a=document.createElementNS("http://www.w3.org/2000/svg","line");a.setAttribute("class","cultui-binding-line"),a.setAttribute("x1",K(s.anchorX,"390")),a.setAttribute("y1",K(s.anchorY,"210")),a.setAttribute("x2",String(Di(s.x,780))),a.setAttribute("y2",String(Di(s.y,420))),o.append(a)}return n.append(i),n}function da(e){for(const t of e.embeddedDocuments||[]){const r=Q(t.surface);if(r.root)return r}}function la(e){const t=(e.embeddedDocuments||[])[0],r=Q(e.props),n=x(r.documentId,t?.documentId,"");if(n)return{documentId:n,presentationKind:x(r.presentationKind,t?.presentationKind,""),schemaId:x(r.schemaId,t?.schemaId,""),slotId:x(r.slotId,t?.slotId,"")}}async function xr(e,t){const r=da(e);if(r)return r;const n=la(e);if(!n?.documentId||!t.documentResolver)return;const o=await t.documentResolver(n,e);if(o)return Q(o.surface).root?o.surface:o}function fa(e,t){const r=j("div","cultui-modal-backdrop"),n=j("section","cultui-modal");n.setAttribute("role","dialog"),n.setAttribute("aria-modal","true");const o=j("header","cultui-modal-header");o.append(j("h2","","Configure Binding"));const i=j("button","cultui-modal-close","Close");i.type="button",i.addEventListener("click",()=>r.remove()),o.append(i);const c=j("div","cultui-modal-body");n.append(o,c),r.append(n),r.addEventListener("click",s=>{s.target===r&&r.remove()}),document.body.append(r),c.append(j("div","detail","materializing document")),Promise.resolve(e).then(s=>{o.querySelector("h2").textContent=s?.title||"Configure Binding",c.replaceChildren(s?.root?le(s.root,t):Le("Embedded document unavailable"))}).catch(s=>{c.replaceChildren(Le(`Embedded document failed: ${s instanceof Error?s.message:String(s)}`))})}function uu(e,t,r,n,o){const i=Q(e.props),c=(e.children||[])[0],s=Q(c?.props),d=x(s.anchor,i.anchor,"trigger"),u=x(s.placement,i.placement,"below-start"),a=Number(x(s.offsetX,i.offsetX,"0"))||0,f=Number(x(s.offsetY,i.offsetY,"4"))||0,m=j("div","cultui-modal-backdrop");m.style.background="transparent",m.style.placeItems="start";const y=j("section","cultui-modal");y.setAttribute("role","dialog"),y.setAttribute("aria-modal","true"),y.style.position="fixed",y.style.width="min(420px, calc(100vw - 24px))",y.style.maxHeight="min(620px, calc(100vh - 24px))";const $=j("header","cultui-modal-header");$.append(j("h2","",x(s.title,i.title,i.label,"Options")));const S=j("button","cultui-modal-close","Close");S.type="button",S.addEventListener("click",()=>m.remove()),$.append(S);const g=j("div","cultui-modal-body");if(c){const p=c.children||[];p.length>0?g.replaceChildren(...p.map(w=>le(w,t))):g.append(le(c,t))}else g.append(Le("Popup has no content"));y.append($,g),m.append(y),m.addEventListener("click",p=>{p.target===m&&m.remove()}),document.body.append(m);const _=du(d,u,r,y,n,o,a,f);y.style.left=`${_.left}px`,y.style.top=`${_.top}px`}function du(e,t,r,n,o,i,c,s){const d=r.getBoundingClientRect(),u=n.getBoundingClientRect(),a=u.width||420,f=u.height||320,m=e==="cursor"?{left:o,right:o,top:i,bottom:i}:d;if(t==="right-down"||t==="dropdown")return rr(m,a,f,c,s,"right","down");if(t==="left-down")return rr(m,a,f,c,s,"left","down");if(t==="right-up")return rr(m,a,f,c,s,"right","up");if(t==="left-up")return rr(m,a,f,c,s,"left","up");switch(t){case"above-start":return xe(m.left+c,m.top-f-s,a,f);case"above-end":return xe(m.right-a+c,m.top-f-s,a,f);case"below-end":return xe(m.right-a+c,m.bottom+s,a,f);case"right-start":return xe(m.right+c,m.top+s,a,f);case"left-start":return xe(m.left-a-c,m.top+s,a,f);case"center":return xe((window.innerWidth-a)/2+c,(window.innerHeight-f)/2+s,a,f);default:return xe(m.left+c,m.bottom+s,a,f)}}function rr(e,t,r,n,o,i,c){const d=window.innerWidth-e.right-n-12,u=e.left-n-12,a=window.innerHeight-e.top-o-12,f=e.bottom-o-12,m=i==="right"?d>=t||d>=u:!(u>=t||u>=d),y=c==="down"?a>=r||a>=f:!(f>=r||f>=a),$=m?e.right+n:e.left-t-n,S=y?e.top+o:e.bottom-r-o;return xe($,S,t,r)}function xe(e,t,r,n){return{left:Li(e,12,window.innerWidth-r-12),top:Li(t,12,window.innerHeight-n-12)}}function Li(e,t,r){return r + + + + + + + + + + + + + + + + + YBXA + `}function fu(e,t=document.body){const r=ma(e),n=document.documentElement.style;wu(r.assets.fontCss);for(const[u,a]of Object.entries(zc))n.setProperty(u,a);const o={colorBackground:"--bg",colorBackgroundTop:"--bg-top",colorBackgroundMid:"--bg-mid",colorBackgroundBottom:"--bg-bottom",colorShellSurfaceTop:"--shell-top",colorShellSurfaceBottom:"--shell-bottom",colorPanel:"--panel",colorPanelAlt:"--panel-2",colorPanelBorder:"--line",colorPanelBorderDeep:"--line-deep",colorText:"--text",colorTextBright:"--text-bright",colorMuted:"--quiet",colorAccent:"--accent",colorAccentStrong:"--accent-strong",colorCornerAccent:"--corner-accent",colorLink:"--cyan",colorShadow:"--shadow",colorPixelGrid:"--pixel-grid"};for(const[u,a]of Object.entries(o)){const f=r.tokens[u];f!==void 0&&n.setProperty(a,String(f))}const i=r.tokens.fontBody,c=r.tokens.fontDisplay,s=r.tokens.fontTitle,d=r.tokens.fontMono;i&&n.setProperty("--font-body",nr(String(i))),c&&n.setProperty("--font-title",nr(String(c))),s&&n.setProperty("--font-title",nr(String(s))),d&&n.setProperty("--font-mono",nr(String(d))),r.tokens.borderWidthPx&&n.setProperty("--border-width",`${r.tokens.borderWidthPx}px`),r.tokens.borderBottomWidthPx&&n.setProperty("--border-bottom-width",`${r.tokens.borderBottomWidthPx}px`),r.tokens.cornerAccentPx&&n.setProperty("--corner-accent-size",`${r.tokens.cornerAccentPx}px`),t.dataset.pixelArt=r.tokens.pixelArt||r.tokens.imageRendering==="pixelated"?"true":"false",t.dataset.scanlines=r.tokens.scanlineOverlay?"true":"false"}function Be(e,t={},r={}){const n=Q(t.action),o=Ke(r)?.surface,i=r.provider?.providerId||o?.providerId||"surface unknown",c=r.activeSurfaceId||o?.surface?.id||r.provider?.surfaces?.[0]?.surfaceId||i,s=hu(r,c),d=x(s.commandBoundary,t.commandBoundary,n.commandBoundary,n.target),u=x(s.receiptSchema,t.receiptSchema,n.receiptSchema);if(!d||!u)throw new Error(`Eve surface ${c} cannot invoke commands without an advertised command boundary and receipt schema.`);const a=e||K(n.type,"invoke"),f=o?.commands?.find(g=>g.command===a),m=pa(f?.captureBindings??n.captureBindings??t.captureBindings),y=r.draftStore?.capture(i,c,m)??{},$=mu(n);return m.length&&($.bindings=y),{schema:"gamecult.eve.command_invocation.v1",providerId:i,surfaceId:c,operation:{operationId:a,schemaId:x(f?.payloadSchema,n.schemaId,t.payloadSchema,"gamecult.eve.operation_payload.v1"),idempotencyKey:pu(),routeHint:{sourceVersion:Math.max(0,Math.trunc(o?.version??0)),...x(f?.transport,t.transport,n.transport)?{transport:x(f?.transport,t.transport,n.transport)}:{}}},payload:$,issuedAt:new Date().toISOString(),clientId:r.clientId||"eve.browser",commandBoundary:d,receiptSchema:u}}function mu(e){const t={...e};for(const r of["command","commandBoundary","receiptSchema","schemaId","captureBindings","transport"])delete t[r];return t}function pu(){if(typeof globalThis.crypto?.randomUUID=="function")return globalThis.crypto.randomUUID();const e=new Uint8Array(16);if(globalThis.crypto?.getRandomValues?.(e),!e.some(Boolean))for(let t=0;tt.toString(16).padStart(2,"0")).join("")}function hu(e,t){const r=[...e.provider?.surfaces||[],...e.provider?.localAdvertisement?.surfaces||[]];return r.find(n=>n.surfaceId===t&&n.worldInteraction)?.worldInteraction||r.find(n=>n.worldInteraction)?.worldInteraction||{}}function Lr(e,t){const r=Q(e.action);return K(e.command,K(e.commandId,K(r.command,K(r.target,K(r.type,t?.commandId||"")))))}function Le(e){const t=j("section","pane");return t.append(j("h2","","No Surface")),t.append(j("div","detail",e)),t}function Fi(e,t,r,n,o){e.dataset.commandId=r,e.tabIndex=e instanceof HTMLButtonElement?e.tabIndex:0;const i=()=>{const c=Be(r,n,o);o.commandSink?.(c,t)};e.addEventListener("click",i),e.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),i())})}function yr(e,t,r){const n=(e.stateBindings||[]).find(a=>a.targetProp==="value")??e.stateBindings?.[0],o=Ke(r)?.surface,i=r.provider?.providerId||o?.providerId||"surface unknown",c=r.activeSurfaceId||o?.surface?.id||i,s=x(n?.bindingName,t.bind,n?.pointerId,e.id),d=s&&r.draftStore?.has(i,c,s)?r.draftStore.get(i,c,s):void 0,u=n?.accessMode||(n?"read":"local-draft");return{binding:n,bindingName:s,providerId:i,surfaceId:c,value:d??t.value??"",disabled:Te(t.disabled)||u==="read"}}function at(e,t,r){e.bindingName&&r.draftStore?.set(e.providerId,e.surfaceId,e.bindingName,t)}function Xr(e,t,r,n){const o=e.binding,i=o?.writeCommand;!o||!i||!e.bindingName||n.commandSink?.(Be(i,{action:{bindingName:e.bindingName,documentId:o.documentId,fieldPath:o.fieldPath,value:t}},n),r)}function yu(e,t,r,n,o,i){const c=yr(e,r,i),s=j("label","field cultui-field cultui-editable");te(s,e),it(s,r),re(s,n,o);const d=K(r.label,"");d&&s.append(j("span","field-label",d));const u=j(t==="control.input.textarea"?"textarea":"input","field-control cultui-field-input");u instanceof HTMLInputElement?(u.type=t.includes("number")||t==="control.range"?"number":"text",r.min!==void 0&&(u.min=String(r.min)),r.max!==void 0&&(u.max=String(r.max)),r.step!==void 0&&(u.step=String(r.step))):r.rows!==void 0&&(u.rows=_e(r.rows,3)),u.value=String(c.value??""),u.disabled=c.disabled,u.name=c.bindingName,u.dataset.bindingName=c.bindingName,u.setAttribute("aria-label",d||c.bindingName||e.id||"Input"),r.placeholder!==void 0&&u.setAttribute("placeholder",String(r.placeholder)),Te(r.required)&&(u.required=!0),u.addEventListener("input",()=>{const f=u instanceof HTMLInputElement&&u.type==="number"?u.value===""?"":Number(u.value):u.value;at(c,f,i)}),u.addEventListener("change",()=>{const f=u instanceof HTMLInputElement&&u.type==="number"?u.value===""?"":Number(u.value):u.value;Xr(c,f,e,i)}),s.append(u);const a=x(r.validationMessage,r.error,"");if(a){const f=j("span","cultui-field-validation",a);f.setAttribute("role","alert"),s.append(f),u.setAttribute("aria-invalid","true")}return s}function gu(e,t,r,n,o,i){const c=yr(e,t,i),s=j("fieldset","field cultui-field cultui-choice-group");te(s,e),re(s,n,o);const d=x(t.label,e.text,c.bindingName);d&&s.append(j("legend","field-label",d));for(const u of r){const a=Q(u.props),f=x(a.value,u.id),m=j("label","cultui-choice"),y=j("input");y.type=Te(t.multiple)?"checkbox":"radio",y.name=c.bindingName,y.value=f,y.disabled=c.disabled||Te(a.disabled),y.checked=y.type==="checkbox"?pa(c.value).includes(f):String(c.value)===f,y.addEventListener("change",()=>{const $=y.type==="checkbox"?[...s.querySelectorAll("input:checked")].map(S=>S.value):f;at(c,$,i),Xr(c,$,e,i)}),m.append(y,document.createTextNode(x(a.label,u.text,f))),s.append(m)}return s}function vu(e,t,r,n,o,i){const c=yr(e,{...t,bind:t.bind||`${e.id||"tabs"}.selected`},i),s=j("section","cultui-tabs");te(s,e),re(s,n,o);const d=j("div","cultui-tab-list");d.setAttribute("role","tablist");const u=j("div","cultui-tab-panels"),a=x(c.value,Q(r[0]?.props).value,r[0]?.id),f=m=>{at(c,m,i);for(const y of d.querySelectorAll("[role=tab]")){const $=y.dataset.value===m;y.setAttribute("aria-selected",String($)),y.tabIndex=$?0:-1}for(const y of u.querySelectorAll("[role=tabpanel]"))y.hidden=y.dataset.value!==m};for(const[m,y]of r.entries()){const $=Q(y.props),S=x($.value,y.id,String(m)),g=j("button","cultui-tab",x($.label,y.text,S));g.type="button",g.dataset.value=S,g.setAttribute("role","tab"),g.addEventListener("click",()=>f(S)),d.append(g);const _=j("section","cultui-tab-panel");_.dataset.value=S,_.setAttribute("role","tabpanel");for(const p of y.children||[])_.append(le(p,i));u.append(_)}return s.append(d,u),f(a),s}function bu(e,t,r,n,o,i){const c=yr(e,t,i),s=j("label","field cultui-field cultui-select");te(s,e),it(s,t),re(s,n,o);const d=K(t.label,"");d&&s.append(j("span","field-label",d));const u=j("select","field-control cultui-field-select");u.setAttribute("aria-label",d||e.id||"Select");for(const f of r){if(f.kind!=="control.option"&&f.kind!=="input.option"&&f.kind!=="option")continue;const m=Q(f.props),y=document.createElement("option");y.value=K(m.value,f.id||""),y.textContent=K(m.label,K(m.text,y.value)),y.disabled=Te(m.disabled)||m.enabled!==void 0&&!Te(m.enabled),u.append(y)}u.value=String(c.value??""),u.name=c.bindingName,u.dataset.bindingName=c.bindingName,u.disabled=c.disabled||t.enabled!==void 0&&!Te(t.enabled);const a=Lr(t,e);return a?(u.dataset.commandId=a,u.addEventListener("change",()=>{at(c,u.value,i);const f=Be(a,{...t,action:{...Q(t.action),value:u.value}},i);i.commandSink?.(f,e)})):u.addEventListener("change",()=>{at(c,u.value,i),Xr(c,u.value,e,i)}),s.append(u),s}function _u(e,t,r){const n=$u(e,t,r),o=Q(n.find(m=>m.kind==="control.box")?.props),i=n.filter(m=>m.kind==="control.part"),c=Number(e.min??0),s=Number(e.max??1),d=j("div","cultui-slider");d.dataset.skin=K(e.skin,"default"),d.dataset.bind=K(e.bind,""),Eu(d,o);const u=j("div","cultui-slider-visual"),a=j("input","cultui-slider-input");a.type="range",a.min=String(c),a.max=String(s),a.step=String(e.step??.01),a.setAttribute("aria-label",K(e.bind,"slider"));for(const m of i){const y=Q(m.props),$=j("span",`cultui-slider-part ${K(y.name,"part")}`);Pu($,y),u.append($)}return i.some(m=>Q(m.props).name==="track")||u.append(j("span","cultui-slider-part track")),i.some(m=>Q(m.props).name==="fill")||u.append(j("span","cultui-slider-part fill")),i.some(m=>Q(m.props).name==="thumb")||u.append(j("span","cultui-slider-part thumb")),d.append(u,a),(m=>{const y=Number(m??c),$=Math.max(c,Math.min(s,Number.isFinite(y)?y:c)),S=s===c?0:($-c)/(s-c)*100;a.value=String($),d.style.setProperty("--cultui-slider-value",`${S}%`),d.dataset.value=String($)})(e.value??c),a.addEventListener("input",()=>{const m=Be(K(e.command,"control.slider.input"),{...e,action:{...Q(e.action),value:Number(a.value)},value:Number(a.value)},r);r.commandSink?.(m,{kind:"control.slider",props:e})}),d}function $u(e,t,r){const n=typeof e.skin=="string"?e.skin:"",i=[...n?Ke(r)?.styles.controlSkins[n]?.children||[]:[],...t];return i.length?i:[{kind:"control.box",props:{height:18,overflow:"visible"}},{kind:"control.part",props:{name:"track",anchor:"center",size:["100%",6],radius:2,fill:"color.panelInset"}},{kind:"control.part",props:{name:"fill",anchor:["left","center"],size:["value%",6],radius:2,fill:"color.accent"}},{kind:"control.part",props:{name:"thumb",anchor:["value","center"],size:[12,12],bleed:3,radius:999,fill:"color.accent"}}]}function ma(e){if(Array.isArray(e)){const t={},r={};for(const n of e)n?.name&&(n.name==="font.web.google"&&typeof n.value=="string"?r.fontCss=n.value:t[n.name]=n.value);return{tokens:t,assets:r,controlSkins:{}}}return{tokens:Q(e?.tokens),assets:Q(e?.assets),controlSkins:Q(e?.controlSkins)}}function nt(e,t){if(!e)return"";const r=Ke(t)?.surface,n=t.assetUrlResolver;return n?n(e,r):/^(https?:|data:|blob:)/i.test(e)?e:t.assetBaseUrl&&e.startsWith("/")?`${t.assetBaseUrl.replace(/\/+$/,"")}${e}`:e}function wu(e){const t=typeof e=="string"?e.trim():"";if(!t||Ni.has(t))return;const r=document.createElement("link");r.rel="preconnect",r.href="https://fonts.gstatic.com",r.crossOrigin="anonymous",document.head.append(r);const n=document.createElement("link");n.rel="stylesheet",n.href=t,n.dataset.href=t,document.head.append(n),Ni.set(t,n)}function Su(e,t,r){const n=[];return(e==="text.title"||t.role==="title")&&n.push("cultui-title","eve-text-title"),e==="text.subtitle"&&n.push("eve-text-subtitle"),e==="label"&&n.push("cultui-label"),t.role==="mono"&&n.push("detail","mono"),n.length===0&&n.push("detail","eve-text"),n.join(" ")}function Eu(e,t){t.height!==void 0&&(e.style.minHeight=ce(t.height)),t.width!==void 0&&(e.style.width=ce(t.width)),typeof t.overflow=="string"&&(e.style.overflow=t.overflow)}function Pu(e,t){const r=Array.isArray(t.size)?t.size:[t.size,void 0];r[0]!==void 0&&r[0]!=="value%"&&(e.style.width=ce(r[0])),r[1]!==void 0&&(e.style.height=ce(r[1])),t.radius!==void 0&&(e.style.borderRadius=ce(t.radius)),t.fill!==void 0&&(e.style.background=or(String(t.fill))),t.bleed!==void 0&&e.style.setProperty("--part-bleed",ce(t.bleed)),(Array.isArray(t.anchor)?t.anchor:[t.anchor]).includes("value")&&(e.dataset.anchorValue="true")}function it(e,t){t.gap!==void 0&&(e.style.gap=ce(t.gap)),t.padding!==void 0&&(e.style.padding=ce(t.padding)),t.size!==void 0&&(e.style.flex=Iu(t.size)),t.min!==void 0&&(e.style.minWidth=ce(t.min)),t.max!==void 0&&(e.style.maxWidth=ce(t.max)),t.align!==void 0&&(e.style.alignItems=t.align==="end"?"flex-end":String(t.align)),(t.clip==="true"||t.clip===!0)&&(e.style.overflow="hidden"),t.scroll==="y"&&(e.style.overflowY="auto"),t.scroll==="x"&&(e.style.overflowX="auto")}function Iu(e){return typeof e=="string"&&e.endsWith("fr")?`${Number(e.slice(0,-2))||1} 1 0`:e==="auto"||e==="content"?"0 0 auto":`0 0 ${ce(e)}`}function ce(e){return Array.isArray(e)?e.map(ce).join(" "):typeof e=="number"?`${e}px`:typeof e=="string"&&/^-?\d+(\.\d+)?$/.test(e)?`${e}px`:String(e??"")}function or(e){return{"color.accent":"var(--accent)","color.panelInset":"rgba(0, 0, 0, 0.34)","color.panel":"var(--panel)","color.text":"var(--text)"}[e]||e}function nr(e){return e.includes("Zen Kaku Gothic New")||e.includes("M PLUS 1")?e:e.includes("Montserrat")?`${e}, "Zen Kaku Gothic New", "M PLUS 1", "Noto Sans JP", "Hiragino Sans", "Yu Gothic", sans-serif`:e.includes("Ubuntu")?`${e}, "M PLUS 1", "Noto Sans JP", "Hiragino Sans", "Yu Gothic", sans-serif`:`${e}, "Noto Sans JP", "Hiragino Sans", "Yu Gothic", sans-serif`}function te(e,t){t.id&&(e.id=t.id),t.id&&(e.dataset.eveNodeId=t.id),t.kind&&(e.dataset.eveKind=t.kind)}function Q(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function Ru(e){return Array.isArray(e)?e:[]}function Au(e){return Ru(e).map((t,r)=>sa({kind:"list.item",props:Q(t)}))}function K(e,t){return e==null?t:String(e)}function pa(e){return Array.isArray(e)?e.map(t=>String(t).trim()).filter(Boolean):typeof e=="string"?e.split(",").map(t=>t.trim()).filter(Boolean):[]}function x(...e){for(const t of e){if(typeof t=="string"&&t.trim())return t;if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function Te(e){return typeof e=="boolean"?e:typeof e=="number"?e!==0:typeof e=="string"?["1","true","yes","on"].includes(e.trim().toLowerCase()):!1}function _e(e,t){const r=Number(e);return Number.isFinite(r)?Math.max(0,Math.floor(r)):t}function ku(e){const t=e.toLowerCase();return t.includes("sensor")?"S":t.includes("thermal")?"T":t.includes("fuel")?"F":t.includes("cargo")?"C":t.includes("weapon")?"W":e.trim().slice(0,1).toUpperCase()||"?"}function Cu(e){const t=e.trim().split(/\s+/).filter(Boolean);return t.length&&t.slice(0,2).map(r=>r[0]?.toUpperCase()||"").join("")||"?"}function Ui(e){const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(100,t)):0}function j(e,t="",r=""){const n=document.createElement(e);return t&&(n.className=t),r&&(n.textContent=r),n}const Dr="gamecult.heimdall.access.attempt";function Nu(e){const t=new Set(e.advertisedOrigins.map(r=>new URL(r).origin));return{pluginId:"gamecult.heimdall.access",capabilities:["auth.gate","auth.begin","auth.complete","auth.logout"],componentKinds:["heimdall.access_gate","heimdall.identity","heimdall.access_status"],schemas:["heimdall.access_gate_state.v1"],normalizeDocument(r,n){return n},renderComponent(r,n){const o=document.createElement("section");o.className=`heimdall-access heimdall-access-${String(n.state||"unknown")}`,r.id&&(o.id=r.id),o.setAttribute("role","status"),o.setAttribute("aria-live","polite");const i=document.createElement("h2");i.textContent=String(n.title||"Access");const c=document.createElement("p");c.textContent=String(n.detail||""),o.append(i,c);const s=String(n.displayName||"");if(s){const d=document.createElement("p");d.className="heimdall-identity",d.textContent=s,o.append(d)}return o},async consumeCommandResult(r){if(r.schemaId==="heimdall.auth_navigation_receipt.v1"){const n=String(r.payload.handle||""),o=ju(r.payload.navigation),i=new URL(String(o.url||"")),c=Array.isArray(o.allowedOrigins)?o.allowedOrigins.filter(s=>typeof s=="string"):[];if(!n||i.protocol!=="https:"||!t.has(i.origin)||!c.includes(i.origin))throw new Error("Heimdall returned an unsafe authentication navigation receipt.");sessionStorage.setItem(Dr,n),window.location.assign(i.toString());return}if(r.schemaId==="heimdall.auth_completion_status.v1"){const n=String(r.payload.status||"");(n==="authenticated"||n==="denied"||n==="expired")&&sessionStorage.removeItem(Dr)}}}}const Fr=Nu({advertisedOrigins:["https://discord.com","https://heimdall.gamecult.org"]});async function Tu(e){const t=sessionStorage.getItem(Dr);return t?(await e.complete(t),!0):!1}function ju(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}class Ou{provider;sourceVersion=0;async providerAdvertisement(){return this.provider=await Tr("api/eve/provider"),this.provider}async surface(t){const r=t.surfaceId||"ghostlight.play",n=sessionStorage.getItem("ghostlight.pendingInvite"),o=n?`?invite=${encodeURIComponent(n)}`:"",i=await Tr(`api/eve/surfaces/${encodeURIComponent(r)}${o}`);return this.sourceVersion=Math.max(0,Math.trunc(i.version||0)),i}async submitCommand(t){const r=await Tr("api/eve/commands",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});return t.operation.operationId==="session_zero.join"&&r.receipt?.state==="accepted"&&sessionStorage.removeItem("ghostlight.pendingInvite"),r}async completeAuthentication(t){return this.provider||await this.providerAdvertisement(),await this.submitCommand({schema:"gamecult.eve.command_invocation.v1",providerId:this.provider?.providerId||"gamecult.ghostlight.dungeon",surfaceId:"ghostlight.play",operation:{operationId:"heimdall.auth.complete",schemaId:"heimdall.auth_complete_command.v1",idempotencyKey:crypto.randomUUID(),routeHint:{sourceVersion:this.sourceVersion}},payload:{handle:t},issuedAt:new Date().toISOString(),clientId:"ghostlight.browser",commandBoundary:"ghostlight.eve.commands",receiptSchema:"gamecult.eve.command_result.v1"})}}const zi=new URL(window.location.href).searchParams.get("invite");zi&&(sessionStorage.setItem("ghostlight.pendingInvite",zi),history.replaceState(null,"",`${window.location.pathname}${window.location.hash}`));async function Tr(e,t){const r=await fetch(e,{cache:"no-store",credentials:"same-origin",...t}),n=await r.json().catch(()=>{});if(!r.ok){const o=n&&typeof n.message=="string"?n.message:`Ghostlight refused the request (${r.status}).`;throw new Error(o)}return n}function ha(e){const t=document.getElementById(e);if(!(t instanceof HTMLElement))throw new Error(`Missing browser host #${e}.`);return t}const Mu=ha("surface"),Yr=ha("status"),ya=new Ou,Jr=new Fc(Mu,ya,{body:document.body,clientId:"ghostlight.browser",pollMs:0,requestedSurfaceId:"ghostlight.play",source:"Ghostlight",statusElement:Yr,pluginAdapters:[Fr]});window.addEventListener("unhandledrejection",e=>{e.preventDefault(),Yr.textContent=e.reason instanceof Error?e.reason.message:String(e.reason)});await Jr.start();await Tu({complete:async e=>{const t=await ya.completeAuthentication(e);t.pluginPayload?.pluginId===Fr.pluginId&&await Fr.consumeCommandResult?.(t.pluginPayload),await Jr.refresh()}});const ga=new EventSource("api/eve/events");ga.addEventListener("revision",()=>{Jr.refresh()});ga.addEventListener("error",()=>{Yr.textContent="Live revision notices are unavailable; your authoritative surface remains safe to refresh."}); diff --git a/web/dist/index.html b/web/dist/index.html index 2fc091c..b93dc30 100644 --- a/web/dist/index.html +++ b/web/dist/index.html @@ -4,55 +4,16 @@ Ghostlight Dungeon - - + + - +

GHOSTLIGHT / LIVING WORLDS

Ghostlight Dungeon

Reading the table…

-
- - - - -
- -
+
diff --git a/web/index.html b/web/index.html index 788299f..e55fe7b 100644 --- a/web/index.html +++ b/web/index.html @@ -6,52 +6,13 @@ Ghostlight Dungeon - +

GHOSTLIGHT / LIVING WORLDS

Ghostlight Dungeon

Reading the table…

-
- - - - -
- -
+
diff --git a/web/package-lock.json b/web/package-lock.json index d618b2a..172c995 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -6,7 +6,9 @@ "": { "name": "@gamecult/ghostlight-dungeon-web", "dependencies": { - "@gamecult/eve-browser-lowering": "file:../vendor/eve/packages/eve-browser-lowering" + "@gamecult/eve-browser-lowering": "file:../vendor/eve/packages/eve-browser-lowering", + "@gamecult/eve-contracts": "file:../vendor/eve/packages/eve-contracts", + "ajv": "^8.17.1" }, "devDependencies": { "typescript": "^5.6.3", @@ -15,11 +17,30 @@ }, "../vendor/eve/packages/eve-browser-lowering": { "name": "@gamecult/eve-browser-lowering", - "version": "0.1.0", + "version": "0.1.1", + "dependencies": { + "@gamecult/eve-contracts": "file:../eve-contracts" + }, "devDependencies": { + "@types/jsdom": "^30.0.0", + "jsdom": "^30.0.1", "typescript": "^5.6.3" } }, + "../vendor/eve/packages/eve-contracts": { + "name": "@gamecult/eve-contracts", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "ajv": "^8.17.1" + }, + "devDependencies": { + "@msgpack/msgpack": "^3.1.2", + "@types/node": "^24.0.0", + "json-schema-to-typescript": "^15.0.4", + "typescript": "^5.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", @@ -466,6 +487,10 @@ "resolved": "../vendor/eve/packages/eve-browser-lowering", "link": true }, + "node_modules/@gamecult/eve-contracts": { + "resolved": "../vendor/eve/packages/eve-contracts", + "link": true + }, "node_modules/@napi-rs/lzma-linux-x64-gnu": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", @@ -882,6 +907,22 @@ "dev": true, "license": "MIT" }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/esbuild": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", @@ -924,6 +965,28 @@ "@esbuild/win32-x64": "0.28.2" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -957,6 +1020,12 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.18", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", @@ -1025,6 +1094,15 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/rollup": { "version": "4.62.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", diff --git a/web/package.json b/web/package.json index f4d2c8a..18b262a 100644 --- a/web/package.json +++ b/web/package.json @@ -5,8 +5,13 @@ "scripts": { "build": "npm run typecheck && vite build", "dev": "vite --host 127.0.0.1 --port 8832", + "test": "node test/static-boundary.mjs", "typecheck": "tsc --noEmit" }, - "dependencies": { "@gamecult/eve-browser-lowering": "file:../vendor/eve/packages/eve-browser-lowering" }, + "dependencies": { + "@gamecult/eve-browser-lowering": "file:../vendor/eve/packages/eve-browser-lowering", + "@gamecult/eve-contracts": "file:../vendor/eve/packages/eve-contracts", + "ajv": "^8.17.1" + }, "devDependencies": { "typescript": "^5.6.3", "vite": "^7.1.2" } } diff --git a/web/src/heimdall-access-adapter.provenance.md b/web/src/heimdall-access-adapter.provenance.md new file mode 100644 index 0000000..b75c40d --- /dev/null +++ b/web/src/heimdall-access-adapter.provenance.md @@ -0,0 +1,11 @@ +# Heimdall access browser adapter provenance + +- Owner: `GameCult/Heimdall` +- Plugin: `gamecult.heimdall.access` +- Source commit: `19e5109` +- Source path: `plugins/gamecult.heimdall.access/browser-adapter.ts` +- Vendoring mode: exact semantic copy with formatting only + +Ghostlight embeds this adapter so immutable releases do not depend on a sibling +checkout at browser-build time. Authentication behavior remains Heimdall-owned; +changes are imported from the owner and this provenance is advanced with them. diff --git a/web/src/heimdall-access-adapter.ts b/web/src/heimdall-access-adapter.ts new file mode 100644 index 0000000..bf14f62 --- /dev/null +++ b/web/src/heimdall-access-adapter.ts @@ -0,0 +1,78 @@ +// Vendored from GameCult/Heimdall commit 19e5109, plugin +// gamecult.heimdall.access. Heimdall owns these semantics; Ghostlight embeds the +// adapter because its release must remain self-contained. +const ATTEMPT_KEY = "gamecult.heimdall.access.attempt"; + +export interface HeimdallAccessResumeTarget { + complete(handle: string): Promise; +} + +export function createHeimdallAccessBrowserAdapter(options: { advertisedOrigins: readonly string[] }) { + const advertisedOrigins = new Set(options.advertisedOrigins.map(value => new URL(value).origin)); + return { + pluginId: "gamecult.heimdall.access", + capabilities: ["auth.gate", "auth.begin", "auth.complete", "auth.logout"], + componentKinds: ["heimdall.access_gate", "heimdall.identity", "heimdall.access_status"], + schemas: ["heimdall.access_gate_state.v1"], + normalizeDocument(_schemaId: string | undefined, value: unknown): unknown { + return value; + }, + renderComponent(component: { id?: string }, props: Record): HTMLElement { + const view = document.createElement("section"); + view.className = `heimdall-access heimdall-access-${String(props.state || "unknown")}`; + if (component.id) view.id = component.id; + view.setAttribute("role", "status"); + view.setAttribute("aria-live", "polite"); + const title = document.createElement("h2"); + title.textContent = String(props.title || "Access"); + const detail = document.createElement("p"); + detail.textContent = String(props.detail || ""); + view.append(title, detail); + const displayName = String(props.displayName || ""); + if (displayName) { + const identity = document.createElement("p"); + identity.className = "heimdall-identity"; + identity.textContent = displayName; + view.append(identity); + } + return view; + }, + async consumeCommandResult(pluginPayload: { schemaId: string; payload: Record }): Promise { + if (pluginPayload.schemaId === "heimdall.auth_navigation_receipt.v1") { + const handle = String(pluginPayload.payload.handle || ""); + const navigation = object(pluginPayload.payload.navigation); + const url = new URL(String(navigation.url || "")); + const allowedOrigins = Array.isArray(navigation.allowedOrigins) + ? navigation.allowedOrigins.filter((value): value is string => typeof value === "string") + : []; + if (!handle || url.protocol !== "https:" || !advertisedOrigins.has(url.origin) || !allowedOrigins.includes(url.origin)) { + throw new Error("Heimdall returned an unsafe authentication navigation receipt."); + } + sessionStorage.setItem(ATTEMPT_KEY, handle); + window.location.assign(url.toString()); + return; + } + if (pluginPayload.schemaId === "heimdall.auth_completion_status.v1") { + const status = String(pluginPayload.payload.status || ""); + if (status === "authenticated" || status === "denied" || status === "expired") { + sessionStorage.removeItem(ATTEMPT_KEY); + } + } + }, + }; +} + +export const heimdallAccessBrowserAdapter = createHeimdallAccessBrowserAdapter({ + advertisedOrigins: ["https://discord.com", "https://heimdall.gamecult.org"], +}); + +export async function resumeHeimdallAccess(target: HeimdallAccessResumeTarget): Promise { + const handle = sessionStorage.getItem(ATTEMPT_KEY); + if (!handle) return false; + await target.complete(handle); + return true; +} + +function object(value: unknown): Record { + return value && typeof value === "object" && !Array.isArray(value) ? value as Record : {}; +} diff --git a/web/src/main.ts b/web/src/main.ts index a6c7976..821a48e 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -1,257 +1,121 @@ -import { renderEveSurface } from "@gamecult/eve-browser-lowering"; +import { + EveBrowserProviderHost, + type EveBrowserProviderTransport, + type EveCommandIntent, + type EveProviderAdvertisement, + type EveProviderSurfaceAdvertisement, + type EveSurfaceDocument, +} from "@gamecult/eve-browser-lowering"; +import { heimdallAccessBrowserAdapter, resumeHeimdallAccess } from "./heimdall-access-adapter"; import "@gamecult/eve-browser-lowering/styles.css"; import "./style.css"; -const $ = (selector: string) => document.querySelector(selector)!; -const status = $("#status") as HTMLElement; -const entry = $("#entry") as HTMLElement; -const sessionRoot = $("#session-zero") as HTMLElement; -const surfaceHost = $("#surface") as HTMLElement; -const playControls = $("#play-controls") as HTMLElement; -const receipt = $("#receipt") as HTMLElement; -let revision = 0; -let resolutionEpoch = 0; -let viewerActorId = ""; -let sessionId = ""; -let viewerMemberId = ""; -let activeChannel = "shared:table"; -let currentSurface: any = null; -let requestActive = false; +class GhostlightEveTransport implements EveBrowserProviderTransport { + private provider: EveProviderAdvertisement | undefined; + private sourceVersion = 0; -class ServerFailure extends Error {} - -function el(tag: K, text?: string, className?: string) { - const value = document.createElement(tag); - if (text !== undefined) value.textContent = text; - if (className) value.className = className; - return value; -} - -async function decode(response: Response) { - if (response.status === 204) return null; - return (response.headers.get("content-type") ?? "").includes("json") ? response.json() : response.text(); -} - -function errorText(body: any, fallback: string) { - if (typeof body === "string" && body.trim()) return body.trim(); - return typeof body?.error === "string" ? body.error : fallback; -} - -async function post(path: string, body: unknown) { - if (requestActive) throw new Error("Another table command is still being admitted."); - requestActive = true; - document.body.setAttribute("aria-busy", "true"); - try { - const response = await fetch(path, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) }); - const value = await decode(response); - if (!response.ok) throw new ServerFailure(errorText(value, "The server refused the command.")); - return value; - } finally { - requestActive = false; - document.body.removeAttribute("aria-busy"); + async providerAdvertisement(): Promise { + this.provider = await fetchJson("api/eve/provider"); + return this.provider; } -} -function showError(reason: unknown) { - const message = reason instanceof Error ? reason.message : "The connection failed."; - status.textContent = message; - receipt.hidden = false; - receipt.replaceChildren(el("h2", reason instanceof ServerFailure ? "Request refused" : "Request interrupted"), el("p", message), el("p", "The server remains authoritative. Refresh before retrying.", "quiet")); -} - -window.addEventListener("unhandledrejection", event => { event.preventDefault(); showError(event.reason); }); - -function showAuthenticationGate() { - entry.hidden = true; sessionRoot.hidden = true; playControls.hidden = true; surfaceHost.hidden = false; - const card = el("article", undefined, "card"); - card.append(el("h2", "Ghostlight Dungeon playtest"), el("p", "Sign in through Heimdall with an eligible Discord account.")); - const button = el("button", "Continue with Discord"); - button.addEventListener("click", () => void startLogin().catch(showError)); - card.append(button); - surfaceHost.replaceChildren(card); -} - -async function startLogin() { - const response = await fetch("/api/auth/heimdall/start", { method: "POST" }); - const body = await decode(response); - if (!response.ok) throw new ServerFailure(errorText(body, "Heimdall could not begin sign-in.")); - sessionStorage.setItem("ghostlight_heimdall_attempt", body.attempt_id); - window.location.assign(body.authorization_url); -} - -async function resumeLogin() { - const attempt = sessionStorage.getItem("ghostlight_heimdall_attempt"); - if (!attempt) return; - const deadline = Date.now() + 600_000; - while (Date.now() < deadline) { - await new Promise(resolve => window.setTimeout(resolve, 900)); - const response = await fetch(`/api/auth/heimdall/attempt/${encodeURIComponent(attempt)}`, { cache: "no-store" }); - const body = await decode(response); - if (!response.ok) throw new ServerFailure(errorText(body, "Heimdall sign-in expired.")); - if (body.status === "pending") continue; - if (body.status !== "succeeded") throw new ServerFailure(body.error ?? "Discord access was not admitted."); - const adopted = await fetch(`/api/auth/heimdall/attempt/${encodeURIComponent(attempt)}/adopt`, { method: "POST" }); - if (!adopted.ok) throw new ServerFailure(errorText(await decode(adopted), "Heimdall session adoption failed.")); - sessionStorage.removeItem("ghostlight_heimdall_attempt"); - return; + async surface(surface: EveProviderSurfaceAdvertisement): Promise { + const surfaceId = surface.surfaceId || "ghostlight.play"; + const pendingInvite = sessionStorage.getItem("ghostlight.pendingInvite"); + const query = pendingInvite ? `?invite=${encodeURIComponent(pendingInvite)}` : ""; + const document = await fetchJson(`api/eve/surfaces/${encodeURIComponent(surfaceId)}${query}`); + this.sourceVersion = Math.max(0, Math.trunc(document.version || 0)); + return document; } - throw new Error("Heimdall sign-in timed out."); -} -async function refresh() { - const response = await fetch("/api/surface", { cache: "no-store" }); - if (response.status === 401) return showAuthenticationGate(); - const surface = await decode(response); - if (!response.ok) throw new ServerFailure(errorText(surface, "The table surface is unavailable.")); - currentSurface = surface; - if (surface.surface_id === "ghostlight.session-zero-entry") return renderEntry(); - if (surface.session_zero) return renderSession(surface.session_zero); - renderCampaign(surface); -} - -function renderEntry() { - status.textContent = "No campaign is selected. Begin or join a Session Zero."; - entry.hidden = false; sessionRoot.hidden = true; surfaceHost.hidden = true; playControls.hidden = true; - const invite = new URLSearchParams(location.search).get("invite"); - if (invite) ($("#join-token") as HTMLInputElement).value = invite; -} - -function pairs(target: HTMLElement, fields: Record) { - target.replaceChildren(); - for (const [label, raw] of Object.entries(fields)) { - const value = Array.isArray(raw) ? raw.join(" · ") : String(raw || "Not decided yet"); - target.append(el("dt", label.replaceAll("_", " ")), el("dd", value)); - } -} - -function renderSession(session: any) { - entry.hidden = true; sessionRoot.hidden = false; surfaceHost.hidden = true; playControls.hidden = true; - sessionId = session.id; revision = Number(session.revision); viewerMemberId = session.viewer_member_id; - if (!session.channels.some((channel: any) => channel.id === activeChannel)) activeChannel = "shared:table"; - $("#session-title").textContent = currentSurface.title; - $("#session-state").textContent = `${String(session.status).replaceAll("_", " ")} · revision ${revision}`; - status.textContent = session.status === "compiling" ? "The DM is compiling the agreed brief. You can leave this page." : "Session Zero is persistent. Conversation is not world truth until unanimous publication."; - const shared = activeChannel === "shared:table"; - $("#tab-shared").setAttribute("aria-pressed", String(shared)); - $("#tab-private").setAttribute("aria-pressed", String(!shared)); - const channel = session.channels.find((item: any) => item.id === activeChannel) ?? session.channels[0]; - const transcript = $("#session-transcript"); transcript.replaceChildren(); - for (const message of channel?.messages ?? []) { - const item = el("li", undefined, `message ${message.speaker}`); - item.append(el("strong", message.speaker === "dm" ? "DM" : message.speaker === "system" ? "Table" : "Player"), el("p", message.text)); - transcript.append(item); - } - const roster = $("#roster"); roster.replaceChildren(); - for (const member of session.public_party) { - const row = el("p", `${member.approved ? "Ready" : "Not ready"} · ${member.display_name} as ${member.name || "undecided"}${member.is_host ? " · host" : ""}`); - if (session.viewer_is_host && !session.roster_locked && !member.is_host) { - const remove = el("button", "Remove"); - remove.addEventListener("click", async () => { await post(`/api/session-zero/${sessionId}/remove-member`, { expected_revision: revision, member_id: member.member_id }); await refresh(); }); - row.append(" ", remove); + async submitCommand(intent: EveCommandIntent): Promise { + const result = await fetchJson("api/eve/commands", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify(intent), + }); + if (intent.operation.operationId === "session_zero.join" && result.receipt?.state === "accepted") { + sessionStorage.removeItem("ghostlight.pendingInvite"); } - roster.append(row); + return result; } - $("#cell-pool").textContent = `${session.pooled_cell_allowance} pooled active Persona cells · ${session.active_members}/8 players`; - pairs($("#contract-ledger"), session.contract); - pairs($("#character-ledger"), session.private_character); - const boundaryList = $("#boundary-list"); boundaryList.replaceChildren(...session.private_boundaries.map((boundary: any) => { - const item = el("li", `${boundary.level.replaceAll("_", " ")} · ${boundary.topic} `); - const remove = el("button", "Remove"); remove.addEventListener("click", async () => { await post(`/api/session-zero/${sessionId}/boundary/${encodeURIComponent(boundary.id)}/remove`, { expected_revision: revision }); await refresh(); }); item.append(remove); return item; - })); - const decisions = $("#decision-list"); decisions.replaceChildren(); - for (const decision of session.decisions.filter((item: any) => !item.resolved)) { - const card = el("article", undefined, "decision"); - card.append(el("h4", decision.prompt), el("p", decision.proposed_resolution)); - const accept = el("button", "Accept"); accept.addEventListener("click", () => void decide(decision.id, true)); - const counter = el("button", "Counter"); counter.addEventListener("click", async () => { const text = window.prompt("What should the DM propose instead?", decision.proposed_resolution); if (!text?.trim()) return; await post(`/api/session-zero/${sessionId}/decision`, { expected_revision: revision, decision_id: decision.id, accept: false, counter: text.trim() }); await refresh(); }); - const discuss = el("button", "Discuss"); discuss.addEventListener("click", () => { ($("#session-message") as HTMLTextAreaElement).value = `I'd like to discuss: ${decision.prompt}`; ($("#session-message") as HTMLTextAreaElement).focus(); }); - card.append(accept, counter, discuss); decisions.append(card); + + async completeAuthentication(handle: string): Promise { + if (!this.provider) await this.providerAdvertisement(); + return await this.submitCommand({ + schema: "gamecult.eve.command_invocation.v1", + providerId: this.provider?.providerId || "gamecult.ghostlight.dungeon", + surfaceId: "ghostlight.play", + operation: { + operationId: "heimdall.auth.complete", + schemaId: "heimdall.auth_complete_command.v1", + idempotencyKey: crypto.randomUUID(), + routeHint: { sourceVersion: this.sourceVersion }, + }, + payload: { handle }, + issuedAt: new Date().toISOString(), + clientId: "ghostlight.browser", + commandBoundary: "ghostlight.eve.commands", + receiptSchema: "gamecult.eve.command_result.v1", + }); } - const review = $("#review-card") as HTMLElement; review.hidden = !session.preview; - if (session.preview) { - const content = $("#review-content"); content.replaceChildren(el("p", session.preview.title)); - if (session.preview.branch_assumptions?.length) content.append(el("p", `Branch-local assumptions: ${session.preview.branch_assumptions.join("; ")}`)); - content.append(el("p", `${Object.keys(session.preview.topology ?? {}).length} locations · ${Object.keys(session.preview.institutions ?? {}).length} institutions · ${Object.keys(session.preview.clocks ?? {}).length} clocks`)); +} + +const linkedInvite = new URL(window.location.href).searchParams.get("invite"); +if (linkedInvite) { + sessionStorage.setItem("ghostlight.pendingInvite", linkedInvite); + history.replaceState(null, "", `${window.location.pathname}${window.location.hash}`); +} + +async function fetchJson(input: RequestInfo | URL, init?: RequestInit): Promise { + const response = await fetch(input, { cache: "no-store", credentials: "same-origin", ...init }); + const body = await response.json().catch(() => undefined); + if (!response.ok) { + const message = body && typeof body.message === "string" + ? body.message + : `Ghostlight refused the request (${response.status}).`; + throw new Error(message); } - const host = Boolean(session.viewer_is_host); - ($("#invite-form") as HTMLFormElement).hidden = !host || session.roster_locked; - ($("#lock-roster") as HTMLButtonElement).disabled = !host || session.roster_locked; - ($("#compile-session") as HTMLButtonElement).disabled = !host || !session.roster_locked || ["compiling", "review", "published"].includes(session.status); - ($("#approve-session") as HTMLButtonElement).disabled = session.status !== "review" || session.approved; - ($("#publish-session") as HTMLButtonElement).disabled = !host || !session.publish_ready; + return body as T; } -function renderCampaign(surface: any) { - entry.hidden = true; sessionRoot.hidden = true; surfaceHost.hidden = false; playControls.hidden = false; - revision = Number(surface.world_revision); resolutionEpoch = Number(surface.resolution?.policy?.resolution_epoch ?? 0); viewerActorId = surface.viewer_actor_id; - if (!viewerActorId) throw new Error("Actor-filtered campaign surface omitted the viewer actor binding."); - renderEveSurface(surface, surfaceHost, { body: document.body, clientId: "ghostlight.browser", statusElement: status }); - status.textContent = `World revision ${revision}. Your surface contains only ${viewerActorId}'s permitted state.`; - const budget = Number(surface.resolution?.policy?.active_cell_budget ?? 8); - ($("#active-cell-budget") as HTMLInputElement).value = String(budget); ($("#active-cell-budget-value") as HTMLOutputElement).value = String(budget); - const travelSelect = $("#travel-destination") as HTMLSelectElement; - travelSelect.replaceChildren(...(surface.reachable_destinations ?? []).map((destination: any) => { - const option = document.createElement("option"); option.value = destination.id; option.textContent = `${destination.name} · ${destination.travel_minutes} minutes`; return option; - })); - renderGovernance(surface.governance ?? {}); +function requiredElement(id: string): T { + const element = document.getElementById(id); + if (!(element instanceof HTMLElement)) throw new Error(`Missing browser host #${id}.`); + return element as T; } -function renderGovernance(governance: any) { - const timeForm = $("#time-form") as HTMLFormElement; - const travelForm = $("#travel-form") as HTMLFormElement; - const budgetForm = $("#resolution-form") as HTMLFormElement; - const pendingTime = governance.time_proposals?.[0]; - const pendingTravel = governance.travel_proposals?.[0]; - const pendingBudget = governance.cell_budget_proposals?.[0]; - const timeButton = timeForm.querySelector("button")!; - const travelButton = travelForm.querySelector("button")!; - const budgetButton = budgetForm.querySelector("button")!; - timeButton.textContent = pendingTime ? `Approve ${pendingTime.minutes} minute advance (${pendingTime.approvals.length}/${governance.active_member_count})` : "Propose time"; - travelButton.textContent = pendingTravel ? `Approve group travel (${pendingTravel.approvals.length}/${governance.active_member_count})` : "Propose travel"; - budgetButton.textContent = pendingBudget ? `Approve ${pendingBudget.active_cell_budget} cells (${pendingBudget.approvals.length}/${governance.active_member_count})` : "Propose budget"; - timeForm.dataset.proposalId = pendingTime?.id ?? ""; travelForm.dataset.proposalId = pendingTravel?.id ?? ""; budgetForm.dataset.proposalId = pendingBudget?.id ?? ""; -} +const surfaceHost = requiredElement("surface"); +const status = requiredElement("status"); +const api = new GhostlightEveTransport(); +const host = new EveBrowserProviderHost(surfaceHost, api, { + body: document.body, + clientId: "ghostlight.browser", + pollMs: 0, + requestedSurfaceId: "ghostlight.play", + source: "Ghostlight", + statusElement: status, + pluginAdapters: [heimdallAccessBrowserAdapter], +}); -async function decide(decisionId: string, accept: boolean) { - await post(`/api/session-zero/${sessionId}/decision`, { expected_revision: revision, decision_id: decisionId, accept, counter: null }); await refresh(); -} +window.addEventListener("unhandledrejection", event => { + event.preventDefault(); + status.textContent = event.reason instanceof Error ? event.reason.message : String(event.reason); +}); -function showCommand(body: any) { - receipt.hidden = false; - if (body.kind === "assessed") { - const a = body.assessment; receipt.replaceChildren(el("h2", a.admissible ? `Assessment · DC ${a.dc}` : "Attempt not admitted"), el("p", a.admissible ? `Success: ${a.success_stake}` : a.missing_permission)); - if (a.admissible) { const confirm = el("button", "Confirm server roll"); confirm.addEventListener("click", () => void sendWorld({ type: "attempt", actor_id: viewerActorId, assessment_digest: a.digest })); receipt.append(confirm); } - } else if (body.kind?.includes("pending")) receipt.replaceChildren(el("h2", "Waiting for the table"), el("p", "The proposal is revision-bound and will commit only after every active member approves.")); - else receipt.replaceChildren(el("h2", "World committed"), el("p", body.receipt?.roll ? `d20 ${body.receipt.roll.d20} · ${String(body.receipt.roll.outcome).replaceAll("_", " ")}` : `Revision ${body.revision ?? revision}`)); -} +await host.start(); +await resumeHeimdallAccess({ + complete: async handle => { + const result = await api.completeAuthentication(handle); + if (result.pluginPayload?.pluginId === heimdallAccessBrowserAdapter.pluginId) { + await heimdallAccessBrowserAdapter.consumeCommandResult?.(result.pluginPayload); + } + await host.refresh(); + }, +}); -async function sendWorld(command: unknown) { const body = await post("/api/command", command); showCommand(body); await refresh(); return body; } - -$("#session-entry-form").addEventListener("submit", async event => { event.preventDefault(); const data = Object.fromEntries(new FormData(event.currentTarget as HTMLFormElement)); delete data.mode; await post("/api/session-zero", data); await refresh(); }); -$("#join-form").addEventListener("submit", async event => { event.preventDefault(); const token = ($("#join-token") as HTMLInputElement).value.trim(); await post(`/api/session-zero/join/${encodeURIComponent(token)}`, { display_name: ($("#join-name") as HTMLInputElement).value.trim() }); history.replaceState({}, "", location.pathname); await refresh(); }); -$("#tab-shared").addEventListener("click", () => { activeChannel = "shared:table"; renderSession(currentSurface.session_zero); }); -$("#tab-private").addEventListener("click", () => { activeChannel = `private:${viewerMemberId}`; renderSession(currentSurface.session_zero); }); -$("#session-message-form").addEventListener("submit", async event => { event.preventDefault(); const input = $("#session-message") as HTMLTextAreaElement; await post(`/api/session-zero/${sessionId}/message`, { expected_revision: revision, channel_id: activeChannel, text: input.value.trim() }); input.value = ""; status.textContent = "Your message is durable. The DM is considering it."; await refresh(); }); -$("#invite-form").addEventListener("submit", async event => { event.preventDefault(); const body = await post(`/api/session-zero/${sessionId}/invites`, { count: Number(($( - "#invite-count") as HTMLInputElement).value) }); const output = $("#invite-output"); output.replaceChildren(); for (const token of body.invite_tokens) { const url = `${location.origin}${location.pathname}?invite=${encodeURIComponent(token)}`; const p = el("p"); const link = el("a", url); link.href = url; p.append(link); output.append(p); } await refresh(); }); -$("#boundary-form").addEventListener("submit", async event => { event.preventDefault(); await post(`/api/session-zero/${sessionId}/boundary`, { expected_revision: revision, boundary_id: null, topic: ($("#boundary-topic") as HTMLInputElement).value.trim(), level: ($("#boundary-level") as HTMLSelectElement).value }); ($("#boundary-topic") as HTMLInputElement).value = ""; await refresh(); }); -$("#lock-roster").addEventListener("click", async () => { await post(`/api/session-zero/${sessionId}/lock`, { expected_revision: revision }); await refresh(); }); -$("#compile-session").addEventListener("click", async () => { await post(`/api/session-zero/${sessionId}/compile`, { expected_revision: revision }); await refresh(); }); -$("#approve-session").addEventListener("click", async () => { await post(`/api/session-zero/${sessionId}/approve`, { expected_revision: revision }); await refresh(); }); -$("#publish-session").addEventListener("click", async () => { await post(`/api/session-zero/${sessionId}/publish`, { expected_revision: revision }); await refresh(); }); -$("#composer").addEventListener("submit", async event => { event.preventDefault(); const description = ($("#attempt") as HTMLTextAreaElement).value.trim(); const intended = ($("#intended-effect") as HTMLInputElement).value.trim(); if (!intended) return void (status.textContent = "Name the uncertain effect, or use Speak."); await sendWorld({ type: "assess", expected_revision: revision, intent: { actor_id: viewerActorId, description, intended_effect: intended } }); }); -$("#speak").addEventListener("click", async () => { const input = $("#attempt") as HTMLTextAreaElement; await sendWorld({ type: "speak", expected_revision: revision, actor_id: viewerActorId, text: input.value.trim(), intended_effect: null }); input.value = ""; }); -$("#contract-review").addEventListener("click", async () => { await post("/api/campaigns/contract-review", {}); await refresh(); }); -$("#active-cell-budget").addEventListener("input", event => { ($("#active-cell-budget-value") as HTMLOutputElement).value = (event.currentTarget as HTMLInputElement).value; }); -$("#time-form").addEventListener("submit", async event => { event.preventDefault(); const form = event.currentTarget as HTMLFormElement; const id = form.dataset.proposalId; const body = id ? await post(`/api/governance/time/${encodeURIComponent(id)}/approve`, { expected_revision: revision }) : await post("/api/governance/time", { expected_revision: revision, minutes: Number(($( - "#time-minutes") as HTMLInputElement).value) }); showCommand(body); await refresh(); }); -$("#travel-form").addEventListener("submit", async event => { event.preventDefault(); const form = event.currentTarget as HTMLFormElement; const id = form.dataset.proposalId; const destination = ($("#travel-destination") as HTMLSelectElement).value; if (!id && !destination) return void (status.textContent = "No reachable destination is compiled from this scene."); const body = id ? await post(`/api/governance/travel/${encodeURIComponent(id)}/approve`, { expected_revision: revision }) : await post("/api/governance/travel", { expected_revision: revision, destination_location_id: destination }); showCommand(body); await refresh(); }); -$("#resolution-form").addEventListener("submit", async event => { event.preventDefault(); const form = event.currentTarget as HTMLFormElement; const id = form.dataset.proposalId; const body = id ? await post(`/api/governance/cell-budget/${encodeURIComponent(id)}/approve`, { expected_revision: revision }) : await post("/api/governance/cell-budget", { expected_revision: revision, expected_resolution_epoch: resolutionEpoch, active_cell_budget: Number(($( - "#active-cell-budget") as HTMLInputElement).value) }); showCommand(body); await refresh(); }); - -const events = new EventSource("/api/events"); -let refreshQueued = false; -events.addEventListener("revision", () => { if (refreshQueued) return; refreshQueued = true; window.setTimeout(() => { refreshQueued = false; void refresh().catch(showError); }, 100); }); -events.onerror = () => { status.textContent = "Realtime revision notices are reconnecting; the server remains authoritative."; }; - -void resumeLogin().then(refresh).catch(showError); +const events = new EventSource("api/eve/events"); +events.addEventListener("revision", () => void host.refresh()); +events.addEventListener("error", () => { + status.textContent = "Live revision notices are unavailable; your authoritative surface remains safe to refresh."; +}); diff --git a/web/src/style.css b/web/src/style.css index 03e5cf2..40c4bac 100644 --- a/web/src/style.css +++ b/web/src/style.css @@ -1,5 +1,25 @@ @import url('https://fonts.googleapis.com/css2?family=Crimson+Pro:opsz,wght@8..144,400;8..144,600&family=IBM+Plex+Mono:wght@400;600&display=swap'); -:root{color-scheme:dark;font-family:"Crimson Pro",serif;background:#0c1110;color:#e8e1cf}body{margin:0;min-height:100vh;background:radial-gradient(circle at 15% 0,#253229 0,transparent 38rem),linear-gradient(145deg,#0c1110,#111513)}header,main{width:min(1180px,calc(100% - 2rem));margin:auto}header{padding:3rem 0 1.25rem;border-bottom:1px solid #66543d}h1{font-size:clamp(2.6rem,8vw,5.5rem);font-weight:400;letter-spacing:-.045em;margin:.1rem 0}.eyebrow,#status,label,button,pre,.state-pill,dt{font-family:"IBM Plex Mono",monospace}.eyebrow{color:#d49b58;letter-spacing:.18em;font-size:.72rem}#status{color:#9aa69f;font-size:.78rem}main{padding:1.5rem 0 5rem}#surface{min-height:8rem}form,.card{margin-top:1rem;padding:1rem;border:1px solid #66543d;background:#17201ddd}label{display:block;font-size:.72rem;text-transform:uppercase;letter-spacing:.12em;margin:.65rem 0 .25rem}textarea,input,select{box-sizing:border-box;width:100%;resize:vertical;background:#0b0f0d;color:#f2e7d0;border:1px solid #4a5148;padding:.8rem;margin:.15rem 0;font:1.05rem/1.4 "Crimson Pro",serif}input[type="radio"]{width:auto}input[type="range"]{padding:.25rem;accent-color:#d49b58}textarea{min-height:7rem}button{margin:.8rem .5rem 0 0;padding:.65rem 1rem;border:1px solid #d49b58;background:#d49b58;color:#17120c;cursor:pointer}button+button,.channel-tabs button[aria-pressed="false"]{background:transparent;color:#d49b58}button:disabled,input:disabled,textarea:disabled,select:disabled{cursor:not-allowed;opacity:.5}pre{white-space:pre-wrap;padding:1rem;background:#080b09;color:#aeb9af;overflow:auto;font-size:.72rem}.card h3{margin:.1rem 0}.card p{color:#b9c0b7}.warning{color:#e4a86a!important}code{font-family:"IBM Plex Mono",monospace;color:#d49b58}.skip-link{position:absolute;left:-10000px}.skip-link:focus{left:1rem;top:1rem;background:#d49b58;color:#111;padding:.5rem;z-index:9}.session-heading{display:flex;justify-content:space-between;align-items:end;gap:1rem}.state-pill{padding:.4rem .65rem;border:1px solid #66543d;color:#d49b58;font-size:.72rem}.channel-tabs{position:sticky;top:0;z-index:2;padding:.35rem 0;background:#0c1110e8}.session-grid{display:grid;grid-template-columns:minmax(0,1.65fr) minmax(18rem,1fr);gap:1rem}.session-grid aside{min-width:0}.transcript{list-style:none;padding:0;max-height:34rem;overflow:auto}.message{border-left:2px solid #59675e;padding:.6rem .8rem;margin:.65rem 0;background:#0b0f0d}.message.dm{border-color:#d49b58}.message p{white-space:pre-wrap;margin:.25rem 0}.message strong,dt{color:#d49b58;font-size:.72rem;text-transform:uppercase;letter-spacing:.08em}.decision{border-top:1px solid #354039;padding:.8rem 0}dl{display:grid;grid-template-columns:minmax(7rem,.7fr) minmax(0,1.3fr);gap:.45rem .75rem}dt,dd{margin:0;overflow-wrap:anywhere}fieldset{border:1px solid #4a5148;margin:1rem 0}fieldset label{display:inline-block;margin-right:1rem}.button-row{display:flex;flex-wrap:wrap}.governance{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.governance h2{grid-column:1/-1}.quiet{color:#9aa69f!important}.session-actions button{display:block;width:100%}.card a{color:#d49b58;overflow-wrap:anywhere} -@media(max-width:820px){.session-grid,.governance{grid-template-columns:1fr}.session-grid aside{display:contents}.channel-tabs{display:flex}.channel-tabs button{flex:1}.session-heading{align-items:start;flex-direction:column}dl{grid-template-columns:1fr}.message{padding:.5rem}} -@media(max-width:600px){header{padding-top:2rem}h1{font-size:3rem}header,main{width:min(100% - 1rem,1180px)}form,.card{padding:.75rem}.state-pill{margin:0}} -.form-heading{font:600 .72rem "IBM Plex Mono",monospace;text-transform:uppercase;letter-spacing:.12em;color:#d49b58}.card details{margin:.65rem 0;border-top:1px solid #354039;padding-top:.65rem}.card summary{cursor:pointer;font:600 .76rem "IBM Plex Mono",monospace;color:#d49b58}.card ul{margin:.6rem 0;padding-left:1.25rem}.card li{margin:.25rem 0;color:#c8d0c8}#receipt h3{margin:.1rem 0 .75rem} +:root{color-scheme:dark;font-family:"Crimson Pro",serif;background:#0c1110;color:#e8e1cf} +body{margin:0;min-height:100vh;background:radial-gradient(circle at 15% 0,#253229 0,transparent 38rem),linear-gradient(145deg,#0c1110,#111513)} +header,#surface{width:min(1180px,calc(100% - 2rem));margin:auto} +header{padding:3rem 0 1.25rem;border-bottom:1px solid #66543d} +h1{font-size:clamp(2.6rem,8vw,5.5rem);font-weight:400;letter-spacing:-.045em;margin:.1rem 0} +.eyebrow,#status,.field-label,button,pre{font-family:"IBM Plex Mono",monospace} +.eyebrow{color:#d49b58;letter-spacing:.18em;font-size:.72rem} +#status{color:#9aa69f;font-size:.78rem} +#surface{padding:1.5rem 0 5rem;min-height:12rem} +.eve-surface{display:grid;gap:1rem} +.card,.pane,.heimdall-access{padding:1rem;border:1px solid #66543d;background:#17201ddd} +.cultui-field{display:block;margin:.75rem 0} +.field-label{display:block;font-size:.72rem;text-transform:uppercase;letter-spacing:.12em;margin:.65rem 0 .25rem} +textarea,input,select{box-sizing:border-box;width:100%;resize:vertical;background:#0b0f0d;color:#f2e7d0;border:1px solid #4a5148;padding:.8rem;margin:.15rem 0;font:1.05rem/1.4 "Crimson Pro",serif} +textarea{min-height:7rem} +button{margin:.8rem .5rem 0 0;padding:.65rem 1rem;border:1px solid #d49b58;background:#d49b58;color:#17120c;cursor:pointer} +button:disabled,input:disabled,textarea:disabled,select:disabled{cursor:not-allowed;opacity:.5} +pre,.cultui-code{white-space:pre-wrap;padding:1rem;background:#080b09;color:#aeb9af;overflow:auto;font:.72rem/1.5 "IBM Plex Mono",monospace} +.skip-link{position:absolute;left:-10000px}.skip-link:focus{left:1rem;top:1rem;background:#d49b58;color:#111;padding:.5rem;z-index:9} +.cultui-list-item{border-top:1px solid #354039;padding:.8rem 0} +.cultui-list-item-label,.cultui-list-item-status{font-family:"IBM Plex Mono",monospace;color:#d49b58;font-size:.72rem;text-transform:uppercase;letter-spacing:.08em} +.cultui-tabs [role="tablist"]{display:flex;gap:.4rem;position:sticky;top:0;background:#0c1110e8;z-index:2} +.eve-command-result{margin:1rem 0;padding:1rem;border:1px solid #66543d;background:#17201d} +@media(max-width:600px){header{padding-top:2rem}h1{font-size:3rem}header,#surface{width:min(100% - 1rem,1180px)}.card,.pane,.heimdall-access{padding:.75rem}} diff --git a/web/test/static-boundary.mjs b/web/test/static-boundary.mjs new file mode 100644 index 0000000..ac429fc --- /dev/null +++ b/web/test/static-boundary.mjs @@ -0,0 +1,36 @@ +import { readFileSync, readdirSync, statSync } from "node:fs"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const forbidden = [ + "/api/session-zero", + "/api/governance", + "/api/command", + "/api/auth/heimdall", + "renderSession", + "renderCampaign", + "payload.fields", + 'kind: "form"', + '"kind":"form"', +]; + +function sourceFiles(directory) { + return readdirSync(directory) + .flatMap(name => { + const path = join(directory, name); + return statSync(path).isDirectory() ? sourceFiles(path) : [path]; + }) + .filter(path => /\.(ts|tsx|js|mjs)$/.test(path)); +} + +const violations = sourceFiles(fileURLToPath(new URL("../src", import.meta.url))) + .flatMap(path => { + const source = readFileSync(path, "utf8"); + return forbidden.filter(token => source.includes(token)).map(token => `${path}: ${token}`); + }); + +if (violations.length) { + throw new Error(`Ghostlight browser crossed its Eve boundary:\n${violations.join("\n")}`); +} + +console.log("Ghostlight browser contains only the Eve provider boundary."); diff --git a/web/vite.config.mjs b/web/vite.config.mjs new file mode 100644 index 0000000..946bc96 --- /dev/null +++ b/web/vite.config.mjs @@ -0,0 +1,15 @@ +import { fileURLToPath, URL } from "node:url"; +import { defineConfig } from "vite"; + +export default defineConfig({ + resolve: { + alias: { + "@gamecult/eve-contracts": fileURLToPath( + new URL("../vendor/eve/packages/eve-contracts/dist/index.js", import.meta.url), + ), + "ajv/dist/2020.js": fileURLToPath( + new URL("./node_modules/ajv/dist/2020.js", import.meta.url), + ), + }, + }, +});