diff --git a/cypher2/README.md b/cypher2/README.md
new file mode 100644
index 00000000..dfd3e166
--- /dev/null
+++ b/cypher2/README.md
@@ -0,0 +1,31 @@
+# Cypher 2 — official Roll20 Beacon character sheet
+
+Official Beacon character sheet for **Cypher 2** (system family: **Cypher**),
+published by **Monte Cook Games**. Built with Vue 3, Pinia, and the Beacon SDK.
+
+## Features
+
+- Full character sentence (descriptor / type / focus, with optional species and
+ second descriptor/focus), tier, effort, XP, and pools with edge
+- Quick d20 pool rolls and a guided roller with skill selection, assets,
+ effort spending (edge-aware), and live cost/ease preview
+- Damage track, recovery rolls, shield and armor tracking
+- Skills (with proficiencies), abilities, attacks, cyphers, artifacts, gear,
+ and character arcs
+- Genre skins configurable from the sheet's settings
+
+## Development
+
+```bash
+npm i
+npm run dev # dev server with an offline relay (browser, no Roll20)
+npm run build # generates the validator, compiles scss, bundles dist/
+```
+
+## Structure notes
+
+- `src/contract/validate.js` is **generated** — `prebuild` regenerates it from
+ `cypher-contract/cypher-character.schema.json` (the vendored character-data
+ schema). Edit the schema, not the generated file.
+- `public/host.css` is compiled from `src/rollTemplates/host.scss` by
+ `npm run build-scss`.
diff --git a/cypher2/cypher-contract/cypher-character.schema.json b/cypher2/cypher-contract/cypher-character.schema.json
new file mode 100644
index 00000000..4a8a10f5
--- /dev/null
+++ b/cypher2/cypher-contract/cypher-character.schema.json
@@ -0,0 +1,452 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://clockpunkstudios.com/cypher-contract/cypher-character.schema.json",
+ "title": "Cypher Character",
+ "description": "Canonical Cypher character document, schemaVersion 2. Contract between Cypher Tools (exporter), the Roll20 Beacon sheet (importer), and the compendium build (drag-drop payloads). v2 adopts the Cypher Tools (MCG) counter-proposal of 2026-08-24 — rationale per field cites section numbers of 2026-08-24-response-v2/cypher-tools-format-gap-audit.md; the acceptance decision record is handoff/2026-08-24-v2-acceptance.md. Conventions from v1 are preserved throughout: additionalProperties false everywhere, every field required, an absent value is an explicit \"\", [], or null rather than an omitted key. See docs/rules-verification.md for book-verified rule values.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "schemaVersion", "kind", "name", "sentence", "tier", "effort", "xp", "storyXp",
+ "resourcePoints", "rank", "advancement", "pools", "recovery", "wounds", "shield",
+ "armor", "armorModifiers", "cypherLimit", "genre", "subgenre",
+ "skills", "abilities", "attacks", "equipment", "cyphers", "artifacts",
+ "powerShifts", "currencies", "arcs",
+ "background", "notes", "portraitUrl"
+ ],
+ "properties": {
+ "schemaVersion": { "const": 2 },
+ "kind": { "const": "cypher-character" },
+ "name": { "type": "string", "minLength": 1 },
+
+ "sentence": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["descriptor", "secondDescriptor", "type", "focus", "secondFocus", "species"],
+ "properties": {
+ "descriptor": { "type": "string" },
+ "secondDescriptor": {
+ "type": "string",
+ "description": "ADDED (§3.12). The book allows a character to take two descriptors (\"you instead gain the benefit of two descriptors\" — your own rules-verification.md). v1 could only hold one, forcing exporters to join them into a single string."
+ },
+ "type": {
+ "type": "string",
+ "description": "NOTE (§6.7), no shape change: in the real-world genre there are no book types at all — the player enters a free-text profession (\"Paramedic\", \"Investigative Journalist\") and it occupies this slot. An importer must not validate `type` against a known list."
+ },
+ "focus": { "type": "string" },
+ "secondFocus": {
+ "type": "string",
+ "description": "ADDED (§6.1). The superhero Living God type grants a Second Focus ability, and the character then has two. Without this field the two are joined into `focus` as \"Masters Weaponry and Explores\", which reads as one focus with an odd name. Rare — exactly one of our 55 types grants it — but the cost is one string and the failure without it is silent. \"\" when the character has one focus."
+ },
+ "species": { "type": "string", "description": "Cypher Tools tracks species first-class; see §6 question 1 re: reconciling the Bross fixture." }
+ }
+ },
+
+ "tier": { "type": "integer", "minimum": 1 },
+ "effort": { "type": "integer", "minimum": 1, "description": "No maximum (amended from the MCG draft's 6 at acceptance — handoff/2026-08-24-v2-acceptance.md §2): 6 is the cap via normal advancement, but abilities (e.g. Superheroics) can raise the Effort limit above it. Importers must not reject or clamp values above 6. Mirrors the unbounded `tier` precedent." },
+ "xp": { "type": "integer", "minimum": 0 },
+ "storyXp": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "ADDED (§3.15). A second, separately-tracked XP pool. v1 had one `xp`, which forced the Foundry export to sum the two into a single number and lose the distinction. 0 when the game doesn't use it."
+ },
+ "resourcePoints": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "ADDED (§3.15). \"RP\" — a progression counter, deliberately NOT a currency. 0 when unused."
+ },
+ "rank": {
+ "anyOf": [{ "type": "integer", "minimum": 1, "maximum": 5 }, { "type": "null" }],
+ "description": "ADDED (§3.14). Superhero rank 1–5; gates which origin abilities a character may take. null outside the superhero genre."
+ },
+
+ "advancement": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["stats", "effort", "edge", "skill", "other"],
+ "description": "UNCHANGED. Maps 1:1 to Cypher Tools' five advancement slots. Note §4.10: tier 7+ characters currently export all-false because we stop recording purchases past tier 6 — ours to fix, not a schema problem.",
+ "properties": {
+ "stats": { "type": "boolean" },
+ "effort": { "type": "boolean" },
+ "edge": { "type": "boolean" },
+ "skill": { "type": "boolean" },
+ "other": { "type": "boolean" }
+ }
+ },
+
+ "pools": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["might", "speed", "intellect"],
+ "properties": {
+ "might": { "$ref": "#/$defs/pool" },
+ "speed": { "$ref": "#/$defs/pool" },
+ "intellect": { "$ref": "#/$defs/pool" }
+ }
+ },
+
+ "recovery": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["bonus", "slots"],
+ "description": "CHANGED (§2.4) — this is our highest-priority ask, and the one place v1 is narrower than the book rather than narrower than our model.",
+ "properties": {
+ "bonus": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "UNCHANGED. Points added to the 1d6 recovery roll; defaults to tier."
+ },
+ "slots": {
+ "type": "array",
+ "minItems": 1,
+ "items": { "$ref": "#/$defs/recoverySlot" },
+ "description": "REPLACES v1's `used` object of exactly four booleans. Order is significant — position determines rest duration, and the book's \"+2 if the one-action recovery is taken as your last action\" depends on it. A default character has exactly four slots in the order action, tenMinutes, oneHour, tenHours, which is v1's shape expressed as an array. Why the change: (a) five separate abilities grant EXTRA one-action recoveries — Healing (one per shift, unbounded), Untamed Recovery, Mind Surge, Machine Not Flesh — so a character with two Healing shifts has six slots and v1 can carry four; (b) Push on Through REPLACES the ten-minute recovery with a second one-action recovery, so for those characters v1's `used.tenMinutes` silently mislabels a one-action slot. Both are expressible here without special cases."
+ }
+ }
+ },
+
+ "wounds": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["minor", "moderate", "major"],
+ "properties": {
+ "minor": { "$ref": "#/$defs/woundTier" },
+ "moderate": { "$ref": "#/$defs/woundTier" },
+ "major": { "$ref": "#/$defs/woundTier" }
+ }
+ },
+
+ "shield": {
+ "anyOf": [{ "$ref": "#/$defs/shield" }, { "type": "null" }],
+ "description": "ADDED (§3.7). A shield tracks its own wounds — \"A shield can take three minor wounds, two moderate wounds, and one major wound\" (quoted in your own rules-verification.md, where it is noted as out of scope for v1). Maxima are per-character because abilities modify them (Shield Master raises moderate to 3). null when the character carries no shield."
+ },
+
+ "armor": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "RETAINED, but see §3.22 — we believe this field is inherited from the Foundry `cyphersystem` system (1e-shaped) rather than from the 2e book, and we will send 0 for essentially every character. Evidence: the official 2e form-fillable sheet has no numeric Armor field (only a free-text Armor_and_Modifiers box plus armor-proficiency checkboxes), our builder hardcodes 0, and no PC-facing ability in the Character Rulebook grants a numeric Armor bonus. Left in place rather than removed so any 1e-shaped consumer keeps working; `armorModifiers` below is where the real information lives. Worth deciding whether it survives to v3."
+ },
+ "armorModifiers": {
+ "type": "string",
+ "description": "ADDED (§3.22). The free-text armor box as it appears on the 2e sheet — the field that actually records a character's armor. \"\" when empty."
+ },
+
+ "cypherLimit": { "type": "integer", "minimum": 0 },
+
+ "genre": {
+ "type": "string",
+ "description": "ADDED (§3.13). e.g. \"fantasy\", \"scifi\", \"superhero\", \"real_world\". Drives cypher naming and equipment lists, and tells an importer which optional systems are in play. \"\" when unset."
+ },
+ "subgenre": {
+ "type": "string",
+ "description": "ADDED (§3.13). e.g. \"Dungeon Fantasy\". \"\" when unset."
+ },
+
+ "skills": { "type": "array", "items": { "$ref": "#/$defs/skill" } },
+ "abilities": { "type": "array", "items": { "$ref": "#/$defs/ability" } },
+ "attacks": { "type": "array", "items": { "$ref": "#/$defs/attack" } },
+ "equipment": { "type": "array", "items": { "$ref": "#/$defs/equipment" } },
+ "cyphers": { "type": "array", "items": { "$ref": "#/$defs/cypher" } },
+ "artifacts": { "type": "array", "items": { "$ref": "#/$defs/artifact" } },
+ "powerShifts": { "type": "array", "items": { "$ref": "#/$defs/powerShift" } },
+ "currencies": { "type": "array", "items": { "$ref": "#/$defs/currency" } },
+ "arcs": { "type": "array", "items": { "$ref": "#/$defs/arc" } },
+
+ "background": { "type": "string" },
+ "notes": { "type": "string" },
+ "portraitUrl": {
+ "type": "string",
+ "description": "ADDED (§3.20). A fetchable URL for the character's portrait, or \"\" when there is none. Cypher Tools already serves portrait URLs to unauthenticated clients via its share-link endpoint, so this is an established path rather than a new exposure. Consumers should treat it as optional and degrade gracefully — it is served by the application rather than a CDN."
+ }
+ },
+
+ "$defs": {
+ "pool": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["current", "max", "edge"],
+ "properties": {
+ "current": { "type": "integer", "minimum": 0 },
+ "max": { "type": "integer", "minimum": 0 },
+ "edge": { "type": "integer", "minimum": 0 }
+ }
+ },
+ "woundTier": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["current", "max"],
+ "properties": {
+ "current": { "type": "integer", "minimum": 0 },
+ "max": { "type": "integer", "minimum": 0 }
+ }
+ },
+ "shield": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["minor", "moderate", "major"],
+ "description": "ADDED (§3.7). Book default 3 / 2 / 1; maxima are per-character because abilities modify them.",
+ "properties": {
+ "minor": { "$ref": "#/$defs/woundTier" },
+ "moderate": { "$ref": "#/$defs/woundTier" },
+ "major": { "$ref": "#/$defs/woundTier" }
+ }
+ },
+ "recoverySlot": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["kind", "used", "note"],
+ "description": "ADDED (§2.4). One box on the recovery track.",
+ "properties": {
+ "kind": {
+ "enum": ["action", "tenMinutes", "oneHour", "tenHours"],
+ "description": "The rest duration this slot requires. A character may have more than one slot of the same kind — that is exactly how extra one-action recoveries and Push on Through are represented."
+ },
+ "used": { "type": "boolean" },
+ "note": {
+ "type": "string",
+ "description": "Why this slot exists beyond the standard four, or any restriction on it — e.g. \"Healing power shift\", or \"Mind Surge: Intellect Pool only\". \"\" for the four standard slots."
+ }
+ }
+ },
+
+ "poolName": { "enum": ["might", "speed", "intellect"] },
+ "skillRating": { "enum": ["inability", "practiced", "trained", "specialized", "expert"] },
+ "weaponRange": {
+ "enum": ["immediate", "short", "long", "veryLong", "special"],
+ "description": "ADDED (§3.2)."
+ },
+
+ "skill": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "rating", "pool", "asset", "isProficiency", "source", "description"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "rating": { "$ref": "#/$defs/skillRating" },
+ "pool": { "anyOf": [{ "$ref": "#/$defs/poolName" }, { "type": "null" }] },
+ "asset": {
+ "enum": [0, 1, 2],
+ "description": "ADDED (§3.5). Assets ease a task like training does but stack under different rules, so they cannot be folded into `rating`. v1 had no home for this and our Foundry export smuggles it into description text as \"Asset: x2.\". 0 when none."
+ },
+ "isProficiency": {
+ "type": "boolean",
+ "description": "ADDED (§3.6). True for type/focus-granted weapon and armor proficiencies (\"Freely Use All Weapons\", \"Freely Use Light And Medium Armor\"). These are NOT trainable via advancement and should not render with a rating badge. In bross-drikess.json they appear as ordinary \"practiced\" skills, so a v1 importer will offer to advance them."
+ },
+ "source": { "type": "string" },
+ "description": { "type": "string" }
+ }
+ },
+
+ "ability": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "cost", "pools", "enabler", "activation", "source", "description"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "cost": {
+ "description": "UNCHANGED from v1. null = no cost. variable: true means the cost is set in play (points MUST be null, plus MUST be false).",
+ "anyOf": [
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["points", "plus", "variable"],
+ "properties": {
+ "points": { "anyOf": [{ "type": "integer", "minimum": 0 }, { "type": "null" }] },
+ "plus": { "type": "boolean" },
+ "variable": { "type": "boolean" }
+ },
+ "oneOf": [
+ { "properties": { "variable": { "const": false }, "points": { "type": "integer" } } },
+ { "properties": { "variable": { "const": true }, "points": { "type": "null" }, "plus": { "const": false } } }
+ ]
+ },
+ { "type": "null" }
+ ]
+ },
+ "pools": {
+ "type": "array",
+ "items": { "$ref": "#/$defs/poolName" },
+ "uniqueItems": true,
+ "maxItems": 3
+ },
+ "enabler": {
+ "type": "boolean",
+ "description": "UNCHANGED, and derivable from `activation` — kept so consumers that only need the binary distinction don't have to parse a string."
+ },
+ "activation": {
+ "type": "string",
+ "description": "ADDED (§3.1). The ability's activation as printed, verbatim. `enabler` answers \"is this an enabler\" but discards WHEN IN THE ROUND the ability fires, which is what a VTT sheet needs for initiative-order UI. Across our 663-row catalog: \"Enabler\" (344), \"Action\" (143), \"Action to initiate\" (54), \"Last action\" (31), \"First action\" (8), plus ~25 long-form variants — e.g. \"Action when in your normal form; enabler when using Beast Form\", \"Ten minutes to prepare a cypher as a spell; action to cast a cypher as a spell\", \"First action, action, or Last action\". Deliberately a string and not an enum: the long-form tail is irreducible. \"\" when the source gives none."
+ },
+ "source": { "type": "string" },
+ "description": { "type": "string" }
+ }
+ },
+
+ "attack": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "pool", "weaponClass", "damage", "skillRating", "range", "modifier", "notes"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "pool": { "$ref": "#/$defs/poolName" },
+ "weaponClass": { "anyOf": [{ "enum": ["light", "medium", "heavy"] }, { "type": "null" }] },
+ "damage": { "type": "integer", "minimum": 0 },
+ "skillRating": { "$ref": "#/$defs/skillRating" },
+ "range": {
+ "anyOf": [{ "$ref": "#/$defs/weaponRange" }, { "type": "null" }],
+ "description": "ADDED (§3.2). Note our EXISTING Foundry export already carries this as system.basic.range, so v1 is a regression against what Roll20 users get today by importing the Foundry file. null when unspecified (treat as immediate)."
+ },
+ "modifier": {
+ "anyOf": [{ "$ref": "#/$defs/attackModifier" }, { "type": "null" }],
+ "description": "ADDED (§3.3). A standing ease/hinder on this attack. Also already in the Foundry export as system.basic.steps + modifier. null when the attack is unmodified."
+ },
+ "notes": { "type": "string" }
+ }
+ },
+ "attackModifier": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["steps", "direction"],
+ "properties": {
+ "steps": { "type": "integer", "minimum": 1 },
+ "direction": { "enum": ["eased", "hindered"] }
+ }
+ },
+
+ "equipment": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "level", "quantity", "notes"],
+ "description": "UNCHANGED. Note (§2.3) that Cypher Tools stores equipment as free text, one item per line, so we will send level: null — the level 1 / quantity 1 values in bross-drikess.json are an artifact of our Foundry renderer, not character data.",
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "level": { "anyOf": [{ "type": "integer", "minimum": 1 }, { "type": "null" }] },
+ "quantity": { "type": "integer", "minimum": 0 },
+ "notes": { "type": "string" }
+ }
+ },
+
+ "cypher": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "displayName", "level", "cypherKind", "power", "activated", "description"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "displayName": {
+ "type": "string",
+ "description": "ADDED (§3.10). Genre-specific alias, when it differs from the canonical name — the catalog renames some cyphers per genre. \"\" when the same as `name`."
+ },
+ "level": { "anyOf": [{ "type": "integer", "minimum": 1 }, { "type": "null" }] },
+ "cypherKind": {
+ "anyOf": [{ "enum": ["cypher", "manifest"] }, { "type": "null" }],
+ "description": "ADDED (§3.10). Manifest cyphers are worn or wielded rather than one-shot, so this is a behavioral difference and not a label — 98 of our 189 catalog cyphers are manifest. Named `cypherKind` rather than `kind` to avoid colliding with the drop payload's `kind`."
+ },
+ "power": {
+ "anyOf": [{ "enum": ["low", "medium", "high", "advanced", "ultra", "nonstandard"] }, { "type": "null" }],
+ "description": "ADDED (§3.10). Power tier. null is legitimate and common — 73 of our 189 catalog cyphers carry no power icon."
+ },
+ "activated": {
+ "type": "boolean",
+ "description": "ADDED (§3.10). Whether the cypher is currently in use."
+ },
+ "description": { "type": "string" }
+ }
+ },
+
+ "artifact": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "level", "depletion", "form", "description"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "level": {
+ "anyOf": [{ "type": "integer", "minimum": 1 }, { "type": "null" }],
+ "description": "UNCHANGED and correct as-is: an artifact on a character has a rolled integer level. The book's roll formula (\"1d6 + 3\") stays a catalog concern on the exporter's side."
+ },
+ "depletion": {
+ "description": "CHANGED (§2.1). One addition: the \"automatic\" sentinel, for artifacts that deplete on use. This is NOT the same as null — null means an artifact never depletes, and conflating the two is a correctness bug rather than a lost detail. Also stating explicitly what v1 left ambiguous: `chance` means depletion occurs on a roll of 1 through `chance`, which is what makes the book's ranged forms (\"1-3 in 1d6\") representable. Note the book writes d100 as \"1d00\"; `die` keeps the \"1d100\" spelling and exporters map it. Two further kinds of depletion text — the \"(check each ...)\" trigger clause (25 of the book's 72 artifacts) and the \"upon depletion, ...\" consequence (19) — are deliberately NOT structured here; Cypher Tools does not model artifacts yet, so we would rather see how they are used before fixing a shape, and they can live in `description` meanwhile. Flagged in §2.1 so the loss is a known decision rather than an oversight.",
+ "anyOf": [
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["chance", "die"],
+ "properties": {
+ "chance": {
+ "type": "integer",
+ "minimum": 1,
+ "description": "Depletion occurs on a roll of 1 through `chance` — this reading makes the book's ranged forms (\"1-3 in 1d6\", 5 rows) representable. v1 left it ambiguous; stating it explicitly here."
+ },
+ "die": { "enum": ["1d6", "1d10", "1d20", "1d100"] }
+ }
+ },
+ { "const": "automatic" },
+ { "type": "null" }
+ ]
+ },
+ "form": {
+ "type": "string",
+ "description": "ADDED (§2.1). Populated on every one of the book's 72 artifacts and often the most evocative text on the row (\"Beaded necklace set with closed eye symbol or jewel\"). \"\" when none."
+ },
+ "description": { "type": "string" }
+ }
+ },
+
+ "powerShift": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "shifts", "description"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "shifts": { "type": "integer", "minimum": 1 },
+ "description": { "type": "string" }
+ }
+ },
+ "currency": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "amount"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "amount": { "type": "number", "minimum": 0 }
+ }
+ },
+ "arcStep": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "completed"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "completed": { "type": "boolean" }
+ }
+ },
+ "arc": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "description", "steps"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "description": { "type": "string" },
+ "steps": { "type": "array", "items": { "$ref": "#/$defs/arcStep" } }
+ }
+ },
+
+ "dropPayload": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["contractVersion", "kind", "item"],
+ "description": "contractVersion bumps in lockstep with schemaVersion, per your README.",
+ "properties": {
+ "contractVersion": { "const": 2 },
+ "kind": { "enum": ["skill", "ability", "equipment", "cypher", "artifact", "arc"] },
+ "item": { "type": "object" }
+ },
+ "oneOf": [
+ { "properties": { "kind": { "const": "skill" }, "item": { "$ref": "#/$defs/skill" } } },
+ { "properties": { "kind": { "const": "ability" }, "item": { "$ref": "#/$defs/ability" } } },
+ { "properties": { "kind": { "const": "equipment" }, "item": { "$ref": "#/$defs/equipment" } } },
+ { "properties": { "kind": { "const": "cypher" }, "item": { "$ref": "#/$defs/cypher" } } },
+ { "properties": { "kind": { "const": "artifact" }, "item": { "$ref": "#/$defs/artifact" } } },
+ { "properties": { "kind": { "const": "arc" }, "item": { "$ref": "#/$defs/arc" } } }
+ ]
+ }
+ }
+}
diff --git a/cypher2/index.html b/cypher2/index.html
new file mode 100644
index 00000000..4870139c
--- /dev/null
+++ b/cypher2/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Cypher Sheet
+
+
+
+
+
+
diff --git a/cypher2/package-lock.json b/cypher2/package-lock.json
new file mode 100644
index 00000000..f3bee673
--- /dev/null
+++ b/cypher2/package-lock.json
@@ -0,0 +1,9935 @@
+{
+ "name": "@clockpunk/cypher-beacon-sheet",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@clockpunk/cypher-beacon-sheet",
+ "version": "0.0.0",
+ "dependencies": {
+ "@roll20-official/beacon-sdk": "^0.1.17",
+ "ajv": "^8.17.1",
+ "handlebars": "^4.7.8",
+ "lodash": "^4.17.21",
+ "pinia": "^2.1.7",
+ "uuid": "^9.0.1",
+ "vue": "^3.4.21"
+ },
+ "devDependencies": {
+ "@rushstack/eslint-patch": "^1.8.0",
+ "@tailwindcss/vite": "^4.3.3",
+ "@types/uuid": "^9.0.8",
+ "@vitejs/plugin-vue": "^5.0.4",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/eslint-config-prettier": "^9.0.0",
+ "@vue/test-utils": "^2.4.11",
+ "eslint": "^8.57.0",
+ "eslint-plugin-vue": "^9.23.0",
+ "jsdom": "^24.1.3",
+ "npm-run-all": "^4.1.5",
+ "playwright": "^1.49.1",
+ "postcss": "^8.5.26",
+ "postcss-selector-parser": "^6.1.4",
+ "prettier": "^3.2.5",
+ "sass": "^1.75.0",
+ "tailwindcss": "^4.3.3",
+ "vite": "^5.2.8",
+ "vite-plugin-vue-devtools": "^7.0.25",
+ "vitest": "^1.6.1"
+ }
+ },
+ "node_modules/@antfu/utils": {
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz",
+ "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+ "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@babel/types": "^7.29.8",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+ "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
+ "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.29.7",
+ "@babel/helper-member-expression-to-functions": "^7.29.7",
+ "@babel/helper-optimise-call-expression": "^7.29.7",
+ "@babel/helper-replace-supers": "^7.29.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
+ "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
+ "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
+ "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.29.7",
+ "@babel/helper-optimise-call-expression": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
+ "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.8"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-decorators": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz",
+ "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.29.7",
+ "@babel/helper-plugin-utils": "^7.29.7",
+ "@babel/plugin-syntax-decorators": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-decorators": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz",
+ "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz",
+ "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+ "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+ "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz",
+ "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.29.7",
+ "@babel/helper-create-class-features-plugin": "^7.29.7",
+ "@babel/helper-plugin-utils": "^7.29.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+ "@babel/plugin-syntax-typescript": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+ "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+ "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.8",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.8",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.8",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.1.0",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz",
+ "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ajv": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
+ "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@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",
+ "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^22.20 || ^24.12 || >=25"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@one-ini/wasm": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@parcel/watcher": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz",
+ "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.6.0",
+ "@parcel/watcher-darwin-arm64": "2.6.0",
+ "@parcel/watcher-darwin-x64": "2.6.0",
+ "@parcel/watcher-freebsd-x64": "2.6.0",
+ "@parcel/watcher-linux-arm-glibc": "2.6.0",
+ "@parcel/watcher-linux-arm-musl": "2.6.0",
+ "@parcel/watcher-linux-arm64-glibc": "2.6.0",
+ "@parcel/watcher-linux-arm64-musl": "2.6.0",
+ "@parcel/watcher-linux-x64-glibc": "2.6.0",
+ "@parcel/watcher-linux-x64-musl": "2.6.0",
+ "@parcel/watcher-win32-arm64": "2.6.0",
+ "@parcel/watcher-win32-x64": "2.6.0"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz",
+ "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz",
+ "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz",
+ "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz",
+ "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz",
+ "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz",
+ "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz",
+ "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz",
+ "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz",
+ "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz",
+ "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz",
+ "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz",
+ "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz",
+ "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@roll20-official/beacon-sdk": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@roll20-official/beacon-sdk/-/beacon-sdk-0.1.17.tgz",
+ "integrity": "sha512-xNzxoE9hE7jENZbUAnoSh37YPdx0PV4dog5pImp74WNybnse5u1mNqEz/2L/SXxjIVqTFG40S9Le+FxgBNMHog==",
+ "license": "ISC",
+ "dependencies": {
+ "@types/sanitize-html": "^2.9.3",
+ "axios": "^1.5.0",
+ "axios-retry": "^3.7.0",
+ "buffer": "^6.0.3",
+ "deep-object-diff": "^1.1.7",
+ "lodash": "^4.17.21",
+ "prettier": "^2.6.2",
+ "process": "^0.11.10",
+ "sanitize-html": "^2.11.0",
+ "sanitize-html-react": "^1.13.0",
+ "throttle-debounce": "^5.0.0",
+ "typescript": "^4.6.3",
+ "uuid": "^8.3.2"
+ }
+ },
+ "node_modules/@roll20-official/beacon-sdk/node_modules/prettier": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/@roll20-official/beacon-sdk/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz",
+ "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz",
+ "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz",
+ "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz",
+ "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz",
+ "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz",
+ "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz",
+ "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz",
+ "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz",
+ "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz",
+ "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz",
+ "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz",
+ "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz",
+ "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz",
+ "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz",
+ "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz",
+ "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz",
+ "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz",
+ "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz",
+ "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz",
+ "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz",
+ "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz",
+ "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz",
+ "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz",
+ "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz",
+ "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz",
+ "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rushstack/eslint-patch": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.16.1.tgz",
+ "integrity": "sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sec-ant/readable-stream": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
+ "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.12",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz",
+ "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
+ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz",
+ "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "enhanced-resolve": "^5.24.1",
+ "jiti": "^2.7.0",
+ "lightningcss": "1.32.0",
+ "magic-string": "^0.30.21",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.3.3"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz",
+ "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.3.3",
+ "@tailwindcss/oxide-darwin-arm64": "4.3.3",
+ "@tailwindcss/oxide-darwin-x64": "4.3.3",
+ "@tailwindcss/oxide-freebsd-x64": "4.3.3",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.3.3",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.3.3",
+ "@tailwindcss/oxide-linux-x64-musl": "4.3.3",
+ "@tailwindcss/oxide-wasm32-wasi": "4.3.3",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.3.3"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz",
+ "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz",
+ "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz",
+ "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz",
+ "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz",
+ "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz",
+ "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz",
+ "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz",
+ "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz",
+ "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz",
+ "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.11.1",
+ "@emnapi/runtime": "^1.11.1",
+ "@emnapi/wasi-threads": "^1.2.2",
+ "@napi-rs/wasm-runtime": "^1.1.4",
+ "@tybys/wasm-util": "^0.10.2",
+ "tslib": "^2.8.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz",
+ "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz",
+ "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/vite": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz",
+ "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tailwindcss/node": "4.3.3",
+ "@tailwindcss/oxide": "4.3.3",
+ "tailwindcss": "4.3.3"
+ },
+ "peerDependencies": {
+ "vite": "^5.2.0 || ^6 || ^7 || ^8"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/sanitize-html": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.16.1.tgz",
+ "integrity": "sha512-n9wjs8bCOTyN/ynwD8s/nTcTreIHB1vf31vhLMGqUPNHaweKC4/fAl4Dj+hUlCTKYgm4P3k83fmiFfzkZ6sgMA==",
+ "license": "MIT",
+ "dependencies": {
+ "htmlparser2": "^10.1"
+ }
+ },
+ "node_modules/@types/uuid": {
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
+ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz",
+ "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vitejs/plugin-vue-jsx": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.1.0.tgz",
+ "integrity": "sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.23.3",
+ "@babel/plugin-transform-typescript": "^7.23.3",
+ "@vue/babel-plugin-jsx": "^1.1.5"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.0.0 || ^5.0.0",
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz",
+ "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "1.6.1",
+ "@vitest/utils": "1.6.1",
+ "chai": "^4.3.10"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz",
+ "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "1.6.1",
+ "p-limit": "^5.0.0",
+ "pathe": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner/node_modules/p-limit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
+ "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@vitest/runner/node_modules/pathe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vitest/runner/node_modules/yocto-queue": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz",
+ "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz",
+ "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "magic-string": "^0.30.5",
+ "pathe": "^1.1.1",
+ "pretty-format": "^29.7.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot/node_modules/pathe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vitest/spy": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz",
+ "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^2.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz",
+ "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "diff-sequences": "^29.6.3",
+ "estree-walker": "^3.0.3",
+ "loupe": "^2.3.7",
+ "pretty-format": "^29.7.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils/node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/@vue/babel-helper-vue-transform-on": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz",
+ "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vue/babel-plugin-jsx": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz",
+ "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.0",
+ "@babel/types": "^7.28.2",
+ "@vue/babel-helper-vue-transform-on": "1.5.0",
+ "@vue/babel-plugin-resolve-type": "1.5.0",
+ "@vue/shared": "^3.5.18"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/babel-plugin-resolve-type": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz",
+ "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/parser": "^7.28.0",
+ "@vue/compiler-sfc": "^3.5.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
+ "integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.7",
+ "@vue/shared": "3.5.40",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz",
+ "integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.40",
+ "@vue/shared": "3.5.40"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz",
+ "integrity": "sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.7",
+ "@vue/compiler-core": "3.5.40",
+ "@vue/compiler-dom": "3.5.40",
+ "@vue/compiler-ssr": "3.5.40",
+ "@vue/shared": "3.5.40",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.19",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz",
+ "integrity": "sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.40",
+ "@vue/shared": "3.5.40"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
+ "license": "MIT"
+ },
+ "node_modules/@vue/devtools-core": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.10.tgz",
+ "integrity": "sha512-rpsAY7HuxYUz6G7R0zBGoOgYsn/r3iU0LixLOGNJ3o5if6tkPDGIGV+6CIJbDNbeueP2HsGDCOQ5ni6Wr36xEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.10",
+ "@vue/devtools-shared": "^7.7.10",
+ "mitt": "^3.0.1",
+ "nanoid": "^5.1.0",
+ "pathe": "^2.0.3",
+ "vite-hot-client": "^2.0.4"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/@vue/devtools-core/node_modules/nanoid": {
+ "version": "5.1.16",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.16.tgz",
+ "integrity": "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.js"
+ },
+ "engines": {
+ "node": "^18 || >=20"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.10.tgz",
+ "integrity": "sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.10",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.10.tgz",
+ "integrity": "sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/eslint-config-prettier": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
+ "integrity": "sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-config-prettier": "^9.0.0",
+ "eslint-plugin-prettier": "^5.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">= 8.0.0",
+ "prettier": ">= 3.0.0"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz",
+ "integrity": "sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.40"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.40.tgz",
+ "integrity": "sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.40",
+ "@vue/shared": "3.5.40"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz",
+ "integrity": "sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.40",
+ "@vue/runtime-core": "3.5.40",
+ "@vue/shared": "3.5.40",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.40.tgz",
+ "integrity": "sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.40",
+ "@vue/runtime-dom": "3.5.40",
+ "@vue/shared": "3.5.40"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
+ "integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
+ "license": "MIT"
+ },
+ "node_modules/@vue/test-utils": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.11.tgz",
+ "integrity": "sha512-GDqaqZsA6m2E5vNzej0aYiIb6BX8xV9pNSbbbXKOfEYwg7ZNblVX8suyqmUBThq8VIrgAJNxn+z72hVtUeiWHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-beautify": "^1.14.9",
+ "vue-component-type-helpers": "^3.0.0"
+ },
+ "peerDependencies": {
+ "@vue/compiler-dom": "3.x",
+ "@vue/server-renderer": "3.x",
+ "vue": "3.x"
+ },
+ "peerDependenciesMeta": {
+ "@vue/server-renderer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/abbrev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.5",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
+ "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "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/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.19.0.tgz",
+ "integrity": "sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.16.0",
+ "form-data": "^4.0.6",
+ "https-proxy-agent": "^5.0.1",
+ "proxy-from-env": "^2.1.0"
+ }
+ },
+ "node_modules/axios-retry": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz",
+ "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.15.4",
+ "is-retry-allowed": "^2.2.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.12",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.12.tgz",
+ "integrity": "sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
+ "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz",
+ "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.10.44",
+ "caniuse-lite": "^1.0.30001806",
+ "electron-to-chromium": "^1.5.393",
+ "node-releases": "^2.0.51",
+ "update-browserslist-db": "^1.2.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
+ "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "get-intrinsic": "^1.3.0",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001806",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",
+ "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chai": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
+ "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.3",
+ "deep-eql": "^4.1.3",
+ "get-func-name": "^2.0.2",
+ "loupe": "^2.3.6",
+ "pathval": "^1.1.1",
+ "type-detect": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
+ "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-func-name": "^2.0.2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
+ "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/copy-anything": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz",
+ "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-what": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssstyle": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cssstyle/node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.21",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz",
+ "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deep-eql": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
+ "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-detect": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deep-object-diff": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz",
+ "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==",
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-browser": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz",
+ "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
+ "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/dom-serializer/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/editorconfig": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz",
+ "integrity": "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@one-ini/wasm": "0.1.1",
+ "commander": "^10.0.0",
+ "minimatch": "^9.0.1",
+ "semver": "^7.5.3"
+ },
+ "bin": {
+ "editorconfig": "bin/editorconfig"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/node_modules/brace-expansion": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz",
+ "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/editorconfig/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/editorconfig/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.400",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.400.tgz",
+ "integrity": "sha512-96EWDNjM59SYflgeV5Ylsf4EMiq1a25YjCnJH7cxn/AF2H3pILRweaUnoLax0yKHWdpOzY6JKEu45e8irqZIHA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.24.5",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz",
+ "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/error-stack-parser-es": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz",
+ "integrity": "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
+ "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-abstract-get": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz",
+ "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.2",
+ "is-callable": "^1.2.7",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz",
+ "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-abstract-get": "^1.0.0",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.1.0",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz",
+ "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.5.6",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz",
+ "integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.1",
+ "synckit": "^0.11.13"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-vue": {
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz",
+ "integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "globals": "^13.24.0",
+ "natural-compare": "^1.4.0",
+ "nth-check": "^2.1.1",
+ "postcss-selector-parser": "^6.0.15",
+ "semver": "^7.6.3",
+ "vue-eslint-parser": "^9.4.3",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-vue/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ajv": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
+ "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/eslint/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/execa": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz",
+ "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "figures": "^6.1.0",
+ "get-stream": "^9.0.0",
+ "human-signals": "^8.0.1",
+ "is-plain-obj": "^4.1.0",
+ "is-stream": "^4.0.1",
+ "npm-run-path": "^6.0.0",
+ "pretty-ms": "^9.2.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^4.0.0",
+ "yoctocolors": "^2.1.1"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "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-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "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/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/figures": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
+ "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-unicode-supported": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz",
+ "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
+ "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
+ "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.4",
+ "mime-types": "^2.1.35"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "11.4.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz",
+ "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/fs-extra/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz",
+ "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2",
+ "hasown": "^2.0.4",
+ "is-callable": "^1.2.7",
+ "is-document.all": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-func-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
+ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
+ "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sec-ant/readable-stream": "^0.4.1",
+ "is-stream": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz",
+ "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.9",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz",
+ "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==",
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
+ "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "entities": "^7.0.1"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz",
+ "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
+ "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.2",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
+ "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-document.all": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz",
+ "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-retry-allowed": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz",
+ "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
+ "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz",
+ "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
+ "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
+ "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-beautify": {
+ "version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
+ "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "config-chain": "^1.1.13",
+ "editorconfig": "^1.0.4",
+ "glob": "^10.4.2",
+ "js-cookie": "^3.0.5",
+ "nopt": "^7.2.1"
+ },
+ "bin": {
+ "css-beautify": "js/bin/css-beautify.js",
+ "html-beautify": "js/bin/html-beautify.js",
+ "js-beautify": "js/bin/js-beautify.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-cookie": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz",
+ "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
+ "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "24.1.3",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.3.tgz",
+ "integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssstyle": "^4.0.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.4.3",
+ "form-data": "^4.0.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.5",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.12",
+ "parse5": "^7.1.2",
+ "rrweb-cssom": "^0.7.1",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.1.4",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^2.11.2"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jsdom/node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/jsdom/node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/jsdom/node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
+ "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonfile/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kolorist": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
+ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/launder": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/launder/-/launder-1.7.1.tgz",
+ "integrity": "sha512-mU6WRz5EusL9ZZuiZ5SO4Y6C0P9PAUR9iwdb6bzj4KDihm28DiHFw+/yk9DBH4f+Pv1wuzQ4e2jV3oQ7mkIqvw==",
+ "license": "MIT",
+ "dependencies": {
+ "dayjs": "^1.11.7"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.32.0",
+ "lightningcss-darwin-arm64": "1.32.0",
+ "lightningcss-darwin-x64": "1.32.0",
+ "lightningcss-freebsd-x64": "1.32.0",
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
+ "lightningcss-linux-arm64-gnu": "1.32.0",
+ "lightningcss-linux-arm64-musl": "1.32.0",
+ "lightningcss-linux-x64-gnu": "1.32.0",
+ "lightningcss-linux-x64-musl": "1.32.0",
+ "lightningcss-win32-arm64-msvc": "1.32.0",
+ "lightningcss-win32-x64-msvc": "1.32.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/local-pkg": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz",
+ "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mlly": "^1.7.3",
+ "pkg-types": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loupe": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
+ "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-func-name": "^2.0.1"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mlly": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz",
+ "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.16.0",
+ "pathe": "^2.0.3",
+ "pkg-types": "^1.3.1",
+ "ufo": "^1.6.3"
+ }
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.17",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.17.tgz",
+ "integrity": "sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "license": "MIT"
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.52",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.52.tgz",
+ "integrity": "sha512-MRlTqhAfoMx/4mhEbPo3Hi02g9LJZaJkka69V6h67Cb1gjrAG0jsTE4CZX1eptNx+VCAwJmfpnDIF4P0Nh1A7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/npm-run-all": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
+ "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "chalk": "^2.4.1",
+ "cross-spawn": "^6.0.5",
+ "memorystream": "^0.3.1",
+ "minimatch": "^3.0.4",
+ "pidtree": "^0.3.0",
+ "read-pkg": "^3.0.0",
+ "shell-quote": "^1.6.1",
+ "string.prototype.padend": "^3.0.0"
+ },
+ "bin": {
+ "npm-run-all": "bin/npm-run-all/index.js",
+ "run-p": "bin/run-p/index.js",
+ "run-s": "bin/run-s/index.js"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/npm-run-all/node_modules/cross-spawn": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+ "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-all/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
+ "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0",
+ "unicorn-magic": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.24",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.24.tgz",
+ "integrity": "sha512-7YRhZ3jS45LwmSCT4b2sVFHt/WuovaktDU07QrtOBY2PXskss5a9jfmR9jptyumwXST+rFjrmppMY1KT/yn35A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/own-keys": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz",
+ "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/parse-ms": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse-srcset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
+ "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==",
+ "license": "MIT"
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathval": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
+ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
+ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pinia": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz",
+ "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^6.6.3",
+ "vue-demi": "^0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.4.4",
+ "vue": "^2.7.0 || ^3.5.11"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "node_modules/playwright": {
+ "version": "1.49.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz",
+ "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.49.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.49.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz",
+ "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/playwright/node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.26",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz",
+ "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.17",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz",
+ "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.9.6",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz",
+ "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz",
+ "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/pretty-ms": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
+ "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse-ms": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/proxy-from-env": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+ "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/psl": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
+ "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/lupomontero"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
+ "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp-quote": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz",
+ "integrity": "sha512-R9elSUXyJeACXh7raO50vvfZyTdQ1bxYm0KlN2XD8eEzPAnedJTHMk4F7lCaggu9DrfUWP3CDUjAgyW1f2DpgA==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz",
+ "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.9"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@napi-rs/lzma-linux-x64-gnu": "1.5.1",
+ "@rollup/rollup-android-arm-eabi": "4.62.4",
+ "@rollup/rollup-android-arm64": "4.62.4",
+ "@rollup/rollup-darwin-arm64": "4.62.4",
+ "@rollup/rollup-darwin-x64": "4.62.4",
+ "@rollup/rollup-freebsd-arm64": "4.62.4",
+ "@rollup/rollup-freebsd-x64": "4.62.4",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.62.4",
+ "@rollup/rollup-linux-arm-musleabihf": "4.62.4",
+ "@rollup/rollup-linux-arm64-gnu": "4.62.4",
+ "@rollup/rollup-linux-arm64-musl": "4.62.4",
+ "@rollup/rollup-linux-loong64-gnu": "4.62.4",
+ "@rollup/rollup-linux-loong64-musl": "4.62.4",
+ "@rollup/rollup-linux-ppc64-gnu": "4.62.4",
+ "@rollup/rollup-linux-ppc64-musl": "4.62.4",
+ "@rollup/rollup-linux-riscv64-gnu": "4.62.4",
+ "@rollup/rollup-linux-riscv64-musl": "4.62.4",
+ "@rollup/rollup-linux-s390x-gnu": "4.62.4",
+ "@rollup/rollup-linux-x64-gnu": "4.62.4",
+ "@rollup/rollup-linux-x64-musl": "4.62.4",
+ "@rollup/rollup-openbsd-x64": "4.62.4",
+ "@rollup/rollup-openharmony-arm64": "4.62.4",
+ "@rollup/rollup-win32-arm64-msvc": "4.62.4",
+ "@rollup/rollup-win32-ia32-msvc": "4.62.4",
+ "@rollup/rollup-win32-x64-gnu": "4.62.4",
+ "@rollup/rollup-win32-x64-msvc": "4.62.4",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rrweb-cssom": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
+ "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz",
+ "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sanitize-html": {
+ "version": "2.17.5",
+ "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.5.tgz",
+ "integrity": "sha512-ZmU1joGRrvoyctKIiuwUxqR6moLoU2Wk+2bMccN6f7UwhAmwYDvWziqPxRDDN2Qip62NqnIrVrT9akbL6Wretg==",
+ "license": "MIT",
+ "dependencies": {
+ "deepmerge": "^4.2.2",
+ "escape-string-regexp": "^4.0.0",
+ "htmlparser2": "^10.1.0",
+ "is-plain-object": "^5.0.0",
+ "launder": "^1.7.1",
+ "parse-srcset": "^1.0.2",
+ "postcss": "^8.3.11"
+ }
+ },
+ "node_modules/sanitize-html-react": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/sanitize-html-react/-/sanitize-html-react-1.13.0.tgz",
+ "integrity": "sha512-EDoOqPd2wrJEV6px8XvWEx7b+JNIoka3mI4fdBVa6S/de9b+UnmzKsVqBkj93s+FwIaBv1fBuXiXkoVxmAU3MQ==",
+ "license": "MIT",
+ "dependencies": {
+ "htmlparser2": "^3.9.0",
+ "regexp-quote": "0.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/sanitize-html-react/node_modules/dom-serializer": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+ "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/sanitize-html-react/node_modules/dom-serializer/node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/sanitize-html-react/node_modules/dom-serializer/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/sanitize-html-react/node_modules/domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/sanitize-html-react/node_modules/domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "1"
+ }
+ },
+ "node_modules/sanitize-html-react/node_modules/domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "node_modules/sanitize-html-react/node_modules/entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/sanitize-html-react/node_modules/htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.102.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz",
+ "integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^5.0.0",
+ "immutable": "^5.1.5",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher": "^2.4.1"
+ }
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz",
+ "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sirv": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+ "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.23",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz",
+ "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
+ "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/string.prototype.padend": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz",
+ "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz",
+ "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.2",
+ "es-object-atoms": "^1.1.2",
+ "has-property-descriptors": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz",
+ "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
+ "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz",
+ "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/strip-literal/node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/superjson": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz",
+ "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-anything": "^4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/synckit": {
+ "version": "0.11.13",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz",
+ "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.3.6"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz",
+ "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
+ "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/throttle-debounce": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
+ "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.22"
+ }
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinypool": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
+ "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
+ "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
+ "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz",
+ "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "for-each": "^0.3.5",
+ "gopd": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "possible-typed-array-names": "^1.1.0",
+ "reflect.getprototypeof": "^1.0.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.9.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/ufo": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz",
+ "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uglify-js": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
+ "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-hot-client": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.2.0.tgz",
+ "integrity": "sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0"
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz",
+ "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.3.4",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "vite": "^5.0.0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vite-node/node_modules/pathe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite-plugin-inspect": {
+ "version": "0.8.9",
+ "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.8.9.tgz",
+ "integrity": "sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@antfu/utils": "^0.7.10",
+ "@rollup/pluginutils": "^5.1.3",
+ "debug": "^4.3.7",
+ "error-stack-parser-es": "^0.1.5",
+ "fs-extra": "^11.2.0",
+ "open": "^10.1.0",
+ "perfect-debounce": "^1.0.0",
+ "picocolors": "^1.1.1",
+ "sirv": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1"
+ },
+ "peerDependenciesMeta": {
+ "@nuxt/kit": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-vue-devtools": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.10.tgz",
+ "integrity": "sha512-aHkUvDKxUdmSnuolEc8DkOrSjMpKO4Bb/BG01x2pBv6xTv487No9Tr7BMAsH2XWwMd+LtlUeCamhEZyEu9vxKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-core": "^7.7.10",
+ "@vue/devtools-kit": "^7.7.10",
+ "@vue/devtools-shared": "^7.7.10",
+ "execa": "^9.5.2",
+ "sirv": "^3.0.1",
+ "vite-plugin-inspect": "0.8.9",
+ "vite-plugin-vue-inspector": "^5.3.1"
+ },
+ "engines": {
+ "node": ">=v14.21.3"
+ },
+ "peerDependencies": {
+ "vite": "^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0"
+ }
+ },
+ "node_modules/vite-plugin-vue-inspector": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.4.0.tgz",
+ "integrity": "sha512-Iq/024CydcE46FZqWPU4t4lw4uYOdLnFSO1RNxJVt2qY9zxIjmnkBqhHnYaReWM82kmNnaXs7OkfgRrV2GEjyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.23.0",
+ "@babel/plugin-proposal-decorators": "^7.23.0",
+ "@babel/plugin-syntax-import-attributes": "^7.22.5",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-transform-typescript": "^7.22.15",
+ "@vue/babel-plugin-jsx": "^1.1.5",
+ "@vue/compiler-dom": "^3.3.4",
+ "kolorist": "^1.8.0",
+ "magic-string": "^0.30.4"
+ },
+ "peerDependencies": {
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz",
+ "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "1.6.1",
+ "@vitest/runner": "1.6.1",
+ "@vitest/snapshot": "1.6.1",
+ "@vitest/spy": "1.6.1",
+ "@vitest/utils": "1.6.1",
+ "acorn-walk": "^8.3.2",
+ "chai": "^4.3.10",
+ "debug": "^4.3.4",
+ "execa": "^8.0.1",
+ "local-pkg": "^0.5.0",
+ "magic-string": "^0.30.5",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "std-env": "^3.5.0",
+ "strip-literal": "^2.0.0",
+ "tinybench": "^2.5.1",
+ "tinypool": "^0.8.3",
+ "vite": "^5.0.0",
+ "vite-node": "1.6.1",
+ "why-is-node-running": "^2.2.2"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "@vitest/browser": "1.6.1",
+ "@vitest/ui": "1.6.1",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/vitest/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vitest/node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/vitest/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vitest/node_modules/npm-run-path": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+ "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vitest/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vitest/node_modules/pathe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vitest/node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz",
+ "integrity": "sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.40",
+ "@vue/compiler-sfc": "3.5.40",
+ "@vue/runtime-dom": "3.5.40",
+ "@vue/server-renderer": "3.5.40",
+ "@vue/shared": "3.5.40"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-component-type-helpers": {
+ "version": "3.3.9",
+ "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-3.3.9.tgz",
+ "integrity": "sha512-3c/UfMe0SqyEfcGTyH7mfshHagJ9QTCbppCb0/uGpHZpFug7+If3GeGZN7I0YheKEExemx3xldQPoO7PQSOLQg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "9.4.3",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
+ "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "eslint-scope": "^7.1.1",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.3.1",
+ "esquery": "^1.4.0",
+ "lodash": "^4.17.21",
+ "semver": "^7.3.6"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/vue-eslint-parser/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.22",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz",
+ "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "8.21.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.2.tgz",
+ "integrity": "sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yoctocolors": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz",
+ "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/cypher2/package.json b/cypher2/package.json
new file mode 100644
index 00000000..243aa3b0
--- /dev/null
+++ b/cypher2/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "@clockpunk/cypher-beacon-sheet",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "prebuild": "node scripts/build-validator.mjs && node scripts/build-embedded-css.mjs",
+ "build": "run-s build-scss && vite build",
+ "build-scss": "sass ./src/rollTemplates/host.scss ./public/host.css --no-source-map --no-charset",
+ "generate-validator": "node scripts/build-validator.mjs",
+ "preview": "vite preview",
+ "build-embedded-css": "node scripts/build-embedded-css.mjs"
+ },
+ "dependencies": {
+ "@roll20-official/beacon-sdk": "^0.1.17",
+ "ajv": "^8.17.1",
+ "handlebars": "^4.7.8",
+ "lodash": "^4.17.21",
+ "pinia": "^2.1.7",
+ "uuid": "^9.0.1",
+ "vue": "^3.4.21"
+ },
+ "devDependencies": {
+ "@rushstack/eslint-patch": "^1.8.0",
+ "@tailwindcss/vite": "^4.3.3",
+ "@types/uuid": "^9.0.8",
+ "@vitejs/plugin-vue": "^5.0.4",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/eslint-config-prettier": "^9.0.0",
+ "@vue/test-utils": "^2.4.11",
+ "eslint": "^8.57.0",
+ "eslint-plugin-vue": "^9.23.0",
+ "jsdom": "^24.1.3",
+ "npm-run-all": "^4.1.5",
+ "playwright": "^1.49.1",
+ "postcss": "^8.5.26",
+ "postcss-selector-parser": "^6.1.4",
+ "prettier": "^3.2.5",
+ "sass": "^1.75.0",
+ "tailwindcss": "^4.3.3",
+ "vite": "^5.2.8",
+ "vite-plugin-vue-devtools": "^7.0.25",
+ "vitest": "^1.6.1"
+ }
+}
diff --git a/cypher2/preview.png b/cypher2/preview.png
new file mode 100644
index 00000000..c9c86ec4
Binary files /dev/null and b/cypher2/preview.png differ
diff --git a/cypher2/public/host.css b/cypher2/public/host.css
new file mode 100644
index 00000000..b4eb7d05
--- /dev/null
+++ b/cypher2/public/host.css
@@ -0,0 +1,81 @@
+.cypher-roll {
+ border: 1px solid #7b5cd6;
+ border-radius: 6px;
+ padding: 0.5rem 0.75rem;
+ font-family: system-ui, sans-serif;
+}
+.cypher-roll__stat {
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ font-size: 0.8rem;
+}
+.cypher-roll__die {
+ font-size: 1.6rem;
+ font-weight: 700;
+ line-height: 1.2;
+}
+.cypher-roll__beats {
+ font-size: 0.9rem;
+}
+.cypher-roll__die--auto {
+ color: #1a6b1a;
+}
+.cypher-roll__verdict {
+ font-size: 0.9rem;
+ border-top: 1px solid #ddd;
+ padding-top: 0.25rem;
+ margin-top: 0.25rem;
+}
+.cypher-roll__verdict--success {
+ color: #1a6b1a;
+ font-weight: 600;
+}
+.cypher-roll__verdict--failure {
+ color: #8a1a1a;
+ font-weight: 600;
+}
+.cypher-roll__detail {
+ font-size: 0.8rem;
+ opacity: 0.75;
+}
+.cypher-roll__special {
+ margin-top: 0.25rem;
+ font-weight: 600;
+ color: #a12727;
+}
+.cypher-roll__wounds {
+ font-size: 0.85rem;
+ border-top: 1px solid #ddd;
+ padding-top: 0.25rem;
+ margin-top: 0.25rem;
+}
+
+.cypher-item {
+ border: 1px solid #7b5cd6;
+ border-radius: 6px;
+ padding: 0.5rem 0.75rem;
+ font-family: system-ui, sans-serif;
+}
+.cypher-item__title {
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ font-size: 0.9rem;
+}
+.cypher-item__fields {
+ font-size: 0.8rem;
+ opacity: 0.75;
+}
+.cypher-item__source {
+ font-size: 0.75rem;
+ font-style: italic;
+ opacity: 0.6;
+}
+.cypher-item__prose {
+ white-space: pre-wrap;
+ font-size: 0.9rem;
+ border-top: 1px solid #ddd;
+ padding-top: 0.35rem;
+ margin-top: 0.35rem;
+}
diff --git a/cypher2/scripts/build-embedded-css.mjs b/cypher2/scripts/build-embedded-css.mjs
new file mode 100644
index 00000000..1a14423f
--- /dev/null
+++ b/cypher2/scripts/build-embedded-css.mjs
@@ -0,0 +1,62 @@
+/* eslint-env node */
+// Generates src/assets/embedded.css: the four Fira faces and the Cypher wordmark
+// as data: URIs.
+//
+// WHY INLINE (ddd-brb): vite.config.js builds a production `base` of
+// `${VITE_SHEET_PATH}/${VITE_SHEET_SHORT_NAME}/`. Neither env var is set anywhere in
+// this repo, so a url('./fonts/x.woff2') reference resolves to /undefined/undefined/
+// in the published bundle. `npm run sandbox` uses --mode staging with base "/" and
+// therefore CANNOT reproduce the failure. Everything ships embedded.
+//
+// The output is COMMITTED (same policy as src/contract/validate.js) so a build never
+// needs the network, and `prebuild` regenerates it so it can never drift.
+import { readFileSync, writeFileSync } from 'node:fs'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const here = path.dirname(fileURLToPath(import.meta.url))
+const asset = (name) => path.join(here, '../src/assets', name)
+const b64 = (name) => readFileSync(asset(name)).toString('base64')
+
+const FACES = [
+ ['Fira Sans', 400, 'fonts/fira-sans-400.woff2'],
+ ['Fira Sans', 700, 'fonts/fira-sans-700.woff2'],
+ ['Fira Sans Condensed', 400, 'fonts/fira-sans-condensed-400.woff2'],
+ ['Fira Sans Condensed', 700, 'fonts/fira-sans-condensed-700.woff2']
+]
+
+const face = ([family, weight, file]) => `@font-face {
+ font-family: '${family}';
+ font-style: normal;
+ font-weight: ${weight};
+ font-display: swap;
+ src: url('data:font/woff2;base64,${b64(file)}') format('woff2');
+}`
+
+const out = `/* GENERATED by scripts/build-embedded-css.mjs — DO NOT EDIT.
+ Regenerate with: npm run build-embedded-css
+
+ Fira Sans / Fira Sans Condensed, SIL Open Font License 1.1 (src/assets/fonts/OFL.txt).
+ Google Fonts "latin" subset: U+0000-00FF plus common punctuation. Glyphs outside it
+ fall back per-glyph to the next family in --cy-font-body / --cy-font-cond, so a
+ character name in Polish or Turkish renders in system-ui rather than not at all.
+
+ Four faces only: no italic (the sheet uses none) and no 600 (the banner weight is
+ 700, so nothing is synthesised). Both are spec section 10 decisions, reversible by
+ adding a face here and regenerating.
+
+ Stand-in for Scala Sans Pro, which the printed sheet uses and which is Adobe-Fonts
+ only (ddd-2o9 / ddd-hn1). If MCG ever licences it for self-hosting, migration is
+ prepending the real family to those two tokens — nothing else moves. */
+
+${FACES.map(face).join('\n\n')}
+
+/* The CYPHER wordmark is ART, not type — the printed sheet draws it in Modesto
+ Condensed, which is equally unshippable, so no display face is substituted. */
+:root {
+ --cy-wordmark: url('data:image/png;base64,${b64('cypher-wordmark.png')}');
+}
+`
+
+writeFileSync(asset('embedded.css'), out)
+console.log(`embedded.css: ${out.length.toLocaleString()} bytes`)
diff --git a/cypher2/scripts/build-validator.mjs b/cypher2/scripts/build-validator.mjs
new file mode 100644
index 00000000..4e5c6cbf
--- /dev/null
+++ b/cypher2/scripts/build-validator.mjs
@@ -0,0 +1,57 @@
+/* eslint-env node */
+/* Generates src/contract/validate.js from the contract schema.
+ Run: npm run generate-validator (also runs automatically via prebuild). */
+import { existsSync, readFileSync, writeFileSync } from 'node:fs'
+import { fileURLToPath } from 'node:url'
+import path from 'node:path'
+import Ajv2020 from 'ajv/dist/2020.js'
+import standaloneCode from 'ajv/dist/standalone/index.js'
+
+const here = path.dirname(fileURLToPath(import.meta.url))
+/* The repo-root cypher-contract/ is the source of truth. The published sheet
+ folder (Roll20/roll20-beacon-sheets) ships WITHOUT it — there the schema is
+ vendored inside the sheet at ./cypher-contract/, and Roll20's CI (npm i +
+ npm run build → prebuild → this script) must resolve that copy instead. */
+const SCHEMA_CANDIDATES = [
+ path.resolve(here, '../../cypher-contract/cypher-character.schema.json'),
+ path.resolve(here, '../cypher-contract/cypher-character.schema.json')
+]
+export const SCHEMA_PATH = SCHEMA_CANDIDATES.find((p) => existsSync(p)) ?? SCHEMA_CANDIDATES[0]
+export const OUT_PATH = path.resolve(here, '../src/contract/validate.js')
+
+/* Ajv standalone still emits CommonJS require() for its runtime helpers even
+ with esm: true. Browsers have no require, so a raw emission crashes the
+ production bundle before Vue mounts (vitest masks this — its transform
+ pipeline shims CJS). Rewrite each `require("mod").default` into a real ESM
+ import; the `.default ?? mod` fallback covers both Node and bundler interop
+ shapes for the CJS helper modules. */
+const toEsmImports = (code) => {
+ const imports = []
+ let n = 0
+ const transformed = code.replace(/require\("([^"]+)"\)\.default/g, (_, mod) => {
+ const name = `__ajvRuntime${n++}`
+ imports.push(`import ${name} from "${mod}";`)
+ return `(${name}.default ?? ${name})`
+ })
+ if (/\brequire\s*\(/.test(transformed)) {
+ throw new Error('build-validator: unconverted require() in generated validator — emission shape changed')
+ }
+ return imports.join('') + transformed
+}
+
+export const generateValidatorSource = () => {
+ const schema = JSON.parse(readFileSync(SCHEMA_PATH, 'utf8'))
+ // verbose: errors carry .data (needed for enum messages); allErrors: report
+ // every violation, not just the first (beacon-mapping §5.1 "first few violations").
+ const ajv = new Ajv2020({ code: { source: true, esm: true }, verbose: true, allErrors: true })
+ const validate = ajv.compile(schema)
+ const banner =
+ '/* GENERATED by scripts/build-validator.mjs from cypher-contract/cypher-character.schema.json — do not edit. */\n' +
+ '/* eslint-disable */\n'
+ return banner + toEsmImports(standaloneCode(ajv, validate))
+}
+
+if (process.argv[1] === fileURLToPath(import.meta.url)) {
+ writeFileSync(OUT_PATH, generateValidatorSource())
+ console.log(`wrote ${OUT_PATH}`)
+}
diff --git a/cypher2/sheet.json b/cypher2/sheet.json
new file mode 100644
index 00000000..1aae1847
--- /dev/null
+++ b/cypher2/sheet.json
@@ -0,0 +1,11 @@
+{
+ "advanced": true,
+ "authors": "Monte Cook Games",
+ "roll20userid": "2554658",
+ "preview": "preview.png",
+ "compendium": "",
+ "useroptions": [],
+ "instructions": "Official Beacon character sheet for Cypher 2.",
+ "legacy": false,
+ "tags": ""
+}
diff --git a/cypher2/src/App.vue b/cypher2/src/App.vue
new file mode 100644
index 00000000..29719e1e
--- /dev/null
+++ b/cypher2/src/App.vue
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cypher2/src/assets/cypher-wordmark.png b/cypher2/src/assets/cypher-wordmark.png
new file mode 100644
index 00000000..96171504
Binary files /dev/null and b/cypher2/src/assets/cypher-wordmark.png differ
diff --git a/cypher2/src/assets/embedded.css b/cypher2/src/assets/embedded.css
new file mode 100644
index 00000000..73a80245
--- /dev/null
+++ b/cypher2/src/assets/embedded.css
@@ -0,0 +1,53 @@
+/* GENERATED by scripts/build-embedded-css.mjs — DO NOT EDIT.
+ Regenerate with: npm run build-embedded-css
+
+ Fira Sans / Fira Sans Condensed, SIL Open Font License 1.1 (src/assets/fonts/OFL.txt).
+ Google Fonts "latin" subset: U+0000-00FF plus common punctuation. Glyphs outside it
+ fall back per-glyph to the next family in --cy-font-body / --cy-font-cond, so a
+ character name in Polish or Turkish renders in system-ui rather than not at all.
+
+ Four faces only: no italic (the sheet uses none) and no 600 (the banner weight is
+ 700, so nothing is synthesised). Both are spec section 10 decisions, reversible by
+ adding a face here and regenerating.
+
+ Stand-in for Scala Sans Pro, which the printed sheet uses and which is Adobe-Fonts
+ only (ddd-2o9 / ddd-hn1). If MCG ever licences it for self-hosting, migration is
+ prepending the real family to those two tokens — nothing else moves. */
+
+@font-face {
+ font-family: 'Fira Sans';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url('data:font/woff2;base64,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') format('woff2');
+}
+
+@font-face {
+ font-family: 'Fira Sans';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url('data:font/woff2;base64,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') format('woff2');
+}
+
+@font-face {
+ font-family: 'Fira Sans Condensed';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url('data:font/woff2;base64,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') format('woff2');
+}
+
+@font-face {
+ font-family: 'Fira Sans Condensed';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url('data:font/woff2;base64,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') format('woff2');
+}
+
+/* The CYPHER wordmark is ART, not type — the printed sheet draws it in Modesto
+ Condensed, which is equally unshippable, so no display face is substituted. */
+:root {
+ --cy-wordmark: url('data:image/png;base64,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');
+}
diff --git a/cypher2/src/assets/fonts/OFL.txt b/cypher2/src/assets/fonts/OFL.txt
new file mode 100644
index 00000000..b8272271
--- /dev/null
+++ b/cypher2/src/assets/fonts/OFL.txt
@@ -0,0 +1,93 @@
+Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/cypher2/src/assets/fonts/fira-sans-400.woff2 b/cypher2/src/assets/fonts/fira-sans-400.woff2
new file mode 100644
index 00000000..83fa27c6
Binary files /dev/null and b/cypher2/src/assets/fonts/fira-sans-400.woff2 differ
diff --git a/cypher2/src/assets/fonts/fira-sans-700.woff2 b/cypher2/src/assets/fonts/fira-sans-700.woff2
new file mode 100644
index 00000000..30698304
Binary files /dev/null and b/cypher2/src/assets/fonts/fira-sans-700.woff2 differ
diff --git a/cypher2/src/assets/fonts/fira-sans-condensed-400.woff2 b/cypher2/src/assets/fonts/fira-sans-condensed-400.woff2
new file mode 100644
index 00000000..75c1ed7c
Binary files /dev/null and b/cypher2/src/assets/fonts/fira-sans-condensed-400.woff2 differ
diff --git a/cypher2/src/assets/fonts/fira-sans-condensed-700.woff2 b/cypher2/src/assets/fonts/fira-sans-condensed-700.woff2
new file mode 100644
index 00000000..8d609246
Binary files /dev/null and b/cypher2/src/assets/fonts/fira-sans-condensed-700.woff2 differ
diff --git a/cypher2/src/assets/main.css b/cypher2/src/assets/main.css
new file mode 100644
index 00000000..9f0102f0
--- /dev/null
+++ b/cypher2/src/assets/main.css
@@ -0,0 +1,1130 @@
+/* Cypher sheet base styles. Every color/spacing decision is a custom property
+ so genre themes (spec ④) can restyle without layout changes. */
+@import 'tailwindcss';
+/* Fonts + wordmark, inlined as data: URIs. GENERATED — see scripts/build-embedded-css.mjs
+ and the ddd-brb note there for why nothing may be referenced by URL. */
+@import './embedded.css';
+/* Docs mention class names as prose; don't let the scanner turn them into utilities. */
+@source not "../../README.md";
+@source not "../../docs";
+
+/* ===========================================================================
+ TOKENS. A skin is variable redefinition and NOTHING else — there is not one
+ selector below :root/[data-theme] in this file that names a theme (enforced by
+ src/assets/__tests__/tokens.test.js).
+
+ Three families: --cy-* colour, --cy-geo-* geometry, --cy-font-* type.
+ Every colour was SAMPLED from MCG's source art in Cypher/ — render, crop the
+ region, take the modal colour — except where a measured contrast failure forced
+ a documented deviation. See spec sections 3.3/3.4.
+ =========================================================================== */
+
+/* -- BASE -- "Cypher 2-Character Sheets default.pdf" p1. ------------------- */
+:root,
+[data-theme='base'] {
+ --cy-bg: #f4e7e1;
+ --cy-surface: #ffefe8;
+ --cy-field: #ffffff;
+ --cy-ink: #32312f;
+ --cy-muted: #6d5d58;
+ --cy-accent: #732928;
+ --cy-accent-contrast: #ffffff;
+ --cy-accent-soft: #ddb7ab;
+ --cy-band: #ffddc2;
+ --cy-warn: #a12727;
+ /* DEVIATION (spec amendment 1): the sampled rule colour is the accent-soft
+ #ddb7ab, which measures 1.84:1 on the field and 1.64:1 on the surface — under
+ the 3:1 UI-boundary floor, which would put EVERY border in this skin below the
+ bar the spec sets. Darkened along the same hue: 3.60:1 / 3.22:1. */
+ --cy-border: #b07a68;
+ --cy-overlay: rgb(50 41 40 / 0.55);
+ /* Stacking. One layer for every dialog — the roller and the shell-hosted modals
+ share it (ddd-6hx); nothing else on the sheet positions above the sticky chrome. */
+ --cy-z-modal: 20;
+
+ --cy-geo-corner: 4px;
+ --cy-geo-panel-clip: none;
+ --cy-geo-panel-shadow: none;
+ --cy-geo-pip: 50%; /* border-radius; circle */
+ --cy-geo-pip-clip: none;
+ --cy-geo-rule: 1px;
+ --cy-geo-banner-clip: none;
+ --cy-geo-banner-radius: 0 8px 8px 0;
+ --cy-geo-banner-tracking: 0.06em;
+ /* Chips are ~0.62rem in FONT SIZE, rendering ~0.95rem tall; a banner-scale 9px
+ cut takes about half of that and reads as a printing error rather than a
+ shape. Separate tokens, deliberately — do not collapse these back together. */
+ --cy-geo-chip-clip: none;
+ --cy-geo-chip-radius: 3px;
+
+ --cy-font-body: 'Fira Sans', 'Segoe UI', system-ui, sans-serif;
+ --cy-font-cond: 'Fira Sans Condensed', 'Fira Sans', system-ui, sans-serif;
+ /* 700, not the mockup's 600: only 400 and 700 are embedded, and a synthesised
+ 600 is a fake weight (spec section 10). */
+ --cy-font-weight-banner: 700;
+
+ /* Spacing is shared by every skin, deliberately not themed. */
+ --cy-gap: 0.6rem;
+ --cy-pad: 0.5rem;
+}
+
+/* -- FANTASY -- "Cypher 2 Fantasy.png".
+ DEVIATION (spec 3.3): the printed sheet banners in ochre, which is 3.65:1 on
+ white — under AA both as text and as a fill carrying white text. Banner fill is
+ the deep brown sampled from the same sheet (10.00:1 on parchment) and ochre
+ demotes to accent-soft: rules, borders and large display only. This skin does
+ not colour-match its source, by design. ------------------------------------ */
+[data-theme='fantasy'] {
+ --cy-bg: #e8cba4;
+ --cy-surface: #fdf1e3;
+ --cy-field: #fffdf8;
+ --cy-ink: #2b1c0c;
+ --cy-muted: #6f5636;
+ --cy-accent: #59320c;
+ --cy-accent-contrast: #fdf1e3;
+ --cy-accent-soft: #c7701a; /* never carries small text */
+ --cy-band: #f3c48b;
+ --cy-warn: #8f2d12;
+ --cy-border: #c7701a; /* 3.59 on field / 3.28 on surface — passes as-is */
+ --cy-overlay: rgb(43 28 12 / 0.6);
+
+ /* hand-cut edges: asymmetric radii, zero raster art */
+ --cy-geo-corner: 10px 3px 9px 4px;
+ --cy-geo-panel-clip: none;
+ --cy-geo-panel-shadow: 0 1px 0 0 rgb(199 112 26 / 0.55);
+ --cy-geo-pip: 0;
+ --cy-geo-pip-clip: polygon(
+ 30% 0%, 70% 0%, 100% 30%, 100% 70%,
+ 70% 100%, 30% 100%, 0% 70%, 0% 30%
+ ); /* octagon */
+ --cy-geo-rule: 2px;
+ --cy-geo-banner-clip: none;
+ --cy-geo-banner-radius: 3px 10px 3px 10px;
+ --cy-geo-banner-tracking: 0.12em;
+ --cy-geo-chip-clip: none;
+ --cy-geo-chip-radius: 2px 7px 2px 7px;
+}
+
+/* -- SCI-FI -- "Cypher 2 SF.png". Cyan is a rule/glow colour ONLY, never text.
+ PANEL CHAMFER DROPPED (spec amendment 3): clip-path deletes the border along the
+ cut AND removes box-shadow entirely, so a chamfered panel cannot carry this
+ skin's own "1px + cyan ring". The chamfer now lives on banners, chips, pips and
+ buttons — shapes with no border to lose — and panels keep a real border plus the
+ ring. --cy-geo-corner rises from 0 to 4px since it is no longer clipped instead.
+ Measured by render; the approved mockup has the same defect. ---------------- */
+[data-theme='scifi'] {
+ --cy-bg: #cbe4f4;
+ --cy-surface: #eaf6fb;
+ --cy-field: #ffffff;
+ --cy-ink: #0d1b2e;
+ --cy-muted: #4a6076;
+ --cy-accent: #1d4b96;
+ --cy-accent-contrast: #ffffff;
+ --cy-accent-soft: #62bff4; /* never text */
+ --cy-band: #cfe8f5;
+ --cy-warn: #a3162e;
+ --cy-border: #4370b0; /* 5.02 on field / 4.56 on surface */
+ --cy-overlay: rgb(13 27 46 / 0.6);
+
+ --cy-geo-corner: 4px;
+ --cy-geo-panel-clip: none;
+ --cy-geo-panel-shadow: 0 0 0 1px rgb(98 191 244 / 0.55); /* the cyan ring */
+ --cy-geo-pip: 0;
+ /* Corner-cut square, NOT a shear. A sheared pip reads as torn rather than
+ engineered, and at 1rem loses too much fill to scan filled-vs-empty. */
+ --cy-geo-pip-clip: polygon(28% 0, 100% 0, 100% 72%, 72% 100%, 0 100%, 0 28%);
+ --cy-geo-rule: 1px;
+ --cy-geo-banner-clip: polygon(0 0, 100% 0, calc(100% - 9px) 100%, 0 100%);
+ --cy-geo-banner-radius: 0;
+ --cy-geo-banner-tracking: 0.16em;
+ --cy-geo-chip-clip: polygon(0 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
+ --cy-geo-chip-radius: 0;
+}
+
+/* Tailwind namespace bridge. `inline` makes utilities emit var(--cy-*) directly,
+ so a [data-theme] subtree redefining --cy-* re-skins every utility (spec ④).
+ Components use ONLY these semantic utilities — never the default palette. */
+@theme inline {
+ --color-bg: var(--cy-bg);
+ --color-surface: var(--cy-surface);
+ --color-field: var(--cy-field);
+ --color-band: var(--cy-band);
+ --color-ink: var(--cy-ink);
+ --color-muted: var(--cy-muted);
+ --color-accent: var(--cy-accent);
+ --color-accent-contrast: var(--cy-accent-contrast);
+ --color-warn: var(--cy-warn);
+ --color-border: var(--cy-border);
+ --color-overlay: var(--cy-overlay);
+ --font-sheet: var(--cy-font-body);
+ --font-cond: var(--cy-font-cond);
+ --radius-sheet: var(--cy-geo-corner);
+ --spacing-sheet: var(--cy-gap);
+}
+/* --cy-accent-soft is deliberately NOT bridged: it must never be reachable as a
+ text-colour utility (spec 3.3 — it never carries small text). The only places it
+ fills a background are BEM rules in this file. */
+
+/* Preflight reconciliation: the sheet leaves these element families native-styled;
+ v4 preflight zeroes their UA chrome (margin/padding/border/font). `revert` rolls
+ back to UA defaults. Lives in @layer components so it BEATS preflight (base) but
+ LOSES to utilities — a migrated component's utility classes must win — while
+ un-layered BEM rules continue to out-rank all of it. */
+@layer components {
+ html { line-height: revert; }
+ input, select, textarea, button {
+ margin: revert; padding: revert; border: revert; border-radius: revert;
+ background-color: revert; color: revert; font: revert;
+ }
+ ::file-selector-button {
+ margin: revert; padding: revert; border: revert; border-radius: revert;
+ background-color: revert; color: revert; font: revert; appearance: revert;
+ }
+ ::placeholder { color: revert; opacity: revert; }
+ p { margin: revert; }
+ h3 { margin: revert; font-size: revert; font-weight: revert; }
+}
+
+/* ===========================================================================
+ PRIMITIVES — theme-blind. Every value resolves to a token.
+ Un-layered on purpose: these are the sheet's base look and must out-rank the
+ preflight-reconciliation block in @layer components, which reverts UA chrome on
+ inputs and buttons. (Verified in a real build, not assumed.)
+ =========================================================================== */
+.panel {
+ background: var(--cy-surface);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ clip-path: var(--cy-geo-panel-clip);
+ box-shadow: var(--cy-geo-panel-shadow);
+ padding: var(--cy-pad);
+ min-width: 0;
+}
+
+/* A section label as the printed sheet draws it: an accent-filled tab of condensed
+ caps. In stack mode these are the ONLY navigation the sheet has, so every one of
+ the seven segment panels (and the pinned rail's own panels) must carry one — do
+ not demote them to plain headings. */
+.banner {
+ display: inline-block;
+ width: fit-content;
+ margin: 0 0 0.4rem 0;
+ padding: 0.3rem 0.85rem 0.3rem 0.55rem;
+ background: var(--cy-accent);
+ color: var(--cy-accent-contrast);
+ font-family: var(--cy-font-cond);
+ font-size: 0.7rem;
+ font-weight: var(--cy-font-weight-banner);
+ line-height: 1;
+ text-transform: uppercase;
+ letter-spacing: var(--cy-geo-banner-tracking);
+ border-radius: var(--cy-geo-banner-radius);
+ clip-path: var(--cy-geo-banner-clip);
+}
+.banner--warn { background: var(--cy-warn); }
+
+.field {
+ width: 100%;
+ min-width: 0;
+ padding: 0.25rem 0.4rem;
+ background: var(--cy-field);
+ color: var(--cy-ink);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ font: inherit;
+}
+/* The preflight-reconciliation block sets `::placeholder { color: revert }`, which
+ styles the pseudo-element DIRECTLY — so .field's own `color` never reaches it.
+ Needs its own un-layered rule or placeholders stay UA grey in every skin.
+
+ ddd-2g8 walkthrough: plain --cy-muted read as imported data ("Species
+ (optional)" vs a real species). Italic makes the distinction CATEGORICAL, and
+ the colour mixes muted 45% into the field so every skin derives its own
+ lighter grey — a hardcoded grey would only suit one skin. NOT opacity: that
+ also fades the italic's weight and composites over whatever sits behind. */
+.field::placeholder {
+ color: color-mix(in srgb, var(--cy-muted) 45%, var(--cy-field));
+ font-style: italic;
+ opacity: 1;
+}
+/* Inset, because a clipped element (chips, pips) discards an outside outline. */
+.field:focus-visible { outline: 2px solid var(--cy-accent); outline-offset: -2px; }
+
+/* The button-side counterpart of .field. The preflight-reconciliation block above
+ REVERTS UA chrome onto `button`, so a button renders bare unless some rule skins
+ it back — and making that opt-in per component is how seven buttons across
+ ImportExportPanel and ArcSteps reached the sandbox unstyled (ddd-001 walkthrough,
+ skins item 9). skin-coverage.test.js now requires every button in a panel or the
+ modal to carry this class or have its own deliberate rule.
+
+ `color` is set explicitly where .roller__buttons button leaves it reverted: a
+ shared primitive cannot assume the UA default reads correctly against every skin's
+ --cy-surface. The 1.5rem floors are WCAG 2.2 SC 2.5.8, the same minimum this bead
+ put on .header__settings and .item-list__add; `min-*` only raises the floor, so the
+ padding below still sets the resting size of the worded buttons. */
+.btn {
+ padding: 0.3rem 0.7rem;
+ min-width: 1.5rem;
+ min-height: 1.5rem;
+ background: var(--cy-surface);
+ color: var(--cy-ink);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ font: inherit;
+ cursor: pointer;
+}
+.btn:focus-visible { outline: 2px solid var(--cy-accent); outline-offset: -2px; }
+/* Destructive variant. Same two properties the armed row delete repaints
+ (.item-list__delete--armed), so "this cannot be undone" reads the same way
+ everywhere. Single class after .btn: wins on source order, inherits the rest. */
+.btn--warn { color: var(--cy-warn); border-color: var(--cy-warn); }
+
+.microlabel {
+ font-family: var(--cy-font-cond);
+ font-size: 0.6rem;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ color: var(--cy-muted);
+}
+
+.cypher-sheet {
+ /* Reflow on the SHEET's own width, not the viewport's — a Roll20 side panel
+ resizes independently of the window (same finding as the DDD sheet). Size
+ queries evaluate against the CONTENT box, so this padding subtracts: a 280px
+ panel queries at 280 - 2*9.6 = 260.8px = 16.3rem, a 480px panel at 28.8rem.
+
+ RollerModal (position:fixed) stays inside this element. container-type applies
+ style + size containment and an independent formatting context, NOT layout
+ containment, so it does not become a containing block for fixed descendants
+ (CSS Conditional 5; verified in Chromium and by WPT
+ no-layout-containment-fixedpos). An earlier draft claimed otherwise. */
+ container: sheet / inline-size;
+ font-family: var(--cy-font-body);
+ /* The mockup's type scale. `rem` sizes are root-relative and do NOT shift with
+ this — but `em`, `font: inherit` controls and every unitless line-height do, and
+ without it the sheet reads a size larger than the approved mockup throughout. */
+ font-size: 0.875rem;
+ color: var(--cy-ink);
+ background: var(--cy-bg);
+ padding: var(--cy-gap);
+ display: grid;
+ gap: var(--cy-gap);
+ min-width: 0;
+}
+
+/* --- Play strip ---
+ ⚠️ min-width:0 on every direct grid item of .cypher-sheet is LOAD-BEARING (the
+ ddd-2bv class: grid min-content propagation). A grid item defaults to
+ min-width:auto, so it cannot shrink below its own min-content — and because all
+ three items share one column, the WIDEST min-content wins for all of them. In
+ stack mode the pinned rail and clusters hold every segment panel and every
+ width:100% control in them, so without this the play strip is dragged to 271px
+ inside a 260.8px content box and the whole sheet overflows at 280px. Measured,
+ not guessed: removing it reproduces exactly that. */
+.play-strip { display: grid; gap: var(--cy-gap); min-width: 0; }
+/* The pinned rail (spec ⑦ §4.1, amended by the owner 2026-08-23): the single
+ Damage & Recovery vitals panel (ddd-2g8 variant A — wounds/shield/recovery
+ columns). Visible at every width and behind no switch — the segmented controls
+ never hide any of it. The armor and cypher-limit scalars it used to hold are
+ gone (ddd-2g8): armorModifiers is edited in Gear, cypherLimit in Cyphers.
+
+ TWO elements carry this class. The rail is a TREATMENT, not one contiguous region:
+ Notes & Background gets the same always-visible treatment but sits LAST, after the
+ clusters, so the class rides both and source order alone puts each where it goes.
+ Nothing here may become position- or order-dependent (no :first-child, no nth-child)
+ without splitting the class first — the shared rule is the whole point. */
+.pinned-rail { display: grid; gap: var(--cy-gap); min-width: 0; }
+.clusters { display: grid; gap: var(--cy-gap); min-width: 0; }
+/* Same reason, one level down: in stack mode .cluster__panels becomes a grid and the
+ segment panels are its items, so each must be allowed below its min-content. */
+.cluster { display: grid; gap: 0.35rem; align-content: start; min-width: 0; }
+.cluster__panels { min-width: 0; }
+.cluster__panel { min-width: 0; }
+
+/* --- Identity ---
+ The printed sheet stacks the character sentence one field per line, with a
+ microlabel above and the grammatical role below, joined by IS A / WHO bars. */
+.header { display: grid; gap: 0.15rem; }
+/* The wordmark rides beside the name field rather than owning a row of its own: at
+ 11rem centred it cost ~88px of height to say something the sheet already says. `end`
+ sits its baseline on the input's, so the name row's margin-bottom moves up to this
+ wrapper — with align-items:end a margin on the flex item would push the mark down by
+ exactly that much. It hides below 27rem (see the stack block near the end of the file),
+ which also drops its role="img"/aria-label from the a11y tree there; deliberate, since
+ announcing a logo nobody can see is worse than staying quiet on a sheet that is
+ self-evidently a Cypher sheet. */
+.header__nameplate {
+ display: flex;
+ align-items: end;
+ gap: var(--cy-gap);
+ margin-bottom: 0.4rem;
+}
+.header__row--name { flex: 1 1 auto; margin-bottom: 0; }
+.header__settings {
+ flex: 0 0 auto;
+ align-self: end;
+ background: none;
+ color: var(--cy-accent);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ cursor: pointer;
+ /* WCAG 2.2 SC 2.5.8 (Target Size Minimum): the settings cog is the ONLY route to
+ settings and import/export below 27rem, where the segmented controls are hidden,
+ so its hit target must clear 24x24px. The preflight-reconciliation block above (`font: revert`
+ on `button`) restores Chromium's default control font (13.3333px Arial) here, not
+ the sheet's 0.875rem type — and this rule's own padding is fixed rem, not em, so it
+ doesn't scale with that font. Net result without a floor: ~24.4x21.8px, ~2.2px
+ short on height only (ddd-001 Task 7, browser-only — jsdom computes no layout and
+ never saw it). An explicit minimum is deterministic; `font: inherit` would only
+ trade one unmeasured type-scale dependency for another. `rem` is root-relative, so
+ 1.5rem is exactly 24px regardless of .cypher-sheet's own font-size. */
+ min-width: 1.5rem;
+ min-height: 1.5rem;
+ display: inline-grid;
+ place-items: center;
+ padding: 0.15rem 0.45rem;
+}
+.header__mark {
+ display: block;
+ flex: none;
+ /* 2:1 native, so 5rem reads 80x40 — within a few px of the label+input stack beside it. */
+ width: 5rem;
+ aspect-ratio: 2 / 1;
+ margin: 0;
+ background-image: var(--cy-wordmark);
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.header__sentence { display: grid; gap: 0.15rem; }
+/* Each group is a bar over its own fields. Single-column here, so the default is the
+ printed stack; the two @container blocks near the bottom of this file widen it. The
+ bar spans whatever columns its group has, which is the whole reason the groups exist
+ — it keeps the reflow to grid-template-columns and off :has()/nth-child. */
+.header__group { display: grid; gap: 0.15rem; min-width: 0; }
+.header__row { display: grid; gap: 0.15rem; margin-bottom: 0.4rem; min-width: 0; }
+.header__row-foot { display: flex; justify-content: space-between; gap: 0.5rem; }
+/* Joiner bars carry --cy-ink, NOT --cy-accent (spec amendment 2): accent-on-soft
+ measures 3.05:1 in fantasy and 4.11:1 in scifi, violating 3.3's own rule that
+ accent-soft never carries small text. Ink-on-soft is 7.08 / 4.52 / 8.47. Fantasy's
+ 4.52:1 is the tightest pair on the sheet — do not lighten --cy-accent-soft or raise
+ this font-size without re-measuring. */
+.header__who {
+ display: block;
+ /* Spans its group's columns, so the bar stays full-width over the fields it joins no
+ matter how many columns the group has. In the single-column stack `1 / -1` is just
+ column 1 — which is why this needs no combinator and no @container override, and why
+ tokens.test.js's descendant-rule allowlist stays untouched. */
+ grid-column: 1 / -1;
+ margin: 0.35rem 0;
+ padding: 0.1rem 0;
+ background: var(--cy-accent-soft);
+ color: var(--cy-ink);
+ border-radius: var(--cy-geo-corner);
+ font-family: var(--cy-font-cond);
+ font-size: 0.7rem;
+ font-weight: 700;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ text-align: center;
+}
+.header__name { font-size: 1.05rem; font-weight: 700; }
+.header__numbers { display: flex; flex-wrap: wrap; gap: var(--cy-gap); }
+/* A real wrap floor (ddd-5vb audit): eight labels now share this row, and with
+ `flex-basis: 0; min-width: 0` nothing ever wraps — just above the 27rem
+ stack threshold every field compressed to ~40px. The floor is MIN-WIDTH, not
+ flex-basis: a narrow-width container query turns this row into a COLUMN, and
+ in column direction flex-basis is the MAIN axis — a rem basis mints that
+ many pixels of label HEIGHT (the capture.mjs caption-inflation trap),
+ while min-width is inert there. */
+.header__numbers label { display: grid; gap: 0.1rem; flex: 1 1 0; min-width: 4.5rem; }
+/* Content-proportional widths. These are caps, not fixed widths — every one still
+ shrinks below its cap, so narrow behaviour is unchanged. */
+.header__name { max-width: 26rem; }
+.header__descriptor, .header__species, .header__type, .header__focus { max-width: 18rem; }
+.header__numbers .field { max-width: 6rem; }
+/* Genre/subgenre are the numbers row's only TEXT fields (ddd-5vb) — 6rem
+ truncates real subgenres ("Dungeon Fantasy"). The wider cap must outrank the
+ 6rem rule above, which is two-class, hence the sanctioned descendant form
+ (tokens.test.js). */
+.header__numbers .header__genre, .header__numbers .header__subgenre { max-width: 10rem; }
+/* The text pair claims a double grow share and a higher wrap floor: with all
+ eight labels on one line ("Street-Level" at ~786px content) an equal split
+ clips the value while every numeric neighbour has room to spare. grow +
+ min-width only — NO basis, same column-direction reason as above. Two-class
+ for the same specificity reason as the caps. */
+.header__numbers .header__label--wide { flex-grow: 2; min-width: 7rem; }
+/* The import-only second descriptor/focus (ddd-5vb): joined into the sentence
+ display under its primary's field — the input edits the primary only (owner
+ ruling; no new inputs). */
+.header__second { font-size: 0.65rem; font-style: italic; color: var(--cy-muted); }
+
+/* --- Pools --- */
+.pools-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--cy-gap); }
+.pool-card__head {
+ display: flex; justify-content: space-between; align-items: center;
+ gap: 0.25rem; margin-bottom: 0.3rem;
+}
+.pool-card__name {
+ margin: 0;
+ font-family: var(--cy-font-cond);
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+}
+/* One die-face design element, two homes: the pool cards' d20 and the recovery
+ column's d6 (ddd-5v9) share the rule so they can never drift apart. */
+.pool-card__roll,
+.recovery__roll {
+ padding: 0.2rem 0.45rem;
+ background: var(--cy-accent);
+ color: var(--cy-accent-contrast);
+ border: var(--cy-geo-rule) solid var(--cy-accent);
+ border-radius: var(--cy-geo-corner);
+ clip-path: var(--cy-geo-banner-clip);
+ font: inherit;
+ font-family: var(--cy-font-cond);
+ font-size: 0.75rem;
+ font-weight: 700;
+ line-height: 1;
+ cursor: pointer;
+}
+.pool-card__roll:focus-visible,
+.recovery__roll:focus-visible { outline: 2px solid var(--cy-ink); outline-offset: -3px; }
+/* WCAG 2.5.8: the d6 is the ONLY recovery-roll target, so it gets the same
+ 1.5rem floor as .btn (ddd-5v9 audit P2). Deliberately NOT on the shared rule
+ above: the pool d20 shares the defect but sits on an accepted surface —
+ resizing it is ddd-v3yj's call, not this bead's. */
+.recovery__roll { min-width: 1.5rem; min-height: 1.5rem; }
+/* The printed sheet gives a pool TWO fields (Pool, Edge); this sheet has three
+ (Current, Max, Edge). Three numeric inputs do not fit a 147px card at 480px — they
+ render two-digit values clipped to "1(" — so the row wraps to 2+1 instead. The
+ basis is what forces the wrap, and flex-shrink MUST be 0: a flex item shrinks
+ before it wraps, so with shrink:1 all three still squeeze onto one line at 39px and
+ clip silently — which no overflow assertion can see, because the clipping happens
+ INSIDE the input. Measured at 480px: 39.3px available vs 42px needed. */
+.pool-card__fields { display: flex; flex-wrap: wrap; gap: 0.35rem; }
+.pool-card__fields label { display: grid; gap: 0.1rem; min-width: 0; flex: 1 0 2.8rem; }
+
+/* --- Vitals panel (ddd-2g8 variant A, owner-picked) ---
+ ONE "Damage & Recovery" panel: wounds / shield / recovery as rule-divided
+ columns, one pencil owning edit mode for the whole cluster. Play view is
+ labels + pips only — maxima, shield add/remove and the bonus are edit-mode.
+ Columns are FLEX, not grid: the shield column comes and goes (null shield,
+ edit mode) and a fixed grid template would misplace recovery when it does. */
+.vitals__head { display: flex; justify-content: space-between; align-items: center; }
+/* Icon-only pencil toggle: the fill IS the mode indicator (aria-pressed carries
+ it for the screen reader). */
+.vitals__edit--active { background: var(--cy-accent); color: var(--cy-accent-contrast); }
+.vitals__cols { display: flex; flex-wrap: wrap; }
+.vitals__col { flex: 1 1 13rem; min-width: 0; padding: 0.3rem 0.85rem 0.2rem 0.85rem; }
+/* Modifier classes, not compounds (`.shield.vitals__col`) — the specificity
+ policy allows single-class rules only. The rule sits on the columns
+ THEMSELVES, not a sibling combinator: wounds and shield share WoundsTrack's
+ display:contents wrapper, so shield and recovery are not DOM-adjacent and
+ `+` cannot reach across. */
+.vitals__col--flush { padding-left: 0.25rem; }
+.vitals__col--rule { border-left: var(--cy-geo-rule) solid var(--cy-border); }
+/* h4 keeps its UA margin (the preflight reconciliation only reverts h3). */
+.vitals__col-head { margin: 0 0 0.35rem 0; }
+
+/* --- Wounds ---
+ Both wrap declarations are load-bearing (ddd-2bv): .wounds__pips lets a long pip run
+ reflow inside the row (the 280px layout, where Stone Body sets minor.max=8), and
+ .wounds__tier's wrap is the outer safety valve for maxima high enough that even a
+ wrapped pip run, the label and the max input can't share one line. Do not flatten.
+ WoundsTrack.test.js regex-matches both selectors at line start with exactly one
+ space before the brace — do not reformat these two rules. */
+.wounds__tier {
+ display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem;
+ padding: 0.3rem 0.25rem; margin-bottom: 0.25rem; border-radius: var(--cy-geo-corner);
+}
+.wounds__pips { display: flex; flex-wrap: wrap; gap: 0.25rem; min-width: 0; }
+.wounds__tier--moderate { background: var(--cy-band); }
+.wounds__label {
+ flex: 0 0 4.2rem;
+ /* Right-aligned so every tier's pips share one left edge (variant A). */
+ text-align: right;
+ font-family: var(--cy-font-cond);
+ font-size: 0.66rem;
+ font-weight: 700;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+}
+.wounds__max { flex: 0 0 3rem; }
+/* ddd-0xq: the wound-type label doubles as a disclosure button for the tier's
+ book rule text. Button reset keeps .wounds__label's shared metrics (same
+ element carries both classes, so the label's font/alignment rules apply);
+ the basis widens to fit the caret without letting it wrap to its own line. */
+.wounds__label--toggle {
+ flex-basis: 5rem;
+ background: none;
+ border: 0;
+ padding: 0;
+ color: inherit;
+ cursor: pointer;
+}
+.wounds__label--toggle:focus-visible { outline: 2px solid var(--cy-ink); outline-offset: 2px; }
+.wounds__caret { margin-left: 0.25rem; }
+/* The revealed rule text, a sibling BELOW the tier row. Margins tuck it under
+ its own tracker before the next tier's row. */
+.wounds__note {
+ margin: -0.1rem 0 0.3rem;
+ padding: 0 0.25rem;
+ font-size: 0.66rem;
+ line-height: 1.3;
+ color: var(--cy-muted);
+}
+.wound-pip {
+ width: 1.05rem; height: 1.05rem; padding: 0;
+ background: var(--cy-field);
+ border: 2px solid var(--cy-warn);
+ border-radius: var(--cy-geo-pip);
+ clip-path: var(--cy-geo-pip-clip);
+ cursor: pointer;
+}
+.wound-pip--filled { background: var(--cy-warn); }
+.wound-pip:focus-visible { outline: 2px solid var(--cy-ink); outline-offset: -4px; }
+
+/* --- Shield (ddd-2g8) ---
+ The shield column reuses .wounds__tier / .wounds__pips / .wound-pip wholesale —
+ same shape, same wrap rules. Only the header and add/remove affordances are its
+ own; both add and remove exist only in edit mode. */
+.shield__add { display: block; margin-top: 0.25rem; }
+.shield__head { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
+.shield__remove { padding: 0.15rem 0.45rem; }
+/* Armed state: same two properties as .item-list__delete--armed, so "this cannot
+ be undone" reads the same way everywhere. */
+.shield__remove--armed { color: var(--cy-warn); border-color: var(--cy-warn); }
+
+/* --- Recovery ---
+ The recovery column. Its header (.recovery__label) is the shared column-head
+ microlabel carrying the live roll expression — the accent lozenge retired with
+ variant A. */
+/* Head row (ddd-5v9): column head + the d6 die face. The label's col-head
+ margin moves to the row so the pair centers as one unit (source order beats
+ the .vitals__col-head rule — the ddd-93d lesson, used deliberately here). */
+.recovery__head { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.35rem; }
+.recovery__label { margin: 0; }
+.recovery__body { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem; }
+.recovery__steps { display: flex; flex-wrap: wrap; gap: 0.55rem; align-items: start; }
+/* By CLASS, not `label` (ddd-2g8): in edit mode the step wrapper is a span — a
+ label may hold only one labelable control and edit mode adds three. */
+.recovery__step { display: grid; justify-items: center; gap: 0.15rem; }
+/* The visible why-this-box-exists note (was tooltip-only; a title attr never
+ surfaces on touch). */
+.recovery__note {
+ max-width: 6rem;
+ font-size: 0.6rem;
+ line-height: 1.2;
+ text-align: center;
+ color: var(--cy-muted);
+}
+/* Edit mode (ddd-2g8): per-slot kind select + note input + remove, and the
+ add-slot affordance at the end of the run. */
+.recovery__kind { max-width: 5.5rem; }
+.recovery__note-input { max-width: 6.5rem; }
+.recovery__slot-remove { padding: 0.15rem 0.45rem; }
+/* The last slot cannot be removed (contract minItems: 1) — and a disabled button
+ must LOOK disabled, not merely be inert (the ModalShell ✕ class of bug). */
+.recovery__slot-remove:disabled { color: var(--cy-muted); border-color: var(--cy-border); cursor: default; }
+.recovery__slot-add { align-self: center; }
+/* A checkbox styled as a pip. appearance:none is essential — the UA control otherwise
+ paints over every token. Kept a checkbox, not a button, because RecoveryBlock.test.js
+ drives it with setValue(); the class sits on the input so no descendant rule is
+ needed. Unlike the select in Task 8 this loses no affordance: the checked fill IS
+ the state indication. */
+.recovery__pip {
+ width: 1.05rem; height: 1.05rem; margin: 0; padding: 0;
+ appearance: none;
+ background: var(--cy-field);
+ border: 2px solid var(--cy-warn);
+ border-radius: var(--cy-geo-pip);
+ clip-path: var(--cy-geo-pip-clip);
+ cursor: pointer;
+}
+.recovery__pip:checked { background: var(--cy-warn); }
+.recovery__pip:focus-visible { outline: 2px solid var(--cy-ink); outline-offset: -4px; }
+.recovery__bonus { display: grid; gap: 0.1rem; flex: 0 0 4rem; }
+/* The healing explainer (ddd-5v9): reference copy, muted like the slot notes
+ but full-width under the track. */
+.recovery__heal-note { margin: 0.4rem 0 0; font-size: 0.65rem; line-height: 1.35; color: var(--cy-muted); }
+
+/* --- Clusters & segment panels ---
+ SegmentedControl styling lives in utilities in SegmentedControl.vue (the ddd-tmp
+ prove-out). The BEM names remain in the template as test/JS hooks; do not re-add
+ styling rules for them here — an un-layered rule would silently out-rank the
+ template's utilities.
+
+ The rule below is a sanctioned child-combinator exception to the specificity policy
+ (spec §7): stack mode has to override it, and has to be overridable by a selector of
+ EQUAL specificity later in the file. See the @container block at the bottom and read
+ the warning there before touching either. */
+.cluster__panels > [data-segment]:not([data-active]) { display: none; }
+
+/* --- Item lists --- */
+.item-list { margin-bottom: var(--cy-gap); }
+.item-list__head { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
+/* Band scale, right edge — a `+` sized to the banner beside it, not a full-width
+ worded button stranded at the far side of a wide panel (spec ⑦ §4.4 item 3). */
+.item-list__add {
+ flex: 0 0 auto;
+ /* WCAG 2.2 SC 2.5.8 (Target Size Minimum), same floor and same reasoning as
+ .header__settings above: this control was shrunk to band scale in this bead and
+ landed at ~22.4x22.2px, below the 24px minimum. `min-*` only raises the floor, so
+ the padding below is untouched. rem is root-relative, so 1.5rem is exactly 24px
+ regardless of .cypher-sheet's own font-size. */
+ min-width: 1.5rem;
+ min-height: 1.5rem;
+ display: inline-grid;
+ place-items: center;
+ padding: 0 0.4rem;
+ line-height: 1.4;
+ background: transparent;
+ color: var(--cy-accent);
+ border: var(--cy-geo-rule) solid var(--cy-accent);
+ border-radius: var(--cy-geo-chip-radius);
+ font-family: var(--cy-font-cond);
+ font-size: 0.9rem;
+ cursor: pointer;
+}
+.item-list__rows { list-style: none; margin: 0; padding: 0; }
+.item-list__row {
+ display: flex; gap: 0.5rem; align-items: flex-start;
+ padding: 0.4rem 0;
+ border-top: var(--cy-geo-rule) solid var(--cy-border);
+}
+/* The mockup's first row has no rule above it — the banner already separates it. */
+.item-list__row:first-child { border-top: none; }
+.item-list__fields { display: flex; flex-wrap: wrap; gap: 0.5rem; flex: 1; min-width: 0; }
+.item-list__fields input, .item-list__fields select { min-width: 0; }
+.item-list__fields .row-name { flex: 1 1 9rem; }
+.item-list__fields textarea { width: 100%; }
+/* --- Read-optimized rows (spec ⑦ §4.2) ---
+ A WRAPPING FLEX ROW, not a grid, and that is a deliberate deviation from §4.2's
+ wording (recorded as D2 in the plan): summary cells collapse per row, so the cell
+ count varies, and a grid cannot reflow a variable count onto a second line — at
+ 280px inside a cluster panel it overflows instead. What §4.2 is actually asking for
+ — no panel-level column flow, columns supplied by the cluster layout — is
+ done in main.css's container-query block, not here. */
+.item-list__summary {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: baseline;
+ gap: 0.15rem 0.5rem;
+ flex: 1;
+ min-width: 0;
+}
+.summary-name { font-weight: 700; min-width: 0; overflow-wrap: anywhere; }
+/* --cy-ink, NOT --cy-muted. A summary cell carries DATA (a rating, a level, a
+ depletion), and --cy-muted is the exact token .microlabel uses — the same fault
+ spec §4.4 item 4 named when the tab strip read at field-label contrast. The name
+ still leads on weight, and the condensed uppercase face keeps the hierarchy without
+ spending contrast on it. */
+.summary-cell {
+ font-family: var(--cy-font-cond);
+ font-size: 0.72rem;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: var(--cy-ink);
+}
+/* The disclosure toggle (item-contents spec §6 D3): the summary LINE is the control,
+ so this is a wearing .item-list__summary's layout. The reset is explicit
+ because the preflight-reconciliation block in @layer components REVERTS UA chrome
+ onto every button — without it the row grows a grey bevel and a centred serif face.
+ Source order does the rest: this single-class rule sits after .item-list__summary,
+ so equal specificity resolves in its favour. */
+.item-list__summary--toggle {
+ appearance: none;
+ background: transparent;
+ border: none;
+ padding: 0;
+ margin: 0;
+ font: inherit;
+ color: inherit;
+ text-align: left;
+ cursor: pointer;
+}
+.item-list__summary--toggle:focus-visible {
+ outline: 2px solid var(--cy-accent);
+ outline-offset: 2px;
+}
+.item-list__caret {
+ flex: 0 0 auto;
+ color: var(--cy-accent);
+ /* Not the .summary-cell 0.72rem: this is the row's only visible affordance, and at
+ that size in a condensed face it reads as a speck rather than a control. */
+ font-size: 0.85rem;
+ line-height: 1.3;
+}
+
+/* The expansion (item-contents spec §6). flex-basis 100% drops it onto its own line
+ inside the row's flex box; only read-mode rows wrap, so the fallback inline-editor
+ layout is untouched. `p { margin: revert }` in the preflight block puts UA margins
+ back on paragraphs, hence the explicit 0. */
+.item-list__row--read { flex-wrap: wrap; }
+.item-list__body { flex: 0 0 100%; min-width: 0; padding: 0.1rem 0 0.15rem 0.85rem; }
+.item-list__body-source {
+ margin: 0;
+ font-family: var(--cy-font-cond);
+ font-size: 0.72rem;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: var(--cy-muted);
+}
+/* pre-wrap: descriptions are multi-paragraph textareas, and collapsing them here would
+ reproduce on the sheet the exact unreadability this feature exists to fix. */
+.item-list__body-prose {
+ margin: 0;
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
+ font-size: 0.85rem;
+ line-height: 1.45;
+ color: var(--cy-ink);
+}
+
+/* The (i) and the 💬 — one rule, two controls, because they are the same chip in the
+ same place and a second copy is a second thing to keep in step. Chip geometry and
+ the same WCAG 2.2 SC 2.5.8 24px floor .item-list__add and .header__settings carry:
+ (i) is the ONLY route to a row's fields and 💬 is the only route to the chat card,
+ so both must be tappable at 280px. rem is root-relative, so 1.5rem is exactly 24px
+ regardless of .cypher-sheet's own font-size. */
+.item-list__edit,
+.item-list__chat,
+.item-list__roll {
+ flex: 0 0 auto;
+ min-width: 1.5rem;
+ min-height: 1.5rem;
+ display: inline-grid;
+ place-items: center;
+ padding: 0 0.4rem;
+ background: transparent;
+ color: var(--cy-accent);
+ border: var(--cy-geo-rule) solid var(--cy-accent);
+ border-radius: var(--cy-geo-chip-radius);
+ font-family: var(--cy-font-cond);
+ font-size: 0.8rem;
+ line-height: 1.4;
+ cursor: pointer;
+}
+.item-list__edit:focus-visible,
+.item-list__chat:focus-visible,
+.item-list__roll:focus-visible { outline: 2px solid var(--cy-accent); outline-offset: -2px; }
+/* The editor's footer: delete on the left, Done on the right, wrapping at 280px. */
+.item-list__editor-foot {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ gap: 0.5rem;
+ margin-top: var(--cy-gap);
+}
+/* Armed state. .btn is a single class defined earlier in the file, so this single
+ class wins on source order for the two properties it names, and inherits the rest. */
+.item-list__delete--armed { color: var(--cy-warn); border-color: var(--cy-warn); }
+/* The empty region IS the affordance (spec ⑦ §4.4 item 5). */
+.item-list__empty-add {
+ display: block;
+ width: 100%;
+ margin-top: 0.35rem;
+ padding: 0.5rem;
+ background: transparent;
+ color: var(--cy-muted);
+ border: var(--cy-geo-rule) dashed var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ font-family: var(--cy-font-cond);
+ font-size: 0.8rem;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ cursor: pointer;
+}
+.item-list__remove {
+ flex: 0 0 auto;
+ background: none;
+ color: var(--cy-muted);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ cursor: pointer;
+}
+.row-desc { width: 100%; font-size: 0.85rem; }
+
+/* The two segments that hold more than one list column their lists whenever their
+ cluster cell is wide enough, and stack them when it is not. No @container needed:
+ auto-fit already answers "does another track fit?", and keying it to the SHEET's
+ width would be the wrong question now that a cluster occupies half of it.
+ `minmax(min(22rem, 100%), 1fr)` not `minmax(22rem, 1fr)`: a grid track does not
+ shrink below its min, so the bare 22rem form OVERFLOWS a 260.8px content box at
+ 280px — the ddd-2bv damage pattern with a different cause.
+ `> *` zeroes the .item-list margin that `gap` replaces and applies the min-width: 0
+ guard; both are properties of the CHILDREN, so a single class cannot express them. */
+.gear-segment, .advancement-segment {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
+ gap: var(--cy-gap);
+ align-items: start;
+}
+.gear-segment > *, .advancement-segment > * { min-width: 0; margin-bottom: 0; }
+/* The panel-level armor box (ddd-2g8). Full row, not a grid track of its own —
+ auto-fit would otherwise hand a lone text field a 22rem column beside Equipment. */
+.gear-segment__armor { grid-column: 1 / -1; display: grid; gap: 0.1rem; }
+/* The relocated cypherLimit editor (ddd-2g8), below the Cyphers list per the
+ owner's walkthrough call. */
+.cyphers-segment__limit { display: grid; gap: 0.1rem; max-width: 5rem; margin-top: 0.5rem; }
+
+/* A rating select styled as the printed sheet's chip. Chips use --cy-geo-chip-*
+ rather than the banner tokens — a banner-scale 9px cut takes about half a chip's
+ rendered height and reads as a printing error.
+
+ appearance:none removes the UA arrow, which will not fit and would break the clip —
+ so the chip must say "editable" some other way, or it reads as static text. The
+ caret is drawn as a background gradient (no extra element, no icon font), and the
+ focus ring is INSET because clip-path discards an outside outline. */
+.row-rating {
+ appearance: none;
+ padding: 0.1rem 1.1rem 0.1rem 0.5rem;
+ background-color: var(--cy-accent);
+ background-image:
+ linear-gradient(45deg, transparent 50%, var(--cy-accent-contrast) 50%),
+ linear-gradient(135deg, var(--cy-accent-contrast) 50%, transparent 50%);
+ background-position: right 0.5rem top 55%, right 0.29rem top 55%;
+ background-size: 0.22rem 0.22rem, 0.22rem 0.22rem;
+ background-repeat: no-repeat;
+ color: var(--cy-accent-contrast);
+ border: var(--cy-geo-rule) solid var(--cy-accent);
+ border-radius: var(--cy-geo-chip-radius);
+ clip-path: var(--cy-geo-chip-clip);
+ font-family: var(--cy-font-cond);
+ font-size: 0.62rem;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ cursor: pointer;
+}
+.row-rating:focus-visible { outline: 2px solid var(--cy-ink); outline-offset: -3px; }
+
+.import__alert { border: var(--cy-geo-rule) solid var(--cy-warn); color: var(--cy-warn); border-radius: var(--cy-geo-corner); padding: 0.5rem; margin: 0.5rem 0; }
+.import__confirm { border: var(--cy-geo-rule) solid var(--cy-accent); border-radius: var(--cy-geo-corner); padding: 0.5rem; margin: 0.5rem 0; }
+/* .export__alert carries .import__alert too — same treatment by design, so it
+ needs no rule of its own. Transient copy feedback reads as quiet status
+ until it's a failure, which escalates to the warn colour. */
+.export__copy-status { font-size: 0.85rem; color: var(--cy-muted); margin: 0.5rem 0; }
+.export__copy-status--error { color: var(--cy-warn); }
+/* Breathing room between the file picker and the paste box (owner walkthrough).
+ 1rem = 16px; the spacing tokens (--cy-gap 0.6rem / --cy-pad 0.5rem) are both
+ tighter than the separation these two alternative entry points need. */
+.import__file { margin-bottom: 1rem; }
+.import__paste { width: 100%; }
+.notes-block__field { display: grid; gap: 0.15rem; margin-bottom: var(--cy-gap); }
+.advancement__row { display: flex; gap: 0.4rem; align-items: baseline; cursor: pointer; }
+.arc-steps { display: grid; gap: 0.25rem; }
+.arc-steps__step { display: flex; gap: 0.35rem; align-items: center; }
+.arc-steps__name { flex: 1 1 auto; min-width: 0; }
+.ability-cost { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
+.cost-points { flex: 0 0 4rem; }
+.cost-pools { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: baseline; }
+
+.settings__row { display: grid; gap: 0.15rem; margin-bottom: 0.5rem; }
+.settings__hint { font-size: 0.78rem; color: var(--cy-muted); margin: 0 0 0.75rem; }
+.settings__toggle { display: flex; gap: var(--cy-gap); align-items: baseline; cursor: pointer; }
+
+/* --- Guided roller modal (spec ③) ---
+ The overlay, panel, header and dialog contract are ModalShell's (.modal*, below);
+ only the roller's body styling lives here (ddd-6hx). */
+.roller__form { display: grid; gap: var(--cy-gap); }
+.roller__pool { margin: 0; font-size: 0.85rem; color: var(--cy-muted); }
+.roller__field { display: flex; flex-direction: column; gap: 0.25rem; }
+.roller__label { font-size: 0.75rem; color: var(--cy-muted); }
+.roller__show-all { display: flex; align-items: center; gap: 0.4rem; font-size: 0.85rem; }
+.roller__steppers { display: flex; flex-wrap: wrap; gap: var(--cy-gap); }
+.roller__steppers > .roller__field { flex: 1 1 8rem; min-width: 0; }
+.roller__stepper { display: flex; align-items: center; gap: 0.5rem; }
+.roller__stepper strong { min-width: 1.5rem; text-align: center; }
+.roller__step-down,
+.roller__step-up {
+ width: 2rem; height: 2rem;
+ border: var(--cy-geo-rule) solid var(--cy-accent);
+ border-radius: var(--cy-geo-corner);
+ background: none; cursor: pointer; font-size: 1rem;
+}
+.roller__step-down:disabled,
+.roller__step-up:disabled { opacity: 0.4; cursor: not-allowed; }
+.roller__summary {
+ display: grid; gap: 0.25rem;
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ padding: 0.5rem;
+ font-size: 0.85rem;
+}
+.roller__error { color: var(--cy-warn); margin: 0; font-size: 0.85rem; }
+.roller__buttons { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem; }
+.roller__buttons button {
+ padding: 0.4rem 0.9rem;
+ border-radius: var(--cy-geo-corner);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ background: var(--cy-surface);
+ cursor: pointer;
+ font: inherit;
+}
+/* Qualified under .roller__buttons: the generic `.roller__buttons button`
+ rule above is (0,1,1) and would out-specify a bare `.roller__roll` (0,1,0),
+ leaving the accent background overridden while the white text survives —
+ white-on-white (ddd-axi closeout audit P1). */
+.roller__buttons .roller__roll {
+ border-color: var(--cy-accent);
+ background: var(--cy-accent);
+ color: var(--cy-accent-contrast);
+}
+.roller__cancel:disabled,
+.roller__roll:disabled { opacity: 0.5; cursor: not-allowed; }
+
+/* --- Shared modal shell (spec ⑦ §4.3) ---
+ Every value is a token. `position: fixed` is safe inside .cypher-sheet's
+ container-type — see the note in ModalShell.vue. */
+.modal {
+ position: fixed;
+ inset: 0;
+ z-index: var(--cy-z-modal);
+ display: grid;
+ place-items: center;
+ padding: var(--cy-gap);
+ background: var(--cy-overlay);
+}
+.modal__panel {
+ width: min(32rem, 100%);
+ max-height: 100%;
+ overflow-y: auto;
+ min-width: 0;
+ background: var(--cy-surface);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ box-shadow: var(--cy-geo-panel-shadow);
+ padding: var(--cy-pad);
+}
+.modal__panel--compact { width: min(22rem, 100%); }
+.modal__head {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 0.5rem;
+ margin-bottom: var(--cy-gap);
+}
+.modal__close {
+ flex: 0 0 auto;
+ background: none;
+ color: var(--cy-muted);
+ border: var(--cy-geo-rule) solid var(--cy-border);
+ border-radius: var(--cy-geo-corner);
+ cursor: pointer;
+}
+/* close-disabled (ddd-6hx) makes the ✕ inert mid-roll; without this it still LOOKS
+ clickable and the refusal is silent — the exact thing the prop exists to avoid
+ (Codex closeout P2). Same treatment as the roller's own frozen controls. */
+.modal__close:disabled { opacity: 0.5; cursor: not-allowed; }
+.modal__body { min-width: 0; }
+
+/* ==========================================================================
+ CONTAINER QUERIES. Thresholds are measured off the CONTENT box: root padding
+ is --cy-gap (0.6rem) on both sides, so a 480px panel queries at 28.8rem.
+ ========================================================================== */
+
+/* --- STACK MODE (<27rem, owner decision, spec 6.2) ---
+ Both segmented controls are HIDDEN and all seven segment panels render in one
+ scroll. This inverts the usual disclosure direction — narrow shows MORE, not less
+ — and was accepted knowingly: nothing is hidden at the width where hunting is
+ hardest, and it reclaims three rows of chrome where vertical space is scarcest.
+ Banner headings are the scroll landmarks.
+
+ ui.characterSegment / ui.kitSegment are NOT cleared here — they are ignored, so
+ widening restores whatever segments were last chosen.
+
+ `width < 27rem`, NOT `max-width: 27rem`: max-width includes equality, which would
+ put exactly 27rem into stack mode and contradict 6.3's "the segmented controls
+ persist at every width >= 27rem". The boundary has its own browser assertion. */
+@container sheet (width < 27rem) {
+ /* Both controls hide; every segment panel renders in one scroll. The header ⚙ does
+ NOT hide with them — it is the only route to settings and import/export at this
+ width (spec ⑦ §6, and it carries its own capture assertion). */
+ .segmented-control { display: none; }
+
+ /* READ BEFORE EDITING — the ddd-axi bug class, and it bit on the FIRST build of
+ this mechanism. A CONTAINER QUERY ADDS ZERO SPECIFICITY. The `:not([data-active])`
+ below is NOT decoration: without it this selector is (0,2,0) and loses to the
+ base hide rule's (0,3,0), so every inactive panel stays hidden and the sheet shows
+ one panel per cluster at 280px. Matching specificity plus LATER SOURCE ORDER is
+ the entire mechanism. Any container-query override in this file must repeat its
+ base rule's selector VERBATIM. jsdom cannot see this — scripts/capture.mjs is the
+ gate, and it is mutation-tested. */
+ .cluster__panels > [data-segment]:not([data-active]) { display: block; }
+
+ .cluster__panels { display: grid; gap: var(--cy-gap); }
+
+ .pools-row { grid-template-columns: 1fr; }
+
+ /* Turning a flex row into a column reinterprets BOTH cross-axis alignment and every
+ flex-basis: align-items:flex-start would stop children stretching to full width,
+ and a 12rem/9rem basis becomes a HEIGHT. Each of these must be reset in the same
+ breath as the direction change. The last repeats its base selector verbatim for
+ the same reason the panel rule above does. */
+ /* wrap MUST flip to nowrap with the direction: a wrapped COLUMN flex container
+ has no definite height to break lines against, and the fallback sizing
+ inflates every column ~60px past its content (measured 173 vs 117 on the
+ wounds column at 340px). Same family as the flex-basis trap below. */
+ .vitals__cols { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+ /* flex-basis is MAIN-axis: stacked, the columns' 13rem basis becomes a 208px
+ HEIGHT and opens dead space between the trackers — the same trap the old
+ scalars stack rule documented. Reset in the same breath as the direction. */
+ .vitals__col { flex: none; padding-left: 0.25rem; padding-right: 0.25rem; }
+ /* Stacked columns: the vertical rules become horizontal. Selectors repeated
+ VERBATIM from the base rules — a container query adds zero specificity, so
+ these win on source order alone. */
+ .vitals__col--rule {
+ border-left: none;
+ border-top: var(--cy-geo-rule) solid var(--cy-border);
+ }
+ .item-list__fields { flex-direction: column; align-items: stretch; }
+ .item-list__fields .row-name { flex: none; width: 100%; }
+ .header__numbers { flex-direction: column; gap: 0.35rem; }
+ /* Selector repeated VERBATIM from the base rule, per the note above — a container
+ query adds zero specificity, so this wins on source order alone. At 280px the
+ wordmark would eat a third of the name field's width to no purpose. */
+ .header__mark { display: none; }
+}
+
+/* --- IDENTITY SENTENCE: two widenings (ddd-11d) ---
+ Stacked one field per line, the sentence spends the whole panel height on four inputs
+ and leaves a wide sheet empty beside them. Both steps are grid-template-columns on
+ elements that are ALREADY grids above, so nothing here changes display or direction —
+ which is what keeps the flex-basis and align-items traps documented in the stack block
+ out of this one.
+
+ THE 3-UP THRESHOLD IS BOUNDED BY THE MICROLABELS, NOT BY TASTE — but not in the way
+ it looks. .header__row-foot is a flex row at min-width:auto, so it never shrinks below
+ its own min-content (DESCRIPTOR 56px + ADJECTIVE 46px + the 0.5rem gap = 109px, the
+ widest of the four pairs). Squeeze the cell below that and the labels do NOT collide:
+ the foot keeps its width and overflows the cell, painting across the field beside it.
+
+ Measured by sweeping the sheet 380->620px with 3-up forced on: the foot first fits at
+ 25rem (115px cell vs 109px needed) and breaks at 23.8rem (108px). 25rem is BELOW the
+ 27rem stack threshold, so 3-up would technically fit the moment stack mode ends — at
+ 27.5rem the cell is 128px against a 128px foot, i.e. zero headroom. 32rem is chosen
+ instead for ~152px cells and ~43px of slack. Lowering it toward 27rem is not a
+ correctness bug until 25rem, but it spends the entire margin. Re-measure if the
+ microlabel text, font or --cy-gap changes. */
+@container sheet (width >= 32rem) {
+ .header__group--isa { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--cy-gap); }
+}
+/* Both groups side by side, each keeping its own bar over its own fields. The bars land
+ on one row and the four fields on the next for free: the groups are siblings in one
+ grid row and both lead with the same-height bar, so their internal rows align without
+ a subgrid. 3fr/1.4fr, not 3fr/1fr — the who group holds one field to the isa group's
+ three, and a focus reads longer than a descriptor. */
+@container sheet (width >= 48rem) {
+ .header__sentence {
+ grid-template-columns: minmax(0, 3fr) minmax(0, 1.4fr);
+ column-gap: var(--cy-gap);
+ align-items: start;
+ }
+
+ /* Character and Kit side by side. This is what spec §4.2 means by "the columns come
+ from the cluster layout": the summary rows do not flow, the sheet does. */
+ .clusters { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
+}
diff --git a/cypher2/src/components/AbilitiesSegment.vue b/cypher2/src/components/AbilitiesSegment.vue
new file mode 100644
index 00000000..9ea8a18a
--- /dev/null
+++ b/cypher2/src/components/AbilitiesSegment.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ {{ row.name }}
+ {{ costText(row) }}
+ Enabler
+
+
+
+
+
+ Enabler
+
+
+
+
+
+
+
+
+
diff --git a/cypher2/src/components/AbilityCost.vue b/cypher2/src/components/AbilityCost.vue
new file mode 100644
index 00000000..3892aa1d
--- /dev/null
+++ b/cypher2/src/components/AbilityCost.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+ No cost
+ Fixed
+ Variable
+
+
+
+
+
+ + (levels)
+
+
+
+
+
+ {{ p.charAt(0).toUpperCase() + p.slice(1) }}
+
+
+
+
diff --git a/cypher2/src/components/AdvancementSegment.vue b/cypher2/src/components/AdvancementSegment.vue
new file mode 100644
index 00000000..f9efd9fc
--- /dev/null
+++ b/cypher2/src/components/AdvancementSegment.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
diff --git a/cypher2/src/components/ArcSteps.vue b/cypher2/src/components/ArcSteps.vue
new file mode 100644
index 00000000..03b7893e
--- /dev/null
+++ b/cypher2/src/components/ArcSteps.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/cypher2/src/components/ArtifactsSegment.vue b/cypher2/src/components/ArtifactsSegment.vue
new file mode 100644
index 00000000..767e8cd3
--- /dev/null
+++ b/cypher2/src/components/ArtifactsSegment.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+ {{ row.name }}
+ {{ cell }}
+
+
+
+
+
+
+ No depletion
+ Depletes on a roll
+ Depletes on use
+
+
+ Chance
+
+
+
+ {{ d }}
+
+
+
+
+
+
diff --git a/cypher2/src/components/AttacksSegment.vue b/cypher2/src/components/AttacksSegment.vue
new file mode 100644
index 00000000..a5a87d72
--- /dev/null
+++ b/cypher2/src/components/AttacksSegment.vue
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+ {{ row.name }}
+ {{ row.damage }} damage
+ {{ row.skillRating }}
+
+ {{ modifierText(row) }}
+
+
+
+
+
+
+ {{ s.text }}
+
+ {{ poolLabel(p) }}
+
+
+
+
+ {{ s.text }}
+
+ — n/a
+ {{ WEAPON_CLASS_LABELS[w] }}
+
+
+ Damage
+
+
+
+
+ {{ s.text }}
+
+ {{ r }}
+
+
+
+
+ {{ s.text }}
+
+ — unspecified
+ {{ WEAPON_RANGE_LABELS[r] }}
+
+
+
+ {{ s.text }}
+
+ No modifier
+ Eased
+ Hindered
+
+
+ Steps
+
+
+
+
+
+
+
diff --git a/cypher2/src/components/CyphersSegment.vue b/cypher2/src/components/CyphersSegment.vue
new file mode 100644
index 00000000..50cfa4e5
--- /dev/null
+++ b/cypher2/src/components/CyphersSegment.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+ {{ chosenName(row) }}
+ {{ cell }}
+
+
+
+
+
+
+
+
+
+ {{ s.text }}
+
+ — unspecified
+ {{ CYPHER_KIND_LABELS[k] }}
+
+
+
+ {{ s.text }}
+
+ — no power tier
+ {{ POWER_TIER_LABELS[p] }}
+
+
+
+ Activated
+
+
+
+
+
+
+
+ Limit
+
+
+
+
diff --git a/cypher2/src/components/GearSegment.vue b/cypher2/src/components/GearSegment.vue
new file mode 100644
index 00000000..b5ac6ade
--- /dev/null
+++ b/cypher2/src/components/GearSegment.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+ Armor
+
+
+
+
+
+
+ {{ row.name }}
+ {{ cell }}
+
+
+
+
+ Qty
+
+
+
+
+
+
+
+
+ {{ row.name }}
+ {{ row.amount }}
+
+
+
+ Amount
+
+
+
+
+
+
diff --git a/cypher2/src/components/ImportExportPanel.vue b/cypher2/src/components/ImportExportPanel.vue
new file mode 100644
index 00000000..190ec5a0
--- /dev/null
+++ b/cypher2/src/components/ImportExportPanel.vue
@@ -0,0 +1,127 @@
+
+
+
+
+ Import character
+
+ Accepts Cypher character JSON (schema version 2) — the native export from Cypher Tools
+ or this sheet's own export.
+
+
+
+ Validate pasted JSON
+
+
+
{{ failure.message }}
+
+
+
+
+
+ Replace the current sheet with {{ pending.name }} ? Everything on this sheet will be overwritten. (Theme and other sheet settings are kept.)
+
+
+
Replace sheet
+
Cancel
+
+
+ Export character
+ Download JSON
+ Copy to clipboard
+
+
{{ exportFailure.message }}
+
+
+
+ {{ copyStatus.message }}
+
+
+
diff --git a/cypher2/src/components/ItemList.vue b/cypher2/src/components/ItemList.vue
new file mode 100644
index 00000000..3614f9ed
--- /dev/null
+++ b/cypher2/src/components/ItemList.vue
@@ -0,0 +1,303 @@
+
+
+
+
+
+
+
+ {{ addLabel }}
+
+
+
+
+
+
+
+ {{ isExpanded(row) ? '▾' : '▸' }}
+
+
+
+
+
+
+
+
+
+
+ d20
+
+
+
+
+
+
+
+
+
+ {{ confirming === row._id ? 'Confirm ✕' : '✕' }}
+
+
+
+
+
+ {{ descriptors[index].source }}
+
+
{{ descriptors[index].prose }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cypher2/src/components/ModalShell.vue b/cypher2/src/components/ModalShell.vue
new file mode 100644
index 00000000..4831ea49
--- /dev/null
+++ b/cypher2/src/components/ModalShell.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
diff --git a/cypher2/src/components/NotesBlock.vue b/cypher2/src/components/NotesBlock.vue
new file mode 100644
index 00000000..19b8f207
--- /dev/null
+++ b/cypher2/src/components/NotesBlock.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
Notes & Background
+
+ Background
+
+
+
+ Notes
+
+
+
+
diff --git a/cypher2/src/components/PoolCard.vue b/cypher2/src/components/PoolCard.vue
new file mode 100644
index 00000000..aa5d18cc
--- /dev/null
+++ b/cypher2/src/components/PoolCard.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
diff --git a/cypher2/src/components/PoolsRow.vue b/cypher2/src/components/PoolsRow.vue
new file mode 100644
index 00000000..ed4c290c
--- /dev/null
+++ b/cypher2/src/components/PoolsRow.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/cypher2/src/components/RecoveryBlock.vue b/cypher2/src/components/RecoveryBlock.vue
new file mode 100644
index 00000000..50aee92a
--- /dev/null
+++ b/cypher2/src/components/RecoveryBlock.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
diff --git a/cypher2/src/components/RollerModal.vue b/cypher2/src/components/RollerModal.vue
new file mode 100644
index 00000000..ba5d843e
--- /dev/null
+++ b/cypher2/src/components/RollerModal.vue
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
diff --git a/cypher2/src/components/RowLevel.vue b/cypher2/src/components/RowLevel.vue
new file mode 100644
index 00000000..384655d3
--- /dev/null
+++ b/cypher2/src/components/RowLevel.vue
@@ -0,0 +1,35 @@
+
+
+
+ Level
+
+
+
diff --git a/cypher2/src/components/RowProse.vue b/cypher2/src/components/RowProse.vue
new file mode 100644
index 00000000..7b768688
--- /dev/null
+++ b/cypher2/src/components/RowProse.vue
@@ -0,0 +1,28 @@
+
+
+
+
+ {{ label }}
+
+
+
diff --git a/cypher2/src/components/SegmentCluster.vue b/cypher2/src/components/SegmentCluster.vue
new file mode 100644
index 00000000..9e81107a
--- /dev/null
+++ b/cypher2/src/components/SegmentCluster.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
diff --git a/cypher2/src/components/SegmentedControl.vue b/cypher2/src/components/SegmentedControl.vue
new file mode 100644
index 00000000..273ff8c1
--- /dev/null
+++ b/cypher2/src/components/SegmentedControl.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ {{ s.label }}
+
+
+
diff --git a/cypher2/src/components/SettingsModal.vue b/cypher2/src/components/SettingsModal.vue
new file mode 100644
index 00000000..1e83b592
--- /dev/null
+++ b/cypher2/src/components/SettingsModal.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+ Sheet skin
+
+ {{ t.label }}
+
+
+
+ Per character. Stored with this sheet's display settings, not with the character
+ data — an exported character carries no skin.
+
+
+
+
+ Guided rolls — walk through skill, assets, and Effort; spends pool points.
+
+
+
+
+ Whisper item cards to the GM — chat cards sent from a row stay private. Rolls
+ are unaffected.
+
+
+
+
+
diff --git a/cypher2/src/components/SheetHeader.vue b/cypher2/src/components/SheetHeader.vue
new file mode 100644
index 00000000..59fc8ff8
--- /dev/null
+++ b/cypher2/src/components/SheetHeader.vue
@@ -0,0 +1,157 @@
+
+
+
+
+
+
diff --git a/cypher2/src/components/SkillsSegment.vue b/cypher2/src/components/SkillsSegment.vue
new file mode 100644
index 00000000..ab5dde8d
--- /dev/null
+++ b/cypher2/src/components/SkillsSegment.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+ {{ row.name }}
+ {{ poolLabel(row.pool) }}
+ {{ ratingOrProficiency(row) }}
+ {{ assetText(row) }}
+
+
+
+
+
+
+ {{ s.text }}
+
+ {{ r }}
+
+
+
+
+ {{ s.text }}
+
+ — no pool
+ {{ poolLabel(p) }}
+
+
+
+ Asset
+
+
+ {{ s.text }}
+
+ {{ a }}
+
+
+
+
+ Proficiency
+
+
+
+
+
+
diff --git a/cypher2/src/components/StatusRow.vue b/cypher2/src/components/StatusRow.vue
new file mode 100644
index 00000000..b8bf7c79
--- /dev/null
+++ b/cypher2/src/components/StatusRow.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
Damage & Recovery
+
+
+
+
+
+
+
+
+
+
diff --git a/cypher2/src/components/WoundsTrack.vue b/cypher2/src/components/WoundsTrack.vue
new file mode 100644
index 00000000..d0d94bd3
--- /dev/null
+++ b/cypher2/src/components/WoundsTrack.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
Wounds
+
+
+
+ {{ t.label
+ }}{{
+ openNotes[t.key] ? '▾' : '▸'
+ }}
+
+
+
+
+
+
+
+
+
+ {{ t.note }}
+
+
+
+
+
+
+
+
Shield
+
+ {{ confirmingRemove ? 'Confirm ✕' : '✕' }}
+
+
+
+ + Shield
+
+
+
+ {{ t.label }}
+
+
+
+
+
+
+
+
+
diff --git a/cypher2/src/components/enums.js b/cypher2/src/components/enums.js
new file mode 100644
index 00000000..5dbf8266
--- /dev/null
+++ b/cypher2/src/components/enums.js
@@ -0,0 +1,111 @@
+// The ordered lists for the contract's closed enums (ddd-yzx). The POOL
+// enum keeps its own home in pools.js, which also owns the degrading label reader.
+//
+// These are NOT derived from cypher-character.schema.json at runtime, deliberately:
+// the schema reaches the sheet only through scripts/build-validator.mjs, which bakes
+// it into the generated src/contract/validate.js and exports the validator FUNCTION
+// only — the schema object there is module-private. Importing the .json a second time
+// would ship a second copy of it in the bundle and sits outside vite's dev-server
+// fs.allow root, and a JSON Schema `enum` array carries neither display ORDER nor
+// LABELS, both of which these lists decide. So the lists are hand-written and
+// __tests__/contract-enums.test.js is the lock: it fails if any of them stops
+// matching the schema, or if a stops rendering the list.
+
+// Weakest -> strongest. That order is a UX decision of this sheet's, not the
+// schema's — the schema's enum array happens to agree, and the guard test pins
+// this spelling literally so a schema reorder can never reshuffle the dropdown.
+export const RATINGS = ['inability', 'practiced', 'trained', 'specialized', 'expert']
+
+// Lightest -> heaviest, matching the book's damage ladder. Stored lowercase; the
+// shows title case, the chat card prints the raw value ("medium weapon").
+export const WEAPON_CLASSES = ['light', 'medium', 'heavy']
+export const WEAPON_CLASS_LABELS = { light: 'Light', medium: 'Medium', heavy: 'Heavy' }
+
+// Recovery-track box labels, keyed by $defs.recoverySlot's kind enum (schema v2).
+// Shortest -> longest rest, the book's track order. The key set is locked against
+// the schema by contract-enums.test.js like every other list here; a slot whose
+// stored kind is outside it renders the raw value instead (RecoveryBlock), the
+// same honest-degrade rule as poolLabel()/strayOptions.
+export const RECOVERY_KIND_LABELS = {
+ action: 'Action',
+ tenMinutes: '10 min',
+ oneHour: '1 hr',
+ tenHours: '10 hrs'
+}
+
+// Nearest -> farthest, the book's range ladder; 'special' is the catch-all and
+// sits last. attack.range is nullable ("— unspecified", treat as immediate per
+// the schema note), so the sentinel '' option belongs to the segment, not here.
+export const WEAPON_RANGES = ['immediate', 'short', 'long', 'veryLong', 'special']
+export const WEAPON_RANGE_LABELS = {
+ immediate: 'Immediate',
+ short: 'Short',
+ long: 'Long',
+ veryLong: 'Very long',
+ special: 'Special'
+}
+
+// cypher vs manifest is BEHAVIORAL, not a label — manifest cyphers are worn or
+// wielded rather than one-shot (contract §3.10). Nullable: null = unspecified.
+export const CYPHER_KINDS = ['cypher', 'manifest']
+export const CYPHER_KIND_LABELS = { cypher: 'Cypher', manifest: 'Manifest' }
+
+// Weakest -> strongest power tiers; 'nonstandard' last (contract §3.10).
+// Nullable: 73 of MCG's 189 catalog cyphers carry no power icon.
+export const POWER_TIERS = ['low', 'medium', 'high', 'advanced', 'ultra', 'nonstandard']
+export const POWER_TIER_LABELS = {
+ low: 'Low',
+ medium: 'Medium',
+ high: 'High',
+ advanced: 'Advanced',
+ ultra: 'Ultra',
+ nonstandard: 'Nonstandard'
+}
+
+// skill.asset's closed enum (contract §3.5): assets ease like training but
+// stack under different rules, capped at 2.
+export const SKILL_ASSETS = [0, 1, 2]
+
+// attackModifier.direction's closed enum. The editor folds it into a
+// none/eased/hindered mode select ('none' = the schema's null).
+export const MODIFIER_DIRECTIONS = ['eased', 'hindered']
+
+// EVERY read of a stored value through a label map goes through here — never
+// LABELS[value] directly (ddd-9ir / ddd-5vb audit): hydrate() applies no enum
+// validation, and a stored 'constructor' finds the inherited Function on a
+// bare lookup, printing its source into the cell. Object.hasOwn + raw-value
+// fallback is the poolLabel() rule, shared so no new map can re-grow the bug.
+export const enumLabel = (labels, value) => (Object.hasOwn(labels, value) ? labels[value] : value)
+
+// The EDITOR half of the ddd-9ir ruling (ddd-4s3). poolLabel() made the row SUMMARY
+// degrade honestly; a had no such fallback, so an out-of-enum stored value
+// matched no and the control rendered BLANK — indistinguishable from a
+// rendering fault, and pointing at no field in particular while the player is looking
+// straight at the broken one. Coercing to a legal value on open was rejected: that is
+// a silent WRITE of data the player never asked for, which is the objection ddd-9ir
+// was filed over. So the bad value gets an of its own instead, `disabled` —
+// the value stays visible and selected, and once the player moves off it, it cannot be
+// re-picked. A one-way exit is correct: a legal value must never be replaceable by an
+// illegal one.
+//
+// Returns an ARRAY of 0 or 1 entries so the template can v-for it (ArtifactsSegment's
+// summaryCells idiom): a v-if plus an interpolation would evaluate this twice per
+// render, the double-read ddd-0k1 removed elsewhere. Zero entries for a legal value is
+// what keeps a clean row's option list BYTE-IDENTICAL — contract-enums.test.js asserts
+// those lists EQUAL the schema enum, and it must stay unmodified.
+//
+// null/undefined/'' are excluded deliberately, not incidentally: for skill.pool and
+// attack.weaponClass they are the nullable state, a LEGAL value that already owns the
+// '— no pool' / '— n/a' sentinel option. Handing it a second, disabled option would
+// brand a valid choice as broken. This is the same boundary the summary's `v-if` and
+// poolLabel() already draw.
+//
+// The ⚠ leads so the "this is wrong" signal is the first glyph rendered and cannot be
+// clipped away at 280px (docs/sandbox-walkthrough.md item 5); the raw value comes next
+// because it is the payload — the one thing telling the player WHAT their file got
+// wrong; the parenthetical names the problem last. Nothing here can be mistaken for a
+// legal option, which the raw value alone ("psyche") would be.
+export const strayOptions = (value, allowed, what) =>
+ value === null || value === undefined || value === '' || allowed.includes(value)
+ ? []
+ : [{ value, text: `⚠ ${value} (not a valid ${what})` }]
diff --git a/cypher2/src/components/icons/IconChat.vue b/cypher2/src/components/icons/IconChat.vue
new file mode 100644
index 00000000..fba68309
--- /dev/null
+++ b/cypher2/src/components/icons/IconChat.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/cypher2/src/components/icons/IconPencil.vue b/cypher2/src/components/icons/IconPencil.vue
new file mode 100644
index 00000000..daad3ff3
--- /dev/null
+++ b/cypher2/src/components/icons/IconPencil.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/cypher2/src/components/pools.js b/cypher2/src/components/pools.js
new file mode 100644
index 00000000..e0b62d8f
--- /dev/null
+++ b/cypher2/src/components/pools.js
@@ -0,0 +1,24 @@
+// The ordered list for the pool enum (ddd-yzx). Order is the book's
+// Might/Speed/Intellect, which is also PoolsRow's order — a UX decision of this
+// sheet's, pinned literally by __tests__/contract-enums.test.js so a reorder of the
+// schema's incidental enum array can never reshuffle the dropdown. See enums.js for
+// why these lists are hand-written rather than read out of the schema at runtime.
+export const POOL_NAMES = ['might', 'speed', 'intellect']
+
+// The three pool display labels. Shared because the item-contents descriptors in
+// SkillsSegment and AttacksSegment both need them (item-contents spec §3.1) and a
+// second copy of the map is a second thing to keep in step. The row s read
+// their option text through poolLabel() too, so an option and its summary cell cannot
+// disagree; PoolsRow still spells its labels inline (it is not this change's file).
+export const POOL_LABELS = { might: 'Might', speed: 'Speed', intellect: 'Intellect' }
+
+// EVERY read of a STORED pool value goes through here — never POOL_LABELS[value]
+// directly (ddd-9ir item 1). hydrate() applies no enum validation, so a Beacon
+// snapshot or a drag-drop payload can put any string in row.pool, and a bare lookup
+// renders the miss as an EMPTY cell: the row silently loses information instead of
+// degrading visibly. Falling back to the RAW VALUE rather than collapsing the cell,
+// because a collapsed cell is indistinguishable from "not tied to a Pool" — a real
+// and different state — and the raw value tells a player WHAT their file got wrong.
+// Object.hasOwn, not `?? pool`: POOL_LABELS.constructor is a truthy Function that a
+// nullish coalesce would print (the same trap themes.js avoids with a Set).
+export const poolLabel = (pool) => (Object.hasOwn(POOL_LABELS, pool) ? POOL_LABELS[pool] : pool)
diff --git a/cypher2/src/components/rowFields.js b/cypher2/src/components/rowFields.js
new file mode 100644
index 00000000..677b3d68
--- /dev/null
+++ b/cypher2/src/components/rowFields.js
@@ -0,0 +1,13 @@
+// Shared read-side vocabulary for the segment row templates, alongside pools.js.
+//
+// `level` is `integer >= 1 | null` on the three lists that carry one (cyphers,
+// artifacts, equipment). Both places that READ it — the summary cell and the item-card
+// descriptor (item-contents spec §3.1) — go through here, so neither the wording nor
+// the collapse rule (null COLLAPSES; it never renders "Level 0") can drift between the
+// two sites or between the three lists. The WRITE side is RowLevel.vue.
+//
+// Returns literal `false`, not null, when the level is unset. That is the `&&` shape
+// every other descriptor fragment in the segments uses, and itemCardTemplateData drops
+// booleans and nulls alike (rollTemplates/itemCard.js) — but the `false` is observed,
+// not incidental: CyphersSegment.test.js asserts it directly.
+export const levelField = (row) => row.level !== null && `Level ${row.level}`
diff --git a/cypher2/src/components/segments.js b/cypher2/src/components/segments.js
new file mode 100644
index 00000000..a646d88b
--- /dev/null
+++ b/cypher2/src/components/segments.js
@@ -0,0 +1,35 @@
+// Spec ⑦ §4.1: seven global tabs become two local switches of three and four. This
+// file replaces components/tabs.js — the sheet has no global tab bar any more.
+export const CHARACTER_SEGMENTS = [
+ { key: 'skills', label: 'Skills' },
+ { key: 'abilities', label: 'Abilities' },
+ { key: 'advancement', label: 'Advancement' }
+]
+
+export const KIT_SEGMENTS = [
+ { key: 'attacks', label: 'Attacks' },
+ { key: 'cyphers', label: 'Cyphers' },
+ { key: 'artifacts', label: 'Artifacts' },
+ { key: 'gear', label: 'Gear' }
+]
+
+// The full discipline of the retired resolveTab(), for the same three reasons (spec §5):
+//
+// 1. A Set, NOT `key in PANELS` — the latter would accept 'toString'.
+// 2. Falls back to the FIRST segment. Every panel is mounted, so an unknown stored
+// key would leave no panel carrying data-active and render a blank cluster. The
+// fallback is load-bearing, not cosmetic.
+// 3. Never writes back. Spec §6 requires the stored value to survive untouched, so
+// widening across the 27rem stack threshold restores the last real choice.
+//
+// Both the control and the panel host read ONE resolved value — SegmentCluster resolves
+// nothing itself, it takes `active` already resolved (see SegmentCluster.vue). That is
+// stronger than tabs.js's convention of "both callers must remember to resolve".
+const makeResolver = (segments) => {
+ const keys = new Set(segments.map((s) => s.key))
+ const first = segments[0].key
+ return (key) => (keys.has(key) ? key : first)
+}
+
+export const resolveCharacterSegment = makeResolver(CHARACTER_SEGMENTS)
+export const resolveKitSegment = makeResolver(KIT_SEGMENTS)
diff --git a/cypher2/src/components/switcherClasses.js b/cypher2/src/components/switcherClasses.js
new file mode 100644
index 00000000..f8b6e84d
--- /dev/null
+++ b/cypher2/src/components/switcherClasses.js
@@ -0,0 +1,28 @@
+// Shared switcher styling. SegmentedControl is the only consumer now — TabBar is
+// deleted — so the sizing and contrast work in spec ⑦ §4.4 item 4 is done
+// once (ddd-001) and inherited, not redone.
+//
+// ⚠ COLOUR LIVES IN EXACTLY ONE BRANCH. Tailwind's OUTPUT order decides which utility
+// wins, not the order of names in the class string. A `bg-transparent` in the base
+// would beat a `bg-accent` in the active branch and the active control would stay
+// transparent in every skin. switcherClasses.test.js guards this.
+//
+// `border-[length:...]` rather than a bare `border`, which hardcodes 1px and would
+// ignore fantasy's 2px --cy-geo-rule.
+export const SWITCHER_BASE = [
+ 'flex-none cursor-pointer',
+ 'px-[0.85rem] py-[0.45rem]',
+ 'font-cond text-[0.82rem] uppercase tracking-[var(--cy-geo-banner-tracking)]',
+ 'border-[length:var(--cy-geo-rule)] border-solid border-b-0',
+ 'rounded-[var(--cy-geo-banner-radius)] [clip-path:var(--cy-geo-banner-clip)]'
+].join(' ')
+
+export const SWITCHER_ACTIVE = 'bg-accent text-accent-contrast border-accent font-bold'
+
+// `text-ink`, not `text-muted`: --cy-muted is the exact token .microlabel uses, so an
+// inactive tab read at field-label contrast — the fault spec ⑦ §4.4 item 4 names when it
+// asks for weight, spacing AND contrast. --color-ink is the sheet's primary body-text
+// token (bridged in main.css's @theme block, so it re-skins per [data-theme] like every
+// other semantic utility). Active still separates from inactive on background, border
+// and weight, so promoting inactive to body-text contrast costs no state legibility.
+export const SWITCHER_INACTIVE = 'bg-transparent text-ink border-transparent'
diff --git a/cypher2/src/components/themes.js b/cypher2/src/components/themes.js
new file mode 100644
index 00000000..01b1e76c
--- /dev/null
+++ b/cypher2/src/components/themes.js
@@ -0,0 +1,14 @@
+// The three shipped skins. Superhero and Real-World are the book's other two genres
+// but MCG supplied no printed sheet art for them — deferred to ddd-bdv, which is now
+// two more [data-theme] blocks and no code.
+export const THEMES = [
+ { key: 'base', label: 'Base' },
+ { key: 'fantasy', label: 'Fantasy' },
+ { key: 'scifi', label: 'Science Fiction' }
+]
+
+const KEYS = new Set(THEMES.map((t) => t.key))
+
+// An unknown value resolves to base rather than leaving the blank or the
+// sheet unthemed. A Set, not `key in {...}` — the latter would accept 'toString'.
+export const resolveTheme = (key) => (KEYS.has(key) ? key : 'base')
diff --git a/cypher2/src/contract/exporter.js b/cypher2/src/contract/exporter.js
new file mode 100644
index 00000000..9031047d
--- /dev/null
+++ b/cypher2/src/contract/exporter.js
@@ -0,0 +1,52 @@
+import { ARRAY_KEYS } from '@/stores/sheetStore.js'
+import { DEFAULT_CHARACTER_NAME } from '@/stores/index.js'
+
+// Plain deep copy of reactive values. JSON round-trip is safe here: values are
+// JSON-shaped by construction, and _id/arrayPosition are already removed by
+// explicit destructuring (never rely on serialization to hide them —
+// beacon-mapping §3.2).
+const plain = (value) => JSON.parse(JSON.stringify(value))
+
+const stripRow = (row) => {
+ const { _id, arrayPosition, ...rest } = row
+ return plain(rest)
+}
+
+// store -> schema document. Store array order IS the exported order; do not
+// sort by arrayPosition (beacon-mapping §3.3).
+export const exportDocument = ({ sheet, meta }) => ({
+ schemaVersion: 2,
+ kind: 'cypher-character',
+ name: meta.name || DEFAULT_CHARACTER_NAME,
+ sentence: plain(sheet.sentence),
+ tier: sheet.tier,
+ effort: sheet.effort,
+ xp: sheet.xp,
+ storyXp: sheet.storyXp,
+ resourcePoints: sheet.resourcePoints,
+ rank: sheet.rank,
+ advancement: plain(sheet.advancement),
+ pools: plain(sheet.pools),
+ recovery: plain(sheet.recovery),
+ wounds: plain(sheet.wounds),
+ shield: plain(sheet.shield),
+ armor: sheet.armor,
+ armorModifiers: sheet.armorModifiers,
+ cypherLimit: sheet.cypherLimit,
+ genre: sheet.genre,
+ subgenre: sheet.subgenre,
+ ...Object.fromEntries(ARRAY_KEYS.map((k) => [k, sheet[k].map(stripRow)])),
+ background: sheet.background,
+ notes: sheet.notes,
+ portraitUrl: sheet.portraitUrl
+})
+
+export const downloadDocument = (doc) => {
+ const blob = new Blob([JSON.stringify(doc, null, 2)], { type: 'application/json' })
+ const url = URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = `${doc.name || 'cypher-character'}.json`
+ a.click()
+ URL.revokeObjectURL(url)
+}
diff --git a/cypher2/src/contract/importer.js b/cypher2/src/contract/importer.js
new file mode 100644
index 00000000..c335848a
--- /dev/null
+++ b/cypher2/src/contract/importer.js
@@ -0,0 +1,83 @@
+import { v4 as uuidv4 } from 'uuid'
+import { validateDocument, SUPPORTED_SCHEMA_VERSION } from './validation.js'
+import { ARRAY_KEYS } from '@/stores/sheetStore.js'
+
+export const FAILURE = {
+ NOT_JSON: 'not-json',
+ WRONG_KIND: 'wrong-kind',
+ NEWER_VERSION: 'newer-version',
+ SCHEMA_INVALID: 'schema-invalid'
+}
+
+const fail = (code, message, details) => ({ ok: false, failure: { code, message, details } })
+
+// Pure: parses and validates, never touches stores (beacon-mapping §5 steps 1–2).
+// The caller confirms with the user, then calls applyDocument (steps 3–4).
+export const parseAndValidate = (text) => {
+ let doc
+ try {
+ doc = JSON.parse(text)
+ } catch (e) {
+ return fail(FAILURE.NOT_JSON, `This file is not valid JSON. ${e.message}`)
+ }
+
+ const kind = doc?.kind
+ if (kind !== 'cypher-character') {
+ const found = kind === undefined ? 'it has no kind field' : `found ${JSON.stringify(kind)}`
+ return fail(
+ FAILURE.WRONG_KIND,
+ `This file is not a Cypher character: expected kind "cypher-character", but ${found}.`
+ )
+ }
+
+ const version = doc.schemaVersion
+ if (typeof version === 'number' && version > SUPPORTED_SCHEMA_VERSION) {
+ return fail(
+ FAILURE.NEWER_VERSION,
+ `This character uses schema version ${version}, but this sheet supports version ` +
+ `${SUPPORTED_SCHEMA_VERSION}. The sheet needs updating — the file is fine.`
+ )
+ }
+
+ const { valid, errors } = validateDocument(doc)
+ if (!valid) {
+ return fail(
+ FAILURE.SCHEMA_INVALID,
+ 'This file does not match the Cypher character schema.',
+ errors.slice(0, 5)
+ )
+ }
+
+ return { ok: true, doc }
+}
+
+const plain = (value) => JSON.parse(JSON.stringify(value))
+
+// Wholesale replace (beacon-mapping §5 step 4). Incoming rows never carry _id
+// (the schema forbids it); every row gets a fresh one. ui is never touched (§4).
+export const applyDocument = (doc, { sheet, meta }) => {
+ meta.name = doc.name
+ sheet.sentence = plain(doc.sentence)
+ sheet.tier = doc.tier
+ sheet.effort = doc.effort
+ sheet.xp = doc.xp
+ sheet.storyXp = doc.storyXp
+ sheet.resourcePoints = doc.resourcePoints
+ sheet.rank = doc.rank
+ sheet.advancement = plain(doc.advancement)
+ sheet.pools = plain(doc.pools)
+ sheet.recovery = plain(doc.recovery)
+ sheet.wounds = plain(doc.wounds)
+ sheet.shield = plain(doc.shield)
+ sheet.armor = doc.armor
+ sheet.armorModifiers = doc.armorModifiers
+ sheet.cypherLimit = doc.cypherLimit
+ sheet.genre = doc.genre
+ sheet.subgenre = doc.subgenre
+ sheet.portraitUrl = doc.portraitUrl
+ ARRAY_KEYS.forEach((k) => {
+ sheet[k] = doc[k].map((row) => ({ _id: uuidv4(), ...plain(row) }))
+ })
+ sheet.background = doc.background
+ sheet.notes = doc.notes
+}
diff --git a/cypher2/src/contract/validate.js b/cypher2/src/contract/validate.js
new file mode 100644
index 00000000..88c31b18
--- /dev/null
+++ b/cypher2/src/contract/validate.js
@@ -0,0 +1,3 @@
+/* GENERATED by scripts/build-validator.mjs from cypher-contract/cypher-character.schema.json — do not edit. */
+/* eslint-disable */
+import __ajvRuntime0 from "ajv/dist/runtime/ucs2length";import __ajvRuntime1 from "ajv/dist/runtime/equal";"use strict";export const validate = validate20;export default validate20;const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://clockpunkstudios.com/cypher-contract/cypher-character.schema.json","title":"Cypher Character","description":"Canonical Cypher character document, schemaVersion 2. Contract between Cypher Tools (exporter), the Roll20 Beacon sheet (importer), and the compendium build (drag-drop payloads). v2 adopts the Cypher Tools (MCG) counter-proposal of 2026-08-24 — rationale per field cites section numbers of 2026-08-24-response-v2/cypher-tools-format-gap-audit.md; the acceptance decision record is handoff/2026-08-24-v2-acceptance.md. Conventions from v1 are preserved throughout: additionalProperties false everywhere, every field required, an absent value is an explicit \"\", [], or null rather than an omitted key. See docs/rules-verification.md for book-verified rule values.","type":"object","additionalProperties":false,"required":["schemaVersion","kind","name","sentence","tier","effort","xp","storyXp","resourcePoints","rank","advancement","pools","recovery","wounds","shield","armor","armorModifiers","cypherLimit","genre","subgenre","skills","abilities","attacks","equipment","cyphers","artifacts","powerShifts","currencies","arcs","background","notes","portraitUrl"],"properties":{"schemaVersion":{"const":2},"kind":{"const":"cypher-character"},"name":{"type":"string","minLength":1},"sentence":{"type":"object","additionalProperties":false,"required":["descriptor","secondDescriptor","type","focus","secondFocus","species"],"properties":{"descriptor":{"type":"string"},"secondDescriptor":{"type":"string","description":"ADDED (§3.12). The book allows a character to take two descriptors (\"you instead gain the benefit of two descriptors\" — your own rules-verification.md). v1 could only hold one, forcing exporters to join them into a single string."},"type":{"type":"string","description":"NOTE (§6.7), no shape change: in the real-world genre there are no book types at all — the player enters a free-text profession (\"Paramedic\", \"Investigative Journalist\") and it occupies this slot. An importer must not validate `type` against a known list."},"focus":{"type":"string"},"secondFocus":{"type":"string","description":"ADDED (§6.1). The superhero Living God type grants a Second Focus ability, and the character then has two. Without this field the two are joined into `focus` as \"Masters Weaponry and Explores\", which reads as one focus with an odd name. Rare — exactly one of our 55 types grants it — but the cost is one string and the failure without it is silent. \"\" when the character has one focus."},"species":{"type":"string","description":"Cypher Tools tracks species first-class; see §6 question 1 re: reconciling the Bross fixture."}}},"tier":{"type":"integer","minimum":1},"effort":{"type":"integer","minimum":1,"description":"No maximum (amended from the MCG draft's 6 at acceptance — handoff/2026-08-24-v2-acceptance.md §2): 6 is the cap via normal advancement, but abilities (e.g. Superheroics) can raise the Effort limit above it. Importers must not reject or clamp values above 6. Mirrors the unbounded `tier` precedent."},"xp":{"type":"integer","minimum":0},"storyXp":{"type":"integer","minimum":0,"description":"ADDED (§3.15). A second, separately-tracked XP pool. v1 had one `xp`, which forced the Foundry export to sum the two into a single number and lose the distinction. 0 when the game doesn't use it."},"resourcePoints":{"type":"integer","minimum":0,"description":"ADDED (§3.15). \"RP\" — a progression counter, deliberately NOT a currency. 0 when unused."},"rank":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}],"description":"ADDED (§3.14). Superhero rank 1–5; gates which origin abilities a character may take. null outside the superhero genre."},"advancement":{"type":"object","additionalProperties":false,"required":["stats","effort","edge","skill","other"],"description":"UNCHANGED. Maps 1:1 to Cypher Tools' five advancement slots. Note §4.10: tier 7+ characters currently export all-false because we stop recording purchases past tier 6 — ours to fix, not a schema problem.","properties":{"stats":{"type":"boolean"},"effort":{"type":"boolean"},"edge":{"type":"boolean"},"skill":{"type":"boolean"},"other":{"type":"boolean"}}},"pools":{"type":"object","additionalProperties":false,"required":["might","speed","intellect"],"properties":{"might":{"$ref":"#/$defs/pool"},"speed":{"$ref":"#/$defs/pool"},"intellect":{"$ref":"#/$defs/pool"}}},"recovery":{"type":"object","additionalProperties":false,"required":["bonus","slots"],"description":"CHANGED (§2.4) — this is our highest-priority ask, and the one place v1 is narrower than the book rather than narrower than our model.","properties":{"bonus":{"type":"integer","minimum":0,"description":"UNCHANGED. Points added to the 1d6 recovery roll; defaults to tier."},"slots":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/recoverySlot"},"description":"REPLACES v1's `used` object of exactly four booleans. Order is significant — position determines rest duration, and the book's \"+2 if the one-action recovery is taken as your last action\" depends on it. A default character has exactly four slots in the order action, tenMinutes, oneHour, tenHours, which is v1's shape expressed as an array. Why the change: (a) five separate abilities grant EXTRA one-action recoveries — Healing (one per shift, unbounded), Untamed Recovery, Mind Surge, Machine Not Flesh — so a character with two Healing shifts has six slots and v1 can carry four; (b) Push on Through REPLACES the ten-minute recovery with a second one-action recovery, so for those characters v1's `used.tenMinutes` silently mislabels a one-action slot. Both are expressible here without special cases."}}},"wounds":{"type":"object","additionalProperties":false,"required":["minor","moderate","major"],"properties":{"minor":{"$ref":"#/$defs/woundTier"},"moderate":{"$ref":"#/$defs/woundTier"},"major":{"$ref":"#/$defs/woundTier"}}},"shield":{"anyOf":[{"$ref":"#/$defs/shield"},{"type":"null"}],"description":"ADDED (§3.7). A shield tracks its own wounds — \"A shield can take three minor wounds, two moderate wounds, and one major wound\" (quoted in your own rules-verification.md, where it is noted as out of scope for v1). Maxima are per-character because abilities modify them (Shield Master raises moderate to 3). null when the character carries no shield."},"armor":{"type":"integer","minimum":0,"description":"RETAINED, but see §3.22 — we believe this field is inherited from the Foundry `cyphersystem` system (1e-shaped) rather than from the 2e book, and we will send 0 for essentially every character. Evidence: the official 2e form-fillable sheet has no numeric Armor field (only a free-text Armor_and_Modifiers box plus armor-proficiency checkboxes), our builder hardcodes 0, and no PC-facing ability in the Character Rulebook grants a numeric Armor bonus. Left in place rather than removed so any 1e-shaped consumer keeps working; `armorModifiers` below is where the real information lives. Worth deciding whether it survives to v3."},"armorModifiers":{"type":"string","description":"ADDED (§3.22). The free-text armor box as it appears on the 2e sheet — the field that actually records a character's armor. \"\" when empty."},"cypherLimit":{"type":"integer","minimum":0},"genre":{"type":"string","description":"ADDED (§3.13). e.g. \"fantasy\", \"scifi\", \"superhero\", \"real_world\". Drives cypher naming and equipment lists, and tells an importer which optional systems are in play. \"\" when unset."},"subgenre":{"type":"string","description":"ADDED (§3.13). e.g. \"Dungeon Fantasy\". \"\" when unset."},"skills":{"type":"array","items":{"$ref":"#/$defs/skill"}},"abilities":{"type":"array","items":{"$ref":"#/$defs/ability"}},"attacks":{"type":"array","items":{"$ref":"#/$defs/attack"}},"equipment":{"type":"array","items":{"$ref":"#/$defs/equipment"}},"cyphers":{"type":"array","items":{"$ref":"#/$defs/cypher"}},"artifacts":{"type":"array","items":{"$ref":"#/$defs/artifact"}},"powerShifts":{"type":"array","items":{"$ref":"#/$defs/powerShift"}},"currencies":{"type":"array","items":{"$ref":"#/$defs/currency"}},"arcs":{"type":"array","items":{"$ref":"#/$defs/arc"}},"background":{"type":"string"},"notes":{"type":"string"},"portraitUrl":{"type":"string","description":"ADDED (§3.20). A fetchable URL for the character's portrait, or \"\" when there is none. Cypher Tools already serves portrait URLs to unauthenticated clients via its share-link endpoint, so this is an established path rather than a new exposure. Consumers should treat it as optional and degrade gracefully — it is served by the application rather than a CDN."}},"$defs":{"pool":{"type":"object","additionalProperties":false,"required":["current","max","edge"],"properties":{"current":{"type":"integer","minimum":0},"max":{"type":"integer","minimum":0},"edge":{"type":"integer","minimum":0}}},"woundTier":{"type":"object","additionalProperties":false,"required":["current","max"],"properties":{"current":{"type":"integer","minimum":0},"max":{"type":"integer","minimum":0}}},"shield":{"type":"object","additionalProperties":false,"required":["minor","moderate","major"],"description":"ADDED (§3.7). Book default 3 / 2 / 1; maxima are per-character because abilities modify them.","properties":{"minor":{"$ref":"#/$defs/woundTier"},"moderate":{"$ref":"#/$defs/woundTier"},"major":{"$ref":"#/$defs/woundTier"}}},"recoverySlot":{"type":"object","additionalProperties":false,"required":["kind","used","note"],"description":"ADDED (§2.4). One box on the recovery track.","properties":{"kind":{"enum":["action","tenMinutes","oneHour","tenHours"],"description":"The rest duration this slot requires. A character may have more than one slot of the same kind — that is exactly how extra one-action recoveries and Push on Through are represented."},"used":{"type":"boolean"},"note":{"type":"string","description":"Why this slot exists beyond the standard four, or any restriction on it — e.g. \"Healing power shift\", or \"Mind Surge: Intellect Pool only\". \"\" for the four standard slots."}}},"poolName":{"enum":["might","speed","intellect"]},"skillRating":{"enum":["inability","practiced","trained","specialized","expert"]},"weaponRange":{"enum":["immediate","short","long","veryLong","special"],"description":"ADDED (§3.2)."},"skill":{"type":"object","additionalProperties":false,"required":["name","rating","pool","asset","isProficiency","source","description"],"properties":{"name":{"type":"string","minLength":1},"rating":{"$ref":"#/$defs/skillRating"},"pool":{"anyOf":[{"$ref":"#/$defs/poolName"},{"type":"null"}]},"asset":{"enum":[0,1,2],"description":"ADDED (§3.5). Assets ease a task like training does but stack under different rules, so they cannot be folded into `rating`. v1 had no home for this and our Foundry export smuggles it into description text as \"Asset: x2.\". 0 when none."},"isProficiency":{"type":"boolean","description":"ADDED (§3.6). True for type/focus-granted weapon and armor proficiencies (\"Freely Use All Weapons\", \"Freely Use Light And Medium Armor\"). These are NOT trainable via advancement and should not render with a rating badge. In bross-drikess.json they appear as ordinary \"practiced\" skills, so a v1 importer will offer to advance them."},"source":{"type":"string"},"description":{"type":"string"}}},"ability":{"type":"object","additionalProperties":false,"required":["name","cost","pools","enabler","activation","source","description"],"properties":{"name":{"type":"string","minLength":1},"cost":{"description":"UNCHANGED from v1. null = no cost. variable: true means the cost is set in play (points MUST be null, plus MUST be false).","anyOf":[{"type":"object","additionalProperties":false,"required":["points","plus","variable"],"properties":{"points":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"plus":{"type":"boolean"},"variable":{"type":"boolean"}},"oneOf":[{"properties":{"variable":{"const":false},"points":{"type":"integer"}}},{"properties":{"variable":{"const":true},"points":{"type":"null"},"plus":{"const":false}}}]},{"type":"null"}]},"pools":{"type":"array","items":{"$ref":"#/$defs/poolName"},"uniqueItems":true,"maxItems":3},"enabler":{"type":"boolean","description":"UNCHANGED, and derivable from `activation` — kept so consumers that only need the binary distinction don't have to parse a string."},"activation":{"type":"string","description":"ADDED (§3.1). The ability's activation as printed, verbatim. `enabler` answers \"is this an enabler\" but discards WHEN IN THE ROUND the ability fires, which is what a VTT sheet needs for initiative-order UI. Across our 663-row catalog: \"Enabler\" (344), \"Action\" (143), \"Action to initiate\" (54), \"Last action\" (31), \"First action\" (8), plus ~25 long-form variants — e.g. \"Action when in your normal form; enabler when using Beast Form\", \"Ten minutes to prepare a cypher as a spell; action to cast a cypher as a spell\", \"First action, action, or Last action\". Deliberately a string and not an enum: the long-form tail is irreducible. \"\" when the source gives none."},"source":{"type":"string"},"description":{"type":"string"}}},"attack":{"type":"object","additionalProperties":false,"required":["name","pool","weaponClass","damage","skillRating","range","modifier","notes"],"properties":{"name":{"type":"string","minLength":1},"pool":{"$ref":"#/$defs/poolName"},"weaponClass":{"anyOf":[{"enum":["light","medium","heavy"]},{"type":"null"}]},"damage":{"type":"integer","minimum":0},"skillRating":{"$ref":"#/$defs/skillRating"},"range":{"anyOf":[{"$ref":"#/$defs/weaponRange"},{"type":"null"}],"description":"ADDED (§3.2). Note our EXISTING Foundry export already carries this as system.basic.range, so v1 is a regression against what Roll20 users get today by importing the Foundry file. null when unspecified (treat as immediate)."},"modifier":{"anyOf":[{"$ref":"#/$defs/attackModifier"},{"type":"null"}],"description":"ADDED (§3.3). A standing ease/hinder on this attack. Also already in the Foundry export as system.basic.steps + modifier. null when the attack is unmodified."},"notes":{"type":"string"}}},"attackModifier":{"type":"object","additionalProperties":false,"required":["steps","direction"],"properties":{"steps":{"type":"integer","minimum":1},"direction":{"enum":["eased","hindered"]}}},"equipment":{"type":"object","additionalProperties":false,"required":["name","level","quantity","notes"],"description":"UNCHANGED. Note (§2.3) that Cypher Tools stores equipment as free text, one item per line, so we will send level: null — the level 1 / quantity 1 values in bross-drikess.json are an artifact of our Foundry renderer, not character data.","properties":{"name":{"type":"string","minLength":1},"level":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"quantity":{"type":"integer","minimum":0},"notes":{"type":"string"}}},"cypher":{"type":"object","additionalProperties":false,"required":["name","displayName","level","cypherKind","power","activated","description"],"properties":{"name":{"type":"string","minLength":1},"displayName":{"type":"string","description":"ADDED (§3.10). Genre-specific alias, when it differs from the canonical name — the catalog renames some cyphers per genre. \"\" when the same as `name`."},"level":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"cypherKind":{"anyOf":[{"enum":["cypher","manifest"]},{"type":"null"}],"description":"ADDED (§3.10). Manifest cyphers are worn or wielded rather than one-shot, so this is a behavioral difference and not a label — 98 of our 189 catalog cyphers are manifest. Named `cypherKind` rather than `kind` to avoid colliding with the drop payload's `kind`."},"power":{"anyOf":[{"enum":["low","medium","high","advanced","ultra","nonstandard"]},{"type":"null"}],"description":"ADDED (§3.10). Power tier. null is legitimate and common — 73 of our 189 catalog cyphers carry no power icon."},"activated":{"type":"boolean","description":"ADDED (§3.10). Whether the cypher is currently in use."},"description":{"type":"string"}}},"artifact":{"type":"object","additionalProperties":false,"required":["name","level","depletion","form","description"],"properties":{"name":{"type":"string","minLength":1},"level":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"UNCHANGED and correct as-is: an artifact on a character has a rolled integer level. The book's roll formula (\"1d6 + 3\") stays a catalog concern on the exporter's side."},"depletion":{"description":"CHANGED (§2.1). One addition: the \"automatic\" sentinel, for artifacts that deplete on use. This is NOT the same as null — null means an artifact never depletes, and conflating the two is a correctness bug rather than a lost detail. Also stating explicitly what v1 left ambiguous: `chance` means depletion occurs on a roll of 1 through `chance`, which is what makes the book's ranged forms (\"1-3 in 1d6\") representable. Note the book writes d100 as \"1d00\"; `die` keeps the \"1d100\" spelling and exporters map it. Two further kinds of depletion text — the \"(check each ...)\" trigger clause (25 of the book's 72 artifacts) and the \"upon depletion, ...\" consequence (19) — are deliberately NOT structured here; Cypher Tools does not model artifacts yet, so we would rather see how they are used before fixing a shape, and they can live in `description` meanwhile. Flagged in §2.1 so the loss is a known decision rather than an oversight.","anyOf":[{"type":"object","additionalProperties":false,"required":["chance","die"],"properties":{"chance":{"type":"integer","minimum":1,"description":"Depletion occurs on a roll of 1 through `chance` — this reading makes the book's ranged forms (\"1-3 in 1d6\", 5 rows) representable. v1 left it ambiguous; stating it explicitly here."},"die":{"enum":["1d6","1d10","1d20","1d100"]}}},{"const":"automatic"},{"type":"null"}]},"form":{"type":"string","description":"ADDED (§2.1). Populated on every one of the book's 72 artifacts and often the most evocative text on the row (\"Beaded necklace set with closed eye symbol or jewel\"). \"\" when none."},"description":{"type":"string"}}},"powerShift":{"type":"object","additionalProperties":false,"required":["name","shifts","description"],"properties":{"name":{"type":"string","minLength":1},"shifts":{"type":"integer","minimum":1},"description":{"type":"string"}}},"currency":{"type":"object","additionalProperties":false,"required":["name","amount"],"properties":{"name":{"type":"string","minLength":1},"amount":{"type":"number","minimum":0}}},"arcStep":{"type":"object","additionalProperties":false,"required":["name","completed"],"properties":{"name":{"type":"string","minLength":1},"completed":{"type":"boolean"}}},"arc":{"type":"object","additionalProperties":false,"required":["name","description","steps"],"properties":{"name":{"type":"string","minLength":1},"description":{"type":"string"},"steps":{"type":"array","items":{"$ref":"#/$defs/arcStep"}}}},"dropPayload":{"type":"object","additionalProperties":false,"required":["contractVersion","kind","item"],"description":"contractVersion bumps in lockstep with schemaVersion, per your README.","properties":{"contractVersion":{"const":2},"kind":{"enum":["skill","ability","equipment","cypher","artifact","arc"]},"item":{"type":"object"}},"oneOf":[{"properties":{"kind":{"const":"skill"},"item":{"$ref":"#/$defs/skill"}}},{"properties":{"kind":{"const":"ability"},"item":{"$ref":"#/$defs/ability"}}},{"properties":{"kind":{"const":"equipment"},"item":{"$ref":"#/$defs/equipment"}}},{"properties":{"kind":{"const":"cypher"},"item":{"$ref":"#/$defs/cypher"}}},{"properties":{"kind":{"const":"artifact"},"item":{"$ref":"#/$defs/artifact"}}},{"properties":{"kind":{"const":"arc"},"item":{"$ref":"#/$defs/arc"}}}]}}};const schema32 = {"type":"object","additionalProperties":false,"required":["current","max","edge"],"properties":{"current":{"type":"integer","minimum":0},"max":{"type":"integer","minimum":0},"edge":{"type":"integer","minimum":0}}};const schema35 = {"type":"object","additionalProperties":false,"required":["kind","used","note"],"description":"ADDED (§2.4). One box on the recovery track.","properties":{"kind":{"enum":["action","tenMinutes","oneHour","tenHours"],"description":"The rest duration this slot requires. A character may have more than one slot of the same kind — that is exactly how extra one-action recoveries and Push on Through are represented."},"used":{"type":"boolean"},"note":{"type":"string","description":"Why this slot exists beyond the standard four, or any restriction on it — e.g. \"Healing power shift\", or \"Mind Surge: Intellect Pool only\". \"\" for the four standard slots."}}};const schema36 = {"type":"object","additionalProperties":false,"required":["current","max"],"properties":{"current":{"type":"integer","minimum":0},"max":{"type":"integer","minimum":0}}};const schema53 = {"type":"object","additionalProperties":false,"required":["name","level","quantity","notes"],"description":"UNCHANGED. Note (§2.3) that Cypher Tools stores equipment as free text, one item per line, so we will send level: null — the level 1 / quantity 1 values in bross-drikess.json are an artifact of our Foundry renderer, not character data.","properties":{"name":{"type":"string","minLength":1},"level":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"quantity":{"type":"integer","minimum":0},"notes":{"type":"string"}}};const schema54 = {"type":"object","additionalProperties":false,"required":["name","displayName","level","cypherKind","power","activated","description"],"properties":{"name":{"type":"string","minLength":1},"displayName":{"type":"string","description":"ADDED (§3.10). Genre-specific alias, when it differs from the canonical name — the catalog renames some cyphers per genre. \"\" when the same as `name`."},"level":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"cypherKind":{"anyOf":[{"enum":["cypher","manifest"]},{"type":"null"}],"description":"ADDED (§3.10). Manifest cyphers are worn or wielded rather than one-shot, so this is a behavioral difference and not a label — 98 of our 189 catalog cyphers are manifest. Named `cypherKind` rather than `kind` to avoid colliding with the drop payload's `kind`."},"power":{"anyOf":[{"enum":["low","medium","high","advanced","ultra","nonstandard"]},{"type":"null"}],"description":"ADDED (§3.10). Power tier. null is legitimate and common — 73 of our 189 catalog cyphers carry no power icon."},"activated":{"type":"boolean","description":"ADDED (§3.10). Whether the cypher is currently in use."},"description":{"type":"string"}}};const schema55 = {"type":"object","additionalProperties":false,"required":["name","level","depletion","form","description"],"properties":{"name":{"type":"string","minLength":1},"level":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"UNCHANGED and correct as-is: an artifact on a character has a rolled integer level. The book's roll formula (\"1d6 + 3\") stays a catalog concern on the exporter's side."},"depletion":{"description":"CHANGED (§2.1). One addition: the \"automatic\" sentinel, for artifacts that deplete on use. This is NOT the same as null — null means an artifact never depletes, and conflating the two is a correctness bug rather than a lost detail. Also stating explicitly what v1 left ambiguous: `chance` means depletion occurs on a roll of 1 through `chance`, which is what makes the book's ranged forms (\"1-3 in 1d6\") representable. Note the book writes d100 as \"1d00\"; `die` keeps the \"1d100\" spelling and exporters map it. Two further kinds of depletion text — the \"(check each ...)\" trigger clause (25 of the book's 72 artifacts) and the \"upon depletion, ...\" consequence (19) — are deliberately NOT structured here; Cypher Tools does not model artifacts yet, so we would rather see how they are used before fixing a shape, and they can live in `description` meanwhile. Flagged in §2.1 so the loss is a known decision rather than an oversight.","anyOf":[{"type":"object","additionalProperties":false,"required":["chance","die"],"properties":{"chance":{"type":"integer","minimum":1,"description":"Depletion occurs on a roll of 1 through `chance` — this reading makes the book's ranged forms (\"1-3 in 1d6\", 5 rows) representable. v1 left it ambiguous; stating it explicitly here."},"die":{"enum":["1d6","1d10","1d20","1d100"]}}},{"const":"automatic"},{"type":"null"}]},"form":{"type":"string","description":"ADDED (§2.1). Populated on every one of the book's 72 artifacts and often the most evocative text on the row (\"Beaded necklace set with closed eye symbol or jewel\"). \"\" when none."},"description":{"type":"string"}}};const schema56 = {"type":"object","additionalProperties":false,"required":["name","shifts","description"],"properties":{"name":{"type":"string","minLength":1},"shifts":{"type":"integer","minimum":1},"description":{"type":"string"}}};const schema57 = {"type":"object","additionalProperties":false,"required":["name","amount"],"properties":{"name":{"type":"string","minLength":1},"amount":{"type":"number","minimum":0}}};const func1 = Object.prototype.hasOwnProperty;const func2 = (__ajvRuntime0.default ?? __ajvRuntime0);const schema39 = {"type":"object","additionalProperties":false,"required":["minor","moderate","major"],"description":"ADDED (§3.7). Book default 3 / 2 / 1; maxima are per-character because abilities modify them.","properties":{"minor":{"$ref":"#/$defs/woundTier"},"moderate":{"$ref":"#/$defs/woundTier"},"major":{"$ref":"#/$defs/woundTier"}}};function validate21(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){let vErrors = null;let errors = 0;const evaluated0 = validate21.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.minor === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "minor"},message:"must have required property '"+"minor"+"'",schema:schema39.required,parentSchema:schema39,data};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.moderate === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "moderate"},message:"must have required property '"+"moderate"+"'",schema:schema39.required,parentSchema:schema39,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.major === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "major"},message:"must have required property '"+"major"+"'",schema:schema39.required,parentSchema:schema39,data};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}for(const key0 in data){if(!(((key0 === "minor") || (key0 === "moderate")) || (key0 === "major"))){const err3 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties",schema:false,parentSchema:schema39,data};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}}if(data.minor !== undefined){let data0 = data.minor;if(data0 && typeof data0 == "object" && !Array.isArray(data0)){if(data0.current === undefined){const err4 = {instancePath:instancePath+"/minor",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema36.required,parentSchema:schema36,data:data0};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}if(data0.max === undefined){const err5 = {instancePath:instancePath+"/minor",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema36.required,parentSchema:schema36,data:data0};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}for(const key1 in data0){if(!((key1 === "current") || (key1 === "max"))){const err6 = {instancePath:instancePath+"/minor",schemaPath:"#/$defs/woundTier/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties",schema:false,parentSchema:schema36,data:data0};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}}if(data0.current !== undefined){let data1 = data0.current;if(!(((typeof data1 == "number") && (!(data1 % 1) && !isNaN(data1))) && (isFinite(data1)))){const err7 = {instancePath:instancePath+"/minor/current",schemaPath:"#/$defs/woundTier/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.current.type,parentSchema:schema36.properties.current,data:data1};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}if((typeof data1 == "number") && (isFinite(data1))){if(data1 < 0 || isNaN(data1)){const err8 = {instancePath:instancePath+"/minor/current",schemaPath:"#/$defs/woundTier/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.current,data:data1};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}}if(data0.max !== undefined){let data2 = data0.max;if(!(((typeof data2 == "number") && (!(data2 % 1) && !isNaN(data2))) && (isFinite(data2)))){const err9 = {instancePath:instancePath+"/minor/max",schemaPath:"#/$defs/woundTier/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.max.type,parentSchema:schema36.properties.max,data:data2};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}if((typeof data2 == "number") && (isFinite(data2))){if(data2 < 0 || isNaN(data2)){const err10 = {instancePath:instancePath+"/minor/max",schemaPath:"#/$defs/woundTier/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.max,data:data2};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}}}}else {const err11 = {instancePath:instancePath+"/minor",schemaPath:"#/$defs/woundTier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema36.type,parentSchema:schema36,data:data0};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}if(data.moderate !== undefined){let data3 = data.moderate;if(data3 && typeof data3 == "object" && !Array.isArray(data3)){if(data3.current === undefined){const err12 = {instancePath:instancePath+"/moderate",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema36.required,parentSchema:schema36,data:data3};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}if(data3.max === undefined){const err13 = {instancePath:instancePath+"/moderate",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema36.required,parentSchema:schema36,data:data3};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}for(const key2 in data3){if(!((key2 === "current") || (key2 === "max"))){const err14 = {instancePath:instancePath+"/moderate",schemaPath:"#/$defs/woundTier/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties",schema:false,parentSchema:schema36,data:data3};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}}if(data3.current !== undefined){let data4 = data3.current;if(!(((typeof data4 == "number") && (!(data4 % 1) && !isNaN(data4))) && (isFinite(data4)))){const err15 = {instancePath:instancePath+"/moderate/current",schemaPath:"#/$defs/woundTier/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.current.type,parentSchema:schema36.properties.current,data:data4};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}if((typeof data4 == "number") && (isFinite(data4))){if(data4 < 0 || isNaN(data4)){const err16 = {instancePath:instancePath+"/moderate/current",schemaPath:"#/$defs/woundTier/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.current,data:data4};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}}}if(data3.max !== undefined){let data5 = data3.max;if(!(((typeof data5 == "number") && (!(data5 % 1) && !isNaN(data5))) && (isFinite(data5)))){const err17 = {instancePath:instancePath+"/moderate/max",schemaPath:"#/$defs/woundTier/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.max.type,parentSchema:schema36.properties.max,data:data5};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}if((typeof data5 == "number") && (isFinite(data5))){if(data5 < 0 || isNaN(data5)){const err18 = {instancePath:instancePath+"/moderate/max",schemaPath:"#/$defs/woundTier/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.max,data:data5};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}}}}else {const err19 = {instancePath:instancePath+"/moderate",schemaPath:"#/$defs/woundTier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema36.type,parentSchema:schema36,data:data3};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}}if(data.major !== undefined){let data6 = data.major;if(data6 && typeof data6 == "object" && !Array.isArray(data6)){if(data6.current === undefined){const err20 = {instancePath:instancePath+"/major",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema36.required,parentSchema:schema36,data:data6};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}if(data6.max === undefined){const err21 = {instancePath:instancePath+"/major",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema36.required,parentSchema:schema36,data:data6};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}for(const key3 in data6){if(!((key3 === "current") || (key3 === "max"))){const err22 = {instancePath:instancePath+"/major",schemaPath:"#/$defs/woundTier/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties",schema:false,parentSchema:schema36,data:data6};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}}if(data6.current !== undefined){let data7 = data6.current;if(!(((typeof data7 == "number") && (!(data7 % 1) && !isNaN(data7))) && (isFinite(data7)))){const err23 = {instancePath:instancePath+"/major/current",schemaPath:"#/$defs/woundTier/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.current.type,parentSchema:schema36.properties.current,data:data7};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}if((typeof data7 == "number") && (isFinite(data7))){if(data7 < 0 || isNaN(data7)){const err24 = {instancePath:instancePath+"/major/current",schemaPath:"#/$defs/woundTier/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.current,data:data7};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}}}if(data6.max !== undefined){let data8 = data6.max;if(!(((typeof data8 == "number") && (!(data8 % 1) && !isNaN(data8))) && (isFinite(data8)))){const err25 = {instancePath:instancePath+"/major/max",schemaPath:"#/$defs/woundTier/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.max.type,parentSchema:schema36.properties.max,data:data8};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}if((typeof data8 == "number") && (isFinite(data8))){if(data8 < 0 || isNaN(data8)){const err26 = {instancePath:instancePath+"/major/max",schemaPath:"#/$defs/woundTier/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.max,data:data8};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}}}}else {const err27 = {instancePath:instancePath+"/major",schemaPath:"#/$defs/woundTier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema36.type,parentSchema:schema36,data:data6};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}}}else {const err28 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema39.type,parentSchema:schema39,data};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}validate21.errors = vErrors;return errors === 0;}validate21.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false};const schema43 = {"type":"object","additionalProperties":false,"required":["name","rating","pool","asset","isProficiency","source","description"],"properties":{"name":{"type":"string","minLength":1},"rating":{"$ref":"#/$defs/skillRating"},"pool":{"anyOf":[{"$ref":"#/$defs/poolName"},{"type":"null"}]},"asset":{"enum":[0,1,2],"description":"ADDED (§3.5). Assets ease a task like training does but stack under different rules, so they cannot be folded into `rating`. v1 had no home for this and our Foundry export smuggles it into description text as \"Asset: x2.\". 0 when none."},"isProficiency":{"type":"boolean","description":"ADDED (§3.6). True for type/focus-granted weapon and armor proficiencies (\"Freely Use All Weapons\", \"Freely Use Light And Medium Armor\"). These are NOT trainable via advancement and should not render with a rating badge. In bross-drikess.json they appear as ordinary \"practiced\" skills, so a v1 importer will offer to advance them."},"source":{"type":"string"},"description":{"type":"string"}}};const schema44 = {"enum":["inability","practiced","trained","specialized","expert"]};const schema45 = {"enum":["might","speed","intellect"]};function validate23(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){let vErrors = null;let errors = 0;const evaluated0 = validate23.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.name === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "name"},message:"must have required property '"+"name"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.rating === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "rating"},message:"must have required property '"+"rating"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.pool === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "pool"},message:"must have required property '"+"pool"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.asset === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "asset"},message:"must have required property '"+"asset"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}if(data.isProficiency === undefined){const err4 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "isProficiency"},message:"must have required property '"+"isProficiency"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}if(data.source === undefined){const err5 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "source"},message:"must have required property '"+"source"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}if(data.description === undefined){const err6 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "description"},message:"must have required property '"+"description"+"'",schema:schema43.required,parentSchema:schema43,data};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}for(const key0 in data){if(!(((((((key0 === "name") || (key0 === "rating")) || (key0 === "pool")) || (key0 === "asset")) || (key0 === "isProficiency")) || (key0 === "source")) || (key0 === "description"))){const err7 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties",schema:false,parentSchema:schema43,data};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}}if(data.name !== undefined){let data0 = data.name;if(typeof data0 === "string"){if(func2(data0) < 1){const err8 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/minLength",keyword:"minLength",params:{limit: 1},message:"must NOT have fewer than 1 characters",schema:1,parentSchema:schema43.properties.name,data:data0};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}else {const err9 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema43.properties.name.type,parentSchema:schema43.properties.name,data:data0};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}}if(data.rating !== undefined){let data1 = data.rating;if(!(((((data1 === "inability") || (data1 === "practiced")) || (data1 === "trained")) || (data1 === "specialized")) || (data1 === "expert"))){const err10 = {instancePath:instancePath+"/rating",schemaPath:"#/$defs/skillRating/enum",keyword:"enum",params:{allowedValues: schema44.enum},message:"must be equal to one of the allowed values",schema:schema44.enum,parentSchema:schema44,data:data1};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}}if(data.pool !== undefined){let data2 = data.pool;const _errs7 = errors;let valid2 = false;const _errs8 = errors;if(!(((data2 === "might") || (data2 === "speed")) || (data2 === "intellect"))){const err11 = {instancePath:instancePath+"/pool",schemaPath:"#/$defs/poolName/enum",keyword:"enum",params:{allowedValues: schema45.enum},message:"must be equal to one of the allowed values",schema:schema45.enum,parentSchema:schema45,data:data2};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}var _valid0 = _errs8 === errors;valid2 = valid2 || _valid0;const _errs10 = errors;if(data2 !== null){const err12 = {instancePath:instancePath+"/pool",schemaPath:"#/properties/pool/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema43.properties.pool.anyOf[1].type,parentSchema:schema43.properties.pool.anyOf[1],data:data2};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}var _valid0 = _errs10 === errors;valid2 = valid2 || _valid0;if(!valid2){const err13 = {instancePath:instancePath+"/pool",schemaPath:"#/properties/pool/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema43.properties.pool.anyOf,parentSchema:schema43.properties.pool,data:data2};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}else {errors = _errs7;if(vErrors !== null){if(_errs7){vErrors.length = _errs7;}else {vErrors = null;}}}}if(data.asset !== undefined){let data3 = data.asset;if(!(((data3 === 0) || (data3 === 1)) || (data3 === 2))){const err14 = {instancePath:instancePath+"/asset",schemaPath:"#/properties/asset/enum",keyword:"enum",params:{allowedValues: schema43.properties.asset.enum},message:"must be equal to one of the allowed values",schema:schema43.properties.asset.enum,parentSchema:schema43.properties.asset,data:data3};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}}if(data.isProficiency !== undefined){let data4 = data.isProficiency;if(typeof data4 !== "boolean"){const err15 = {instancePath:instancePath+"/isProficiency",schemaPath:"#/properties/isProficiency/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema43.properties.isProficiency.type,parentSchema:schema43.properties.isProficiency,data:data4};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}}if(data.source !== undefined){let data5 = data.source;if(typeof data5 !== "string"){const err16 = {instancePath:instancePath+"/source",schemaPath:"#/properties/source/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema43.properties.source.type,parentSchema:schema43.properties.source,data:data5};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}}if(data.description !== undefined){let data6 = data.description;if(typeof data6 !== "string"){const err17 = {instancePath:instancePath+"/description",schemaPath:"#/properties/description/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema43.properties.description.type,parentSchema:schema43.properties.description,data:data6};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}}}else {const err18 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema43.type,parentSchema:schema43,data};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}validate23.errors = vErrors;return errors === 0;}validate23.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false};const schema46 = {"type":"object","additionalProperties":false,"required":["name","cost","pools","enabler","activation","source","description"],"properties":{"name":{"type":"string","minLength":1},"cost":{"description":"UNCHANGED from v1. null = no cost. variable: true means the cost is set in play (points MUST be null, plus MUST be false).","anyOf":[{"type":"object","additionalProperties":false,"required":["points","plus","variable"],"properties":{"points":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"plus":{"type":"boolean"},"variable":{"type":"boolean"}},"oneOf":[{"properties":{"variable":{"const":false},"points":{"type":"integer"}}},{"properties":{"variable":{"const":true},"points":{"type":"null"},"plus":{"const":false}}}]},{"type":"null"}]},"pools":{"type":"array","items":{"$ref":"#/$defs/poolName"},"uniqueItems":true,"maxItems":3},"enabler":{"type":"boolean","description":"UNCHANGED, and derivable from `activation` — kept so consumers that only need the binary distinction don't have to parse a string."},"activation":{"type":"string","description":"ADDED (§3.1). The ability's activation as printed, verbatim. `enabler` answers \"is this an enabler\" but discards WHEN IN THE ROUND the ability fires, which is what a VTT sheet needs for initiative-order UI. Across our 663-row catalog: \"Enabler\" (344), \"Action\" (143), \"Action to initiate\" (54), \"Last action\" (31), \"First action\" (8), plus ~25 long-form variants — e.g. \"Action when in your normal form; enabler when using Beast Form\", \"Ten minutes to prepare a cypher as a spell; action to cast a cypher as a spell\", \"First action, action, or Last action\". Deliberately a string and not an enum: the long-form tail is irreducible. \"\" when the source gives none."},"source":{"type":"string"},"description":{"type":"string"}}};const func0 = (__ajvRuntime1.default ?? __ajvRuntime1);function validate25(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){let vErrors = null;let errors = 0;const evaluated0 = validate25.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.name === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "name"},message:"must have required property '"+"name"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.cost === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "cost"},message:"must have required property '"+"cost"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.pools === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "pools"},message:"must have required property '"+"pools"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.enabler === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "enabler"},message:"must have required property '"+"enabler"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}if(data.activation === undefined){const err4 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "activation"},message:"must have required property '"+"activation"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}if(data.source === undefined){const err5 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "source"},message:"must have required property '"+"source"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}if(data.description === undefined){const err6 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "description"},message:"must have required property '"+"description"+"'",schema:schema46.required,parentSchema:schema46,data};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}for(const key0 in data){if(!(((((((key0 === "name") || (key0 === "cost")) || (key0 === "pools")) || (key0 === "enabler")) || (key0 === "activation")) || (key0 === "source")) || (key0 === "description"))){const err7 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties",schema:false,parentSchema:schema46,data};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}}if(data.name !== undefined){let data0 = data.name;if(typeof data0 === "string"){if(func2(data0) < 1){const err8 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/minLength",keyword:"minLength",params:{limit: 1},message:"must NOT have fewer than 1 characters",schema:1,parentSchema:schema46.properties.name,data:data0};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}else {const err9 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema46.properties.name.type,parentSchema:schema46.properties.name,data:data0};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}}if(data.cost !== undefined){let data1 = data.cost;const _errs5 = errors;let valid1 = false;const _errs6 = errors;const _errs8 = errors;let valid2 = false;let passing0 = null;const _errs9 = errors;if(data1 && typeof data1 == "object" && !Array.isArray(data1)){if(data1.variable !== undefined){let data2 = data1.variable;if(false !== data2){const err10 = {instancePath:instancePath+"/cost/variable",schemaPath:"#/properties/cost/anyOf/0/oneOf/0/properties/variable/const",keyword:"const",params:{allowedValue: false},message:"must be equal to constant",schema:false,parentSchema:schema46.properties.cost.anyOf[0].oneOf[0].properties.variable,data:data2};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}}if(data1.points !== undefined){let data3 = data1.points;if(!(((typeof data3 == "number") && (!(data3 % 1) && !isNaN(data3))) && (isFinite(data3)))){const err11 = {instancePath:instancePath+"/cost/points",schemaPath:"#/properties/cost/anyOf/0/oneOf/0/properties/points/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema46.properties.cost.anyOf[0].oneOf[0].properties.points.type,parentSchema:schema46.properties.cost.anyOf[0].oneOf[0].properties.points,data:data3};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}}var _valid1 = _errs9 === errors;if(_valid1){valid2 = true;passing0 = 0;var props0 = {};props0.variable = true;props0.points = true;}const _errs13 = errors;if(data1 && typeof data1 == "object" && !Array.isArray(data1)){if(data1.variable !== undefined){let data4 = data1.variable;if(true !== data4){const err12 = {instancePath:instancePath+"/cost/variable",schemaPath:"#/properties/cost/anyOf/0/oneOf/1/properties/variable/const",keyword:"const",params:{allowedValue: true},message:"must be equal to constant",schema:true,parentSchema:schema46.properties.cost.anyOf[0].oneOf[1].properties.variable,data:data4};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}}if(data1.points !== undefined){let data5 = data1.points;if(data5 !== null){const err13 = {instancePath:instancePath+"/cost/points",schemaPath:"#/properties/cost/anyOf/0/oneOf/1/properties/points/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema46.properties.cost.anyOf[0].oneOf[1].properties.points.type,parentSchema:schema46.properties.cost.anyOf[0].oneOf[1].properties.points,data:data5};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}}if(data1.plus !== undefined){let data6 = data1.plus;if(false !== data6){const err14 = {instancePath:instancePath+"/cost/plus",schemaPath:"#/properties/cost/anyOf/0/oneOf/1/properties/plus/const",keyword:"const",params:{allowedValue: false},message:"must be equal to constant",schema:false,parentSchema:schema46.properties.cost.anyOf[0].oneOf[1].properties.plus,data:data6};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}}}var _valid1 = _errs13 === errors;if(_valid1 && valid2){valid2 = false;passing0 = [passing0, 1];}else {if(_valid1){valid2 = true;passing0 = 1;if(props0 !== true){props0 = props0 || {};props0.variable = true;props0.points = true;props0.plus = true;}}}if(!valid2){const err15 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/0/oneOf",keyword:"oneOf",params:{passingSchemas: passing0},message:"must match exactly one schema in oneOf",schema:schema46.properties.cost.anyOf[0].oneOf,parentSchema:schema46.properties.cost.anyOf[0],data:data1};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}else {errors = _errs8;if(vErrors !== null){if(_errs8){vErrors.length = _errs8;}else {vErrors = null;}}}if(data1 && typeof data1 == "object" && !Array.isArray(data1)){if(data1.points === undefined){const err16 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/0/required",keyword:"required",params:{missingProperty: "points"},message:"must have required property '"+"points"+"'",schema:schema46.properties.cost.anyOf[0].required,parentSchema:schema46.properties.cost.anyOf[0],data:data1};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}if(data1.plus === undefined){const err17 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/0/required",keyword:"required",params:{missingProperty: "plus"},message:"must have required property '"+"plus"+"'",schema:schema46.properties.cost.anyOf[0].required,parentSchema:schema46.properties.cost.anyOf[0],data:data1};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}if(data1.variable === undefined){const err18 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/0/required",keyword:"required",params:{missingProperty: "variable"},message:"must have required property '"+"variable"+"'",schema:schema46.properties.cost.anyOf[0].required,parentSchema:schema46.properties.cost.anyOf[0],data:data1};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}for(const key1 in data1){if(!(((key1 === "points") || (key1 === "plus")) || (key1 === "variable"))){const err19 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/0/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties",schema:false,parentSchema:schema46.properties.cost.anyOf[0],data:data1};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}}if(data1.points !== undefined){let data7 = data1.points;const _errs20 = errors;let valid6 = false;const _errs21 = errors;if(!(((typeof data7 == "number") && (!(data7 % 1) && !isNaN(data7))) && (isFinite(data7)))){const err20 = {instancePath:instancePath+"/cost/points",schemaPath:"#/properties/cost/anyOf/0/properties/points/anyOf/0/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema46.properties.cost.anyOf[0].properties.points.anyOf[0].type,parentSchema:schema46.properties.cost.anyOf[0].properties.points.anyOf[0],data:data7};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}if((typeof data7 == "number") && (isFinite(data7))){if(data7 < 0 || isNaN(data7)){const err21 = {instancePath:instancePath+"/cost/points",schemaPath:"#/properties/cost/anyOf/0/properties/points/anyOf/0/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema46.properties.cost.anyOf[0].properties.points.anyOf[0],data:data7};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}}var _valid2 = _errs21 === errors;valid6 = valid6 || _valid2;const _errs23 = errors;if(data7 !== null){const err22 = {instancePath:instancePath+"/cost/points",schemaPath:"#/properties/cost/anyOf/0/properties/points/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema46.properties.cost.anyOf[0].properties.points.anyOf[1].type,parentSchema:schema46.properties.cost.anyOf[0].properties.points.anyOf[1],data:data7};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}var _valid2 = _errs23 === errors;valid6 = valid6 || _valid2;if(!valid6){const err23 = {instancePath:instancePath+"/cost/points",schemaPath:"#/properties/cost/anyOf/0/properties/points/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema46.properties.cost.anyOf[0].properties.points.anyOf,parentSchema:schema46.properties.cost.anyOf[0].properties.points,data:data7};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}else {errors = _errs20;if(vErrors !== null){if(_errs20){vErrors.length = _errs20;}else {vErrors = null;}}}}if(data1.plus !== undefined){let data8 = data1.plus;if(typeof data8 !== "boolean"){const err24 = {instancePath:instancePath+"/cost/plus",schemaPath:"#/properties/cost/anyOf/0/properties/plus/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema46.properties.cost.anyOf[0].properties.plus.type,parentSchema:schema46.properties.cost.anyOf[0].properties.plus,data:data8};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}}if(data1.variable !== undefined){let data9 = data1.variable;if(typeof data9 !== "boolean"){const err25 = {instancePath:instancePath+"/cost/variable",schemaPath:"#/properties/cost/anyOf/0/properties/variable/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema46.properties.cost.anyOf[0].properties.variable.type,parentSchema:schema46.properties.cost.anyOf[0].properties.variable,data:data9};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}}}else {const err26 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/0/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema46.properties.cost.anyOf[0].type,parentSchema:schema46.properties.cost.anyOf[0],data:data1};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}var _valid0 = _errs6 === errors;valid1 = valid1 || _valid0;const _errs29 = errors;if(data1 !== null){const err27 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema46.properties.cost.anyOf[1].type,parentSchema:schema46.properties.cost.anyOf[1],data:data1};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}var _valid0 = _errs29 === errors;valid1 = valid1 || _valid0;if(!valid1){const err28 = {instancePath:instancePath+"/cost",schemaPath:"#/properties/cost/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema46.properties.cost.anyOf,parentSchema:schema46.properties.cost,data:data1};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}else {errors = _errs5;if(vErrors !== null){if(_errs5){vErrors.length = _errs5;}else {vErrors = null;}}}}if(data.pools !== undefined){let data10 = data.pools;if(Array.isArray(data10)){if(data10.length > 3){const err29 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/maxItems",keyword:"maxItems",params:{limit: 3},message:"must NOT have more than 3 items",schema:3,parentSchema:schema46.properties.pools,data:data10};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}const len0 = data10.length;for(let i0=0; i0 1){outer0:for(;i1--;){for(j0 = i1; j0--;){if(func0(data10[i1], data10[j0])){const err31 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/uniqueItems",keyword:"uniqueItems",params:{i: i1, j: j0},message:"must NOT have duplicate items (items ## "+j0+" and "+i1+" are identical)",schema:true,parentSchema:schema46.properties.pools,data:data10};if(vErrors === null){vErrors = [err31];}else {vErrors.push(err31);}errors++;break outer0;}}}}}else {const err32 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema46.properties.pools.type,parentSchema:schema46.properties.pools,data:data10};if(vErrors === null){vErrors = [err32];}else {vErrors.push(err32);}errors++;}}if(data.enabler !== undefined){let data12 = data.enabler;if(typeof data12 !== "boolean"){const err33 = {instancePath:instancePath+"/enabler",schemaPath:"#/properties/enabler/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema46.properties.enabler.type,parentSchema:schema46.properties.enabler,data:data12};if(vErrors === null){vErrors = [err33];}else {vErrors.push(err33);}errors++;}}if(data.activation !== undefined){let data13 = data.activation;if(typeof data13 !== "string"){const err34 = {instancePath:instancePath+"/activation",schemaPath:"#/properties/activation/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema46.properties.activation.type,parentSchema:schema46.properties.activation,data:data13};if(vErrors === null){vErrors = [err34];}else {vErrors.push(err34);}errors++;}}if(data.source !== undefined){let data14 = data.source;if(typeof data14 !== "string"){const err35 = {instancePath:instancePath+"/source",schemaPath:"#/properties/source/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema46.properties.source.type,parentSchema:schema46.properties.source,data:data14};if(vErrors === null){vErrors = [err35];}else {vErrors.push(err35);}errors++;}}if(data.description !== undefined){let data15 = data.description;if(typeof data15 !== "string"){const err36 = {instancePath:instancePath+"/description",schemaPath:"#/properties/description/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema46.properties.description.type,parentSchema:schema46.properties.description,data:data15};if(vErrors === null){vErrors = [err36];}else {vErrors.push(err36);}errors++;}}}else {const err37 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema46.type,parentSchema:schema46,data};if(vErrors === null){vErrors = [err37];}else {vErrors.push(err37);}errors++;}validate25.errors = vErrors;return errors === 0;}validate25.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false};const schema48 = {"type":"object","additionalProperties":false,"required":["name","pool","weaponClass","damage","skillRating","range","modifier","notes"],"properties":{"name":{"type":"string","minLength":1},"pool":{"$ref":"#/$defs/poolName"},"weaponClass":{"anyOf":[{"enum":["light","medium","heavy"]},{"type":"null"}]},"damage":{"type":"integer","minimum":0},"skillRating":{"$ref":"#/$defs/skillRating"},"range":{"anyOf":[{"$ref":"#/$defs/weaponRange"},{"type":"null"}],"description":"ADDED (§3.2). Note our EXISTING Foundry export already carries this as system.basic.range, so v1 is a regression against what Roll20 users get today by importing the Foundry file. null when unspecified (treat as immediate)."},"modifier":{"anyOf":[{"$ref":"#/$defs/attackModifier"},{"type":"null"}],"description":"ADDED (§3.3). A standing ease/hinder on this attack. Also already in the Foundry export as system.basic.steps + modifier. null when the attack is unmodified."},"notes":{"type":"string"}}};const schema51 = {"enum":["immediate","short","long","veryLong","special"],"description":"ADDED (§3.2)."};const schema52 = {"type":"object","additionalProperties":false,"required":["steps","direction"],"properties":{"steps":{"type":"integer","minimum":1},"direction":{"enum":["eased","hindered"]}}};function validate27(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){let vErrors = null;let errors = 0;const evaluated0 = validate27.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.name === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "name"},message:"must have required property '"+"name"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.pool === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "pool"},message:"must have required property '"+"pool"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.weaponClass === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "weaponClass"},message:"must have required property '"+"weaponClass"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.damage === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "damage"},message:"must have required property '"+"damage"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}if(data.skillRating === undefined){const err4 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "skillRating"},message:"must have required property '"+"skillRating"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}if(data.range === undefined){const err5 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "range"},message:"must have required property '"+"range"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}if(data.modifier === undefined){const err6 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "modifier"},message:"must have required property '"+"modifier"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}if(data.notes === undefined){const err7 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "notes"},message:"must have required property '"+"notes"+"'",schema:schema48.required,parentSchema:schema48,data};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}for(const key0 in data){if(!((((((((key0 === "name") || (key0 === "pool")) || (key0 === "weaponClass")) || (key0 === "damage")) || (key0 === "skillRating")) || (key0 === "range")) || (key0 === "modifier")) || (key0 === "notes"))){const err8 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties",schema:false,parentSchema:schema48,data};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}if(data.name !== undefined){let data0 = data.name;if(typeof data0 === "string"){if(func2(data0) < 1){const err9 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/minLength",keyword:"minLength",params:{limit: 1},message:"must NOT have fewer than 1 characters",schema:1,parentSchema:schema48.properties.name,data:data0};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}}else {const err10 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema48.properties.name.type,parentSchema:schema48.properties.name,data:data0};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}}if(data.pool !== undefined){let data1 = data.pool;if(!(((data1 === "might") || (data1 === "speed")) || (data1 === "intellect"))){const err11 = {instancePath:instancePath+"/pool",schemaPath:"#/$defs/poolName/enum",keyword:"enum",params:{allowedValues: schema45.enum},message:"must be equal to one of the allowed values",schema:schema45.enum,parentSchema:schema45,data:data1};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}if(data.weaponClass !== undefined){let data2 = data.weaponClass;const _errs7 = errors;let valid2 = false;const _errs8 = errors;if(!(((data2 === "light") || (data2 === "medium")) || (data2 === "heavy"))){const err12 = {instancePath:instancePath+"/weaponClass",schemaPath:"#/properties/weaponClass/anyOf/0/enum",keyword:"enum",params:{allowedValues: schema48.properties.weaponClass.anyOf[0].enum},message:"must be equal to one of the allowed values",schema:schema48.properties.weaponClass.anyOf[0].enum,parentSchema:schema48.properties.weaponClass.anyOf[0],data:data2};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}var _valid0 = _errs8 === errors;valid2 = valid2 || _valid0;const _errs9 = errors;if(data2 !== null){const err13 = {instancePath:instancePath+"/weaponClass",schemaPath:"#/properties/weaponClass/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema48.properties.weaponClass.anyOf[1].type,parentSchema:schema48.properties.weaponClass.anyOf[1],data:data2};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}var _valid0 = _errs9 === errors;valid2 = valid2 || _valid0;if(!valid2){const err14 = {instancePath:instancePath+"/weaponClass",schemaPath:"#/properties/weaponClass/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema48.properties.weaponClass.anyOf,parentSchema:schema48.properties.weaponClass,data:data2};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}else {errors = _errs7;if(vErrors !== null){if(_errs7){vErrors.length = _errs7;}else {vErrors = null;}}}}if(data.damage !== undefined){let data3 = data.damage;if(!(((typeof data3 == "number") && (!(data3 % 1) && !isNaN(data3))) && (isFinite(data3)))){const err15 = {instancePath:instancePath+"/damage",schemaPath:"#/properties/damage/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema48.properties.damage.type,parentSchema:schema48.properties.damage,data:data3};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}if((typeof data3 == "number") && (isFinite(data3))){if(data3 < 0 || isNaN(data3)){const err16 = {instancePath:instancePath+"/damage",schemaPath:"#/properties/damage/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema48.properties.damage,data:data3};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}}}if(data.skillRating !== undefined){let data4 = data.skillRating;if(!(((((data4 === "inability") || (data4 === "practiced")) || (data4 === "trained")) || (data4 === "specialized")) || (data4 === "expert"))){const err17 = {instancePath:instancePath+"/skillRating",schemaPath:"#/$defs/skillRating/enum",keyword:"enum",params:{allowedValues: schema44.enum},message:"must be equal to one of the allowed values",schema:schema44.enum,parentSchema:schema44,data:data4};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}}if(data.range !== undefined){let data5 = data.range;const _errs16 = errors;let valid4 = false;const _errs17 = errors;if(!(((((data5 === "immediate") || (data5 === "short")) || (data5 === "long")) || (data5 === "veryLong")) || (data5 === "special"))){const err18 = {instancePath:instancePath+"/range",schemaPath:"#/$defs/weaponRange/enum",keyword:"enum",params:{allowedValues: schema51.enum},message:"must be equal to one of the allowed values",schema:schema51.enum,parentSchema:schema51,data:data5};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}var _valid1 = _errs17 === errors;valid4 = valid4 || _valid1;const _errs19 = errors;if(data5 !== null){const err19 = {instancePath:instancePath+"/range",schemaPath:"#/properties/range/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema48.properties.range.anyOf[1].type,parentSchema:schema48.properties.range.anyOf[1],data:data5};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}var _valid1 = _errs19 === errors;valid4 = valid4 || _valid1;if(!valid4){const err20 = {instancePath:instancePath+"/range",schemaPath:"#/properties/range/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema48.properties.range.anyOf,parentSchema:schema48.properties.range,data:data5};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}else {errors = _errs16;if(vErrors !== null){if(_errs16){vErrors.length = _errs16;}else {vErrors = null;}}}}if(data.modifier !== undefined){let data6 = data.modifier;const _errs22 = errors;let valid6 = false;const _errs23 = errors;if(data6 && typeof data6 == "object" && !Array.isArray(data6)){if(data6.steps === undefined){const err21 = {instancePath:instancePath+"/modifier",schemaPath:"#/$defs/attackModifier/required",keyword:"required",params:{missingProperty: "steps"},message:"must have required property '"+"steps"+"'",schema:schema52.required,parentSchema:schema52,data:data6};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}if(data6.direction === undefined){const err22 = {instancePath:instancePath+"/modifier",schemaPath:"#/$defs/attackModifier/required",keyword:"required",params:{missingProperty: "direction"},message:"must have required property '"+"direction"+"'",schema:schema52.required,parentSchema:schema52,data:data6};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}for(const key1 in data6){if(!((key1 === "steps") || (key1 === "direction"))){const err23 = {instancePath:instancePath+"/modifier",schemaPath:"#/$defs/attackModifier/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties",schema:false,parentSchema:schema52,data:data6};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}}if(data6.steps !== undefined){let data7 = data6.steps;if(!(((typeof data7 == "number") && (!(data7 % 1) && !isNaN(data7))) && (isFinite(data7)))){const err24 = {instancePath:instancePath+"/modifier/steps",schemaPath:"#/$defs/attackModifier/properties/steps/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema52.properties.steps.type,parentSchema:schema52.properties.steps,data:data7};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}if((typeof data7 == "number") && (isFinite(data7))){if(data7 < 1 || isNaN(data7)){const err25 = {instancePath:instancePath+"/modifier/steps",schemaPath:"#/$defs/attackModifier/properties/steps/minimum",keyword:"minimum",params:{comparison: ">=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema52.properties.steps,data:data7};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}}}if(data6.direction !== undefined){let data8 = data6.direction;if(!((data8 === "eased") || (data8 === "hindered"))){const err26 = {instancePath:instancePath+"/modifier/direction",schemaPath:"#/$defs/attackModifier/properties/direction/enum",keyword:"enum",params:{allowedValues: schema52.properties.direction.enum},message:"must be equal to one of the allowed values",schema:schema52.properties.direction.enum,parentSchema:schema52.properties.direction,data:data8};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}}}else {const err27 = {instancePath:instancePath+"/modifier",schemaPath:"#/$defs/attackModifier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema52.type,parentSchema:schema52,data:data6};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}var _valid2 = _errs23 === errors;valid6 = valid6 || _valid2;const _errs30 = errors;if(data6 !== null){const err28 = {instancePath:instancePath+"/modifier",schemaPath:"#/properties/modifier/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema48.properties.modifier.anyOf[1].type,parentSchema:schema48.properties.modifier.anyOf[1],data:data6};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}var _valid2 = _errs30 === errors;valid6 = valid6 || _valid2;if(!valid6){const err29 = {instancePath:instancePath+"/modifier",schemaPath:"#/properties/modifier/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema48.properties.modifier.anyOf,parentSchema:schema48.properties.modifier,data:data6};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}else {errors = _errs22;if(vErrors !== null){if(_errs22){vErrors.length = _errs22;}else {vErrors = null;}}}}if(data.notes !== undefined){let data9 = data.notes;if(typeof data9 !== "string"){const err30 = {instancePath:instancePath+"/notes",schemaPath:"#/properties/notes/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema48.properties.notes.type,parentSchema:schema48.properties.notes,data:data9};if(vErrors === null){vErrors = [err30];}else {vErrors.push(err30);}errors++;}}}else {const err31 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema48.type,parentSchema:schema48,data};if(vErrors === null){vErrors = [err31];}else {vErrors.push(err31);}errors++;}validate27.errors = vErrors;return errors === 0;}validate27.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false};const schema58 = {"type":"object","additionalProperties":false,"required":["name","description","steps"],"properties":{"name":{"type":"string","minLength":1},"description":{"type":"string"},"steps":{"type":"array","items":{"$ref":"#/$defs/arcStep"}}}};const schema59 = {"type":"object","additionalProperties":false,"required":["name","completed"],"properties":{"name":{"type":"string","minLength":1},"completed":{"type":"boolean"}}};function validate29(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){let vErrors = null;let errors = 0;const evaluated0 = validate29.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.name === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "name"},message:"must have required property '"+"name"+"'",schema:schema58.required,parentSchema:schema58,data};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.description === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "description"},message:"must have required property '"+"description"+"'",schema:schema58.required,parentSchema:schema58,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.steps === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "steps"},message:"must have required property '"+"steps"+"'",schema:schema58.required,parentSchema:schema58,data};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}for(const key0 in data){if(!(((key0 === "name") || (key0 === "description")) || (key0 === "steps"))){const err3 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties",schema:false,parentSchema:schema58,data};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}}if(data.name !== undefined){let data0 = data.name;if(typeof data0 === "string"){if(func2(data0) < 1){const err4 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/minLength",keyword:"minLength",params:{limit: 1},message:"must NOT have fewer than 1 characters",schema:1,parentSchema:schema58.properties.name,data:data0};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}else {const err5 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema58.properties.name.type,parentSchema:schema58.properties.name,data:data0};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}}if(data.description !== undefined){let data1 = data.description;if(typeof data1 !== "string"){const err6 = {instancePath:instancePath+"/description",schemaPath:"#/properties/description/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema58.properties.description.type,parentSchema:schema58.properties.description,data:data1};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}}if(data.steps !== undefined){let data2 = data.steps;if(Array.isArray(data2)){const len0 = data2.length;for(let i0=0; i0=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema31.properties.tier,data:data10};if(vErrors === null){vErrors = [err52];}else {vErrors.push(err52);}errors++;}}}if(data.effort !== undefined){let data11 = data.effort;if(!(((typeof data11 == "number") && (!(data11 % 1) && !isNaN(data11))) && (isFinite(data11)))){const err53 = {instancePath:instancePath+"/effort",schemaPath:"#/properties/effort/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.effort.type,parentSchema:schema31.properties.effort,data:data11};if(vErrors === null){vErrors = [err53];}else {vErrors.push(err53);}errors++;}if((typeof data11 == "number") && (isFinite(data11))){if(data11 < 1 || isNaN(data11)){const err54 = {instancePath:instancePath+"/effort",schemaPath:"#/properties/effort/minimum",keyword:"minimum",params:{comparison: ">=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema31.properties.effort,data:data11};if(vErrors === null){vErrors = [err54];}else {vErrors.push(err54);}errors++;}}}if(data.xp !== undefined){let data12 = data.xp;if(!(((typeof data12 == "number") && (!(data12 % 1) && !isNaN(data12))) && (isFinite(data12)))){const err55 = {instancePath:instancePath+"/xp",schemaPath:"#/properties/xp/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.xp.type,parentSchema:schema31.properties.xp,data:data12};if(vErrors === null){vErrors = [err55];}else {vErrors.push(err55);}errors++;}if((typeof data12 == "number") && (isFinite(data12))){if(data12 < 0 || isNaN(data12)){const err56 = {instancePath:instancePath+"/xp",schemaPath:"#/properties/xp/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema31.properties.xp,data:data12};if(vErrors === null){vErrors = [err56];}else {vErrors.push(err56);}errors++;}}}if(data.storyXp !== undefined){let data13 = data.storyXp;if(!(((typeof data13 == "number") && (!(data13 % 1) && !isNaN(data13))) && (isFinite(data13)))){const err57 = {instancePath:instancePath+"/storyXp",schemaPath:"#/properties/storyXp/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.storyXp.type,parentSchema:schema31.properties.storyXp,data:data13};if(vErrors === null){vErrors = [err57];}else {vErrors.push(err57);}errors++;}if((typeof data13 == "number") && (isFinite(data13))){if(data13 < 0 || isNaN(data13)){const err58 = {instancePath:instancePath+"/storyXp",schemaPath:"#/properties/storyXp/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema31.properties.storyXp,data:data13};if(vErrors === null){vErrors = [err58];}else {vErrors.push(err58);}errors++;}}}if(data.resourcePoints !== undefined){let data14 = data.resourcePoints;if(!(((typeof data14 == "number") && (!(data14 % 1) && !isNaN(data14))) && (isFinite(data14)))){const err59 = {instancePath:instancePath+"/resourcePoints",schemaPath:"#/properties/resourcePoints/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.resourcePoints.type,parentSchema:schema31.properties.resourcePoints,data:data14};if(vErrors === null){vErrors = [err59];}else {vErrors.push(err59);}errors++;}if((typeof data14 == "number") && (isFinite(data14))){if(data14 < 0 || isNaN(data14)){const err60 = {instancePath:instancePath+"/resourcePoints",schemaPath:"#/properties/resourcePoints/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema31.properties.resourcePoints,data:data14};if(vErrors === null){vErrors = [err60];}else {vErrors.push(err60);}errors++;}}}if(data.rank !== undefined){let data15 = data.rank;const _errs32 = errors;let valid2 = false;const _errs33 = errors;if(!(((typeof data15 == "number") && (!(data15 % 1) && !isNaN(data15))) && (isFinite(data15)))){const err61 = {instancePath:instancePath+"/rank",schemaPath:"#/properties/rank/anyOf/0/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.rank.anyOf[0].type,parentSchema:schema31.properties.rank.anyOf[0],data:data15};if(vErrors === null){vErrors = [err61];}else {vErrors.push(err61);}errors++;}if((typeof data15 == "number") && (isFinite(data15))){if(data15 > 5 || isNaN(data15)){const err62 = {instancePath:instancePath+"/rank",schemaPath:"#/properties/rank/anyOf/0/maximum",keyword:"maximum",params:{comparison: "<=", limit: 5},message:"must be <= 5",schema:5,parentSchema:schema31.properties.rank.anyOf[0],data:data15};if(vErrors === null){vErrors = [err62];}else {vErrors.push(err62);}errors++;}if(data15 < 1 || isNaN(data15)){const err63 = {instancePath:instancePath+"/rank",schemaPath:"#/properties/rank/anyOf/0/minimum",keyword:"minimum",params:{comparison: ">=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema31.properties.rank.anyOf[0],data:data15};if(vErrors === null){vErrors = [err63];}else {vErrors.push(err63);}errors++;}}var _valid0 = _errs33 === errors;valid2 = valid2 || _valid0;const _errs35 = errors;if(data15 !== null){const err64 = {instancePath:instancePath+"/rank",schemaPath:"#/properties/rank/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema31.properties.rank.anyOf[1].type,parentSchema:schema31.properties.rank.anyOf[1],data:data15};if(vErrors === null){vErrors = [err64];}else {vErrors.push(err64);}errors++;}var _valid0 = _errs35 === errors;valid2 = valid2 || _valid0;if(!valid2){const err65 = {instancePath:instancePath+"/rank",schemaPath:"#/properties/rank/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema31.properties.rank.anyOf,parentSchema:schema31.properties.rank,data:data15};if(vErrors === null){vErrors = [err65];}else {vErrors.push(err65);}errors++;}else {errors = _errs32;if(vErrors !== null){if(_errs32){vErrors.length = _errs32;}else {vErrors = null;}}}}if(data.advancement !== undefined){let data16 = data.advancement;if(data16 && typeof data16 == "object" && !Array.isArray(data16)){if(data16.stats === undefined){const err66 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/required",keyword:"required",params:{missingProperty: "stats"},message:"must have required property '"+"stats"+"'",schema:schema31.properties.advancement.required,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err66];}else {vErrors.push(err66);}errors++;}if(data16.effort === undefined){const err67 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/required",keyword:"required",params:{missingProperty: "effort"},message:"must have required property '"+"effort"+"'",schema:schema31.properties.advancement.required,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err67];}else {vErrors.push(err67);}errors++;}if(data16.edge === undefined){const err68 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/required",keyword:"required",params:{missingProperty: "edge"},message:"must have required property '"+"edge"+"'",schema:schema31.properties.advancement.required,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err68];}else {vErrors.push(err68);}errors++;}if(data16.skill === undefined){const err69 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/required",keyword:"required",params:{missingProperty: "skill"},message:"must have required property '"+"skill"+"'",schema:schema31.properties.advancement.required,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err69];}else {vErrors.push(err69);}errors++;}if(data16.other === undefined){const err70 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/required",keyword:"required",params:{missingProperty: "other"},message:"must have required property '"+"other"+"'",schema:schema31.properties.advancement.required,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err70];}else {vErrors.push(err70);}errors++;}for(const key2 in data16){if(!(((((key2 === "stats") || (key2 === "effort")) || (key2 === "edge")) || (key2 === "skill")) || (key2 === "other"))){const err71 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties",schema:false,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err71];}else {vErrors.push(err71);}errors++;}}if(data16.stats !== undefined){let data17 = data16.stats;if(typeof data17 !== "boolean"){const err72 = {instancePath:instancePath+"/advancement/stats",schemaPath:"#/properties/advancement/properties/stats/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema31.properties.advancement.properties.stats.type,parentSchema:schema31.properties.advancement.properties.stats,data:data17};if(vErrors === null){vErrors = [err72];}else {vErrors.push(err72);}errors++;}}if(data16.effort !== undefined){let data18 = data16.effort;if(typeof data18 !== "boolean"){const err73 = {instancePath:instancePath+"/advancement/effort",schemaPath:"#/properties/advancement/properties/effort/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema31.properties.advancement.properties.effort.type,parentSchema:schema31.properties.advancement.properties.effort,data:data18};if(vErrors === null){vErrors = [err73];}else {vErrors.push(err73);}errors++;}}if(data16.edge !== undefined){let data19 = data16.edge;if(typeof data19 !== "boolean"){const err74 = {instancePath:instancePath+"/advancement/edge",schemaPath:"#/properties/advancement/properties/edge/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema31.properties.advancement.properties.edge.type,parentSchema:schema31.properties.advancement.properties.edge,data:data19};if(vErrors === null){vErrors = [err74];}else {vErrors.push(err74);}errors++;}}if(data16.skill !== undefined){let data20 = data16.skill;if(typeof data20 !== "boolean"){const err75 = {instancePath:instancePath+"/advancement/skill",schemaPath:"#/properties/advancement/properties/skill/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema31.properties.advancement.properties.skill.type,parentSchema:schema31.properties.advancement.properties.skill,data:data20};if(vErrors === null){vErrors = [err75];}else {vErrors.push(err75);}errors++;}}if(data16.other !== undefined){let data21 = data16.other;if(typeof data21 !== "boolean"){const err76 = {instancePath:instancePath+"/advancement/other",schemaPath:"#/properties/advancement/properties/other/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema31.properties.advancement.properties.other.type,parentSchema:schema31.properties.advancement.properties.other,data:data21};if(vErrors === null){vErrors = [err76];}else {vErrors.push(err76);}errors++;}}}else {const err77 = {instancePath:instancePath+"/advancement",schemaPath:"#/properties/advancement/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.advancement.type,parentSchema:schema31.properties.advancement,data:data16};if(vErrors === null){vErrors = [err77];}else {vErrors.push(err77);}errors++;}}if(data.pools !== undefined){let data22 = data.pools;if(data22 && typeof data22 == "object" && !Array.isArray(data22)){if(data22.might === undefined){const err78 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/required",keyword:"required",params:{missingProperty: "might"},message:"must have required property '"+"might"+"'",schema:schema31.properties.pools.required,parentSchema:schema31.properties.pools,data:data22};if(vErrors === null){vErrors = [err78];}else {vErrors.push(err78);}errors++;}if(data22.speed === undefined){const err79 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/required",keyword:"required",params:{missingProperty: "speed"},message:"must have required property '"+"speed"+"'",schema:schema31.properties.pools.required,parentSchema:schema31.properties.pools,data:data22};if(vErrors === null){vErrors = [err79];}else {vErrors.push(err79);}errors++;}if(data22.intellect === undefined){const err80 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/required",keyword:"required",params:{missingProperty: "intellect"},message:"must have required property '"+"intellect"+"'",schema:schema31.properties.pools.required,parentSchema:schema31.properties.pools,data:data22};if(vErrors === null){vErrors = [err80];}else {vErrors.push(err80);}errors++;}for(const key3 in data22){if(!(((key3 === "might") || (key3 === "speed")) || (key3 === "intellect"))){const err81 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties",schema:false,parentSchema:schema31.properties.pools,data:data22};if(vErrors === null){vErrors = [err81];}else {vErrors.push(err81);}errors++;}}if(data22.might !== undefined){let data23 = data22.might;if(data23 && typeof data23 == "object" && !Array.isArray(data23)){if(data23.current === undefined){const err82 = {instancePath:instancePath+"/pools/might",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema32.required,parentSchema:schema32,data:data23};if(vErrors === null){vErrors = [err82];}else {vErrors.push(err82);}errors++;}if(data23.max === undefined){const err83 = {instancePath:instancePath+"/pools/might",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema32.required,parentSchema:schema32,data:data23};if(vErrors === null){vErrors = [err83];}else {vErrors.push(err83);}errors++;}if(data23.edge === undefined){const err84 = {instancePath:instancePath+"/pools/might",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "edge"},message:"must have required property '"+"edge"+"'",schema:schema32.required,parentSchema:schema32,data:data23};if(vErrors === null){vErrors = [err84];}else {vErrors.push(err84);}errors++;}for(const key4 in data23){if(!(((key4 === "current") || (key4 === "max")) || (key4 === "edge"))){const err85 = {instancePath:instancePath+"/pools/might",schemaPath:"#/$defs/pool/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key4},message:"must NOT have additional properties",schema:false,parentSchema:schema32,data:data23};if(vErrors === null){vErrors = [err85];}else {vErrors.push(err85);}errors++;}}if(data23.current !== undefined){let data24 = data23.current;if(!(((typeof data24 == "number") && (!(data24 % 1) && !isNaN(data24))) && (isFinite(data24)))){const err86 = {instancePath:instancePath+"/pools/might/current",schemaPath:"#/$defs/pool/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.current.type,parentSchema:schema32.properties.current,data:data24};if(vErrors === null){vErrors = [err86];}else {vErrors.push(err86);}errors++;}if((typeof data24 == "number") && (isFinite(data24))){if(data24 < 0 || isNaN(data24)){const err87 = {instancePath:instancePath+"/pools/might/current",schemaPath:"#/$defs/pool/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.current,data:data24};if(vErrors === null){vErrors = [err87];}else {vErrors.push(err87);}errors++;}}}if(data23.max !== undefined){let data25 = data23.max;if(!(((typeof data25 == "number") && (!(data25 % 1) && !isNaN(data25))) && (isFinite(data25)))){const err88 = {instancePath:instancePath+"/pools/might/max",schemaPath:"#/$defs/pool/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.max.type,parentSchema:schema32.properties.max,data:data25};if(vErrors === null){vErrors = [err88];}else {vErrors.push(err88);}errors++;}if((typeof data25 == "number") && (isFinite(data25))){if(data25 < 0 || isNaN(data25)){const err89 = {instancePath:instancePath+"/pools/might/max",schemaPath:"#/$defs/pool/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.max,data:data25};if(vErrors === null){vErrors = [err89];}else {vErrors.push(err89);}errors++;}}}if(data23.edge !== undefined){let data26 = data23.edge;if(!(((typeof data26 == "number") && (!(data26 % 1) && !isNaN(data26))) && (isFinite(data26)))){const err90 = {instancePath:instancePath+"/pools/might/edge",schemaPath:"#/$defs/pool/properties/edge/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.edge.type,parentSchema:schema32.properties.edge,data:data26};if(vErrors === null){vErrors = [err90];}else {vErrors.push(err90);}errors++;}if((typeof data26 == "number") && (isFinite(data26))){if(data26 < 0 || isNaN(data26)){const err91 = {instancePath:instancePath+"/pools/might/edge",schemaPath:"#/$defs/pool/properties/edge/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.edge,data:data26};if(vErrors === null){vErrors = [err91];}else {vErrors.push(err91);}errors++;}}}}else {const err92 = {instancePath:instancePath+"/pools/might",schemaPath:"#/$defs/pool/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema32.type,parentSchema:schema32,data:data23};if(vErrors === null){vErrors = [err92];}else {vErrors.push(err92);}errors++;}}if(data22.speed !== undefined){let data27 = data22.speed;if(data27 && typeof data27 == "object" && !Array.isArray(data27)){if(data27.current === undefined){const err93 = {instancePath:instancePath+"/pools/speed",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema32.required,parentSchema:schema32,data:data27};if(vErrors === null){vErrors = [err93];}else {vErrors.push(err93);}errors++;}if(data27.max === undefined){const err94 = {instancePath:instancePath+"/pools/speed",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema32.required,parentSchema:schema32,data:data27};if(vErrors === null){vErrors = [err94];}else {vErrors.push(err94);}errors++;}if(data27.edge === undefined){const err95 = {instancePath:instancePath+"/pools/speed",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "edge"},message:"must have required property '"+"edge"+"'",schema:schema32.required,parentSchema:schema32,data:data27};if(vErrors === null){vErrors = [err95];}else {vErrors.push(err95);}errors++;}for(const key5 in data27){if(!(((key5 === "current") || (key5 === "max")) || (key5 === "edge"))){const err96 = {instancePath:instancePath+"/pools/speed",schemaPath:"#/$defs/pool/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key5},message:"must NOT have additional properties",schema:false,parentSchema:schema32,data:data27};if(vErrors === null){vErrors = [err96];}else {vErrors.push(err96);}errors++;}}if(data27.current !== undefined){let data28 = data27.current;if(!(((typeof data28 == "number") && (!(data28 % 1) && !isNaN(data28))) && (isFinite(data28)))){const err97 = {instancePath:instancePath+"/pools/speed/current",schemaPath:"#/$defs/pool/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.current.type,parentSchema:schema32.properties.current,data:data28};if(vErrors === null){vErrors = [err97];}else {vErrors.push(err97);}errors++;}if((typeof data28 == "number") && (isFinite(data28))){if(data28 < 0 || isNaN(data28)){const err98 = {instancePath:instancePath+"/pools/speed/current",schemaPath:"#/$defs/pool/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.current,data:data28};if(vErrors === null){vErrors = [err98];}else {vErrors.push(err98);}errors++;}}}if(data27.max !== undefined){let data29 = data27.max;if(!(((typeof data29 == "number") && (!(data29 % 1) && !isNaN(data29))) && (isFinite(data29)))){const err99 = {instancePath:instancePath+"/pools/speed/max",schemaPath:"#/$defs/pool/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.max.type,parentSchema:schema32.properties.max,data:data29};if(vErrors === null){vErrors = [err99];}else {vErrors.push(err99);}errors++;}if((typeof data29 == "number") && (isFinite(data29))){if(data29 < 0 || isNaN(data29)){const err100 = {instancePath:instancePath+"/pools/speed/max",schemaPath:"#/$defs/pool/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.max,data:data29};if(vErrors === null){vErrors = [err100];}else {vErrors.push(err100);}errors++;}}}if(data27.edge !== undefined){let data30 = data27.edge;if(!(((typeof data30 == "number") && (!(data30 % 1) && !isNaN(data30))) && (isFinite(data30)))){const err101 = {instancePath:instancePath+"/pools/speed/edge",schemaPath:"#/$defs/pool/properties/edge/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.edge.type,parentSchema:schema32.properties.edge,data:data30};if(vErrors === null){vErrors = [err101];}else {vErrors.push(err101);}errors++;}if((typeof data30 == "number") && (isFinite(data30))){if(data30 < 0 || isNaN(data30)){const err102 = {instancePath:instancePath+"/pools/speed/edge",schemaPath:"#/$defs/pool/properties/edge/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.edge,data:data30};if(vErrors === null){vErrors = [err102];}else {vErrors.push(err102);}errors++;}}}}else {const err103 = {instancePath:instancePath+"/pools/speed",schemaPath:"#/$defs/pool/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema32.type,parentSchema:schema32,data:data27};if(vErrors === null){vErrors = [err103];}else {vErrors.push(err103);}errors++;}}if(data22.intellect !== undefined){let data31 = data22.intellect;if(data31 && typeof data31 == "object" && !Array.isArray(data31)){if(data31.current === undefined){const err104 = {instancePath:instancePath+"/pools/intellect",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema32.required,parentSchema:schema32,data:data31};if(vErrors === null){vErrors = [err104];}else {vErrors.push(err104);}errors++;}if(data31.max === undefined){const err105 = {instancePath:instancePath+"/pools/intellect",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema32.required,parentSchema:schema32,data:data31};if(vErrors === null){vErrors = [err105];}else {vErrors.push(err105);}errors++;}if(data31.edge === undefined){const err106 = {instancePath:instancePath+"/pools/intellect",schemaPath:"#/$defs/pool/required",keyword:"required",params:{missingProperty: "edge"},message:"must have required property '"+"edge"+"'",schema:schema32.required,parentSchema:schema32,data:data31};if(vErrors === null){vErrors = [err106];}else {vErrors.push(err106);}errors++;}for(const key6 in data31){if(!(((key6 === "current") || (key6 === "max")) || (key6 === "edge"))){const err107 = {instancePath:instancePath+"/pools/intellect",schemaPath:"#/$defs/pool/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key6},message:"must NOT have additional properties",schema:false,parentSchema:schema32,data:data31};if(vErrors === null){vErrors = [err107];}else {vErrors.push(err107);}errors++;}}if(data31.current !== undefined){let data32 = data31.current;if(!(((typeof data32 == "number") && (!(data32 % 1) && !isNaN(data32))) && (isFinite(data32)))){const err108 = {instancePath:instancePath+"/pools/intellect/current",schemaPath:"#/$defs/pool/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.current.type,parentSchema:schema32.properties.current,data:data32};if(vErrors === null){vErrors = [err108];}else {vErrors.push(err108);}errors++;}if((typeof data32 == "number") && (isFinite(data32))){if(data32 < 0 || isNaN(data32)){const err109 = {instancePath:instancePath+"/pools/intellect/current",schemaPath:"#/$defs/pool/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.current,data:data32};if(vErrors === null){vErrors = [err109];}else {vErrors.push(err109);}errors++;}}}if(data31.max !== undefined){let data33 = data31.max;if(!(((typeof data33 == "number") && (!(data33 % 1) && !isNaN(data33))) && (isFinite(data33)))){const err110 = {instancePath:instancePath+"/pools/intellect/max",schemaPath:"#/$defs/pool/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.max.type,parentSchema:schema32.properties.max,data:data33};if(vErrors === null){vErrors = [err110];}else {vErrors.push(err110);}errors++;}if((typeof data33 == "number") && (isFinite(data33))){if(data33 < 0 || isNaN(data33)){const err111 = {instancePath:instancePath+"/pools/intellect/max",schemaPath:"#/$defs/pool/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.max,data:data33};if(vErrors === null){vErrors = [err111];}else {vErrors.push(err111);}errors++;}}}if(data31.edge !== undefined){let data34 = data31.edge;if(!(((typeof data34 == "number") && (!(data34 % 1) && !isNaN(data34))) && (isFinite(data34)))){const err112 = {instancePath:instancePath+"/pools/intellect/edge",schemaPath:"#/$defs/pool/properties/edge/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema32.properties.edge.type,parentSchema:schema32.properties.edge,data:data34};if(vErrors === null){vErrors = [err112];}else {vErrors.push(err112);}errors++;}if((typeof data34 == "number") && (isFinite(data34))){if(data34 < 0 || isNaN(data34)){const err113 = {instancePath:instancePath+"/pools/intellect/edge",schemaPath:"#/$defs/pool/properties/edge/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema32.properties.edge,data:data34};if(vErrors === null){vErrors = [err113];}else {vErrors.push(err113);}errors++;}}}}else {const err114 = {instancePath:instancePath+"/pools/intellect",schemaPath:"#/$defs/pool/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema32.type,parentSchema:schema32,data:data31};if(vErrors === null){vErrors = [err114];}else {vErrors.push(err114);}errors++;}}}else {const err115 = {instancePath:instancePath+"/pools",schemaPath:"#/properties/pools/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.pools.type,parentSchema:schema31.properties.pools,data:data22};if(vErrors === null){vErrors = [err115];}else {vErrors.push(err115);}errors++;}}if(data.recovery !== undefined){let data35 = data.recovery;if(data35 && typeof data35 == "object" && !Array.isArray(data35)){if(data35.bonus === undefined){const err116 = {instancePath:instancePath+"/recovery",schemaPath:"#/properties/recovery/required",keyword:"required",params:{missingProperty: "bonus"},message:"must have required property '"+"bonus"+"'",schema:schema31.properties.recovery.required,parentSchema:schema31.properties.recovery,data:data35};if(vErrors === null){vErrors = [err116];}else {vErrors.push(err116);}errors++;}if(data35.slots === undefined){const err117 = {instancePath:instancePath+"/recovery",schemaPath:"#/properties/recovery/required",keyword:"required",params:{missingProperty: "slots"},message:"must have required property '"+"slots"+"'",schema:schema31.properties.recovery.required,parentSchema:schema31.properties.recovery,data:data35};if(vErrors === null){vErrors = [err117];}else {vErrors.push(err117);}errors++;}for(const key7 in data35){if(!((key7 === "bonus") || (key7 === "slots"))){const err118 = {instancePath:instancePath+"/recovery",schemaPath:"#/properties/recovery/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key7},message:"must NOT have additional properties",schema:false,parentSchema:schema31.properties.recovery,data:data35};if(vErrors === null){vErrors = [err118];}else {vErrors.push(err118);}errors++;}}if(data35.bonus !== undefined){let data36 = data35.bonus;if(!(((typeof data36 == "number") && (!(data36 % 1) && !isNaN(data36))) && (isFinite(data36)))){const err119 = {instancePath:instancePath+"/recovery/bonus",schemaPath:"#/properties/recovery/properties/bonus/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.recovery.properties.bonus.type,parentSchema:schema31.properties.recovery.properties.bonus,data:data36};if(vErrors === null){vErrors = [err119];}else {vErrors.push(err119);}errors++;}if((typeof data36 == "number") && (isFinite(data36))){if(data36 < 0 || isNaN(data36)){const err120 = {instancePath:instancePath+"/recovery/bonus",schemaPath:"#/properties/recovery/properties/bonus/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema31.properties.recovery.properties.bonus,data:data36};if(vErrors === null){vErrors = [err120];}else {vErrors.push(err120);}errors++;}}}if(data35.slots !== undefined){let data37 = data35.slots;if(Array.isArray(data37)){if(data37.length < 1){const err121 = {instancePath:instancePath+"/recovery/slots",schemaPath:"#/properties/recovery/properties/slots/minItems",keyword:"minItems",params:{limit: 1},message:"must NOT have fewer than 1 items",schema:1,parentSchema:schema31.properties.recovery.properties.slots,data:data37};if(vErrors === null){vErrors = [err121];}else {vErrors.push(err121);}errors++;}const len0 = data37.length;for(let i0=0; i0=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.current,data:data44};if(vErrors === null){vErrors = [err140];}else {vErrors.push(err140);}errors++;}}}if(data43.max !== undefined){let data45 = data43.max;if(!(((typeof data45 == "number") && (!(data45 % 1) && !isNaN(data45))) && (isFinite(data45)))){const err141 = {instancePath:instancePath+"/wounds/minor/max",schemaPath:"#/$defs/woundTier/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.max.type,parentSchema:schema36.properties.max,data:data45};if(vErrors === null){vErrors = [err141];}else {vErrors.push(err141);}errors++;}if((typeof data45 == "number") && (isFinite(data45))){if(data45 < 0 || isNaN(data45)){const err142 = {instancePath:instancePath+"/wounds/minor/max",schemaPath:"#/$defs/woundTier/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.max,data:data45};if(vErrors === null){vErrors = [err142];}else {vErrors.push(err142);}errors++;}}}}else {const err143 = {instancePath:instancePath+"/wounds/minor",schemaPath:"#/$defs/woundTier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema36.type,parentSchema:schema36,data:data43};if(vErrors === null){vErrors = [err143];}else {vErrors.push(err143);}errors++;}}if(data42.moderate !== undefined){let data46 = data42.moderate;if(data46 && typeof data46 == "object" && !Array.isArray(data46)){if(data46.current === undefined){const err144 = {instancePath:instancePath+"/wounds/moderate",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema36.required,parentSchema:schema36,data:data46};if(vErrors === null){vErrors = [err144];}else {vErrors.push(err144);}errors++;}if(data46.max === undefined){const err145 = {instancePath:instancePath+"/wounds/moderate",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema36.required,parentSchema:schema36,data:data46};if(vErrors === null){vErrors = [err145];}else {vErrors.push(err145);}errors++;}for(const key11 in data46){if(!((key11 === "current") || (key11 === "max"))){const err146 = {instancePath:instancePath+"/wounds/moderate",schemaPath:"#/$defs/woundTier/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key11},message:"must NOT have additional properties",schema:false,parentSchema:schema36,data:data46};if(vErrors === null){vErrors = [err146];}else {vErrors.push(err146);}errors++;}}if(data46.current !== undefined){let data47 = data46.current;if(!(((typeof data47 == "number") && (!(data47 % 1) && !isNaN(data47))) && (isFinite(data47)))){const err147 = {instancePath:instancePath+"/wounds/moderate/current",schemaPath:"#/$defs/woundTier/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.current.type,parentSchema:schema36.properties.current,data:data47};if(vErrors === null){vErrors = [err147];}else {vErrors.push(err147);}errors++;}if((typeof data47 == "number") && (isFinite(data47))){if(data47 < 0 || isNaN(data47)){const err148 = {instancePath:instancePath+"/wounds/moderate/current",schemaPath:"#/$defs/woundTier/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.current,data:data47};if(vErrors === null){vErrors = [err148];}else {vErrors.push(err148);}errors++;}}}if(data46.max !== undefined){let data48 = data46.max;if(!(((typeof data48 == "number") && (!(data48 % 1) && !isNaN(data48))) && (isFinite(data48)))){const err149 = {instancePath:instancePath+"/wounds/moderate/max",schemaPath:"#/$defs/woundTier/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.max.type,parentSchema:schema36.properties.max,data:data48};if(vErrors === null){vErrors = [err149];}else {vErrors.push(err149);}errors++;}if((typeof data48 == "number") && (isFinite(data48))){if(data48 < 0 || isNaN(data48)){const err150 = {instancePath:instancePath+"/wounds/moderate/max",schemaPath:"#/$defs/woundTier/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.max,data:data48};if(vErrors === null){vErrors = [err150];}else {vErrors.push(err150);}errors++;}}}}else {const err151 = {instancePath:instancePath+"/wounds/moderate",schemaPath:"#/$defs/woundTier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema36.type,parentSchema:schema36,data:data46};if(vErrors === null){vErrors = [err151];}else {vErrors.push(err151);}errors++;}}if(data42.major !== undefined){let data49 = data42.major;if(data49 && typeof data49 == "object" && !Array.isArray(data49)){if(data49.current === undefined){const err152 = {instancePath:instancePath+"/wounds/major",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "current"},message:"must have required property '"+"current"+"'",schema:schema36.required,parentSchema:schema36,data:data49};if(vErrors === null){vErrors = [err152];}else {vErrors.push(err152);}errors++;}if(data49.max === undefined){const err153 = {instancePath:instancePath+"/wounds/major",schemaPath:"#/$defs/woundTier/required",keyword:"required",params:{missingProperty: "max"},message:"must have required property '"+"max"+"'",schema:schema36.required,parentSchema:schema36,data:data49};if(vErrors === null){vErrors = [err153];}else {vErrors.push(err153);}errors++;}for(const key12 in data49){if(!((key12 === "current") || (key12 === "max"))){const err154 = {instancePath:instancePath+"/wounds/major",schemaPath:"#/$defs/woundTier/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key12},message:"must NOT have additional properties",schema:false,parentSchema:schema36,data:data49};if(vErrors === null){vErrors = [err154];}else {vErrors.push(err154);}errors++;}}if(data49.current !== undefined){let data50 = data49.current;if(!(((typeof data50 == "number") && (!(data50 % 1) && !isNaN(data50))) && (isFinite(data50)))){const err155 = {instancePath:instancePath+"/wounds/major/current",schemaPath:"#/$defs/woundTier/properties/current/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.current.type,parentSchema:schema36.properties.current,data:data50};if(vErrors === null){vErrors = [err155];}else {vErrors.push(err155);}errors++;}if((typeof data50 == "number") && (isFinite(data50))){if(data50 < 0 || isNaN(data50)){const err156 = {instancePath:instancePath+"/wounds/major/current",schemaPath:"#/$defs/woundTier/properties/current/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.current,data:data50};if(vErrors === null){vErrors = [err156];}else {vErrors.push(err156);}errors++;}}}if(data49.max !== undefined){let data51 = data49.max;if(!(((typeof data51 == "number") && (!(data51 % 1) && !isNaN(data51))) && (isFinite(data51)))){const err157 = {instancePath:instancePath+"/wounds/major/max",schemaPath:"#/$defs/woundTier/properties/max/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema36.properties.max.type,parentSchema:schema36.properties.max,data:data51};if(vErrors === null){vErrors = [err157];}else {vErrors.push(err157);}errors++;}if((typeof data51 == "number") && (isFinite(data51))){if(data51 < 0 || isNaN(data51)){const err158 = {instancePath:instancePath+"/wounds/major/max",schemaPath:"#/$defs/woundTier/properties/max/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema36.properties.max,data:data51};if(vErrors === null){vErrors = [err158];}else {vErrors.push(err158);}errors++;}}}}else {const err159 = {instancePath:instancePath+"/wounds/major",schemaPath:"#/$defs/woundTier/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema36.type,parentSchema:schema36,data:data49};if(vErrors === null){vErrors = [err159];}else {vErrors.push(err159);}errors++;}}}else {const err160 = {instancePath:instancePath+"/wounds",schemaPath:"#/properties/wounds/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.wounds.type,parentSchema:schema31.properties.wounds,data:data42};if(vErrors === null){vErrors = [err160];}else {vErrors.push(err160);}errors++;}}if(data.shield !== undefined){let data52 = data.shield;const _errs127 = errors;let valid23 = false;const _errs128 = errors;if(!(validate21(data52, {instancePath:instancePath+"/shield",parentData:data,parentDataProperty:"shield",rootData,dynamicAnchors}))){vErrors = vErrors === null ? validate21.errors : vErrors.concat(validate21.errors);errors = vErrors.length;}var _valid1 = _errs128 === errors;valid23 = valid23 || _valid1;const _errs129 = errors;if(data52 !== null){const err161 = {instancePath:instancePath+"/shield",schemaPath:"#/properties/shield/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema31.properties.shield.anyOf[1].type,parentSchema:schema31.properties.shield.anyOf[1],data:data52};if(vErrors === null){vErrors = [err161];}else {vErrors.push(err161);}errors++;}var _valid1 = _errs129 === errors;valid23 = valid23 || _valid1;if(!valid23){const err162 = {instancePath:instancePath+"/shield",schemaPath:"#/properties/shield/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema31.properties.shield.anyOf,parentSchema:schema31.properties.shield,data:data52};if(vErrors === null){vErrors = [err162];}else {vErrors.push(err162);}errors++;}else {errors = _errs127;if(vErrors !== null){if(_errs127){vErrors.length = _errs127;}else {vErrors = null;}}}}if(data.armor !== undefined){let data53 = data.armor;if(!(((typeof data53 == "number") && (!(data53 % 1) && !isNaN(data53))) && (isFinite(data53)))){const err163 = {instancePath:instancePath+"/armor",schemaPath:"#/properties/armor/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.armor.type,parentSchema:schema31.properties.armor,data:data53};if(vErrors === null){vErrors = [err163];}else {vErrors.push(err163);}errors++;}if((typeof data53 == "number") && (isFinite(data53))){if(data53 < 0 || isNaN(data53)){const err164 = {instancePath:instancePath+"/armor",schemaPath:"#/properties/armor/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema31.properties.armor,data:data53};if(vErrors === null){vErrors = [err164];}else {vErrors.push(err164);}errors++;}}}if(data.armorModifiers !== undefined){let data54 = data.armorModifiers;if(typeof data54 !== "string"){const err165 = {instancePath:instancePath+"/armorModifiers",schemaPath:"#/properties/armorModifiers/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema31.properties.armorModifiers.type,parentSchema:schema31.properties.armorModifiers,data:data54};if(vErrors === null){vErrors = [err165];}else {vErrors.push(err165);}errors++;}}if(data.cypherLimit !== undefined){let data55 = data.cypherLimit;if(!(((typeof data55 == "number") && (!(data55 % 1) && !isNaN(data55))) && (isFinite(data55)))){const err166 = {instancePath:instancePath+"/cypherLimit",schemaPath:"#/properties/cypherLimit/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema31.properties.cypherLimit.type,parentSchema:schema31.properties.cypherLimit,data:data55};if(vErrors === null){vErrors = [err166];}else {vErrors.push(err166);}errors++;}if((typeof data55 == "number") && (isFinite(data55))){if(data55 < 0 || isNaN(data55)){const err167 = {instancePath:instancePath+"/cypherLimit",schemaPath:"#/properties/cypherLimit/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema31.properties.cypherLimit,data:data55};if(vErrors === null){vErrors = [err167];}else {vErrors.push(err167);}errors++;}}}if(data.genre !== undefined){let data56 = data.genre;if(typeof data56 !== "string"){const err168 = {instancePath:instancePath+"/genre",schemaPath:"#/properties/genre/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema31.properties.genre.type,parentSchema:schema31.properties.genre,data:data56};if(vErrors === null){vErrors = [err168];}else {vErrors.push(err168);}errors++;}}if(data.subgenre !== undefined){let data57 = data.subgenre;if(typeof data57 !== "string"){const err169 = {instancePath:instancePath+"/subgenre",schemaPath:"#/properties/subgenre/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema31.properties.subgenre.type,parentSchema:schema31.properties.subgenre,data:data57};if(vErrors === null){vErrors = [err169];}else {vErrors.push(err169);}errors++;}}if(data.skills !== undefined){let data58 = data.skills;if(Array.isArray(data58)){const len1 = data58.length;for(let i1=0; i1=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema53.properties.level.anyOf[0],data:data67};if(vErrors === null){vErrors = [err181];}else {vErrors.push(err181);}errors++;}}var _valid2 = _errs160 === errors;valid34 = valid34 || _valid2;const _errs162 = errors;if(data67 !== null){const err182 = {instancePath:instancePath+"/equipment/" + i4+"/level",schemaPath:"#/$defs/equipment/properties/level/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema53.properties.level.anyOf[1].type,parentSchema:schema53.properties.level.anyOf[1],data:data67};if(vErrors === null){vErrors = [err182];}else {vErrors.push(err182);}errors++;}var _valid2 = _errs162 === errors;valid34 = valid34 || _valid2;if(!valid34){const err183 = {instancePath:instancePath+"/equipment/" + i4+"/level",schemaPath:"#/$defs/equipment/properties/level/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema53.properties.level.anyOf,parentSchema:schema53.properties.level,data:data67};if(vErrors === null){vErrors = [err183];}else {vErrors.push(err183);}errors++;}else {errors = _errs159;if(vErrors !== null){if(_errs159){vErrors.length = _errs159;}else {vErrors = null;}}}}if(data65.quantity !== undefined){let data68 = data65.quantity;if(!(((typeof data68 == "number") && (!(data68 % 1) && !isNaN(data68))) && (isFinite(data68)))){const err184 = {instancePath:instancePath+"/equipment/" + i4+"/quantity",schemaPath:"#/$defs/equipment/properties/quantity/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema53.properties.quantity.type,parentSchema:schema53.properties.quantity,data:data68};if(vErrors === null){vErrors = [err184];}else {vErrors.push(err184);}errors++;}if((typeof data68 == "number") && (isFinite(data68))){if(data68 < 0 || isNaN(data68)){const err185 = {instancePath:instancePath+"/equipment/" + i4+"/quantity",schemaPath:"#/$defs/equipment/properties/quantity/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema53.properties.quantity,data:data68};if(vErrors === null){vErrors = [err185];}else {vErrors.push(err185);}errors++;}}}if(data65.notes !== undefined){let data69 = data65.notes;if(typeof data69 !== "string"){const err186 = {instancePath:instancePath+"/equipment/" + i4+"/notes",schemaPath:"#/$defs/equipment/properties/notes/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema53.properties.notes.type,parentSchema:schema53.properties.notes,data:data69};if(vErrors === null){vErrors = [err186];}else {vErrors.push(err186);}errors++;}}}else {const err187 = {instancePath:instancePath+"/equipment/" + i4,schemaPath:"#/$defs/equipment/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema53.type,parentSchema:schema53,data:data65};if(vErrors === null){vErrors = [err187];}else {vErrors.push(err187);}errors++;}}}else {const err188 = {instancePath:instancePath+"/equipment",schemaPath:"#/properties/equipment/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.equipment.type,parentSchema:schema31.properties.equipment,data:data64};if(vErrors === null){vErrors = [err188];}else {vErrors.push(err188);}errors++;}}if(data.cyphers !== undefined){let data70 = data.cyphers;if(Array.isArray(data70)){const len5 = data70.length;for(let i5=0; i5=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema54.properties.level.anyOf[0],data:data74};if(vErrors === null){vErrors = [err201];}else {vErrors.push(err201);}errors++;}}var _valid3 = _errs180 === errors;valid39 = valid39 || _valid3;const _errs182 = errors;if(data74 !== null){const err202 = {instancePath:instancePath+"/cyphers/" + i5+"/level",schemaPath:"#/$defs/cypher/properties/level/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema54.properties.level.anyOf[1].type,parentSchema:schema54.properties.level.anyOf[1],data:data74};if(vErrors === null){vErrors = [err202];}else {vErrors.push(err202);}errors++;}var _valid3 = _errs182 === errors;valid39 = valid39 || _valid3;if(!valid39){const err203 = {instancePath:instancePath+"/cyphers/" + i5+"/level",schemaPath:"#/$defs/cypher/properties/level/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema54.properties.level.anyOf,parentSchema:schema54.properties.level,data:data74};if(vErrors === null){vErrors = [err203];}else {vErrors.push(err203);}errors++;}else {errors = _errs179;if(vErrors !== null){if(_errs179){vErrors.length = _errs179;}else {vErrors = null;}}}}if(data71.cypherKind !== undefined){let data75 = data71.cypherKind;const _errs185 = errors;let valid40 = false;const _errs186 = errors;if(!((data75 === "cypher") || (data75 === "manifest"))){const err204 = {instancePath:instancePath+"/cyphers/" + i5+"/cypherKind",schemaPath:"#/$defs/cypher/properties/cypherKind/anyOf/0/enum",keyword:"enum",params:{allowedValues: schema54.properties.cypherKind.anyOf[0].enum},message:"must be equal to one of the allowed values",schema:schema54.properties.cypherKind.anyOf[0].enum,parentSchema:schema54.properties.cypherKind.anyOf[0],data:data75};if(vErrors === null){vErrors = [err204];}else {vErrors.push(err204);}errors++;}var _valid4 = _errs186 === errors;valid40 = valid40 || _valid4;const _errs187 = errors;if(data75 !== null){const err205 = {instancePath:instancePath+"/cyphers/" + i5+"/cypherKind",schemaPath:"#/$defs/cypher/properties/cypherKind/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema54.properties.cypherKind.anyOf[1].type,parentSchema:schema54.properties.cypherKind.anyOf[1],data:data75};if(vErrors === null){vErrors = [err205];}else {vErrors.push(err205);}errors++;}var _valid4 = _errs187 === errors;valid40 = valid40 || _valid4;if(!valid40){const err206 = {instancePath:instancePath+"/cyphers/" + i5+"/cypherKind",schemaPath:"#/$defs/cypher/properties/cypherKind/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema54.properties.cypherKind.anyOf,parentSchema:schema54.properties.cypherKind,data:data75};if(vErrors === null){vErrors = [err206];}else {vErrors.push(err206);}errors++;}else {errors = _errs185;if(vErrors !== null){if(_errs185){vErrors.length = _errs185;}else {vErrors = null;}}}}if(data71.power !== undefined){let data76 = data71.power;const _errs190 = errors;let valid41 = false;const _errs191 = errors;if(!((((((data76 === "low") || (data76 === "medium")) || (data76 === "high")) || (data76 === "advanced")) || (data76 === "ultra")) || (data76 === "nonstandard"))){const err207 = {instancePath:instancePath+"/cyphers/" + i5+"/power",schemaPath:"#/$defs/cypher/properties/power/anyOf/0/enum",keyword:"enum",params:{allowedValues: schema54.properties.power.anyOf[0].enum},message:"must be equal to one of the allowed values",schema:schema54.properties.power.anyOf[0].enum,parentSchema:schema54.properties.power.anyOf[0],data:data76};if(vErrors === null){vErrors = [err207];}else {vErrors.push(err207);}errors++;}var _valid5 = _errs191 === errors;valid41 = valid41 || _valid5;const _errs192 = errors;if(data76 !== null){const err208 = {instancePath:instancePath+"/cyphers/" + i5+"/power",schemaPath:"#/$defs/cypher/properties/power/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema54.properties.power.anyOf[1].type,parentSchema:schema54.properties.power.anyOf[1],data:data76};if(vErrors === null){vErrors = [err208];}else {vErrors.push(err208);}errors++;}var _valid5 = _errs192 === errors;valid41 = valid41 || _valid5;if(!valid41){const err209 = {instancePath:instancePath+"/cyphers/" + i5+"/power",schemaPath:"#/$defs/cypher/properties/power/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema54.properties.power.anyOf,parentSchema:schema54.properties.power,data:data76};if(vErrors === null){vErrors = [err209];}else {vErrors.push(err209);}errors++;}else {errors = _errs190;if(vErrors !== null){if(_errs190){vErrors.length = _errs190;}else {vErrors = null;}}}}if(data71.activated !== undefined){let data77 = data71.activated;if(typeof data77 !== "boolean"){const err210 = {instancePath:instancePath+"/cyphers/" + i5+"/activated",schemaPath:"#/$defs/cypher/properties/activated/type",keyword:"type",params:{type: "boolean"},message:"must be boolean",schema:schema54.properties.activated.type,parentSchema:schema54.properties.activated,data:data77};if(vErrors === null){vErrors = [err210];}else {vErrors.push(err210);}errors++;}}if(data71.description !== undefined){let data78 = data71.description;if(typeof data78 !== "string"){const err211 = {instancePath:instancePath+"/cyphers/" + i5+"/description",schemaPath:"#/$defs/cypher/properties/description/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema54.properties.description.type,parentSchema:schema54.properties.description,data:data78};if(vErrors === null){vErrors = [err211];}else {vErrors.push(err211);}errors++;}}}else {const err212 = {instancePath:instancePath+"/cyphers/" + i5,schemaPath:"#/$defs/cypher/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema54.type,parentSchema:schema54,data:data71};if(vErrors === null){vErrors = [err212];}else {vErrors.push(err212);}errors++;}}}else {const err213 = {instancePath:instancePath+"/cyphers",schemaPath:"#/properties/cyphers/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.cyphers.type,parentSchema:schema31.properties.cyphers,data:data70};if(vErrors === null){vErrors = [err213];}else {vErrors.push(err213);}errors++;}}if(data.artifacts !== undefined){let data79 = data.artifacts;if(Array.isArray(data79)){const len6 = data79.length;for(let i6=0; i6=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema55.properties.level.anyOf[0],data:data82};if(vErrors === null){vErrors = [err223];}else {vErrors.push(err223);}errors++;}}var _valid6 = _errs208 === errors;valid46 = valid46 || _valid6;const _errs210 = errors;if(data82 !== null){const err224 = {instancePath:instancePath+"/artifacts/" + i6+"/level",schemaPath:"#/$defs/artifact/properties/level/anyOf/1/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema55.properties.level.anyOf[1].type,parentSchema:schema55.properties.level.anyOf[1],data:data82};if(vErrors === null){vErrors = [err224];}else {vErrors.push(err224);}errors++;}var _valid6 = _errs210 === errors;valid46 = valid46 || _valid6;if(!valid46){const err225 = {instancePath:instancePath+"/artifacts/" + i6+"/level",schemaPath:"#/$defs/artifact/properties/level/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema55.properties.level.anyOf,parentSchema:schema55.properties.level,data:data82};if(vErrors === null){vErrors = [err225];}else {vErrors.push(err225);}errors++;}else {errors = _errs207;if(vErrors !== null){if(_errs207){vErrors.length = _errs207;}else {vErrors = null;}}}}if(data80.depletion !== undefined){let data83 = data80.depletion;const _errs213 = errors;let valid47 = false;const _errs214 = errors;if(data83 && typeof data83 == "object" && !Array.isArray(data83)){if(data83.chance === undefined){const err226 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/required",keyword:"required",params:{missingProperty: "chance"},message:"must have required property '"+"chance"+"'",schema:schema55.properties.depletion.anyOf[0].required,parentSchema:schema55.properties.depletion.anyOf[0],data:data83};if(vErrors === null){vErrors = [err226];}else {vErrors.push(err226);}errors++;}if(data83.die === undefined){const err227 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/required",keyword:"required",params:{missingProperty: "die"},message:"must have required property '"+"die"+"'",schema:schema55.properties.depletion.anyOf[0].required,parentSchema:schema55.properties.depletion.anyOf[0],data:data83};if(vErrors === null){vErrors = [err227];}else {vErrors.push(err227);}errors++;}for(const key16 in data83){if(!((key16 === "chance") || (key16 === "die"))){const err228 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key16},message:"must NOT have additional properties",schema:false,parentSchema:schema55.properties.depletion.anyOf[0],data:data83};if(vErrors === null){vErrors = [err228];}else {vErrors.push(err228);}errors++;}}if(data83.chance !== undefined){let data84 = data83.chance;if(!(((typeof data84 == "number") && (!(data84 % 1) && !isNaN(data84))) && (isFinite(data84)))){const err229 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion/chance",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/properties/chance/type",keyword:"type",params:{type: "integer"},message:"must be integer",schema:schema55.properties.depletion.anyOf[0].properties.chance.type,parentSchema:schema55.properties.depletion.anyOf[0].properties.chance,data:data84};if(vErrors === null){vErrors = [err229];}else {vErrors.push(err229);}errors++;}if((typeof data84 == "number") && (isFinite(data84))){if(data84 < 1 || isNaN(data84)){const err230 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion/chance",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/properties/chance/minimum",keyword:"minimum",params:{comparison: ">=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema55.properties.depletion.anyOf[0].properties.chance,data:data84};if(vErrors === null){vErrors = [err230];}else {vErrors.push(err230);}errors++;}}}if(data83.die !== undefined){let data85 = data83.die;if(!((((data85 === "1d6") || (data85 === "1d10")) || (data85 === "1d20")) || (data85 === "1d100"))){const err231 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion/die",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/properties/die/enum",keyword:"enum",params:{allowedValues: schema55.properties.depletion.anyOf[0].properties.die.enum},message:"must be equal to one of the allowed values",schema:schema55.properties.depletion.anyOf[0].properties.die.enum,parentSchema:schema55.properties.depletion.anyOf[0].properties.die,data:data85};if(vErrors === null){vErrors = [err231];}else {vErrors.push(err231);}errors++;}}}else {const err232 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/0/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema55.properties.depletion.anyOf[0].type,parentSchema:schema55.properties.depletion.anyOf[0],data:data83};if(vErrors === null){vErrors = [err232];}else {vErrors.push(err232);}errors++;}var _valid7 = _errs214 === errors;valid47 = valid47 || _valid7;const _errs220 = errors;if("automatic" !== data83){const err233 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/1/const",keyword:"const",params:{allowedValue: "automatic"},message:"must be equal to constant",schema:"automatic",parentSchema:schema55.properties.depletion.anyOf[1],data:data83};if(vErrors === null){vErrors = [err233];}else {vErrors.push(err233);}errors++;}var _valid7 = _errs220 === errors;valid47 = valid47 || _valid7;const _errs221 = errors;if(data83 !== null){const err234 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf/2/type",keyword:"type",params:{type: "null"},message:"must be null",schema:schema55.properties.depletion.anyOf[2].type,parentSchema:schema55.properties.depletion.anyOf[2],data:data83};if(vErrors === null){vErrors = [err234];}else {vErrors.push(err234);}errors++;}var _valid7 = _errs221 === errors;valid47 = valid47 || _valid7;if(!valid47){const err235 = {instancePath:instancePath+"/artifacts/" + i6+"/depletion",schemaPath:"#/$defs/artifact/properties/depletion/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema55.properties.depletion.anyOf,parentSchema:schema55.properties.depletion,data:data83};if(vErrors === null){vErrors = [err235];}else {vErrors.push(err235);}errors++;}else {errors = _errs213;if(vErrors !== null){if(_errs213){vErrors.length = _errs213;}else {vErrors = null;}}}}if(data80.form !== undefined){let data86 = data80.form;if(typeof data86 !== "string"){const err236 = {instancePath:instancePath+"/artifacts/" + i6+"/form",schemaPath:"#/$defs/artifact/properties/form/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema55.properties.form.type,parentSchema:schema55.properties.form,data:data86};if(vErrors === null){vErrors = [err236];}else {vErrors.push(err236);}errors++;}}if(data80.description !== undefined){let data87 = data80.description;if(typeof data87 !== "string"){const err237 = {instancePath:instancePath+"/artifacts/" + i6+"/description",schemaPath:"#/$defs/artifact/properties/description/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema55.properties.description.type,parentSchema:schema55.properties.description,data:data87};if(vErrors === null){vErrors = [err237];}else {vErrors.push(err237);}errors++;}}}else {const err238 = {instancePath:instancePath+"/artifacts/" + i6,schemaPath:"#/$defs/artifact/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema55.type,parentSchema:schema55,data:data80};if(vErrors === null){vErrors = [err238];}else {vErrors.push(err238);}errors++;}}}else {const err239 = {instancePath:instancePath+"/artifacts",schemaPath:"#/properties/artifacts/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.artifacts.type,parentSchema:schema31.properties.artifacts,data:data79};if(vErrors === null){vErrors = [err239];}else {vErrors.push(err239);}errors++;}}if(data.powerShifts !== undefined){let data88 = data.powerShifts;if(Array.isArray(data88)){const len7 = data88.length;for(let i7=0; i7=", limit: 1},message:"must be >= 1",schema:1,parentSchema:schema56.properties.shifts,data:data91};if(vErrors === null){vErrors = [err247];}else {vErrors.push(err247);}errors++;}}}if(data89.description !== undefined){let data92 = data89.description;if(typeof data92 !== "string"){const err248 = {instancePath:instancePath+"/powerShifts/" + i7+"/description",schemaPath:"#/$defs/powerShift/properties/description/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema56.properties.description.type,parentSchema:schema56.properties.description,data:data92};if(vErrors === null){vErrors = [err248];}else {vErrors.push(err248);}errors++;}}}else {const err249 = {instancePath:instancePath+"/powerShifts/" + i7,schemaPath:"#/$defs/powerShift/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema56.type,parentSchema:schema56,data:data89};if(vErrors === null){vErrors = [err249];}else {vErrors.push(err249);}errors++;}}}else {const err250 = {instancePath:instancePath+"/powerShifts",schemaPath:"#/properties/powerShifts/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.powerShifts.type,parentSchema:schema31.properties.powerShifts,data:data88};if(vErrors === null){vErrors = [err250];}else {vErrors.push(err250);}errors++;}}if(data.currencies !== undefined){let data93 = data.currencies;if(Array.isArray(data93)){const len8 = data93.length;for(let i8=0; i8=", limit: 0},message:"must be >= 0",schema:0,parentSchema:schema57.properties.amount,data:data96};if(vErrors === null){vErrors = [err256];}else {vErrors.push(err256);}errors++;}}else {const err257 = {instancePath:instancePath+"/currencies/" + i8+"/amount",schemaPath:"#/$defs/currency/properties/amount/type",keyword:"type",params:{type: "number"},message:"must be number",schema:schema57.properties.amount.type,parentSchema:schema57.properties.amount,data:data96};if(vErrors === null){vErrors = [err257];}else {vErrors.push(err257);}errors++;}}}else {const err258 = {instancePath:instancePath+"/currencies/" + i8,schemaPath:"#/$defs/currency/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema57.type,parentSchema:schema57,data:data94};if(vErrors === null){vErrors = [err258];}else {vErrors.push(err258);}errors++;}}}else {const err259 = {instancePath:instancePath+"/currencies",schemaPath:"#/properties/currencies/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.currencies.type,parentSchema:schema31.properties.currencies,data:data93};if(vErrors === null){vErrors = [err259];}else {vErrors.push(err259);}errors++;}}if(data.arcs !== undefined){let data97 = data.arcs;if(Array.isArray(data97)){const len9 = data97.length;for(let i9=0; i9 '$.skills[0].rating' (the contract manifest's path convention)
+export const formatPath = (instancePath) => {
+ if (!instancePath) return '$'
+ return (
+ '$' +
+ instancePath
+ .split('/')
+ .slice(1)
+ .map((seg) => (/^\d+$/.test(seg) ? `[${seg}]` : `.${seg}`))
+ .join('')
+ )
+}
+
+const formatError = (e) => {
+ const path = formatPath(e.instancePath)
+ if (e.keyword === 'required') return `${path}: '${e.params.missingProperty}' is a required property`
+ if (e.keyword === 'enum')
+ return `${path}: ${JSON.stringify(e.data)} is not one of ${JSON.stringify(e.params.allowedValues)}`
+ if (e.keyword === 'additionalProperties')
+ return `${path}: Additional properties are not allowed ('${e.params.additionalProperty}' was unexpected)`
+ return `${path}: ${e.message}`
+}
+
+export const validateDocument = (doc) => {
+ const valid = validate(doc)
+ if (valid) return { valid: true, errors: [] }
+ return { valid: false, errors: (validate.errors ?? []).map(formatError) }
+}
diff --git a/cypher2/src/dice/rolls.js b/cypher2/src/dice/rolls.js
new file mode 100644
index 00000000..501fc517
--- /dev/null
+++ b/cypher2/src/dice/rolls.js
@@ -0,0 +1,65 @@
+// Pure Cypher quick-roll logic. No Beacon/Vue dependencies — fully unit-testable.
+// Task roll: 1d20 vs difficulty × 3. Quick roll reports the highest difficulty
+// beaten; it never deducts pool points (spec ① decision — the guided roller owns costs).
+
+export const SPECIALS = {
+ 1: { code: 'gm-intrusion', label: 'GM Intrusion' },
+ 17: { code: 'damage-1', label: '+1 damage' },
+ 18: { code: 'damage-2', label: '+2 damage' },
+ 19: { code: 'minor-effect', label: 'Minor effect' },
+ 20: { code: 'major-effect', label: 'Major effect' }
+}
+
+export const beatsDifficulty = (die) => Math.floor(die / 3)
+
+export const interpretStatRoll = (die) => ({
+ die,
+ beats: beatsDifficulty(die),
+ special: SPECIALS[die] ?? null
+})
+
+// ---- Guided roller math (spec ③). Pure; the roller owns pool costs. ----
+
+// Skill ease ladder; the book caps the skill portion at 3 steps.
+export const SKILL_EASES = { inability: -1, practiced: 0, trained: 1, specialized: 2, expert: 3 }
+
+// EVERY read of a STORED rating goes through here — never SKILL_EASES[rating]
+// directly (ddd-c8f) — and the book's 3-step cap lives here too, so the chat
+// card and the math can never cap differently. hydrate() applies no enum
+// validation, and `?? 0` does not guard a prototype key: SKILL_EASES.constructor
+// is a truthy Function, so the coalesce never fires and Math.min(Function, 3) is
+// NaN. That NaN reaches interpretGuidedRoll's `base.beats >= effective`, where
+// every comparison is false — reporting EVERY roll as a failure, natural 20
+// included, after the Effort has already left the pool. Object.hasOwn, same
+// shape as poolLabel (ddd-9ir). Fallback 0 (= practiced, no ease): an unknown
+// rating says nothing about the character's training, so the math must add and
+// subtract nothing — -1 would silently hinder a roll the data never called an
+// inability. The bad value still degrades VISIBLY: the card's eases line prints
+// the raw rating verbatim beside this +0.
+export const skillEase = (rating) =>
+ Object.hasOwn(SKILL_EASES, rating) ? Math.min(SKILL_EASES[rating], 3) : 0
+
+// Effort ladder before Edge: 3 for the first level, +2 per additional (book).
+export const rawEffortCost = (levels) => (levels <= 0 ? 0 : 3 + 2 * (levels - 1))
+
+export const effortCost = (levels, edge = 0) => Math.max(0, rawEffortCost(levels) - edge)
+
+// Closed form, not a loop: schemaVersion 2 dropped the effort maximum, so
+// effortStat is arbitrary valid input and a 1..effortStat scan can freeze the
+// sheet (ddd-aqm audit). Affordable ⇔ effortCost(L, edge) ≤ poolCurrent, and
+// with rawEffortCost affine (2L + 1) that is L ≤ (poolCurrent + edge − 1) / 2 —
+// the max(0, …) branch folds in because poolCurrent is never negative here.
+export const maxAffordableEffort = (effortStat, poolCurrent, edge = 0) =>
+ Math.max(0, Math.min(effortStat, Math.floor((poolCurrent + edge - 1) / 2)))
+
+export const easedSteps = ({ skillRating = null, assets = 0, effortLevels = 0 }) =>
+ skillEase(skillRating) + Math.min(Math.max(assets, 0), 2) + Math.max(effortLevels, 0)
+
+export const interpretGuidedRoll = ({ die, eased, difficulty = null }) => {
+ const base = interpretStatRoll(die)
+ if (difficulty === null) {
+ return { ...base, eased, difficulty: null, effective: null, success: null, autoSuccess: false }
+ }
+ const effective = Math.max(0, difficulty - eased)
+ return { ...base, eased, difficulty, effective, success: base.beats >= effective, autoSuccess: effective === 0 }
+}
diff --git a/cypher2/src/main.js b/cypher2/src/main.js
new file mode 100644
index 00000000..7603f09e
--- /dev/null
+++ b/cypher2/src/main.js
@@ -0,0 +1,25 @@
+import './assets/main.css'
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import { createRelay } from './relay/relay'
+import App from './App.vue'
+
+// Offline dev relay outside the Roll20 host (dev server, vitest).
+const env = import.meta.env.MODE || ''
+const isDevEnvironment = ['development', 'test'].includes(env)
+
+const pinia = createPinia()
+const app = createApp(App)
+const { relayPinia, relayVue } = await createRelay({ devMode: isDevEnvironment })
+
+app.use(pinia)
+app.use(relayVue)
+pinia.use(relayPinia)
+
+// Test seam for scripts/capture.mjs — the harness sets ui.theme/ui.characterSegment/ui.kitSegment/ui.guidedRoll
+// before the Settings select exists. DEV-only: import.meta.env.DEV is false in every
+// built bundle. NOT gated on MODE — ddd-dxk: the sandbox runs mode 'staging', and a
+// MODE check would ship this to players.
+if (import.meta.env.DEV) window.__pinia__ = pinia
+
+app.mount('#app')
diff --git a/cypher2/src/relay/handlers/handlers.js b/cypher2/src/relay/handlers/handlers.js
new file mode 100644
index 00000000..cef011c1
--- /dev/null
+++ b/cypher2/src/relay/handlers/handlers.js
@@ -0,0 +1,25 @@
+import { initValues, beaconPulse } from '../relay'
+
+// onInit is called when the Relay is first loaded. It is used to set up the initial values of the sheet.
+export const onInit = ({ character, settings, compendiumDropData }) => {
+ initValues.id = character.id
+ initValues.character = character
+ initValues.settings = settings
+ initValues.compendiumDrop = compendiumDropData ? compendiumDropData : null
+ console.log('onInit -> Example Sheet Relay')
+}
+
+// onChange is called when the character data is updated. This is where you will update the sheet with the new data.
+export const onChange = async ({ character }) => {
+ const old = beaconPulse.value // This is a way to trigger a re-render of the sheet, see relay.js for more information.
+ beaconPulse.value = old + 1
+ console.log('onChange -> Example Sheet Relay', character)
+}
+
+export const onSettingsChange = () => {}
+
+export const onSharedSettingsChange = () => {}
+
+export const onTranslationsRequest = () => ({})
+
+export const onDragOver = () => {}
diff --git a/cypher2/src/relay/relay.js b/cypher2/src/relay/relay.js
new file mode 100644
index 00000000..52287720
--- /dev/null
+++ b/cypher2/src/relay/relay.js
@@ -0,0 +1,232 @@
+import { initRelay } from '@roll20-official/beacon-sdk'
+import { debounce } from 'lodash'
+
+import {
+ onInit,
+ onChange,
+ onSettingsChange,
+ onSharedSettingsChange,
+ onTranslationsRequest,
+ onDragOver
+} from './handlers/handlers'
+import { reactive, ref, watch, nextTick, shallowRef } from 'vue'
+import { v4 as uuidv4 } from 'uuid'
+
+/*
+This is the configuration for the relay. It defines the handlers and actions that the sheet will use.
+The handlers are functions that are called by the relay when certain events occur.
+The actions are custom functions that can be called by the sheet to perform specific actions.
+the computed properties are exposed by the sheet to be used in macros, inline rolls and tokens.
+*/
+
+// Token-bar exposure (spec §4): campaigns bind bars to these computed pools.
+// The get shape follows the Beacon advanced-example convention; the sandbox
+// walkthrough is the real gate (spec §8 risk). Attributes carry contract paths
+// at their root (stores/index.js), so pools live at attributes.pools..
+const poolFromCharacter = (character, pool) => {
+ const p = character?.attributes?.pools?.[pool]
+ return { current: p?.current ?? 0, max: p?.max ?? 0 }
+}
+
+// Marks a write as token-originated. doUpdate stamps the sheet's own id here so
+// the beaconPulse watcher can skip its own echo; a token-bar write must NOT
+// inherit that id, or the watcher swallows the pulse and the sheet UI drifts
+// away from the bar. Any non-sheetId value forces the hydrate (ddd-6qe).
+export const TOKEN_BAR_UPDATE_ID = 'token-bar'
+
+// Token-side edits (ddd-6qe). The SDK derives read-only from the ABSENCE of a
+// set handler (actionHandler.js: `readonly: !computed[property].set`), which is
+// why the bar bubble showed a blocked cursor with get alone. Args arrive as raw
+// host strings, and onSetComputed re-runs get() right after set() to echo the
+// value back to the bar — so the dispatch must land in the SDK's character
+// cache before that read, which dispatch.updateCharacter does synchronously.
+const setPoolCurrent = (pool) => async ({ character, dispatch }, value) => {
+ if (!dispatch?.updateCharacter) return
+ const parsed = Number(String(value ?? '').trim())
+ // A cleared or garbled bubble must not silently zero a GM's pool mid-combat.
+ if (String(value ?? '').trim() === '' || !Number.isFinite(parsed)) return
+ const { max } = poolFromCharacter(character, pool)
+ const current = Math.min(Math.max(0, Math.floor(parsed)), max)
+ // updateCharacter jsonDiffs `attributes` against the cached document and
+ // treats every OMITTED key as a deletion (deep-object-diff yields undefined,
+ // replaceUndefined turns it into null, deleteNullValues drops the key). A
+ // one-pool fragment would therefore wipe wounds, armor, the other pools, and
+ // even this pool's own max/edge. Send the whole tree with only `current`
+ // moved; unchanged branches are shared by reference and never mutated, and
+ // updateCharacter deep-clones before diffing.
+ const attributes = {
+ ...character?.attributes,
+ pools: {
+ ...character?.attributes?.pools,
+ [pool]: { ...character?.attributes?.pools?.[pool], current }
+ },
+ updateId: TOKEN_BAR_UPDATE_ID
+ }
+ await dispatch.updateCharacter({ character: { id: character?.id, attributes } })
+}
+
+const poolComputed = (pool) => ({
+ tokenBarValue: true,
+ get: ({ character }) => poolFromCharacter(character, pool),
+ set: setPoolCurrent(pool)
+})
+
+export const computedPools = {
+ might: poolComputed('might'),
+ speed: poolComputed('speed'),
+ intellect: poolComputed('intellect')
+}
+
+const relayConfig = {
+ handlers: {
+ onInit,
+ onChange,
+ onSettingsChange,
+ onSharedSettingsChange,
+ onTranslationsRequest,
+ onDragOver
+ },
+ // Refer to our advanced example sheet on how to setup actions and computed properties.
+ actions: {},
+ computed: computedPools
+}
+
+// Almost everything below here is Boilerplate and you probably want to keep it intact.
+export const initValues = reactive({
+ id: '',
+ character: { attributes: {} },
+ settings: {},
+ compendiumDrop: null
+})
+
+/*
+We use refs to keep track of the state of the sheet.
+This is a way to keep track of the state of the sheet in a reactive way.
+*/
+export const beaconPulse = ref(0)
+export const blockUpdate = ref(false)
+export const dispatchRef = shallowRef()
+export const dropUpdate = ref({})
+export const settingsSheet = ref(false)
+const sheetId = ref(uuidv4())
+
+/*
+This is the function that is called when the character data is updated.
+logMode is a flag that can be used to log the updates to the console. This is useful for debugging.
+*/
+// Last payload the remote is known to hold — set on every dispatch AND on
+// every hydrate (to the post-hydrate document). Transient UI state
+// (rollerStat) bubbles $subscribe without changing the dehydrated document,
+// so byte-identical fires are skipped (ddd-hy2) — including the first roller
+// churn after startup or a hydrate. An edit restoring a PRE-hydrate value
+// still differs from the post-hydrate baseline, so it persists (audit r2).
+let lastSentPayload = null
+
+const doUpdate = (dispatch, getUpdate, logMode = false) => {
+ // getUpdate is a thunk: dehydration happens at debounce-fire time, never at
+ // schedule time — a snapshot captured before a hydrate would resurrect stale
+ // state the store no longer holds (ddd-ej2).
+ const update = getUpdate()
+ const payload = JSON.stringify(update)
+ if (payload === lastSentPayload) {
+ if (logMode) console.info('⏭️ Skipping byte-identical update')
+ return
+ }
+ lastSentPayload = payload
+ if (logMode) console.info('➡️ ExampleSheet: Updating Firebase')
+ if (logMode) console.dir(`Firebase Update: ${initValues.character.id}`, update)
+ const character = {
+ character: {
+ id: initValues.character.id,
+ ...update
+ }
+ }
+ character.character.attributes.updateId = sheetId.value
+ dispatch.updateCharacter(character)
+}
+
+// This is a debounced version of the update function that will only be called after 800ms of inactivity.
+const debounceUpdate = debounce(doUpdate, 800)
+
+/*
+Dev relay is used to run the sheet in a web browser
+It will log the updates to the console instead of sending them to the VTT or Roll20/Characters
+This is useful for testing the sheet without having to connect to the server.
+*/
+const devRelay = async () => ({
+ update: (...args) => console.log('devRelay update', args),
+ updateCharacter: (...args) => console.log('devRelay updateCharacter', args),
+ characters: {},
+ updateTokensByCharacter: () => ''
+})
+
+/*
+This function is called to create the relay.
+It will return the relayPinia and relayVue objects that can be used to install the relay in the sheet.
+ RelayPinia is used to hydrate the store and watch for changes.
+ RelayVue is used to provide the dispatch object from the Beacon SDK to the sheet.
+We use a watcher of beaconPulse value to trigger a re-render of the sheet when the value changes, see the onChange handler.
+This is just one way to trigger a re-render, you can implement your own logic to trigger a re-render.
+*/
+export const createRelay = async ({ devMode = false, primaryStore = 'app', logMode = false }) => {
+ const dispatch = await (devMode ? devRelay() : initRelay(relayConfig))
+ const relayPinia = (context) => {
+ if (context.store.$id !== primaryStore) return
+ const store = context.store
+
+ dispatchRef.value = dispatch
+
+ // Init Store
+ const { attributes, ...profile } = initValues.character
+ store.hydrateStore(attributes, profile)
+ lastSentPayload = JSON.stringify(store.dehydrateStore()) // startup baseline (ddd-hy2)
+
+ // Beacon Provides access to settings, like campaign id for example
+ store.setCampaignId(initValues.settings.campaignId)
+ store.setPermissions(initValues.settings.owned, initValues.settings.gm)
+
+ // Watch for changes
+ store.$subscribe(() => {
+ if (blockUpdate.value === true) return
+ debounceUpdate(dispatch, () => store.dehydrateStore(), logMode)
+ })
+
+ // Watch for changes from the Beacon SDK, triggered everytime the Beacon Pulse value changes
+ watch(beaconPulse, async (newValue, oldValue) => {
+ if (logMode) console.log('❤️ Beacon Pulse', { newValue, oldValue })
+ const characterId = initValues.character.id
+ blockUpdate.value = true
+ if (logMode) console.log('🔓🔴 locking changes')
+ const { attributes, ...profile } = dispatch.characters[characterId]
+ if (attributes.updateId === sheetId.value) {
+ blockUpdate.value = false
+ return
+ }
+ // A real hydrate supersedes any pending local persist: cancel it, or its
+ // pre-hydrate snapshot fires after unlock and overwrites the newer remote
+ // state (ddd-ej2). Own-echo pulses return above and keep pending writes.
+ debounceUpdate.cancel()
+ store.hydrateStore(attributes, profile)
+ // Baseline = the document remote just gave us: roller churn after a
+ // hydrate must not echo it back, while an edit restoring a pre-hydrate
+ // value differs from this baseline and still persists (ddd-hy2 audit).
+ lastSentPayload = JSON.stringify(store.dehydrateStore())
+ await nextTick()
+ if (logMode) console.log('🔓🟢 unlocking changes')
+ blockUpdate.value = false
+ })
+
+ return { ...dispatch }
+ }
+
+ const relayVue = {
+ install(app) {
+ app.provide('dispatch', dispatch)
+ }
+ }
+
+ return {
+ relayPinia,
+ relayVue
+ }
+}
diff --git a/cypher2/src/rollTemplates/guidedCard.js b/cypher2/src/rollTemplates/guidedCard.js
new file mode 100644
index 00000000..30747d08
--- /dev/null
+++ b/cypher2/src/rollTemplates/guidedCard.js
@@ -0,0 +1,67 @@
+// Pure presentation for the guided-roll chat card (spec ③ §4).
+// Math lives in dice/rolls.js; this module only builds display strings.
+import { skillEase } from '@/dice/rolls.js'
+
+const signed = (n) => (n >= 0 ? `+${n}` : `−${-n}`)
+
+export const easesLine = ({ skill, assets, effortLevels, eased }) => {
+ const parts = []
+ // skillEase, never SKILL_EASES[rating] — one source with easedSteps (ddd-c8f)
+ // so the card can never describe a different number than the roll used.
+ if (skill) parts.push(`${skill.name} (${skill.rating}) ${signed(skillEase(skill.rating))}`)
+ const a = Math.min(Math.max(assets, 0), 2)
+ if (a > 0) parts.push(a === 1 ? 'asset +1' : `assets +${a}`)
+ if (effortLevels > 0) parts.push(`Effort ${effortLevels}`)
+ if (parts.length === 0) return 'No eases'
+ const label = eased >= 0 ? `Eased ${eased}` : `Hindered ${-eased}`
+ return `${label}: ${parts.join(' · ')}`
+}
+
+// Zero-cost wording shared by the chat card and the modal's live preview —
+// one source so the preview can never drift from the posted card.
+export const noSpendLine = (rawCost) =>
+ rawCost > 0 ? `No points spent (Edge covered ${rawCost})` : 'No points spent'
+
+export const spendLine = ({ cost, rawCost, edge, statLabel, poolAfter, poolMax, refunded = false }) => {
+ if (cost === 0) return noSpendLine(rawCost)
+ // Natural 20 (book rule): the cost drops to 0 and the points come back.
+ if (refunded) return `Natural 20 — ${cost} ${statLabel} refunded · pool ${poolAfter}/${poolMax}`
+ const detail = edge > 0 ? ` (${rawCost} − ${edge} Edge)` : ''
+ return `Spent ${cost} ${statLabel}${detail} · pool ${poolAfter}/${poolMax}`
+}
+
+export const verdictLine = (interp) => {
+ if (interp.die === null) return `Automatic success — difficulty ${interp.difficulty} eased to 0`
+ if (interp.difficulty === null) {
+ if (interp.eased === 0) return `Beats difficulty ${interp.beats}`
+ // Difficulty domain caps at 10: a die-20 (beats 6) with 7 eases is "up
+ // to 10", not a fictional 13 (3rd audit F4). A negative projection means
+ // the roll beats NOTHING: die 1 + inability cannot even beat difficulty
+ // 0, which the hindrance makes effective difficulty 1 — never render
+ // that as "effectively 0" (5th audit F4).
+ const capable = Math.min(10, interp.beats + interp.eased)
+ if (interp.eased > 0) return `Beats difficulty ${interp.beats} (+${interp.eased} eased → up to ${capable})`
+ return capable < 0
+ ? `Beats difficulty ${interp.beats} (−${-interp.eased} hindered → beats nothing)`
+ : `Beats difficulty ${interp.beats} (−${-interp.eased} hindered → effectively ${capable})`
+ }
+ return interp.success
+ ? `Success vs difficulty ${interp.difficulty} → ${interp.effective}`
+ : `Failure vs difficulty ${interp.difficulty} → ${interp.effective}`
+}
+
+export const guidedRollTemplateData = ({ statLabel, skill, assets, effortLevels, interp, cost, rawCost, edge, poolAfter, poolMax, refunded = false }) => ({
+ stat: statLabel,
+ die: interp.die,
+ auto: interp.die === null,
+ verdict: verdictLine(interp),
+ tone: interp.difficulty === null ? null : interp.success ? 'success' : 'failure',
+ eases: easesLine({ skill, assets, effortLevels, eased: interp.eased }),
+ spend: spendLine({ cost, rawCost, edge, statLabel, poolAfter, poolMax, refunded }),
+ // Specials are success-gated (5th audit F5): the book grants 17–20 bonus
+ // damage/effects "in addition to the normal results" of a task that
+ // succeeds — so a KNOWN failure suppresses them. GM Intrusion (natural 1)
+ // is not success-dependent. No-difficulty rolls keep the quick-roll
+ // behavior: outcome unknown at post time.
+ special: interp.success === false && interp.special?.code !== 'gm-intrusion' ? null : interp.special ?? null
+})
diff --git a/cypher2/src/rollTemplates/host.scss b/cypher2/src/rollTemplates/host.scss
new file mode 100644
index 00000000..4a4cb201
--- /dev/null
+++ b/cypher2/src/rollTemplates/host.scss
@@ -0,0 +1,88 @@
+.cypher-roll {
+ border: 1px solid #7b5cd6;
+ border-radius: 6px;
+ padding: 0.5rem 0.75rem;
+ font-family: system-ui, sans-serif;
+
+ &__stat {
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ font-size: 0.8rem;
+ }
+ &__die {
+ font-size: 1.6rem;
+ font-weight: 700;
+ line-height: 1.2;
+ }
+ &__beats {
+ font-size: 0.9rem;
+ }
+ &__die--auto {
+ color: #1a6b1a;
+ }
+ &__verdict {
+ font-size: 0.9rem;
+ border-top: 1px solid #ddd;
+ padding-top: 0.25rem;
+ margin-top: 0.25rem;
+ &--success { color: #1a6b1a; font-weight: 600; }
+ &--failure { color: #8a1a1a; font-weight: 600; }
+ }
+ &__detail {
+ font-size: 0.8rem;
+ opacity: 0.75;
+ }
+ &__special {
+ margin-top: 0.25rem;
+ font-weight: 600;
+ color: #a12727;
+ }
+ // The recovery card's wound-removal line (ddd-5v9): rule-separated from the
+ // total like the verdict, body-sized because it is instruction, not detail.
+ &__wounds {
+ font-size: 0.85rem;
+ border-top: 1px solid #ddd;
+ padding-top: 0.25rem;
+ margin-top: 0.25rem;
+ }
+}
+
+// The item card (item-contents spec §4). A sibling of .cypher-roll, not a variant:
+// it carries prose, not a die.
+//
+// SKIN-NEUTRAL BY CONSTRUCTION, and that is correct rather than a gap. host.css is
+// loaded into Roll20's chat pane, outside .cypher-sheet, so it can never see
+// [data-theme]. The existing roll card has the same property.
+.cypher-item {
+ border: 1px solid #7b5cd6;
+ border-radius: 6px;
+ padding: 0.5rem 0.75rem;
+ font-family: system-ui, sans-serif;
+
+ &__title {
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ font-size: 0.9rem;
+ }
+ &__fields {
+ font-size: 0.8rem;
+ opacity: 0.75;
+ }
+ &__source {
+ font-size: 0.75rem;
+ font-style: italic;
+ opacity: 0.6;
+ }
+ // pre-wrap, NOT the default. Descriptions are multi-paragraph textareas; without
+ // this every ability arrives in chat as one run-on paragraph, which would reproduce
+ // the exact readability complaint this spec exists to fix, in a second venue.
+ &__prose {
+ white-space: pre-wrap;
+ font-size: 0.9rem;
+ border-top: 1px solid #ddd;
+ padding-top: 0.35rem;
+ margin-top: 0.35rem;
+ }
+}
diff --git a/cypher2/src/rollTemplates/index.hbs b/cypher2/src/rollTemplates/index.hbs
new file mode 100644
index 00000000..c079124c
--- /dev/null
+++ b/cypher2/src/rollTemplates/index.hbs
@@ -0,0 +1,52 @@
+{{#if statRoll}}
+
+
{{statRoll.stat}}
+
{{statRoll.die}}
+
Beats difficulty {{statRoll.beats}}
+ {{#if statRoll.special}}
+
{{statRoll.special.label}}
+ {{/if}}
+
+{{/if}}
+{{#if guidedRoll}}
+
+
{{guidedRoll.stat}}
+ {{#if guidedRoll.auto}}
+
Auto
+ {{else}}
+
{{guidedRoll.die}}
+ {{/if}}
+
{{guidedRoll.verdict}}
+
{{guidedRoll.eases}}
+
{{guidedRoll.spend}}
+ {{#if guidedRoll.special}}
+
{{guidedRoll.special.label}}
+ {{/if}}
+
+{{/if}}
+{{#if recoveryRoll}}
+
+
{{recoveryRoll.title}}
+
{{recoveryRoll.total}}
+
{{recoveryRoll.breakdown}}
+
+
10 min: Remove all minor wounds
+
1 hr: Remove one moderate wound or all minor wounds
+
10 hrs: Remove all moderate wounds and, with a successful difficulty 6 Might task, remove one major wound; in place of removing one moderate wound, you can remove all minor wounds
+
+
+{{/if}}
+{{#if itemCard}}
+
+
{{itemCard.title}}
+ {{#if itemCard.fields}}
+
{{itemCard.fields}}
+ {{/if}}
+ {{#if itemCard.source}}
+
{{itemCard.source}}
+ {{/if}}
+ {{#if itemCard.prose}}
+
{{itemCard.prose}}
+ {{/if}}
+
+{{/if}}
diff --git a/cypher2/src/rollTemplates/index.js b/cypher2/src/rollTemplates/index.js
new file mode 100644
index 00000000..b33ae236
--- /dev/null
+++ b/cypher2/src/rollTemplates/index.js
@@ -0,0 +1,10 @@
+import handlebars from 'handlebars'
+import template from './index.hbs?raw'
+
+const rollTemplates = {
+ base: handlebars.compile(template)
+}
+
+export const createRollTemplate = (parameters) => {
+ return rollTemplates.base(parameters)
+}
diff --git a/cypher2/src/rollTemplates/itemCard.js b/cypher2/src/rollTemplates/itemCard.js
new file mode 100644
index 00000000..7096d0be
--- /dev/null
+++ b/cypher2/src/rollTemplates/itemCard.js
@@ -0,0 +1,34 @@
+// Pure presentation for the item chat card (item-contents spec §4).
+// Segments own the per-list descriptor (§3.1) because the field wording is per-list
+// knowledge; this module owns the projection rules every list shares — falsy fields
+// drop, an empty section is absent, nothing is trusted to be a string — so no segment
+// repeats them and no two lists can drift on the shared rules.
+//
+// The separator is joined HERE rather than emitted by the template. Handlebars would
+// need an {{#unless @last}} to avoid a trailing '·', and that is exactly the kind of
+// detail that survives review and ships. A joined string cannot grow a stray one.
+const FIELD_SEPARATOR = ' · '
+
+// Trim-to-null: a textarea a player opened and closed holds '\n', which is truthy and
+// would render an empty prose block with a border around it.
+//
+// BOOLEANS ARE DROPPED, not stringified. Descriptors write `row.enabler && 'Enabler'`,
+// so an unset flag arrives as literal `false` — and String(false) is the truthy string
+// 'false', which would print on the card. Numbers are NOT dropped: a currency amount of
+// 0 is a real value the card must show.
+const text = (v) => {
+ if (v == null || typeof v === 'boolean') return null
+ const s = String(v).trim()
+ return s.length ? s : null
+}
+
+export const itemCardTemplateData = (list, contents = {}) => ({
+ list,
+ // A row whose name the player cleared still posts. `rowWhat` says "unnamed row N" on
+ // the sheet, where the index is visible; a card in the chat log has no list around it
+ // for an index to mean anything, so it says this instead.
+ title: text(contents.title) ?? 'Unnamed',
+ fields: (contents.fields ?? []).map(text).filter(Boolean).join(FIELD_SEPARATOR) || null,
+ source: text(contents.source),
+ prose: text(contents.prose)
+})
diff --git a/cypher2/src/rollTemplates/recoveryCard.js b/cypher2/src/rollTemplates/recoveryCard.js
new file mode 100644
index 00000000..15a9ce04
--- /dev/null
+++ b/cypher2/src/rollTemplates/recoveryCard.js
@@ -0,0 +1,12 @@
+// Pure presentation for the recovery-roll chat card (ddd-5v9; reworked by
+// ddd-4uhf). Recoveries can be used in ANY order — owner ruling — so the card
+// never guesses which slot is being spent: every roll reports the total plus
+// the full wound-removal summary for the three timed tiers. That copy is
+// static markup in index.hbs, not data — the source's emphasized "all" needs
+// an that Handlebars data fields would escape — so this module carries
+// only the numbers.
+export const recoveryRollTemplateData = ({ die, bonus }) => ({
+ title: 'Recovery',
+ total: die + bonus,
+ breakdown: `1d6 (${die}) + ${bonus} — points to distribute among pools`
+})
diff --git a/cypher2/src/stores/index.js b/cypher2/src/stores/index.js
new file mode 100644
index 00000000..fe70bc14
--- /dev/null
+++ b/cypher2/src/stores/index.js
@@ -0,0 +1,40 @@
+import { defineStore } from 'pinia'
+import { useMetaStore } from '@/stores/metaStore.js'
+import { useSheetStore } from '@/stores/sheetStore.js'
+
+export const DEFAULT_CHARACTER_NAME = 'Unnamed Character'
+
+/*
+ * Master store: combines meta (profile) + sheet (attributes) for the relay.
+ * Unlike the Dog sheet quickstart, the sheet store dehydrates to the
+ * attributes ROOT (not attributes.sheet) so contract paths appear verbatim
+ * in the dehydrated document (beacon-mapping §2); `ui` is its own top-level
+ * key (§4) and the relay stamps `updateId` beside them.
+ */
+export const useAppStore = defineStore('app', () => {
+ const stores = {
+ meta: useMetaStore(),
+ sheet: useSheetStore()
+ }
+ const storeRegistry = Object.keys(stores)
+
+ const dehydrateStore = () => {
+ const { name, bio, gmNotes, avatar } = stores.meta.dehydrate()
+ return { name, bio, gmNotes, avatar, attributes: stores.sheet.dehydrate() }
+ }
+
+ const hydrateStore = (attributes, profile) => {
+ if (attributes) stores.sheet.hydrate(attributes)
+ if (profile) stores.meta.hydrate(profile)
+ }
+
+ const setPermissions = (owned, gm) => {
+ stores.meta.permissions.isOwner = owned
+ stores.meta.permissions.isGM = gm
+ }
+ const setCampaignId = (campaignId) => {
+ stores.meta.campaignId = campaignId
+ }
+
+ return { ...stores, storeRegistry, dehydrateStore, hydrateStore, setPermissions, setCampaignId }
+})
diff --git a/cypher2/src/stores/metaStore.js b/cypher2/src/stores/metaStore.js
new file mode 100644
index 00000000..4fe3de84
--- /dev/null
+++ b/cypher2/src/stores/metaStore.js
@@ -0,0 +1,55 @@
+import { defineStore } from 'pinia'
+import { reactive, ref } from 'vue'
+
+/* Every Character, regardless of sheet, has these meta fields
+ * and they must be saved to firebase in this specific way.
+ * This store can be reused as-is for any other Vue project.
+ * */
+export const useMetaStore = defineStore('meta', () => {
+ const id = ref('')
+ const name = ref('')
+ const avatar = ref('')
+ const bio = ref('')
+ const gmNotes = ref('')
+ const token = ref({})
+ const campaignId = ref(null)
+ const permissions = reactive({
+ isOwner: false,
+ isGM: false
+ })
+
+ // Handles retrieving these values from the store
+ const dehydrate = () => {
+ return {
+ name: name.value,
+ avatar: avatar.value,
+ bio: bio.value,
+ gmNotes: gmNotes.value,
+ campaignId: campaignId.value
+ }
+ }
+
+ // Handles updating these values in the store.
+ const hydrate = (hydrateStore) => {
+ id.value = hydrateStore.id ?? id.value
+ name.value = hydrateStore.name ?? name.value
+ avatar.value = hydrateStore.avatar ?? avatar.value
+ bio.value = hydrateStore.bio ?? bio.value
+ gmNotes.value = hydrateStore.gmNotes ?? gmNotes.value
+
+ token.value = hydrateStore.token ?? token.value
+ }
+
+ return {
+ id,
+ name,
+ avatar,
+ bio,
+ gmNotes,
+ token,
+ permissions,
+ campaignId,
+ dehydrate,
+ hydrate
+ }
+})
diff --git a/cypher2/src/stores/sheetStore.js b/cypher2/src/stores/sheetStore.js
new file mode 100644
index 00000000..2090a0e3
--- /dev/null
+++ b/cypher2/src/stores/sheetStore.js
@@ -0,0 +1,501 @@
+import { defineStore } from 'pinia'
+import { computed, ref } from 'vue'
+import { v4 as uuidv4 } from 'uuid'
+import { arrayToObject, objectToArray } from '@/utility/objectify'
+import { dispatchRef, initValues } from '@/relay/relay.js'
+import { createRollTemplate } from '@/rollTemplates/index.js'
+import { interpretStatRoll, interpretGuidedRoll, easedSteps, effortCost, rawEffortCost } from '@/dice/rolls.js'
+import { guidedRollTemplateData } from '@/rollTemplates/guidedCard.js'
+import { recoveryRollTemplateData } from '@/rollTemplates/recoveryCard.js'
+import { itemCardTemplateData } from '@/rollTemplates/itemCard.js'
+
+// The nine contract arrays, in schema order.
+export const ARRAY_KEYS = [
+ 'skills', 'abilities', 'attacks', 'equipment', 'cyphers',
+ 'artifacts', 'powerShifts', 'currencies', 'arcs'
+]
+
+// Default rows are schema-valid (every `name` has minLength 1), no _id —
+// callers stamp one at creation (beacon-mapping §3.2).
+export const rowFactories = {
+ skills: () => ({ name: 'New skill', rating: 'practiced', pool: null, asset: 0, isProficiency: false, source: '', description: '' }),
+ abilities: () => ({ name: 'New ability', cost: null, pools: [], enabler: false, activation: '', source: '', description: '' }),
+ attacks: () => ({ name: 'New attack', pool: 'might', weaponClass: 'light', damage: 0, skillRating: 'practiced', range: null, modifier: null, notes: '' }),
+ equipment: () => ({ name: 'New equipment', level: null, quantity: 1, notes: '' }),
+ cyphers: () => ({ name: 'New cypher', displayName: '', level: null, cypherKind: null, power: null, activated: false, description: '' }),
+ artifacts: () => ({ name: 'New artifact', level: null, depletion: null, form: '', description: '' }),
+ powerShifts: () => ({ name: 'New power shift', shifts: 1, description: '' }),
+ currencies: () => ({ name: 'New currency', amount: 0 }),
+ arcs: () => ({ name: 'New arc', description: '', steps: [] })
+}
+
+// The recovery track's standard four boxes, in book order (order is positional
+// rest duration — beacon-mapping §3.3). A factory, not a shared constant: slot
+// objects are mutated in place by the checkboxes.
+export const STANDARD_SLOT_KINDS = ['action', 'tenMinutes', 'oneHour', 'tenHours']
+export const defaultRecoverySlots = () =>
+ STANDARD_SLOT_KINDS.map((kind) => ({ kind, used: false, note: '' }))
+
+const sheetStore = () => {
+ // Scalars and nested objects: schema paths verbatim (beacon-mapping §2).
+ // Defaults mirror fixtures/valid/blank-tier1.json — pools 10/10/10 and
+ // cypherLimit 2 are neutral seeds, wounds 3/3/3 is the book default.
+ const blankSentence = () => ({
+ descriptor: '', secondDescriptor: '', type: '', focus: '', secondFocus: '', species: ''
+ })
+ const sentence = ref(blankSentence())
+ const tier = ref(1)
+ const effort = ref(1)
+ const xp = ref(0)
+ const storyXp = ref(0)
+ const resourcePoints = ref(0)
+ const rank = ref(null)
+ const advancement = ref({ stats: false, effort: false, edge: false, skill: false, other: false })
+ const pools = ref({
+ might: { current: 10, max: 10, edge: 0 },
+ speed: { current: 10, max: 10, edge: 0 },
+ intellect: { current: 10, max: 10, edge: 0 }
+ })
+ const recovery = ref({ bonus: 1, slots: defaultRecoverySlots() })
+ const wounds = ref({
+ minor: { current: 0, max: 3 },
+ moderate: { current: 0, max: 3 },
+ major: { current: 0, max: 3 }
+ })
+ const shield = ref(null)
+ const armor = ref(0)
+ const armorModifiers = ref('')
+ const cypherLimit = ref(2)
+ const genre = ref('')
+ const subgenre = ref('')
+ const portraitUrl = ref('')
+
+ const skills = ref([])
+ const abilities = ref([])
+ const attacks = ref([])
+ const equipment = ref([])
+ const cyphers = ref([])
+ const artifacts = ref([])
+ const powerShifts = ref([])
+ const currencies = ref([])
+ const arcs = ref([])
+
+ const background = ref('')
+ const notes = ref('')
+
+ // Sheet-local state: outside the contract (beacon-mapping §4).
+ // ui is a PRESENTATION branch, not a contract path: dehydrate() ships it alongside
+ // the contract paths and hydrate() merges it back, so the two segment keys,
+ // guidedRoll and theme persist per character without touching
+ // cypher-character.schema.json or the exported document (exporter.js never reads
+ // ui). Spec amendment 6; spec ⑦ §2.3 for the activeTab -> two-key replacement.
+ const ui = ref({
+ characterSegment: 'skills',
+ kitSegment: 'attacks',
+ guidedRoll: false,
+ theme: 'base',
+ // Item cards only. Roll cards stay public whatever this says — a sheet whose
+ // rolls could go silent would be a different feature (item-contents spec §5).
+ whisperItemCards: false
+ })
+
+ // A WHITELIST, not a spread. spec ⑦ §5 drops ui.activeTab rather than mapping it,
+ // and `{...ui.value, ...s.ui}` would defeat that: a pre-bead-2 character's stored
+ // activeTab would merge straight back in, and since dehydrate() ships ui wholesale
+ // it would be re-persisted forever. Unknown keys from a future sheet version are
+ // dropped for the same reason — this branch is owned here, not by the payload.
+ const UI_KEYS = ['characterSegment', 'kitSegment', 'guidedRoll', 'theme', 'whisperItemCards']
+
+ const arrays = { skills, abilities, attacks, equipment, cyphers, artifacts, powerShifts, currencies, arcs }
+
+ const addRow = (key) => {
+ arrays[key].value.push({ _id: uuidv4(), ...rowFactories[key]() })
+ }
+ const removeRow = (key, id) => {
+ const i = arrays[key].value.findIndex((r) => r._id === id)
+ if (i >= 0) arrays[key].value.splice(i, 1)
+ }
+
+ // Visibility is an ARGUMENT, not a store read. post() is shared by the roll cards
+ // and the item cards, and only the item cards are governed by ui.whisperItemCards
+ // (item-contents spec §5) — a branch that read the flag in here would silence rolls
+ // too, and every existing caller would keep compiling.
+ const post = (content, { whisper = false } = {}) =>
+ dispatchRef.value.post({
+ characterId: initValues.character.id,
+ content,
+ options: { whisper: whisper ? 'gm' : undefined }
+ })
+
+ // Post one row's contents to chat (item-contents spec §4.1). The per-list field
+ // wording lives in the segment's `contents` descriptor; the shared projection rules
+ // live in itemCard.js. This is the seam between them and owns neither.
+ const postItem = (list, contents) =>
+ post(createRollTemplate({ itemCard: itemCardTemplateData(list, contents) }), {
+ whisper: ui.value.whisperItemCards
+ })
+
+ // Quick roll: 1d20 on a stat. Reports the ladder; NEVER deducts pool points.
+
+ const rollStat = async (statName) => {
+ const { results } = await dispatchRef.value.roll({ rolls: { [statName]: '1d20' } })
+ const die = results[statName].results.rolls[0].results[0]
+ const stat = statName.charAt(0).toUpperCase() + statName.slice(1)
+ return post(createRollTemplate({ statRoll: { stat, ...interpretStatRoll(die) } }))
+ }
+
+ // Recovery roll (ddd-5v9; tier inference dropped by ddd-4uhf): recoveries
+ // can be used in ANY order — owner ruling — so the card never guesses which
+ // slot is being spent. 1d6 + bonus; the card carries the full three-tier
+ // wound-removal summary instead. The rollStat shape, not rollGuided's:
+ // nothing is mutated — the slot checkboxes stay player-owned manual state —
+ // and the bonus is snapshotted BEFORE the await so a mid-flight edit cannot
+ // rewrite the card.
+ const rollRecovery = async () => {
+ const bonus = recovery.value.bonus
+ const { results } = await dispatchRef.value.roll({ rolls: { recovery: '1d6' } })
+ const die = results.recovery.results.rolls[0].results[0]
+ return post(createRollTemplate({ recoveryRoll: recoveryRollTemplateData({ die, bonus }) }))
+ }
+
+ // Guided roller (spec ③ + ddd-669y). rollerStat / rollerSkillId /
+ // rollerSession are transient UI state — deliberately NOT in dehydrate():
+ // a half-open roller must never persist or export.
+ //
+ // rollerStat alone can no longer express "open": a poolless skill's entry
+ // (ddd-669y) opens the roller with NO stat chosen, so the open predicate is
+ // rollerOpen and every "an open roller owns the session" guard reads it.
+ // rollerSession is the modal's remount key — bumped once per OPEN, stable
+ // within one, because the modal's own pool select now writes rollerStat
+ // mid-open and a rollerStat-keyed modal would remount and wipe its state on
+ // every pool change.
+ const rollerStat = ref(null)
+ const rollerSkillId = ref(null)
+ const rollerSession = ref(0)
+ const rollerOpen = computed(() => rollerStat.value !== null || rollerSkillId.value !== null)
+
+ const rollIntent = (statName) => {
+ // An open roller owns the session UNCONDITIONALLY (4th audit F2): the
+ // guard sits above the toggle branch, so even a hydrate flipping the
+ // toggle off mid-open cannot let an intent fall through to a free quick
+ // roll behind the modal — and the session-keyed modal never sees a
+ // truthy→truthy stat swap that would reuse stale transient state (3rd
+ // audit F8).
+ if (rollerOpen.value) return
+ if (ui.value.guidedRoll) {
+ rollerSession.value += 1
+ rollerStat.value = statName
+ return
+ }
+ return rollStat(statName)
+ }
+
+ // Per-skill entry (ddd-669y): opens the guided roller REGARDLESS of the
+ // ui.guidedRoll setting — an explicit per-row button is its own opt-in, the
+ // setting only governs what a bare pool click means. The skill's pool
+ // preselects when it has one (changeable in the modal — owner ruling);
+ // poolless skills open with no stat and the modal gates Roll until one is
+ // picked. Proficiencies never roll (MCG §3.6): the row hides the button,
+ // and this guard holds when a stale id arrives anyway.
+ const rollSkill = (skillId) => {
+ if (rollerOpen.value) return
+ const row = skills.value.find((r) => r._id === skillId)
+ if (!row || row.isProficiency) return
+ rollerSession.value += 1
+ rollerSkillId.value = skillId
+ // Only a LEGAL pool preselects (audit P2): hydrate preserves out-of-enum
+ // pool values by design (ddd-9ir), and handing one to rollerStat would
+ // enable Roll against a pool that does not exist — rollGuided then throws,
+ // and a prototype key like __proto__ would even resolve to an inherited
+ // object. Object.hasOwn against the live pools graph, the poolLabel shape;
+ // an unknown pool opens on the sentinel and the player picks.
+ rollerStat.value = typeof row.pool === 'string' && Object.hasOwn(pools.value, row.pool) ? row.pool : null
+ }
+
+ // The roller owns pool costs (spec ① decision). Concurrency policy (audit
+ // passes 2–3): the spend is RESERVED synchronously at commit — no await
+ // sits between the affordability check and the deduction, so the check can
+ // never go stale and the card reports reservation-time truth. Affordability
+ // is checked against min(current, max): PoolCard clamps its fields
+ // independently, so current > max sheets exist and must not fund Effort
+ // with phantom points (3rd audit F2). Reservation and refund are exact
+ // ±cost on the SAME pool object — never negative (cost ≤ current by the
+ // check). The refund is an exact reversal, but an upward edit of that same
+ // object mid-flight can leave current above max afterward — tolerated,
+ // like any hand-edited overfull pool. If a mid-flight hydrate replaced
+ // the pools graph, the refund is SKIPPED — the newer write wins, like any
+ // sheet field (3rd audit F5). Promise.race cannot cancel a Beacon
+ // dispatch, so a timeout refunds AND stays subscribed: dice (or an
+ // auto-success card) settling late re-deduct and finish, keeping "dice
+ // rolled ⇔ points spent" eventually consistent (3rd audit F1). A natural
+ // 20 refunds the spend (book rule, 3rd audit F3); a failed post after real
+ // dice undoes nothing — the dice hit the table. (Known, out of scope: the
+ // spec ② relay debounce can persist a stale pre-hydrate snapshot — a
+ // sheet-wide pre-existing race tracked as ddd-ej2; these writes ride that
+ // path by design, like every other field.)
+ const ROLL_TIMEOUT_MS = 15000
+ const TIMEOUT_ERROR = new Error('dispatch timeout')
+ const withTimeout = (promise, ms = ROLL_TIMEOUT_MS) => {
+ let timer
+ return Promise.race([
+ promise,
+ new Promise((_, reject) => { timer = setTimeout(() => reject(TIMEOUT_ERROR), ms) })
+ ]).finally(() => clearTimeout(timer))
+ }
+
+ const rollGuided = async ({ stat, skillId = null, assets = 0, effortLevels = 0, difficulty = null }) => {
+ // Resolution-boundary clamps (the modal mirrors both, but no caller may
+ // exceed them): Effort ≤ the character's Effort stat; difficulty 0–10.
+ // Policy: silent normalization — the card is built from the clamped
+ // values, so chat always shows what was actually charged.
+ const levels = Math.min(Math.max(effortLevels, 0), effort.value)
+ const diff = difficulty === null ? null : Math.min(Math.max(Math.floor(difficulty) || 0, 0), 10)
+
+ // Snapshot everything the card will render: after the awaits below, live
+ // objects may have been replaced or edited.
+ const pool = pools.value[stat]
+ const edge = pool.edge
+ const poolMax = pool.max
+ const available = Math.min(pool.current, Math.max(poolMax, 0))
+ const row = skillId === null ? null : (skills.value.find((r) => r._id === skillId) ?? null)
+ const skill = row ? { name: row.name, rating: row.rating } : null
+ const eased = easedSteps({ skillRating: skill?.rating ?? null, assets, effortLevels: levels })
+ const rawCost = rawEffortCost(levels)
+ const cost = effortCost(levels, edge)
+ if (cost > available) return { ok: false, reason: 'insufficient-pool' }
+
+ // Reserve — synchronous with the check above; nothing can interleave.
+ pool.current -= cost
+ const poolAfter = pool.current
+ const refund = () => { if (pools.value[stat] === pool) pool.current += cost }
+ const rededuct = () => {
+ const live = pools.value[stat]
+ live.current = Math.max(0, live.current - cost) // pool floor 0, whatever happened meanwhile
+ }
+
+ const statLabel = stat.charAt(0).toUpperCase() + stat.slice(1)
+ // Card pool figures always come as a PAIR from the same snapshot (4th
+ // audit F3): reservation-time by default, live-time whenever a branch
+ // reports the live current — never reservation-max with live-current.
+ const cardFor = (interp, { refunded = false, shownAfter = poolAfter, shownMax = poolMax } = {}) => createRollTemplate({
+ guidedRoll: guidedRollTemplateData({
+ statLabel, skill, assets, effortLevels: levels, interp, cost, rawCost, edge,
+ poolAfter: shownAfter, poolMax: shownMax, refunded
+ })
+ })
+
+ if (diff !== null && Math.max(0, diff - eased) === 0) {
+ const interp = { die: null, beats: null, special: null, eased, difficulty: diff, effective: 0, success: true, autoSuccess: true }
+ let posting
+ try {
+ // Inside try: a SYNCHRONOUS throw from post() must refund like any
+ // other failure — never escape with the reservation held (5th audit F3).
+ posting = post(cardFor(interp))
+ await withTimeout(posting)
+ } catch (err) {
+ refund()
+ // The card may still land after a timeout refund — spend re-applies.
+ // Accepted exception (5th audit F2): the card's HTML left with the
+ // post at reservation time; late settlement re-deducts the pool but
+ // cannot rewrite an already-submitted card — its figures stay the
+ // (internally consistent) reservation-time pair.
+ // Outer .catch for the same reason as the dice path below: a sync
+ // throw from rededuct() rejects the .then-returned promise.
+ if (err === TIMEOUT_ERROR) posting.then(() => rededuct(), () => {}).catch(() => {})
+ return { ok: false, reason: 'post-failed' }
+ }
+ return { ok: true }
+ }
+
+ // On-time finish: a natural 20 refunds the spend BEFORE the card is
+ // built. Non-refunded cards keep reporting reservation-time truth
+ // (documented policy); the nat-20 card reports the pool after its refund.
+ const finishRoll = (die) => {
+ const refunded = die === 20 && cost > 0
+ if (refunded) refund()
+ const live = pools.value[stat]
+ const shown = refunded ? { shownAfter: live.current, shownMax: live.max } : {}
+ return post(cardFor(interpretGuidedRoll({ die, eased, difficulty: diff }), { refunded, ...shown }))
+ }
+
+ let rolling
+ let die
+ try {
+ // Inside try: a synchronous throw refunds too (5th audit F3). A sync
+ // throw can never be TIMEOUT_ERROR, so the late-settlement branch
+ // below only runs with `rolling` defined.
+ rolling = dispatchRef.value.roll({ rolls: { [stat]: '1d20' } })
+ const { results } = await withTimeout(rolling)
+ die = results[stat].results.rolls[0].results[0]
+ } catch (err) {
+ refund()
+ if (err === TIMEOUT_ERROR) {
+ // Dice may still land after the timeout refund. Re-deduct and post
+ // then — except a late natural 20, which nets to zero: the timeout
+ // already refunded, so the pool is never touched again.
+ rolling.then(({ results }) => {
+ const lateDie = results[stat].results.rolls[0].results[0]
+ const refunded = lateDie === 20 && cost > 0
+ if (!refunded) rededuct()
+ const live = pools.value[stat] // settlement-time pair (4th audit F3)
+ return post(cardFor(interpretGuidedRoll({ die: lateDie, eased, difficulty: diff }),
+ { refunded, shownAfter: live.current, shownMax: live.max }))
+ }, () => {}).catch(() => {})
+ // ^ outer catch, not inner: a SYNCHRONOUS throw from post() rejects
+ // the .then-returned promise, which an inner .catch on post's own
+ // promise would never see (7th audit F4).
+ }
+ return { ok: false, reason: 'dispatch-failed' }
+ }
+ try {
+ await withTimeout(finishRoll(die))
+ } catch {
+ // Card lost but dice hit the table — the spend (or nat-20 refund) stands.
+ }
+ return { ok: true }
+ }
+
+ // Persistence: contract paths at the attributes root + the ui branch.
+ const dehydrate = () => ({
+ sentence: sentence.value,
+ tier: tier.value,
+ effort: effort.value,
+ xp: xp.value,
+ storyXp: storyXp.value,
+ resourcePoints: resourcePoints.value,
+ rank: rank.value,
+ advancement: advancement.value,
+ pools: pools.value,
+ recovery: recovery.value,
+ wounds: wounds.value,
+ shield: shield.value,
+ armor: armor.value,
+ armorModifiers: armorModifiers.value,
+ cypherLimit: cypherLimit.value,
+ genre: genre.value,
+ subgenre: subgenre.value,
+ ...Object.fromEntries(ARRAY_KEYS.map((k) => [k, arrayToObject(arrays[k].value)])),
+ background: background.value,
+ notes: notes.value,
+ portraitUrl: portraitUrl.value,
+ ui: ui.value
+ })
+
+ // Beacon persistence hardening: Firebase-backed storage drops null-valued
+ // keys on write and can hand nested arrays back as numeric-keyed objects,
+ // and the VTT host hands them back as '$__$' marker STRINGS in the
+ // onInit payload (sandbox ground truth, ddd-bt6). Restore each row to its
+ // schema shape — missing fields fall back to the row factory's defaults
+ // (which carry the schema's nulls), nested arrays are decoded from either
+ // readback form. A complete row passes through unchanged, so
+ // import/round-trip behavior is unaffected.
+ const ARRAY_MARKER = '$__$'
+ const decodeMarkerArray = (v, fallback) => {
+ try {
+ const parsed = JSON.parse(v.slice(ARRAY_MARKER.length))
+ return Array.isArray(parsed) ? parsed : fallback
+ } catch {
+ return fallback
+ }
+ }
+ const normalizeRow = (key, row) => {
+ const defaults = rowFactories[key]()
+ const out = { ...defaults, ...row }
+ for (const [field, dv] of Object.entries(defaults)) {
+ const v = out[field]
+ if (!Array.isArray(dv)) continue
+ if (typeof v === 'string' && v.startsWith(ARRAY_MARKER)) {
+ out[field] = decodeMarkerArray(v, dv)
+ } else if (v && typeof v === 'object' && !Array.isArray(v)) {
+ out[field] = Object.values(v)
+ }
+ }
+ // ability cost is the one nested object with a nullable required member:
+ // a dropped cost.points must come back as null, not stay absent.
+ if (key === 'abilities' && out.cost && typeof out.cost === 'object' && out.cost.points === undefined) {
+ out.cost = { ...out.cost, points: null }
+ }
+ return out
+ }
+
+ // recovery.slots is the one nested array OUTSIDE the row path (beacon-mapping
+ // §3.3), so it needs the same Firebase-readback decoding normalizeRow gives
+ // row-nested arrays — plus the schemaVersion-1 migration: attributes written
+ // by the v1 sheet carry `used` (four booleans) instead of `slots`. Policy
+ // (beacon-mapping §5): hydrate HEALS persisted state — no validator runs
+ // here, and an unrecoverable slots value must fall back to the standard four
+ // rather than brick the export; strict rejection is the importer's job, not
+ // hydrate's.
+ const normalizeRecovery = (r) => {
+ if (!r || typeof r !== 'object') return undefined
+ const bonus = typeof r.bonus === 'number' ? r.bonus : 1
+ let slots = r.slots
+ if (typeof slots === 'string' && slots.startsWith(ARRAY_MARKER)) {
+ slots = decodeMarkerArray(slots, [])
+ } else if (slots && typeof slots === 'object' && !Array.isArray(slots)) {
+ slots = Object.values(slots) // numeric keys iterate ascending — order preserved
+ }
+ if (!Array.isArray(slots)) slots = []
+ slots = slots
+ .filter((s) => s && typeof s === 'object')
+ .map((s) => {
+ const { kind = 'action', used = false, note = '' } = s
+ return { kind, used, note }
+ })
+ if (!slots.length && r.used && typeof r.used === 'object') {
+ // v1 shape: the four booleans map to the four standard slots, in order.
+ slots = STANDARD_SLOT_KINDS.map((kind) => ({ kind, used: r.used[kind] === true, note: '' }))
+ }
+ return { bonus, slots: slots.length ? slots : defaultRecoverySlots() }
+ }
+
+ const hydrate = (s) => {
+ if (!s) return
+ // Merge over the blank sentence: pre-v2 attributes carry only four keys, and
+ // a clobbering assignment would export a schema-invalid document.
+ if (s.sentence) sentence.value = { ...blankSentence(), ...s.sentence }
+ tier.value = s.tier ?? tier.value
+ effort.value = s.effort ?? effort.value
+ xp.value = s.xp ?? xp.value
+ storyXp.value = s.storyXp ?? storyXp.value
+ resourcePoints.value = s.resourcePoints ?? resourcePoints.value
+ // rank/shield: null is the only legal absent state, and Firebase drops
+ // null-valued keys on write. The dropped null does NOT come back as a
+ // missing key — Roll20's attribute layer materializes it as an EMPTY
+ // STRING (ddd-wbc, live-verified), so the heal must be type-checked:
+ // `?? null` would pass '' into the store and the export validator.
+ rank.value = Number.isInteger(s.rank) ? s.rank : null
+ advancement.value = s.advancement ?? advancement.value
+ pools.value = s.pools ?? pools.value
+ recovery.value = normalizeRecovery(s.recovery) ?? recovery.value
+ wounds.value = s.wounds ?? wounds.value
+ shield.value = s.shield && typeof s.shield === 'object' ? s.shield : null
+ armor.value = s.armor ?? armor.value
+ armorModifiers.value = s.armorModifiers ?? armorModifiers.value
+ cypherLimit.value = s.cypherLimit ?? cypherLimit.value
+ genre.value = s.genre ?? genre.value
+ subgenre.value = s.subgenre ?? subgenre.value
+ portraitUrl.value = s.portraitUrl ?? portraitUrl.value
+ ARRAY_KEYS.forEach((k) => {
+ if (s[k]) arrays[k].value = objectToArray(s[k]).map((row) => normalizeRow(k, row))
+ })
+ background.value = s.background ?? background.value
+ notes.value = s.notes ?? notes.value
+ const incoming = s.ui ?? {}
+ const nextUi = { ...ui.value }
+ for (const k of UI_KEYS) if (incoming[k] !== undefined) nextUi[k] = incoming[k]
+ ui.value = nextUi
+ }
+
+ return {
+ sentence, tier, effort, xp, storyXp, resourcePoints, rank,
+ advancement, pools, recovery, wounds, shield, armor, armorModifiers, cypherLimit,
+ genre, subgenre, portraitUrl,
+ skills, abilities, attacks, equipment, cyphers, artifacts, powerShifts, currencies, arcs,
+ background, notes, ui,
+ addRow, removeRow, postItem, rollStat, rollerStat, rollerSkillId, rollerSession, rollerOpen,
+ rollIntent, rollSkill, rollGuided, rollRecovery, dehydrate, hydrate
+ }
+}
+
+export const useSheetStore = defineStore('sheet', sheetStore)
diff --git a/cypher2/src/utility/clamp.js b/cypher2/src/utility/clamp.js
new file mode 100644
index 00000000..8c02bcfd
--- /dev/null
+++ b/cypher2/src/utility/clamp.js
@@ -0,0 +1,16 @@
+// Input clamps that keep hand-edited state inside the schema's floors,
+// so the store always exports a valid document (spec §5).
+export const clampInt = (v, min = 0) => Math.max(min, Math.floor(Number(v) || 0))
+export const clampNumber = (v, min = 0) => Math.max(min, Number(v) || 0)
+// equipment/cypher/artifact level: integer >= 1 or null ("no level")
+export const toNullableLevel = (v) => (v === '' || v === null || v === undefined ? null : clampInt(v, 1))
+
+// ddd-9sf: when a clamp REJECTS typed input the model does not change, Vue does
+// not re-render, and the box keeps text the document does not contain (level 1,
+// type 0, box reads 0 while store/export/chat say 1). Every clamped number
+// input's @change writes back through this DOM resync — enforced by the sweep
+// in clamp-resync.test.js. null renders as an empty box (nullable level).
+export const syncClamped = (event, value) => {
+ event.target.value = value ?? ''
+ return value
+}
diff --git a/cypher2/src/utility/objectify.js b/cypher2/src/utility/objectify.js
new file mode 100644
index 00000000..520879d8
--- /dev/null
+++ b/cypher2/src/utility/objectify.js
@@ -0,0 +1,45 @@
+/*
+This is a utility function that will handle converting an array into a list of objects in a firebase friendly format.
+ */
+export const arrayToObject = (array) => {
+ const isValidArray = array.every((item) => '_id' in item)
+
+ if (!isValidArray) throw new Error('Tried to objectify an array, but not every item had ids')
+
+ const newObject = {}
+
+ array.forEach((item, index) => {
+ const { _id, ...rest } = item
+
+ newObject[_id] = {
+ ...rest,
+ arrayPosition: index
+ }
+ })
+
+ return newObject
+}
+
+/*
+This is a utility function that will handle converting an object from firebase into an array.
+ */
+export const objectToArray = (object) => {
+ if (!object) return []
+
+ const newArray = []
+ const objectIds = Object.keys(object)
+
+ objectIds.forEach((key) => {
+ if (object[key]) {
+ const position = object[key].arrayPosition
+ const item = {
+ _id: key,
+ ...object[key],
+ arrayPosition: undefined
+ }
+ newArray[position] = item
+ }
+ })
+
+ return newArray.filter((x) => x)
+}
diff --git a/cypher2/vite.config.js b/cypher2/vite.config.js
new file mode 100644
index 00000000..4cefe97a
--- /dev/null
+++ b/cypher2/vite.config.js
@@ -0,0 +1,72 @@
+/* eslint-env node */
+import { fileURLToPath, URL } from 'node:url'
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import VueDevTools from 'vite-plugin-vue-devtools'
+import tailwindcss from '@tailwindcss/vite'
+
+// https://vitejs.dev/config/
+export default defineConfig(({ mode }) => ({
+ plugins: [
+ vue(),
+ vueJsx(),
+ VueDevTools(),
+ tailwindcss(),
+ ],
+ base:
+ mode === "production"
+ ? `${process.env.VITE_SHEET_PATH}/${process.env.VITE_SHEET_SHORT_NAME}/`
+ : "/",
+ build: {
+ target: 'esnext',
+ emptyOutDir: true,
+ minify: true,
+ cssCodeSplit: false,
+ rollupOptions: {
+ input: {
+ sheet: "src/main.js"
+ },
+ output: {
+ dir: "dist",
+ compact: false,
+ assetFileNames: (assetInfo) => {
+ const names = assetInfo.names ?? []
+ if (names.includes('style.css')) return 'sheet.css'
+ return 'assets/[name][extname]'
+ },
+ entryFileNames: "sheet.js",
+ minifyInternalExports: false
+ }
+ }
+ },
+ assetsInclude: ["**/*.hbs"],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ },
+ optimizeDeps: {
+ esbuildOptions: {
+ define: {
+ global: "globalThis"
+ }
+ }
+ },
+ server: {
+ cors: false,
+ // ddd-x61, ported from devils-dandy-dogs (this project was scaffolded from the Dog
+ // sheet before the fix landed there). The HMR client calls location.reload() on its
+ // own frame when the websocket closes uncleanly — exactly what a frozen background
+ // tab produces. Roll20 will NOT re-issue `init` to a frame that reloaded itself, so
+ // beacon-sdk's initRelay never resolves and the sandbox sheet is a silent blank
+ // field. `staging` is the sandbox mode that runs INSIDE Roll20, so it must never
+ // self-reload; `npm run dev` (development) mounts standalone and keeps full HMR.
+ //
+ // `ws` is the load-bearing one, NOT `hmr`: vite gates the websocket server on
+ // `server.ws === false`; `hmr: false` only suppresses update *sending*, leaving the
+ // socket open and the reload path live. See sandbox-relay-policy.test.js.
+ hmr: mode !== 'staging',
+ ws: mode !== 'staging'
+ }
+}))