@fonsecabarreto/genesis-gl-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +33 -0
- package/dist/Camera-DY_8gx3C.d.ts +45 -0
- package/dist/Core/classes/Material.d.ts +3 -0
- package/dist/Core/classes/Material.js +9 -0
- package/dist/Core/classes/Material.js.map +1 -0
- package/dist/Core/classes/Model.d.ts +5 -0
- package/dist/Core/classes/Model.js +7 -0
- package/dist/Core/classes/Model.js.map +1 -0
- package/dist/Core/classes/Renderer.d.ts +30 -0
- package/dist/Core/classes/Renderer.js +11 -0
- package/dist/Core/classes/Renderer.js.map +1 -0
- package/dist/Core/classes/Scene.d.ts +37 -0
- package/dist/Core/classes/Scene.js +7 -0
- package/dist/Core/classes/Scene.js.map +1 -0
- package/dist/Core/classes/Viewport.d.ts +37 -0
- package/dist/Core/classes/Viewport.js +7 -0
- package/dist/Core/classes/Viewport.js.map +1 -0
- package/dist/Core/domain/interfaces/Vectors.d.ts +4 -0
- package/dist/Core/domain/interfaces/Vectors.js +1 -0
- package/dist/Core/domain/interfaces/Vectors.js.map +1 -0
- package/dist/Core/index.d.ts +10 -0
- package/dist/Core/index.js +51 -0
- package/dist/Core/index.js.map +1 -0
- package/dist/Core/utils/get-overlap.d.ts +3 -0
- package/dist/Core/utils/get-overlap.js +11 -0
- package/dist/Core/utils/get-overlap.js.map +1 -0
- package/dist/Core/utils/load-glb.d.ts +101 -0
- package/dist/Core/utils/load-glb.js +697 -0
- package/dist/Core/utils/load-glb.js.map +1 -0
- package/dist/Core/utils/parse-obj.d.ts +10 -0
- package/dist/Core/utils/parse-obj.js +183 -0
- package/dist/Core/utils/parse-obj.js.map +1 -0
- package/dist/Editor/index.d.ts +364 -0
- package/dist/Editor/index.js +1737 -0
- package/dist/Editor/index.js.map +1 -0
- package/dist/Game/controls/KeyboardInput.d.ts +8 -0
- package/dist/Game/controls/KeyboardInput.js +7 -0
- package/dist/Game/controls/KeyboardInput.js.map +1 -0
- package/dist/Game/index.d.ts +45 -0
- package/dist/Game/index.js +353 -0
- package/dist/Game/index.js.map +1 -0
- package/dist/KeyboardControl-5w7Vm0J0.d.ts +18 -0
- package/dist/KeyboardInput-DTsfj3tE.d.ts +166 -0
- package/dist/Material-BGLkldxv.d.ts +74 -0
- package/dist/Model-CQvDXd-b.d.ts +302 -0
- package/dist/WebGLCore-DR7ZHJB0.d.ts +22 -0
- package/dist/chunk-3ULETMWF.js +144 -0
- package/dist/chunk-3ULETMWF.js.map +1 -0
- package/dist/chunk-5TAAXI6S.js +330 -0
- package/dist/chunk-5TAAXI6S.js.map +1 -0
- package/dist/chunk-6LS6AO5H.js +296 -0
- package/dist/chunk-6LS6AO5H.js.map +1 -0
- package/dist/chunk-JK2HEZAT.js +317 -0
- package/dist/chunk-JK2HEZAT.js.map +1 -0
- package/dist/chunk-P7QOKDLY.js +57 -0
- package/dist/chunk-P7QOKDLY.js.map +1 -0
- package/dist/chunk-QCQVJCSR.js +968 -0
- package/dist/chunk-QCQVJCSR.js.map +1 -0
- package/dist/chunk-SUNYSY45.js +81 -0
- package/dist/chunk-SUNYSY45.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/Editor/sections/materials/MaterialSpec.ts","../../src/Editor/sections/materials/MaterialStore.ts","../../src/Editor/sections/scene/SceneSpec.ts","../../src/Editor/sections/scene/SceneStore.ts","../../src/Editor/sections/scene/SceneSection.ts","../../src/Editor/EditorSidebar.ts","../../src/Editor/TopBar.ts","../../src/Editor/sections/models/ModelsSection.ts"],"sourcesContent":["/** Plain, JSON-serialisable description of a material preset. */\nexport interface MaterialSpec {\n /** Unique identifier (crypto.randomUUID). */\n id: string;\n /** Human-readable name shown in the UI. */\n name: string;\n\n /** RGBA albedo / base colour [0–1]. */\n albedoColor: [number, number, number, number];\n /** RGB diffuse colour [0–1]. */\n diffuse: [number, number, number];\n /** RGB ambient colour [0–1]. */\n ambientColor: [number, number, number];\n /** RGB specular colour [0–1]. */\n specular: [number, number, number];\n\n /** Phong shininess exponent. */\n shininess: number;\n /** Opacity (d / Tr). */\n dissolve: number;\n\n /** Skip lighting calculations and render with raw albedo. */\n unlit: boolean;\n /** Render both front and back faces. */\n doubleSided: boolean;\n\n /** Optional public path to a texture image (relative to /public). */\n texturePath?: string;\n /** When true the texture wraps with GL_REPEAT instead of CLAMP_TO_EDGE. */\n textureRepeat?: boolean;\n /** Physics friction coefficient [0–1]. Defaults to 0.75 when omitted. */\n friction?: number;\n}\n\n/** Create a spec with sensible defaults. */\nexport function createDefaultSpec(name = 'New Material'): MaterialSpec {\n return {\n id: crypto.randomUUID(),\n name,\n albedoColor: [1, 1, 1, 1],\n diffuse: [1, 1, 1],\n ambientColor: [0.1, 0.1, 0.1],\n specular: [0.3, 0.3, 0.3],\n shininess: 64,\n dissolve: 1,\n unlit: false,\n doubleSided: false,\n friction: 0.3,\n };\n}\n","import { createDefaultSpec, MaterialSpec } from './MaterialSpec';\n\nconst STORAGE_KEY = 'genesisgl__material_presets';\n\ntype StoreListener = (specs: MaterialSpec[]) => void;\n\nexport interface MaterialStoreOptions {\n /**\n * URL / public-folder path to a JSON file that seeds the store on {@link MaterialStore.init}.\n * Example: `'data/materials.json'`\n *\n * The file is fetched once with `fetch()` during init. If the fetch succeeds its\n * contents supersede anything already in `localStorage`.\n */\n filePath?: string;\n}\n\n/**\n * Manages a collection of {@link MaterialSpec} presets.\n *\n * - Automatically persists to `localStorage` on every change (synchronous).\n * - Call {@link init} once at startup to seed from a configurable JSON file.\n * - Supports exporting / importing the whole collection as a `.json` file.\n */\nexport class MaterialStore {\n private specs = new Map<string, MaterialSpec>();\n private listeners: StoreListener[] = [];\n private readonly filePath: string | null;\n\n constructor(options: MaterialStoreOptions = {}) {\n this.filePath = options.filePath ?? null;\n // Seed from localStorage immediately so the store is usable before init().\n this.loadFromStorage();\n }\n\n /**\n * Asynchronously loads materials from the configured {@link MaterialStoreOptions.filePath}.\n * Call this once during app / resource initialisation (e.g. inside `loadResources`).\n *\n * The file data is merged on top of any localStorage data; conflicting IDs are\n * overwritten by the file version.\n */\n async init(): Promise<void> {\n if (!this.filePath) return;\n try {\n const res = await fetch(this.filePath);\n if (!res.ok) {\n console.warn(\n `[MaterialStore] Could not load \"${this.filePath}\" (${res.status})`,\n );\n return;\n }\n const items = (await res.json()) as MaterialSpec[];\n for (const spec of items) this.specs.set(spec.id, spec);\n // Sync localStorage so subsequent reloads don't need the fetch.\n this.persist();\n this.emit();\n } catch {\n console.warn(`[MaterialStore] Failed to fetch \"${this.filePath}\"`);\n }\n }\n\n // ── CRUD ────────────────────────────────────────────────────\n\n getAll(): MaterialSpec[] {\n return [...this.specs.values()];\n }\n\n get(id: string): MaterialSpec | undefined {\n return this.specs.get(id);\n }\n\n /** Add a brand-new spec and return it. */\n create(name?: string): MaterialSpec {\n const spec = createDefaultSpec(name);\n this.specs.set(spec.id, spec);\n this.persist();\n this.emit();\n void this.syncToServer();\n return spec;\n }\n\n /** Replace an existing spec (matched by id). */\n update(spec: MaterialSpec): void {\n if (!this.specs.has(spec.id)) return;\n this.specs.set(spec.id, { ...spec });\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n /** Deep-clone a spec under a new id. */\n duplicate(id: string): MaterialSpec | undefined {\n const src = this.specs.get(id);\n if (!src) return undefined;\n const copy: MaterialSpec = {\n ...src,\n id: crypto.randomUUID(),\n name: `${src.name} (copy)`,\n albedoColor: [...src.albedoColor],\n diffuse: [...src.diffuse],\n ambientColor: [...src.ambientColor],\n specular: [...src.specular],\n };\n this.specs.set(copy.id, copy);\n this.persist();\n this.emit();\n void this.syncToServer();\n return copy;\n }\n\n delete(id: string): void {\n this.specs.delete(id);\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n // ── Server sync ──────────────────────────────────────────────\n\n /**\n * Write the full collection to the server's `materials.json` via the\n * `PUT /api/materials` endpoint provided by the Vite dev plugin.\n * Silently no-ops if no `filePath` was configured.\n */\n async syncToServer(): Promise<boolean> {\n if (!this.filePath) return false;\n try {\n const res = await fetch('/api/materials', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(this.getAll(), null, 2),\n });\n if (!res.ok) {\n console.warn(`[MaterialStore] Server sync failed (${res.status})`);\n }\n return res.ok;\n } catch {\n console.warn('[MaterialStore] syncToServer: network error');\n return false;\n }\n }\n\n // ── Persistence ──────────────────────────────────────────────\n\n private persist(): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(this.getAll()));\n } catch {\n console.warn('[MaterialStore] Failed to write to localStorage');\n }\n }\n\n private loadFromStorage(): void {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return;\n const items = JSON.parse(raw) as unknown as MaterialSpec[];\n for (const spec of items) this.specs.set(spec.id, spec);\n } catch {\n console.warn('[MaterialStore] Failed to read from localStorage');\n }\n }\n\n // ── File I/O ─────────────────────────────────────────────────\n\n /** Download the full collection as a `.json` file (defaults to the configured filePath name). */\n async exportToFile(filename?: string): Promise<void> {\n const defaultName = this.filePath\n ? this.filePath.split('/').pop() ?? 'materials.json'\n : 'materials.json';\n const name = filename ?? defaultName;\n const json = JSON.stringify(this.getAll(), null, 2);\n const blob = new Blob([json], { type: 'application/json' });\n\n // Use File System Access API when available, fallback to <a download>\n if ('showSaveFilePicker' in window) {\n try {\n const handle = await (\n window as typeof window & {\n showSaveFilePicker: (\n opts: unknown,\n ) => Promise<FileSystemFileHandle>;\n }\n ).showSaveFilePicker({\n suggestedName: name,\n types: [\n { description: 'JSON', accept: { 'application/json': ['.json'] } },\n ],\n });\n const writable = await handle.createWritable();\n await writable.write(blob);\n await writable.close();\n return;\n } catch {\n // user cancelled or API unavailable — fall through\n }\n }\n\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = name;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n /**\n * Open a file-picker, parse the JSON, and merge imported specs.\n * Existing specs with the same id are overwritten.\n */\n importFromFile(): Promise<void> {\n return new Promise((resolve) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = '.json,application/json';\n\n input.onchange = async () => {\n const file = input.files?.[0];\n if (!file) {\n resolve();\n return;\n }\n\n try {\n const text = await file.text();\n const items = JSON.parse(text) as unknown as MaterialSpec[];\n for (const spec of items) this.specs.set(spec.id, spec);\n this.persist();\n this.emit();\n } catch {\n console.error('[MaterialStore] Failed to parse imported file');\n }\n resolve();\n };\n\n input.click();\n });\n }\n\n // ── Subscriptions ────────────────────────────────────────────\n\n subscribe(fn: StoreListener): () => void {\n this.listeners.push(fn);\n return () => {\n this.listeners = this.listeners.filter((l) => l !== fn);\n };\n }\n\n private emit(): void {\n const all = this.getAll();\n for (const fn of this.listeners) fn(all);\n }\n}\n","import { Vector3 } from '../../../Core/domain/interfaces/Vectors';\n\n/** JSON-serialisable description of a single item placed in the scene. */\nexport interface SceneItemSpec {\n /** Unique identifier (crypto.randomUUID). */\n id: string;\n /** Human-readable label shown in the editor. */\n name: string;\n /**\n * Key used to look up the base model in the DI / resource container.\n * The model must have been loaded during resource initialisation.\n */\n resourceKey: string;\n\n translation: Vector3;\n rotation: Vector3;\n scale: Vector3;\n\n /**\n * Custom AABB override relative to translation:\n * `[offsetX, offsetY, offsetZ, width, height, depth]`.\n * When `null` or omitted the model's auto-computed bbox is used.\n */\n bounds?: [number, number, number, number, number, number] | null;\n\n /** Whether this item participates in collision detection. Defaults to `true`. */\n collider?: boolean;\n\n /**\n * Optional material name (from `materials.json`) to override the model's\n * default material. Applied to all meshes in the model at placement time.\n */\n materialKey?: string | null;\n}\n\n/** Top-level scene definition stored in `scene.json`. */\nexport interface SceneSpec {\n /** World position where the player spawns. */\n playerSpawn: Vector3;\n /** All placed models in the scene. */\n items: SceneItemSpec[];\n}\n\n/** Create a new scene item with sensible defaults. */\nexport function createDefaultSceneItem(\n name = 'New Item',\n resourceKey = '',\n): SceneItemSpec {\n return {\n id: crypto.randomUUID(),\n name,\n resourceKey,\n translation: [0, 0, 0],\n rotation: [0, 0, 0],\n scale: [1, 1, 1],\n bounds: null,\n collider: true,\n materialKey: null,\n };\n}\n\n/** Create an empty scene. */\nexport function createDefaultScene(): SceneSpec {\n return {\n playerSpawn: [0, 0, 0],\n items: [],\n };\n}\n","import { createDefaultScene, SceneItemSpec, SceneSpec } from './SceneSpec';\n\nconst STORAGE_KEY = 'genesisgl__scene';\n\ntype StoreListener = (spec: SceneSpec) => void;\n\nexport interface SceneStoreOptions {\n /**\n * URL / public-folder path to a JSON file that seeds the store on {@link SceneStore.init}.\n * Example: `'data/scene.json'`\n */\n filePath?: string;\n}\n\n/**\n * Manages the current scene definition ({@link SceneSpec}).\n *\n * Follows the same patterns as `MaterialStore`:\n * - Persists to `localStorage` on every change.\n * - Call {@link init} once at startup to load from a JSON file.\n * - Syncs back to the server via a PUT endpoint (Vite dev plugin).\n */\nexport class SceneStore {\n private scene: SceneSpec = createDefaultScene();\n private listeners: StoreListener[] = [];\n private readonly filePath: string | null;\n\n constructor(options: SceneStoreOptions = {}) {\n this.filePath = options.filePath ?? null;\n this.loadFromStorage();\n }\n\n // ── Initialisation ──────────────────────────────────────────\n\n async init(): Promise<void> {\n if (!this.filePath) return;\n try {\n const res = await fetch(this.filePath);\n if (!res.ok) {\n console.warn(\n `[SceneStore] Could not load \"${this.filePath}\" (${res.status})`,\n );\n return;\n }\n const data = (await res.json()) as SceneSpec;\n this.scene = data;\n this.persist();\n this.emit();\n } catch {\n console.warn(`[SceneStore] Failed to fetch \"${this.filePath}\"`);\n }\n }\n\n // ── Read ─────────────────────────────────────────────────────\n\n get(): SceneSpec {\n return this.scene;\n }\n\n getItems(): SceneItemSpec[] {\n return this.scene.items;\n }\n\n getItem(id: string): SceneItemSpec | undefined {\n return this.scene.items.find((i) => i.id === id);\n }\n\n getPlayerSpawn(): [number, number, number] {\n return [...this.scene.playerSpawn] as [number, number, number];\n }\n\n // ── Mutations ────────────────────────────────────────────────\n\n setPlayerSpawn(x: number, y: number, z: number): void {\n this.scene.playerSpawn = [x, y, z];\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n addItem(item: SceneItemSpec): void {\n this.scene.items.push(item);\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n updateItem(item: SceneItemSpec): void {\n const idx = this.scene.items.findIndex((i) => i.id === item.id);\n if (idx === -1) return;\n this.scene.items[idx] = { ...item };\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n deleteItem(id: string): void {\n this.scene.items = this.scene.items.filter((i) => i.id !== id);\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n /** Replace the entire scene definition. */\n setScene(spec: SceneSpec): void {\n this.scene = spec;\n this.persist();\n this.emit();\n void this.syncToServer();\n }\n\n // ── Server sync ──────────────────────────────────────────────\n\n async syncToServer(): Promise<boolean> {\n if (!this.filePath) return false;\n try {\n const res = await fetch('/api/scene', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(this.scene, null, 2),\n });\n if (!res.ok) {\n console.warn(`[SceneStore] Server sync failed (${res.status})`);\n }\n return res.ok;\n } catch {\n console.warn('[SceneStore] syncToServer: network error');\n return false;\n }\n }\n\n // ── Persistence ──────────────────────────────────────────────\n\n private persist(): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(this.scene));\n } catch {\n console.warn('[SceneStore] Failed to write to localStorage');\n }\n }\n\n private loadFromStorage(): void {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return;\n const data = JSON.parse(raw) as unknown as SceneSpec;\n if (data && Array.isArray(data.items)) {\n this.scene = data;\n }\n } catch {\n console.warn('[SceneStore] Failed to read from localStorage');\n }\n }\n\n // ── File I/O ─────────────────────────────────────────────────\n\n async exportToFile(filename = 'scene.json'): Promise<void> {\n const json = JSON.stringify(this.scene, null, 2);\n const blob = new Blob([json], { type: 'application/json' });\n\n if ('showSaveFilePicker' in window) {\n try {\n const handle = await (\n window as typeof window & {\n showSaveFilePicker: (\n opts: unknown,\n ) => Promise<FileSystemFileHandle>;\n }\n ).showSaveFilePicker({\n suggestedName: filename,\n types: [\n { description: 'JSON', accept: { 'application/json': ['.json'] } },\n ],\n });\n const writable = await handle.createWritable();\n await writable.write(blob);\n await writable.close();\n return;\n } catch {\n // user cancelled — fall through\n }\n }\n\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n importFromFile(): Promise<void> {\n return new Promise((resolve) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = '.json,application/json';\n\n input.onchange = async () => {\n const file = input.files?.[0];\n if (!file) {\n resolve();\n return;\n }\n try {\n const text = await file.text();\n const data = JSON.parse(text) as unknown as SceneSpec;\n if (data && Array.isArray(data.items)) {\n this.scene = data;\n this.persist();\n this.emit();\n }\n } catch {\n console.error('[SceneStore] Failed to parse imported file');\n }\n resolve();\n };\n\n input.click();\n });\n }\n\n // ── Subscriptions ────────────────────────────────────────────\n\n subscribe(fn: StoreListener): () => void {\n this.listeners.push(fn);\n return () => {\n this.listeners = this.listeners.filter((l) => l !== fn);\n };\n }\n\n private emit(): void {\n const spec = this.scene;\n for (const fn of this.listeners) fn(spec);\n }\n}\n","import { EditorTab } from '../../EditorSidebar';\nimport { createDefaultSceneItem, SceneItemSpec } from './SceneSpec';\nimport { SceneStore } from './SceneStore';\n\n/** Entry from models.json */\nexport interface ModelRegistryEntry {\n key: string;\n name: string;\n type: string;\n path?: string;\n description?: string;\n}\n\nexport interface SceneSectionOptions {\n /** URL to the models registry JSON file. */\n modelsFile?: string;\n /** Returns the list of material names currently available. */\n getMaterialNames?: () => string[];\n /** Renderer reference — used to toggle hitbox debug visualisation. */\n renderer?: { debug: boolean };\n}\n\n/**\n * Scene Editor — rendered as a tab inside the {@link EditorSidebar}.\n *\n * Lets the user:\n * – View / edit player spawn position.\n * – View / edit every scene item (translation, rotation, scale, bounds, collider).\n * – Add, duplicate, and delete items.\n * – Reload the game to apply changes.\n */\nexport class SceneSection {\n private root: HTMLElement | null = null;\n private listEl: HTMLElement | null = null;\n private selectedId: string | null = null;\n private formEl: HTMLElement | null = null;\n private unsub?: () => void;\n private modelRegistry: ModelRegistryEntry[] = [];\n private readonly getMaterialNames: () => string[];\n private readonly modelsFile: string | null;\n private readonly renderer: { debug: boolean } | null;\n private hitboxCheck: HTMLInputElement | null = null;\n\n private constructor(\n private readonly store: SceneStore,\n options: SceneSectionOptions = {},\n ) {\n this.modelsFile = options.modelsFile ?? null;\n this.getMaterialNames = options.getMaterialNames ?? (() => []);\n this.renderer = options.renderer ?? null;\n }\n\n // ── Factory ──────────────────────────────────────────────────\n\n static create(\n store: SceneStore,\n options?: SceneSectionOptions,\n ): SceneSection {\n return new SceneSection(store, options);\n }\n\n // ── Tab descriptor ───────────────────────────────────────────\n\n asTab(): EditorTab {\n return {\n id: 'scene',\n label: '🌍 Scene',\n buildContent: (c) => this.buildContent(c),\n onActivate: () => this.onActivate(),\n onDeactivate: () => this.onDeactivate(),\n destroy: () => this.unsub?.(),\n };\n }\n\n // ── Lifecycle ────────────────────────────────────────────────\n\n private onActivate(): void {\n // Load model registry if not loaded yet\n if (this.modelRegistry.length === 0 && this.modelsFile) {\n void fetch(this.modelsFile)\n .then((r) => r.json())\n .then((data: ModelRegistryEntry[]) => {\n this.modelRegistry = data;\n this.refreshForm(); // re-render form with dropdown populated\n })\n .catch(() =>\n console.warn('[SceneSection] Could not load models registry'),\n );\n }\n this.refreshList();\n this.refreshForm();\n }\n\n private onDeactivate(): void {\n /* nothing for now */\n }\n\n // ── Build ────────────────────────────────────────────────────\n\n private buildContent(container: HTMLElement): void {\n this.root = container;\n\n // ── Toolbar\n const toolbar = mk('div', TOOLBAR_STYLE);\n toolbar.appendChild(\n this.mkBtn('+ Item', () => this.onAdd(), 'Add scene item'),\n );\n toolbar.appendChild(\n this.mkBtn('❑', () => this.onDuplicate(), 'Duplicate selected'),\n );\n toolbar.appendChild(\n this.mkBtn('🗑', () => this.onDelete(), 'Delete selected'),\n );\n const reloadBtn = mk(\n 'button',\n BTN_STYLE + ';margin-left:auto;color:#6cf;border-color:#446;',\n );\n reloadBtn.textContent = '🔄 Reload Game';\n reloadBtn.title = 'Sync JSON then reload game to apply changes';\n reloadBtn.onclick = () => location.reload();\n toolbar.appendChild(reloadBtn);\n\n // ── Hitbox toggle\n if (this.renderer) {\n const hitboxLabel = document.createElement('label');\n hitboxLabel.style.cssText =\n 'display:flex;align-items:center;gap:4px;cursor:pointer;color:#ccc;font-size:10px;margin-left:6px;';\n this.hitboxCheck = document.createElement('input');\n this.hitboxCheck.type = 'checkbox';\n this.hitboxCheck.checked = this.renderer.debug;\n this.hitboxCheck.onchange = () => {\n if (this.renderer) {\n this.renderer.debug = this.hitboxCheck!.checked;\n }\n };\n hitboxLabel.appendChild(this.hitboxCheck);\n const hitboxText = document.createElement('span');\n hitboxText.textContent = 'Hitboxes';\n hitboxLabel.appendChild(hitboxText);\n toolbar.appendChild(hitboxLabel);\n }\n\n // ── Body (list + form)\n const body = mk('div', 'display:flex;flex:1;overflow:hidden;');\n this.listEl = mk('div', LIST_STYLE);\n this.formEl = mk('div', FORM_STYLE);\n body.appendChild(this.listEl);\n body.appendChild(this.formEl);\n\n container.appendChild(toolbar);\n container.appendChild(body);\n\n this.unsub = this.store.subscribe(() => {\n this.refreshList();\n this.refreshForm();\n });\n\n this.refreshList();\n }\n\n // ── List ─────────────────────────────────────────────────────\n\n private refreshList(): void {\n if (!this.listEl) return;\n this.listEl.innerHTML = '';\n\n // ── Player Spawn card (always on top)\n const spawn = this.store.getPlayerSpawn();\n const spawnCard = mk('div', CARD_STYLE);\n spawnCard.style.borderLeft = '3px solid #e8a';\n const spawnLabel = mk(\n 'div',\n 'font-weight:bold;color:#e8a;margin-bottom:2px;font-size:11px;',\n );\n spawnLabel.textContent = '🧑 Player Spawn';\n spawnCard.appendChild(spawnLabel);\n spawnCard.appendChild(\n dataRow('pos', `${f(spawn[0])} ${f(spawn[1])} ${f(spawn[2])}`),\n );\n spawnCard.style.cursor = 'pointer';\n spawnCard.onclick = () => {\n this.selectedId = '__player_spawn__';\n this.refreshList();\n this.refreshForm();\n };\n if (this.selectedId === '__player_spawn__') {\n spawnCard.style.background = '#2a2d3a';\n }\n this.listEl.appendChild(spawnCard);\n\n // ── Separator\n const sep = mk('div', 'height:1px;background:#333;margin:6px 0;');\n this.listEl.appendChild(sep);\n\n // ── Scene Items\n const heading = mk(\n 'div',\n 'color:#666;font-size:10px;letter-spacing:1px;padding:0 0 4px;',\n );\n const items = this.store.getItems();\n heading.textContent = `SCENE ITEMS (${items.length})`;\n this.listEl.appendChild(heading);\n\n for (const item of items) {\n const active = item.id === this.selectedId;\n const card = mk('div', CARD_STYLE);\n if (active) card.style.background = '#2a2d3a';\n card.style.cursor = 'pointer';\n card.onclick = () => {\n this.selectedId = item.id;\n // Auto-show hitboxes when selecting a model\n if (this.renderer) {\n this.renderer.debug = true;\n if (this.hitboxCheck) this.hitboxCheck.checked = true;\n }\n this.refreshList();\n this.refreshForm();\n };\n\n const nameEl = mk(\n 'div',\n 'font-weight:bold;color:#9cdcfe;margin-bottom:2px;font-size:11px;',\n );\n nameEl.textContent = `${item.name} [${item.resourceKey}]`;\n card.appendChild(nameEl);\n\n card.appendChild(\n dataRow(\n 'pos',\n `${f(item.translation[0])} ${f(item.translation[1])} ${f(item.translation[2])}`,\n ),\n );\n card.appendChild(\n dataRow(\n 'scl',\n `${f(item.scale[0])} ${f(item.scale[1])} ${f(item.scale[2])}`,\n ),\n );\n\n this.listEl.appendChild(card);\n }\n }\n\n // ── Form ─────────────────────────────────────────────────────\n\n private refreshForm(): void {\n if (!this.formEl) return;\n this.formEl.innerHTML = '';\n\n if (this.selectedId === '__player_spawn__') {\n this.buildSpawnForm(this.formEl);\n return;\n }\n\n const item = this.selectedId\n ? this.store.getItem(this.selectedId)\n : undefined;\n if (!item) {\n const hint = mk('div', 'color:#666;padding:8px;font-size:11px;');\n hint.textContent = 'Select an item to edit';\n this.formEl.appendChild(hint);\n return;\n }\n\n this.buildItemForm(this.formEl, item);\n }\n\n private buildSpawnForm(container: HTMLElement): void {\n const spawn = this.store.getPlayerSpawn();\n const title = mk(\n 'div',\n 'font-weight:bold;color:#e8a;padding:0 0 6px;font-size:12px;',\n );\n title.textContent = '🧑 Player Spawn';\n container.appendChild(title);\n\n container.appendChild(\n this.vec3Row('Position', spawn, (v) => {\n this.store.setPlayerSpawn(v[0], v[1], v[2]);\n }),\n );\n }\n\n private buildItemForm(container: HTMLElement, item: SceneItemSpec): void {\n const title = mk(\n 'div',\n 'font-weight:bold;color:#9cdcfe;padding:0 0 6px;font-size:12px;',\n );\n title.textContent = item.name;\n container.appendChild(title);\n\n // Name\n container.appendChild(\n this.textRow('Name', item.name, (v) => {\n this.store.updateItem({ ...item, name: v });\n }),\n );\n\n // Resource Key (model picker dropdown)\n const modelOptions = this.modelRegistry.map((m) => ({\n value: m.key,\n label: `${m.name} (${m.type})`,\n }));\n container.appendChild(\n this.selectRow('Resource', item.resourceKey, modelOptions, (v) => {\n this.store.updateItem({ ...item, resourceKey: v });\n }),\n );\n\n // Material override\n const matNames = this.getMaterialNames();\n const matOptions = [\n { value: '', label: '(default)' },\n ...matNames.map((n) => ({ value: n, label: n })),\n ];\n container.appendChild(\n this.selectRow('Material', item.materialKey ?? '', matOptions, (v) => {\n this.store.updateItem({ ...item, materialKey: v || null });\n }),\n );\n\n // Translation\n container.appendChild(\n this.vec3Row(\n 'Position',\n [...item.translation] as [number, number, number],\n (v) => {\n this.store.updateItem({ ...item, translation: v });\n },\n ),\n );\n\n // Rotation\n container.appendChild(\n this.vec3Row(\n 'Rotation',\n [...item.rotation] as [number, number, number],\n (v) => {\n this.store.updateItem({ ...item, rotation: v });\n },\n ),\n );\n\n // Scale\n container.appendChild(\n this.vec3Row(\n 'Scale',\n [...item.scale] as [number, number, number],\n (v) => {\n this.store.updateItem({ ...item, scale: v });\n },\n ),\n );\n\n // Bounds\n const hasBounds = item.bounds != null;\n container.appendChild(\n this.checkRow('Custom Bounds', hasBounds, (on) => {\n if (on) {\n this.store.updateItem({\n ...item,\n bounds: [0, 0, 0, 1, 1, 1],\n });\n } else {\n this.store.updateItem({ ...item, bounds: null });\n }\n }),\n );\n\n if (item.bounds) {\n const b = item.bounds;\n container.appendChild(\n this.vec3Row('Offset', [b[0], b[1], b[2]], (v) => {\n this.store.updateItem({\n ...item,\n bounds: [v[0], v[1], v[2], b[3], b[4], b[5]],\n });\n }),\n );\n container.appendChild(\n this.vec3Row('Size', [b[3], b[4], b[5]], (v) => {\n this.store.updateItem({\n ...item,\n bounds: [b[0], b[1], b[2], v[0], v[1], v[2]],\n });\n }),\n );\n }\n\n // Collider\n container.appendChild(\n this.checkRow('Collider', item.collider !== false, (on) => {\n this.store.updateItem({ ...item, collider: on });\n }),\n );\n }\n\n // ── CRUD actions ─────────────────────────────────────────────\n\n private onAdd(): void {\n const item = createDefaultSceneItem();\n this.store.addItem(item);\n this.selectedId = item.id;\n }\n\n private onDuplicate(): void {\n if (!this.selectedId || this.selectedId === '__player_spawn__') return;\n const src = this.store.getItem(this.selectedId);\n if (!src) return;\n const copy: SceneItemSpec = {\n ...src,\n id: crypto.randomUUID(),\n name: `${src.name} (copy)`,\n translation: [...src.translation] as [number, number, number],\n rotation: [...src.rotation] as [number, number, number],\n scale: [...src.scale] as [number, number, number],\n bounds: src.bounds\n ? ([...src.bounds] as [number, number, number, number, number, number])\n : null,\n };\n this.store.addItem(copy);\n this.selectedId = copy.id;\n }\n\n private onDelete(): void {\n if (!this.selectedId || this.selectedId === '__player_spawn__') return;\n this.store.deleteItem(this.selectedId);\n this.selectedId = null;\n }\n\n // ── Input helpers ────────────────────────────────────────────\n\n private vec3Row(\n label: string,\n values: [number, number, number],\n onChange: (v: [number, number, number]) => void,\n ): HTMLElement {\n const row = mk('div', ROW_STYLE);\n const lbl = mk('div', LABEL_STYLE);\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const group = mk('div', 'display:flex;gap:4px;');\n const labels = ['X', 'Y', 'Z'];\n\n for (let i = 0; i < 3; i++) {\n const wrap = mk('div', 'display:flex;flex-direction:column;flex:1;');\n const axisLbl = mk('div', 'color:#666;font-size:9px;text-align:center;');\n axisLbl.textContent = labels[i];\n const input = document.createElement('input');\n input.type = 'number';\n input.step = '0.1';\n input.value = String(values[i]);\n input.style.cssText = INPUT_STYLE;\n input.onchange = () => {\n const v = [...values] as [number, number, number];\n v[i] = parseFloat(input.value) || 0;\n onChange(v);\n };\n wrap.appendChild(axisLbl);\n wrap.appendChild(input);\n group.appendChild(wrap);\n }\n\n row.appendChild(group);\n return row;\n }\n\n private textRow(\n label: string,\n value: string,\n onChange: (v: string) => void,\n ): HTMLElement {\n const row = mk('div', ROW_STYLE);\n const lbl = mk('div', LABEL_STYLE);\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const input = document.createElement('input');\n input.type = 'text';\n input.value = value;\n input.style.cssText = INPUT_STYLE + ';flex:1;';\n input.onchange = () => onChange(input.value);\n row.appendChild(input);\n return row;\n }\n\n private selectRow(\n label: string,\n value: string,\n options: { value: string; label: string }[],\n onChange: (v: string) => void,\n ): HTMLElement {\n const row = mk('div', ROW_STYLE);\n const lbl = mk('div', LABEL_STYLE);\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const select = document.createElement('select');\n select.style.cssText = INPUT_STYLE + ';flex:1;';\n for (const opt of options) {\n const o = document.createElement('option');\n o.value = opt.value;\n o.textContent = opt.label;\n if (opt.value === value) o.selected = true;\n select.appendChild(o);\n }\n select.onchange = () => onChange(select.value);\n row.appendChild(select);\n return row;\n }\n\n private checkRow(\n label: string,\n checked: boolean,\n onChange: (v: boolean) => void,\n ): HTMLElement {\n const row = mk('div', ROW_STYLE + ';align-items:center;');\n const lbl = mk('div', LABEL_STYLE);\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const input = document.createElement('input');\n input.type = 'checkbox';\n input.checked = checked;\n input.onchange = () => onChange(input.checked);\n row.appendChild(input);\n return row;\n }\n\n private mkBtn(\n text: string,\n onClick: () => void,\n title: string,\n ): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.textContent = text;\n btn.title = title;\n btn.style.cssText = BTN_STYLE;\n btn.onclick = onClick;\n return btn;\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction mk(\n tag: string,\n style = '',\n): HTMLElement & HTMLButtonElement & HTMLDivElement {\n const el = document.createElement(tag) as HTMLElement &\n HTMLButtonElement &\n HTMLDivElement;\n if (style) el.style.cssText = style;\n return el;\n}\n\nfunction f(n: number): string {\n return n.toFixed(2);\n}\n\nfunction dataRow(label: string, value: string): HTMLElement {\n const row = document.createElement('div');\n row.style.cssText = 'display:flex;gap:4px;line-height:1.6;';\n\n const lbl = document.createElement('span');\n lbl.style.cssText = 'color:#666;width:28px;flex-shrink:0;font-size:10px;';\n lbl.textContent = label;\n\n const val = document.createElement('span');\n val.style.cssText = 'color:#ccc;font-size:10px;';\n val.textContent = value;\n\n row.appendChild(lbl);\n row.appendChild(val);\n return row;\n}\n\n// ── Styles ────────────────────────────────────────────────────────\n\nconst TOOLBAR_STYLE = [\n 'display:flex',\n 'gap:6px',\n 'padding:6px 10px',\n 'background:#222',\n 'border-bottom:1px solid #333',\n 'flex-shrink:0',\n].join(';');\n\nconst BTN_STYLE = [\n 'background:#2a2a2a',\n 'color:#ccc',\n 'border:1px solid #555',\n 'border-radius:4px',\n 'padding:3px 10px',\n 'cursor:pointer',\n 'font-size:11px',\n 'font-family:monospace',\n].join(';');\n\nconst LIST_STYLE = [\n 'width:220px',\n 'overflow-y:auto',\n 'padding:8px',\n 'border-right:1px solid #333',\n 'flex-shrink:0',\n].join(';');\n\nconst FORM_STYLE = ['flex:1', 'overflow-y:auto', 'padding:10px'].join(';');\n\nconst CARD_STYLE = [\n 'background:#1e1e1e',\n 'border:1px solid #333',\n 'border-radius:4px',\n 'padding:6px 8px',\n 'margin-bottom:4px',\n 'font-family:monospace',\n 'font-size:10px',\n].join(';');\n\nconst ROW_STYLE = ['display:flex', 'gap:6px', 'margin-bottom:8px'].join(';');\n\nconst LABEL_STYLE = [\n 'color:#888',\n 'font-size:11px',\n 'width:70px',\n 'flex-shrink:0',\n 'padding-top:2px',\n].join(';');\n\nconst INPUT_STYLE = [\n 'background:#1a1a1a',\n 'color:#ccc',\n 'border:1px solid #444',\n 'border-radius:3px',\n 'padding:3px 5px',\n 'font-size:11px',\n 'font-family:monospace',\n 'width:60px',\n 'outline:none',\n].join(';');\n","import { MaterialSpec } from './sections/materials/MaterialSpec';\nimport { MaterialStore } from './sections/materials/MaterialStore';\n\ntype Vec3Field = 'diffuse' | 'ambientColor' | 'specular';\n\nexport interface EditorTab {\n id: string;\n /** Label shown on the tab button. */\n label: string;\n /** Called once to populate the tab's content container. */\n buildContent: (container: HTMLElement) => void;\n /** Called each time the tab becomes the active, visible tab. */\n onActivate?: () => void;\n /** Called each time the tab is hidden (tab switch or sidebar hide). */\n onDeactivate?: () => void;\n /** Optional cleanup called when the sidebar is unmounted. */\n destroy?: () => void;\n}\n\n/**\n * Fixed right-side editor sidebar.\n *\n * - Hosts a tab strip so new features can be added via {@link addTab}.\n * - First tab is the Material Editor (colour preview swatches + full form).\n * - Every store mutation auto-syncs to `materials.json` via the Vite dev plugin.\n * - \"🔄 Reload Game\" triggers `location.reload()` to pick up JSON changes.\n */\nexport class EditorSidebar {\n private root!: HTMLElement;\n private tabBar!: HTMLElement;\n private contentArea!: HTMLElement;\n private tabs: EditorTab[] = [];\n private activeTabId: string | null = null;\n\n // material panel state\n private listEl!: HTMLElement;\n private formEl!: HTMLElement;\n private selectedId: string | null = null;\n private unsubMaterials?: () => void;\n\n // drag-resize state\n private _sidebarWidth = 520;\n private _dragging = false;\n\n // layout mode: 'absolute' overlays, 'shared' shrinks viewport\n private _layoutMode: 'absolute' | 'shared' = 'absolute';\n private _layoutBtn: HTMLButtonElement | null = null;\n\n private constructor(private readonly store: MaterialStore) {}\n\n // ── Public API ──────────────────────────────────────────────\n\n static mount(store: MaterialStore): EditorSidebar {\n const s = new EditorSidebar(store);\n s.build();\n return s;\n }\n\n show(): void {\n this.root.style.display = 'flex';\n this.applyLayout();\n if (this.activeTabId) {\n this.tabs.find((t) => t.id === this.activeTabId)?.onActivate?.();\n }\n }\n\n hide(): void {\n if (this.activeTabId) {\n this.tabs.find((t) => t.id === this.activeTabId)?.onDeactivate?.();\n }\n this.root.style.display = 'none';\n this.applyLayout();\n }\n\n toggle(): void {\n if (this.root.style.display === 'none') this.show();\n else this.hide();\n }\n\n get isVisible(): boolean {\n return this.root.style.display !== 'none';\n }\n\n /** Register an extra tab. */\n addTab(tab: EditorTab): void {\n this.tabs.push(tab);\n if (this.tabBar) this.renderTabBar();\n }\n\n unmount(): void {\n this.unsubMaterials?.();\n for (const t of this.tabs) t.destroy?.();\n this.root?.remove();\n }\n\n // ── Build ────────────────────────────────────────────────────\n\n private build(): void {\n this.root = el('div', { id: 'gl-editor-sidebar' }, SIDEBAR_STYLE);\n this.root.style.display = 'none';\n this.root.style.width = `${this._sidebarWidth}px`;\n\n // ── Drag handle (left edge) ────────────────────────────────\n const handle = el('div', {}, DRAG_HANDLE_STYLE);\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n this._dragging = true;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n });\n document.addEventListener('mousemove', (e) => {\n if (!this._dragging) return;\n const newWidth = window.innerWidth - e.clientX;\n this._sidebarWidth = Math.max(280, Math.min(newWidth, 900));\n this.root.style.width = `${this._sidebarWidth}px`;\n this.applyLayout();\n });\n document.addEventListener('mouseup', () => {\n if (!this._dragging) return;\n this._dragging = false;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n });\n this.root.appendChild(handle);\n\n const header = el('div', {}, HEADER_STYLE);\n const title = el(\n 'span',\n {},\n 'font-weight:bold;color:#9cdcfe;letter-spacing:1px;',\n );\n title.textContent = '🛠 Editor';\n header.appendChild(title);\n // Layout toggle (absolute ↔ shared)\n this._layoutBtn = el(\n 'button',\n {},\n ICON_BTN_STYLE + ';margin-left:auto;font-size:14px;',\n );\n this._layoutBtn.title = 'Toggle: overlay / share viewport';\n this._layoutBtn.textContent = '⇔';\n this._layoutBtn.onclick = () => this.toggleLayout();\n header.appendChild(this._layoutBtn);\n\n const closeBtn = el('button', {}, ICON_BTN_STYLE);\n closeBtn.textContent = '✕';\n closeBtn.title = 'Close sidebar';\n closeBtn.onclick = () => this.hide();\n header.appendChild(closeBtn);\n\n this.tabBar = el('div', {}, TAB_BAR_STYLE);\n this.contentArea = el(\n 'div',\n {},\n 'flex:1;overflow:hidden;display:flex;flex-direction:column;',\n );\n\n this.root.appendChild(header);\n this.root.appendChild(this.tabBar);\n this.root.appendChild(this.contentArea);\n document.body.appendChild(this.root);\n\n this.addTab({\n id: 'materials',\n label: '🎨 Materials',\n buildContent: (c) => this.buildMaterialsContent(c),\n destroy: () => this.unsubMaterials?.(),\n });\n this.activateTab('materials');\n }\n\n // ── Layout mode ──────────────────────────────────────────────\n\n private toggleLayout(): void {\n this._layoutMode = this._layoutMode === 'absolute' ? 'shared' : 'absolute';\n this.applyLayout();\n }\n\n private applyLayout(): void {\n const visible = this.root.style.display !== 'none';\n if (this._layoutMode === 'shared' && visible) {\n document.body.style.marginRight = `${this._sidebarWidth}px`;\n } else {\n document.body.style.marginRight = '0';\n }\n // Update button label hint\n if (this._layoutBtn) {\n this._layoutBtn.textContent = this._layoutMode === 'absolute' ? '⇔' : '⇤';\n this._layoutBtn.title =\n this._layoutMode === 'absolute'\n ? 'Switch to shared layout (shrink viewport)'\n : 'Switch to overlay layout';\n }\n }\n\n // ── Tab system ───────────────────────────────────────────────\n\n private renderTabBar(): void {\n this.tabBar.innerHTML = '';\n for (const tab of this.tabs) {\n const btn = el(\n 'button',\n {},\n TAB_BTN_STYLE + (tab.id === this.activeTabId ? TAB_BTN_ACTIVE : ''),\n );\n btn.textContent = tab.label;\n btn.onclick = () => this.activateTab(tab.id);\n this.tabBar.appendChild(btn);\n }\n }\n\n /** Activate a tab by id. Safe to call from outside (e.g. TopBar button). */\n activateTab(id: string): void {\n // Deactivate the current tab before switching\n if (this.activeTabId && this.activeTabId !== id) {\n this.tabs.find((t) => t.id === this.activeTabId)?.onDeactivate?.();\n }\n this.activeTabId = id;\n this.renderTabBar();\n this.contentArea.innerHTML = '';\n const tab = this.tabs.find((t) => t.id === id);\n if (!tab) return;\n const c = el(\n 'div',\n {},\n 'flex:1;overflow:hidden;display:flex;flex-direction:column;',\n );\n tab.buildContent(c);\n this.contentArea.appendChild(c);\n tab.onActivate?.();\n }\n\n // ── Materials tab content ────────────────────────────────────\n\n private buildMaterialsContent(container: HTMLElement): void {\n const toolbar = el('div', {}, TOOLBAR_STYLE);\n toolbar.appendChild(this.mkBtn('+', () => this.onNew(), 'New material'));\n toolbar.appendChild(this.mkBtn('❑', () => this.onDuplicate(), 'Duplicate'));\n toolbar.appendChild(this.mkBtn('🗑', () => this.onDelete(), 'Delete'));\n const reloadBtn = el(\n 'button',\n {},\n BTN_STYLE + ';margin-left:auto;color:#6cf;border-color:#446;',\n );\n reloadBtn.textContent = '🔄 Reload Game';\n reloadBtn.title = 'Sync JSON then reload game to apply changes';\n reloadBtn.onclick = () => location.reload();\n toolbar.appendChild(reloadBtn);\n\n const body = el('div', {}, 'display:flex;flex:1;overflow:hidden;');\n this.listEl = el('div', {}, LIST_STYLE);\n this.formEl = el('div', {}, FORM_STYLE);\n body.appendChild(this.listEl);\n body.appendChild(this.formEl);\n\n container.appendChild(toolbar);\n container.appendChild(body);\n\n this.unsubMaterials = this.store.subscribe(() => this.refreshList());\n this.refreshList();\n }\n\n // ── List ─────────────────────────────────────────────────────\n\n private refreshList(): void {\n this.listEl.innerHTML = '';\n for (const spec of this.store.getAll()) {\n const active = spec.id === this.selectedId;\n const item = el(\n 'div',\n {},\n LIST_ITEM_STYLE + (active ? LIST_ITEM_ACTIVE : ''),\n );\n // Colour preview swatch\n const swatch = el('div', {}, swatchStyle(spec));\n item.appendChild(swatch);\n const nameEl = el(\n 'span',\n {},\n 'flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;',\n );\n nameEl.textContent = spec.name;\n item.appendChild(nameEl);\n item.onclick = () => this.select(spec.id);\n this.listEl.appendChild(item);\n }\n\n if (this.selectedId && !this.store.get(this.selectedId)) {\n this.selectedId = null;\n this.formEl.innerHTML = EMPTY_FORM_HTML;\n }\n }\n\n private select(id: string): void {\n this.selectedId = id;\n this.refreshList();\n this.buildForm();\n }\n\n // ── Form ─────────────────────────────────────────────────────\n\n private buildForm(): void {\n const spec = this.selectedId ? this.store.get(this.selectedId) : undefined;\n this.formEl.innerHTML = '';\n if (!spec) return;\n\n const draft: MaterialSpec = {\n ...spec,\n albedoColor: [...spec.albedoColor],\n diffuse: [...spec.diffuse],\n ambientColor: [...spec.ambientColor],\n specular: [...spec.specular],\n };\n\n const save = () => {\n this.store.update(draft);\n this.select(draft.id);\n };\n\n // Name\n formRow(this.formEl, 'Name', () => {\n const inp = el('input', { type: 'text', value: draft.name }, INPUT_STYLE);\n inp.oninput = () => {\n draft.name = inp.value;\n };\n inp.onblur = save;\n return inp;\n });\n\n // Albedo RGBA\n formRow(this.formEl, 'Albedo (RGBA)', () => {\n const wrap = el('div', {}, 'display:flex;gap:4px;align-items:center;');\n const hex = rgbToHex(\n draft.albedoColor[0],\n draft.albedoColor[1],\n draft.albedoColor[2],\n );\n const picker = el(\n 'input',\n { type: 'color', value: hex },\n 'cursor:pointer;',\n );\n const alphaIn = el(\n 'input',\n {\n type: 'range',\n min: '0',\n max: '1',\n step: '0.01',\n value: String(draft.albedoColor[3]),\n },\n 'flex:1;',\n );\n const alphaLbl = el(\n 'span',\n {},\n 'min-width:30px;color:#ccc;font-size:11px;',\n );\n alphaLbl.textContent = draft.albedoColor[3].toFixed(2);\n const update = () => {\n const [r, g, b] = hexToRgb(picker.value);\n draft.albedoColor = [r, g, b, parseFloat(alphaIn.value)];\n alphaLbl.textContent = parseFloat(alphaIn.value).toFixed(2);\n save();\n };\n picker.oninput = update;\n alphaIn.oninput = update;\n wrap.appendChild(picker);\n wrap.appendChild(alphaIn);\n wrap.appendChild(alphaLbl);\n return wrap;\n });\n\n // Vec3 colour pickers\n for (const key of ['diffuse', 'ambientColor', 'specular'] as Vec3Field[]) {\n const label = {\n diffuse: 'Diffuse',\n ambientColor: 'Ambient',\n specular: 'Specular',\n }[key];\n formRow(this.formEl, label, () => {\n const hex = rgbToHex(draft[key][0], draft[key][1], draft[key][2]);\n const picker = el(\n 'input',\n { type: 'color', value: hex },\n 'cursor:pointer;',\n );\n picker.oninput = () => {\n [draft[key][0], draft[key][1], draft[key][2]] = hexToRgb(\n picker.value,\n );\n save();\n };\n return picker;\n });\n }\n\n // Sliders\n numericRow(this.formEl, 'Shininess', draft.shininess, 2, 256, 1, (v) => {\n draft.shininess = v;\n save();\n });\n numericRow(this.formEl, 'Dissolve', draft.dissolve, 0, 1, 0.01, (v) => {\n draft.dissolve = v;\n save();\n });\n numericRow(\n this.formEl,\n 'Friction',\n draft.friction ?? 0.75,\n 0,\n 1,\n 0.01,\n (v) => {\n draft.friction = v;\n save();\n },\n );\n\n // Toggles\n checkRow(this.formEl, 'Unlit', draft.unlit, (v) => {\n draft.unlit = v;\n save();\n });\n checkRow(this.formEl, 'Double Sided', draft.doubleSided, (v) => {\n draft.doubleSided = v;\n save();\n });\n\n // Texture path\n formRow(this.formEl, 'Texture Path', () => {\n const inp = el(\n 'input',\n {\n type: 'text',\n value: draft.texturePath ?? '',\n placeholder: 'textures/my-tex.png',\n },\n INPUT_STYLE,\n );\n inp.oninput = () => {\n draft.texturePath = inp.value || undefined;\n };\n inp.onblur = save;\n return inp;\n });\n }\n\n // ── Actions ──────────────────────────────────────────────────\n\n private onNew(): void {\n const spec = this.store.create();\n this.select(spec.id);\n }\n\n private onDuplicate(): void {\n if (!this.selectedId) return;\n const copy = this.store.duplicate(this.selectedId);\n if (copy) this.select(copy.id);\n }\n\n private onDelete(): void {\n if (!this.selectedId) return;\n if (!confirm('Delete this material?')) return;\n this.store.delete(this.selectedId);\n this.selectedId = null;\n this.formEl.innerHTML = EMPTY_FORM_HTML;\n }\n\n private mkBtn(\n label: string,\n onClick: () => void,\n title = '',\n ): HTMLButtonElement {\n const b = el('button', {}, BTN_STYLE);\n b.textContent = label;\n b.title = title;\n b.onclick = onClick;\n return b;\n }\n}\n\n// ── DOM helpers ───────────────────────────────────────────────────\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Record<string, string> = {},\n style = '',\n): HTMLElementTagNameMap[K] {\n const e = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs))\n (e as unknown as Record<string, string>)[k] = v;\n if (style) e.style.cssText = style;\n return e;\n}\n\nfunction formRow(\n parent: HTMLElement,\n label: string,\n buildInput: () => HTMLElement,\n): void {\n const row = el(\n 'div',\n {},\n 'display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;gap:8px;',\n );\n const lbl = el(\n 'label',\n {},\n 'color:#bbb;font-size:12px;white-space:nowrap;min-width:90px;',\n );\n lbl.textContent = label;\n row.appendChild(lbl);\n const wrap = el('div', {}, 'flex:1;');\n wrap.appendChild(buildInput());\n row.appendChild(wrap);\n parent.appendChild(row);\n}\n\nfunction numericRow(\n parent: HTMLElement,\n label: string,\n value: number,\n min: number,\n max: number,\n step: number,\n onChange: (v: number) => void,\n): void {\n formRow(parent, label, () => {\n const wrap = el('div', {}, 'display:flex;gap:4px;align-items:center;');\n const slider = el(\n 'input',\n {\n type: 'range',\n min: String(min),\n max: String(max),\n step: String(step),\n value: String(value),\n },\n 'flex:1;',\n );\n const lbl = el(\n 'span',\n {},\n 'min-width:36px;color:#ccc;font-size:11px;text-align:right;',\n );\n lbl.textContent = value.toString();\n slider.oninput = () => {\n lbl.textContent = slider.value;\n onChange(parseFloat(slider.value));\n };\n wrap.appendChild(slider);\n wrap.appendChild(lbl);\n return wrap;\n });\n}\n\nfunction checkRow(\n parent: HTMLElement,\n label: string,\n value: boolean,\n onChange: (v: boolean) => void,\n): void {\n formRow(parent, label, () => {\n const cb = el('input', { type: 'checkbox' }, '');\n cb.checked = value;\n cb.onchange = () => onChange(cb.checked);\n return cb;\n });\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n const byte = (v: number) =>\n Math.round(Math.min(1, Math.max(0, v)) * 255)\n .toString(16)\n .padStart(2, '0');\n return `#${byte(r)}${byte(g)}${byte(b)}`;\n}\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const n = parseInt(hex.slice(1), 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nfunction swatchStyle(spec: MaterialSpec): string {\n const [r, g, b, a] = spec.albedoColor;\n return [\n `background:rgba(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)},${a})`,\n 'width:18px',\n 'min-width:18px',\n 'height:18px',\n 'border-radius:3px',\n 'border:1px solid #666',\n 'flex-shrink:0',\n ].join(';');\n}\n\n// ── Constants ─────────────────────────────────────────────────────\n\nconst EMPTY_FORM_HTML =\n '<p style=\"color:#888;padding:16px 10px;font-size:12px;\">Select or create a material.</p>';\n\n// ── Styles ────────────────────────────────────────────────────────\n\nconst SIDEBAR_STYLE = [\n 'position:fixed',\n 'top:32px',\n 'right:0',\n 'height:calc(100vh - 32px)',\n 'background:#1e1e1e',\n 'border-left:1px solid #444',\n 'display:flex',\n 'flex-direction:column',\n 'color:#ddd',\n 'font-family:monospace',\n 'font-size:12px',\n 'z-index:9998',\n 'box-shadow:-4px 0 20px rgba(0,0,0,.6)',\n 'overflow:hidden',\n].join(';');\n\nconst DRAG_HANDLE_STYLE = [\n 'position:absolute',\n 'top:0',\n 'left:0',\n 'width:5px',\n 'height:100%',\n 'cursor:col-resize',\n 'z-index:1',\n 'background:transparent',\n].join(';');\n\nconst HEADER_STYLE = [\n 'display:flex',\n 'align-items:center',\n 'gap:8px',\n 'padding:0 12px',\n 'height:36px',\n 'background:#252525',\n 'border-bottom:1px solid #444',\n 'flex-shrink:0',\n].join(';');\n\nconst ICON_BTN_STYLE = [\n 'padding:2px 7px',\n 'background:transparent',\n 'color:#888',\n 'border:1px solid #444',\n 'border-radius:4px',\n 'cursor:pointer',\n 'font-size:12px',\n].join(';');\n\nconst TAB_BAR_STYLE = [\n 'display:flex',\n 'background:#1a1a1a',\n 'border-bottom:1px solid #444',\n 'flex-shrink:0',\n].join(';');\n\nconst TAB_BTN_STYLE = [\n 'padding:5px 12px',\n 'background:transparent',\n 'color:#aaa',\n 'border:none',\n 'border-right:1px solid #333',\n 'cursor:pointer',\n 'font-family:monospace',\n 'font-size:11px',\n 'white-space:nowrap',\n].join(';');\n\nconst TAB_BTN_ACTIVE =\n ';background:#1e1e1e;color:#fff;border-bottom:2px solid #007acc;';\n\nconst TOOLBAR_STYLE = [\n 'display:flex',\n 'align-items:center',\n 'gap:4px',\n 'padding:5px 8px',\n 'background:#252525',\n 'border-bottom:1px solid #444',\n 'flex-shrink:0',\n].join(';');\n\nconst BTN_STYLE = [\n 'padding:3px 8px',\n 'background:#3a3a3a',\n 'color:#ddd',\n 'border:1px solid #555',\n 'border-radius:4px',\n 'cursor:pointer',\n 'font-family:monospace',\n 'font-size:11px',\n].join(';');\n\nconst LIST_STYLE = [\n 'width:140px',\n 'min-width:140px',\n 'overflow-y:auto',\n 'border-right:1px solid #333',\n 'padding:4px',\n 'display:flex',\n 'flex-direction:column',\n 'gap:2px',\n].join(';');\n\nconst LIST_ITEM_STYLE = [\n 'display:flex',\n 'align-items:center',\n 'gap:6px',\n 'padding:5px 6px',\n 'border-radius:4px',\n 'cursor:pointer',\n 'overflow:hidden',\n 'color:#ccc',\n].join(';');\n\nconst LIST_ITEM_ACTIVE =\n ';background:#007acc22;outline:1px solid #007acc;color:#fff;';\n\nconst FORM_STYLE = ['flex:1', 'overflow-y:auto', 'padding:10px 10px 16px'].join(\n ';',\n);\n\nconst INPUT_STYLE = [\n 'width:100%',\n 'background:#2a2a2a',\n 'border:1px solid #555',\n 'border-radius:3px',\n 'color:#ddd',\n 'padding:3px 5px',\n 'font-family:monospace',\n 'font-size:11px',\n 'box-sizing:border-box',\n].join(';');\n","/** Minimal sidebar interface used by TopBar for tab-aware buttons. */\ninterface ISidebar {\n show(): void;\n toggle(): void;\n activateTab(id: string): void;\n readonly isVisible: boolean;\n}\n\n/**\n * Slim top bar pinned at the top of the viewport.\n * Houses engine tool buttons (e.g. Material Editor toggle).\n */\nexport class TopBar {\n private root!: HTMLElement;\n\n private constructor() {}\n\n static mount(materialPanel: ISidebar): TopBar {\n const bar = new TopBar();\n bar.build(materialPanel);\n return bar;\n }\n\n unmount(): void {\n this.root?.remove();\n }\n\n private build(materialPanel: ISidebar): void {\n this.root = document.createElement('div');\n this.root.id = 'gl-top-bar';\n this.root.style.cssText = TOP_BAR_STYLE;\n\n // Left group – branding\n const brand = document.createElement('span');\n brand.textContent = 'GenesisGL';\n brand.style.cssText =\n 'font-weight:bold;color:#9cdcfe;letter-spacing:1px;margin-right:16px;';\n this.root.appendChild(brand);\n\n // Tool buttons\n this.root.appendChild(this.mkToggleBtn('🎨 Materials', materialPanel));\n\n document.body.prepend(this.root);\n\n // Push page content down so the bar doesn't overlay anything\n document.body.style.paddingTop = `${this.root.offsetHeight || 34}px`;\n }\n\n /** Add the Models tab button after the game has started. */\n addModelsButton(sidebar: ISidebar): void {\n const btn = document.createElement('button');\n btn.textContent = '🧠 Models';\n btn.style.cssText = BTN_STYLE;\n btn.onclick = () => {\n sidebar.show();\n sidebar.activateTab('models');\n btn.style.cssText = sidebar.isVisible ? BTN_ACTIVE_STYLE : BTN_STYLE;\n };\n this.root.appendChild(btn);\n }\n\n /** Add the Scene tab button after the game has started. */\n addSceneButton(sidebar: ISidebar): void {\n const btn = document.createElement('button');\n btn.textContent = '🌍 Scene';\n btn.style.cssText = BTN_STYLE;\n btn.onclick = () => {\n sidebar.show();\n sidebar.activateTab('scene');\n btn.style.cssText = sidebar.isVisible ? BTN_ACTIVE_STYLE : BTN_STYLE;\n };\n this.root.appendChild(btn);\n }\n\n private mkToggleBtn(label: string, panel: ISidebar): HTMLButtonElement {\n return this.mkPanelToggleBtn(label, panel);\n }\n\n private mkPanelToggleBtn(\n label: string,\n panel: { toggle(): void; isVisible: boolean },\n ): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.textContent = label;\n btn.style.cssText = BTN_STYLE;\n btn.onclick = () => {\n panel.toggle();\n btn.style.cssText = panel.isVisible ? BTN_ACTIVE_STYLE : BTN_STYLE;\n };\n return btn;\n }\n}\n\n// ── Styles ────────────────────────────────────────────────────────\n\nconst TOP_BAR_STYLE = [\n 'position:fixed',\n 'top:0',\n 'left:0',\n 'right:0',\n 'height:32px',\n 'z-index:9999',\n 'display:flex',\n 'align-items:center',\n 'padding:0 12px',\n 'gap:6px',\n 'background:#1a1a1a',\n 'border-bottom:1px solid #444',\n 'font-family:monospace',\n 'font-size:12px',\n 'color:#ddd',\n 'box-shadow:0 2px 8px rgba(0,0,0,.5)',\n].join(';');\n\nconst BTN_STYLE = [\n 'padding:3px 10px',\n 'background:#2d2d2d',\n 'color:#ddd',\n 'border:1px solid #555',\n 'border-radius:4px',\n 'cursor:pointer',\n 'font-size:11px',\n 'font-family:monospace',\n].join(';');\n\nconst BTN_ACTIVE_STYLE = [\n 'padding:3px 10px',\n 'background:#007acc',\n 'color:#fff',\n 'border:1px solid #007acc',\n 'border-radius:4px',\n 'cursor:pointer',\n 'font-size:11px',\n 'font-family:monospace',\n].join(';');\n","import { EditorTab } from '../../EditorSidebar';\n\n/** Minimal interface: only the debug flag we need. */\ninterface IRenderer {\n debug: boolean;\n}\n\n/** Bounding box as stored on Model. */\ninterface AABB {\n min: [number, number, number];\n max: [number, number, number];\n}\n\n/** Minimal model shape required by the inspector. */\ninterface IModel {\n translation: [number, number, number];\n rotation: [number, number, number];\n scale: [number, number, number];\n boundingBox: AABB;\n}\n\n/** Minimal scene interface: just the keyed entry list. */\ninterface IScene {\n getEntries(): [string, IModel][];\n}\n\n/**\n * Model Inspector — rendered as a tab inside the {@link EditorSidebar}.\n *\n * Lifecycle:\n * – `buildContent(container)` builds the DOM once when the tab is activated.\n * – `onActivate()` enables `renderer.debug` and starts a 200 ms refresh loop.\n * – `onDeactivate()` disables `renderer.debug` and stops the refresh loop.\n * – `asTab()` returns an {@link EditorTab} descriptor ready for `sidebar.addTab()`.\n */\nexport class ModelsSection {\n private listEl: HTMLElement | null = null;\n private hitboxCheck: HTMLInputElement | null = null;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n\n private constructor(\n private readonly renderer: IRenderer,\n private readonly scene: IScene,\n ) {}\n\n // ── Factory ──────────────────────────────────────────────────\n\n static create(renderer: IRenderer, scene: IScene): ModelsSection {\n return new ModelsSection(renderer, scene);\n }\n\n // ── Tab descriptor ───────────────────────────────────────────\n\n asTab(): EditorTab {\n return {\n id: 'models',\n label: '🧠 Models',\n buildContent: (c) => this.buildContent(c),\n onActivate: () => this.start(),\n onDeactivate: () => this.stop(),\n destroy: () => this.stop(),\n };\n }\n\n // ── Lifecycle ────────────────────────────────────────────────\n\n private start(): void {\n this.renderer.debug = true;\n if (this.hitboxCheck) this.hitboxCheck.checked = true;\n this.refresh();\n if (this.intervalId === null) {\n this.intervalId = setInterval(() => this.refresh(), 200);\n }\n }\n\n private stop(): void {\n this.renderer.debug = false;\n if (this.hitboxCheck) this.hitboxCheck.checked = false;\n if (this.intervalId !== null) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n }\n\n // ── Build ────────────────────────────────────────────────────\n\n private buildContent(container: HTMLElement): void {\n // ── Controls row\n const controls = mk('div', CONTROLS_STYLE);\n const hitboxRow = document.createElement('label');\n hitboxRow.style.cssText =\n 'display:flex;align-items:center;gap:6px;cursor:pointer;color:#ccc;font-size:11px;';\n this.hitboxCheck = document.createElement('input');\n this.hitboxCheck.type = 'checkbox';\n this.hitboxCheck.checked = this.renderer.debug;\n this.hitboxCheck.onchange = () => {\n this.renderer.debug = this.hitboxCheck!.checked;\n };\n hitboxRow.appendChild(this.hitboxCheck);\n const hitboxLbl = document.createElement('span');\n hitboxLbl.textContent = 'Show Hitboxes';\n hitboxRow.appendChild(hitboxLbl);\n controls.appendChild(hitboxRow);\n\n // ── Model list\n this.listEl = mk('div', LIST_STYLE);\n\n container.appendChild(controls);\n container.appendChild(this.listEl);\n }\n\n // ── Live refresh ─────────────────────────────────────────────\n\n private refresh(): void {\n if (!this.listEl) return;\n const entries = this.scene.getEntries();\n this.listEl.innerHTML = '';\n\n const heading = mk(\n 'div',\n 'color:#666;font-size:10px;letter-spacing:1px;padding:0 0 4px;',\n );\n heading.textContent = `MODELS (${entries.length})`;\n this.listEl.appendChild(heading);\n\n for (const [key, model] of entries) {\n const card = mk('div', CARD_STYLE);\n\n const nameEl = mk(\n 'div',\n 'font-weight:bold;color:#9cdcfe;margin-bottom:4px;',\n );\n nameEl.textContent = key;\n card.appendChild(nameEl);\n\n const t = model.translation;\n const r = model.rotation;\n const s = model.scale;\n const bb = model.boundingBox;\n const w = bb.max[0] - bb.min[0];\n const h = bb.max[1] - bb.min[1];\n const d = bb.max[2] - bb.min[2];\n\n card.appendChild(dataRow('pos', `${f(t[0])} ${f(t[1])} ${f(t[2])}`));\n card.appendChild(dataRow('rot', `${f(r[0])} ${f(r[1])} ${f(r[2])}`));\n card.appendChild(dataRow('scl', `${f(s[0])} ${f(s[1])} ${f(s[2])}`));\n card.appendChild(dataRow('bbox', `${f(w)}w ${f(h)}h ${f(d)}d`));\n\n this.listEl.appendChild(card);\n }\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction mk(\n tag: string,\n style = '',\n): HTMLElement & HTMLButtonElement & HTMLDivElement {\n const el = document.createElement(tag) as HTMLElement &\n HTMLButtonElement &\n HTMLDivElement;\n if (style) el.style.cssText = style;\n return el;\n}\n\nfunction f(n: number): string {\n return n.toFixed(2);\n}\n\nfunction dataRow(label: string, value: string): HTMLElement {\n const row = document.createElement('div');\n row.style.cssText = 'display:flex;gap:4px;line-height:1.6;';\n\n const lbl = document.createElement('span');\n lbl.style.cssText = 'color:#666;width:28px;flex-shrink:0;font-size:10px;';\n lbl.textContent = label;\n\n const val = document.createElement('span');\n val.style.cssText = 'color:#ccc;font-size:10px;';\n val.textContent = value;\n\n row.appendChild(lbl);\n row.appendChild(val);\n return row;\n}\n\n// ── Styles ────────────────────────────────────────────────────────\n\nconst CONTROLS_STYLE = [\n 'padding:6px 10px',\n 'background:#222',\n 'border-bottom:1px solid #333',\n 'flex-shrink:0',\n].join(';');\n\nconst LIST_STYLE = [\n 'overflow-y:auto',\n 'padding:8px',\n 'display:flex',\n 'flex-direction:column',\n 'gap:6px',\n].join(';');\n\nconst CARD_STYLE = [\n 'background:#252525',\n 'border:1px solid #333',\n 'border-radius:4px',\n 'padding:6px 8px',\n].join(';');\n"],"mappings":";AAmCO,SAAS,kBAAkB,OAAO,gBAA8B;AACrE,SAAO;AAAA,IACL,IAAI,OAAO,WAAW;AAAA,IACtB;AAAA,IACA,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,IACxB,SAAS,CAAC,GAAG,GAAG,CAAC;AAAA,IACjB,cAAc,CAAC,KAAK,KAAK,GAAG;AAAA,IAC5B,UAAU,CAAC,KAAK,KAAK,GAAG;AAAA,IACxB,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AACF;;;AC/CA,IAAM,cAAc;AAsBb,IAAM,gBAAN,MAAoB;AAAA,EACjB,QAAQ,oBAAI,IAA0B;AAAA,EACtC,YAA6B,CAAC;AAAA,EACrB;AAAA,EAEjB,YAAY,UAAgC,CAAC,GAAG;AAC9C,SAAK,WAAW,QAAQ,YAAY;AAEpC,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,SAAU;AACpB,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,KAAK,QAAQ;AACrC,UAAI,CAAC,IAAI,IAAI;AACX,gBAAQ;AAAA,UACN,mCAAmC,KAAK,QAAQ,MAAM,IAAI,MAAM;AAAA,QAClE;AACA;AAAA,MACF;AACA,YAAM,QAAS,MAAM,IAAI,KAAK;AAC9B,iBAAW,QAAQ,MAAO,MAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAEtD,WAAK,QAAQ;AACb,WAAK,KAAK;AAAA,IACZ,QAAQ;AACN,cAAQ,KAAK,oCAAoC,KAAK,QAAQ,GAAG;AAAA,IACnE;AAAA,EACF;AAAA;AAAA,EAIA,SAAyB;AACvB,WAAO,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC;AAAA,EAChC;AAAA,EAEA,IAAI,IAAsC;AACxC,WAAO,KAAK,MAAM,IAAI,EAAE;AAAA,EAC1B;AAAA;AAAA,EAGA,OAAO,MAA6B;AAClC,UAAM,OAAO,kBAAkB,IAAI;AACnC,SAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAC5B,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AACvB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAO,MAA0B;AAC/B,QAAI,CAAC,KAAK,MAAM,IAAI,KAAK,EAAE,EAAG;AAC9B,SAAK,MAAM,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,CAAC;AACnC,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA;AAAA,EAGA,UAAU,IAAsC;AAC9C,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,OAAqB;AAAA,MACzB,GAAG;AAAA,MACH,IAAI,OAAO,WAAW;AAAA,MACtB,MAAM,GAAG,IAAI,IAAI;AAAA,MACjB,aAAa,CAAC,GAAG,IAAI,WAAW;AAAA,MAChC,SAAS,CAAC,GAAG,IAAI,OAAO;AAAA,MACxB,cAAc,CAAC,GAAG,IAAI,YAAY;AAAA,MAClC,UAAU,CAAC,GAAG,IAAI,QAAQ;AAAA,IAC5B;AACA,SAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAC5B,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,MAAM,OAAO,EAAE;AACpB,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAiC;AACrC,QAAI,CAAC,KAAK,SAAU,QAAO;AAC3B,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,kBAAkB;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,KAAK,OAAO,GAAG,MAAM,CAAC;AAAA,MAC7C,CAAC;AACD,UAAI,CAAC,IAAI,IAAI;AACX,gBAAQ,KAAK,uCAAuC,IAAI,MAAM,GAAG;AAAA,MACnE;AACA,aAAO,IAAI;AAAA,IACb,QAAQ;AACN,cAAQ,KAAK,6CAA6C;AAC1D,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAIQ,UAAgB;AACtB,QAAI;AACF,mBAAa,QAAQ,aAAa,KAAK,UAAU,KAAK,OAAO,CAAC,CAAC;AAAA,IACjE,QAAQ;AACN,cAAQ,KAAK,iDAAiD;AAAA,IAChE;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAC9B,QAAI;AACF,YAAM,MAAM,aAAa,QAAQ,WAAW;AAC5C,UAAI,CAAC,IAAK;AACV,YAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,iBAAW,QAAQ,MAAO,MAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAAA,IACxD,QAAQ;AACN,cAAQ,KAAK,kDAAkD;AAAA,IACjE;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,UAAkC;AACnD,UAAM,cAAc,KAAK,WACrB,KAAK,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK,mBAClC;AACJ,UAAM,OAAO,YAAY;AACzB,UAAM,OAAO,KAAK,UAAU,KAAK,OAAO,GAAG,MAAM,CAAC;AAClD,UAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAG1D,QAAI,wBAAwB,QAAQ;AAClC,UAAI;AACF,cAAM,SAAS,MACb,OAKA,mBAAmB;AAAA,UACnB,eAAe;AAAA,UACf,OAAO;AAAA,YACL,EAAE,aAAa,QAAQ,QAAQ,EAAE,oBAAoB,CAAC,OAAO,EAAE,EAAE;AAAA,UACnE;AAAA,QACF,CAAC;AACD,cAAM,WAAW,MAAM,OAAO,eAAe;AAC7C,cAAM,SAAS,MAAM,IAAI;AACzB,cAAM,SAAS,MAAM;AACrB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,OAAO;AACT,MAAE,WAAW;AACb,MAAE,MAAM;AACR,QAAI,gBAAgB,GAAG;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAgC;AAC9B,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,OAAO;AACb,YAAM,SAAS;AAEf,YAAM,WAAW,YAAY;AAC3B,cAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,YAAI,CAAC,MAAM;AACT,kBAAQ;AACR;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,gBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,qBAAW,QAAQ,MAAO,MAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AACtD,eAAK,QAAQ;AACb,eAAK,KAAK;AAAA,QACZ,QAAQ;AACN,kBAAQ,MAAM,+CAA+C;AAAA,QAC/D;AACA,gBAAQ;AAAA,MACV;AAEA,YAAM,MAAM;AAAA,IACd,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,UAAU,IAA+B;AACvC,SAAK,UAAU,KAAK,EAAE;AACtB,WAAO,MAAM;AACX,WAAK,YAAY,KAAK,UAAU,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,IACxD;AAAA,EACF;AAAA,EAEQ,OAAa;AACnB,UAAM,MAAM,KAAK,OAAO;AACxB,eAAW,MAAM,KAAK,UAAW,IAAG,GAAG;AAAA,EACzC;AACF;;;ACjNO,SAAS,uBACd,OAAO,YACP,cAAc,IACC;AACf,SAAO;AAAA,IACL,IAAI,OAAO,WAAW;AAAA,IACtB;AAAA,IACA;AAAA,IACA,aAAa,CAAC,GAAG,GAAG,CAAC;AAAA,IACrB,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,IAClB,OAAO,CAAC,GAAG,GAAG,CAAC;AAAA,IACf,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAGO,SAAS,qBAAgC;AAC9C,SAAO;AAAA,IACL,aAAa,CAAC,GAAG,GAAG,CAAC;AAAA,IACrB,OAAO,CAAC;AAAA,EACV;AACF;;;ACjEA,IAAMA,eAAc;AAoBb,IAAM,aAAN,MAAiB;AAAA,EACd,QAAmB,mBAAmB;AAAA,EACtC,YAA6B,CAAC;AAAA,EACrB;AAAA,EAEjB,YAAY,UAA6B,CAAC,GAAG;AAC3C,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAIA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,SAAU;AACpB,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,KAAK,QAAQ;AACrC,UAAI,CAAC,IAAI,IAAI;AACX,gBAAQ;AAAA,UACN,gCAAgC,KAAK,QAAQ,MAAM,IAAI,MAAM;AAAA,QAC/D;AACA;AAAA,MACF;AACA,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,WAAK,QAAQ;AACb,WAAK,QAAQ;AACb,WAAK,KAAK;AAAA,IACZ,QAAQ;AACN,cAAQ,KAAK,iCAAiC,KAAK,QAAQ,GAAG;AAAA,IAChE;AAAA,EACF;AAAA;AAAA,EAIA,MAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAA4B;AAC1B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,QAAQ,IAAuC;AAC7C,WAAO,KAAK,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EACjD;AAAA,EAEA,iBAA2C;AACzC,WAAO,CAAC,GAAG,KAAK,MAAM,WAAW;AAAA,EACnC;AAAA;AAAA,EAIA,eAAe,GAAW,GAAW,GAAiB;AACpD,SAAK,MAAM,cAAc,CAAC,GAAG,GAAG,CAAC;AACjC,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA,EAEA,QAAQ,MAA2B;AACjC,SAAK,MAAM,MAAM,KAAK,IAAI;AAC1B,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA,EAEA,WAAW,MAA2B;AACpC,UAAM,MAAM,KAAK,MAAM,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE;AAC9D,QAAI,QAAQ,GAAI;AAChB,SAAK,MAAM,MAAM,GAAG,IAAI,EAAE,GAAG,KAAK;AAClC,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA,EAEA,WAAW,IAAkB;AAC3B,SAAK,MAAM,QAAQ,KAAK,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAC7D,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA;AAAA,EAGA,SAAS,MAAuB;AAC9B,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,KAAK,aAAa;AAAA,EACzB;AAAA;AAAA,EAIA,MAAM,eAAiC;AACrC,QAAI,CAAC,KAAK,SAAU,QAAO;AAC3B,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,cAAc;AAAA,QACpC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,CAAC;AAAA,MAC1C,CAAC;AACD,UAAI,CAAC,IAAI,IAAI;AACX,gBAAQ,KAAK,oCAAoC,IAAI,MAAM,GAAG;AAAA,MAChE;AACA,aAAO,IAAI;AAAA,IACb,QAAQ;AACN,cAAQ,KAAK,0CAA0C;AACvD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAIQ,UAAgB;AACtB,QAAI;AACF,mBAAa,QAAQA,cAAa,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IAC9D,QAAQ;AACN,cAAQ,KAAK,8CAA8C;AAAA,IAC7D;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAC9B,QAAI;AACF,YAAM,MAAM,aAAa,QAAQA,YAAW;AAC5C,UAAI,CAAC,IAAK;AACV,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,UAAI,QAAQ,MAAM,QAAQ,KAAK,KAAK,GAAG;AACrC,aAAK,QAAQ;AAAA,MACf;AAAA,IACF,QAAQ;AACN,cAAQ,KAAK,+CAA+C;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,aAAa,WAAW,cAA6B;AACzD,UAAM,OAAO,KAAK,UAAU,KAAK,OAAO,MAAM,CAAC;AAC/C,UAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAE1D,QAAI,wBAAwB,QAAQ;AAClC,UAAI;AACF,cAAM,SAAS,MACb,OAKA,mBAAmB;AAAA,UACnB,eAAe;AAAA,UACf,OAAO;AAAA,YACL,EAAE,aAAa,QAAQ,QAAQ,EAAE,oBAAoB,CAAC,OAAO,EAAE,EAAE;AAAA,UACnE;AAAA,QACF,CAAC;AACD,cAAM,WAAW,MAAM,OAAO,eAAe;AAC7C,cAAM,SAAS,MAAM,IAAI;AACzB,cAAM,SAAS,MAAM;AACrB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,OAAO;AACT,MAAE,WAAW;AACb,MAAE,MAAM;AACR,QAAI,gBAAgB,GAAG;AAAA,EACzB;AAAA,EAEA,iBAAgC;AAC9B,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,OAAO;AACb,YAAM,SAAS;AAEf,YAAM,WAAW,YAAY;AAC3B,cAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,YAAI,CAAC,MAAM;AACT,kBAAQ;AACR;AAAA,QACF;AACA,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,gBAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,cAAI,QAAQ,MAAM,QAAQ,KAAK,KAAK,GAAG;AACrC,iBAAK,QAAQ;AACb,iBAAK,QAAQ;AACb,iBAAK,KAAK;AAAA,UACZ;AAAA,QACF,QAAQ;AACN,kBAAQ,MAAM,4CAA4C;AAAA,QAC5D;AACA,gBAAQ;AAAA,MACV;AAEA,YAAM,MAAM;AAAA,IACd,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,UAAU,IAA+B;AACvC,SAAK,UAAU,KAAK,EAAE;AACtB,WAAO,MAAM;AACX,WAAK,YAAY,KAAK,UAAU,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,IACxD;AAAA,EACF;AAAA,EAEQ,OAAa;AACnB,UAAM,OAAO,KAAK;AAClB,eAAW,MAAM,KAAK,UAAW,IAAG,IAAI;AAAA,EAC1C;AACF;;;AC3MO,IAAM,eAAN,MAAM,cAAa;AAAA,EAYhB,YACW,OACjB,UAA+B,CAAC,GAChC;AAFiB;AAGjB,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,mBAAmB,QAAQ,qBAAqB,MAAM,CAAC;AAC5D,SAAK,WAAW,QAAQ,YAAY;AAAA,EACtC;AAAA,EANmB;AAAA,EAZX,OAA2B;AAAA,EAC3B,SAA6B;AAAA,EAC7B,aAA4B;AAAA,EAC5B,SAA6B;AAAA,EAC7B;AAAA,EACA,gBAAsC,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACT,cAAuC;AAAA;AAAA,EAa/C,OAAO,OACL,OACA,SACc;AACd,WAAO,IAAI,cAAa,OAAO,OAAO;AAAA,EACxC;AAAA;AAAA,EAIA,QAAmB;AACjB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,cAAc,CAAC,MAAM,KAAK,aAAa,CAAC;AAAA,MACxC,YAAY,MAAM,KAAK,WAAW;AAAA,MAClC,cAAc,MAAM,KAAK,aAAa;AAAA,MACtC,SAAS,MAAM,KAAK,QAAQ;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA,EAIQ,aAAmB;AAEzB,QAAI,KAAK,cAAc,WAAW,KAAK,KAAK,YAAY;AACtD,WAAK,MAAM,KAAK,UAAU,EACvB,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EACpB,KAAK,CAAC,SAA+B;AACpC,aAAK,gBAAgB;AACrB,aAAK,YAAY;AAAA,MACnB,CAAC,EACA;AAAA,QAAM,MACL,QAAQ,KAAK,+CAA+C;AAAA,MAC9D;AAAA,IACJ;AACA,SAAK,YAAY;AACjB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEQ,eAAqB;AAAA,EAE7B;AAAA;AAAA,EAIQ,aAAa,WAA8B;AACjD,SAAK,OAAO;AAGZ,UAAM,UAAU,GAAG,OAAO,aAAa;AACvC,YAAQ;AAAA,MACN,KAAK,MAAM,eAAU,MAAM,KAAK,MAAM,GAAG,gBAAgB;AAAA,IAC3D;AACA,YAAQ;AAAA,MACN,KAAK,MAAM,UAAK,MAAM,KAAK,YAAY,GAAG,oBAAoB;AAAA,IAChE;AACA,YAAQ;AAAA,MACN,KAAK,MAAM,aAAM,MAAM,KAAK,SAAS,GAAG,iBAAiB;AAAA,IAC3D;AACA,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,YAAY;AAAA,IACd;AACA,cAAU,cAAc;AACxB,cAAU,QAAQ;AAClB,cAAU,UAAU,MAAM,SAAS,OAAO;AAC1C,YAAQ,YAAY,SAAS;AAG7B,QAAI,KAAK,UAAU;AACjB,YAAM,cAAc,SAAS,cAAc,OAAO;AAClD,kBAAY,MAAM,UAChB;AACF,WAAK,cAAc,SAAS,cAAc,OAAO;AACjD,WAAK,YAAY,OAAO;AACxB,WAAK,YAAY,UAAU,KAAK,SAAS;AACzC,WAAK,YAAY,WAAW,MAAM;AAChC,YAAI,KAAK,UAAU;AACjB,eAAK,SAAS,QAAQ,KAAK,YAAa;AAAA,QAC1C;AAAA,MACF;AACA,kBAAY,YAAY,KAAK,WAAW;AACxC,YAAM,aAAa,SAAS,cAAc,MAAM;AAChD,iBAAW,cAAc;AACzB,kBAAY,YAAY,UAAU;AAClC,cAAQ,YAAY,WAAW;AAAA,IACjC;AAGA,UAAM,OAAO,GAAG,OAAO,sCAAsC;AAC7D,SAAK,SAAS,GAAG,OAAO,UAAU;AAClC,SAAK,SAAS,GAAG,OAAO,UAAU;AAClC,SAAK,YAAY,KAAK,MAAM;AAC5B,SAAK,YAAY,KAAK,MAAM;AAE5B,cAAU,YAAY,OAAO;AAC7B,cAAU,YAAY,IAAI;AAE1B,SAAK,QAAQ,KAAK,MAAM,UAAU,MAAM;AACtC,WAAK,YAAY;AACjB,WAAK,YAAY;AAAA,IACnB,CAAC;AAED,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA,EAIQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,YAAY;AAGxB,UAAM,QAAQ,KAAK,MAAM,eAAe;AACxC,UAAM,YAAY,GAAG,OAAO,UAAU;AACtC,cAAU,MAAM,aAAa;AAC7B,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AACA,eAAW,cAAc;AACzB,cAAU,YAAY,UAAU;AAChC,cAAU;AAAA,MACR,QAAQ,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE;AAAA,IACjE;AACA,cAAU,MAAM,SAAS;AACzB,cAAU,UAAU,MAAM;AACxB,WAAK,aAAa;AAClB,WAAK,YAAY;AACjB,WAAK,YAAY;AAAA,IACnB;AACA,QAAI,KAAK,eAAe,oBAAoB;AAC1C,gBAAU,MAAM,aAAa;AAAA,IAC/B;AACA,SAAK,OAAO,YAAY,SAAS;AAGjC,UAAM,MAAM,GAAG,OAAO,0CAA0C;AAChE,SAAK,OAAO,YAAY,GAAG;AAG3B,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,MAAM,SAAS;AAClC,YAAQ,cAAc,iBAAiB,MAAM,MAAM;AACnD,SAAK,OAAO,YAAY,OAAO;AAE/B,eAAW,QAAQ,OAAO;AACxB,YAAM,SAAS,KAAK,OAAO,KAAK;AAChC,YAAM,OAAO,GAAG,OAAO,UAAU;AACjC,UAAI,OAAQ,MAAK,MAAM,aAAa;AACpC,WAAK,MAAM,SAAS;AACpB,WAAK,UAAU,MAAM;AACnB,aAAK,aAAa,KAAK;AAEvB,YAAI,KAAK,UAAU;AACjB,eAAK,SAAS,QAAQ;AACtB,cAAI,KAAK,YAAa,MAAK,YAAY,UAAU;AAAA,QACnD;AACA,aAAK,YAAY;AACjB,aAAK,YAAY;AAAA,MACnB;AAEA,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,MACF;AACA,aAAO,cAAc,GAAG,KAAK,IAAI,MAAM,KAAK,WAAW;AACvD,WAAK,YAAY,MAAM;AAEvB,WAAK;AAAA,QACH;AAAA,UACE;AAAA,UACA,GAAG,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC;AAAA,QACjF;AAAA,MACF;AACA,WAAK;AAAA,QACH;AAAA,UACE;AAAA,UACA,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC;AAAA,QAC/D;AAAA,MACF;AAEA,WAAK,OAAO,YAAY,IAAI;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA,EAIQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,YAAY;AAExB,QAAI,KAAK,eAAe,oBAAoB;AAC1C,WAAK,eAAe,KAAK,MAAM;AAC/B;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,aACd,KAAK,MAAM,QAAQ,KAAK,UAAU,IAClC;AACJ,QAAI,CAAC,MAAM;AACT,YAAM,OAAO,GAAG,OAAO,wCAAwC;AAC/D,WAAK,cAAc;AACnB,WAAK,OAAO,YAAY,IAAI;AAC5B;AAAA,IACF;AAEA,SAAK,cAAc,KAAK,QAAQ,IAAI;AAAA,EACtC;AAAA,EAEQ,eAAe,WAA8B;AACnD,UAAM,QAAQ,KAAK,MAAM,eAAe;AACxC,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AACA,UAAM,cAAc;AACpB,cAAU,YAAY,KAAK;AAE3B,cAAU;AAAA,MACR,KAAK,QAAQ,YAAY,OAAO,CAAC,MAAM;AACrC,aAAK,MAAM,eAAe,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,cAAc,WAAwB,MAA2B;AACvE,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AACA,UAAM,cAAc,KAAK;AACzB,cAAU,YAAY,KAAK;AAG3B,cAAU;AAAA,MACR,KAAK,QAAQ,QAAQ,KAAK,MAAM,CAAC,MAAM;AACrC,aAAK,MAAM,WAAW,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH;AAGA,UAAM,eAAe,KAAK,cAAc,IAAI,CAAC,OAAO;AAAA,MAClD,OAAO,EAAE;AAAA,MACT,OAAO,GAAG,EAAE,IAAI,MAAM,EAAE,IAAI;AAAA,IAC9B,EAAE;AACF,cAAU;AAAA,MACR,KAAK,UAAU,YAAY,KAAK,aAAa,cAAc,CAAC,MAAM;AAChE,aAAK,MAAM,WAAW,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;AAAA,MACnD,CAAC;AAAA,IACH;AAGA,UAAM,WAAW,KAAK,iBAAiB;AACvC,UAAM,aAAa;AAAA,MACjB,EAAE,OAAO,IAAI,OAAO,YAAY;AAAA,MAChC,GAAG,SAAS,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE;AAAA,IACjD;AACA,cAAU;AAAA,MACR,KAAK,UAAU,YAAY,KAAK,eAAe,IAAI,YAAY,CAAC,MAAM;AACpE,aAAK,MAAM,WAAW,EAAE,GAAG,MAAM,aAAa,KAAK,KAAK,CAAC;AAAA,MAC3D,CAAC;AAAA,IACH;AAGA,cAAU;AAAA,MACR,KAAK;AAAA,QACH;AAAA,QACA,CAAC,GAAG,KAAK,WAAW;AAAA,QACpB,CAAC,MAAM;AACL,eAAK,MAAM,WAAW,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAGA,cAAU;AAAA,MACR,KAAK;AAAA,QACH;AAAA,QACA,CAAC,GAAG,KAAK,QAAQ;AAAA,QACjB,CAAC,MAAM;AACL,eAAK,MAAM,WAAW,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAGA,cAAU;AAAA,MACR,KAAK;AAAA,QACH;AAAA,QACA,CAAC,GAAG,KAAK,KAAK;AAAA,QACd,CAAC,MAAM;AACL,eAAK,MAAM,WAAW,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,UAAU;AACjC,cAAU;AAAA,MACR,KAAK,SAAS,iBAAiB,WAAW,CAAC,OAAO;AAChD,YAAI,IAAI;AACN,eAAK,MAAM,WAAW;AAAA,YACpB,GAAG;AAAA,YACH,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,UAC3B,CAAC;AAAA,QACH,OAAO;AACL,eAAK,MAAM,WAAW,EAAE,GAAG,MAAM,QAAQ,KAAK,CAAC;AAAA,QACjD;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,IAAI,KAAK;AACf,gBAAU;AAAA,QACR,KAAK,QAAQ,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;AAChD,eAAK,MAAM,WAAW;AAAA,YACpB,GAAG;AAAA,YACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,UAC7C,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AACA,gBAAU;AAAA,QACR,KAAK,QAAQ,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;AAC9C,eAAK,MAAM,WAAW;AAAA,YACpB,GAAG;AAAA,YACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,UAC7C,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAGA,cAAU;AAAA,MACR,KAAK,SAAS,YAAY,KAAK,aAAa,OAAO,CAAC,OAAO;AACzD,aAAK,MAAM,WAAW,EAAE,GAAG,MAAM,UAAU,GAAG,CAAC;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAIQ,QAAc;AACpB,UAAM,OAAO,uBAAuB;AACpC,SAAK,MAAM,QAAQ,IAAI;AACvB,SAAK,aAAa,KAAK;AAAA,EACzB;AAAA,EAEQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,cAAc,KAAK,eAAe,mBAAoB;AAChE,UAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,UAAU;AAC9C,QAAI,CAAC,IAAK;AACV,UAAM,OAAsB;AAAA,MAC1B,GAAG;AAAA,MACH,IAAI,OAAO,WAAW;AAAA,MACtB,MAAM,GAAG,IAAI,IAAI;AAAA,MACjB,aAAa,CAAC,GAAG,IAAI,WAAW;AAAA,MAChC,UAAU,CAAC,GAAG,IAAI,QAAQ;AAAA,MAC1B,OAAO,CAAC,GAAG,IAAI,KAAK;AAAA,MACpB,QAAQ,IAAI,SACP,CAAC,GAAG,IAAI,MAAM,IACf;AAAA,IACN;AACA,SAAK,MAAM,QAAQ,IAAI;AACvB,SAAK,aAAa,KAAK;AAAA,EACzB;AAAA,EAEQ,WAAiB;AACvB,QAAI,CAAC,KAAK,cAAc,KAAK,eAAe,mBAAoB;AAChE,SAAK,MAAM,WAAW,KAAK,UAAU;AACrC,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA,EAIQ,QACN,OACA,QACA,UACa;AACb,UAAM,MAAM,GAAG,OAAO,SAAS;AAC/B,UAAM,MAAM,GAAG,OAAO,WAAW;AACjC,QAAI,cAAc;AAClB,QAAI,YAAY,GAAG;AAEnB,UAAM,QAAQ,GAAG,OAAO,uBAAuB;AAC/C,UAAM,SAAS,CAAC,KAAK,KAAK,GAAG;AAE7B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,OAAO,GAAG,OAAO,4CAA4C;AACnE,YAAM,UAAU,GAAG,OAAO,6CAA6C;AACvE,cAAQ,cAAc,OAAO,CAAC;AAC9B,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,OAAO;AACb,YAAM,OAAO;AACb,YAAM,QAAQ,OAAO,OAAO,CAAC,CAAC;AAC9B,YAAM,MAAM,UAAU;AACtB,YAAM,WAAW,MAAM;AACrB,cAAM,IAAI,CAAC,GAAG,MAAM;AACpB,UAAE,CAAC,IAAI,WAAW,MAAM,KAAK,KAAK;AAClC,iBAAS,CAAC;AAAA,MACZ;AACA,WAAK,YAAY,OAAO;AACxB,WAAK,YAAY,KAAK;AACtB,YAAM,YAAY,IAAI;AAAA,IACxB;AAEA,QAAI,YAAY,KAAK;AACrB,WAAO;AAAA,EACT;AAAA,EAEQ,QACN,OACA,OACA,UACa;AACb,UAAM,MAAM,GAAG,OAAO,SAAS;AAC/B,UAAM,MAAM,GAAG,OAAO,WAAW;AACjC,QAAI,cAAc;AAClB,QAAI,YAAY,GAAG;AAEnB,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO;AACb,UAAM,QAAQ;AACd,UAAM,MAAM,UAAU,cAAc;AACpC,UAAM,WAAW,MAAM,SAAS,MAAM,KAAK;AAC3C,QAAI,YAAY,KAAK;AACrB,WAAO;AAAA,EACT;AAAA,EAEQ,UACN,OACA,OACA,SACA,UACa;AACb,UAAM,MAAM,GAAG,OAAO,SAAS;AAC/B,UAAM,MAAM,GAAG,OAAO,WAAW;AACjC,QAAI,cAAc;AAClB,QAAI,YAAY,GAAG;AAEnB,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,MAAM,UAAU,cAAc;AACrC,eAAW,OAAO,SAAS;AACzB,YAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,QAAE,QAAQ,IAAI;AACd,QAAE,cAAc,IAAI;AACpB,UAAI,IAAI,UAAU,MAAO,GAAE,WAAW;AACtC,aAAO,YAAY,CAAC;AAAA,IACtB;AACA,WAAO,WAAW,MAAM,SAAS,OAAO,KAAK;AAC7C,QAAI,YAAY,MAAM;AACtB,WAAO;AAAA,EACT;AAAA,EAEQ,SACN,OACA,SACA,UACa;AACb,UAAM,MAAM,GAAG,OAAO,YAAY,sBAAsB;AACxD,UAAM,MAAM,GAAG,OAAO,WAAW;AACjC,QAAI,cAAc;AAClB,QAAI,YAAY,GAAG;AAEnB,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO;AACb,UAAM,UAAU;AAChB,UAAM,WAAW,MAAM,SAAS,MAAM,OAAO;AAC7C,QAAI,YAAY,KAAK;AACrB,WAAO;AAAA,EACT;AAAA,EAEQ,MACN,MACA,SACA,OACmB;AACnB,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,QAAI,cAAc;AAClB,QAAI,QAAQ;AACZ,QAAI,MAAM,UAAU;AACpB,QAAI,UAAU;AACd,WAAO;AAAA,EACT;AACF;AAIA,SAAS,GACP,KACA,QAAQ,IAC0C;AAClD,QAAMC,MAAK,SAAS,cAAc,GAAG;AAGrC,MAAI,MAAO,CAAAA,IAAG,MAAM,UAAU;AAC9B,SAAOA;AACT;AAEA,SAAS,EAAE,GAAmB;AAC5B,SAAO,EAAE,QAAQ,CAAC;AACpB;AAEA,SAAS,QAAQ,OAAe,OAA4B;AAC1D,QAAM,MAAM,SAAS,cAAc,KAAK;AACxC,MAAI,MAAM,UAAU;AAEpB,QAAM,MAAM,SAAS,cAAc,MAAM;AACzC,MAAI,MAAM,UAAU;AACpB,MAAI,cAAc;AAElB,QAAM,MAAM,SAAS,cAAc,MAAM;AACzC,MAAI,MAAM,UAAU;AACpB,MAAI,cAAc;AAElB,MAAI,YAAY,GAAG;AACnB,MAAI,YAAY,GAAG;AACnB,SAAO;AACT;AAIA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,YAAY;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,aAAa,CAAC,UAAU,mBAAmB,cAAc,EAAE,KAAK,GAAG;AAEzE,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,YAAY,CAAC,gBAAgB,WAAW,mBAAmB,EAAE,KAAK,GAAG;AAE3E,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;;;ACrmBH,IAAM,gBAAN,MAAM,eAAc;AAAA,EAqBjB,YAA6B,OAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EApB7B;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAoB,CAAC;AAAA,EACrB,cAA6B;AAAA;AAAA,EAG7B;AAAA,EACA;AAAA,EACA,aAA4B;AAAA,EAC5B;AAAA;AAAA,EAGA,gBAAgB;AAAA,EAChB,YAAY;AAAA;AAAA,EAGZ,cAAqC;AAAA,EACrC,aAAuC;AAAA;AAAA,EAM/C,OAAO,MAAM,OAAqC;AAChD,UAAM,IAAI,IAAI,eAAc,KAAK;AACjC,MAAE,MAAM;AACR,WAAO;AAAA,EACT;AAAA,EAEA,OAAa;AACX,SAAK,KAAK,MAAM,UAAU;AAC1B,SAAK,YAAY;AACjB,QAAI,KAAK,aAAa;AACpB,WAAK,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,WAAW,GAAG,aAAa;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,aAAa;AACpB,WAAK,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,WAAW,GAAG,eAAe;AAAA,IACnE;AACA,SAAK,KAAK,MAAM,UAAU;AAC1B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,SAAe;AACb,QAAI,KAAK,KAAK,MAAM,YAAY,OAAQ,MAAK,KAAK;AAAA,QAC7C,MAAK,KAAK;AAAA,EACjB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,KAAK,MAAM,YAAY;AAAA,EACrC;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,SAAK,KAAK,KAAK,GAAG;AAClB,QAAI,KAAK,OAAQ,MAAK,aAAa;AAAA,EACrC;AAAA,EAEA,UAAgB;AACd,SAAK,iBAAiB;AACtB,eAAW,KAAK,KAAK,KAAM,GAAE,UAAU;AACvC,SAAK,MAAM,OAAO;AAAA,EACpB;AAAA;AAAA,EAIQ,QAAc;AACpB,SAAK,OAAO,GAAG,OAAO,EAAE,IAAI,oBAAoB,GAAG,aAAa;AAChE,SAAK,KAAK,MAAM,UAAU;AAC1B,SAAK,KAAK,MAAM,QAAQ,GAAG,KAAK,aAAa;AAG7C,UAAM,SAAS,GAAG,OAAO,CAAC,GAAG,iBAAiB;AAC9C,WAAO,iBAAiB,aAAa,CAAC,MAAM;AAC1C,QAAE,eAAe;AACjB,WAAK,YAAY;AACjB,eAAS,KAAK,MAAM,SAAS;AAC7B,eAAS,KAAK,MAAM,aAAa;AAAA,IACnC,CAAC;AACD,aAAS,iBAAiB,aAAa,CAAC,MAAM;AAC5C,UAAI,CAAC,KAAK,UAAW;AACrB,YAAM,WAAW,OAAO,aAAa,EAAE;AACvC,WAAK,gBAAgB,KAAK,IAAI,KAAK,KAAK,IAAI,UAAU,GAAG,CAAC;AAC1D,WAAK,KAAK,MAAM,QAAQ,GAAG,KAAK,aAAa;AAC7C,WAAK,YAAY;AAAA,IACnB,CAAC;AACD,aAAS,iBAAiB,WAAW,MAAM;AACzC,UAAI,CAAC,KAAK,UAAW;AACrB,WAAK,YAAY;AACjB,eAAS,KAAK,MAAM,SAAS;AAC7B,eAAS,KAAK,MAAM,aAAa;AAAA,IACnC,CAAC;AACD,SAAK,KAAK,YAAY,MAAM;AAE5B,UAAM,SAAS,GAAG,OAAO,CAAC,GAAG,YAAY;AACzC,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,CAAC;AAAA,MACD;AAAA,IACF;AACA,UAAM,cAAc;AACpB,WAAO,YAAY,KAAK;AAExB,SAAK,aAAa;AAAA,MAChB;AAAA,MACA,CAAC;AAAA,MACD,iBAAiB;AAAA,IACnB;AACA,SAAK,WAAW,QAAQ;AACxB,SAAK,WAAW,cAAc;AAC9B,SAAK,WAAW,UAAU,MAAM,KAAK,aAAa;AAClD,WAAO,YAAY,KAAK,UAAU;AAElC,UAAM,WAAW,GAAG,UAAU,CAAC,GAAG,cAAc;AAChD,aAAS,cAAc;AACvB,aAAS,QAAQ;AACjB,aAAS,UAAU,MAAM,KAAK,KAAK;AACnC,WAAO,YAAY,QAAQ;AAE3B,SAAK,SAAS,GAAG,OAAO,CAAC,GAAG,aAAa;AACzC,SAAK,cAAc;AAAA,MACjB;AAAA,MACA,CAAC;AAAA,MACD;AAAA,IACF;AAEA,SAAK,KAAK,YAAY,MAAM;AAC5B,SAAK,KAAK,YAAY,KAAK,MAAM;AACjC,SAAK,KAAK,YAAY,KAAK,WAAW;AACtC,aAAS,KAAK,YAAY,KAAK,IAAI;AAEnC,SAAK,OAAO;AAAA,MACV,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,cAAc,CAAC,MAAM,KAAK,sBAAsB,CAAC;AAAA,MACjD,SAAS,MAAM,KAAK,iBAAiB;AAAA,IACvC,CAAC;AACD,SAAK,YAAY,WAAW;AAAA,EAC9B;AAAA;AAAA,EAIQ,eAAqB;AAC3B,SAAK,cAAc,KAAK,gBAAgB,aAAa,WAAW;AAChE,SAAK,YAAY;AAAA,EACnB;AAAA,EAEQ,cAAoB;AAC1B,UAAM,UAAU,KAAK,KAAK,MAAM,YAAY;AAC5C,QAAI,KAAK,gBAAgB,YAAY,SAAS;AAC5C,eAAS,KAAK,MAAM,cAAc,GAAG,KAAK,aAAa;AAAA,IACzD,OAAO;AACL,eAAS,KAAK,MAAM,cAAc;AAAA,IACpC;AAEA,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,cAAc,KAAK,gBAAgB,aAAa,WAAM;AACtE,WAAK,WAAW,QACd,KAAK,gBAAgB,aACjB,8CACA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAIQ,eAAqB;AAC3B,SAAK,OAAO,YAAY;AACxB,eAAW,OAAO,KAAK,MAAM;AAC3B,YAAM,MAAM;AAAA,QACV;AAAA,QACA,CAAC;AAAA,QACD,iBAAiB,IAAI,OAAO,KAAK,cAAc,iBAAiB;AAAA,MAClE;AACA,UAAI,cAAc,IAAI;AACtB,UAAI,UAAU,MAAM,KAAK,YAAY,IAAI,EAAE;AAC3C,WAAK,OAAO,YAAY,GAAG;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA,EAGA,YAAY,IAAkB;AAE5B,QAAI,KAAK,eAAe,KAAK,gBAAgB,IAAI;AAC/C,WAAK,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,WAAW,GAAG,eAAe;AAAA,IACnE;AACA,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,YAAY,YAAY;AAC7B,UAAM,MAAM,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC7C,QAAI,CAAC,IAAK;AACV,UAAM,IAAI;AAAA,MACR;AAAA,MACA,CAAC;AAAA,MACD;AAAA,IACF;AACA,QAAI,aAAa,CAAC;AAClB,SAAK,YAAY,YAAY,CAAC;AAC9B,QAAI,aAAa;AAAA,EACnB;AAAA;AAAA,EAIQ,sBAAsB,WAA8B;AAC1D,UAAM,UAAU,GAAG,OAAO,CAAC,GAAGC,cAAa;AAC3C,YAAQ,YAAY,KAAK,MAAM,UAAK,MAAM,KAAK,MAAM,GAAG,cAAc,CAAC;AACvE,YAAQ,YAAY,KAAK,MAAM,UAAK,MAAM,KAAK,YAAY,GAAG,WAAW,CAAC;AAC1E,YAAQ,YAAY,KAAK,MAAM,aAAM,MAAM,KAAK,SAAS,GAAG,QAAQ,CAAC;AACrE,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,CAAC;AAAA,MACDC,aAAY;AAAA,IACd;AACA,cAAU,cAAc;AACxB,cAAU,QAAQ;AAClB,cAAU,UAAU,MAAM,SAAS,OAAO;AAC1C,YAAQ,YAAY,SAAS;AAE7B,UAAM,OAAO,GAAG,OAAO,CAAC,GAAG,sCAAsC;AACjE,SAAK,SAAS,GAAG,OAAO,CAAC,GAAGC,WAAU;AACtC,SAAK,SAAS,GAAG,OAAO,CAAC,GAAGC,WAAU;AACtC,SAAK,YAAY,KAAK,MAAM;AAC5B,SAAK,YAAY,KAAK,MAAM;AAE5B,cAAU,YAAY,OAAO;AAC7B,cAAU,YAAY,IAAI;AAE1B,SAAK,iBAAiB,KAAK,MAAM,UAAU,MAAM,KAAK,YAAY,CAAC;AACnE,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA,EAIQ,cAAoB;AAC1B,SAAK,OAAO,YAAY;AACxB,eAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;AACtC,YAAM,SAAS,KAAK,OAAO,KAAK;AAChC,YAAM,OAAO;AAAA,QACX;AAAA,QACA,CAAC;AAAA,QACD,mBAAmB,SAAS,mBAAmB;AAAA,MACjD;AAEA,YAAM,SAAS,GAAG,OAAO,CAAC,GAAG,YAAY,IAAI,CAAC;AAC9C,WAAK,YAAY,MAAM;AACvB,YAAM,SAAS;AAAA,QACb;AAAA,QACA,CAAC;AAAA,QACD;AAAA,MACF;AACA,aAAO,cAAc,KAAK;AAC1B,WAAK,YAAY,MAAM;AACvB,WAAK,UAAU,MAAM,KAAK,OAAO,KAAK,EAAE;AACxC,WAAK,OAAO,YAAY,IAAI;AAAA,IAC9B;AAEA,QAAI,KAAK,cAAc,CAAC,KAAK,MAAM,IAAI,KAAK,UAAU,GAAG;AACvD,WAAK,aAAa;AAClB,WAAK,OAAO,YAAY;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,OAAO,IAAkB;AAC/B,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAIQ,YAAkB;AACxB,UAAM,OAAO,KAAK,aAAa,KAAK,MAAM,IAAI,KAAK,UAAU,IAAI;AACjE,SAAK,OAAO,YAAY;AACxB,QAAI,CAAC,KAAM;AAEX,UAAM,QAAsB;AAAA,MAC1B,GAAG;AAAA,MACH,aAAa,CAAC,GAAG,KAAK,WAAW;AAAA,MACjC,SAAS,CAAC,GAAG,KAAK,OAAO;AAAA,MACzB,cAAc,CAAC,GAAG,KAAK,YAAY;AAAA,MACnC,UAAU,CAAC,GAAG,KAAK,QAAQ;AAAA,IAC7B;AAEA,UAAM,OAAO,MAAM;AACjB,WAAK,MAAM,OAAO,KAAK;AACvB,WAAK,OAAO,MAAM,EAAE;AAAA,IACtB;AAGA,YAAQ,KAAK,QAAQ,QAAQ,MAAM;AACjC,YAAM,MAAM,GAAG,SAAS,EAAE,MAAM,QAAQ,OAAO,MAAM,KAAK,GAAGC,YAAW;AACxE,UAAI,UAAU,MAAM;AAClB,cAAM,OAAO,IAAI;AAAA,MACnB;AACA,UAAI,SAAS;AACb,aAAO;AAAA,IACT,CAAC;AAGD,YAAQ,KAAK,QAAQ,iBAAiB,MAAM;AAC1C,YAAM,OAAO,GAAG,OAAO,CAAC,GAAG,0CAA0C;AACrE,YAAM,MAAM;AAAA,QACV,MAAM,YAAY,CAAC;AAAA,QACnB,MAAM,YAAY,CAAC;AAAA,QACnB,MAAM,YAAY,CAAC;AAAA,MACrB;AACA,YAAM,SAAS;AAAA,QACb;AAAA,QACA,EAAE,MAAM,SAAS,OAAO,IAAI;AAAA,QAC5B;AAAA,MACF;AACA,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,KAAK;AAAA,UACL,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAO,OAAO,MAAM,YAAY,CAAC,CAAC;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AACA,YAAM,WAAW;AAAA,QACf;AAAA,QACA,CAAC;AAAA,QACD;AAAA,MACF;AACA,eAAS,cAAc,MAAM,YAAY,CAAC,EAAE,QAAQ,CAAC;AACrD,YAAM,SAAS,MAAM;AACnB,cAAM,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,OAAO,KAAK;AACvC,cAAM,cAAc,CAAC,GAAG,GAAG,GAAG,WAAW,QAAQ,KAAK,CAAC;AACvD,iBAAS,cAAc,WAAW,QAAQ,KAAK,EAAE,QAAQ,CAAC;AAC1D,aAAK;AAAA,MACP;AACA,aAAO,UAAU;AACjB,cAAQ,UAAU;AAClB,WAAK,YAAY,MAAM;AACvB,WAAK,YAAY,OAAO;AACxB,WAAK,YAAY,QAAQ;AACzB,aAAO;AAAA,IACT,CAAC;AAGD,eAAW,OAAO,CAAC,WAAW,gBAAgB,UAAU,GAAkB;AACxE,YAAM,QAAQ;AAAA,QACZ,SAAS;AAAA,QACT,cAAc;AAAA,QACd,UAAU;AAAA,MACZ,EAAE,GAAG;AACL,cAAQ,KAAK,QAAQ,OAAO,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,CAAC;AAChE,cAAM,SAAS;AAAA,UACb;AAAA,UACA,EAAE,MAAM,SAAS,OAAO,IAAI;AAAA,UAC5B;AAAA,QACF;AACA,eAAO,UAAU,MAAM;AACrB,WAAC,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI;AAAA,YAC9C,OAAO;AAAA,UACT;AACA,eAAK;AAAA,QACP;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAGA,eAAW,KAAK,QAAQ,aAAa,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,MAAM;AACtE,YAAM,YAAY;AAClB,WAAK;AAAA,IACP,CAAC;AACD,eAAW,KAAK,QAAQ,YAAY,MAAM,UAAU,GAAG,GAAG,MAAM,CAAC,MAAM;AACrE,YAAM,WAAW;AACjB,WAAK;AAAA,IACP,CAAC;AACD;AAAA,MACE,KAAK;AAAA,MACL;AAAA,MACA,MAAM,YAAY;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,MAAM;AACL,cAAM,WAAW;AACjB,aAAK;AAAA,MACP;AAAA,IACF;AAGA,aAAS,KAAK,QAAQ,SAAS,MAAM,OAAO,CAAC,MAAM;AACjD,YAAM,QAAQ;AACd,WAAK;AAAA,IACP,CAAC;AACD,aAAS,KAAK,QAAQ,gBAAgB,MAAM,aAAa,CAAC,MAAM;AAC9D,YAAM,cAAc;AACpB,WAAK;AAAA,IACP,CAAC;AAGD,YAAQ,KAAK,QAAQ,gBAAgB,MAAM;AACzC,YAAM,MAAM;AAAA,QACV;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO,MAAM,eAAe;AAAA,UAC5B,aAAa;AAAA,QACf;AAAA,QACAA;AAAA,MACF;AACA,UAAI,UAAU,MAAM;AAClB,cAAM,cAAc,IAAI,SAAS;AAAA,MACnC;AACA,UAAI,SAAS;AACb,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,QAAc;AACpB,UAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,SAAK,OAAO,KAAK,EAAE;AAAA,EACrB;AAAA,EAEQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,WAAY;AACtB,UAAM,OAAO,KAAK,MAAM,UAAU,KAAK,UAAU;AACjD,QAAI,KAAM,MAAK,OAAO,KAAK,EAAE;AAAA,EAC/B;AAAA,EAEQ,WAAiB;AACvB,QAAI,CAAC,KAAK,WAAY;AACtB,QAAI,CAAC,QAAQ,uBAAuB,EAAG;AACvC,SAAK,MAAM,OAAO,KAAK,UAAU;AACjC,SAAK,aAAa;AAClB,SAAK,OAAO,YAAY;AAAA,EAC1B;AAAA,EAEQ,MACN,OACA,SACA,QAAQ,IACW;AACnB,UAAM,IAAI,GAAG,UAAU,CAAC,GAAGH,UAAS;AACpC,MAAE,cAAc;AAChB,MAAE,QAAQ;AACV,MAAE,UAAU;AACZ,WAAO;AAAA,EACT;AACF;AAIA,SAAS,GACP,KACA,QAAgC,CAAC,GACjC,QAAQ,IACkB;AAC1B,QAAM,IAAI,SAAS,cAAc,GAAG;AACpC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK;AACvC,IAAC,EAAwC,CAAC,IAAI;AAChD,MAAI,MAAO,GAAE,MAAM,UAAU;AAC7B,SAAO;AACT;AAEA,SAAS,QACP,QACA,OACA,YACM;AACN,QAAM,MAAM;AAAA,IACV;AAAA,IACA,CAAC;AAAA,IACD;AAAA,EACF;AACA,QAAM,MAAM;AAAA,IACV;AAAA,IACA,CAAC;AAAA,IACD;AAAA,EACF;AACA,MAAI,cAAc;AAClB,MAAI,YAAY,GAAG;AACnB,QAAM,OAAO,GAAG,OAAO,CAAC,GAAG,SAAS;AACpC,OAAK,YAAY,WAAW,CAAC;AAC7B,MAAI,YAAY,IAAI;AACpB,SAAO,YAAY,GAAG;AACxB;AAEA,SAAS,WACP,QACA,OACA,OACA,KACA,KACA,MACA,UACM;AACN,UAAQ,QAAQ,OAAO,MAAM;AAC3B,UAAM,OAAO,GAAG,OAAO,CAAC,GAAG,0CAA0C;AACrE,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,KAAK,OAAO,GAAG;AAAA,QACf,KAAK,OAAO,GAAG;AAAA,QACf,MAAM,OAAO,IAAI;AAAA,QACjB,OAAO,OAAO,KAAK;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AACA,UAAM,MAAM;AAAA,MACV;AAAA,MACA,CAAC;AAAA,MACD;AAAA,IACF;AACA,QAAI,cAAc,MAAM,SAAS;AACjC,WAAO,UAAU,MAAM;AACrB,UAAI,cAAc,OAAO;AACzB,eAAS,WAAW,OAAO,KAAK,CAAC;AAAA,IACnC;AACA,SAAK,YAAY,MAAM;AACvB,SAAK,YAAY,GAAG;AACpB,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,SACP,QACA,OACA,OACA,UACM;AACN,UAAQ,QAAQ,OAAO,MAAM;AAC3B,UAAM,KAAK,GAAG,SAAS,EAAE,MAAM,WAAW,GAAG,EAAE;AAC/C,OAAG,UAAU;AACb,OAAG,WAAW,MAAM,SAAS,GAAG,OAAO;AACvC,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,SAAS,GAAW,GAAW,GAAmB;AACzD,QAAM,OAAO,CAAC,MACZ,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,EACzC,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AACpB,SAAO,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;AACxC;AAEA,SAAS,SAAS,KAAuC;AACvD,QAAM,IAAI,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE;AACnC,SAAO,EAAG,KAAK,KAAM,OAAO,MAAO,KAAK,IAAK,OAAO,MAAM,IAAI,OAAO,GAAG;AAC1E;AAEA,SAAS,YAAY,MAA4B;AAC/C,QAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,KAAK;AAC1B,SAAO;AAAA,IACL,mBAAmB,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC;AAAA,IACzF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,GAAG;AACZ;AAIA,IAAM,kBACJ;AAIF,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,iBACJ;AAEF,IAAMD,iBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAMC,aAAY;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAMC,cAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,mBACJ;AAEF,IAAMC,cAAa,CAAC,UAAU,mBAAmB,wBAAwB,EAAE;AAAA,EACzE;AACF;AAEA,IAAMC,eAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;;;ACntBH,IAAM,SAAN,MAAM,QAAO;AAAA,EACV;AAAA,EAEA,cAAc;AAAA,EAAC;AAAA,EAEvB,OAAO,MAAM,eAAiC;AAC5C,UAAM,MAAM,IAAI,QAAO;AACvB,QAAI,MAAM,aAAa;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,UAAgB;AACd,SAAK,MAAM,OAAO;AAAA,EACpB;AAAA,EAEQ,MAAM,eAA+B;AAC3C,SAAK,OAAO,SAAS,cAAc,KAAK;AACxC,SAAK,KAAK,KAAK;AACf,SAAK,KAAK,MAAM,UAAU;AAG1B,UAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,UAAM,cAAc;AACpB,UAAM,MAAM,UACV;AACF,SAAK,KAAK,YAAY,KAAK;AAG3B,SAAK,KAAK,YAAY,KAAK,YAAY,uBAAgB,aAAa,CAAC;AAErE,aAAS,KAAK,QAAQ,KAAK,IAAI;AAG/B,aAAS,KAAK,MAAM,aAAa,GAAG,KAAK,KAAK,gBAAgB,EAAE;AAAA,EAClE;AAAA;AAAA,EAGA,gBAAgB,SAAyB;AACvC,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,QAAI,cAAc;AAClB,QAAI,MAAM,UAAUC;AACpB,QAAI,UAAU,MAAM;AAClB,cAAQ,KAAK;AACb,cAAQ,YAAY,QAAQ;AAC5B,UAAI,MAAM,UAAU,QAAQ,YAAY,mBAAmBA;AAAA,IAC7D;AACA,SAAK,KAAK,YAAY,GAAG;AAAA,EAC3B;AAAA;AAAA,EAGA,eAAe,SAAyB;AACtC,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,QAAI,cAAc;AAClB,QAAI,MAAM,UAAUA;AACpB,QAAI,UAAU,MAAM;AAClB,cAAQ,KAAK;AACb,cAAQ,YAAY,OAAO;AAC3B,UAAI,MAAM,UAAU,QAAQ,YAAY,mBAAmBA;AAAA,IAC7D;AACA,SAAK,KAAK,YAAY,GAAG;AAAA,EAC3B;AAAA,EAEQ,YAAY,OAAe,OAAoC;AACrE,WAAO,KAAK,iBAAiB,OAAO,KAAK;AAAA,EAC3C;AAAA,EAEQ,iBACN,OACA,OACmB;AACnB,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,QAAI,cAAc;AAClB,QAAI,MAAM,UAAUA;AACpB,QAAI,UAAU,MAAM;AAClB,YAAM,OAAO;AACb,UAAI,MAAM,UAAU,MAAM,YAAY,mBAAmBA;AAAA,IAC3D;AACA,WAAO;AAAA,EACT;AACF;AAIA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAMA,aAAY;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;;;ACnGH,IAAM,gBAAN,MAAM,eAAc;AAAA,EAKjB,YACW,UACA,OACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EANX,SAA6B;AAAA,EAC7B,cAAuC;AAAA,EACvC,aAAoD;AAAA;AAAA,EAS5D,OAAO,OAAO,UAAqB,OAA8B;AAC/D,WAAO,IAAI,eAAc,UAAU,KAAK;AAAA,EAC1C;AAAA;AAAA,EAIA,QAAmB;AACjB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,cAAc,CAAC,MAAM,KAAK,aAAa,CAAC;AAAA,MACxC,YAAY,MAAM,KAAK,MAAM;AAAA,MAC7B,cAAc,MAAM,KAAK,KAAK;AAAA,MAC9B,SAAS,MAAM,KAAK,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAIQ,QAAc;AACpB,SAAK,SAAS,QAAQ;AACtB,QAAI,KAAK,YAAa,MAAK,YAAY,UAAU;AACjD,SAAK,QAAQ;AACb,QAAI,KAAK,eAAe,MAAM;AAC5B,WAAK,aAAa,YAAY,MAAM,KAAK,QAAQ,GAAG,GAAG;AAAA,IACzD;AAAA,EACF;AAAA,EAEQ,OAAa;AACnB,SAAK,SAAS,QAAQ;AACtB,QAAI,KAAK,YAAa,MAAK,YAAY,UAAU;AACjD,QAAI,KAAK,eAAe,MAAM;AAC5B,oBAAc,KAAK,UAAU;AAC7B,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAIQ,aAAa,WAA8B;AAEjD,UAAM,WAAWC,IAAG,OAAO,cAAc;AACzC,UAAM,YAAY,SAAS,cAAc,OAAO;AAChD,cAAU,MAAM,UACd;AACF,SAAK,cAAc,SAAS,cAAc,OAAO;AACjD,SAAK,YAAY,OAAO;AACxB,SAAK,YAAY,UAAU,KAAK,SAAS;AACzC,SAAK,YAAY,WAAW,MAAM;AAChC,WAAK,SAAS,QAAQ,KAAK,YAAa;AAAA,IAC1C;AACA,cAAU,YAAY,KAAK,WAAW;AACtC,UAAM,YAAY,SAAS,cAAc,MAAM;AAC/C,cAAU,cAAc;AACxB,cAAU,YAAY,SAAS;AAC/B,aAAS,YAAY,SAAS;AAG9B,SAAK,SAASA,IAAG,OAAOC,WAAU;AAElC,cAAU,YAAY,QAAQ;AAC9B,cAAU,YAAY,KAAK,MAAM;AAAA,EACnC;AAAA;AAAA,EAIQ,UAAgB;AACtB,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,UAAU,KAAK,MAAM,WAAW;AACtC,SAAK,OAAO,YAAY;AAExB,UAAM,UAAUD;AAAA,MACd;AAAA,MACA;AAAA,IACF;AACA,YAAQ,cAAc,YAAY,QAAQ,MAAM;AAChD,SAAK,OAAO,YAAY,OAAO;AAE/B,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,YAAM,OAAOA,IAAG,OAAOE,WAAU;AAEjC,YAAM,SAASF;AAAA,QACb;AAAA,QACA;AAAA,MACF;AACA,aAAO,cAAc;AACrB,WAAK,YAAY,MAAM;AAEvB,YAAM,IAAI,MAAM;AAChB,YAAM,IAAI,MAAM;AAChB,YAAM,IAAI,MAAM;AAChB,YAAM,KAAK,MAAM;AACjB,YAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;AAC9B,YAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;AAC9B,YAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;AAE9B,WAAK,YAAYG,SAAQ,OAAO,GAAGC,GAAE,EAAE,CAAC,CAAC,CAAC,KAAKA,GAAE,EAAE,CAAC,CAAC,CAAC,KAAKA,GAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrE,WAAK,YAAYD,SAAQ,OAAO,GAAGC,GAAE,EAAE,CAAC,CAAC,CAAC,KAAKA,GAAE,EAAE,CAAC,CAAC,CAAC,KAAKA,GAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrE,WAAK,YAAYD,SAAQ,OAAO,GAAGC,GAAE,EAAE,CAAC,CAAC,CAAC,KAAKA,GAAE,EAAE,CAAC,CAAC,CAAC,KAAKA,GAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrE,WAAK,YAAYD,SAAQ,QAAQ,GAAGC,GAAE,CAAC,CAAC,MAAMA,GAAE,CAAC,CAAC,MAAMA,GAAE,CAAC,CAAC,GAAG,CAAC;AAEhE,WAAK,OAAO,YAAY,IAAI;AAAA,IAC9B;AAAA,EACF;AACF;AAIA,SAASJ,IACP,KACA,QAAQ,IAC0C;AAClD,QAAMK,MAAK,SAAS,cAAc,GAAG;AAGrC,MAAI,MAAO,CAAAA,IAAG,MAAM,UAAU;AAC9B,SAAOA;AACT;AAEA,SAASD,GAAE,GAAmB;AAC5B,SAAO,EAAE,QAAQ,CAAC;AACpB;AAEA,SAASD,SAAQ,OAAe,OAA4B;AAC1D,QAAM,MAAM,SAAS,cAAc,KAAK;AACxC,MAAI,MAAM,UAAU;AAEpB,QAAM,MAAM,SAAS,cAAc,MAAM;AACzC,MAAI,MAAM,UAAU;AACpB,MAAI,cAAc;AAElB,QAAM,MAAM,SAAS,cAAc,MAAM;AACzC,MAAI,MAAM,UAAU;AACpB,MAAI,cAAc;AAElB,MAAI,YAAY,GAAG;AACnB,MAAI,YAAY,GAAG;AACnB,SAAO;AACT;AAIA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAMF,cAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,IAAMC,cAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;","names":["STORAGE_KEY","el","TOOLBAR_STYLE","BTN_STYLE","LIST_STYLE","FORM_STYLE","INPUT_STYLE","BTN_STYLE","mk","LIST_STYLE","CARD_STYLE","dataRow","f","el"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import '../../Camera-DY_8gx3C.js';
|
|
2
|
+
import '../../KeyboardControl-5w7Vm0J0.js';
|
|
3
|
+
export { K as KeyboardInput } from '../../KeyboardInput-DTsfj3tE.js';
|
|
4
|
+
import 'gl-matrix';
|
|
5
|
+
import '../../Core/domain/interfaces/Vectors.js';
|
|
6
|
+
import '../../Model-CQvDXd-b.js';
|
|
7
|
+
import '../../WebGLCore-DR7ZHJB0.js';
|
|
8
|
+
import '../../Material-BGLkldxv.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export { A as AnimationController, a as AnimationState, b as AnimationTransition, C as Character, K as KeyboardInput, T as TransitionCondition } from '../KeyboardInput-DTsfj3tE.js';
|
|
2
|
+
import { g as Mesh } from '../Model-CQvDXd-b.js';
|
|
3
|
+
import { b as Material } from '../Material-BGLkldxv.js';
|
|
4
|
+
import '../Camera-DY_8gx3C.js';
|
|
5
|
+
import 'gl-matrix';
|
|
6
|
+
import '../Core/domain/interfaces/Vectors.js';
|
|
7
|
+
import '../KeyboardControl-5w7Vm0J0.js';
|
|
8
|
+
import '../WebGLCore-DR7ZHJB0.js';
|
|
9
|
+
|
|
10
|
+
declare class Arm extends Mesh {
|
|
11
|
+
private swingPhase;
|
|
12
|
+
private swingSpeed;
|
|
13
|
+
private swingAmount;
|
|
14
|
+
private side;
|
|
15
|
+
constructor(vertices: Float32Array, normals: Float32Array, material: Material, side?: 1 | -1);
|
|
16
|
+
/**
|
|
17
|
+
* Updates the animation state for this arm.
|
|
18
|
+
* Returns the desired rotation (in radians) to be applied externally.
|
|
19
|
+
*/
|
|
20
|
+
animate(moving: boolean, deltaTime: number, invert?: number): number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare class Head extends Mesh {
|
|
24
|
+
constructor(vertices: Float32Array, normals: Float32Array, material: Material);
|
|
25
|
+
/**
|
|
26
|
+
* Create a Head mesh from an existing Mesh.
|
|
27
|
+
* Optionally override translation and scale.
|
|
28
|
+
*/
|
|
29
|
+
static fromMesh(mesh: Mesh): Head;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class Leg extends Mesh {
|
|
33
|
+
private swingAngle;
|
|
34
|
+
private swingSpeed;
|
|
35
|
+
private swingAmount;
|
|
36
|
+
private side;
|
|
37
|
+
constructor(vertices: Float32Array, normals: Float32Array, material: Material, side: 1 | -1);
|
|
38
|
+
/**
|
|
39
|
+
* Updates the swing animation state for this leg.
|
|
40
|
+
* The actual rotation transform should be applied by a parent model/skeleton.
|
|
41
|
+
*/
|
|
42
|
+
animate(moving: boolean, deltaTime: number): number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { Arm, Head, Leg };
|