@zylem/game-lib 0.6.2 → 0.6.3

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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -16
  3. package/dist/actions.d.ts +30 -21
  4. package/dist/actions.js +628 -145
  5. package/dist/actions.js.map +1 -1
  6. package/dist/behavior/platformer-3d.d.ts +296 -0
  7. package/dist/behavior/platformer-3d.js +518 -0
  8. package/dist/behavior/platformer-3d.js.map +1 -0
  9. package/dist/behavior/ricochet-2d.d.ts +274 -0
  10. package/dist/behavior/ricochet-2d.js +394 -0
  11. package/dist/behavior/ricochet-2d.js.map +1 -0
  12. package/dist/behavior/screen-wrap.d.ts +86 -0
  13. package/dist/behavior/screen-wrap.js +195 -0
  14. package/dist/behavior/screen-wrap.js.map +1 -0
  15. package/dist/behavior/thruster.d.ts +10 -0
  16. package/dist/behavior/thruster.js +234 -0
  17. package/dist/behavior/thruster.js.map +1 -0
  18. package/dist/behavior/world-boundary-2d.d.ts +141 -0
  19. package/dist/behavior/world-boundary-2d.js +181 -0
  20. package/dist/behavior/world-boundary-2d.js.map +1 -0
  21. package/dist/behavior-descriptor-BWNWmIjv.d.ts +142 -0
  22. package/dist/{blueprints-Cq3Ko6_G.d.ts → blueprints-BWGz8fII.d.ts} +2 -2
  23. package/dist/camera-B5e4c78l.d.ts +468 -0
  24. package/dist/camera.d.ts +3 -2
  25. package/dist/camera.js +900 -211
  26. package/dist/camera.js.map +1 -1
  27. package/dist/composition-DrzFrbqI.d.ts +218 -0
  28. package/dist/{core-bO8TzV7u.d.ts → core-DAkskq6Y.d.ts} +60 -62
  29. package/dist/core.d.ts +10 -6
  30. package/dist/core.js +6896 -5020
  31. package/dist/core.js.map +1 -1
  32. package/dist/{entities-DvByhMGU.d.ts → entities-DC9ce_vx.d.ts} +113 -3
  33. package/dist/entities.d.ts +5 -3
  34. package/dist/entities.js +3727 -3167
  35. package/dist/entities.js.map +1 -1
  36. package/dist/entity-BpbZqg19.d.ts +1100 -0
  37. package/dist/global-change-Dc8uCKi2.d.ts +25 -0
  38. package/dist/main.d.ts +418 -15
  39. package/dist/main.js +11384 -8515
  40. package/dist/main.js.map +1 -1
  41. package/dist/{stage-types-Bd-KtcYT.d.ts → stage-types-BFsm3qsZ.d.ts} +205 -13
  42. package/dist/stage.d.ts +10 -7
  43. package/dist/stage.js +5311 -3880
  44. package/dist/stage.js.map +1 -1
  45. package/dist/thruster-DhRaJnoL.d.ts +172 -0
  46. package/dist/world-Be5m1XC1.d.ts +31 -0
  47. package/package.json +29 -13
  48. package/dist/behaviors.d.ts +0 -854
  49. package/dist/behaviors.js +0 -1209
  50. package/dist/behaviors.js.map +0 -1
  51. package/dist/camera-CeJPAgGg.d.ts +0 -116
  52. package/dist/moveable-B_vyA6cw.d.ts +0 -67
  53. package/dist/transformable-CUhvyuYO.d.ts +0 -67
  54. package/dist/world-C8tQ7Plj.d.ts +0 -774
package/dist/stage.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/game/game-event-bus.ts","../src/lib/game/game-state.ts","../src/lib/systems/transformable.system.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/src/index.ts","../src/lib/events/event-emitter-delegate.ts","../src/lib/events/zylem-events.ts","../src/lib/events/index.ts","../src/lib/entities/entity.ts","../src/lib/core/loaders/texture-loader.ts","../src/lib/core/loaders/gltf-loader.ts","../src/lib/core/loaders/fbx-loader.ts","../src/lib/core/loaders/obj-loader.ts","../src/lib/core/loaders/audio-loader.ts","../src/lib/core/loaders/file-loader.ts","../src/lib/core/loaders/index.ts","../src/lib/core/asset-manager.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/entities/common.ts","../src/lib/debug/debug-state.ts","../src/lib/stage/entity-spawner.ts","../src/lib/camera/perspective.ts","../src/lib/camera/third-person.ts","../src/lib/camera/fixed-2d.ts","../src/lib/graphics/render-pass.ts","../src/lib/camera/camera-debug-delegate.ts","../src/lib/camera/zylem-camera.ts","../src/lib/camera/camera.ts","../src/lib/behaviors/thruster/index.ts","../src/lib/behaviors/screen-wrap/index.ts","../src/lib/behaviors/world-boundary-2d/index.ts","../src/lib/behaviors/ricochet-2d/index.ts","../src/lib/behaviors/movement-sequence-2d/index.ts","../src/lib/coordinators/boundary-ricochet.coordinator.ts","../src/lib/behaviors/index.ts","../src/lib/core/utility/vector.ts","../src/lib/stage/stage-state.ts","../src/api/main.ts","../src/lib/entities/actor.ts","../src/lib/collision/world.ts","../src/lib/graphics/zylem-scene.ts","../src/lib/core/lifecycle-base.ts","../src/lib/stage/debug-entity-cursor.ts","../src/lib/stage/stage-debug-delegate.ts","../src/lib/stage/stage-camera-debug-delegate.ts","../src/lib/stage/stage-camera-delegate.ts","../src/lib/stage/stage-loading-delegate.ts","../src/lib/stage/stage-entity-model-delegate.ts","../src/lib/core/utility/options-parser.ts","../src/lib/stage/stage-config.ts","../src/lib/stage/zylem-stage.ts","../src/lib/stage/stage-default.ts","../src/lib/stage/stage.ts","../src/api/stage.ts","../src/lib/stage/stage-events.ts"],"sourcesContent":["import { LoadingEvent } from '../core/interfaces';\n\n/**\n * Event types for the game event bus.\n */\nexport type GameEventType = \n\t| 'stage:loading:start'\n\t| 'stage:loading:progress'\n\t| 'stage:loading:complete'\n\t| 'game:state:updated';\n\n/**\n * Payload for stage loading events.\n */\nexport interface StageLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n/**\n * Payload for game state update events.\n */\nexport interface GameStateUpdatedPayload {\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n}\n\n/**\n * Event map for typed event handling.\n */\nexport interface GameEventMap {\n\t'stage:loading:start': StageLoadingPayload;\n\t'stage:loading:progress': StageLoadingPayload;\n\t'stage:loading:complete': StageLoadingPayload;\n\t'game:state:updated': GameStateUpdatedPayload;\n}\n\ntype EventCallback<T> = (payload: T) => void;\n\n/**\n * Simple event bus for game-stage communication.\n * Used to decouple stage loading events from direct coupling.\n */\nexport class GameEventBus {\n\tprivate listeners: Map<GameEventType, Set<EventCallback<any>>> = new Map();\n\n\t/**\n\t * Subscribe to an event type.\n\t */\n\ton<K extends GameEventType>(event: K, callback: EventCallback<GameEventMap[K]>): () => void {\n\t\tif (!this.listeners.has(event)) {\n\t\t\tthis.listeners.set(event, new Set());\n\t\t}\n\t\tthis.listeners.get(event)!.add(callback);\n\t\treturn () => this.off(event, callback);\n\t}\n\n\t/**\n\t * Unsubscribe from an event type.\n\t */\n\toff<K extends GameEventType>(event: K, callback: EventCallback<GameEventMap[K]>): void {\n\t\tthis.listeners.get(event)?.delete(callback);\n\t}\n\n\t/**\n\t * Emit an event to all subscribers.\n\t */\n\temit<K extends GameEventType>(event: K, payload: GameEventMap[K]): void {\n\t\tconst callbacks = this.listeners.get(event);\n\t\tif (!callbacks) return;\n\t\tfor (const cb of callbacks) {\n\t\t\ttry {\n\t\t\t\tcb(payload);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(`Error in event handler for ${event}`, e);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clear all listeners.\n\t */\n\tdispose(): void {\n\t\tthis.listeners.clear();\n\t}\n}\n\n/**\n * Singleton event bus instance for global game events.\n */\nexport const gameEventBus = new GameEventBus();\n","import { proxy, subscribe } from 'valtio/vanilla';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\nimport { gameEventBus } from './game-event-bus';\n\n/**\n * Internal game state store using valtio proxy for reactivity.\n */\nconst state = proxy({\n\tid: '',\n\tglobals: {} as Record<string, unknown>,\n\ttime: 0,\n});\n\n/**\n * Track active subscriptions for cleanup on game dispose.\n */\nconst activeSubscriptions: Set<() => void> = new Set();\n\n/**\n * Set a global value by path.\n * Emits a 'game:state:updated' event when the value changes.\n * @example setGlobal('score', 100)\n * @example setGlobal('player.health', 50)\n */\nexport function setGlobal(path: string, value: unknown): void {\n\tconst previousValue = getByPath(state.globals, path);\n\tsetByPath(state.globals, path, value);\n\n\tgameEventBus.emit('game:state:updated', {\n\t\tpath,\n\t\tvalue,\n\t\tpreviousValue,\n\t});\n}\n\n/**\n * Create/initialize a global with a default value.\n * Only sets the value if it doesn't already exist.\n * Use this to ensure globals have initial values before game starts.\n * @example createGlobal('score', 0)\n * @example createGlobal('player.health', 100)\n */\nexport function createGlobal<T>(path: string, defaultValue: T): T {\n\tconst existing = getByPath<T>(state.globals, path);\n\tif (existing === undefined) {\n\t\tsetByPath(state.globals, path, defaultValue);\n\t\treturn defaultValue;\n\t}\n\treturn existing;\n}\n\n/**\n * Get a global value by path.\n * @example getGlobal('score') // 100\n * @example getGlobal<number>('player.health') // 50\n */\nexport function getGlobal<T = unknown>(path: string): T | undefined {\n\treturn getByPath<T>(state.globals, path);\n}\n\n/**\n * Subscribe to changes on a global value at a specific path.\n * Returns an unsubscribe function. Subscriptions are automatically\n * cleaned up when the game is disposed.\n * @example const unsub = onGlobalChange('score', (val) => console.log(val));\n */\nexport function onGlobalChange<T = unknown>(\n\tpath: string,\n\tcallback: (value: T) => void\n): () => void {\n\tlet previous = getByPath<T>(state.globals, path);\n\tconst unsub = subscribe(state.globals, () => {\n\t\tconst current = getByPath<T>(state.globals, path);\n\t\tif (current !== previous) {\n\t\t\tprevious = current;\n\t\t\tcallback(current as T);\n\t\t}\n\t});\n\tactiveSubscriptions.add(unsub);\n\treturn () => {\n\t\tunsub();\n\t\tactiveSubscriptions.delete(unsub);\n\t};\n}\n\n/**\n * Subscribe to changes on multiple global paths.\n * Callback fires when any of the paths change, receiving all current values.\n * Subscriptions are automatically cleaned up when the game is disposed.\n * @example const unsub = onGlobalChanges(['score', 'lives'], ([score, lives]) => console.log(score, lives));\n */\nexport function onGlobalChanges<T extends unknown[] = unknown[]>(\n\tpaths: string[],\n\tcallback: (values: T) => void\n): () => void {\n\tlet previousValues = paths.map(p => getByPath(state.globals, p));\n\tconst unsub = subscribe(state.globals, () => {\n\t\tconst currentValues = paths.map(p => getByPath(state.globals, p));\n\t\tconst hasChange = currentValues.some((val, i) => val !== previousValues[i]);\n\t\tif (hasChange) {\n\t\t\tpreviousValues = currentValues;\n\t\t\tcallback(currentValues as T);\n\t\t}\n\t});\n\tactiveSubscriptions.add(unsub);\n\treturn () => {\n\t\tunsub();\n\t\tactiveSubscriptions.delete(unsub);\n\t};\n}\n\n/**\n * Get the entire globals object (read-only snapshot).\n */\nexport function getGlobals<T = Record<string, unknown>>(): T {\n\treturn state.globals as T;\n}\n\n/**\n * Initialize globals from an object. Used internally during game setup.\n */\nexport function initGlobals(globals: Record<string, unknown>): void {\n\tfor (const [key, value] of Object.entries(globals)) {\n\t\tsetByPath(state.globals, key, value);\n\t}\n}\n\n/**\n * Reset all globals. Used internally on game dispose.\n */\nexport function resetGlobals(): void {\n\tstate.globals = {};\n}\n\n/**\n * Unsubscribe all active global subscriptions.\n * Used internally on game dispose to prevent old callbacks from firing.\n */\nexport function clearGlobalSubscriptions(): void {\n\tfor (const unsub of activeSubscriptions) {\n\t\tunsub();\n\t}\n\tactiveSubscriptions.clear();\n}\n\nexport { state };","import {\n\tdefineSystem,\n\tdefineQuery,\n\tdefineComponent,\n\tTypes,\n\tremoveQuery,\n\ttype IWorld,\n} from 'bitecs';\nimport { Quaternion } from 'three';\nimport { StageEntity } from '../interfaces/entity';\nimport RAPIER from '@dimforge/rapier3d-compat';\n\nexport type StageSystem = {\n\t_childrenMap: Map<number, StageEntity & { body: RAPIER.RigidBody }>;\n}\n\nexport const position = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32\n});\n\nexport const rotation = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32,\n\tw: Types.f32\n});\n\nexport const scale = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32\n});\n\n// Reusable quaternion to avoid allocations per frame\nconst _tempQuaternion = new Quaternion();\n\nexport type TransformSystemResult = {\n\tsystem: ReturnType<typeof defineSystem>;\n\tdestroy: (world: IWorld) => void;\n};\n\nexport default function createTransformSystem(stage: StageSystem): TransformSystemResult {\n\tconst queryTerms = [position, rotation];\n\tconst transformQuery = defineQuery(queryTerms);\n\tconst stageEntities = stage._childrenMap;\n\n\tconst system = defineSystem((world) => {\n\t\tconst entities = transformQuery(world);\n\t\tif (stageEntities === undefined) {\n\t\t\treturn world;\n\t\t}\n\n\t\tfor (const [key, stageEntity] of stageEntities) {\n\t\t\t// Early bailout - combine conditions\n\t\t\tif (!stageEntity?.body || stageEntity.markedForRemoval) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst id = entities[key];\n\t\t\tconst body = stageEntity.body;\n\t\t\tconst target = stageEntity.group ?? stageEntity.mesh;\n\n\t\t\t// Position sync\n\t\t\tconst translation = body.translation();\n\t\t\tposition.x[id] = translation.x;\n\t\t\tposition.y[id] = translation.y;\n\t\t\tposition.z[id] = translation.z;\n\n\t\t\tif (target) {\n\t\t\t\ttarget.position.set(translation.x, translation.y, translation.z);\n\t\t\t}\n\n\t\t\t// Skip rotation if controlled externally\n\t\t\tif (stageEntity.controlledRotation) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Rotation sync - reuse quaternion\n\t\t\tconst rot = body.rotation();\n\t\t\trotation.x[id] = rot.x;\n\t\t\trotation.y[id] = rot.y;\n\t\t\trotation.z[id] = rot.z;\n\t\t\trotation.w[id] = rot.w;\n\n\t\t\tif (target) {\n\t\t\t\t_tempQuaternion.set(rot.x, rot.y, rot.z, rot.w);\n\t\t\t\ttarget.setRotationFromQuaternion(_tempQuaternion);\n\t\t\t}\n\t\t}\n\n\t\treturn world;\n\t});\n\n\tconst destroy = (world: IWorld) => {\n\t\t// Remove the query from bitecs world tracking\n\t\tremoveQuery(world, transformQuery);\n\t};\n\n\treturn { system, destroy };\n}","/** Vite build flags */\nexport const DEBUG_FLAG = import.meta.env.VITE_DEBUG_FLAG === 'true';","import {\n\tCleanupContext,\n\tCleanupFunction,\n\tDestroyContext,\n\tDestroyFunction,\n\tLoadedContext,\n\tLoadedFunction,\n\tSetupContext,\n\tSetupFunction,\n\tUpdateContext,\n\tUpdateFunction,\n} from \"./base-node-life-cycle\";\nimport { DEBUG_FLAG } from \"./flags\";\nimport { nanoid } from \"nanoid\";\nimport { NodeInterface } from \"./node-interface\";\n\nexport type BaseNodeOptions<T = any> = BaseNode | Partial<T>;\n\n/**\n * Lifecycle callback arrays - each lifecycle event can have multiple callbacks\n * that execute in order.\n */\nexport interface LifecycleCallbacks<T> {\n\tsetup: Array<SetupFunction<T>>;\n\tloaded: Array<LoadedFunction<T>>;\n\tupdate: Array<UpdateFunction<T>>;\n\tdestroy: Array<DestroyFunction<T>>;\n\tcleanup: Array<CleanupFunction<T>>;\n}\n\nexport abstract class BaseNode<Options = any, T = any> implements NodeInterface {\n\tprotected parent: NodeInterface | null = null;\n\tprotected children: NodeInterface[] = [];\n\tpublic options: Options;\n\tpublic eid: number = 0;\n\tpublic uuid: string = '';\n\tpublic name: string = '';\n\tpublic markedForRemoval: boolean = false;\n\n\t/**\n\t * Lifecycle callback arrays - use onSetup(), onUpdate(), etc. to add callbacks\n\t */\n\tprotected lifecycleCallbacks: LifecycleCallbacks<this> = {\n\t\tsetup: [],\n\t\tloaded: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcleanup: [],\n\t};\n\n\tconstructor(args: BaseNodeOptions[] = []) {\n\t\tconst options = args\n\t\t\t.filter(arg => !(arg instanceof BaseNode))\n\t\t\t.reduce((acc, opt) => ({ ...acc, ...opt }), {});\n\t\tthis.options = options as Options;\n\t\tthis.uuid = nanoid();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Fluent API for adding lifecycle callbacks\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add setup callbacks to be executed in order during nodeSetup\n\t */\n\tpublic onSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add loaded callbacks to be executed in order during nodeLoaded\n\t */\n\tpublic onLoaded(...callbacks: Array<LoadedFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.loaded.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add update callbacks to be executed in order during nodeUpdate\n\t */\n\tpublic onUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add destroy callbacks to be executed in order during nodeDestroy\n\t */\n\tpublic onDestroy(...callbacks: Array<DestroyFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.destroy.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add cleanup callbacks to be executed in order during nodeCleanup\n\t */\n\tpublic onCleanup(...callbacks: Array<CleanupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.cleanup.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend setup callbacks (run before existing ones)\n\t */\n\tpublic prependSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.unshift(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend update callbacks (run before existing ones)\n\t */\n\tpublic prependUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.unshift(...callbacks);\n\t\treturn this;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Tree structure\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic setParent(parent: NodeInterface | null): void {\n\t\tthis.parent = parent;\n\t}\n\n\tpublic getParent(): NodeInterface | null {\n\t\treturn this.parent;\n\t}\n\n\tpublic add(baseNode: NodeInterface): void {\n\t\tthis.children.push(baseNode);\n\t\tbaseNode.setParent(this);\n\t}\n\n\tpublic remove(baseNode: NodeInterface): void {\n\t\tconst index = this.children.indexOf(baseNode);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tbaseNode.setParent(null);\n\t\t}\n\t}\n\n\tpublic getChildren(): NodeInterface[] {\n\t\treturn this.children;\n\t}\n\n\tpublic isComposite(): boolean {\n\t\treturn this.children.length > 0;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Abstract methods for subclass implementation\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic abstract create(): T;\n\n\tprotected abstract _setup(params: SetupContext<this>): void;\n\n\tprotected abstract _loaded(params: LoadedContext<this>): Promise<void>;\n\n\tprotected abstract _update(params: UpdateContext<this>): void;\n\n\tprotected abstract _destroy(params: DestroyContext<this>): void;\n\n\tprotected abstract _cleanup(params: CleanupContext<this>): Promise<void>;\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Node lifecycle execution - runs internal + callback arrays\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic nodeSetup(params: SetupContext<this>) {\n\t\tif (DEBUG_FLAG) { /** */ }\n\t\tthis.markedForRemoval = false;\n\n\t\t// 1. Internal setup\n\t\tif (typeof this._setup === 'function') {\n\t\t\tthis._setup(params);\n\t\t}\n\n\t\t// 2. Run all setup callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.setup) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 3. Setup children\n\t\tthis.children.forEach(child => child.nodeSetup(params));\n\t}\n\n\tpublic nodeUpdate(params: UpdateContext<this>): void {\n\t\tif (this.markedForRemoval) {\n\t\t\treturn;\n\t\t}\n\n\t\t// 1. Internal update\n\t\tif (typeof this._update === 'function') {\n\t\t\tthis._update(params);\n\t\t}\n\n\t\t// 2. Run all update callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.update) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 3. Update children\n\t\tthis.children.forEach(child => child.nodeUpdate(params));\n\t}\n\n\tpublic nodeDestroy(params: DestroyContext<this>): void {\n\t\t// 1. Destroy children first\n\t\tthis.children.forEach(child => child.nodeDestroy(params));\n\n\t\t// 2. Run all destroy callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.destroy) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 3. Internal destroy\n\t\tif (typeof this._destroy === 'function') {\n\t\t\tthis._destroy(params);\n\t\t}\n\n\t\tthis.markedForRemoval = true;\n\t}\n\n\tpublic async nodeLoaded(params: LoadedContext<this>): Promise<void> {\n\t\t// 1. Internal loaded\n\t\tif (typeof this._loaded === 'function') {\n\t\t\tawait this._loaded(params);\n\t\t}\n\n\t\t// 2. Run all loaded callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.loaded) {\n\t\t\tcallback(params);\n\t\t}\n\t}\n\n\tpublic async nodeCleanup(params: CleanupContext<this>): Promise<void> {\n\t\t// 1. Run all cleanup callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 2. Internal cleanup\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tawait this._cleanup(params);\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Options\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic getOptions(): Options {\n\t\treturn this.options;\n\t}\n\n\tpublic setOptions(options: Partial<Options>): void {\n\t\tthis.options = { ...this.options, ...options };\n\t}\n}","export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n\tWildcardHandler<T>\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n\tall: EventHandlerMap<Events>;\n\n\ton<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n\ton(type: '*', handler: WildcardHandler<Events>): void;\n\n\toff<Key extends keyof Events>(\n\t\ttype: Key,\n\t\thandler?: Handler<Events[Key]>\n\t): void;\n\toff(type: '*', handler: WildcardHandler<Events>): void;\n\n\temit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n\temit<Key extends keyof Events>(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt<Events extends Record<EventType, unknown>>(\n\tall?: EventHandlerMap<Events>\n): Emitter<Events> {\n\ttype GenericEventHandler =\n\t\t| Handler<Events[keyof Events]>\n\t\t| WildcardHandler<Events>;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList<Events[keyof Events]>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList<Events>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n","import mitt, { Emitter } from 'mitt';\n\n/**\n * Event scope identifier for routing events.\n */\nexport type EventScope = 'game' | 'stage' | 'entity';\n\n/**\n * Reusable delegate for event emission and subscription.\n * Use via composition in Game, Stage, and Entity classes.\n * \n * @example\n * class Game {\n * private eventDelegate = new EventEmitterDelegate<GameEvents>();\n * \n * dispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]) {\n * this.eventDelegate.dispatch(event, payload);\n * }\n * }\n */\nexport class EventEmitterDelegate<TEvents extends Record<string, unknown>> {\n\tprivate emitter: Emitter<TEvents>;\n\tprivate unsubscribes: (() => void)[] = [];\n\n\tconstructor() {\n\t\tthis.emitter = mitt<TEvents>();\n\t}\n\n\t/**\n\t * Dispatch an event to all listeners.\n\t */\n\tdispatch<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n\t\tthis.emitter.emit(event, payload);\n\t}\n\n\t/**\n\t * Subscribe to an event. Returns an unsubscribe function.\n\t */\n\tlisten<K extends keyof TEvents>(\n\t\tevent: K,\n\t\thandler: (payload: TEvents[K]) => void\n\t): () => void {\n\t\tthis.emitter.on(event, handler);\n\t\tconst unsub = () => this.emitter.off(event, handler);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Subscribe to all events.\n\t */\n\tlistenAll(handler: (type: keyof TEvents, payload: TEvents[keyof TEvents]) => void): () => void {\n\t\tthis.emitter.on('*', handler as any);\n\t\tconst unsub = () => this.emitter.off('*', handler as any);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Clean up all subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.unsubscribes.forEach(fn => fn());\n\t\tthis.unsubscribes = [];\n\t\tthis.emitter.all.clear();\n\t}\n}\n","import mitt from 'mitt';\nimport type { LoadingEvent } from '../core/interfaces';\n\n/**\n * Payload for game loading events with stage context.\n */\nexport interface GameLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Game Events\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Payload for stage configuration sent to editor. */\nexport interface StageConfigPayload {\n\tid: string;\n\tbackgroundColor: string;\n\tbackgroundImage: string | null;\n\tgravity: { x: number; y: number; z: number };\n\tinputs: Record<string, string[]>;\n\tvariables: Record<string, unknown>;\n}\n\n/** Payload for entity configuration sent to editor. */\nexport interface EntityConfigPayload {\n\tuuid: string;\n\tname: string;\n\ttype: string;\n\tposition: { x: number; y: number; z: number };\n\trotation: { x: number; y: number; z: number };\n\tscale: { x: number; y: number; z: number };\n}\n\n/** Payload for state dispatch events from game to editor. */\nexport interface StateDispatchPayload {\n\tscope: 'game' | 'stage' | 'entity';\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n\tconfig?: {\n\t\tid: string;\n\t\taspectRatio: number;\n\t\tfullscreen: boolean;\n\t\tbodyBackground: string | undefined;\n\t\tinternalResolution: { width: number; height: number } | undefined;\n\t\tdebug: boolean;\n\t} | null;\n\tstageConfig?: StageConfigPayload | null;\n\tentities?: EntityConfigPayload[] | null;\n}\n\nexport type GameEvents = {\n\t'loading:start': GameLoadingPayload;\n\t'loading:progress': GameLoadingPayload;\n\t'loading:complete': GameLoadingPayload;\n\t'paused': { paused: boolean };\n\t'debug': { enabled: boolean };\n\t'state:dispatch': StateDispatchPayload;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stage Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type StageEvents = {\n\t'stage:loaded': { stageId: string };\n\t'stage:unloaded': { stageId: string };\n\t'stage:variable:changed': { key: string; value: unknown };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type EntityEvents = {\n\t'entity:spawned': { entityId: string; name: string };\n\t'entity:destroyed': { entityId: string };\n\t'entity:collision': { entityId: string; otherId: string };\n\t'entity:model:loading': { entityId: string; files: string[] };\n\t'entity:model:loaded': { entityId: string; success: boolean; meshCount?: number };\n\t'entity:animation:loaded': { entityId: string; animationCount: number };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Combined Event Map\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ZylemEvents = GameEvents & StageEvents & EntityEvents;\n\n/**\n * Global event bus for cross-package communication.\n * \n * Usage:\n * ```ts\n * import { zylemEventBus } from '@zylem/game-lib';\n * \n * // Subscribe\n * const unsub = zylemEventBus.on('loading:progress', (e) => console.log(e));\n * \n * // Emit\n * zylemEventBus.emit('loading:progress', { type: 'progress', progress: 0.5 });\n * \n * // Cleanup\n * unsub();\n * ```\n */\nexport const zylemEventBus = mitt<ZylemEvents>();\n","export { EventEmitterDelegate, type EventScope } from './event-emitter-delegate';\nexport {\n\tzylemEventBus,\n\ttype ZylemEvents,\n\ttype GameEvents,\n\ttype StageEvents,\n\ttype EntityEvents,\n\ttype GameLoadingPayload,\n\ttype StateDispatchPayload,\n\ttype StageConfigPayload,\n\ttype EntityConfigPayload,\n} from './zylem-events';\n","import { Mesh, Material, ShaderMaterial, Group, Color } from 'three';\nimport {\n Collider,\n ColliderDesc,\n RigidBody,\n RigidBodyDesc,\n} from '@dimforge/rapier3d-compat';\nimport { position, rotation, scale } from '../systems/transformable.system';\nimport { Vec3 } from '../core/vector';\nimport { MaterialBuilder, MaterialOptions } from '../graphics/material';\nimport { CollisionOptions } from '../collision/collision-builder';\nimport { BaseNode } from '../core/base-node';\nimport {\n DestroyContext,\n SetupContext,\n UpdateContext,\n LoadedContext,\n CleanupContext,\n} from '../core/base-node-life-cycle';\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from './builder';\nimport { Behavior } from '../actions/behaviors/behavior';\nimport {\n EventEmitterDelegate,\n zylemEventBus,\n type EntityEvents,\n} from '../events';\nimport type {\n BehaviorDescriptor,\n BehaviorRef,\n BehaviorHandle,\n} from '../behaviors/behavior-descriptor';\n\nexport interface CollisionContext<\n T,\n O extends GameEntityOptions,\n TGlobals extends Record<string, unknown> = any,\n> {\n entity: T;\n // Use 'any' for other's options type to break recursive type variance issues\n other: GameEntity<O | any>;\n globals: TGlobals;\n}\n\nexport type BehaviorContext<T, O extends GameEntityOptions> =\n | SetupContext<T, O>\n | UpdateContext<T, O>\n | CollisionContext<T, O>\n | DestroyContext<T, O>;\n\nexport type BehaviorCallback<T, O extends GameEntityOptions> = (\n params: BehaviorContext<T, O>,\n) => void;\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n // Use 'any' for entity and options types to avoid contravariance issues\n // with function parameters. Type safety is still enforced at the call site via onCollision()\n collision?: ((params: CollisionContext<any, any>) => void)[];\n}\n\nexport type IBuilder<BuilderOptions = any> = {\n preBuild: (options: BuilderOptions) => BuilderOptions;\n build: (options: BuilderOptions) => BuilderOptions;\n postBuild: (options: BuilderOptions) => BuilderOptions;\n};\n\nexport type GameEntityOptions = {\n name?: string;\n color?: Color;\n size?: Vec3;\n position?: Vec3;\n batched?: boolean;\n collision?: Partial<CollisionOptions>;\n material?: Partial<MaterialOptions>;\n custom?: { [key: string]: any };\n collisionType?: string;\n collisionGroup?: string;\n collisionFilter?: string[];\n _builders?: {\n meshBuilder?: IBuilder | EntityMeshBuilder | null;\n collisionBuilder?: IBuilder | EntityCollisionBuilder | null;\n materialBuilder?: MaterialBuilder | null;\n };\n};\n\nexport abstract class GameEntityLifeCycle {\n abstract _setup(params: SetupContext<this>): void;\n abstract _update(params: UpdateContext<this>): void;\n abstract _destroy(params: DestroyContext<this>): void;\n}\n\nexport interface EntityDebugInfo {\n buildInfo: () => Record<string, string>;\n}\n\nexport type BehaviorCallbackType = 'setup' | 'update' | 'destroy' | 'collision';\n\nexport class GameEntity<O extends GameEntityOptions>\n extends BaseNode<O>\n implements GameEntityLifeCycle, EntityDebugInfo\n{\n public behaviors: Behavior[] = [];\n public group: Group | undefined;\n public mesh: Mesh | undefined;\n public materials: Material[] | undefined;\n public bodyDesc: RigidBodyDesc | null = null;\n public body: RigidBody | null = null;\n public colliderDesc: ColliderDesc | undefined;\n public collider: Collider | undefined;\n public custom: Record<string, any> = {};\n\n public debugInfo: Record<string, any> = {};\n public debugMaterial: ShaderMaterial | undefined;\n\n public collisionDelegate: CollisionDelegate<this, O> = {\n collision: [],\n };\n public collisionType?: string;\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * Use 'any' for callback types to avoid contravariance issues\n * with function parameters. Type safety is enforced where callbacks are registered.\n */\n public behaviorCallbackMap: Record<\n BehaviorCallbackType,\n BehaviorCallback<any, any>[]\n > = {\n setup: [],\n update: [],\n destroy: [],\n collision: [],\n };\n\n // Event delegate for dispatch/listen API\n protected eventDelegate = new EventEmitterDelegate<EntityEvents>();\n\n // Behavior references (new ECS pattern)\n private behaviorRefs: BehaviorRef[] = [];\n\n constructor() {\n super();\n }\n\n public create(): this {\n const { position: setupPosition } = this.options;\n const { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n this.behaviors = [\n { component: position, values: { x, y, z } },\n { component: scale, values: { x: 0, y: 0, z: 0 } },\n { component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n ];\n this.name = this.options.name || '';\n return this;\n }\n\n /**\n * Add collision callbacks\n */\n public onCollision(\n ...callbacks: ((params: CollisionContext<this, O>) => void)[]\n ): this {\n const existing = this.collisionDelegate.collision ?? [];\n this.collisionDelegate.collision = [...existing, ...callbacks];\n return this;\n }\n\n /**\n * Use a behavior on this entity via typed descriptor.\n * Behaviors will be auto-registered as systems when the entity is spawned.\n * @param descriptor The behavior descriptor (import from behaviors module)\n * @param options Optional overrides for the behavior's default options\n * @returns BehaviorHandle with behavior-specific methods for lazy FSM access\n */\n public use<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n >(\n descriptor: BehaviorDescriptor<O, H>,\n options?: Partial<O>,\n ): BehaviorHandle<O, H> {\n const behaviorRef: BehaviorRef<O> = {\n descriptor: descriptor as BehaviorDescriptor<O, any>,\n options: { ...descriptor.defaultOptions, ...options } as O,\n };\n this.behaviorRefs.push(behaviorRef as BehaviorRef<any>);\n\n // Create base handle\n const baseHandle = {\n getFSM: () => behaviorRef.fsm ?? null,\n getOptions: () => behaviorRef.options,\n ref: behaviorRef,\n };\n\n // Merge behavior-specific methods if createHandle is provided\n const customMethods = descriptor.createHandle?.(behaviorRef) ?? ({} as H);\n\n return {\n ...baseHandle,\n ...customMethods,\n } as BehaviorHandle<O, H>;\n }\n\n /**\n * Get all behavior references attached to this entity.\n * Used by the stage to auto-register required systems.\n */\n public getBehaviorRefs(): BehaviorRef[] {\n return this.behaviorRefs;\n }\n\n /**\n * Entity-specific setup - runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n */\n public _setup(params: SetupContext<this>): void {\n this.behaviorCallbackMap.setup.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n protected async _loaded(_params: LoadedContext<this>): Promise<void> {}\n\n /**\n * Entity-specific update - updates materials and runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)\n */\n public _update(params: UpdateContext<this>): void {\n this.updateMaterials(params);\n this.behaviorCallbackMap.update.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n /**\n * Entity-specific destroy - runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.destroy)\n */\n public _destroy(params: DestroyContext<this>): void {\n this.behaviorCallbackMap.destroy.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n protected async _cleanup(_params: CleanupContext<this>): Promise<void> {}\n\n public _collision(other: GameEntity<O>, globals?: any): void {\n if (this.collisionDelegate.collision?.length) {\n const callbacks = this.collisionDelegate.collision;\n callbacks.forEach((callback) => {\n callback({ entity: this, other, globals });\n });\n }\n this.behaviorCallbackMap.collision.forEach((callback) => {\n callback({ entity: this, other, globals });\n });\n }\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * See `lib/behaviors/thruster/thruster-movement.behavior.ts` for an example.\n */\n public addBehavior(behaviorCallback: {\n type: BehaviorCallbackType;\n handler: any;\n }): this {\n const handler = behaviorCallback.handler as unknown as BehaviorCallback<\n this,\n O\n >;\n if (handler) {\n this.behaviorCallbackMap[behaviorCallback.type].push(handler);\n }\n return this;\n }\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * See `lib/behaviors/thruster/thruster-movement.behavior.ts` for an example.\n */\n public addBehaviors(\n behaviorCallbacks: { type: BehaviorCallbackType; handler: any }[],\n ): this {\n behaviorCallbacks.forEach((callback) => {\n const handler = callback.handler as unknown as BehaviorCallback<this, O>;\n if (handler) {\n this.behaviorCallbackMap[callback.type].push(handler);\n }\n });\n return this;\n }\n\n protected updateMaterials(params: any) {\n if (!this.materials?.length) {\n return;\n }\n for (const material of this.materials) {\n if (material instanceof ShaderMaterial) {\n if (material.uniforms) {\n material.uniforms.iTime &&\n (material.uniforms.iTime.value += params.delta);\n }\n }\n }\n }\n\n public buildInfo(): Record<string, string> {\n const info: Record<string, string> = {};\n info.name = this.name;\n info.uuid = this.uuid;\n info.eid = this.eid.toString();\n return info;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Events API\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Dispatch an event from this entity.\n * Events are emitted both locally and to the global event bus.\n */\n dispatch<K extends keyof EntityEvents>(\n event: K,\n payload: EntityEvents[K],\n ): void {\n this.eventDelegate.dispatch(event, payload);\n (zylemEventBus as any).emit(event, payload);\n }\n\n /**\n * Listen for events on this entity instance.\n * @returns Unsubscribe function\n */\n listen<K extends keyof EntityEvents>(\n event: K,\n handler: (payload: EntityEvents[K]) => void,\n ): () => void {\n return this.eventDelegate.listen(event, handler);\n }\n\n /**\n * Clean up entity event subscriptions.\n */\n disposeEvents(): void {\n this.eventDelegate.dispose();\n }\n}\n","/**\n * Texture loader adapter for the Asset Manager\n */\n\nimport { TextureLoader, Texture, RepeatWrapping, Vector2, Wrapping } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface TextureOptions extends AssetLoadOptions {\n\trepeat?: Vector2;\n\twrapS?: Wrapping;\n\twrapT?: Wrapping;\n}\n\nexport class TextureLoaderAdapter implements LoaderAdapter<Texture> {\n\tprivate loader: TextureLoader;\n\n\tconstructor() {\n\t\tthis.loader = new TextureLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'tga'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: TextureOptions): Promise<Texture> {\n\t\tconst texture = await this.loader.loadAsync(url, (event) => {\n\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t}\n\t\t});\n\n\t\t// Apply texture options\n\t\tif (options?.repeat) {\n\t\t\ttexture.repeat.copy(options.repeat);\n\t\t}\n\t\ttexture.wrapS = options?.wrapS ?? RepeatWrapping;\n\t\ttexture.wrapT = options?.wrapT ?? RepeatWrapping;\n\n\t\treturn texture;\n\t}\n\n\t/**\n\t * Clone a texture for independent usage\n\t */\n\tclone(texture: Texture): Texture {\n\t\tconst cloned = texture.clone();\n\t\tcloned.needsUpdate = true;\n\t\treturn cloned;\n\t}\n}\n","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface GLTFLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parseAsync pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers, so this mainly\n\t * provides a cleaner async/await pattern rather than performance gains\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class GLTFLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: GLTFLoader;\n\n\tconstructor() {\n\t\tthis.loader = new GLTFLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['gltf', 'glb'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parseAsync\n\t * Both fetch and parsing are async, keeping the main thread responsive\n\t */\n\tprivate async loadWithAsyncFetch(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using GLTFLoader.parseAsync\n\t\t\t// The url is passed as the path for resolving relative resources\n\t\t\tconst gltf = await this.loader.parseAsync(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject: gltf.scene,\n\t\t\t\tanimations: gltf.animations,\n\t\t\t\tgltf\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch GLTF load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(gltf: GLTF) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject: gltf.scene,\n\t\t\t\t\t\tanimations: gltf.animations,\n\t\t\t\t\t\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded GLTF scene for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone()),\n\t\t\tgltf: result.gltf\n\t\t};\n\t}\n}\n","/**\n * FBX loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parse\n */\n\nimport { Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface FBXLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parse pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class FBXLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: FBXLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FBXLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'fbx';\n\t}\n\n\tasync load(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parse\n\t */\n\tprivate async loadWithAsyncFetch(url: string, _options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using FBXLoader.parse\n\t\t\tconst object = this.loader.parse(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject,\n\t\t\t\tanimations: (object as any).animations || []\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch FBX load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, _options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: (object as any).animations || []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded FBX object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone())\n\t\t};\n\t}\n}\n","/**\n * OBJ loader adapter for the Asset Manager\n * Supports optional MTL (material) file loading\n */\n\nimport { Object3D, Group } from 'three';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { MTLLoader } from 'three/addons/loaders/MTLLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface OBJLoadOptions extends AssetLoadOptions {\n\t/** Path to MTL material file */\n\tmtlPath?: string;\n}\n\nexport class OBJLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: OBJLoader;\n\tprivate mtlLoader: MTLLoader;\n\n\tconstructor() {\n\t\tthis.loader = new OBJLoader();\n\t\tthis.mtlLoader = new MTLLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'obj';\n\t}\n\n\tasync load(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Load MTL first if provided\n\t\tif (options?.mtlPath) {\n\t\t\tawait this.loadMTL(options.mtlPath);\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Group) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async loadMTL(url: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.mtlLoader.load(\n\t\t\t\turl,\n\t\t\t\t(materials) => {\n\t\t\t\t\tmaterials.preload();\n\t\t\t\t\tthis.loader.setMaterials(materials);\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded OBJ object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: []\n\t\t};\n\t}\n}\n","/**\n * Audio loader adapter for the Asset Manager\n */\n\nimport { AudioLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport class AudioLoaderAdapter implements LoaderAdapter<AudioBuffer> {\n\tprivate loader: AudioLoader;\n\n\tconstructor() {\n\t\tthis.loader = new AudioLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['mp3', 'ogg', 'wav', 'flac', 'aac', 'm4a'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(buffer) => resolve(buffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n","/**\n * File loader adapter for the Asset Manager\n */\n\nimport { FileLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface FileLoadOptions extends AssetLoadOptions {\n\tresponseType?: 'text' | 'arraybuffer' | 'blob' | 'json';\n}\n\nexport class FileLoaderAdapter implements LoaderAdapter<string | ArrayBuffer> {\n\tprivate loader: FileLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FileLoader();\n\t}\n\n\tisSupported(_url: string): boolean {\n\t\t// FileLoader can handle any file type\n\t\treturn true;\n\t}\n\n\tasync load(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst responseType = options?.responseType ?? 'text';\n\t\tthis.loader.setResponseType(responseType as any);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(data) => resolve(data as string | ArrayBuffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n\n/**\n * JSON loader using FileLoader\n */\nexport class JsonLoaderAdapter implements LoaderAdapter<unknown> {\n\tprivate fileLoader: FileLoaderAdapter;\n\n\tconstructor() {\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'json';\n\t}\n\n\tasync load<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\tconst data = await this.fileLoader.load(url, { ...options, responseType: 'json' });\n\t\treturn data as T;\n\t}\n}\n","/**\n * Loader adapters barrel export\n */\n\nexport { TextureLoaderAdapter, type TextureOptions } from './texture-loader';\nexport { GLTFLoaderAdapter, type GLTFLoadOptions } from './gltf-loader';\nexport { FBXLoaderAdapter, type FBXLoadOptions } from './fbx-loader';\nexport { OBJLoaderAdapter, type OBJLoadOptions } from './obj-loader';\nexport { AudioLoaderAdapter } from './audio-loader';\nexport { FileLoaderAdapter, JsonLoaderAdapter, type FileLoadOptions } from './file-loader';\n","/**\n * Centralized Asset Manager for Zylem\n * \n * Provides caching, parallel loading, and unified access to all asset types.\n * All asset loading should funnel through this manager.\n */\n\nimport { Texture, Object3D, LoadingManager, Cache } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport mitt, { Emitter } from 'mitt';\n\nimport {\n\tAssetType,\n\tAssetLoadOptions,\n\tAssetManagerEvents,\n\tBatchLoadItem,\n\tModelLoadResult\n} from './asset-types';\n\nimport {\n\tTextureLoaderAdapter,\n\tGLTFLoaderAdapter,\n\tFBXLoaderAdapter,\n\tOBJLoaderAdapter,\n\tAudioLoaderAdapter,\n\tFileLoaderAdapter,\n\tJsonLoaderAdapter,\n\tTextureOptions,\n\tGLTFLoadOptions,\n\tFBXLoadOptions,\n\tOBJLoadOptions,\n\tFileLoadOptions\n} from './loaders';\n\n/**\n * Asset cache entry\n */\ninterface CacheEntry<T> {\n\tpromise: Promise<T>;\n\tresult?: T;\n\tloadedAt: number;\n}\n\n/**\n * AssetManager - Singleton for all asset loading\n * \n * Features:\n * - URL-based caching with deduplication\n * - Typed load methods for each asset type\n * - Batch loading with Promise.all() for parallelism\n * - Progress events via LoadingManager\n * - Clone support for shared assets (textures, models)\n */\nexport class AssetManager {\n\tprivate static instance: AssetManager | null = null;\n\n\t// Caches for different asset types\n\tprivate textureCache: Map<string, CacheEntry<Texture>> = new Map();\n\tprivate modelCache: Map<string, CacheEntry<ModelLoadResult>> = new Map();\n\tprivate audioCache: Map<string, CacheEntry<AudioBuffer>> = new Map();\n\tprivate fileCache: Map<string, CacheEntry<string | ArrayBuffer>> = new Map();\n\tprivate jsonCache: Map<string, CacheEntry<unknown>> = new Map();\n\n\t// Loaders\n\tprivate textureLoader: TextureLoaderAdapter;\n\tprivate gltfLoader: GLTFLoaderAdapter;\n\tprivate fbxLoader: FBXLoaderAdapter;\n\tprivate objLoader: OBJLoaderAdapter;\n\tprivate audioLoader: AudioLoaderAdapter;\n\tprivate fileLoader: FileLoaderAdapter;\n\tprivate jsonLoader: JsonLoaderAdapter;\n\n\t// Loading manager for progress tracking\n\tprivate loadingManager: LoadingManager;\n\n\t// Event emitter\n\tprivate events: Emitter<AssetManagerEvents>;\n\n\t// Stats\n\tprivate stats = {\n\t\ttexturesLoaded: 0,\n\t\tmodelsLoaded: 0,\n\t\taudioLoaded: 0,\n\t\tfilesLoaded: 0,\n\t\tcacheHits: 0,\n\t\tcacheMisses: 0\n\t};\n\n\tprivate constructor() {\n\t\t// Initialize loaders\n\t\tthis.textureLoader = new TextureLoaderAdapter();\n\t\tthis.gltfLoader = new GLTFLoaderAdapter();\n\t\tthis.fbxLoader = new FBXLoaderAdapter();\n\t\tthis.objLoader = new OBJLoaderAdapter();\n\t\tthis.audioLoader = new AudioLoaderAdapter();\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t\tthis.jsonLoader = new JsonLoaderAdapter();\n\n\t\t// Initialize loading manager\n\t\tthis.loadingManager = new LoadingManager();\n\t\tthis.loadingManager.onProgress = (url, loaded, total) => {\n\t\t\tthis.events.emit('batch:progress', { loaded, total });\n\t\t};\n\n\t\t// Initialize event emitter\n\t\tthis.events = mitt<AssetManagerEvents>();\n\n\t\t// Enable Three.js built-in cache\n\t\tCache.enabled = true;\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tstatic getInstance(): AssetManager {\n\t\tif (!AssetManager.instance) {\n\t\t\tAssetManager.instance = new AssetManager();\n\t\t}\n\t\treturn AssetManager.instance;\n\t}\n\n\t/**\n\t * Reset the singleton (useful for testing)\n\t */\n\tstatic resetInstance(): void {\n\t\tif (AssetManager.instance) {\n\t\t\tAssetManager.instance.clearCache();\n\t\t\tAssetManager.instance = null;\n\t\t}\n\t}\n\n\t// ==================== TEXTURE LOADING ====================\n\n\t/**\n\t * Load a texture with caching\n\t */\n\tasync loadTexture(url: string, options?: TextureOptions): Promise<Texture> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.TEXTURE,\n\t\t\tthis.textureCache,\n\t\t\t() => this.textureLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(texture) => options?.clone ? this.textureLoader.clone(texture) : texture\n\t\t);\n\t}\n\n\t// ==================== MODEL LOADING ====================\n\n\t/**\n\t * Load a GLTF/GLB model with caching\n\t */\n\tasync loadGLTF(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.GLTF,\n\t\t\tthis.modelCache,\n\t\t\t() => this.gltfLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.gltfLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an FBX model with caching\n\t */\n\tasync loadFBX(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.FBX,\n\t\t\tthis.modelCache,\n\t\t\t() => this.fbxLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.fbxLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an OBJ model with caching\n\t */\n\tasync loadOBJ(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Include mtlPath in cache key for OBJ files\n\t\tconst cacheKey = options?.mtlPath ? `${url}:${options.mtlPath}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.OBJ,\n\t\t\tthis.modelCache,\n\t\t\t() => this.objLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.objLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Auto-detect model type and load\n\t */\n\tasync loadModel(url: string, options?: AssetLoadOptions): Promise<ModelLoadResult> {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\t\n\t\tswitch (ext) {\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb':\n\t\t\t\treturn this.loadGLTF(url, options);\n\t\t\tcase 'fbx':\n\t\t\t\treturn this.loadFBX(url, options);\n\t\t\tcase 'obj':\n\t\t\t\treturn this.loadOBJ(url, options);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model format: ${ext}`);\n\t\t}\n\t}\n\n\t// ==================== AUDIO LOADING ====================\n\n\t/**\n\t * Load an audio buffer with caching\n\t */\n\tasync loadAudio(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.AUDIO,\n\t\t\tthis.audioCache,\n\t\t\t() => this.audioLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t// ==================== FILE LOADING ====================\n\n\t/**\n\t * Load a raw file with caching\n\t */\n\tasync loadFile(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst cacheKey = options?.responseType ? `${url}:${options.responseType}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.FILE,\n\t\t\tthis.fileCache,\n\t\t\t() => this.fileLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Load a JSON file with caching\n\t */\n\tasync loadJSON<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.JSON,\n\t\t\tthis.jsonCache,\n\t\t\t() => this.jsonLoader.load<T>(url, options),\n\t\t\toptions\n\t\t) as Promise<T>;\n\t}\n\n\t// ==================== BATCH LOADING ====================\n\n\t/**\n\t * Load multiple assets in parallel\n\t */\n\tasync loadBatch(items: BatchLoadItem[]): Promise<Map<string, any>> {\n\t\tconst results = new Map<string, any>();\n\t\t\n\t\tconst promises = items.map(async (item) => {\n\t\t\ttry {\n\t\t\t\tlet result: any;\n\t\t\t\t\n\t\t\t\tswitch (item.type) {\n\t\t\t\t\tcase AssetType.TEXTURE:\n\t\t\t\t\t\tresult = await this.loadTexture(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.GLTF:\n\t\t\t\t\t\tresult = await this.loadGLTF(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FBX:\n\t\t\t\t\t\tresult = await this.loadFBX(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.OBJ:\n\t\t\t\t\t\tresult = await this.loadOBJ(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.AUDIO:\n\t\t\t\t\t\tresult = await this.loadAudio(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FILE:\n\t\t\t\t\t\tresult = await this.loadFile(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.JSON:\n\t\t\t\t\t\tresult = await this.loadJSON(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`Unknown asset type: ${item.type}`);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tresults.set(item.url, result);\n\t\t\t} catch (error) {\n\t\t\t\tthis.events.emit('asset:error', {\n\t\t\t\t\turl: item.url,\n\t\t\t\t\ttype: item.type,\n\t\t\t\t\terror: error as Error\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t\t\n\t\tthis.events.emit('batch:complete', { urls: items.map(i => i.url) });\n\t\t\n\t\treturn results;\n\t}\n\n\t/**\n\t * Preload assets without returning results\n\t */\n\tasync preload(items: BatchLoadItem[]): Promise<void> {\n\t\tawait this.loadBatch(items);\n\t}\n\n\t// ==================== CACHE MANAGEMENT ====================\n\n\t/**\n\t * Check if an asset is cached\n\t */\n\tisCached(url: string): boolean {\n\t\treturn this.textureCache.has(url) ||\n\t\t\tthis.modelCache.has(url) ||\n\t\t\tthis.audioCache.has(url) ||\n\t\t\tthis.fileCache.has(url) ||\n\t\t\tthis.jsonCache.has(url);\n\t}\n\n\t/**\n\t * Clear all caches or a specific URL\n\t */\n\tclearCache(url?: string): void {\n\t\tif (url) {\n\t\t\tthis.textureCache.delete(url);\n\t\t\tthis.modelCache.delete(url);\n\t\t\tthis.audioCache.delete(url);\n\t\t\tthis.fileCache.delete(url);\n\t\t\tthis.jsonCache.delete(url);\n\t\t} else {\n\t\t\tthis.textureCache.clear();\n\t\t\tthis.modelCache.clear();\n\t\t\tthis.audioCache.clear();\n\t\t\tthis.fileCache.clear();\n\t\t\tthis.jsonCache.clear();\n\t\t\tCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetStats(): typeof this.stats {\n\t\treturn { ...this.stats };\n\t}\n\n\t// ==================== EVENTS ====================\n\n\t/**\n\t * Subscribe to asset manager events\n\t */\n\ton<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.on(event, handler);\n\t}\n\n\t/**\n\t * Unsubscribe from asset manager events\n\t */\n\toff<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.off(event, handler);\n\t}\n\n\t// ==================== PRIVATE HELPERS ====================\n\n\t/**\n\t * Generic cache wrapper for loading assets\n\t */\n\tprivate async loadWithCache<T>(\n\t\turl: string,\n\t\ttype: AssetType,\n\t\tcache: Map<string, CacheEntry<T>>,\n\t\tloader: () => Promise<T>,\n\t\toptions?: AssetLoadOptions,\n\t\tcloner?: (result: T) => T\n\t): Promise<T> {\n\t\t// Check for force reload\n\t\tif (options?.forceReload) {\n\t\t\tcache.delete(url);\n\t\t}\n\n\t\t// Check cache\n\t\tconst cached = cache.get(url);\n\t\tif (cached) {\n\t\t\tthis.stats.cacheHits++;\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: true });\n\t\t\t\n\t\t\tconst result = await cached.promise;\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t}\n\n\t\t// Cache miss - start loading\n\t\tthis.stats.cacheMisses++;\n\t\tthis.events.emit('asset:loading', { url, type });\n\n\t\tconst promise = loader();\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tpromise,\n\t\t\tloadedAt: Date.now()\n\t\t};\n\t\tcache.set(url, entry);\n\n\t\ttry {\n\t\t\tconst result = await promise;\n\t\t\tentry.result = result;\n\t\t\t\n\t\t\t// Update stats\n\t\t\tthis.updateStats(type);\n\t\t\t\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: false });\n\t\t\t\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t} catch (error) {\n\t\t\t// Remove failed entry from cache\n\t\t\tcache.delete(url);\n\t\t\tthis.events.emit('asset:error', { url, type, error: error as Error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate updateStats(type: AssetType): void {\n\t\tswitch (type) {\n\t\t\tcase AssetType.TEXTURE:\n\t\t\t\tthis.stats.texturesLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.GLTF:\n\t\t\tcase AssetType.FBX:\n\t\t\tcase AssetType.OBJ:\n\t\t\t\tthis.stats.modelsLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.AUDIO:\n\t\t\t\tthis.stats.audioLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.FILE:\n\t\t\tcase AssetType.JSON:\n\t\t\t\tthis.stats.filesLoaded++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Singleton instance export for convenience\n */\nexport const assetManager = AssetManager.getInstance();","/**\n * Entity Asset Loader - Refactored to use AssetManager\n * \n * This module provides a compatibility layer for existing code that uses EntityAssetLoader.\n * All loading now goes through the centralized AssetManager for caching.\n */\n\nimport { AnimationClip, Object3D } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport { assetManager } from './asset-manager';\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\n/**\n * EntityAssetLoader - Uses AssetManager for all model loading\n * \n * This class is now a thin wrapper around AssetManager, providing backward\n * compatibility for existing code while benefiting from centralized caching.\n */\nexport class EntityAssetLoader {\n\t/**\n\t * Load a model file (FBX, GLTF, GLB, OBJ) using the asset manager\n\t */\n\tasync loadFile(file: string): Promise<AssetLoaderResult> {\n\t\tconst ext = file.split('.').pop()?.toLowerCase();\n\n\t\tswitch (ext) {\n\t\t\tcase 'fbx': {\n\t\t\t\tconst result = await assetManager.loadFBX(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tanimation: result.animations?.[0]\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb': {\n\t\t\t\tconst result = await assetManager.loadGLTF(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tgltf: result.gltf\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'obj': {\n\t\t\t\tconst result = await assetManager.loadOBJ(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\t}\n}\n","import {\n\tAnimationAction,\n\tAnimationClip,\n\tAnimationMixer,\n\tLoopOnce,\n\tLoopRepeat,\n\tObject3D,\n} from 'three';\nimport { EntityAssetLoader, AssetLoaderResult } from '../../core/entity-asset-loader';\n\nexport type AnimationOptions = {\n\tkey: string;\n\tpauseAtEnd?: boolean;\n\tpauseAtPercentage?: number;\n\tfadeToKey?: string;\n\tfadeDuration?: number;\n};\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport class AnimationDelegate {\n\tprivate _mixer: AnimationMixer | null = null;\n\tprivate _actions: Record<string, AnimationAction> = {};\n\tprivate _animations: AnimationClip[] = [];\n\tprivate _currentAction: AnimationAction | null = null;\n\n\tprivate _pauseAtPercentage = 0;\n\tprivate _isPaused = false;\n\tprivate _queuedKey: string | null = null;\n\tprivate _fadeDuration = 0.5;\n\n\tprivate _currentKey: string = '';\n\tprivate _assetLoader = new EntityAssetLoader();\n\n\tconstructor(private target: Object3D) { }\n\n\tasync loadAnimations(animations: AnimationObject[]): Promise<void> {\n\t\tif (!animations.length) return;\n\n\t\tconst results = await Promise.all(animations.map(a => this._assetLoader.loadFile(a.path)));\n\t\tthis._animations = results\n\t\t\t.filter((r): r is AssetLoaderResult => !!r.animation)\n\t\t\t.map(r => r.animation!);\n\n\t\tif (!this._animations.length) return;\n\n\t\tthis._mixer = new AnimationMixer(this.target);\n\t\tthis._animations.forEach((clip, i) => {\n\t\t\tconst key = animations[i].key || i.toString();\n\t\t\tthis._actions[key] = this._mixer!.clipAction(clip);\n\t\t});\n\n\t\tthis.playAnimation({ key: Object.keys(this._actions)[0] });\n\t}\n\n\tupdate(delta: number): void {\n\t\tif (!this._mixer || !this._currentAction) return;\n\n\t\tthis._mixer.update(delta);\n\n\t\tconst pauseAtTime = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);\n\t\tif (\n\t\t\t!this._isPaused &&\n\t\t\tthis._pauseAtPercentage > 0 &&\n\t\t\tthis._currentAction.time >= pauseAtTime\n\t\t) {\n\t\t\tthis._currentAction.time = pauseAtTime;\n\t\t\tthis._currentAction.paused = true;\n\t\t\tthis._isPaused = true;\n\n\t\t\tif (this._queuedKey !== null) {\n\t\t\t\tconst next = this._actions[this._queuedKey];\n\t\t\t\tnext.reset().play();\n\t\t\t\tthis._currentAction.crossFadeTo(next, this._fadeDuration, false);\n\t\t\t\tthis._currentAction = next;\n\t\t\t\tthis._currentKey = this._queuedKey;\n\t\t\t\tthis._queuedKey = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tplayAnimation(opts: AnimationOptions): void {\n\t\tif (!this._mixer) return;\n\t\tconst { key, pauseAtPercentage = 0, pauseAtEnd = false, fadeToKey, fadeDuration = 0.5 } = opts;\n\t\tif (key === this._currentKey) return;\n\n\t\tthis._queuedKey = fadeToKey || null;\n\t\tthis._fadeDuration = fadeDuration;\n\n\t\tthis._pauseAtPercentage = pauseAtEnd ? 100 : pauseAtPercentage;\n\t\tthis._isPaused = false;\n\n\t\tconst prev = this._currentAction;\n\t\tif (prev) prev.stop();\n\n\t\tconst action = this._actions[key];\n\t\tif (!action) return;\n\n\t\tif (this._pauseAtPercentage > 0) {\n\t\t\taction.setLoop(LoopOnce, Infinity);\n\t\t\taction.clampWhenFinished = true;\n\t\t} else {\n\t\t\taction.setLoop(LoopRepeat, Infinity);\n\t\t\taction.clampWhenFinished = false;\n\t\t}\n\n\t\tif (prev) {\n\t\t\tprev.crossFadeTo(action, fadeDuration, false);\n\t\t}\n\t\taction.reset().play();\n\n\t\tthis._currentAction = action;\n\t\tthis._currentKey = key;\n\t}\n\n\t/**\n\t * Dispose of all animation resources\n\t */\n\tdispose(): void {\n\t\t// Stop all actions\n\t\tObject.values(this._actions).forEach(action => {\n\t\t\taction.stop();\n\t\t});\n\n\t\t// Stop and uncache mixer\n\t\tif (this._mixer) {\n\t\t\tthis._mixer.stopAllAction();\n\t\t\tthis._mixer.uncacheRoot(this.target);\n\t\t\tthis._mixer = null;\n\t\t}\n\n\t\t// Clear references\n\t\tthis._actions = {};\n\t\tthis._animations = [];\n\t\tthis._currentAction = null;\n\t\tthis._currentKey = '';\n\t}\n\n\tget currentAnimationKey() { return this._currentKey; }\n\tget animations() { return this._animations; }\n}\n","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","import { Color, Vector3 } from 'three';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { GameEntityOptions } from './entity';\n\nexport const commonDefaults: Partial<GameEntityOptions> = {\n position: new Vector3(0, 0, 0),\n material: {\n color: new Color('#ffffff'),\n shader: standardShader\n },\n collision: {\n static: false,\n },\n};\n","import { proxy } from 'valtio';\nimport type { GameEntity } from '../entities/entity';\n\nexport type DebugTools = 'select' | 'translate' | 'rotate' | 'scale' | 'delete' | 'none';\n\nexport interface DebugState {\n\tenabled: boolean;\n\tpaused: boolean;\n\ttool: DebugTools;\n\tselectedEntity: GameEntity<any> | null;\n\thoveredEntity: GameEntity<any> | null;\n\tflags: Set<string>;\n}\n\nexport const debugState = proxy<DebugState>({\n\tenabled: false,\n\tpaused: false,\n\ttool: 'none',\n\tselectedEntity: null,\n\thoveredEntity: null,\n\tflags: new Set(),\n});\n\nexport function isPaused(): boolean {\n\treturn debugState.paused;\n}\n\nexport function setPaused(paused: boolean): void {\n\tdebugState.paused = paused;\n}\n\nexport function setDebugFlag(flag: string, value: boolean): void {\n\tif (value) {\n\t\tdebugState.flags.add(flag);\n\t} else {\n\t\tdebugState.flags.delete(flag);\n\t}\n}\n\nexport function getDebugTool(): DebugTools {\n\treturn debugState.tool;\n}\n\nexport function setDebugTool(tool: DebugTools): void {\n\tdebugState.tool = tool;\n}\n\nexport function getSelectedEntity(): GameEntity<any> | null {\n\treturn debugState.selectedEntity;\n}\n\nexport function setSelectedEntity(entity: GameEntity<any> | null): void {\n\tdebugState.selectedEntity = entity;\n}\n\nexport function getHoveredEntity(): GameEntity<any> | null {\n\treturn debugState.hoveredEntity;\n}\n\nexport function setHoveredEntity(entity: GameEntity<any> | null): void {\n\tdebugState.hoveredEntity = entity;\n}\n\nexport function resetHoveredEntity(): void {\n\tdebugState.hoveredEntity = null;\n}\n","import { Euler, Quaternion, Vector2 } from \"three\";\nimport { GameEntity } from \"../entities\";\nimport { Stage } from \"./stage\";\n\nexport interface EntitySpawner {\n\tspawn: (stage: Stage, x: number, y: number) => Promise<GameEntity<any>>;\n\tspawnRelative: (source: any, stage: Stage, offset?: Vector2) => Promise<any | void>;\n}\n\nexport function entitySpawner(factory: (x: number, y: number) => Promise<any> | GameEntity<any>): EntitySpawner {\n\treturn {\n\t\tspawn: async (stage: Stage, x: number, y: number) => {\n\t\t\tconst instance = await Promise.resolve(factory(x, y));\n\t\t\tstage.add(instance);\n\t\t\treturn instance;\n\t\t},\n\t\tspawnRelative: async (source: any, stage: Stage, offset: Vector2 = new Vector2(0, 1)) => {\n\t\t\tif (!source.body) {\n\t\t\t\tconsole.warn('body missing for entity during spawnRelative');\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { x, y, z } = source.body.translation();\n\t\t\tlet rz = (source as any)._rotation2DAngle ?? 0;\n\t\t\ttry {\n\t\t\t\tconst r = source.body.rotation();\n\t\t\t\tconst q = new Quaternion(r.x, r.y, r.z, r.w);\n\t\t\t\tconst e = new Euler().setFromQuaternion(q, 'XYZ');\n\t\t\t\trz = e.z;\n\t\t\t} catch { /* use fallback angle */ }\n\n\t\t\tconst offsetX = Math.sin(-rz) * (offset.x ?? 0);\n\t\t\tconst offsetY = Math.cos(-rz) * (offset.y ?? 0);\n\n\t\t\tconst instance = await Promise.resolve(factory(x + offsetX, y + offsetY));\n\t\t\tstage.add(instance);\n\t\t\treturn instance;\n\t\t}\n\t};\n}","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];","import { Scene, Vector2, Vector3, WebGLRenderer } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { StageEntity } from '../interfaces/entity';\n\ninterface ThirdPersonCameraOptions {\n\ttarget: StageEntity;\n\tdistance: Vector3;\n\tscreenResolution: Vector2;\n\trenderer: WebGLRenderer;\n\tscene: Scene;\n}\n\nexport class ThirdPersonCamera implements PerspectiveController {\n\tdistance: Vector3;\n\tscreenResolution: Vector2 | null = null;\n\trenderer: WebGLRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\tthis.distance = new Vector3(0, 5, 8);\n\t}\n\n\t/**\n\t * Setup the third person camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: WebGLRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\t}\n\n\t/**\n\t * Update the third person camera\n\t */\n\tupdate(delta: number) {\n\t\tif (!this.cameraRef!.target) {\n\t\t\treturn;\n\t\t}\n\t\t// TODO: Implement third person camera following logic\n\t\tconst desiredCameraPosition = this.cameraRef!.target!.group.position.clone().add(this.distance);\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, 0.1);\n\t\tthis.cameraRef!.camera.lookAt(this.cameraRef!.target!.group.position);\n\t}\n\n\t/**\n\t * Handle resize events\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\t\t// TODO: Handle any third-person specific resize logic\n\t}\n\n\t/**\n\t * Set the distance from the target\n\t */\n\tsetDistance(distance: Vector3) {\n\t\tthis.distance = distance;\n\t}\n}","import { Scene, Vector2, WebGLRenderer } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\n\n/**\n * Fixed 2D Camera Controller\n * Maintains a static 2D camera view with no automatic following or movement\n */\nexport class Fixed2DCamera implements PerspectiveController {\n\tscreenResolution: Vector2 | null = null;\n\trenderer: WebGLRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\t// Fixed 2D camera doesn't need any initial setup parameters\n\t}\n\n\t/**\n\t * Setup the fixed 2D camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: WebGLRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\n\t\t// Position camera for 2D view (looking down the Z-axis)\n\t\tthis.cameraRef.camera.position.set(0, 0, 10);\n\t\tthis.cameraRef.camera.lookAt(0, 0, 0);\n\t}\n\n\t/**\n\t * Update the fixed 2D camera\n\t * Fixed cameras don't need to update position/rotation automatically\n\t */\n\tupdate(delta: number) {\n\t\t// Fixed 2D camera maintains its position and orientation\n\t\t// No automatic updates needed for a truly fixed camera\n\t}\n\n\t/**\n\t * Handle resize events for 2D camera\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\n\t\t// For orthographic cameras, we might need to adjust the frustum\n\t\t// This is handled in the main ZylemCamera resize method\n\t}\n}\n","import * as THREE from 'three';\nimport { standardShader } from './shaders/standard.shader';\nimport { WebGLRenderer, WebGLRenderTarget } from 'three';\nimport { Pass, FullScreenQuad } from 'three/addons/postprocessing/Pass.js';\n\nexport default class RenderPass extends Pass {\n\tfsQuad: FullScreenQuad;\n\tresolution: THREE.Vector2;\n\tscene: THREE.Scene;\n\tcamera: THREE.Camera;\n\trgbRenderTarget: WebGLRenderTarget;\n\tnormalRenderTarget: WebGLRenderTarget;\n\tnormalMaterial: THREE.Material;\n\n\tconstructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera) {\n\t\tsuper();\n\t\tthis.resolution = resolution;\n\t\tthis.fsQuad = new FullScreenQuad(this.material());\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.rgbRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\t\tthis.normalRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\n\t\tthis.normalMaterial = new THREE.MeshNormalMaterial();\n\t}\n\n\trender(\n\t\trenderer: WebGLRenderer,\n\t\twriteBuffer: WebGLRenderTarget\n\t) {\n\t\trenderer.setRenderTarget(this.rgbRenderTarget);\n\t\trenderer.render(this.scene, this.camera);\n\n\t\tconst overrideMaterial_old = this.scene.overrideMaterial;\n\t\trenderer.setRenderTarget(this.normalRenderTarget);\n\t\tthis.scene.overrideMaterial = this.normalMaterial;\n\t\trenderer.render(this.scene, this.camera);\n\t\tthis.scene.overrideMaterial = overrideMaterial_old;\n\n\t\t// @ts-ignore\n\t\tconst uniforms = this.fsQuad.material.uniforms;\n\t\tuniforms.tDiffuse.value = this.rgbRenderTarget.texture;\n\t\tuniforms.tDepth.value = this.rgbRenderTarget.depthTexture;\n\t\tuniforms.tNormal.value = this.normalRenderTarget.texture;\n\t\tuniforms.iTime.value += 0.01;\n\n\t\tif (this.renderToScreen) {\n\t\t\trenderer.setRenderTarget(null);\n\t\t} else {\n\t\t\trenderer.setRenderTarget(writeBuffer);\n\t\t}\n\t\tthis.fsQuad.render(renderer);\n\t}\n\n\tmaterial() {\n\t\treturn new THREE.ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tresolution: {\n\t\t\t\t\tvalue: new THREE.Vector4(\n\t\t\t\t\t\tthis.resolution.x,\n\t\t\t\t\t\tthis.resolution.y,\n\t\t\t\t\t\t1 / this.resolution.x,\n\t\t\t\t\t\t1 / this.resolution.y,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t},\n\t\t\tvertexShader: standardShader.vertex,\n\t\t\tfragmentShader: standardShader.fragment\n\t\t});\n\t}\n\n\tdispose() {\n\t\ttry {\n\t\t\tthis.fsQuad?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.rgbRenderTarget as any)?.dispose?.();\n\t\t\t(this.normalRenderTarget as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.normalMaterial as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t}\n}\n","import { Object3D, Vector3, Quaternion, Camera, Scene } from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\nexport interface CameraDebugState {\n\tenabled: boolean;\n\tselected: string[];\n}\n\nexport interface CameraDebugDelegate {\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void;\n\tresolveTarget(uuid: string): Object3D | null;\n}\n\n/**\n * Manages orbit controls and debug state for a camera.\n * Orbit controls are only active when debug mode is enabled.\n */\nexport class CameraOrbitController {\n\tprivate camera: Camera;\n\tprivate domElement: HTMLElement;\n\tprivate cameraRig: Object3D | null = null;\n\tprivate sceneRef: Scene | null = null;\n\t\n\tprivate orbitControls: OrbitControls | null = null;\n\tprivate orbitTarget: Object3D | null = null;\n\tprivate orbitTargetWorldPos: Vector3 = new Vector3();\n\n\tprivate debugDelegate: CameraDebugDelegate | null = null;\n\tprivate debugUnsubscribe: (() => void) | null = null;\n\tprivate debugStateSnapshot: CameraDebugState = { enabled: false, selected: [] };\n\n\t// Saved camera state for restoration when exiting debug mode\n\tprivate savedCameraPosition: Vector3 | null = null;\n\tprivate savedCameraQuaternion: Quaternion | null = null;\n\tprivate savedCameraZoom: number | null = null;\n\tprivate savedCameraLocalPosition: Vector3 | null = null;\n\n\t// Saved debug camera state for restoration when re-entering debug mode\n\tprivate savedDebugCameraPosition: Vector3 | null = null;\n\tprivate savedDebugCameraQuaternion: Quaternion | null = null;\n\tprivate savedDebugCameraZoom: number | null = null;\n\tprivate savedDebugOrbitTarget: Vector3 | null = null;\n\n\tconstructor(camera: Camera, domElement: HTMLElement, cameraRig?: Object3D | null) {\n\t\tthis.camera = camera;\n\t\tthis.domElement = domElement;\n\t\tthis.cameraRig = cameraRig ?? null;\n\t}\n\n\t/**\n\t * Set the scene reference for adding/removing camera when detaching from rig.\n\t */\n\tsetScene(scene: Scene | null): void {\n\t\tthis.sceneRef = scene;\n\t}\n\n\t/**\n\t * Check if debug mode is currently active (orbit controls enabled).\n\t */\n\tget isActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled;\n\t}\n\n\t/**\n\t * Update orbit controls each frame.\n\t * Should be called from the camera's update loop.\n\t */\n\tupdate() {\n\t\tif (this.orbitControls && this.orbitTarget) {\n\t\t\tthis.orbitTarget.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t}\n\t\tthis.orbitControls?.update();\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tif (this.debugDelegate === delegate) {\n\t\t\treturn;\n\t\t}\n\t\tthis.detachDebugDelegate();\n\t\tthis.debugDelegate = delegate;\n\t\tif (!delegate) {\n\t\t\tthis.applyDebugState({ enabled: false, selected: [] });\n\t\t\treturn;\n\t\t}\n\t\tconst unsubscribe = delegate.subscribe((state) => {\n\t\t\tthis.applyDebugState(state);\n\t\t});\n\t\tthis.debugUnsubscribe = () => {\n\t\t\tunsubscribe?.();\n\t\t};\n\t}\n\n\t/**\n\t * Clean up resources.\n\t */\n\tdispose() {\n\t\tthis.disableOrbitControls();\n\t\tthis.detachDebugDelegate();\n\t}\n\n\t/**\n\t * Get the current debug state snapshot.\n\t */\n\tget debugState(): CameraDebugState {\n\t\treturn this.debugStateSnapshot;\n\t}\n\n\tprivate applyDebugState(state: CameraDebugState) {\n\t\tconst wasEnabled = this.debugStateSnapshot.enabled;\n\t\tthis.debugStateSnapshot = {\n\t\t\tenabled: state.enabled,\n\t\t\tselected: [...state.selected],\n\t\t};\n\t\tif (state.enabled && !wasEnabled) {\n\t\t\t// Entering debug mode: save game camera state, detach from rig, restore debug camera state if available\n\t\t\tthis.saveCameraState();\n\t\t\tthis.detachCameraFromRig();\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.restoreDebugCameraState();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else if (!state.enabled && wasEnabled) {\n\t\t\t// Exiting debug mode: save debug camera state, then restore game camera state\n\t\t\tthis.saveDebugCameraState();\n\t\t\tthis.orbitTarget = null;\n\t\t\tthis.disableOrbitControls();\n\t\t\tthis.reattachCameraToRig();\n\t\t\tthis.restoreCameraState();\n\t\t} else if (state.enabled) {\n\t\t\t// Still in debug mode, just update target\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t}\n\t}\n\n\tprivate enableOrbitControls() {\n\t\tif (this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls = new OrbitControls(this.camera, this.domElement);\n\t\tthis.orbitControls.enableDamping = true;\n\t\tthis.orbitControls.dampingFactor = 0.05;\n\t\tthis.orbitControls.screenSpacePanning = false;\n\t\tthis.orbitControls.minDistance = 1;\n\t\tthis.orbitControls.maxDistance = 500;\n\t\tthis.orbitControls.maxPolarAngle = Math.PI / 2;\n\t\t// Default target to origin\n\t\tthis.orbitControls.target.set(0, 0, 0);\n\t}\n\n\tprivate disableOrbitControls() {\n\t\tif (!this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls.dispose();\n\t\tthis.orbitControls = null;\n\t}\n\n\tprivate updateOrbitTargetFromSelection(selected: string[]) {\n\t\t// Default to origin when no entity is selected\n\t\tif (!this.debugDelegate || selected.length === 0) {\n\t\t\tthis.orbitTarget = null;\n\t\t\tif (this.orbitControls) {\n\t\t\t\tthis.orbitControls.target.set(0, 0, 0);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tfor (let i = selected.length - 1; i >= 0; i -= 1) {\n\t\t\tconst uuid = selected[i];\n\t\t\tconst targetObject = this.debugDelegate.resolveTarget(uuid);\n\t\t\tif (targetObject) {\n\t\t\t\tthis.orbitTarget = targetObject;\n\t\t\t\tif (this.orbitControls) {\n\t\t\t\t\ttargetObject.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.orbitTarget = null;\n\t}\n\n\tprivate detachDebugDelegate() {\n\t\tif (this.debugUnsubscribe) {\n\t\t\ttry {\n\t\t\t\tthis.debugUnsubscribe();\n\t\t\t} catch { /* noop */ }\n\t\t}\n\t\tthis.debugUnsubscribe = null;\n\t\tthis.debugDelegate = null;\n\t}\n\n\t/**\n\t * Save camera position, rotation, and zoom before entering debug mode.\n\t */\n\tprivate saveCameraState() {\n\t\tthis.savedCameraPosition = this.camera.position.clone();\n\t\tthis.savedCameraQuaternion = this.camera.quaternion.clone();\n\t\t// Save zoom for orthographic/perspective cameras\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t}\n\n\t/**\n\t * Restore camera position, rotation, and zoom when exiting debug mode.\n\t */\n\tprivate restoreCameraState() {\n\t\tif (this.savedCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraPosition);\n\t\t\tthis.savedCameraPosition = null;\n\t\t}\n\t\tif (this.savedCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedCameraQuaternion);\n\t\t\tthis.savedCameraQuaternion = null;\n\t\t}\n\t\tif (this.savedCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t\tthis.savedCameraZoom = null;\n\t\t}\n\t}\n\n\t/**\n\t * Save debug camera state when exiting debug mode.\n\t */\n\tprivate saveDebugCameraState() {\n\t\tthis.savedDebugCameraPosition = this.camera.position.clone();\n\t\tthis.savedDebugCameraQuaternion = this.camera.quaternion.clone();\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedDebugCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t\tif (this.orbitControls) {\n\t\t\tthis.savedDebugOrbitTarget = this.orbitControls.target.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Restore debug camera state when re-entering debug mode.\n\t */\n\tprivate restoreDebugCameraState() {\n\t\tif (this.savedDebugCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedDebugCameraPosition);\n\t\t}\n\t\tif (this.savedDebugCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedDebugCameraQuaternion);\n\t\t}\n\t\tif (this.savedDebugCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedDebugCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t}\n\t\tif (this.savedDebugOrbitTarget && this.orbitControls) {\n\t\t\tthis.orbitControls.target.copy(this.savedDebugOrbitTarget);\n\t\t}\n\t}\n\n\t/**\n\t * Detach camera from its rig to allow free orbit movement in debug mode.\n\t * Preserves the camera's world position.\n\t */\n\tprivate detachCameraFromRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent !== this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Save the camera's local position for later restoration\n\t\tthis.savedCameraLocalPosition = this.camera.position.clone();\n\n\t\t// Get camera's world position before detaching\n\t\tconst worldPos = new Vector3();\n\t\tthis.camera.getWorldPosition(worldPos);\n\n\t\t// Remove camera from rig\n\t\tthis.cameraRig.remove(this.camera);\n\n\t\t// Add camera directly to scene if scene ref is available\n\t\tif (this.sceneRef) {\n\t\t\tthis.sceneRef.add(this.camera);\n\t\t}\n\n\t\t// Set camera's position to its previous world position\n\t\tthis.camera.position.copy(worldPos);\n\t}\n\n\t/**\n\t * Reattach camera to its rig when exiting debug mode.\n\t * Restores the camera's local position relative to the rig.\n\t */\n\tprivate reattachCameraToRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent === this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove camera from scene if it's there\n\t\tif (this.sceneRef && this.camera.parent === this.sceneRef) {\n\t\t\tthis.sceneRef.remove(this.camera);\n\t\t}\n\n\t\t// Add camera back to rig\n\t\tthis.cameraRig.add(this.camera);\n\n\t\t// Restore camera's local position\n\t\tif (this.savedCameraLocalPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraLocalPosition);\n\t\t\tthis.savedCameraLocalPosition = null;\n\t\t}\n\t}\n}\n","import { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, WebGLRenderer, Scene } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { ThirdPersonCamera } from './third-person';\nimport { Fixed2DCamera } from './fixed-2d';\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport RenderPass from '../graphics/render-pass';\nimport { StageEntity } from '../interfaces/entity';\nimport { CameraOrbitController, CameraDebugDelegate } from './camera-debug-delegate';\n\n// Re-export for backwards compatibility\nexport type { CameraDebugState, CameraDebugDelegate } from './camera-debug-delegate';\n\n/**\n * Interface for perspective-specific camera controllers\n */\nexport interface PerspectiveController {\n\tsetup(params: { screenResolution: Vector2; renderer: WebGLRenderer; scene: Scene; camera: ZylemCamera }): void;\n\tupdate(delta: number): void;\n\tresize(width: number, height: number): void;\n}\n\nexport class ZylemCamera {\n\tcameraRig: Object3D | null = null;\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\trenderer: WebGLRenderer;\n\tcomposer: EffectComposer;\n\t_perspective: PerspectiveType;\n\ttarget: StageEntity | null = null;\n\tsceneRef: Scene | null = null;\n\tfrustumSize = 10;\n\n\t// Perspective controller delegation\n\tperspectiveController: PerspectiveController | null = null;\n\n\t// Debug/orbit controls delegation\n\tprivate orbitController: CameraOrbitController | null = null;\n\n\tconstructor(perspective: PerspectiveType, screenResolution: Vector2, frustumSize: number = 10) {\n\t\tthis._perspective = perspective;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.frustumSize = frustumSize;\n\t\t// Initialize renderer\n\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\tthis.renderer.setSize(screenResolution.x, screenResolution.y);\n\t\tthis.renderer.shadowMap.enabled = true;\n\n\t\t// Initialize composer\n\t\tthis.composer = new EffectComposer(this.renderer);\n\n\t\t// Create camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Setup camera rig only for perspectives that need it (e.g., third-person following)\n\t\tif (this.needsRig()) {\n\t\t\tthis.cameraRig = new Object3D();\n\t\t\tthis.cameraRig.position.set(0, 3, 10);\n\t\t\tthis.cameraRig.add(this.camera);\n\t\t\tthis.camera.lookAt(new Vector3(0, 2, 0));\n\t\t} else {\n\t\t\t// Position camera directly for non-rig perspectives\n\t\t\tthis.camera.position.set(0, 0, 10);\n\t\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\t\t}\n\n\t\t// Initialize perspective controller\n\t\tthis.initializePerspectiveController();\n\n\t\t// Initialize orbit controller (handles debug mode orbit controls)\n\t\tthis.orbitController = new CameraOrbitController(this.camera, this.renderer.domElement, this.cameraRig);\n\t}\n\n\t/**\n\t * Setup the camera with a scene\n\t */\n\tasync setup(scene: Scene) {\n\t\tthis.sceneRef = scene;\n\n\t\t// Setup render pass\n\t\tlet renderResolution = this.screenResolution.clone().divideScalar(2);\n\t\trenderResolution.x |= 0;\n\t\trenderResolution.y |= 0;\n\t\tconst pass = new RenderPass(renderResolution, scene, this.camera);\n\t\tthis.composer.addPass(pass);\n\n\t\t// Setup perspective controller\n\t\tif (this.perspectiveController) {\n\t\t\tthis.perspectiveController.setup({\n\t\t\t\tscreenResolution: this.screenResolution,\n\t\t\t\trenderer: this.renderer,\n\t\t\t\tscene: scene,\n\t\t\t\tcamera: this\n\t\t\t});\n\t\t}\n\n\t\t// Set scene reference for orbit controller (needed for camera rig detachment)\n\t\tthis.orbitController?.setScene(scene);\n\n\t\t// Start render loop\n\t\tthis.renderer.setAnimationLoop((delta) => {\n\t\t\tthis.update(delta || 0);\n\t\t});\n\t}\n\n\t/**\n\t * Update camera and render\n\t */\n\tupdate(delta: number) {\n\t\t// Update orbit controls (if debug mode is enabled)\n\t\tthis.orbitController?.update();\n\n\t\t// Skip perspective controller updates when in debug mode\n\t\t// This keeps the debug camera isolated from game camera logic\n\t\tif (this.perspectiveController && !this.isDebugModeActive()) {\n\t\t\tthis.perspectiveController.update(delta);\n\t\t}\n\n\t\t// Render the scene\n\t\tthis.composer.render(delta);\n\t}\n\n\t/**\n\t * Check if debug mode is active (orbit controls taking over camera)\n\t */\n\tisDebugModeActive(): boolean {\n\t\treturn this.orbitController?.isActive ?? false;\n\t}\n\n\t/**\n\t * Dispose renderer, composer, controls, and detach from scene\n\t */\n\tdestroy() {\n\t\ttry {\n\t\t\tthis.renderer.setAnimationLoop(null as any);\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.composer?.passes?.forEach((p: any) => p.dispose?.());\n\t\t\t// @ts-ignore dispose exists on EffectComposer but not typed here\n\t\t\tthis.composer?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderer.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis.sceneRef = null;\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tthis.orbitController?.setDebugDelegate(delegate);\n\t}\n\n\t/**\n\t * Resize camera and renderer\n\t */\n\tresize(width: number, height: number) {\n\t\tthis.screenResolution.set(width, height);\n\t\tthis.renderer.setSize(width, height, false);\n\t\tthis.composer.setSize(width, height);\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tthis.camera.aspect = width / height;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.perspectiveController) {\n\t\t\tthis.perspectiveController.resize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Update renderer pixel ratio (DPR)\n\t */\n\tsetPixelRatio(dpr: number) {\n\t\tconst safe = Math.max(1, Number.isFinite(dpr) ? dpr : 1);\n\t\tthis.renderer.setPixelRatio(safe);\n\t}\n\n\t/**\n\t * Create camera based on perspective type\n\t */\n\tprivate createCameraForPerspective(aspectRatio: number): Camera {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn this.createFirstPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn this.createIsometricCamera(aspectRatio);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\t\treturn this.createFlat2DCamera(aspectRatio);\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn this.createFixed2DCamera(aspectRatio);\n\t\t\tdefault:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize perspective-specific controller\n\t */\n\tprivate initializePerspectiveController() {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t\t\tbreak;\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\tthis.perspectiveController = new Fixed2DCamera();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t}\n\t}\n\n\tprivate createThirdPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createFirstPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createIsometricCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFlat2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFixed2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn this.createFlat2DCamera(aspectRatio);\n\t}\n\n\t// Movement methods\n\tprivate moveCamera(position: Vector3) {\n\t\tif (this._perspective === Perspectives.Flat2D || this._perspective === Perspectives.Fixed2D) {\n\t\t\tthis.frustumSize = position.z;\n\t\t}\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.position.set(position.x, position.y, position.z);\n\t\t} else {\n\t\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t\t}\n\t}\n\n\tmove(position: Vector3) {\n\t\tthis.moveCamera(position);\n\t}\n\n\trotate(pitch: number, yaw: number, roll: number) {\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.rotateX(pitch);\n\t\t\tthis.cameraRig.rotateY(yaw);\n\t\t\tthis.cameraRig.rotateZ(roll);\n\t\t} else {\n\t\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t\t(this.camera as Object3D).rotateZ(roll);\n\t\t}\n\t}\n\n\t/**\n\t * Check if this perspective type needs a camera rig\n\t */\n\tprivate needsRig(): boolean {\n\t\treturn this._perspective === Perspectives.ThirdPerson;\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\treturn this.renderer.domElement;\n\t}\n}","import { Vector2, Vector3 } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\n\nexport interface CameraOptions {\n\tperspective?: PerspectiveType;\n\tposition?: Vector3;\n\ttarget?: Vector3;\n\tzoom?: number;\n\tscreenResolution?: Vector2;\n}\n\nexport class CameraWrapper {\n\tcameraRef: ZylemCamera;\n\n\tconstructor(camera: ZylemCamera) {\n\t\tthis.cameraRef = camera;\n\t}\n}\n\nexport function createCamera(options: CameraOptions): CameraWrapper {\n\tconst screenResolution = options.screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\tlet frustumSize = 10;\n\tif (options.perspective === 'fixed-2d') {\n\t\tfrustumSize = options.zoom || 10;\n\t}\n\tconst zylemCamera = new ZylemCamera(options.perspective || 'third-person', screenResolution, frustumSize);\n\n\t// Set initial position and target\n\tzylemCamera.move(options.position || new Vector3(0, 0, 0));\n\tzylemCamera.camera.lookAt(options.target || new Vector3(0, 0, 0));\n\n\treturn new CameraWrapper(zylemCamera);\n}","/**\n * Thruster Behavior Module Index\n * \n * Re-exports all thruster-related components and behaviors.\n */\n\n// Components\nexport {\n\ttype ThrusterMovementComponent,\n\ttype ThrusterInputComponent,\n\ttype ThrusterStateComponent,\n\tcreateThrusterMovementComponent,\n\tcreateThrusterInputComponent,\n\tcreateThrusterStateComponent,\n} from './components';\n\n// FSM\nexport {\n\tThrusterState,\n\tThrusterEvent,\n\tThrusterFSM,\n\ttype ThrusterFSMContext,\n\ttype PlayerInput,\n} from './thruster-fsm';\n\n// Behaviors\nexport {\n\tThrusterMovementBehavior,\n\ttype Behavior,\n\ttype ThrusterEntity,\n} from './thruster-movement.behavior';\n\n// Typed Descriptor (new entity.use() API)\nexport { ThrusterBehavior, type ThrusterBehaviorOptions } from './thruster.descriptor';\n","/**\n * Screen Wrap Behavior Module\n */\n\nexport { ScreenWrapBehavior, type ScreenWrapOptions } from './screen-wrap.descriptor';\nexport { ScreenWrapFSM, ScreenWrapState, ScreenWrapEvent } from './screen-wrap-fsm';\n","/**\n * World Boundary 2D Module\n *\n * Barrel exports for the `world-boundary-2d` behavior and its FSM helpers.\n */\nexport { WorldBoundary2DBehavior } from './world-boundary-2d.descriptor';\n\nexport {\n\tWorldBoundary2DFSM,\n\tcomputeWorldBoundary2DHits,\n\thasAnyWorldBoundary2DHit,\n\ttype WorldBoundary2DHit,\n\ttype WorldBoundary2DHits,\n\ttype WorldBoundary2DPosition,\n\ttype WorldBoundary2DBounds,\n\tWorldBoundary2DState,\n\tWorldBoundary2DEvent,\n} from './world-boundary-2d-fsm';\n\nexport type {\n\tWorldBoundary2DOptions,\n\tWorldBoundary2DHandle,\n} from './world-boundary-2d.descriptor';\n","/**\n * Ricochet 2D Behavior Module\n *\n * Exports FSM, types, and behavior descriptor for 2D ricochet/reflection.\n */\n\n// FSM and types\nexport {\n\tRicochet2DFSM,\n\tRicochet2DState,\n\tRicochet2DEvent,\n\ttype Ricochet2DResult,\n\ttype Ricochet2DCollisionContext,\n} from './ricochet-2d-fsm';\n\n// Behavior descriptor, options, and handle\nexport {\n\tRicochet2DBehavior,\n\ttype Ricochet2DOptions,\n\ttype Ricochet2DHandle,\n} from './ricochet-2d.descriptor';\n\n","/**\n * Movement Sequence 2D Behavior Module\n *\n * Exports FSM, types, and behavior descriptor for 2D movement sequencing.\n */\n\n// FSM and types\nexport {\n\tMovementSequence2DFSM,\n\tMovementSequence2DState,\n\tMovementSequence2DEvent,\n\ttype MovementSequence2DStep,\n\ttype MovementSequence2DMovement,\n\ttype MovementSequence2DProgress,\n\ttype MovementSequence2DCurrentStep,\n} from './movement-sequence-2d-fsm';\n\n// Behavior descriptor, options, and handle\nexport {\n\tMovementSequence2DBehavior,\n\ttype MovementSequence2DOptions,\n\ttype MovementSequence2DHandle,\n} from './movement-sequence-2d.descriptor';\n","import { GameEntity } from '../entities/entity';\nimport { Ricochet2DHandle, Ricochet2DResult } from '../behaviors/ricochet-2d/ricochet-2d.descriptor';\nimport { WorldBoundary2DHandle } from '../behaviors/world-boundary-2d/world-boundary-2d.descriptor';\nimport { MoveableEntity } from '../actions/capabilities/moveable';\n\n/**\n * Coordinator that bridges WorldBoundary2DBehavior and Ricochet2DBehavior.\n * \n * Automatically handles:\n * 1. Checking boundary hits\n * 2. Computing collision normals\n * 3. Requesting ricochet result\n * 4. Applying movement\n */\nexport class BoundaryRicochetCoordinator {\n constructor(\n private entity: GameEntity<any> & MoveableEntity,\n private boundary: WorldBoundary2DHandle,\n private ricochet: Ricochet2DHandle\n ) {}\n\n /**\n * Update loop - call this every frame\n */\n public update(): Ricochet2DResult | null {\n const hits = this.boundary.getLastHits();\n if (!hits) return null;\n\n const anyHit = hits.left || hits.right || hits.top || hits.bottom;\n if (!anyHit) return null;\n\n // Compute collision normal from boundary hits\n let normalX = 0;\n let normalY = 0;\n if (hits.left) normalX = 1;\n if (hits.right) normalX = -1;\n if (hits.bottom) normalY = 1;\n if (hits.top) normalY = -1;\n\n // Compute ricochet result\n return this.ricochet.getRicochet({\n entity: this.entity,\n contact: { normal: { x: normalX, y: normalY } },\n });\n }\n}\n","/**\n * Behaviors Module Index\n *\n * Re-exports all ECS components and behaviors.\n */\n\n// Core Behavior System Interface\nexport type { BehaviorSystem, BehaviorSystemFactory } from './behavior-system';\n\n// Behavior Descriptor Pattern\nexport { defineBehavior } from './behavior-descriptor';\nexport type {\n BehaviorDescriptor,\n BehaviorRef,\n BehaviorHandle,\n DefineBehaviorConfig,\n} from './behavior-descriptor';\n\nexport { useBehavior } from './use-behavior';\n\n// Core ECS Components\nexport {\n type TransformComponent,\n type PhysicsBodyComponent,\n createTransformComponent,\n createPhysicsBodyComponent,\n} from './components';\n\n// Physics Behaviors\nexport { PhysicsStepBehavior } from './physics-step.behavior';\nexport { PhysicsSyncBehavior } from './physics-sync.behavior';\n\n// Thruster Module (components, FSM, and behaviors)\nexport * from './thruster';\n\n// Screen Wrap Module\nexport * from './screen-wrap';\n\n// World Boundary 2D Module\nexport * from './world-boundary-2d';\n\n// Ricochet 2D Module\nexport * from './ricochet-2d';\n\n// Movement Sequence 2D Module\nexport * from './movement-sequence-2d';\n\n// Coordinators\nexport * from '../coordinators/boundary-ricochet.coordinator';\n","import { Color, Vector3 as ThreeVector3 } from 'three';\nimport { Vector3 } from '@dimforge/rapier3d-compat';\n\n// TODO: needs implementations\n/**\n * @deprecated This type is deprecated.\n */\nexport type Vect3 = ThreeVector3 | Vector3;\n\nexport const ZylemBlueColor = new Color('#0333EC');\nexport const ZylemBlue = '#0333EC';\nexport const ZylemBlueTransparent = '#0333ECA0';\nexport const ZylemGoldText = '#DAA420';\n\nexport const Vec0 = new Vector3(0, 0, 0);\nexport const Vec1 = new Vector3(1, 1, 1);","import { Color, Vector3 } from 'three';\nimport { proxy, subscribe } from 'valtio/vanilla';\nimport { BaseEntityInterface, GameEntityInterface } from '../types/entity-types';\nimport { StageStateInterface } from '../types/stage-types';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\nimport { ZylemBlueColor } from '../core/utility/vector';\n\n/**\n * Initial stage state with default values.\n * Exported for use in ZylemStage construction.\n */\nexport const initialStageState = {\n\tbackgroundColor: ZylemBlueColor,\n\tbackgroundImage: null,\n\tbackgroundShader: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard'],\n\t\tp2: ['gamepad-2', 'keyboard'],\n\t},\n\tgravity: new Vector3(0, 0, 0),\n\tvariables: {},\n\tentities: [] as GameEntityInterface[],\n};\n\n/**\n * Stage state proxy for reactive updates.\n */\nconst stageState = proxy({\n\tbackgroundColor: new Color(Color.NAMES.cornflowerblue),\n\tbackgroundImage: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard-1'],\n\t\tp2: ['gamepad-2', 'keyboard-2'],\n\t},\n\tvariables: {},\n\tgravity: new Vector3(0, 0, 0),\n\tentities: [],\n} as StageStateInterface);\n\n// ============================================================\n// Stage state setters (internal use)\n// ============================================================\n\nconst setStageBackgroundColor = (value: Color) => {\n\tstageState.backgroundColor = value;\n};\n\nconst setStageBackgroundImage = (value: string | null) => {\n\tstageState.backgroundImage = value;\n};\n\nconst setEntitiesToStage = (entities: Partial<BaseEntityInterface>[]) => {\n\tstageState.entities = entities;\n};\n\n/** Replace the entire stage variables object (used on stage load). */\nconst setStageVariables = (variables: Record<string, any>) => {\n\tstageState.variables = { ...variables };\n};\n\n/** Reset all stage variables (used on stage unload). */\nconst resetStageVariables = () => {\n\tstageState.variables = {};\n};\n\nconst stageStateToString = (state: StageStateInterface) => {\n\tlet string = `\\n`;\n\tfor (const key in state) {\n\t\tconst value = state[key as keyof StageStateInterface];\n\t\tstring += `${key}:\\n`;\n\t\tif (key === 'entities') {\n\t\t\tfor (const entity of state.entities) {\n\t\t\t\tstring += ` ${entity.uuid}: ${entity.name}\\n`;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tfor (const subKey in value as Record<string, any>) {\n\t\t\t\tconst subValue = value?.[subKey as keyof typeof value];\n\t\t\t\tif (subValue) {\n\t\t\t\t\tstring += ` ${subKey}: ${subValue}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof value === 'string') {\n\t\t\tstring += ` ${key}: ${value}\\n`;\n\t\t}\n\t}\n\treturn string;\n};\n\n// ============================================================\n// Object-scoped variable storage (WeakMap-based)\n// ============================================================\n\n/**\n * WeakMap to store variables keyed by object reference.\n * Variables are automatically garbage collected when the target is collected.\n */\nconst variableStore = new WeakMap<object, Record<string, unknown>>();\n\n/**\n * Separate proxy store for reactivity. We need a regular Map for subscriptions\n * since WeakMap doesn't support iteration/subscriptions.\n */\nconst variableProxyStore = new Map<object, ReturnType<typeof proxy>>();\n\nfunction getOrCreateVariableProxy(target: object): Record<string, unknown> {\n\tlet store = variableProxyStore.get(target) as Record<string, unknown> | undefined;\n\tif (!store) {\n\t\tstore = proxy({});\n\t\tvariableProxyStore.set(target, store);\n\t}\n\treturn store;\n}\n\n/**\n * Set a variable on an object by path.\n * @example setVariable(stage1, 'totalAngle', 0.5)\n * @example setVariable(entity, 'enemy.count', 10)\n */\nexport function setVariable(target: object, path: string, value: unknown): void {\n\tconst store = getOrCreateVariableProxy(target);\n\tsetByPath(store, path, value);\n}\n\n/**\n * Create/initialize a variable with a default value on a target object.\n * Only sets the value if it doesn't already exist.\n * @example createVariable(stage1, 'totalAngle', 0)\n * @example createVariable(entity, 'enemy.count', 10)\n */\nexport function createVariable<T>(target: object, path: string, defaultValue: T): T {\n\tconst store = getOrCreateVariableProxy(target);\n\tconst existing = getByPath<T>(store, path);\n\tif (existing === undefined) {\n\t\tsetByPath(store, path, defaultValue);\n\t\treturn defaultValue;\n\t}\n\treturn existing;\n}\n\n/**\n * Get a variable from an object by path.\n * @example getVariable(stage1, 'totalAngle') // 0.5\n * @example getVariable<number>(entity, 'enemy.count') // 10\n */\nexport function getVariable<T = unknown>(target: object, path: string): T | undefined {\n\tconst store = variableProxyStore.get(target);\n\tif (!store) return undefined;\n\treturn getByPath<T>(store, path);\n}\n\n/**\n * Subscribe to changes on a variable at a specific path for a target object.\n * Returns an unsubscribe function.\n * @example const unsub = onVariableChange(stage1, 'score', (val) => console.log(val));\n */\nexport function onVariableChange<T = unknown>(\n\ttarget: object,\n\tpath: string,\n\tcallback: (value: T) => void\n): () => void {\n\tconst store = getOrCreateVariableProxy(target);\n\tlet previous = getByPath<T>(store, path);\n\treturn subscribe(store, () => {\n\t\tconst current = getByPath<T>(store, path);\n\t\tif (current !== previous) {\n\t\t\tprevious = current;\n\t\t\tcallback(current as T);\n\t\t}\n\t});\n}\n\n/**\n * Subscribe to changes on multiple variable paths for a target object.\n * Callback fires when any of the paths change, receiving all current values.\n * Returns an unsubscribe function.\n * @example const unsub = onVariableChanges(stage1, ['count', 'total'], ([count, total]) => console.log(count, total));\n */\nexport function onVariableChanges<T extends unknown[] = unknown[]>(\n\ttarget: object,\n\tpaths: string[],\n\tcallback: (values: T) => void\n): () => void {\n\tconst store = getOrCreateVariableProxy(target);\n\tlet previousValues = paths.map(p => getByPath(store, p));\n\treturn subscribe(store, () => {\n\t\tconst currentValues = paths.map(p => getByPath(store, p));\n\t\tconst hasChange = currentValues.some((val, i) => val !== previousValues[i]);\n\t\tif (hasChange) {\n\t\t\tpreviousValues = currentValues;\n\t\t\tcallback(currentValues as T);\n\t\t}\n\t});\n}\n\n/**\n * Clear all variables for a target object. Used on stage/entity dispose.\n */\nexport function clearVariables(target: object): void {\n\tvariableProxyStore.delete(target);\n}\n\n// ============================================================\n// Legacy stage variable functions (internal, for stage defaults)\n// ============================================================\n\nconst setStageVariable = (key: string, value: any) => {\n\tstageState.variables[key] = value;\n};\n\nconst getStageVariable = (key: string) => {\n\tif (stageState.variables.hasOwnProperty(key)) {\n\t\treturn stageState.variables[key];\n\t} else {\n\t\tconsole.warn(`Stage variable ${key} not found`);\n\t}\n};\n\nexport {\n\tstageState,\n\t\n\tsetStageBackgroundColor,\n\tsetStageBackgroundImage,\n\t\n\tstageStateToString,\n\tsetStageVariable,\n\tgetStageVariable,\n\tsetStageVariables,\n\tresetStageVariables,\n};","// Core game functionality\nexport { createGame, Game } from '../lib/game/game';\nexport type { ZylemGameConfig } from '../lib/game/game-interfaces';\nexport { gameConfig } from '../lib/game/game-config';\n\nexport { createStage } from '../lib/stage/stage';\nexport { entitySpawner } from '../lib/stage/entity-spawner';\nexport type { StageOptions, LoadingEvent } from '../lib/stage/zylem-stage';\nexport type { StageBlueprint } from '../lib/core/blueprints';\nexport { StageManager, stageState } from '../lib/stage/stage-manager';\n\nexport { vessel } from '../lib/core/vessel';\n\n// Camera\nexport { createCamera } from '../lib/camera/camera';\nexport type { PerspectiveType } from '../lib/camera/perspective';\nexport { Perspectives } from '../lib/camera/perspective';\n\n// Utility types\nexport type { Vect3 } from '../lib/core/utility/vector';\n\n// Entities\nexport { createBox } from '../lib/entities/box';\nexport { createSphere } from '../lib/entities/sphere';\nexport { createSprite } from '../lib/entities/sprite';\nexport { createPlane } from '../lib/entities/plane';\nexport { createZone } from '../lib/entities/zone';\nexport { createActor } from '../lib/entities/actor';\nexport { createText } from '../lib/entities/text';\nexport { createRect } from '../lib/entities/rect';\nexport { createDisk } from '../lib/entities/disk';\nexport { createEntityFactory, type TemplateFactory } from '../lib/entities/entity-factory';\nexport { ZylemBox } from '../lib/entities/box';\n\n// ECS Components & Behaviors (new thruster system)\nexport * from '../lib/behaviors';\n\n// Capabilities\nexport { makeMoveable } from '../lib/actions/capabilities/moveable';\nexport { makeRotatable } from '../lib/actions/capabilities/rotatable';\nexport { makeTransformable } from '../lib/actions/capabilities/transformable';\nexport { rotatable } from '../lib/actions/capabilities/rotatable';\nexport { moveable } from '../lib/actions/capabilities/moveable';\nexport { rotateInDirection } from '../lib/actions/capabilities/rotatable';\nexport { move } from '../lib/actions/capabilities/moveable';\nexport { resetVelocity } from '../lib/actions/capabilities/moveable';\n\n\n// Destruction utilities\n// Destruction utilities\nexport { destroy } from '../lib/entities/destroy';\n\n// Sounds\nexport { ricochetSound, pingPongBeep } from '../lib/sounds';\n\n// External dependencies - these will be in separate vendor chunks\nexport { Howl } from 'howler';\nexport * as THREE from 'three';\nexport * as RAPIER from '@dimforge/rapier3d-compat';\n\n// Update helpers\nexport { globalChange, globalChanges, variableChange, variableChanges } from '../lib/actions/global-change';\n\n// State management - standalone functions\nexport { setGlobal, getGlobal, createGlobal, onGlobalChange, onGlobalChanges, getGlobals, clearGlobalSubscriptions } from '../lib/game/game-state';\nexport { setVariable, getVariable, createVariable, onVariableChange, onVariableChanges } from '../lib/stage/stage-state';\n\n// Debug state - exposed for direct mutation by editor integration\nexport { debugState, setDebugTool, setPaused, type DebugTools } from '../lib/debug/debug-state';\n\n// Web Components\nexport { ZylemGameElement, type ZylemGameState } from '../web-components/zylem-game';\n\n// Lifecycle types\nexport type { SetupContext, UpdateContext } from '../lib/core/base-node-life-cycle';\n\n// Interfaces\nexport type { StageEntity } from '../lib/interfaces/entity';\n\n// Entity type symbols for getEntityByName type inference\nexport { \n\tTEXT_TYPE, SPRITE_TYPE, BOX_TYPE, SPHERE_TYPE, \n\tRECT_TYPE, PLANE_TYPE, ZONE_TYPE, ACTOR_TYPE \n} from '../lib/types/entity-type-map';\n\n// Events\nexport {\n\tEventEmitterDelegate,\n\tzylemEventBus,\n\ttype ZylemEvents,\n\ttype GameEvents,\n\ttype StageEvents,\n\ttype EntityEvents,\n\ttype GameLoadingPayload,\n\ttype StateDispatchPayload,\n\ttype StageConfigPayload,\n\ttype EntityConfigPayload,\n} from '../lib/events';\n\n// Shaders\nexport { fireShader } from '../lib/graphics/shaders/fire.shader';\nexport { starShader } from '../lib/graphics/shaders/star.shader';\nexport { standardShader } from '../lib/graphics/shaders/standard.shader';\nexport { debugShader } from '../lib/graphics/shaders/debug.shader';\nexport { objectVertexShader } from '../lib/graphics/shaders/vertex/object.shader';\nexport type { ZylemShaderObject } from '../lib/graphics/material';\n","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, Mesh, MeshStandardMaterial, Group, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport { UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { EntityAssetLoader } from '../core/entity-asset-loader';\nimport { EntityLoaderDelegate } from './delegates/loader';\nimport { Vec3 } from '../core/vector';\nimport { AnimationDelegate, AnimationOptions } from './delegates/animation';\nimport { MaterialOptions } from '../graphics/material';\nimport { DebugInfoProvider } from './delegates/debug';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { commonDefaults } from './common';\nimport { standardShader } from '~/api/main';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport type CollisionShapeType = 'capsule' | 'model';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tcollision: {\n\t\tstatic: false,\n\t\tsize: new Vector3(0.5, 0.5, 0.5),\n\t\tposition: new Vector3(0, 0, 0),\n\t},\n\tmaterial: {\n\t\tshader: standardShader\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Group | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tif (this.collisionShape === 'model') {\n\t\t\treturn this.createColliderFromModel(this.objectModel, options);\n\t\t}\n\t\treturn this.createCapsuleCollider(options);\n\t}\n\n\t/**\n\t * Create a capsule collider based on size options (character controller style).\n\t */\n\tprivate createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\t\tconst halfHeight = ((size as any).y || 1);\n\t\tconst radius = Math.max((size as any).x || 0.5, (size as any).z || 0.5);\n\t\tlet colliderDesc = ColliderDesc.capsule(halfHeight, radius);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, halfHeight + radius, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n\n\t/**\n\t * Create a collider based on model geometry (works with Mesh and SkinnedMesh).\n\t * If collision.size and collision.position are provided, use those instead of computing from geometry.\n\t */\n\tprivate createColliderFromModel(objectModel: Group | null, options: ZylemActorOptions): ColliderDesc {\n\t\tconst collisionSize = options.collision?.size;\n\t\tconst collisionPosition = options.collision?.position;\n\n\t\t// If user provided explicit size, use that instead of computing from model\n\t\tif (collisionSize) {\n\t\t\tconst halfWidth = (collisionSize as any).x / 2;\n\t\t\tconst halfHeight = (collisionSize as any).y / 2;\n\t\t\tconst halfDepth = (collisionSize as any).z / 2;\n\n\t\t\tlet colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\t\t\tcolliderDesc.setSensor(false);\n\n\t\t\t// Use user-provided position or default to center\n\t\t\tconst posX = collisionPosition ? (collisionPosition as any).x : 0;\n\t\t\tconst posY = collisionPosition ? (collisionPosition as any).y : halfHeight;\n\t\t\tconst posZ = collisionPosition ? (collisionPosition as any).z : 0;\n\t\t\tcolliderDesc.setTranslation(posX, posY, posZ);\n\t\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\t\treturn colliderDesc;\n\t\t}\n\n\t\t// Fall back to computing from model geometry\n\t\tif (!objectModel) return this.createCapsuleCollider(options);\n\n\t\t// Find first Mesh (SkinnedMesh or regular Mesh)\n\t\tlet foundGeometry: BufferGeometry | null = null;\n\t\tobjectModel.traverse((child) => {\n\t\t\tif (!foundGeometry && (child as any).isMesh) {\n\t\t\t\tfoundGeometry = (child as Mesh).geometry as BufferGeometry;\n\t\t\t}\n\t\t});\n\n\t\tif (!foundGeometry) return this.createCapsuleCollider(options);\n\n\t\tconst geometry: BufferGeometry = foundGeometry;\n\t\tgeometry.computeBoundingBox();\n\t\tconst box = geometry.boundingBox;\n\t\tif (!box) return this.createCapsuleCollider(options);\n\n\t\tconst height = box.max.y - box.min.y;\n\t\tconst width = box.max.x - box.min.x;\n\t\tconst depth = box.max.z - box.min.z;\n\n\t\t// Create box collider based on mesh bounds\n\t\tlet colliderDesc = ColliderDesc.cuboid(width / 2, height / 2, depth / 2);\n\t\tcolliderDesc.setSensor(false);\n\t\t// Position collider at center of model\n\t\tconst centerY = (box.max.y + box.min.y) / 2;\n\t\tcolliderDesc.setTranslation(0, centerY, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n}\n\nclass ActorBuilder extends EntityBuilder<ZylemActor, ZylemActorOptions> {\n\tprotected createEntity(options: Partial<ZylemActorOptions>): ZylemActor {\n\t\treturn new ZylemActor(options);\n\t}\n}\n\nexport const ACTOR_TYPE = Symbol('Actor');\n\nexport class ZylemActor extends GameEntity<ZylemActorOptions> implements EntityLoaderDelegate, DebugInfoProvider {\n\tstatic type = ACTOR_TYPE;\n\n\tprivate _object: Object3D | null = null;\n\tprivate _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\n\tcontrolledRotation: boolean = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\t// Add actor-specific update to the lifecycle callbacks\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\t/**\n\t * Initiates model and animation loading in background (deferred).\n\t * Call returns immediately; assets will be ready on subsequent updates.\n\t */\n\tload(): void {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\t// Start async loading in background\n\t\tthis.loadModelsDeferred();\n\t}\n\n\t/**\n\t * Returns current data synchronously.\n\t * May return null values if loading is still in progress.\n\t */\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\t/**\n\t * Clean up actor resources including animations, models, and groups\n\t */\n\tactorDestroy(): void {\n\t\t// Stop and dispose animation delegate\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\t// Dispose geometries and materials from loaded object\n\t\tif (this._object) {\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tconst mesh = child as SkinnedMesh;\n\t\t\t\t\tmesh.geometry?.dispose();\n\t\t\t\t\tif (Array.isArray(mesh.material)) {\n\t\t\t\t\t\tmesh.material.forEach(m => m.dispose());\n\t\t\t\t\t} else if (mesh.material) {\n\t\t\t\t\t\tmesh.material.dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._object = null;\n\t\t}\n\n\t\t// Clear group reference\n\t\tif (this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = null as any;\n\t\t}\n\n\t\t// Clear file name references\n\t\tthis._modelFileNames = [];\n\t}\n\n\t/**\n\t * Deferred loading - starts async load and updates entity when complete.\n\t * Called by synchronous load() method.\n\t */\n\tprivate loadModelsDeferred(): void {\n\t\tif (this._modelFileNames.length === 0) return;\n\n\t\t// Emit loading started event\n\t\tthis.dispatch('entity:model:loading', {\n\t\t\tentityId: this.uuid,\n\t\t\tfiles: this._modelFileNames\n\t\t});\n\n\t\tconst promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tPromise.all(promises).then(results => {\n\t\t\tif (results[0]?.object) {\n\t\t\t\tthis._object = results[0].object;\n\t\t\t}\n\t\t\t// Count meshes for the loaded event\n\t\t\tlet meshCount = 0;\n\t\t\tif (this._object) {\n\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\tif ((child as any).isMesh) meshCount++;\n\t\t\t\t});\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.attach(this._object);\n\t\t\t\tthis.group.scale.set(\n\t\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\t\tthis.options.scale?.z || 1\n\t\t\t\t);\n\n\t\t\t\t// Apply material overrides if specified\n\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t// Load animations after model is ready\n\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\tthis._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Emit model loaded event\n\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\tentityId: this.uuid,\n\t\t\t\tsuccess: !!this._object,\n\t\t\t\tmeshCount\n\t\t\t});\n\t\t});\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\t/**\n\t * Apply material overrides from options to all meshes in the loaded model.\n\t * Only applies if material options are explicitly specified (not just defaults).\n\t */\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\t// Only apply if user specified material options beyond defaults\n\t\tif (!materialOptions || (!materialOptions.color && !materialOptions.path)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) return;\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif ((child as any).isMesh) {\n\t\t\t\tconst mesh = child as Mesh;\n\t\t\t\tif (materialOptions.color) {\n\t\t\t\t\t// Create new material with the specified color\n\t\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\t\tfog: true,\n\t\t\t\t\t});\n\t\t\t\t\tmesh.castShadow = true;\n\t\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\t\tmesh.material = newMaterial;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\t/**\n\t * Provide custom debug information for the actor\n\t * This will be merged with the default debug information\n\t */\n\tgetDebugInfo(): Record<string, any> {\n\t\tconst debugInfo: Record<string, any> = {\n\t\t\ttype: 'Actor',\n\t\t\tmodels: this._modelFileNames.length > 0 ? this._modelFileNames : 'none',\n\t\t\tmodelLoaded: !!this._object,\n\t\t\tscale: this.options.scale ?\n\t\t\t\t`${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` :\n\t\t\t\t'1, 1, 1',\n\t\t};\n\n\t\t// Add animation info if available\n\t\tif (this._animationDelegate) {\n\t\t\tdebugInfo.currentAnimation = this._animationDelegate.currentAnimationKey || 'none';\n\t\t\tdebugInfo.animationsCount = this.options.animations?.length || 0;\n\t\t}\n\n\t\t// Add mesh info if model is loaded\n\t\tif (this._object) {\n\t\t\tlet meshCount = 0;\n\t\t\tlet vertexCount = 0;\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tmeshCount++;\n\t\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\t\tif (geometry && geometry.attributes.position) {\n\t\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tdebugInfo.meshCount = meshCount;\n\t\t\tdebugInfo.vertexCount = vertexCount;\n\t\t}\n\n\t\treturn debugInfo;\n\t}\n}\n\ntype ActorOptions = BaseNode | ZylemActorOptions;\n\nexport function createActor(...args: Array<ActorOptions>): ZylemActor {\n\treturn createEntity<ZylemActor, ZylemActorOptions>({\n\t\targs,\n\t\tdefaultConfig: actorDefaults,\n\t\tEntityClass: ZylemActor,\n\t\tBuilderClass: ActorBuilder,\n\t\tCollisionBuilderClass: ActorCollisionBuilder,\n\t\tentityType: ZylemActor.type\n\t});\n}","import { Vector3 } from 'three';\nimport RAPIER, { World } from '@dimforge/rapier3d-compat';\n\nimport { Entity } from '../interfaces/entity';\nimport { state } from '../game/game-state';\nimport { UpdateContext } from '../core/base-node-life-cycle';\nimport { ZylemActor } from '../entities/actor';\nimport { GameEntity } from '../entities/entity';\n\n/**\n * Interface for entities that handle collision events.\n */\nexport interface CollisionHandlerDelegate {\n\thandlePostCollision(params: any): boolean;\n\thandleIntersectionEvent(params: any): void;\n}\n\n/**\n * Type guard to check if an object implements CollisionHandlerDelegate.\n */\nexport function isCollisionHandlerDelegate(obj: any): obj is CollisionHandlerDelegate {\n\treturn typeof obj?.handlePostCollision === \"function\" && typeof obj?.handleIntersectionEvent === \"function\";\n}\n\nexport class ZylemWorld implements Entity<ZylemWorld> {\n\ttype = 'World';\n\tworld: World;\n\tcollisionMap: Map<string, GameEntity<any>> = new Map();\n\tcollisionBehaviorMap: Map<string, GameEntity<any>> = new Map();\n\t_removalMap: Map<string, GameEntity<any>> = new Map();\n\n\tstatic async loadPhysics(gravity: Vector3) {\n\t\tawait RAPIER.init();\n\t\tconst physicsWorld = new RAPIER.World(gravity);\n\t\treturn physicsWorld;\n\t}\n\n\tconstructor(world: World) {\n\t\tthis.world = world;\n\t}\n\n\taddEntity(entity: any) {\n\t\tconst rigidBody = this.world.createRigidBody(entity.bodyDesc);\n\t\tentity.body = rigidBody;\n\t\t// TODO: consider passing in more specific data\n\t\tentity.body.userData = { uuid: entity.uuid, ref: entity };\n\t\tif (this.world.gravity.x === 0 && this.world.gravity.y === 0 && this.world.gravity.z === 0) {\n\t\t\tentity.body.lockTranslations(true, true);\n\t\t\tentity.body.lockRotations(true, true);\n\t\t}\n\t\tconst collider = this.world.createCollider(entity.colliderDesc, entity.body);\n\t\tentity.collider = collider;\n\t\tif (entity.controlledRotation || entity instanceof ZylemActor) {\n\t\t\tentity.body.lockRotations(true, true);\n\t\t\tentity.characterController = this.world.createCharacterController(0.01);\n\t\t\tentity.characterController.setMaxSlopeClimbAngle(45 * Math.PI / 180);\n\t\t\tentity.characterController.setMinSlopeSlideAngle(30 * Math.PI / 180);\n\t\t\tentity.characterController.enableSnapToGround(0.01);\n\t\t\tentity.characterController.setSlideEnabled(true);\n\t\t\tentity.characterController.setApplyImpulsesToDynamicBodies(true);\n\t\t\tentity.characterController.setCharacterMass(1);\n\t\t}\n\t\tthis.collisionMap.set(entity.uuid, entity);\n\t}\n\n\tsetForRemoval(entity: any) {\n\t\tif (entity.body) {\n\t\t\tthis._removalMap.set(entity.uuid, entity);\n\t\t}\n\t}\n\n\tdestroyEntity(entity: GameEntity<any>) {\n\t\tif (entity.collider) {\n\t\t\tthis.world.removeCollider(entity.collider, true);\n\t\t}\n\t\tif (entity.body) {\n\t\t\tthis.world.removeRigidBody(entity.body);\n\t\t\tthis.collisionMap.delete(entity.uuid);\n\t\t\tthis._removalMap.delete(entity.uuid);\n\t\t}\n\t}\n\n\tsetup() { }\n\n\tupdate(params: UpdateContext<any>) {\n\t\tconst { delta } = params;\n\t\tif (!this.world) {\n\t\t\treturn;\n\t\t}\n\t\tthis.updateColliders(delta);\n\t\tthis.updatePostCollisionBehaviors(delta);\n\t\tthis.world.step();\n\t}\n\n\tupdatePostCollisionBehaviors(delta: number) {\n\t\tconst dictionaryRef = this.collisionBehaviorMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as any;\n\t\t\tif (!isCollisionHandlerDelegate(gameEntity)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst active = gameEntity.handlePostCollision({ entity: gameEntity, delta });\n\t\t\tif (!active) {\n\t\t\t\tthis.collisionBehaviorMap.delete(id);\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateColliders(delta: number) {\n\t\tconst dictionaryRef = this.collisionMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as GameEntity<any>;\n\t\t\tif (!gameEntity.body) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this._removalMap.get(gameEntity.uuid)) {\n\t\t\t\tthis.destroyEntity(gameEntity);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.world.contactsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\t\tif (!otherCollider) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\t\tif (!entity) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (gameEntity._collision) {\n\t\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.world.intersectionsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\t\tif (!otherCollider) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\t\tif (!entity) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (gameEntity._collision) {\n\t\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t\t}\n\t\t\t\tif (isCollisionHandlerDelegate(entity)) {\n\t\t\t\t\tentity.handleIntersectionEvent({ entity, other: gameEntity, delta });\n\t\t\t\t\tthis.collisionBehaviorMap.set(uuid, entity);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\ttry {\n\t\t\tfor (const [, entity] of this.collisionMap) {\n\t\t\t\ttry { this.destroyEntity(entity); } catch { /* noop */ }\n\t\t\t}\n\t\t\tthis.collisionMap.clear();\n\t\t\tthis.collisionBehaviorMap.clear();\n\t\t\tthis._removalMap.clear();\n\t\t\t// @ts-ignore\n\t\t\tthis.world = undefined as any;\n\t\t} catch { /* noop */ }\n\t}\n\n}","import {\n\tScene,\n\tColor,\n\tAmbientLight,\n\tDirectionalLight,\n\tObject3D,\n\tVector3,\n\tGridHelper,\n\tSphereGeometry,\n\tBoxGeometry,\n\tShaderMaterial,\n\tMesh,\n\tBackSide\n} from 'three';\nimport { Entity, LifecycleFunction } from '../interfaces/entity';\nimport { GameEntity } from '../entities/entity';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { debugState } from '../debug/debug-state';\nimport { SetupFunction } from '../core/base-node-life-cycle';\nimport { getGlobals } from '../game/game-state';\nimport { assetManager } from '../core/asset-manager';\nimport { ZylemShaderObject } from './material';\n\ninterface SceneState {\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader?: ZylemShaderObject | null;\n}\n\nexport class ZylemScene implements Entity<ZylemScene> {\n\tpublic type = 'Scene';\n\n\t_setup?: SetupFunction<ZylemScene>;\n\tscene!: Scene;\n\tzylemCamera!: ZylemCamera;\n\tcontainerElement: HTMLElement | null = null;\n\tupdate: LifecycleFunction<ZylemScene> = () => { };\n\t_collision?: ((entity: any, other: any, globals?: any) => void) | undefined;\n\t_destroy?: ((globals?: any) => void) | undefined;\n\tname?: string | undefined;\n\ttag?: Set<string> | undefined;\n\n\t// Skybox for background shaders\n\tprivate skyboxMaterial: ShaderMaterial | null = null;\n\n\tconstructor(id: string, camera: ZylemCamera, state: SceneState) {\n\t\tconst scene = new Scene();\n\t\tconst isColor = state.backgroundColor instanceof Color;\n\t\tconst backgroundColor = (isColor) ? state.backgroundColor : new Color(state.backgroundColor);\n\t\tscene.background = backgroundColor as Color;\n\t\t\n\t\tconsole.log('ZylemScene state.backgroundShader:', state.backgroundShader);\n\t\t\n\t\tif (state.backgroundShader) {\n\t\t\tthis.setupBackgroundShader(scene, state.backgroundShader);\n\t\t} else if (state.backgroundImage) {\n\t\t\t// Load background image asynchronously via asset manager\n\t\t\tassetManager.loadTexture(state.backgroundImage).then(texture => {\n\t\t\t\tscene.background = texture;\n\t\t\t});\n\t\t}\n\n\t\tthis.scene = scene;\n\t\tthis.zylemCamera = camera;\n\n\t\tthis.setupLighting(scene);\n\t\tthis.setupCamera(scene, camera);\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugScene();\n\t\t}\n\t}\n\n\t/**\n\t * Create a large inverted box with the shader for skybox effect\n\t * Uses the pos.xyww trick to ensure skybox is always at maximum depth\n\t */\n\tprivate setupBackgroundShader(scene: Scene, shader: ZylemShaderObject) {\n\t\t// Clear the solid color background\n\t\tscene.background = null;\n\n\t\t// Skybox vertex shader with depth trick (pos.xyww ensures depth = 1.0)\n\t\tconst skyboxVertexShader = `\n\t\t\tvarying vec2 vUv;\n\t\t\tvarying vec3 vWorldPosition;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvUv = uv;\n\t\t\t\tvec4 worldPosition = modelMatrix * vec4(position, 1.0);\n\t\t\t\tvWorldPosition = worldPosition.xyz;\n\t\t\t\tvec4 pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n\t\t\t\tgl_Position = pos.xyww; // Ensures depth is always 1.0 (farthest)\n\t\t\t}\n\t\t`;\n\n\t\t// Create shader material with skybox-specific settings\n\t\tthis.skyboxMaterial = new ShaderMaterial({\n\t\t\tvertexShader: skyboxVertexShader,\n\t\t\tfragmentShader: shader.fragment,\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0.0 },\n\t\t\t},\n\t\t\tside: BackSide, // Render on inside of geometry\n\t\t\tdepthWrite: false, // Don't write to depth buffer\n\t\t\tdepthTest: true, // But do test depth\n\t\t});\n\n\t\t// Use BoxGeometry for skybox (like the CodePen example)\n\t\tconst geometry = new BoxGeometry(1, 1, 1);\n\t\tconst skybox = new Mesh(geometry, this.skyboxMaterial);\n\t\tskybox.scale.setScalar(100000); // Scale up significantly\n\t\tskybox.frustumCulled = false; // Always render\n\t\tscene.add(skybox);\n\t\t\n\t\tconsole.log('Skybox created with pos.xyww technique');\n\t}\n\n\tsetup() {\n\t\tif (this._setup) {\n\t\t\tthis._setup({ me: this, camera: this.zylemCamera, globals: getGlobals() });\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.zylemCamera && (this.zylemCamera as any).destroy) {\n\t\t\t(this.zylemCamera as any).destroy();\n\t\t}\n\t\tif (this.skyboxMaterial) {\n\t\t\tthis.skyboxMaterial.dispose();\n\t\t}\n\t\tif (this.scene) {\n\t\t\tthis.scene.traverse((obj: any) => {\n\t\t\t\tif (obj.geometry) {\n\t\t\t\t\tobj.geometry.dispose?.();\n\t\t\t\t}\n\t\t\t\tif (obj.material) {\n\t\t\t\t\tif (Array.isArray(obj.material)) {\n\t\t\t\t\t\tobj.material.forEach((m: any) => m.dispose?.());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tobj.material.dispose?.();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\t/**\n\t * Setup camera with the scene\n\t */\n\tsetupCamera(scene: Scene, camera: ZylemCamera) {\n\t\t// Add camera rig or camera directly to scene\n\t\tif (camera.cameraRig) {\n\t\t\tscene.add(camera.cameraRig);\n\t\t} else {\n\t\t\tscene.add(camera.camera as Object3D);\n\t\t}\n\t\t// Camera handles its own setup now\n\t\tcamera.setup(scene);\n\t}\n\n\t/**\n\t * Setup scene lighting\n\t */\n\tsetupLighting(scene: Scene) {\n\t\tconst ambientLight = new AmbientLight(0xffffff, 2);\n\t\tscene.add(ambientLight);\n\n\t\tconst directionalLight = new DirectionalLight(0xffffff, 2);\n\t\tdirectionalLight.name = 'Light';\n\t\tdirectionalLight.position.set(0, 100, 0);\n\t\tdirectionalLight.castShadow = true;\n\t\tdirectionalLight.shadow.camera.near = 0.1;\n\t\tdirectionalLight.shadow.camera.far = 2000;\n\t\tdirectionalLight.shadow.camera.left = -100;\n\t\tdirectionalLight.shadow.camera.right = 100;\n\t\tdirectionalLight.shadow.camera.top = 100;\n\t\tdirectionalLight.shadow.camera.bottom = -100;\n\t\tdirectionalLight.shadow.mapSize.width = 2048;\n\t\tdirectionalLight.shadow.mapSize.height = 2048;\n\t\tscene.add(directionalLight);\n\t}\n\n\t/**\n\t * Update renderer size - delegates to camera\n\t */\n\tupdateRenderer(width: number, height: number) {\n\t\tthis.zylemCamera.resize(width, height);\n\t}\n\n\t/**\n\t * Add object to scene\n\t */\n\tadd(object: Object3D, position: Vector3 = new Vector3(0, 0, 0)) {\n\t\tobject.position.set(position.x, position.y, position.z);\n\t\tthis.scene.add(object);\n\t}\n\n\t/**\n\t * Add game entity to scene\n\t */\n\taddEntity(entity: GameEntity<any>) {\n\t\tif (entity.group) {\n\t\t\tthis.add(entity.group, entity.options.position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, entity.options.position);\n\t\t}\n\t}\n\n\t/**\n\t * Add an entity's group or mesh to the scene (for late-loaded models).\n\t * Uses entity's current body position if physics is active.\n\t */\n\taddEntityGroup(entity: GameEntity<any>): void {\n\t\tconst position = entity.body\n\t\t\t? new Vector3(\n\t\t\t\tentity.body.translation().x,\n\t\t\t\tentity.body.translation().y,\n\t\t\t\tentity.body.translation().z\n\t\t\t )\n\t\t\t: entity.options.position;\n\n\t\tif (entity.group) {\n\t\t\tthis.add(entity.group, position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, position);\n\t\t}\n\t}\n\n\t/**\n\t * Add debug helpers to scene\n\t */\n\tdebugScene() {\n\t\tconst size = 1000;\n\t\tconst divisions = 100;\n\n\t\tconst gridHelper = new GridHelper(size, divisions);\n\t\tthis.scene.add(gridHelper);\n\t}\n\n\t/**\n\t * Update skybox shader uniforms\n\t */\n\tupdateSkybox(delta: number) {\n\t\tif (this.skyboxMaterial?.uniforms?.iTime) {\n\t\t\tthis.skyboxMaterial.uniforms.iTime.value += delta;\n\t\t}\n\t}\n}","import { DestroyContext, DestroyFunction, SetupContext, SetupFunction, UpdateContext, UpdateFunction } from './base-node-life-cycle';\n\n/**\n * Provides BaseNode-like lifecycle without ECS/children. Consumers implement\n * the protected hooks and may assign public setup/update/destroy callbacks.\n */\nexport abstract class LifeCycleBase<TSelf> {\n\tupdate: UpdateFunction<TSelf> = () => { };\n\tsetup: SetupFunction<TSelf> = () => { };\n\tdestroy: DestroyFunction<TSelf> = () => { };\n\n\tprotected abstract _setup(context: SetupContext<TSelf>): void;\n\tprotected abstract _update(context: UpdateContext<TSelf>): void;\n\tprotected abstract _destroy(context: DestroyContext<TSelf>): void;\n\n\tnodeSetup(context: SetupContext<TSelf>) {\n\t\tif (typeof (this as any)._setup === 'function') {\n\t\t\tthis._setup(context);\n\t\t}\n\t\tif (this.setup) {\n\t\t\tthis.setup(context);\n\t\t}\n\t}\n\n\tnodeUpdate(context: UpdateContext<TSelf>) {\n\t\tif (typeof (this as any)._update === 'function') {\n\t\t\tthis._update(context);\n\t\t}\n\t\tif (this.update) {\n\t\t\tthis.update(context);\n\t\t}\n\t}\n\n\tnodeDestroy(context: DestroyContext<TSelf>) {\n\t\tif (this.destroy) {\n\t\t\tthis.destroy(context);\n\t\t}\n\t\tif (typeof (this as any)._destroy === 'function') {\n\t\t\tthis._destroy(context);\n\t\t}\n\t}\n}\n\n\n","import {\n\tBox3,\n\tBoxGeometry,\n\tColor,\n\tEdgesGeometry,\n\tGroup,\n\tLineBasicMaterial,\n\tLineSegments,\n\tMesh,\n\tMeshBasicMaterial,\n\tObject3D,\n\tScene,\n\tVector3,\n} from 'three';\n\n/**\n * Debug overlay that displays an axis-aligned bounding box around a target Object3D.\n * Shows a semi-transparent fill plus a wireframe outline. Intended for SELECT/DELETE tools.\n */\nexport class DebugEntityCursor {\n\tprivate scene: Scene;\n\tprivate container: Group;\n\tprivate fillMesh: Mesh;\n\tprivate edgeLines: LineSegments;\n\tprivate currentColor: Color = new Color(0x00ff00);\n\tprivate bbox: Box3 = new Box3();\n\tprivate size: Vector3 = new Vector3();\n\tprivate center: Vector3 = new Vector3();\n\n\tconstructor(scene: Scene) {\n\t\tthis.scene = scene;\n\n\t\tconst initialGeometry = new BoxGeometry(1, 1, 1);\n\n\t\tthis.fillMesh = new Mesh(\n\t\t\tinitialGeometry,\n\t\t\tnew MeshBasicMaterial({\n\t\t\t\tcolor: this.currentColor,\n\t\t\t\ttransparent: true,\n\t\t\t\topacity: 0.12,\n\t\t\t\tdepthWrite: false,\n\t\t\t})\n\t\t);\n\n\t\tconst edges = new EdgesGeometry(initialGeometry);\n\t\tthis.edgeLines = new LineSegments(\n\t\t\tedges,\n\t\t\tnew LineBasicMaterial({ color: this.currentColor, linewidth: 1 })\n\t\t);\n\n\t\tthis.container = new Group();\n\t\tthis.container.name = 'DebugEntityCursor';\n\t\tthis.container.add(this.fillMesh);\n\t\tthis.container.add(this.edgeLines);\n\t\tthis.container.visible = false;\n\n\t\tthis.scene.add(this.container);\n\t}\n\n\tsetColor(color: Color | number): void {\n\t\tthis.currentColor.set(color as any);\n\t\t(this.fillMesh.material as MeshBasicMaterial).color.set(this.currentColor);\n\t\t(this.edgeLines.material as LineBasicMaterial).color.set(this.currentColor);\n\t}\n\n\t/**\n\t * Update the cursor to enclose the provided Object3D using a world-space AABB.\n\t */\n\tupdateFromObject(object: Object3D | null | undefined): void {\n\t\tif (!object) {\n\t\t\tthis.hide();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.bbox.setFromObject(object);\n\t\tif (!isFinite(this.bbox.min.x) || !isFinite(this.bbox.max.x)) {\n\t\t\tthis.hide();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.bbox.getSize(this.size);\n\t\tthis.bbox.getCenter(this.center);\n\n\t\tconst newGeom = new BoxGeometry(\n\t\t\tMath.max(this.size.x, 1e-6),\n\t\t\tMath.max(this.size.y, 1e-6),\n\t\t\tMath.max(this.size.z, 1e-6)\n\t\t);\n\t\tthis.fillMesh.geometry.dispose();\n\t\tthis.fillMesh.geometry = newGeom;\n\n\t\tconst newEdges = new EdgesGeometry(newGeom);\n\t\tthis.edgeLines.geometry.dispose();\n\t\tthis.edgeLines.geometry = newEdges;\n\n\t\tthis.container.position.copy(this.center);\n\t\tthis.container.visible = true;\n\t}\n\n\thide(): void {\n\t\tthis.container.visible = false;\n\t}\n\n\tdispose(): void {\n\t\tthis.scene.remove(this.container);\n\t\tthis.fillMesh.geometry.dispose();\n\t\t(this.fillMesh.material as MeshBasicMaterial).dispose();\n\t\tthis.edgeLines.geometry.dispose();\n\t\t(this.edgeLines.material as LineBasicMaterial).dispose();\n\t}\n}\n\n\n","import { Ray, RayColliderToi } from '@dimforge/rapier3d-compat';\nimport { BufferAttribute, BufferGeometry, LineBasicMaterial, LineSegments, Raycaster, Vector2, Vector3 } from 'three';\nimport { ZylemStage } from './zylem-stage';\nimport { debugState, DebugTools, getDebugTool, getHoveredEntity, resetHoveredEntity, setHoveredEntity, setSelectedEntity } from '../debug/debug-state';\nimport { DebugEntityCursor } from './debug-entity-cursor';\n\nexport type AddEntityFactory = (params: { position: Vector3; normal?: Vector3 }) => Promise<any> | any;\n\nexport interface StageDebugDelegateOptions {\n\tmaxRayDistance?: number;\n\taddEntityFactory?: AddEntityFactory | null;\n}\n\nconst SELECT_TOOL_COLOR = 0x22ff22;\nconst DELETE_TOOL_COLOR = 0xff3333;\n\nexport class StageDebugDelegate {\n\tprivate stage: ZylemStage;\n\tprivate options: Required<StageDebugDelegateOptions>;\n\tprivate mouseNdc: Vector2 = new Vector2(-2, -2);\n\tprivate raycaster: Raycaster = new Raycaster();\n\tprivate isMouseDown = false;\n\tprivate disposeFns: Array<() => void> = [];\n\tprivate debugCursor: DebugEntityCursor | null = null;\n\tprivate debugLines: LineSegments | null = null;\n\n\tconstructor(stage: ZylemStage, options?: StageDebugDelegateOptions) {\n\t\tthis.stage = stage;\n\t\tthis.options = {\n\t\t\tmaxRayDistance: options?.maxRayDistance ?? 5_000,\n\t\t\taddEntityFactory: options?.addEntityFactory ?? null,\n\t\t};\n\t\tthis.attachDomListeners();\n\t}\n\n\tprivate initDebugVisuals(): void {\n\t\tif (this.debugLines || !this.stage.scene) return;\n\n\t\tthis.debugLines = new LineSegments(\n\t\t\tnew BufferGeometry(),\n\t\t\tnew LineBasicMaterial({ vertexColors: true })\n\t\t);\n\t\tthis.stage.scene.scene.add(this.debugLines);\n\t\tthis.debugLines.visible = true;\n\n\t\tthis.debugCursor = new DebugEntityCursor(this.stage.scene.scene);\n\t}\n\n\tprivate disposeDebugVisuals(): void {\n\t\tif (this.debugLines && this.stage.scene) {\n\t\t\tthis.stage.scene.scene.remove(this.debugLines);\n\t\t\tthis.debugLines.geometry.dispose();\n\t\t\t(this.debugLines.material as LineBasicMaterial).dispose();\n\t\t\tthis.debugLines = null;\n\t\t}\n\t\tthis.debugCursor?.dispose();\n\t\tthis.debugCursor = null;\n\t}\n\n\tupdate(): void {\n\t\tif (!debugState.enabled) {\n\t\t\tif (this.debugLines) {\n\t\t\t\tthis.disposeDebugVisuals();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.stage.scene || !this.stage.world || !this.stage.cameraRef) return;\n\n\t\t// Initialize visuals if not already created\n\t\tif (!this.debugLines) {\n\t\t\tthis.initDebugVisuals();\n\t\t}\n\n\t\tconst { world, cameraRef } = this.stage;\n\n\t\tif (this.debugLines) {\n\t\t\tconst { vertices, colors } = world.world.debugRender();\n\t\t\tthis.debugLines.geometry.setAttribute('position', new BufferAttribute(vertices, 3));\n\t\t\tthis.debugLines.geometry.setAttribute('color', new BufferAttribute(colors, 4));\n\t\t}\n\t\tconst tool = getDebugTool();\n\t\tconst isCursorTool = tool === 'select' || tool === 'delete';\n\n\t\tthis.raycaster.setFromCamera(this.mouseNdc, cameraRef.camera);\n\t\tconst origin = this.raycaster.ray.origin.clone();\n\t\tconst direction = this.raycaster.ray.direction.clone().normalize();\n\n\t\tconst rapierRay = new Ray(\n\t\t\t{ x: origin.x, y: origin.y, z: origin.z },\n\t\t\t{ x: direction.x, y: direction.y, z: direction.z },\n\t\t);\n\t\tconst hit: RayColliderToi | null = world.world.castRay(rapierRay, this.options.maxRayDistance, true);\n\n\t\tif (hit && isCursorTool) {\n\t\t\t// @ts-ignore - access compat object's parent userData mapping back to GameEntity\n\t\t\tconst rigidBody = hit.collider?._parent;\n\t\t\tconst hoveredUuid: string | undefined = rigidBody?.userData?.uuid;\n\t\t\tif (hoveredUuid) {\n\t\t\t\tconst entity = this.stage._debugMap.get(hoveredUuid);\n\t\t\t\tif (entity) setHoveredEntity(entity as any);\n\t\t\t} else {\n\t\t\t\tresetHoveredEntity();\n\t\t\t}\n\n\t\t\tif (this.isMouseDown) {\n\t\t\t\tthis.handleActionOnHit(hoveredUuid ?? null, origin, direction, hit.toi);\n\t\t\t}\n\t\t}\n\t\tthis.isMouseDown = false;\n\n\t\tconst hoveredUuid = getHoveredEntity();\n\t\tif (!hoveredUuid) {\n\t\t\tthis.debugCursor?.hide();\n\t\t\treturn;\n\t\t}\n\t\tconst hoveredEntity: any = this.stage._debugMap.get(`${hoveredUuid}`);\n\t\tconst targetObject = hoveredEntity?.group ?? hoveredEntity?.mesh ?? null;\n\t\tif (!targetObject) {\n\t\t\tthis.debugCursor?.hide();\n\t\t\treturn;\n\t\t}\n\t\tswitch (tool) {\n\t\t\tcase 'select':\n\t\t\t\tthis.debugCursor?.setColor(SELECT_TOOL_COLOR);\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tthis.debugCursor?.setColor(DELETE_TOOL_COLOR);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.debugCursor?.setColor(0xffffff);\n\t\t\t\tbreak;\n\t\t}\n\t\tthis.debugCursor?.updateFromObject(targetObject);\n\t}\n\n\tdispose(): void {\n\t\tthis.disposeFns.forEach((fn) => fn());\n\t\tthis.disposeFns = [];\n\t\tthis.disposeDebugVisuals();\n\t}\n\n\tprivate handleActionOnHit(hoveredUuid: string | null, origin: Vector3, direction: Vector3, toi: number) {\n\t\tconst tool = getDebugTool();\n\t\tswitch (tool) {\n\t\t\tcase 'select': {\n\t\t\t\tif (hoveredUuid) {\n\t\t\t\t\tconst entity = this.stage._debugMap.get(hoveredUuid);\n\t\t\t\t\tif (entity) setSelectedEntity(entity as any);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'delete': {\n\t\t\t\tif (hoveredUuid) {\n\t\t\t\t\tthis.stage.removeEntityByUuid(hoveredUuid);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\tif (!this.options.addEntityFactory) break;\n\t\t\t\tconst hitPosition = origin.clone().add(direction.clone().multiplyScalar(toi));\n\t\t\t\tconst newNode = this.options.addEntityFactory({ position: hitPosition });\n\t\t\t\tif (newNode) {\n\t\t\t\t\tPromise.resolve(newNode).then((node) => {\n\t\t\t\t\t\tif (node) this.stage.spawnEntity(node);\n\t\t\t\t\t}).catch(() => { });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate attachDomListeners() {\n\t\tconst canvas = this.stage.cameraRef?.renderer.domElement ?? this.stage.scene?.zylemCamera.renderer.domElement;\n\t\tif (!canvas) return;\n\n\t\tconst onMouseMove = (e: MouseEvent) => {\n\t\t\tconst rect = canvas.getBoundingClientRect();\n\t\t\tconst x = ((e.clientX - rect.left) / rect.width) * 2 - 1;\n\t\t\tconst y = -(((e.clientY - rect.top) / rect.height) * 2 - 1);\n\t\t\tthis.mouseNdc.set(x, y);\n\t\t};\n\n\t\tconst onMouseDown = (e: MouseEvent) => {\n\t\t\tthis.isMouseDown = true;\n\t\t};\n\n\t\tcanvas.addEventListener('mousemove', onMouseMove);\n\t\tcanvas.addEventListener('mousedown', onMouseDown);\n\n\t\tthis.disposeFns.push(() => canvas.removeEventListener('mousemove', onMouseMove));\n\t\tthis.disposeFns.push(() => canvas.removeEventListener('mousedown', onMouseDown));\n\t}\n}\n\n\n","import { Object3D } from 'three';\nimport { subscribe } from 'valtio/vanilla';\n\nimport type { CameraDebugDelegate, CameraDebugState } from '../camera/zylem-camera';\nimport { debugState } from '../debug/debug-state';\nimport type { ZylemStage } from './zylem-stage';\n\nconst cloneSelected = (selected: string[]): string[] => [...selected];\n\n/**\n * Debug delegate that bridges the stage's entity map and debug state to the camera.\n */\nexport class StageCameraDebugDelegate implements CameraDebugDelegate {\n\tprivate stage: ZylemStage;\n\n\tconstructor(stage: ZylemStage) {\n\t\tthis.stage = stage;\n\t}\n\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void {\n\t\tconst notify = () => listener(this.snapshot());\n\t\tnotify();\n\t\treturn subscribe(debugState, notify);\n\t}\n\n\tresolveTarget(uuid: string): Object3D | null {\n\t\tconst entity: any = this.stage._debugMap.get(uuid)\n\t\t\t|| this.stage.world?.collisionMap.get(uuid)\n\t\t\t|| null;\n\t\tconst target = entity?.group ?? entity?.mesh ?? null;\n\t\treturn target ?? null;\n\t}\n\n\tprivate snapshot(): CameraDebugState {\n\t\treturn {\n\t\t\tenabled: debugState.enabled,\n\t\t\tselected: debugState.selectedEntity ? [debugState.selectedEntity.uuid] : [],\n\t\t};\n\t}\n}\n\n","import { Vector2 } from 'three';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { Perspectives, PerspectiveType } from '../camera/perspective';\nimport { CameraWrapper } from '../camera/camera';\nimport type { ZylemStage } from './zylem-stage';\n\n/**\n * Delegate for camera creation and management within a stage.\n * Accepts an injected stage reference for context.\n */\nexport class StageCameraDelegate {\n\tprivate stage: ZylemStage;\n\n\tconstructor(stage: ZylemStage) {\n\t\tthis.stage = stage;\n\t}\n\n\t/**\n\t * Create a default third-person camera based on window size.\n\t */\n\tcreateDefaultCamera(): ZylemCamera {\n\t\tconst width = window.innerWidth;\n\t\tconst height = window.innerHeight;\n\t\tconst screenResolution = new Vector2(width, height);\n\t\treturn new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t}\n\n\t/**\n\t * Resolve the camera to use for the stage.\n\t * Uses the provided camera, stage camera wrapper, or creates a default.\n\t * \n\t * @param cameraOverride Optional camera override\n\t * @param cameraWrapper Optional camera wrapper from stage options\n\t * @returns The resolved ZylemCamera instance\n\t */\n\tresolveCamera(cameraOverride?: ZylemCamera | null, cameraWrapper?: CameraWrapper): ZylemCamera {\n\t\tif (cameraOverride) {\n\t\t\treturn cameraOverride;\n\t\t}\n\t\tif (cameraWrapper) {\n\t\t\treturn cameraWrapper.cameraRef;\n\t\t}\n\t\treturn this.createDefaultCamera();\n\t}\n}\n","import { LoadingEvent } from '../core/interfaces';\nimport { gameEventBus, StageLoadingPayload } from '../game/game-event-bus';\n\n/**\n * Event name for stage loading events.\n * Dispatched via window for cross-application communication.\n */\nexport const STAGE_LOADING_EVENT = 'STAGE_LOADING_EVENT';\n\n/**\n * Delegate for managing loading events and progress within a stage.\n * Handles subscription to loading events and broadcasting progress.\n * Emits to game event bus for game-level observation.\n */\nexport class StageLoadingDelegate {\n\tprivate loadingHandlers: Array<(event: LoadingEvent) => void> = [];\n\tprivate stageName?: string;\n\tprivate stageIndex?: number;\n\n\t/**\n\t * Set stage context for event bus emissions.\n\t */\n\tsetStageContext(stageName: string, stageIndex: number): void {\n\t\tthis.stageName = stageName;\n\t\tthis.stageIndex = stageIndex;\n\t}\n\n\t/**\n\t * Subscribe to loading events.\n\t * \n\t * @param callback Invoked for each loading event (start, progress, complete)\n\t * @returns Unsubscribe function\n\t */\n\tonLoading(callback: (event: LoadingEvent) => void): () => void {\n\t\tthis.loadingHandlers.push(callback);\n\t\treturn () => {\n\t\t\tthis.loadingHandlers = this.loadingHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\t/**\n\t * Emit a loading event to all subscribers and to the game event bus.\n\t * \n\t * @param event The loading event to broadcast\n\t */\n\temit(event: LoadingEvent): void {\n\t\t// Dispatch to direct subscribers\n\t\tfor (const handler of this.loadingHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(event);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Loading handler failed', e);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Emit to game event bus for game-level observation\n\t\tconst payload: StageLoadingPayload = {\n\t\t\t...event,\n\t\t\tstageName: this.stageName,\n\t\t\tstageIndex: this.stageIndex,\n\t\t};\n\t\t\n\t\tif (event.type === 'start') {\n\t\t\tgameEventBus.emit('stage:loading:start', payload);\n\t\t} else if (event.type === 'progress') {\n\t\t\tgameEventBus.emit('stage:loading:progress', payload);\n\t\t} else if (event.type === 'complete') {\n\t\t\tgameEventBus.emit('stage:loading:complete', payload);\n\t\t}\n\t}\n\n\t/**\n\t * Emit a start loading event.\n\t */\n\temitStart(message: string = 'Loading stage...'): void {\n\t\tthis.emit({ type: 'start', message, progress: 0 });\n\t}\n\n\t/**\n\t * Emit a progress loading event.\n\t */\n\temitProgress(message: string, current: number, total: number): void {\n\t\tconst progress = total > 0 ? current / total : 0;\n\t\tthis.emit({ type: 'progress', message, progress, current, total });\n\t}\n\n\t/**\n\t * Emit a complete loading event.\n\t */\n\temitComplete(message: string = 'Stage loaded'): void {\n\t\tthis.emit({ type: 'complete', message, progress: 1 });\n\t}\n\n\t/**\n\t * Clear all loading handlers.\n\t */\n\tdispose(): void {\n\t\tthis.loadingHandlers = [];\n\t}\n}\n","import { zylemEventBus } from '../events';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { GameEntity } from '../entities/entity';\n\n/**\n * Delegate for handling deferred model loading in entities.\n * Subscribes to model:loaded events and adds entity groups to the scene\n * when they become available after async loading completes.\n */\nexport class StageEntityModelDelegate {\n\tprivate scene: ZylemScene | null = null;\n\tprivate pendingEntities: Map<string, GameEntity<any>> = new Map();\n\tprivate modelLoadedHandler: ((payload: { entityId: string; success: boolean }) => void) | null = null;\n\n\t/**\n\t * Initialize the delegate with the scene reference and start listening.\n\t */\n\tattach(scene: ZylemScene): void {\n\t\tthis.scene = scene;\n\t\tthis.modelLoadedHandler = (payload) => {\n\t\t\tthis.handleModelLoaded(payload.entityId, payload.success);\n\t\t};\n\t\tzylemEventBus.on('entity:model:loaded', this.modelLoadedHandler);\n\t}\n\n\t/**\n\t * Register an entity for observation.\n\t * When its model loads, the group will be added to the scene.\n\t */\n\tobserve(entity: GameEntity<any>): void {\n\t\tthis.pendingEntities.set(entity.uuid, entity);\n\t}\n\n\t/**\n\t * Unregister an entity (e.g., when removed before model loads).\n\t */\n\tunobserve(entityId: string): void {\n\t\tthis.pendingEntities.delete(entityId);\n\t}\n\n\t/**\n\t * Handle model loaded event - add group to scene if entity is pending.\n\t */\n\tprivate handleModelLoaded(entityId: string, success: boolean): void {\n\t\tconst entity = this.pendingEntities.get(entityId);\n\t\tif (!entity || !success) {\n\t\t\tthis.pendingEntities.delete(entityId);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.scene?.addEntityGroup(entity);\n\t\tthis.pendingEntities.delete(entityId);\n\t}\n\n\t/**\n\t * Cleanup all subscriptions and pending entities.\n\t */\n\tdispose(): void {\n\t\tif (this.modelLoadedHandler) {\n\t\t\tzylemEventBus.off('entity:model:loaded', this.modelLoadedHandler);\n\t\t\tthis.modelLoadedHandler = null;\n\t\t}\n\t\tthis.pendingEntities.clear();\n\t\tthis.scene = null;\n\t}\n}\n","import { BaseNode } from '../base-node';\nimport { CameraWrapper } from '../../camera/camera';\n\n/**\n * Check if an item is a BaseNode (has a create function).\n */\nexport function isBaseNode(item: unknown): item is BaseNode {\n\treturn !!item && typeof item === 'object' && typeof (item as any).create === 'function';\n}\n\n/**\n * Check if an item is a Promise-like (thenable).\n */\nexport function isThenable(item: unknown): item is Promise<any> {\n\treturn !!item && typeof (item as any).then === 'function';\n}\n\n/**\n * Check if an item is a CameraWrapper.\n */\nexport function isCameraWrapper(item: unknown): item is CameraWrapper {\n\treturn !!item && typeof item === 'object' && (item as any).constructor?.name === 'CameraWrapper';\n}\n\n/**\n * Check if an item is a plain config object (not a special type).\n * Excludes BaseNode, CameraWrapper, functions, and promises.\n */\nexport function isConfigObject(item: unknown): boolean {\n\tif (!item || typeof item !== 'object') return false;\n\tif (isBaseNode(item)) return false;\n\tif (isCameraWrapper(item)) return false;\n\tif (isThenable(item)) return false;\n\tif (typeof (item as any).then === 'function') return false;\n\t// Must be a plain object\n\treturn (item as any).constructor === Object || (item as any).constructor?.name === 'Object';\n}\n\n/**\n * Check if an item is an entity input (BaseNode, Promise, or factory function).\n */\nexport function isEntityInput(item: unknown): boolean {\n\tif (!item) return false;\n\tif (isBaseNode(item)) return true;\n\tif (typeof item === 'function') return true;\n\tif (isThenable(item)) return true;\n\treturn false;\n}\n","import { Color, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { CameraWrapper } from '../camera/camera';\nimport { isBaseNode, isCameraWrapper, isConfigObject, isEntityInput, isThenable } from '../core/utility/options-parser';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport type { ZylemShaderObject } from '../graphics/material';\n\n/**\n * Stage configuration type for user-facing options.\n */\nexport type StageConfigLike = Partial<{\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader: ZylemShaderObject;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\n}>;\n\n/**\n * Internal stage configuration class.\n */\nexport class StageConfig {\n\tconstructor(\n\t\tpublic inputs: Record<string, string[]>,\n\t\tpublic backgroundColor: Color | string,\n\t\tpublic backgroundImage: string | null,\n\t\tpublic backgroundShader: ZylemShaderObject | null,\n\t\tpublic gravity: Vector3,\n\t\tpublic variables: Record<string, any>,\n\t) { }\n}\n\n/**\n * Create default stage configuration.\n */\nexport function createDefaultStageConfig(): StageConfig {\n\treturn new StageConfig(\n\t\t{\n\t\t\tp1: ['gamepad-1', 'keyboard-1'],\n\t\t\tp2: ['gamepad-2', 'keyboard-2'],\n\t\t},\n\t\tZylemBlueColor,\n\t\tnull,\n\t\tnull,\n\t\tnew Vector3(0, 0, 0),\n\t\t{},\n\t);\n}\n\n/**\n * Result of parsing stage options.\n */\nexport interface ParsedStageOptions {\n\tconfig: StageConfig;\n\tentities: BaseNode[];\n\tasyncEntities: Array<BaseNode | Promise<any> | (() => BaseNode | Promise<any>)>;\n\tcamera?: CameraWrapper;\n}\n\n/**\n * Parse stage options array and resolve configuration.\n * Separates config objects, camera wrappers, and entity inputs.\n * \n * @param options Stage options array\n * @returns Parsed stage options with resolved config, entities, and camera\n */\nexport function parseStageOptions(options: any[] = []): ParsedStageOptions {\n\tconst defaults = createDefaultStageConfig();\n\tlet config: Partial<StageConfig> = {};\n\tconst entities: BaseNode[] = [];\n\tconst asyncEntities: Array<BaseNode | Promise<any> | (() => BaseNode | Promise<any>)> = [];\n\tlet camera: CameraWrapper | undefined;\n\n\tfor (const item of options) {\n\t\tif (isCameraWrapper(item)) {\n\t\t\tcamera = item;\n\t\t} else if (isBaseNode(item)) {\n\t\t\tentities.push(item);\n\t\t} else if (isEntityInput(item) && !isBaseNode(item)) {\n\t\t\tasyncEntities.push(item);\n\t\t} else if (isConfigObject(item)) {\n\t\t\tconfig = { ...config, ...item };\n\t\t}\n\t}\n\n\t// Merge user config with defaults\n\tconst resolvedConfig = new StageConfig(\n\t\tconfig.inputs ?? defaults.inputs,\n\t\tconfig.backgroundColor ?? defaults.backgroundColor,\n\t\tconfig.backgroundImage ?? defaults.backgroundImage,\n\t\tconfig.backgroundShader ?? defaults.backgroundShader,\n\t\tconfig.gravity ?? defaults.gravity,\n\t\tconfig.variables ?? defaults.variables,\n\t);\n\n\treturn { config: resolvedConfig, entities, asyncEntities, camera };\n}\n\n/**\n * Factory for authoring stage configuration objects in user code.\n * Returns a plain object that can be passed to `createStage(...)`.\n */\nexport function stageConfig(config: StageConfigLike): StageConfigLike {\n\treturn { ...config };\n}\n","import { addEntity, createWorld as createECS, removeEntity } from 'bitecs';\nimport { Color, Vector3, Vector2 } from 'three';\n\nimport { ZylemWorld } from '../collision/world';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { resetStageVariables, setStageBackgroundColor, setStageBackgroundImage, setStageVariables, clearVariables, initialStageState } from './stage-state';\n\nimport { GameEntityInterface } from '../types/entity-types';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport { debugState } from '../debug/debug-state';\nimport { subscribe } from 'valtio/vanilla';\nimport { getGlobals } from \"../game/game-state\";\n\nimport { SetupContext, UpdateContext, DestroyContext } from '../core/base-node-life-cycle';\nimport { LifeCycleBase } from '../core/lifecycle-base';\nimport createTransformSystem, { StageSystem } from '../systems/transformable.system';\nimport { BaseNode } from '../core/base-node';\nimport { nanoid } from 'nanoid';\nimport { Stage } from './stage';\nimport { CameraWrapper } from '../camera/camera';\nimport { StageDebugDelegate } from './stage-debug-delegate';\nimport { StageCameraDebugDelegate } from './stage-camera-debug-delegate';\nimport { StageCameraDelegate } from './stage-camera-delegate';\nimport { StageLoadingDelegate } from './stage-loading-delegate';\nimport { StageEntityModelDelegate } from './stage-entity-model-delegate';\nimport { GameEntity } from '../entities/entity';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { LoadingEvent } from '../core/interfaces';\nimport { parseStageOptions } from './stage-config';\nimport { isBaseNode, isThenable } from '../core/utility/options-parser';\nimport type { BehaviorSystem, BehaviorSystemFactory } from '../behaviors/behavior-system';\nexport type { LoadingEvent };\n\nexport interface ZylemStageConfig {\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader: any | null;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\n\tstageRef?: Stage;\n}\n\ntype NodeLike = { create: Function };\nexport type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);\n\nexport type StageOptionItem = Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput;\nexport type StageOptions = [] | [Partial<ZylemStageConfig>, ...StageOptionItem[]];\n\nexport type StageState = ZylemStageConfig & { entities: GameEntityInterface[] };\n\nconst STAGE_TYPE = 'Stage';\n\n/**\n * ZylemStage orchestrates scene, physics world, entities, and lifecycle.\n *\n * Responsibilities:\n * - Manage stage configuration (background, inputs, gravity, variables)\n * - Initialize and own `ZylemScene` and `ZylemWorld`\n * - Spawn, track, and remove entities; emit entity-added events\n * - Drive per-frame updates and transform system\n */\nexport class ZylemStage extends LifeCycleBase<ZylemStage> {\n\tpublic type = STAGE_TYPE;\n\n\tstate: StageState = { ...initialStageState };\n\tgravity: Vector3;\n\n\tworld: ZylemWorld | null;\n\tscene: ZylemScene | null;\n\n\tchildren: Array<BaseNode> = [];\n\t_childrenMap: Map<number, BaseNode> = new Map();\n\t_removalMap: Map<number, BaseNode> = new Map();\n\n\tprivate pendingEntities: StageEntityInput[] = [];\n\tprivate pendingPromises: Promise<BaseNode>[] = [];\n\tprivate isLoaded: boolean = false;\n\n\t_debugMap: Map<string, BaseNode> = new Map();\n\n\tprivate entityAddedHandlers: Array<(entity: BaseNode) => void> = [];\n\n\tecs = createECS();\n\ttestSystem: any = null;\n\ttransformSystem: ReturnType<typeof createTransformSystem> | null = null;\n\tprivate behaviorSystems: BehaviorSystem[] = [];\n\tprivate registeredSystemKeys: Set<symbol> = new Set();\n\tdebugDelegate: StageDebugDelegate | null = null;\n\tcameraDebugDelegate: StageCameraDebugDelegate | null = null;\n\tprivate debugStateUnsubscribe: (() => void) | null = null;\n\n\tuuid: string;\n\twrapperRef: Stage | null = null;\n\tcamera?: CameraWrapper;\n\tcameraRef?: ZylemCamera | null = null;\n\n\t// Delegates\n\tprivate cameraDelegate: StageCameraDelegate;\n\tprivate loadingDelegate: StageLoadingDelegate;\n\tprivate entityModelDelegate: StageEntityModelDelegate;\n\n\t/**\n\t * Create a new stage.\n\t * @param options Stage options: partial config, camera, and initial entities or factories\n\t */\n\tconstructor(options: StageOptions = []) {\n\t\tsuper();\n\t\tthis.world = null;\n\t\tthis.scene = null;\n\t\tthis.uuid = nanoid();\n\n\t\t// Initialize delegates\n\t\tthis.cameraDelegate = new StageCameraDelegate(this);\n\t\tthis.loadingDelegate = new StageLoadingDelegate();\n\t\tthis.entityModelDelegate = new StageEntityModelDelegate();\n\n\t\t// Parse the options array using the stage-config module\n\t\tconst parsed = parseStageOptions(options);\n\t\tthis.camera = parsed.camera;\n\t\tthis.children = parsed.entities;\n\t\tthis.pendingEntities = parsed.asyncEntities;\n\t\t\n\t\t// Update state with resolved config\n\t\tthis.saveState({\n\t\t\t...this.state,\n\t\t\tinputs: parsed.config.inputs,\n\t\t\tbackgroundColor: parsed.config.backgroundColor,\n\t\t\tbackgroundImage: parsed.config.backgroundImage,\n\t\t\tbackgroundShader: parsed.config.backgroundShader,\n\t\t\tgravity: parsed.config.gravity,\n\t\t\tvariables: parsed.config.variables,\n\t\t\tentities: [],\n\t\t});\n\n\t\tthis.gravity = parsed.config.gravity ?? new Vector3(0, 0, 0);\n\t}\n\n\tprivate handleEntityImmediatelyOrQueue(entity: BaseNode): void {\n\t\tif (this.isLoaded) {\n\t\t\tthis.spawnEntity(entity);\n\t\t} else {\n\t\t\tthis.children.push(entity);\n\t\t}\n\t}\n\n\tprivate handlePromiseWithSpawnOnResolve(promise: Promise<any>): void {\n\t\tif (this.isLoaded) {\n\t\t\tpromise\n\t\t\t\t.then((entity) => this.spawnEntity(entity))\n\t\t\t\t.catch((e) => console.error('Failed to build async entity', e));\n\t\t} else {\n\t\t\tthis.pendingPromises.push(promise as Promise<BaseNode>);\n\t\t}\n\t}\n\n\tprivate saveState(state: StageState) {\n\t\tthis.state = state;\n\t}\n\n\tprivate setState() {\n\t\tconst { backgroundColor, backgroundImage } = this.state;\n\t\tconst color = backgroundColor instanceof Color ? backgroundColor : new Color(backgroundColor);\n\t\tsetStageBackgroundColor(color);\n\t\tsetStageBackgroundImage(backgroundImage);\n\t\t// Initialize reactive stage variables on load\n\t\tsetStageVariables(this.state.variables ?? {});\n\t}\n\n\t/**\n\t * Load and initialize the stage's scene and world.\n\t * Uses generator pattern to yield control to event loop for real-time progress.\n\t * @param id DOM element id for the renderer container\n\t * @param camera Optional camera override\n\t */\n\tasync load(id: string, camera?: ZylemCamera | null) {\n\t\tthis.setState();\n\n\t\t// Use camera delegate to resolve camera\n\t\tconst zylemCamera = this.cameraDelegate.resolveCamera(camera, this.camera);\n\t\tthis.cameraRef = zylemCamera;\n\t\tthis.scene = new ZylemScene(id, zylemCamera, this.state);\n\n\t\tconst physicsWorld = await ZylemWorld.loadPhysics(this.gravity ?? new Vector3(0, 0, 0));\n\t\tthis.world = new ZylemWorld(physicsWorld);\n\n\t\tthis.scene.setup();\n\t\tthis.entityModelDelegate.attach(this.scene);\n\n\t\tthis.loadingDelegate.emitStart();\n\n\t\t// Run entity loading with generator pattern for real-time progress\n\t\tawait this.runEntityLoadGenerator();\n\n\t\tthis.transformSystem = createTransformSystem(this as unknown as StageSystem);\n\t\tthis.isLoaded = true;\n\t\tthis.loadingDelegate.emitComplete();\n\t}\n\n\t/**\n\t * Generator that yields between entity loads for real-time progress updates.\n\t */\n\tprivate *entityLoadGenerator(): Generator<{ current: number; total: number; name: string }> {\n\t\tconst total = this.children.length + this.pendingEntities.length + this.pendingPromises.length;\n\t\tlet current = 0;\n\n\t\tfor (const child of this.children) {\n\t\t\tthis.spawnEntity(child);\n\t\t\tcurrent++;\n\t\t\tyield { current, total, name: child.name || 'unknown' };\n\t\t}\n\n\t\tif (this.pendingEntities.length) {\n\t\t\tthis.enqueue(...this.pendingEntities);\n\t\t\tcurrent += this.pendingEntities.length;\n\t\t\tthis.pendingEntities = [];\n\t\t\tyield { current, total, name: 'pending entities' };\n\t\t}\n\n\t\tif (this.pendingPromises.length) {\n\t\t\tfor (const promise of this.pendingPromises) {\n\t\t\t\tpromise.then((entity) => {\n\t\t\t\t\tthis.spawnEntity(entity);\n\t\t\t\t}).catch((e) => console.error('Failed to resolve pending stage entity', e));\n\t\t\t}\n\t\t\tcurrent += this.pendingPromises.length;\n\t\t\tthis.pendingPromises = [];\n\t\t\tyield { current, total, name: 'async entities' };\n\t\t}\n\t}\n\n\t/**\n\t * Runs the entity load generator, yielding to the event loop between loads.\n\t * This allows the browser to process events and update the UI in real-time.\n\t */\n\tprivate async runEntityLoadGenerator(): Promise<void> {\n\t\tconst gen = this.entityLoadGenerator();\n\t\tfor (const progress of gen) {\n\t\t\tthis.loadingDelegate.emitProgress(`Loaded ${progress.name}`, progress.current, progress.total);\n\t\t\t// Yield to event loop so browser can process events and update UI\n\t\t\t// Use setTimeout(0) for more reliable async behavior than RAF\n\t\t\tawait new Promise<void>(resolve => setTimeout(resolve, 0));\n\t\t}\n\t}\n\n\n\tprotected _setup(params: SetupContext<ZylemStage>): void {\n\t\tif (!this.scene || !this.world) {\n\t\t\tthis.logMissingEntities();\n\t\t\treturn;\n\t\t}\n\t\t// Setup debug delegate based on current state\n\t\tthis.updateDebugDelegate();\n\n\t\t// Subscribe to debugState changes for runtime toggle\n\t\tthis.debugStateUnsubscribe = subscribe(debugState, () => {\n\t\t\tthis.updateDebugDelegate();\n\t\t});\n\t}\n\n\tprivate updateDebugDelegate(): void {\n\t\tif (debugState.enabled && !this.debugDelegate && this.scene && this.world) {\n\t\t\t// Create debug delegate when debug is enabled\n\t\t\tthis.debugDelegate = new StageDebugDelegate(this);\n\t\t\t\n\t\t\t// Create and attach camera debug delegate for orbit controls\n\t\t\tif (this.cameraRef && !this.cameraDebugDelegate) {\n\t\t\t\tthis.cameraDebugDelegate = new StageCameraDebugDelegate(this);\n\t\t\t\tthis.cameraRef.setDebugDelegate(this.cameraDebugDelegate);\n\t\t\t}\n\t\t} else if (!debugState.enabled && this.debugDelegate) {\n\t\t\t// Dispose debug delegate when debug is disabled\n\t\t\tthis.debugDelegate.dispose();\n\t\t\tthis.debugDelegate = null;\n\t\t\t\n\t\t\t// Detach camera debug delegate\n\t\t\tif (this.cameraRef) {\n\t\t\t\tthis.cameraRef.setDebugDelegate(null);\n\t\t\t}\n\t\t\tthis.cameraDebugDelegate = null;\n\t\t}\n\t}\n\n\tprotected _update(params: UpdateContext<ZylemStage>): void {\n\t\tconst { delta } = params;\n\t\tif (!this.scene || !this.world) {\n\t\t\tthis.logMissingEntities();\n\t\t\treturn;\n\t\t}\n\t\tthis.world.update(params);\n\t\tthis.transformSystem?.system(this.ecs);\n\t\t// Run registered ECS behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.update(this.ecs, delta);\n\t\t}\n\t\tthis._childrenMap.forEach((child, eid) => {\n\t\t\tchild.nodeUpdate({\n\t\t\t\t...params,\n\t\t\t\tme: child,\n\t\t\t});\n\t\t\tif (child.markedForRemoval) {\n\t\t\t\tthis.removeEntityByUuid(child.uuid);\n\t\t\t}\n\t\t});\n\t\tthis.scene.update({ delta });\n\t\tthis.scene.updateSkybox(delta);\n\t}\n\n\tpublic outOfLoop() {\n\t\tthis.debugUpdate();\n\t}\n\n\t/** Update debug overlays and helpers if enabled. */\n\tpublic debugUpdate() {\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugDelegate?.update();\n\t\t}\n\t}\n\n\t/** Cleanup owned resources when the stage is destroyed. */\n\tprotected _destroy(params: DestroyContext<ZylemStage>): void {\n\t\t// Cleanup behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.destroy?.(this.ecs);\n\t\t}\n\t\tthis.behaviorSystems = [];\n\t\tthis.registeredSystemKeys.clear();\n\t\tthis._childrenMap.forEach((child) => {\n\t\t\ttry { child.nodeDestroy({ me: child, globals: getGlobals() }); } catch { /* noop */ }\n\t\t});\n\t\tthis._childrenMap.clear();\n\t\tthis._removalMap.clear();\n\t\tthis._debugMap.clear();\n\n\t\tthis.world?.destroy();\n\t\tthis.scene?.destroy();\n\n\t\t// Cleanup debug state subscription\n\t\tif (this.debugStateUnsubscribe) {\n\t\t\tthis.debugStateUnsubscribe();\n\t\t\tthis.debugStateUnsubscribe = null;\n\t\t}\n\n\t\tthis.debugDelegate?.dispose();\n\t\tthis.debugDelegate = null;\n\t\tthis.cameraRef?.setDebugDelegate(null);\n\t\tthis.cameraDebugDelegate = null;\n\n\t\tthis.entityModelDelegate.dispose();\n\n\t\tthis.isLoaded = false;\n\t\tthis.world = null as any;\n\t\tthis.scene = null as any;\n\t\tthis.cameraRef = null;\n\t\t// Cleanup transform system\n\t\tthis.transformSystem?.destroy(this.ecs);\n\t\tthis.transformSystem = null;\n\n\t\t// Clear reactive stage variables on unload\n\t\tresetStageVariables();\n\t\t// Clear object-scoped variables for this stage\n\t\tclearVariables(this);\n\t}\n\n\t/**\n\t * Create, register, and add an entity to the scene/world.\n\t * Safe to call only after `load` when scene/world exist.\n\t */\n\tasync spawnEntity(child: BaseNode) {\n\t\tif (!this.scene || !this.world) {\n\t\t\treturn;\n\t\t}\n\t\tconst entity = child.create();\n\t\tconst eid = addEntity(this.ecs);\n\t\tentity.eid = eid;\n\t\tthis.scene.addEntity(entity);\n\n\t\t// Auto-register behavior systems from entity refs\n\t\tif (typeof entity.getBehaviorRefs === 'function') {\n\t\t\tfor (const ref of entity.getBehaviorRefs()) {\n\t\t\t\tconst key = ref.descriptor.key;\n\t\t\t\tif (!this.registeredSystemKeys.has(key)) {\n\t\t\t\t\tconst system = ref.descriptor.systemFactory({ world: this.world, ecs: this.ecs });\n\t\t\t\t\tthis.behaviorSystems.push(system);\n\t\t\t\t\tthis.registeredSystemKeys.add(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (entity.colliderDesc) {\n\t\t\tthis.world.addEntity(entity);\n\t\t}\n\t\tchild.nodeSetup({\n\t\t\tme: child,\n\t\t\tglobals: getGlobals(),\n\t\t\tcamera: this.scene.zylemCamera,\n\t\t});\n\t\tthis.addEntityToStage(entity);\n\t\tthis.entityModelDelegate.observe(entity);\n\t}\n\n\tbuildEntityState(child: BaseNode): Partial<BaseEntityInterface> {\n\t\tif (child instanceof GameEntity) {\n\t\t\treturn { ...child.buildInfo() } as Partial<BaseEntityInterface>;\n\t\t}\n\t\treturn {\n\t\t\tuuid: child.uuid,\n\t\t\tname: child.name,\n\t\t\teid: child.eid,\n\t\t} as Partial<BaseEntityInterface>;\n\t}\n\n\t/** Add the entity to internal maps and notify listeners. */\n\taddEntityToStage(entity: BaseNode) {\n\t\tthis._childrenMap.set(entity.eid, entity);\n\t\tif (debugState.enabled) {\n\t\t\tthis._debugMap.set(entity.uuid, entity);\n\t\t}\n\t\tfor (const handler of this.entityAddedHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(entity);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('onEntityAdded handler failed', e);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Subscribe to entity-added events.\n\t * @param callback Invoked for each entity when added\n\t * @param options.replayExisting If true and stage already loaded, replays existing entities\n\t * @returns Unsubscribe function\n\t */\n\tonEntityAdded(callback: (entity: BaseNode) => void, options?: { replayExisting?: boolean }) {\n\t\tthis.entityAddedHandlers.push(callback);\n\t\tif (options?.replayExisting && this.isLoaded) {\n\t\t\tthis._childrenMap.forEach((entity) => {\n\t\t\t\ttry { callback(entity); } catch (e) { console.error('onEntityAdded replay failed', e); }\n\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tthis.entityAddedHandlers = this.entityAddedHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\treturn this.loadingDelegate.onLoading(callback);\n\t}\n\n\t/**\n\t * Register an ECS behavior system to run each frame.\n\t * @param systemOrFactory A BehaviorSystem instance or factory function\n\t * @returns this for chaining\n\t */\n\tregisterSystem(systemOrFactory: BehaviorSystem | BehaviorSystemFactory): this {\n\t\tlet system: BehaviorSystem;\n\t\tif (typeof systemOrFactory === 'function') {\n\t\t\tsystem = systemOrFactory({ world: this.world, ecs: this.ecs });\n\t\t} else {\n\t\t\tsystem = systemOrFactory;\n\t\t}\n\t\tthis.behaviorSystems.push(system);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Remove an entity and its resources by its UUID.\n\t * @returns true if removed, false if not found or stage not ready\n\t */\n\tremoveEntityByUuid(uuid: string): boolean {\n\t\tif (!this.scene || !this.world) return false;\n\t\t// Try mapping via world collision map first for physics-backed entities\n\t\t// @ts-ignore - collisionMap is public Map<string, GameEntity<any>>\n\t\tconst mapEntity = this.world.collisionMap.get(uuid) as any | undefined;\n\t\tconst entity: any = mapEntity ?? this._debugMap.get(uuid);\n\t\tif (!entity) return false;\n\n\t\tthis.entityModelDelegate.unobserve(uuid);\n\n\t\tthis.world.destroyEntity(entity);\n\n\t\tif (entity.group) {\n\t\t\tthis.scene.scene.remove(entity.group);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.scene.scene.remove(entity.mesh);\n\t\t}\n\n\t\tremoveEntity(this.ecs, entity.eid);\n\n\t\tlet foundKey: number | null = null;\n\t\tthis._childrenMap.forEach((value, key) => {\n\t\t\tif ((value as any).uuid === uuid) {\n\t\t\t\tfoundKey = key;\n\t\t\t}\n\t\t});\n\t\tif (foundKey !== null) {\n\t\t\tthis._childrenMap.delete(foundKey);\n\t\t}\n\t\tthis._debugMap.delete(uuid);\n\t\treturn true;\n\t}\n\n\t/** Get an entity by its name; returns null if not found. */\n\tgetEntityByName(name: string) {\n\t\tconst arr = Object.entries(Object.fromEntries(this._childrenMap)).map((entry) => entry[1]);\n\t\tconst entity = arr.find((child) => child.name === name);\n\t\tif (!entity) {\n\t\t\tconsole.warn(`Entity ${name} not found`);\n\t\t}\n\t\treturn entity ?? null;\n\t}\n\n\tlogMissingEntities() {\n\t\tconsole.warn('Zylem world or scene is null');\n\t}\n\n\t/** Resize renderer viewport. */\n\tresize(width: number, height: number) {\n\t\tif (this.scene) {\n\t\t\tthis.scene.updateRenderer(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Enqueue items to be spawned. Items can be:\n\t * - BaseNode instances (immediate or deferred until load)\n\t * - Factory functions returning BaseNode or Promise<BaseNode>\n\t * - Promises resolving to BaseNode\n\t */\n\tenqueue(...items: StageEntityInput[]) {\n\t\tfor (const item of items) {\n\t\t\tif (!item) continue;\n\t\t\tif (isBaseNode(item)) {\n\t\t\t\tthis.handleEntityImmediatelyOrQueue(item);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof item === 'function') {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = (item as (() => BaseNode | Promise<any>))();\n\t\t\t\t\tif (isBaseNode(result)) {\n\t\t\t\t\t\tthis.handleEntityImmediatelyOrQueue(result);\n\t\t\t\t\t} else if (isThenable(result)) {\n\t\t\t\t\t\tthis.handlePromiseWithSpawnOnResolve(result as Promise<any>);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Error executing entity factory', error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isThenable(item)) {\n\t\t\t\tthis.handlePromiseWithSpawnOnResolve(item as Promise<any>);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { proxy } from 'valtio/vanilla';\nimport { Vector3 } from 'three';\nimport type { StageOptions, ZylemStageConfig } from './zylem-stage';\nimport { ZylemBlueColor } from '../core/utility/vector';\n\n/**\n * Reactive defaults for building `Stage` instances. These values are applied\n * automatically by the `stage()` builder and can be changed at runtime to\n * influence future stage creations.\n */\nconst initialDefaults: Partial<ZylemStageConfig> = {\n\tbackgroundColor: ZylemBlueColor,\n\tbackgroundImage: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard'],\n\t\tp2: ['gamepad-2', 'keyboard'],\n\t},\n\tgravity: new Vector3(0, 0, 0),\n\tvariables: {},\n};\n\nconst stageDefaultsState = proxy<Partial<ZylemStageConfig>>({\n\t...initialDefaults,\n});\n\n/** Replace multiple defaults at once (shallow merge). */\nfunction setStageDefaults(partial: Partial<ZylemStageConfig>): void {\n\tObject.assign(stageDefaultsState, partial);\n}\n\n/** Reset defaults back to library defaults. */\nfunction resetStageDefaults(): void {\n\tObject.assign(stageDefaultsState, initialDefaults);\n}\n\nexport function getStageOptions(options: StageOptions): StageOptions {\n\tconst defaults = getStageDefaultConfig();\n\tlet originalConfig = {};\n\tif (typeof options[0] === 'object') {\n\t\toriginalConfig = options.shift() ?? {};\n\t}\n\tconst combinedConfig = { ...defaults, ...originalConfig };\n\treturn [combinedConfig, ...options] as StageOptions;\n}\n\n/** Get a plain object copy of the current defaults. */\nfunction getStageDefaultConfig(): Partial<ZylemStageConfig> {\n\treturn {\n\t\tbackgroundColor: stageDefaultsState.backgroundColor,\n\t\tbackgroundImage: stageDefaultsState.backgroundImage ?? null,\n\t\tinputs: stageDefaultsState.inputs ? { ...stageDefaultsState.inputs } : undefined,\n\t\tgravity: stageDefaultsState.gravity,\n\t\tvariables: stageDefaultsState.variables ? { ...stageDefaultsState.variables } : undefined,\n\t};\n}\n\n\n","import { BaseNode } from '../core/base-node';\nimport { DestroyFunction, SetupContext, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';\nimport { LoadingEvent, StageOptionItem, StageOptions, ZylemStage } from './zylem-stage';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { CameraWrapper } from '../camera/camera';\nimport { stageState } from './stage-state';\nimport { getStageOptions } from './stage-default';\nimport { EntityTypeMap } from '../types/entity-type-map';\nimport { EventEmitterDelegate, zylemEventBus, type StageEvents } from '../events';\n\ntype NodeLike = { create: Function };\ntype AnyNode = NodeLike | Promise<NodeLike>;\ntype EntityInput = AnyNode | (() => AnyNode) | (() => Promise<any>);\n\nexport class Stage {\n\twrappedStage: ZylemStage | null;\n\toptions: StageOptionItem[] = [];\n\t// Entities added after construction, consumed on each load\n\tprivate _pendingEntities: BaseNode[] = [];\n\n\t// Lifecycle callback arrays\n\tprivate setupCallbacks: Array<SetupFunction<ZylemStage>> = [];\n\tprivate updateCallbacks: Array<UpdateFunction<ZylemStage>> = [];\n\tprivate destroyCallbacks: Array<DestroyFunction<ZylemStage>> = [];\n\tprivate pendingLoadingCallbacks: Array<(event: LoadingEvent) => void> = [];\n\n\t// Event delegate for dispatch/listen API\n\tprivate eventDelegate = new EventEmitterDelegate<StageEvents>();\n\n\tconstructor(options: StageOptions) {\n\t\tthis.options = options;\n\t\tthis.wrappedStage = null;\n\t}\n\n\tasync load(id: string, camera?: ZylemCamera | CameraWrapper | null) {\n\t\tstageState.entities = [];\n\t\t// Combine original options with pending entities, then clear pending\n\t\tconst loadOptions = [...this.options, ...this._pendingEntities] as StageOptions;\n\t\tthis._pendingEntities = [];\n\t\t\n\t\tthis.wrappedStage = new ZylemStage(loadOptions);\n\t\tthis.wrappedStage.wrapperRef = this;\n\n\t\t// Flush pending loading callbacks BEFORE load so we catch start/progress events\n\t\tthis.pendingLoadingCallbacks.forEach(cb => {\n\t\t\tthis.wrappedStage!.onLoading(cb);\n\t\t});\n\t\tthis.pendingLoadingCallbacks = [];\n\n\t\tconst zylemCamera = camera instanceof CameraWrapper ? camera.cameraRef : camera;\n\t\tawait this.wrappedStage!.load(id, zylemCamera);\n\n\t\tthis.wrappedStage!.onEntityAdded((child) => {\n\t\t\tconst next = this.wrappedStage!.buildEntityState(child);\n\t\t\tstageState.entities = [...stageState.entities, next];\n\t\t}, { replayExisting: true });\n\n\t\t// Apply lifecycle callbacks to wrapped stage\n\t\tthis.applyLifecycleCallbacks();\n\n\t}\n\n\tprivate applyLifecycleCallbacks() {\n\t\tif (!this.wrappedStage) return;\n\n\t\t// Compose setup callbacks into a single function\n\t\tif (this.setupCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.setup = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.setupCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\n\t\t// Compose update callbacks\n\t\tif (this.updateCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.update = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.updateCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\n\t\t// Compose destroy callbacks\n\t\tif (this.destroyCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.destroy = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.destroyCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t}\n\n\tasync addEntities(entities: BaseNode[]) {\n\t\t// Store in pending, don't mutate options\n\t\tthis._pendingEntities.push(...entities);\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.enqueue(...entities);\n\t}\n\n\tadd(...inputs: Array<EntityInput>) {\n\t\tthis.addToBlueprints(...inputs);\n\t\tthis.addToStage(...inputs);\n\t}\n\n\tprivate addToBlueprints(...inputs: Array<EntityInput>) {\n\t\tif (this.wrappedStage) { return; }\n\t\t// Add to options (persistent) so they're available on reload\n\t\tthis.options.push(...(inputs as unknown as StageOptionItem[]));\n\t}\n\n\tprivate addToStage(...inputs: Array<EntityInput>) {\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.enqueue(...(inputs as any));\n\t}\n\n\tstart(params: SetupContext<ZylemStage>) {\n\t\tthis.wrappedStage?.nodeSetup(params);\n\t}\n\n\t// Fluent API for adding lifecycle callbacks\n\tonUpdate(...callbacks: UpdateFunction<ZylemStage>[]): this {\n\t\tthis.updateCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the update callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.update = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.updateCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonSetup(...callbacks: SetupFunction<ZylemStage>[]): this {\n\t\tthis.setupCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the setup callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.setup = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.setupCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonDestroy(...callbacks: DestroyFunction<ZylemStage>[]): this {\n\t\tthis.destroyCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the destroy callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.destroy = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.destroyCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\tif (!this.wrappedStage) { \n\t\t\tthis.pendingLoadingCallbacks.push(callback);\n\t\t\treturn () => {\n\t\t\t\tthis.pendingLoadingCallbacks = this.pendingLoadingCallbacks.filter(c => c !== callback);\n\t\t\t};\n\t\t}\n\t\treturn this.wrappedStage.onLoading(callback);\n\t}\n\n\t/**\n\t * Find an entity by name on the current stage.\n\t * @param name The name of the entity to find\n\t * @param type Optional type symbol for type inference (e.g., TEXT_TYPE, SPRITE_TYPE)\n\t * @returns The entity if found, or undefined\n\t * @example stage.getEntityByName('scoreText', TEXT_TYPE)\n\t */\n\tgetEntityByName<T extends symbol | void = void>(\n\t\tname: string,\n\t\ttype?: T\n\t): T extends keyof EntityTypeMap ? EntityTypeMap[T] | undefined : BaseNode | undefined {\n\t\tconst entity = this.wrappedStage?.children.find(c => c.name === name);\n\t\treturn entity as any;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from the stage.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof StageEvents>(event: K, payload: StageEvents[K]): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this stage instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof StageEvents>(event: K, handler: (payload: StageEvents[K]) => void): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Clean up stage resources including event subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.eventDelegate.dispose();\n\t}\n}\n\n/**\n * Create a stage with optional camera\n */\nexport function createStage(...options: StageOptions): Stage {\n\tconst _options = getStageOptions(options);\n\treturn new Stage([..._options] as StageOptions);\n}","export { createStage } from '../lib/stage/stage';\nexport { entitySpawner } from '../lib/stage/entity-spawner';\nexport type { StageOptions } from '../lib/stage/zylem-stage';\nexport type { StageBlueprint } from '../lib/core/blueprints';\nexport {\n\tSTAGE_STATE_CHANGE,\n\tinitStageStateDispatcher,\n\tdispatchStageState,\n} from '../lib/stage/stage-events';\nexport type { StageStateChangeEvent } from '../lib/stage/stage-events';\n","import { subscribe } from 'valtio/vanilla';\nimport { stageState } from './stage-state';\nimport type { StageStateInterface } from '../types/stage-types';\n\n/**\n * Event name for stage state changes.\n * Dispatched when the stage state proxy is updated.\n */\nexport const STAGE_STATE_CHANGE = 'STAGE_STATE_CHANGE';\n\n/**\n * Event detail payload for STAGE_STATE_CHANGE events.\n */\nexport interface StageStateChangeEvent {\n\tentities: StageStateInterface['entities'];\n\tvariables: StageStateInterface['variables'];\n}\n\n/**\n * Initialize the stage state dispatcher.\n * Subscribes to stageState changes and dispatches STAGE_STATE_CHANGE events to the window.\n * \n * @returns Unsubscribe function to stop dispatching events.\n * \n * @example\n * // Start dispatching stage state changes\n * const unsubscribe = initStageStateDispatcher();\n * \n * // Later, stop dispatching\n * unsubscribe();\n */\nexport function initStageStateDispatcher(): () => void {\n\treturn subscribe(stageState, () => {\n\t\tconst detail: StageStateChangeEvent = {\n\t\t\tentities: stageState.entities,\n\t\t\tvariables: stageState.variables,\n\t\t};\n\t\twindow.dispatchEvent(new CustomEvent(STAGE_STATE_CHANGE, { detail }));\n\t});\n}\n\n/**\n * Manually dispatch the current stage state.\n * Useful for initial sync when a listener is added.\n */\nexport function dispatchStageState(): void {\n\tconst detail: StageStateChangeEvent = {\n\t\tentities: stageState.entities,\n\t\tvariables: stageState.variables,\n\t};\n\twindow.dispatchEvent(new CustomEvent(STAGE_STATE_CHANGE, { detail }));\n}\n"],"mappings":";;;;;;AAAA,IA4Ca,cA+CA;AA3Fb;AAAA;AAAA;AA4CO,IAAM,eAAN,MAAmB;AAAA,MACjB,YAAyD,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,MAKzE,GAA4B,OAAU,UAAsD;AAC3F,YAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAAG;AAC/B,eAAK,UAAU,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,QACpC;AACA,aAAK,UAAU,IAAI,KAAK,EAAG,IAAI,QAAQ;AACvC,eAAO,MAAM,KAAK,IAAI,OAAO,QAAQ;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,IAA6B,OAAU,UAAgD;AACtF,aAAK,UAAU,IAAI,KAAK,GAAG,OAAO,QAAQ;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,KAA8B,OAAU,SAAgC;AACvE,cAAM,YAAY,KAAK,UAAU,IAAI,KAAK;AAC1C,YAAI,CAAC,UAAW;AAChB,mBAAW,MAAM,WAAW;AAC3B,cAAI;AACH,eAAG,OAAO;AAAA,UACX,SAAS,GAAG;AACX,oBAAQ,MAAM,8BAA8B,KAAK,IAAI,CAAC;AAAA,UACvD;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACf,aAAK,UAAU,MAAM;AAAA,MACtB;AAAA,IACD;AAKO,IAAM,eAAe,IAAI,aAAa;AAAA;AAAA;;;AC3F7C,SAAS,OAAO,iBAAiB;AAkH1B,SAAS,aAA6C;AAC5D,SAAO,MAAM;AACd;AApHA,IAOM;AAPN;AAAA;AAAA;AAOA,IAAM,QAAQ,MAAM;AAAA,MACnB,IAAI;AAAA,MACJ,SAAS,CAAC;AAAA,MACV,MAAM;AAAA,IACP,CAAC;AAAA;AAAA;;;ACXD;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AACP,SAAS,kBAAkB;AAmCZ,SAAR,sBAAuC,OAA2C;AACxF,QAAM,aAAa,CAAC,UAAU,QAAQ;AACtC,QAAM,iBAAiB,YAAY,UAAU;AAC7C,QAAM,gBAAgB,MAAM;AAE5B,QAAM,SAAS,aAAa,CAAC,UAAU;AACtC,UAAM,WAAW,eAAe,KAAK;AACrC,QAAI,kBAAkB,QAAW;AAChC,aAAO;AAAA,IACR;AAEA,eAAW,CAAC,KAAK,WAAW,KAAK,eAAe;AAE/C,UAAI,CAAC,aAAa,QAAQ,YAAY,kBAAkB;AACvD;AAAA,MACD;AAEA,YAAM,KAAK,SAAS,GAAG;AACvB,YAAM,OAAO,YAAY;AACzB,YAAM,SAAS,YAAY,SAAS,YAAY;AAGhD,YAAM,cAAc,KAAK,YAAY;AACrC,eAAS,EAAE,EAAE,IAAI,YAAY;AAC7B,eAAS,EAAE,EAAE,IAAI,YAAY;AAC7B,eAAS,EAAE,EAAE,IAAI,YAAY;AAE7B,UAAI,QAAQ;AACX,eAAO,SAAS,IAAI,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAAA,MAChE;AAGA,UAAI,YAAY,oBAAoB;AACnC;AAAA,MACD;AAGA,YAAM,MAAM,KAAK,SAAS;AAC1B,eAAS,EAAE,EAAE,IAAI,IAAI;AACrB,eAAS,EAAE,EAAE,IAAI,IAAI;AACrB,eAAS,EAAE,EAAE,IAAI,IAAI;AACrB,eAAS,EAAE,EAAE,IAAI,IAAI;AAErB,UAAI,QAAQ;AACX,wBAAgB,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,eAAO,0BAA0B,eAAe;AAAA,MACjD;AAAA,IACD;AAEA,WAAO;AAAA,EACR,CAAC;AAED,QAAM,UAAU,CAAC,UAAkB;AAElC,gBAAY,OAAO,cAAc;AAAA,EAClC;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC1B;AArGA,IAgBa,UAMA,UAOA,OAOP;AApCN;AAAA;AAAA;AAgBO,IAAM,WAAW,gBAAgB;AAAA,MACvC,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,IACV,CAAC;AAEM,IAAM,WAAW,gBAAgB;AAAA,MACvC,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,IACV,CAAC;AAEM,IAAM,QAAQ,gBAAgB;AAAA,MACpC,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,IACV,CAAC;AAGD,IAAM,kBAAkB,IAAI,WAAW;AAAA;AAAA;;;ACpCvC,IACa;AADb;AAAA;AAAA;AACO,IAAM,aAAa,YAAY,IAAI,oBAAoB;AAAA;AAAA;;;ACY9D,SAAS,cAAc;AAbvB,IA8BsB;AA9BtB;AAAA;AAAA;AAYA;AAkBO,IAAe,WAAf,MAAe,UAA0D;AAAA,MACrE,SAA+B;AAAA,MAC/B,WAA4B,CAAC;AAAA,MAChC;AAAA,MACA,MAAc;AAAA,MACd,OAAe;AAAA,MACf,OAAe;AAAA,MACf,mBAA4B;AAAA;AAAA;AAAA;AAAA,MAKzB,qBAA+C;AAAA,QACxD,OAAO,CAAC;AAAA,QACR,QAAQ,CAAC;AAAA,QACT,QAAQ,CAAC;AAAA,QACT,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,MACX;AAAA,MAEA,YAAY,OAA0B,CAAC,GAAG;AACzC,cAAM,UAAU,KACd,OAAO,SAAO,EAAE,eAAe,UAAS,EACxC,OAAO,CAAC,KAAK,SAAS,EAAE,GAAG,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC;AAC/C,aAAK,UAAU;AACf,aAAK,OAAO,OAAO;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASO,WAAW,WAA6C;AAC9D,aAAK,mBAAmB,MAAM,KAAK,GAAG,SAAS;AAC/C,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKO,YAAY,WAA8C;AAChE,aAAK,mBAAmB,OAAO,KAAK,GAAG,SAAS;AAChD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKO,YAAY,WAA8C;AAChE,aAAK,mBAAmB,OAAO,KAAK,GAAG,SAAS;AAChD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKO,aAAa,WAA+C;AAClE,aAAK,mBAAmB,QAAQ,KAAK,GAAG,SAAS;AACjD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKO,aAAa,WAA+C;AAClE,aAAK,mBAAmB,QAAQ,KAAK,GAAG,SAAS;AACjD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKO,gBAAgB,WAA6C;AACnE,aAAK,mBAAmB,MAAM,QAAQ,GAAG,SAAS;AAClD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKO,iBAAiB,WAA8C;AACrE,aAAK,mBAAmB,OAAO,QAAQ,GAAG,SAAS;AACnD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAMO,UAAU,QAAoC;AACpD,aAAK,SAAS;AAAA,MACf;AAAA,MAEO,YAAkC;AACxC,eAAO,KAAK;AAAA,MACb;AAAA,MAEO,IAAI,UAA+B;AACzC,aAAK,SAAS,KAAK,QAAQ;AAC3B,iBAAS,UAAU,IAAI;AAAA,MACxB;AAAA,MAEO,OAAO,UAA+B;AAC5C,cAAM,QAAQ,KAAK,SAAS,QAAQ,QAAQ;AAC5C,YAAI,UAAU,IAAI;AACjB,eAAK,SAAS,OAAO,OAAO,CAAC;AAC7B,mBAAS,UAAU,IAAI;AAAA,QACxB;AAAA,MACD;AAAA,MAEO,cAA+B;AACrC,eAAO,KAAK;AAAA,MACb;AAAA,MAEO,cAAuB;AAC7B,eAAO,KAAK,SAAS,SAAS;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA,MAsBO,UAAU,QAA4B;AAC5C,YAAI,YAAY;AAAA,QAAU;AAC1B,aAAK,mBAAmB;AAGxB,YAAI,OAAO,KAAK,WAAW,YAAY;AACtC,eAAK,OAAO,MAAM;AAAA,QACnB;AAGA,mBAAW,YAAY,KAAK,mBAAmB,OAAO;AACrD,mBAAS,MAAM;AAAA,QAChB;AAGA,aAAK,SAAS,QAAQ,WAAS,MAAM,UAAU,MAAM,CAAC;AAAA,MACvD;AAAA,MAEO,WAAW,QAAmC;AACpD,YAAI,KAAK,kBAAkB;AAC1B;AAAA,QACD;AAGA,YAAI,OAAO,KAAK,YAAY,YAAY;AACvC,eAAK,QAAQ,MAAM;AAAA,QACpB;AAGA,mBAAW,YAAY,KAAK,mBAAmB,QAAQ;AACtD,mBAAS,MAAM;AAAA,QAChB;AAGA,aAAK,SAAS,QAAQ,WAAS,MAAM,WAAW,MAAM,CAAC;AAAA,MACxD;AAAA,MAEO,YAAY,QAAoC;AAEtD,aAAK,SAAS,QAAQ,WAAS,MAAM,YAAY,MAAM,CAAC;AAGxD,mBAAW,YAAY,KAAK,mBAAmB,SAAS;AACvD,mBAAS,MAAM;AAAA,QAChB;AAGA,YAAI,OAAO,KAAK,aAAa,YAAY;AACxC,eAAK,SAAS,MAAM;AAAA,QACrB;AAEA,aAAK,mBAAmB;AAAA,MACzB;AAAA,MAEA,MAAa,WAAW,QAA4C;AAEnE,YAAI,OAAO,KAAK,YAAY,YAAY;AACvC,gBAAM,KAAK,QAAQ,MAAM;AAAA,QAC1B;AAGA,mBAAW,YAAY,KAAK,mBAAmB,QAAQ;AACtD,mBAAS,MAAM;AAAA,QAChB;AAAA,MACD;AAAA,MAEA,MAAa,YAAY,QAA6C;AAErE,mBAAW,YAAY,KAAK,mBAAmB,SAAS;AACvD,mBAAS,MAAM;AAAA,QAChB;AAGA,YAAI,OAAO,KAAK,aAAa,YAAY;AACxC,gBAAM,KAAK,SAAS,MAAM;AAAA,QAC3B;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAMO,aAAsB;AAC5B,eAAO,KAAK;AAAA,MACb;AAAA,MAEO,WAAW,SAAiC;AAClD,aAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAG,QAAQ;AAAA,MAC9C;AAAA,IACD;AAAA;AAAA;;;sBCtNCA,GAAAA;AAOA,SAAO,EAINA,KANDA,IAAMA,KAAO,oBAAIC,OAchBC,IAAAA,SAA6BC,GAAWC,GAAAA;AACvC,QAAMC,IAAmDL,EAAKM,IAAIH,CAAAA;AAC9DE,QACHA,EAASE,KAAKH,CAAAA,IAEdJ,EAAKQ,IAAIL,GAAM,CAACC,CAAAA,CAAAA;EAAAA,GAWlBK,KAAAA,SAA8BN,GAAWC,GAAAA;AACxC,QAAMC,IAAmDL,EAAKM,IAAIH,CAAAA;AAC9DE,UACCD,IACHC,EAASK,OAAOL,EAASM,QAAQP,CAAAA,MAAa,GAAG,CAAA,IAEjDJ,EAAKQ,IAAIL,GAAM,CAAA,CAAA;EAAA,GAelBS,MAAAA,SAA+BT,GAAWU,GAAAA;AACzC,QAAIR,IAAWL,EAAKM,IAAIH,CAAAA;AACpBE,SACFA,EACCS,MAAAA,EACAC,IAAI,SAACX,IAAAA;AACLA,MAAAA,GAAQS,CAAAA;IAAAA,CAAAA,IAIXR,IAAWL,EAAKM,IAAI,GAAA,MAElBD,EACCS,MAAAA,EACAC,IAAI,SAACX,IAAAA;AACLA,MAAAA,GAAQD,GAAMU,CAAAA;IAAAA,CAAAA;EAAAA,EAAAA;AAAAA;;;;;;;;ACrHpB,IAoBa;AApBb;AAAA;AAAA;AAAA;AAoBO,IAAM,uBAAN,MAAoE;AAAA,MAClE;AAAA,MACA,eAA+B,CAAC;AAAA,MAExC,cAAc;AACb,aAAK,UAAU,aAAc;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKA,SAAkC,OAAU,SAA2B;AACtE,aAAK,QAAQ,KAAK,OAAO,OAAO;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,OACC,OACA,SACa;AACb,aAAK,QAAQ,GAAG,OAAO,OAAO;AAC9B,cAAM,QAAQ,MAAM,KAAK,QAAQ,IAAI,OAAO,OAAO;AACnD,aAAK,aAAa,KAAK,KAAK;AAC5B,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,SAAqF;AAC9F,aAAK,QAAQ,GAAG,KAAK,OAAc;AACnC,cAAM,QAAQ,MAAM,KAAK,QAAQ,IAAI,KAAK,OAAc;AACxD,aAAK,aAAa,KAAK,KAAK;AAC5B,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACf,aAAK,aAAa,QAAQ,QAAM,GAAG,CAAC;AACpC,aAAK,eAAe,CAAC;AACrB,aAAK,QAAQ,IAAI,MAAM;AAAA,MACxB;AAAA,IACD;AAAA;AAAA;;;AClEA,IA4Ga;AA5Gb;AAAA;AAAA;AAAA;AA4GO,IAAM,gBAAgB,aAAkB;AAAA;AAAA;;;AC5G/C;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACDA,SAAyB,sBAAoC;AAA7D,IAgGa;AAhGb;AAAA;AAAA;AAOA;AAIA;AAUA;AA2EO,IAAM,aAAN,cACG,SAEV;AAAA,MACS,YAAwB,CAAC;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAiC;AAAA,MACjC,OAAyB;AAAA,MACzB;AAAA,MACA;AAAA,MACA,SAA8B,CAAC;AAAA,MAE/B,YAAiC,CAAC;AAAA,MAClC;AAAA,MAEA,oBAAgD;AAAA,QACrD,WAAW,CAAC;AAAA,MACd;AAAA,MACO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,sBAGH;AAAA,QACF,OAAO,CAAC;AAAA,QACR,QAAQ,CAAC;AAAA,QACT,SAAS,CAAC;AAAA,QACV,WAAW,CAAC;AAAA,MACd;AAAA;AAAA,MAGU,gBAAgB,IAAI,qBAAmC;AAAA;AAAA,MAGzD,eAA8B,CAAC;AAAA,MAEvC,cAAc;AACZ,cAAM;AAAA,MACR;AAAA,MAEO,SAAe;AACpB,cAAM,EAAE,UAAU,cAAc,IAAI,KAAK;AACzC,cAAM,EAAE,GAAG,GAAG,EAAE,IAAI,iBAAiB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACxD,aAAK,YAAY;AAAA,UACf,EAAE,WAAW,UAAU,QAAQ,EAAE,GAAG,GAAG,EAAE,EAAE;AAAA,UAC3C,EAAE,WAAW,OAAO,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,UACjD,EAAE,WAAW,UAAU,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,QAC5D;AACA,aAAK,OAAO,KAAK,QAAQ,QAAQ;AACjC,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKO,eACF,WACG;AACN,cAAM,WAAW,KAAK,kBAAkB,aAAa,CAAC;AACtD,aAAK,kBAAkB,YAAY,CAAC,GAAG,UAAU,GAAG,SAAS;AAC7D,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASO,IAIL,YACA,SACsB;AACtB,cAAM,cAA8B;AAAA,UAClC;AAAA,UACA,SAAS,EAAE,GAAG,WAAW,gBAAgB,GAAG,QAAQ;AAAA,QACtD;AACA,aAAK,aAAa,KAAK,WAA+B;AAGtD,cAAM,aAAa;AAAA,UACjB,QAAQ,MAAM,YAAY,OAAO;AAAA,UACjC,YAAY,MAAM,YAAY;AAAA,UAC9B,KAAK;AAAA,QACP;AAGA,cAAM,gBAAgB,WAAW,eAAe,WAAW,KAAM,CAAC;AAElE,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAG;AAAA,QACL;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMO,kBAAiC;AACtC,eAAO,KAAK;AAAA,MACd;AAAA;AAAA;AAAA;AAAA;AAAA,MAMO,OAAO,QAAkC;AAC9C,aAAK,oBAAoB,MAAM,QAAQ,CAAC,aAAa;AACnD,mBAAS,EAAE,GAAG,QAAQ,IAAI,KAAK,CAAC;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,MAEA,MAAgB,QAAQ,SAA6C;AAAA,MAAC;AAAA;AAAA;AAAA;AAAA;AAAA,MAM/D,QAAQ,QAAmC;AAChD,aAAK,gBAAgB,MAAM;AAC3B,aAAK,oBAAoB,OAAO,QAAQ,CAAC,aAAa;AACpD,mBAAS,EAAE,GAAG,QAAQ,IAAI,KAAK,CAAC;AAAA,QAClC,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA;AAAA,MAMO,SAAS,QAAoC;AAClD,aAAK,oBAAoB,QAAQ,QAAQ,CAAC,aAAa;AACrD,mBAAS,EAAE,GAAG,QAAQ,IAAI,KAAK,CAAC;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,MAEA,MAAgB,SAAS,SAA8C;AAAA,MAAC;AAAA,MAEjE,WAAW,OAAsB,SAAqB;AAC3D,YAAI,KAAK,kBAAkB,WAAW,QAAQ;AAC5C,gBAAM,YAAY,KAAK,kBAAkB;AACzC,oBAAU,QAAQ,CAAC,aAAa;AAC9B,qBAAS,EAAE,QAAQ,MAAM,OAAO,QAAQ,CAAC;AAAA,UAC3C,CAAC;AAAA,QACH;AACA,aAAK,oBAAoB,UAAU,QAAQ,CAAC,aAAa;AACvD,mBAAS,EAAE,QAAQ,MAAM,OAAO,QAAQ,CAAC;AAAA,QAC3C,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA;AAAA,MAMO,YAAY,kBAGV;AACP,cAAM,UAAU,iBAAiB;AAIjC,YAAI,SAAS;AACX,eAAK,oBAAoB,iBAAiB,IAAI,EAAE,KAAK,OAAO;AAAA,QAC9D;AACA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA,MAMO,aACL,mBACM;AACN,0BAAkB,QAAQ,CAAC,aAAa;AACtC,gBAAM,UAAU,SAAS;AACzB,cAAI,SAAS;AACX,iBAAK,oBAAoB,SAAS,IAAI,EAAE,KAAK,OAAO;AAAA,UACtD;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MAEU,gBAAgB,QAAa;AACrC,YAAI,CAAC,KAAK,WAAW,QAAQ;AAC3B;AAAA,QACF;AACA,mBAAW,YAAY,KAAK,WAAW;AACrC,cAAI,oBAAoB,gBAAgB;AACtC,gBAAI,SAAS,UAAU;AACrB,uBAAS,SAAS,UACf,SAAS,SAAS,MAAM,SAAS,OAAO;AAAA,YAC7C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEO,YAAoC;AACzC,cAAM,OAA+B,CAAC;AACtC,aAAK,OAAO,KAAK;AACjB,aAAK,OAAO,KAAK;AACjB,aAAK,MAAM,KAAK,IAAI,SAAS;AAC7B,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,SACE,OACA,SACM;AACN,aAAK,cAAc,SAAS,OAAO,OAAO;AAC1C,QAAC,cAAsB,KAAK,OAAO,OAAO;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OACE,OACA,SACY;AACZ,eAAO,KAAK,cAAc,OAAO,OAAO,OAAO;AAAA,MACjD;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAsB;AACpB,aAAK,cAAc,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA;AAAA;;;ACtVA,SAAS,eAAwB,sBAAyC;AAJ1E,IAaa;AAbb;AAAA;AAAA;AAaO,IAAM,uBAAN,MAA6D;AAAA,MAC3D;AAAA,MAER,cAAc;AACb,aAAK,SAAS,IAAI,cAAc;AAAA,MACjC;AAAA,MAEA,YAAY,KAAsB;AACjC,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAC9C,eAAO,CAAC,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,KAAK,EAAE,SAAS,OAAO,EAAE;AAAA,MAC9E;AAAA,MAEA,MAAM,KAAK,KAAa,SAA4C;AACnE,cAAM,UAAU,MAAM,KAAK,OAAO,UAAU,KAAK,CAAC,UAAU;AAC3D,cAAI,SAAS,cAAc,MAAM,kBAAkB;AAClD,oBAAQ,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,UAC9C;AAAA,QACD,CAAC;AAGD,YAAI,SAAS,QAAQ;AACpB,kBAAQ,OAAO,KAAK,QAAQ,MAAM;AAAA,QACnC;AACA,gBAAQ,QAAQ,SAAS,SAAS;AAClC,gBAAQ,QAAQ,SAAS,SAAS;AAElC,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAA2B;AAChC,cAAM,SAAS,QAAQ,MAAM;AAC7B,eAAO,cAAc;AACrB,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;AC7CA,SAAe,kBAAkB;AALjC,IAiBa;AAjBb;AAAA;AAAA;AAiBO,IAAM,oBAAN,MAAkE;AAAA,MAChE;AAAA,MAER,cAAc;AACb,aAAK,SAAS,IAAI,WAAW;AAAA,MAC9B;AAAA,MAEA,YAAY,KAAsB;AACjC,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAC9C,eAAO,CAAC,QAAQ,KAAK,EAAE,SAAS,OAAO,EAAE;AAAA,MAC1C;AAAA,MAEA,MAAM,KAAK,KAAa,SAAqD;AAC5E,YAAI,SAAS,eAAe;AAC3B,iBAAO,KAAK,mBAAmB,KAAK,OAAO;AAAA,QAC5C;AACA,eAAO,KAAK,eAAe,KAAK,OAAO;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAc,mBAAmB,KAAa,SAAqD;AAClG,YAAI;AACH,gBAAM,WAAW,MAAM,MAAM,GAAG;AAChC,cAAI,CAAC,SAAS,IAAI;AACjB,kBAAM,IAAI,MAAM,mBAAmB,GAAG,KAAK,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,UACpF;AACA,gBAAM,SAAS,MAAM,SAAS,YAAY;AAI1C,gBAAM,OAAO,MAAM,KAAK,OAAO,WAAW,QAAQ,GAAG;AAErD,iBAAO;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,YAAY,KAAK;AAAA,YACjB;AAAA,UACD;AAAA,QACD,SAAS,OAAO;AACf,kBAAQ,MAAM,oCAAoC,GAAG,oCAAoC,KAAK;AAC9F,iBAAO,KAAK,eAAe,KAAK,OAAO;AAAA,QACxC;AAAA,MACD;AAAA,MAEA,MAAc,eAAe,KAAa,SAAqD;AAC9F,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,eAAK,OAAO;AAAA,YACX;AAAA,YACA,CAAC,SAAe;AACf,sBAAQ;AAAA,gBACP,QAAQ,KAAK;AAAA,gBACb,YAAY,KAAK;AAAA,gBACjB;AAAA,cACD,CAAC;AAAA,YACF;AAAA,YACA,CAAC,UAAU;AACV,kBAAI,SAAS,cAAc,MAAM,kBAAkB;AAClD,wBAAQ,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,cAC9C;AAAA,YACD;AAAA,YACA,CAAC,UAAU,OAAO,KAAK;AAAA,UACxB;AAAA,QACD,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAA0C;AAC/C,eAAO;AAAA,UACN,QAAQ,OAAO,OAAO,MAAM;AAAA,UAC5B,YAAY,OAAO,YAAY,IAAI,UAAQ,KAAK,MAAM,CAAC;AAAA,UACvD,MAAM,OAAO;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACxFA,SAAS,iBAAiB;AAN1B,IAiBa;AAjBb;AAAA;AAAA;AAiBO,IAAM,mBAAN,MAAiE;AAAA,MAC/D;AAAA,MAER,cAAc;AACb,aAAK,SAAS,IAAI,UAAU;AAAA,MAC7B;AAAA,MAEA,YAAY,KAAsB;AACjC,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAC9C,eAAO,QAAQ;AAAA,MAChB;AAAA,MAEA,MAAM,KAAK,KAAa,SAAoD;AAC3E,YAAI,SAAS,eAAe;AAC3B,iBAAO,KAAK,mBAAmB,KAAK,OAAO;AAAA,QAC5C;AACA,eAAO,KAAK,eAAe,KAAK,OAAO;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,mBAAmB,KAAa,UAAqD;AAClG,YAAI;AACH,gBAAM,WAAW,MAAM,MAAM,GAAG;AAChC,cAAI,CAAC,SAAS,IAAI;AACjB,kBAAM,IAAI,MAAM,mBAAmB,GAAG,KAAK,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,UACpF;AACA,gBAAM,SAAS,MAAM,SAAS,YAAY;AAG1C,gBAAM,SAAS,KAAK,OAAO,MAAM,QAAQ,GAAG;AAE5C,iBAAO;AAAA,YACN;AAAA,YACA,YAAa,OAAe,cAAc,CAAC;AAAA,UAC5C;AAAA,QACD,SAAS,OAAO;AACf,kBAAQ,MAAM,mCAAmC,GAAG,oCAAoC,KAAK;AAC7F,iBAAO,KAAK,eAAe,KAAK,QAAQ;AAAA,QACzC;AAAA,MACD;AAAA,MAEA,MAAc,eAAe,KAAa,SAAoD;AAC7F,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,eAAK,OAAO;AAAA,YACX;AAAA,YACA,CAAC,WAAqB;AACrB,sBAAQ;AAAA,gBACP;AAAA,gBACA,YAAa,OAAe,cAAc,CAAC;AAAA,cAC5C,CAAC;AAAA,YACF;AAAA,YACA,CAAC,UAAU;AACV,kBAAI,SAAS,cAAc,MAAM,kBAAkB;AAClD,wBAAQ,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,cAC9C;AAAA,YACD;AAAA,YACA,CAAC,UAAU,OAAO,KAAK;AAAA,UACxB;AAAA,QACD,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAA0C;AAC/C,eAAO;AAAA,UACN,QAAQ,OAAO,OAAO,MAAM;AAAA,UAC5B,YAAY,OAAO,YAAY,IAAI,UAAQ,KAAK,MAAM,CAAC;AAAA,QACxD;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACnFA,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAP1B,IAea;AAfb;AAAA;AAAA;AAeO,IAAM,mBAAN,MAAiE;AAAA,MAC/D;AAAA,MACA;AAAA,MAER,cAAc;AACb,aAAK,SAAS,IAAI,UAAU;AAC5B,aAAK,YAAY,IAAI,UAAU;AAAA,MAChC;AAAA,MAEA,YAAY,KAAsB;AACjC,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAC9C,eAAO,QAAQ;AAAA,MAChB;AAAA,MAEA,MAAM,KAAK,KAAa,SAAoD;AAE3E,YAAI,SAAS,SAAS;AACrB,gBAAM,KAAK,QAAQ,QAAQ,OAAO;AAAA,QACnC;AAEA,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,eAAK,OAAO;AAAA,YACX;AAAA,YACA,CAAC,WAAkB;AAClB,sBAAQ;AAAA,gBACP;AAAA,gBACA,YAAY,CAAC;AAAA,cACd,CAAC;AAAA,YACF;AAAA,YACA,CAAC,UAAU;AACV,kBAAI,SAAS,cAAc,MAAM,kBAAkB;AAClD,wBAAQ,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,cAC9C;AAAA,YACD;AAAA,YACA,CAAC,UAAU,OAAO,KAAK;AAAA,UACxB;AAAA,QACD,CAAC;AAAA,MACF;AAAA,MAEA,MAAc,QAAQ,KAA4B;AACjD,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,eAAK,UAAU;AAAA,YACd;AAAA,YACA,CAAC,cAAc;AACd,wBAAU,QAAQ;AAClB,mBAAK,OAAO,aAAa,SAAS;AAClC,sBAAQ;AAAA,YACT;AAAA,YACA;AAAA,YACA,CAAC,UAAU,OAAO,KAAK;AAAA,UACxB;AAAA,QACD,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAA0C;AAC/C,eAAO;AAAA,UACN,QAAQ,OAAO,OAAO,MAAM;AAAA,UAC5B,YAAY,CAAC;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;AC1EA,SAAS,mBAAmB;AAJ5B,IAOa;AAPb;AAAA;AAAA;AAOO,IAAM,qBAAN,MAA+D;AAAA,MAC7D;AAAA,MAER,cAAc;AACb,aAAK,SAAS,IAAI,YAAY;AAAA,MAC/B;AAAA,MAEA,YAAY,KAAsB;AACjC,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAC9C,eAAO,CAAC,OAAO,OAAO,OAAO,QAAQ,OAAO,KAAK,EAAE,SAAS,OAAO,EAAE;AAAA,MACtE;AAAA,MAEA,MAAM,KAAK,KAAa,SAAkD;AACzE,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,eAAK,OAAO;AAAA,YACX;AAAA,YACA,CAAC,WAAW,QAAQ,MAAM;AAAA,YAC1B,CAAC,UAAU;AACV,kBAAI,SAAS,cAAc,MAAM,kBAAkB;AAClD,wBAAQ,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,cAC9C;AAAA,YACD;AAAA,YACA,CAAC,UAAU,OAAO,KAAK;AAAA,UACxB;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAAA;AAAA;;;AC7BA,SAAS,kBAAkB;AAJ3B,IAWa,mBAkCA;AA7Cb;AAAA;AAAA;AAWO,IAAM,oBAAN,MAAuE;AAAA,MACrE;AAAA,MAER,cAAc;AACb,aAAK,SAAS,IAAI,WAAW;AAAA,MAC9B;AAAA,MAEA,YAAY,MAAuB;AAElC,eAAO;AAAA,MACR;AAAA,MAEA,MAAM,KAAK,KAAa,SAA0D;AACjF,cAAM,eAAe,SAAS,gBAAgB;AAC9C,aAAK,OAAO,gBAAgB,YAAmB;AAE/C,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,eAAK,OAAO;AAAA,YACX;AAAA,YACA,CAAC,SAAS,QAAQ,IAA4B;AAAA,YAC9C,CAAC,UAAU;AACV,kBAAI,SAAS,cAAc,MAAM,kBAAkB;AAClD,wBAAQ,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,cAC9C;AAAA,YACD;AAAA,YACA,CAAC,UAAU,OAAO,KAAK;AAAA,UACxB;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAKO,IAAM,oBAAN,MAA0D;AAAA,MACxD;AAAA,MAER,cAAc;AACb,aAAK,aAAa,IAAI,kBAAkB;AAAA,MACzC;AAAA,MAEA,YAAY,KAAsB;AACjC,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAC9C,eAAO,QAAQ;AAAA,MAChB;AAAA,MAEA,MAAM,KAAkB,KAAa,SAAwC;AAC5E,cAAM,OAAO,MAAM,KAAK,WAAW,KAAK,KAAK,EAAE,GAAG,SAAS,cAAc,OAAO,CAAC;AACjF,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;AC7DA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACFA,SAA4B,gBAAgB,aAAa;AAPzD,IAqDa,cAyZA;AA9cb;AAAA;AAAA;AASA;AAUA;AAkCO,IAAM,eAAN,MAAM,cAAa;AAAA,MACzB,OAAe,WAAgC;AAAA;AAAA,MAGvC,eAAiD,oBAAI,IAAI;AAAA,MACzD,aAAuD,oBAAI,IAAI;AAAA,MAC/D,aAAmD,oBAAI,IAAI;AAAA,MAC3D,YAA2D,oBAAI,IAAI;AAAA,MACnE,YAA8C,oBAAI,IAAI;AAAA;AAAA,MAGtD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA;AAAA,MAGA;AAAA;AAAA,MAGA,QAAQ;AAAA,QACf,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,aAAa;AAAA,QACb,aAAa;AAAA,QACb,WAAW;AAAA,QACX,aAAa;AAAA,MACd;AAAA,MAEQ,cAAc;AAErB,aAAK,gBAAgB,IAAI,qBAAqB;AAC9C,aAAK,aAAa,IAAI,kBAAkB;AACxC,aAAK,YAAY,IAAI,iBAAiB;AACtC,aAAK,YAAY,IAAI,iBAAiB;AACtC,aAAK,cAAc,IAAI,mBAAmB;AAC1C,aAAK,aAAa,IAAI,kBAAkB;AACxC,aAAK,aAAa,IAAI,kBAAkB;AAGxC,aAAK,iBAAiB,IAAI,eAAe;AACzC,aAAK,eAAe,aAAa,CAAC,KAAK,QAAQ,UAAU;AACxD,eAAK,OAAO,KAAK,kBAAkB,EAAE,QAAQ,MAAM,CAAC;AAAA,QACrD;AAGA,aAAK,SAAS,aAAyB;AAGvC,cAAM,UAAU;AAAA,MACjB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,cAA4B;AAClC,YAAI,CAAC,cAAa,UAAU;AAC3B,wBAAa,WAAW,IAAI,cAAa;AAAA,QAC1C;AACA,eAAO,cAAa;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,gBAAsB;AAC5B,YAAI,cAAa,UAAU;AAC1B,wBAAa,SAAS,WAAW;AACjC,wBAAa,WAAW;AAAA,QACzB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,YAAY,KAAa,SAA4C;AAC1E,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,cAAc,KAAK,KAAK,OAAO;AAAA,UAC1C;AAAA,UACA,CAAC,YAAY,SAAS,QAAQ,KAAK,cAAc,MAAM,OAAO,IAAI;AAAA,QACnE;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,SAAS,KAAa,SAAqD;AAChF,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,WAAW,KAAK,KAAK,OAAO;AAAA,UACvC;AAAA,UACA,CAAC,WAAW,SAAS,QAAQ,KAAK,WAAW,MAAM,MAAM,IAAI;AAAA,QAC9D;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAQ,KAAa,SAAoD;AAC9E,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,UAAU,KAAK,KAAK,OAAO;AAAA,UACtC;AAAA,UACA,CAAC,WAAW,SAAS,QAAQ,KAAK,UAAU,MAAM,MAAM,IAAI;AAAA,QAC7D;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAQ,KAAa,SAAoD;AAE9E,cAAM,WAAW,SAAS,UAAU,GAAG,GAAG,IAAI,QAAQ,OAAO,KAAK;AAClE,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,UAAU,KAAK,KAAK,OAAO;AAAA,UACtC;AAAA,UACA,CAAC,WAAW,SAAS,QAAQ,KAAK,UAAU,MAAM,MAAM,IAAI;AAAA,QAC7D;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,UAAU,KAAa,SAAsD;AAClF,cAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAE9C,gBAAQ,KAAK;AAAA,UACZ,KAAK;AAAA,UACL,KAAK;AACJ,mBAAO,KAAK,SAAS,KAAK,OAAO;AAAA,UAClC,KAAK;AACJ,mBAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,UACjC,KAAK;AACJ,mBAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,UACjC;AACC,kBAAM,IAAI,MAAM,6BAA6B,GAAG,EAAE;AAAA,QACpD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,UAAU,KAAa,SAAkD;AAC9E,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,YAAY,KAAK,KAAK,OAAO;AAAA,UACxC;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,SAAS,KAAa,SAA0D;AACrF,cAAM,WAAW,SAAS,eAAe,GAAG,GAAG,IAAI,QAAQ,YAAY,KAAK;AAC5E,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,WAAW,KAAK,KAAK,OAAO;AAAA,UACvC;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAsB,KAAa,SAAwC;AAChF,eAAO,KAAK;AAAA,UACX;AAAA;AAAA,UAEA,KAAK;AAAA,UACL,MAAM,KAAK,WAAW,KAAQ,KAAK,OAAO;AAAA,UAC1C;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,UAAU,OAAmD;AAClE,cAAM,UAAU,oBAAI,IAAiB;AAErC,cAAM,WAAW,MAAM,IAAI,OAAO,SAAS;AAC1C,cAAI;AACH,gBAAI;AAEJ,oBAAQ,KAAK,MAAM;AAAA,cAClB;AACC,yBAAS,MAAM,KAAK,YAAY,KAAK,KAAK,KAAK,OAAO;AACtD;AAAA,cACD;AACC,yBAAS,MAAM,KAAK,SAAS,KAAK,KAAK,KAAK,OAAO;AACnD;AAAA,cACD;AACC,yBAAS,MAAM,KAAK,QAAQ,KAAK,KAAK,KAAK,OAAO;AAClD;AAAA,cACD;AACC,yBAAS,MAAM,KAAK,QAAQ,KAAK,KAAK,KAAK,OAAO;AAClD;AAAA,cACD;AACC,yBAAS,MAAM,KAAK,UAAU,KAAK,KAAK,KAAK,OAAO;AACpD;AAAA,cACD;AACC,yBAAS,MAAM,KAAK,SAAS,KAAK,KAAK,KAAK,OAAO;AACnD;AAAA,cACD;AACC,yBAAS,MAAM,KAAK,SAAS,KAAK,KAAK,KAAK,OAAO;AACnD;AAAA,cACD;AACC,sBAAM,IAAI,MAAM,uBAAuB,KAAK,IAAI,EAAE;AAAA,YACpD;AAEA,oBAAQ,IAAI,KAAK,KAAK,MAAM;AAAA,UAC7B,SAAS,OAAO;AACf,iBAAK,OAAO,KAAK,eAAe;AAAA,cAC/B,KAAK,KAAK;AAAA,cACV,MAAM,KAAK;AAAA,cACX;AAAA,YACD,CAAC;AACD,kBAAM;AAAA,UACP;AAAA,QACD,CAAC;AAED,cAAM,QAAQ,IAAI,QAAQ;AAE1B,aAAK,OAAO,KAAK,kBAAkB,EAAE,MAAM,MAAM,IAAI,OAAK,EAAE,GAAG,EAAE,CAAC;AAElE,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAQ,OAAuC;AACpD,cAAM,KAAK,UAAU,KAAK;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,SAAS,KAAsB;AAC9B,eAAO,KAAK,aAAa,IAAI,GAAG,KAC/B,KAAK,WAAW,IAAI,GAAG,KACvB,KAAK,WAAW,IAAI,GAAG,KACvB,KAAK,UAAU,IAAI,GAAG,KACtB,KAAK,UAAU,IAAI,GAAG;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA,MAKA,WAAW,KAAoB;AAC9B,YAAI,KAAK;AACR,eAAK,aAAa,OAAO,GAAG;AAC5B,eAAK,WAAW,OAAO,GAAG;AAC1B,eAAK,WAAW,OAAO,GAAG;AAC1B,eAAK,UAAU,OAAO,GAAG;AACzB,eAAK,UAAU,OAAO,GAAG;AAAA,QAC1B,OAAO;AACN,eAAK,aAAa,MAAM;AACxB,eAAK,WAAW,MAAM;AACtB,eAAK,WAAW,MAAM;AACtB,eAAK,UAAU,MAAM;AACrB,eAAK,UAAU,MAAM;AACrB,gBAAM,MAAM;AAAA,QACb;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,WAA8B;AAC7B,eAAO,EAAE,GAAG,KAAK,MAAM;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,GACC,OACA,SACO;AACP,aAAK,OAAO,GAAG,OAAO,OAAO;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKA,IACC,OACA,SACO;AACP,aAAK,OAAO,IAAI,OAAO,OAAO;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,cACb,KACA,MACA,OACA,QACA,SACA,QACa;AAEb,YAAI,SAAS,aAAa;AACzB,gBAAM,OAAO,GAAG;AAAA,QACjB;AAGA,cAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,YAAI,QAAQ;AACX,eAAK,MAAM;AACX,eAAK,OAAO,KAAK,gBAAgB,EAAE,KAAK,MAAM,WAAW,KAAK,CAAC;AAE/D,gBAAM,SAAS,MAAM,OAAO;AAC5B,iBAAO,SAAS,OAAO,MAAM,IAAI;AAAA,QAClC;AAGA,aAAK,MAAM;AACX,aAAK,OAAO,KAAK,iBAAiB,EAAE,KAAK,KAAK,CAAC;AAE/C,cAAM,UAAU,OAAO;AACvB,cAAM,QAAuB;AAAA,UAC5B;AAAA,UACA,UAAU,KAAK,IAAI;AAAA,QACpB;AACA,cAAM,IAAI,KAAK,KAAK;AAEpB,YAAI;AACH,gBAAM,SAAS,MAAM;AACrB,gBAAM,SAAS;AAGf,eAAK,YAAY,IAAI;AAErB,eAAK,OAAO,KAAK,gBAAgB,EAAE,KAAK,MAAM,WAAW,MAAM,CAAC;AAEhE,iBAAO,SAAS,OAAO,MAAM,IAAI;AAAA,QAClC,SAAS,OAAO;AAEf,gBAAM,OAAO,GAAG;AAChB,eAAK,OAAO,KAAK,eAAe,EAAE,KAAK,MAAM,MAAsB,CAAC;AACpE,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,MAEQ,YAAY,MAAuB;AAC1C,gBAAQ,MAAM;AAAA,UACb;AACC,iBAAK,MAAM;AACX;AAAA,UACD;AAAA,UACA;AAAA,UACA;AACC,iBAAK,MAAM;AACX;AAAA,UACD;AACC,iBAAK,MAAM;AACX;AAAA,UACD;AAAA,UACA;AACC,iBAAK,MAAM;AACX;AAAA,QACF;AAAA,MACD;AAAA,IACD;AAKO,IAAM,eAAe,aAAa,YAAY;AAAA;AAAA;;;AC9crD,IAuBa;AAvBb;AAAA;AAAA;AASA;AAcO,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA;AAAA,MAI9B,MAAM,SAAS,MAA0C;AACxD,cAAM,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAE/C,gBAAQ,KAAK;AAAA,UACZ,KAAK,OAAO;AACX,kBAAM,SAAS,MAAM,aAAa,QAAQ,IAAI;AAC9C,mBAAO;AAAA,cACN,QAAQ,OAAO;AAAA,cACf,WAAW,OAAO,aAAa,CAAC;AAAA,YACjC;AAAA,UACD;AAAA,UACA,KAAK;AAAA,UACL,KAAK,OAAO;AACX,kBAAM,SAAS,MAAM,aAAa,SAAS,IAAI;AAC/C,mBAAO;AAAA,cACN,QAAQ,OAAO;AAAA,cACf,MAAM,OAAO;AAAA,YACd;AAAA,UACD;AAAA,UACA,KAAK,OAAO;AACX,kBAAM,SAAS,MAAM,aAAa,QAAQ,IAAI;AAC9C,mBAAO;AAAA,cACN,QAAQ,OAAO;AAAA,YAChB;AAAA,UACD;AAAA,UACA;AACC,kBAAM,IAAI,MAAM,0BAA0B,IAAI,EAAE;AAAA,QAClD;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACxDA;AAAA,EAGC;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AAPP,IAuBa;AAvBb;AAAA;AAAA;AAQA;AAeO,IAAM,oBAAN,MAAwB;AAAA,MAc9B,YAAoB,QAAkB;AAAlB;AAAA,MAAoB;AAAA,MAbhC,SAAgC;AAAA,MAChC,WAA4C,CAAC;AAAA,MAC7C,cAA+B,CAAC;AAAA,MAChC,iBAAyC;AAAA,MAEzC,qBAAqB;AAAA,MACrB,YAAY;AAAA,MACZ,aAA4B;AAAA,MAC5B,gBAAgB;AAAA,MAEhB,cAAsB;AAAA,MACtB,eAAe,IAAI,kBAAkB;AAAA,MAI7C,MAAM,eAAe,YAA8C;AAClE,YAAI,CAAC,WAAW,OAAQ;AAExB,cAAM,UAAU,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAK,KAAK,aAAa,SAAS,EAAE,IAAI,CAAC,CAAC;AACzF,aAAK,cAAc,QACjB,OAAO,CAAC,MAA8B,CAAC,CAAC,EAAE,SAAS,EACnD,IAAI,OAAK,EAAE,SAAU;AAEvB,YAAI,CAAC,KAAK,YAAY,OAAQ;AAE9B,aAAK,SAAS,IAAI,eAAe,KAAK,MAAM;AAC5C,aAAK,YAAY,QAAQ,CAAC,MAAM,MAAM;AACrC,gBAAM,MAAM,WAAW,CAAC,EAAE,OAAO,EAAE,SAAS;AAC5C,eAAK,SAAS,GAAG,IAAI,KAAK,OAAQ,WAAW,IAAI;AAAA,QAClD,CAAC;AAED,aAAK,cAAc,EAAE,KAAK,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC,EAAE,CAAC;AAAA,MAC1D;AAAA,MAEA,OAAO,OAAqB;AAC3B,YAAI,CAAC,KAAK,UAAU,CAAC,KAAK,eAAgB;AAE1C,aAAK,OAAO,OAAO,KAAK;AAExB,cAAM,cAAc,KAAK,eAAe,QAAQ,EAAE,YAAY,KAAK,qBAAqB;AACxF,YACC,CAAC,KAAK,aACN,KAAK,qBAAqB,KAC1B,KAAK,eAAe,QAAQ,aAC3B;AACD,eAAK,eAAe,OAAO;AAC3B,eAAK,eAAe,SAAS;AAC7B,eAAK,YAAY;AAEjB,cAAI,KAAK,eAAe,MAAM;AAC7B,kBAAM,OAAO,KAAK,SAAS,KAAK,UAAU;AAC1C,iBAAK,MAAM,EAAE,KAAK;AAClB,iBAAK,eAAe,YAAY,MAAM,KAAK,eAAe,KAAK;AAC/D,iBAAK,iBAAiB;AACtB,iBAAK,cAAc,KAAK;AACxB,iBAAK,aAAa;AAAA,UACnB;AAAA,QACD;AAAA,MACD;AAAA,MAEA,cAAc,MAA8B;AAC3C,YAAI,CAAC,KAAK,OAAQ;AAClB,cAAM,EAAE,KAAK,oBAAoB,GAAG,aAAa,OAAO,WAAW,eAAe,IAAI,IAAI;AAC1F,YAAI,QAAQ,KAAK,YAAa;AAE9B,aAAK,aAAa,aAAa;AAC/B,aAAK,gBAAgB;AAErB,aAAK,qBAAqB,aAAa,MAAM;AAC7C,aAAK,YAAY;AAEjB,cAAM,OAAO,KAAK;AAClB,YAAI,KAAM,MAAK,KAAK;AAEpB,cAAM,SAAS,KAAK,SAAS,GAAG;AAChC,YAAI,CAAC,OAAQ;AAEb,YAAI,KAAK,qBAAqB,GAAG;AAChC,iBAAO,QAAQ,UAAU,QAAQ;AACjC,iBAAO,oBAAoB;AAAA,QAC5B,OAAO;AACN,iBAAO,QAAQ,YAAY,QAAQ;AACnC,iBAAO,oBAAoB;AAAA,QAC5B;AAEA,YAAI,MAAM;AACT,eAAK,YAAY,QAAQ,cAAc,KAAK;AAAA,QAC7C;AACA,eAAO,MAAM,EAAE,KAAK;AAEpB,aAAK,iBAAiB;AACtB,aAAK,cAAc;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AAEf,eAAO,OAAO,KAAK,QAAQ,EAAE,QAAQ,YAAU;AAC9C,iBAAO,KAAK;AAAA,QACb,CAAC;AAGD,YAAI,KAAK,QAAQ;AAChB,eAAK,OAAO,cAAc;AAC1B,eAAK,OAAO,YAAY,KAAK,MAAM;AACnC,eAAK,SAAS;AAAA,QACf;AAGA,aAAK,WAAW,CAAC;AACjB,aAAK,cAAc,CAAC;AACpB,aAAK,iBAAiB;AACtB,aAAK,cAAc;AAAA,MACpB;AAAA,MAEA,IAAI,sBAAsB;AAAE,eAAO,KAAK;AAAA,MAAa;AAAA,MACrD,IAAI,aAAa;AAAE,eAAO,KAAK;AAAA,MAAa;AAAA,IAC7C;AAAA;AAAA;;;AC/IA,IAAa;AAAb;AAAA;AAAA;AAAO,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAlC,IAEM,UAWO;AAbb;AAAA;AAAA;AAAA;AAEA,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWV,IAAM,iBAAiB;AAAA,MAC1B,QAAQ;AAAA,MACR;AAAA,IACJ;AAAA;AAAA;;;AChBA,SAAS,SAAAG,QAAO,eAAe;AAA/B,IAIa;AAJb;AAAA;AAAA;AACA;AAGO,IAAM,iBAA6C;AAAA,MACtD,UAAU,IAAI,QAAQ,GAAG,GAAG,CAAC;AAAA,MAC7B,UAAU;AAAA,QACN,OAAO,IAAIA,OAAM,SAAS;AAAA,QAC1B,QAAQ;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACP,QAAQ;AAAA,MACZ;AAAA,IACJ;AAAA;AAAA;;;ACbA,SAAS,SAAAC,cAAa;AAuCf,SAAS,eAA2B;AAC1C,SAAO,WAAW;AACnB;AAUO,SAAS,kBAAkB,QAAsC;AACvE,aAAW,iBAAiB;AAC7B;AAEO,SAAS,mBAA2C;AAC1D,SAAO,WAAW;AACnB;AAEO,SAAS,iBAAiB,QAAsC;AACtE,aAAW,gBAAgB;AAC5B;AAEO,SAAS,qBAA2B;AAC1C,aAAW,gBAAgB;AAC5B;AAjEA,IAca;AAdb;AAAA;AAAA;AAcO,IAAM,aAAaA,OAAkB;AAAA,MAC3C,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,OAAO,oBAAI,IAAI;AAAA,IAChB,CAAC;AAAA;AAAA;;;ACrBD,SAAS,OAAO,cAAAC,aAAY,WAAAC,gBAAe;AASpC,SAAS,cAAc,SAAkF;AAC/G,SAAO;AAAA,IACN,OAAO,OAAO,OAAc,GAAW,MAAc;AACpD,YAAM,WAAW,MAAM,QAAQ,QAAQ,QAAQ,GAAG,CAAC,CAAC;AACpD,YAAM,IAAI,QAAQ;AAClB,aAAO;AAAA,IACR;AAAA,IACA,eAAe,OAAO,QAAa,OAAc,SAAkB,IAAIA,SAAQ,GAAG,CAAC,MAAM;AACxF,UAAI,CAAC,OAAO,MAAM;AACjB,gBAAQ,KAAK,8CAA8C;AAC3D,eAAO;AAAA,MACR;AAEA,YAAM,EAAE,GAAG,GAAG,EAAE,IAAI,OAAO,KAAK,YAAY;AAC5C,UAAI,KAAM,OAAe,oBAAoB;AAC7C,UAAI;AACH,cAAM,IAAI,OAAO,KAAK,SAAS;AAC/B,cAAM,IAAI,IAAID,YAAW,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC3C,cAAM,IAAI,IAAI,MAAM,EAAE,kBAAkB,GAAG,KAAK;AAChD,aAAK,EAAE;AAAA,MACR,QAAQ;AAAA,MAA2B;AAEnC,YAAM,UAAU,KAAK,IAAI,CAAC,EAAE,KAAK,OAAO,KAAK;AAC7C,YAAM,UAAU,KAAK,IAAI,CAAC,EAAE,KAAK,OAAO,KAAK;AAE7C,YAAM,WAAW,MAAM,QAAQ,QAAQ,QAAQ,IAAI,SAAS,IAAI,OAAO,CAAC;AACxE,YAAM,IAAI,QAAQ;AAClB,aAAO;AAAA,IACR;AAAA,EACD;AACD;AAvCA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAa;AAAb;AAAA;AAAA;AAAO,IAAM,eAAe;AAAA,MAC3B,aAAa;AAAA,MACb,aAAa;AAAA,MACb,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,IACV;AAAA;AAAA;;;ACNA,SAAyB,WAAAE,gBAA8B;AAAvD,IAYa;AAZb;AAAA;AAAA;AAYO,IAAM,oBAAN,MAAyD;AAAA,MAC/D;AAAA,MACA,mBAAmC;AAAA,MACnC,WAAiC;AAAA,MACjC,QAAsB;AAAA,MACtB,YAAgC;AAAA,MAEhC,cAAc;AACb,aAAK,WAAW,IAAIA,SAAQ,GAAG,GAAG,CAAC;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAmG;AACxG,cAAM,EAAE,kBAAkB,UAAU,OAAO,OAAO,IAAI;AACtD,aAAK,mBAAmB;AACxB,aAAK,WAAW;AAChB,aAAK,QAAQ;AACb,aAAK,YAAY;AAAA,MAClB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,OAAe;AACrB,YAAI,CAAC,KAAK,UAAW,QAAQ;AAC5B;AAAA,QACD;AAEA,cAAM,wBAAwB,KAAK,UAAW,OAAQ,MAAM,SAAS,MAAM,EAAE,IAAI,KAAK,QAAQ;AAC9F,aAAK,UAAW,OAAO,SAAS,KAAK,uBAAuB,GAAG;AAC/D,aAAK,UAAW,OAAO,OAAO,KAAK,UAAW,OAAQ,MAAM,QAAQ;AAAA,MACrE;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,OAAe,QAAgB;AACrC,YAAI,KAAK,kBAAkB;AAC1B,eAAK,iBAAiB,IAAI,OAAO,MAAM;AAAA,QACxC;AAAA,MAED;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,UAAmB;AAC9B,aAAK,WAAW;AAAA,MACjB;AAAA,IACD;AAAA;AAAA;;;AC/DA,IAOa;AAPb;AAAA;AAAA;AAOO,IAAM,gBAAN,MAAqD;AAAA,MAC3D,mBAAmC;AAAA,MACnC,WAAiC;AAAA,MACjC,QAAsB;AAAA,MACtB,YAAgC;AAAA,MAEhC,cAAc;AAAA,MAEd;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAmG;AACxG,cAAM,EAAE,kBAAkB,UAAU,OAAO,OAAO,IAAI;AACtD,aAAK,mBAAmB;AACxB,aAAK,WAAW;AAChB,aAAK,QAAQ;AACb,aAAK,YAAY;AAGjB,aAAK,UAAU,OAAO,SAAS,IAAI,GAAG,GAAG,EAAE;AAC3C,aAAK,UAAU,OAAO,OAAO,GAAG,GAAG,CAAC;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAO,OAAe;AAAA,MAGtB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,OAAe,QAAgB;AACrC,YAAI,KAAK,kBAAkB;AAC1B,eAAK,iBAAiB,IAAI,OAAO,MAAM;AAAA,QACxC;AAAA,MAID;AAAA,IACD;AAAA;AAAA;;;ACpDA,YAAY,WAAW;AAEvB,SAAwB,yBAAyB;AACjD,SAAS,MAAM,sBAAsB;AAHrC,IAKqB;AALrB;AAAA;AAAA;AACA;AAIA,IAAqB,aAArB,cAAwC,KAAK;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,YAAY,YAA2B,OAAoB,QAAsB;AAChF,cAAM;AACN,aAAK,aAAa;AAClB,aAAK,SAAS,IAAI,eAAe,KAAK,SAAS,CAAC;AAChD,aAAK,QAAQ;AACb,aAAK,SAAS;AAEd,aAAK,kBAAkB,IAAI,kBAAkB,WAAW,IAAI,GAAG,WAAW,IAAI,CAAC;AAC/E,aAAK,qBAAqB,IAAI,kBAAkB,WAAW,IAAI,GAAG,WAAW,IAAI,CAAC;AAElF,aAAK,iBAAiB,IAAU,yBAAmB;AAAA,MACpD;AAAA,MAEA,OACC,UACA,aACC;AACD,iBAAS,gBAAgB,KAAK,eAAe;AAC7C,iBAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAEvC,cAAM,uBAAuB,KAAK,MAAM;AACxC,iBAAS,gBAAgB,KAAK,kBAAkB;AAChD,aAAK,MAAM,mBAAmB,KAAK;AACnC,iBAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AACvC,aAAK,MAAM,mBAAmB;AAG9B,cAAM,WAAW,KAAK,OAAO,SAAS;AACtC,iBAAS,SAAS,QAAQ,KAAK,gBAAgB;AAC/C,iBAAS,OAAO,QAAQ,KAAK,gBAAgB;AAC7C,iBAAS,QAAQ,QAAQ,KAAK,mBAAmB;AACjD,iBAAS,MAAM,SAAS;AAExB,YAAI,KAAK,gBAAgB;AACxB,mBAAS,gBAAgB,IAAI;AAAA,QAC9B,OAAO;AACN,mBAAS,gBAAgB,WAAW;AAAA,QACrC;AACA,aAAK,OAAO,OAAO,QAAQ;AAAA,MAC5B;AAAA,MAEA,WAAW;AACV,eAAO,IAAU,qBAAe;AAAA,UAC/B,UAAU;AAAA,YACT,OAAO,EAAE,OAAO,EAAE;AAAA,YAClB,UAAU,EAAE,OAAO,KAAK;AAAA,YACxB,QAAQ,EAAE,OAAO,KAAK;AAAA,YACtB,SAAS,EAAE,OAAO,KAAK;AAAA,YACvB,YAAY;AAAA,cACX,OAAO,IAAU;AAAA,gBAChB,KAAK,WAAW;AAAA,gBAChB,KAAK,WAAW;AAAA,gBAChB,IAAI,KAAK,WAAW;AAAA,gBACpB,IAAI,KAAK,WAAW;AAAA,cACrB;AAAA,YACD;AAAA,UACD;AAAA,UACA,cAAc,eAAe;AAAA,UAC7B,gBAAgB,eAAe;AAAA,QAChC,CAAC;AAAA,MACF;AAAA,MAEA,UAAU;AACT,YAAI;AACH,eAAK,QAAQ,UAAU;AAAA,QACxB,QAAQ;AAAA,QAAa;AACrB,YAAI;AACH,UAAC,KAAK,iBAAyB,UAAU;AACzC,UAAC,KAAK,oBAA4B,UAAU;AAAA,QAC7C,QAAQ;AAAA,QAAa;AACrB,YAAI;AACH,UAAC,KAAK,gBAAwB,UAAU;AAAA,QACzC,QAAQ;AAAA,QAAa;AAAA,MACtB;AAAA,IACD;AAAA;AAAA;;;ACxFA,SAAmB,WAAAC,gBAA0C;AAC7D,SAAS,qBAAqB;AAD9B,IAiBa;AAjBb;AAAA;AAAA;AAiBO,IAAM,wBAAN,MAA4B;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,YAA6B;AAAA,MAC7B,WAAyB;AAAA,MAEzB,gBAAsC;AAAA,MACtC,cAA+B;AAAA,MAC/B,sBAA+B,IAAIA,SAAQ;AAAA,MAE3C,gBAA4C;AAAA,MAC5C,mBAAwC;AAAA,MACxC,qBAAuC,EAAE,SAAS,OAAO,UAAU,CAAC,EAAE;AAAA;AAAA,MAGtE,sBAAsC;AAAA,MACtC,wBAA2C;AAAA,MAC3C,kBAAiC;AAAA,MACjC,2BAA2C;AAAA;AAAA,MAG3C,2BAA2C;AAAA,MAC3C,6BAAgD;AAAA,MAChD,uBAAsC;AAAA,MACtC,wBAAwC;AAAA,MAEhD,YAAY,QAAgB,YAAyB,WAA6B;AACjF,aAAK,SAAS;AACd,aAAK,aAAa;AAClB,aAAK,YAAY,aAAa;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,OAA2B;AACnC,aAAK,WAAW;AAAA,MACjB;AAAA;AAAA;AAAA;AAAA,MAKA,IAAI,WAAoB;AACvB,eAAO,KAAK,mBAAmB;AAAA,MAChC;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,SAAS;AACR,YAAI,KAAK,iBAAiB,KAAK,aAAa;AAC3C,eAAK,YAAY,iBAAiB,KAAK,mBAAmB;AAC1D,eAAK,cAAc,OAAO,KAAK,KAAK,mBAAmB;AAAA,QACxD;AACA,aAAK,eAAe,OAAO;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAiB,UAAsC;AACtD,YAAI,KAAK,kBAAkB,UAAU;AACpC;AAAA,QACD;AACA,aAAK,oBAAoB;AACzB,aAAK,gBAAgB;AACrB,YAAI,CAAC,UAAU;AACd,eAAK,gBAAgB,EAAE,SAAS,OAAO,UAAU,CAAC,EAAE,CAAC;AACrD;AAAA,QACD;AACA,cAAM,cAAc,SAAS,UAAU,CAACC,WAAU;AACjD,eAAK,gBAAgBA,MAAK;AAAA,QAC3B,CAAC;AACD,aAAK,mBAAmB,MAAM;AAC7B,wBAAc;AAAA,QACf;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU;AACT,aAAK,qBAAqB;AAC1B,aAAK,oBAAoB;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,IAAI,aAA+B;AAClC,eAAO,KAAK;AAAA,MACb;AAAA,MAEQ,gBAAgBA,QAAyB;AAChD,cAAM,aAAa,KAAK,mBAAmB;AAC3C,aAAK,qBAAqB;AAAA,UACzB,SAASA,OAAM;AAAA,UACf,UAAU,CAAC,GAAGA,OAAM,QAAQ;AAAA,QAC7B;AACA,YAAIA,OAAM,WAAW,CAAC,YAAY;AAEjC,eAAK,gBAAgB;AACrB,eAAK,oBAAoB;AACzB,eAAK,oBAAoB;AACzB,eAAK,wBAAwB;AAC7B,eAAK,+BAA+BA,OAAM,QAAQ;AAAA,QACnD,WAAW,CAACA,OAAM,WAAW,YAAY;AAExC,eAAK,qBAAqB;AAC1B,eAAK,cAAc;AACnB,eAAK,qBAAqB;AAC1B,eAAK,oBAAoB;AACzB,eAAK,mBAAmB;AAAA,QACzB,WAAWA,OAAM,SAAS;AAEzB,eAAK,+BAA+BA,OAAM,QAAQ;AAAA,QACnD;AAAA,MACD;AAAA,MAEQ,sBAAsB;AAC7B,YAAI,KAAK,eAAe;AACvB;AAAA,QACD;AACA,aAAK,gBAAgB,IAAI,cAAc,KAAK,QAAQ,KAAK,UAAU;AACnE,aAAK,cAAc,gBAAgB;AACnC,aAAK,cAAc,gBAAgB;AACnC,aAAK,cAAc,qBAAqB;AACxC,aAAK,cAAc,cAAc;AACjC,aAAK,cAAc,cAAc;AACjC,aAAK,cAAc,gBAAgB,KAAK,KAAK;AAE7C,aAAK,cAAc,OAAO,IAAI,GAAG,GAAG,CAAC;AAAA,MACtC;AAAA,MAEQ,uBAAuB;AAC9B,YAAI,CAAC,KAAK,eAAe;AACxB;AAAA,QACD;AACA,aAAK,cAAc,QAAQ;AAC3B,aAAK,gBAAgB;AAAA,MACtB;AAAA,MAEQ,+BAA+B,UAAoB;AAE1D,YAAI,CAAC,KAAK,iBAAiB,SAAS,WAAW,GAAG;AACjD,eAAK,cAAc;AACnB,cAAI,KAAK,eAAe;AACvB,iBAAK,cAAc,OAAO,IAAI,GAAG,GAAG,CAAC;AAAA,UACtC;AACA;AAAA,QACD;AACA,iBAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACjD,gBAAM,OAAO,SAAS,CAAC;AACvB,gBAAM,eAAe,KAAK,cAAc,cAAc,IAAI;AAC1D,cAAI,cAAc;AACjB,iBAAK,cAAc;AACnB,gBAAI,KAAK,eAAe;AACvB,2BAAa,iBAAiB,KAAK,mBAAmB;AACtD,mBAAK,cAAc,OAAO,KAAK,KAAK,mBAAmB;AAAA,YACxD;AACA;AAAA,UACD;AAAA,QACD;AACA,aAAK,cAAc;AAAA,MACpB;AAAA,MAEQ,sBAAsB;AAC7B,YAAI,KAAK,kBAAkB;AAC1B,cAAI;AACH,iBAAK,iBAAiB;AAAA,UACvB,QAAQ;AAAA,UAAa;AAAA,QACtB;AACA,aAAK,mBAAmB;AACxB,aAAK,gBAAgB;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA,MAKQ,kBAAkB;AACzB,aAAK,sBAAsB,KAAK,OAAO,SAAS,MAAM;AACtD,aAAK,wBAAwB,KAAK,OAAO,WAAW,MAAM;AAE1D,YAAI,UAAU,KAAK,QAAQ;AAC1B,eAAK,kBAAmB,KAAK,OAAe;AAAA,QAC7C;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKQ,qBAAqB;AAC5B,YAAI,KAAK,qBAAqB;AAC7B,eAAK,OAAO,SAAS,KAAK,KAAK,mBAAmB;AAClD,eAAK,sBAAsB;AAAA,QAC5B;AACA,YAAI,KAAK,uBAAuB;AAC/B,eAAK,OAAO,WAAW,KAAK,KAAK,qBAAqB;AACtD,eAAK,wBAAwB;AAAA,QAC9B;AACA,YAAI,KAAK,oBAAoB,QAAQ,UAAU,KAAK,QAAQ;AAC3D,eAAK,OAAO,OAAO,KAAK;AACxB,UAAC,KAAK,OAAe,yBAAyB;AAC9C,eAAK,kBAAkB;AAAA,QACxB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKQ,uBAAuB;AAC9B,aAAK,2BAA2B,KAAK,OAAO,SAAS,MAAM;AAC3D,aAAK,6BAA6B,KAAK,OAAO,WAAW,MAAM;AAC/D,YAAI,UAAU,KAAK,QAAQ;AAC1B,eAAK,uBAAwB,KAAK,OAAe;AAAA,QAClD;AACA,YAAI,KAAK,eAAe;AACvB,eAAK,wBAAwB,KAAK,cAAc,OAAO,MAAM;AAAA,QAC9D;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKQ,0BAA0B;AACjC,YAAI,KAAK,0BAA0B;AAClC,eAAK,OAAO,SAAS,KAAK,KAAK,wBAAwB;AAAA,QACxD;AACA,YAAI,KAAK,4BAA4B;AACpC,eAAK,OAAO,WAAW,KAAK,KAAK,0BAA0B;AAAA,QAC5D;AACA,YAAI,KAAK,yBAAyB,QAAQ,UAAU,KAAK,QAAQ;AAChE,eAAK,OAAO,OAAO,KAAK;AACxB,UAAC,KAAK,OAAe,yBAAyB;AAAA,QAC/C;AACA,YAAI,KAAK,yBAAyB,KAAK,eAAe;AACrD,eAAK,cAAc,OAAO,KAAK,KAAK,qBAAqB;AAAA,QAC1D;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,sBAA4B;AACnC,YAAI,CAAC,KAAK,aAAa,KAAK,OAAO,WAAW,KAAK,WAAW;AAC7D;AAAA,QACD;AAGA,aAAK,2BAA2B,KAAK,OAAO,SAAS,MAAM;AAG3D,cAAM,WAAW,IAAID,SAAQ;AAC7B,aAAK,OAAO,iBAAiB,QAAQ;AAGrC,aAAK,UAAU,OAAO,KAAK,MAAM;AAGjC,YAAI,KAAK,UAAU;AAClB,eAAK,SAAS,IAAI,KAAK,MAAM;AAAA,QAC9B;AAGA,aAAK,OAAO,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,sBAA4B;AACnC,YAAI,CAAC,KAAK,aAAa,KAAK,OAAO,WAAW,KAAK,WAAW;AAC7D;AAAA,QACD;AAGA,YAAI,KAAK,YAAY,KAAK,OAAO,WAAW,KAAK,UAAU;AAC1D,eAAK,SAAS,OAAO,KAAK,MAAM;AAAA,QACjC;AAGA,aAAK,UAAU,IAAI,KAAK,MAAM;AAG9B,YAAI,KAAK,0BAA0B;AAClC,eAAK,OAAO,SAAS,KAAK,KAAK,wBAAwB;AACvD,eAAK,2BAA2B;AAAA,QACjC;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACrTA,SAA0B,mBAAmB,WAAAE,UAAS,YAAAC,WAAU,oBAAoB,iBAAAC,sBAA4B;AAIhH,SAAS,sBAAsB;AAJ/B,IAqBa;AArBb;AAAA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAcO,IAAM,cAAN,MAAkB;AAAA,MACxB,YAA6B;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAA6B;AAAA,MAC7B,WAAyB;AAAA,MACzB,cAAc;AAAA;AAAA,MAGd,wBAAsD;AAAA;AAAA,MAG9C,kBAAgD;AAAA,MAExD,YAAY,aAA8B,kBAA2B,cAAsB,IAAI;AAC9F,aAAK,eAAe;AACpB,aAAK,mBAAmB;AACxB,aAAK,cAAc;AAEnB,aAAK,WAAW,IAAIA,eAAc,EAAE,WAAW,OAAO,OAAO,KAAK,CAAC;AACnE,aAAK,SAAS,QAAQ,iBAAiB,GAAG,iBAAiB,CAAC;AAC5D,aAAK,SAAS,UAAU,UAAU;AAGlC,aAAK,WAAW,IAAI,eAAe,KAAK,QAAQ;AAGhD,cAAM,cAAc,iBAAiB,IAAI,iBAAiB;AAC1D,aAAK,SAAS,KAAK,2BAA2B,WAAW;AAGzD,YAAI,KAAK,SAAS,GAAG;AACpB,eAAK,YAAY,IAAID,UAAS;AAC9B,eAAK,UAAU,SAAS,IAAI,GAAG,GAAG,EAAE;AACpC,eAAK,UAAU,IAAI,KAAK,MAAM;AAC9B,eAAK,OAAO,OAAO,IAAID,SAAQ,GAAG,GAAG,CAAC,CAAC;AAAA,QACxC,OAAO;AAEN,eAAK,OAAO,SAAS,IAAI,GAAG,GAAG,EAAE;AACjC,eAAK,OAAO,OAAO,IAAIA,SAAQ,GAAG,GAAG,CAAC,CAAC;AAAA,QACxC;AAGA,aAAK,gCAAgC;AAGrC,aAAK,kBAAkB,IAAI,sBAAsB,KAAK,QAAQ,KAAK,SAAS,YAAY,KAAK,SAAS;AAAA,MACvG;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,MAAM,OAAc;AACzB,aAAK,WAAW;AAGhB,YAAI,mBAAmB,KAAK,iBAAiB,MAAM,EAAE,aAAa,CAAC;AACnE,yBAAiB,KAAK;AACtB,yBAAiB,KAAK;AACtB,cAAM,OAAO,IAAI,WAAW,kBAAkB,OAAO,KAAK,MAAM;AAChE,aAAK,SAAS,QAAQ,IAAI;AAG1B,YAAI,KAAK,uBAAuB;AAC/B,eAAK,sBAAsB,MAAM;AAAA,YAChC,kBAAkB,KAAK;AAAA,YACvB,UAAU,KAAK;AAAA,YACf;AAAA,YACA,QAAQ;AAAA,UACT,CAAC;AAAA,QACF;AAGA,aAAK,iBAAiB,SAAS,KAAK;AAGpC,aAAK,SAAS,iBAAiB,CAAC,UAAU;AACzC,eAAK,OAAO,SAAS,CAAC;AAAA,QACvB,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,OAAe;AAErB,aAAK,iBAAiB,OAAO;AAI7B,YAAI,KAAK,yBAAyB,CAAC,KAAK,kBAAkB,GAAG;AAC5D,eAAK,sBAAsB,OAAO,KAAK;AAAA,QACxC;AAGA,aAAK,SAAS,OAAO,KAAK;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,oBAA6B;AAC5B,eAAO,KAAK,iBAAiB,YAAY;AAAA,MAC1C;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU;AACT,YAAI;AACH,eAAK,SAAS,iBAAiB,IAAW;AAAA,QAC3C,QAAQ;AAAA,QAAa;AACrB,YAAI;AACH,eAAK,iBAAiB,QAAQ;AAAA,QAC/B,QAAQ;AAAA,QAAa;AACrB,YAAI;AACH,eAAK,UAAU,QAAQ,QAAQ,CAAC,MAAW,EAAE,UAAU,CAAC;AAExD,eAAK,UAAU,UAAU;AAAA,QAC1B,QAAQ;AAAA,QAAa;AACrB,YAAI;AACH,eAAK,SAAS,QAAQ;AAAA,QACvB,QAAQ;AAAA,QAAa;AACrB,aAAK,WAAW;AAAA,MACjB;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAiB,UAAsC;AACtD,aAAK,iBAAiB,iBAAiB,QAAQ;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,OAAe,QAAgB;AACrC,aAAK,iBAAiB,IAAI,OAAO,MAAM;AACvC,aAAK,SAAS,QAAQ,OAAO,QAAQ,KAAK;AAC1C,aAAK,SAAS,QAAQ,OAAO,MAAM;AAEnC,YAAI,KAAK,kBAAkB,mBAAmB;AAC7C,eAAK,OAAO,SAAS,QAAQ;AAC7B,eAAK,OAAO,uBAAuB;AAAA,QACpC;AAEA,YAAI,KAAK,uBAAuB;AAC/B,eAAK,sBAAsB,OAAO,OAAO,MAAM;AAAA,QAChD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,cAAc,KAAa;AAC1B,cAAM,OAAO,KAAK,IAAI,GAAG,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACvD,aAAK,SAAS,cAAc,IAAI;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKQ,2BAA2B,aAA6B;AAC/D,gBAAQ,KAAK,cAAc;AAAA,UAC1B,KAAK,aAAa;AACjB,mBAAO,KAAK,wBAAwB,WAAW;AAAA,UAChD,KAAK,aAAa;AACjB,mBAAO,KAAK,wBAAwB,WAAW;AAAA,UAChD,KAAK,aAAa;AACjB,mBAAO,KAAK,sBAAsB,WAAW;AAAA,UAC9C,KAAK,aAAa;AACjB,mBAAO,KAAK,mBAAmB,WAAW;AAAA,UAC3C,KAAK,aAAa;AACjB,mBAAO,KAAK,oBAAoB,WAAW;AAAA,UAC5C;AACC,mBAAO,KAAK,wBAAwB,WAAW;AAAA,QACjD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKQ,kCAAkC;AACzC,gBAAQ,KAAK,cAAc;AAAA,UAC1B,KAAK,aAAa;AACjB,iBAAK,wBAAwB,IAAI,kBAAkB;AACnD;AAAA,UACD,KAAK,aAAa;AACjB,iBAAK,wBAAwB,IAAI,cAAc;AAC/C;AAAA,UACD;AACC,iBAAK,wBAAwB,IAAI,kBAAkB;AAAA,QACrD;AAAA,MACD;AAAA,MAEQ,wBAAwB,aAAwC;AACvE,eAAO,IAAI,kBAAkB,IAAI,aAAa,KAAK,GAAI;AAAA,MACxD;AAAA,MAEQ,wBAAwB,aAAwC;AACvE,eAAO,IAAI,kBAAkB,IAAI,aAAa,KAAK,GAAI;AAAA,MACxD;AAAA,MAEQ,sBAAsB,aAAyC;AACtE,eAAO,IAAI;AAAA,UACV,KAAK,cAAc,cAAc;AAAA,UACjC,KAAK,cAAc,cAAc;AAAA,UACjC,KAAK,cAAc;AAAA,UACnB,KAAK,cAAc;AAAA,UACnB;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAAA,MAEQ,mBAAmB,aAAyC;AACnE,eAAO,IAAI;AAAA,UACV,KAAK,cAAc,cAAc;AAAA,UACjC,KAAK,cAAc,cAAc;AAAA,UACjC,KAAK,cAAc;AAAA,UACnB,KAAK,cAAc;AAAA,UACnB;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAAA,MAEQ,oBAAoB,aAAyC;AACpE,eAAO,KAAK,mBAAmB,WAAW;AAAA,MAC3C;AAAA;AAAA,MAGQ,WAAWG,WAAmB;AACrC,YAAI,KAAK,iBAAiB,aAAa,UAAU,KAAK,iBAAiB,aAAa,SAAS;AAC5F,eAAK,cAAcA,UAAS;AAAA,QAC7B;AACA,YAAI,KAAK,WAAW;AACnB,eAAK,UAAU,SAAS,IAAIA,UAAS,GAAGA,UAAS,GAAGA,UAAS,CAAC;AAAA,QAC/D,OAAO;AACN,eAAK,OAAO,SAAS,IAAIA,UAAS,GAAGA,UAAS,GAAGA,UAAS,CAAC;AAAA,QAC5D;AAAA,MACD;AAAA,MAEA,KAAKA,WAAmB;AACvB,aAAK,WAAWA,SAAQ;AAAA,MACzB;AAAA,MAEA,OAAO,OAAe,KAAa,MAAc;AAChD,YAAI,KAAK,WAAW;AACnB,eAAK,UAAU,QAAQ,KAAK;AAC5B,eAAK,UAAU,QAAQ,GAAG;AAC1B,eAAK,UAAU,QAAQ,IAAI;AAAA,QAC5B,OAAO;AACN,UAAC,KAAK,OAAoB,QAAQ,KAAK;AACvC,UAAC,KAAK,OAAoB,QAAQ,GAAG;AACrC,UAAC,KAAK,OAAoB,QAAQ,IAAI;AAAA,QACvC;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKQ,WAAoB;AAC3B,eAAO,KAAK,iBAAiB,aAAa;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAmC;AAClC,eAAO,KAAK,SAAS;AAAA,MACtB;AAAA,IACD;AAAA;AAAA;;;ACtSA,SAAS,WAAAC,UAAS,WAAAC,gBAAe;AAAjC,IAYa;AAZb;AAAA;AAAA;AAYO,IAAM,gBAAN,MAAoB;AAAA,MAC1B;AAAA,MAEA,YAAY,QAAqB;AAChC,aAAK,YAAY;AAAA,MAClB;AAAA,IACD;AAAA;AAAA;;;AClBA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAiCA;AAGA;AAGA;AAGA;AAGA;AAGA;AAAA;AAAA;;;AChDA,SAAS,SAAAC,cAAsC;AAC/C,SAAS,WAAAC,gBAAe;AADxB,IASa,gBAKA,MACA;AAfb;AAAA;AAAA;AASO,IAAM,iBAAiB,IAAID,OAAM,SAAS;AAK1C,IAAM,OAAO,IAAIC,SAAQ,GAAG,GAAG,CAAC;AAChC,IAAM,OAAO,IAAIA,SAAQ,GAAG,GAAG,CAAC;AAAA;AAAA;;;ACfvC,SAAS,SAAAC,QAAO,WAAAC,gBAAe;AAC/B,SAAS,SAAAC,QAAO,aAAAC,kBAAiB;AAsM1B,SAAS,eAAe,QAAsB;AACpD,qBAAmB,OAAO,MAAM;AACjC;AAzMA,IAWa,mBAgBP,YAgBA,yBAIA,yBASA,mBAKA,qBA2CA;AAxGN;AAAA;AAAA;AAKA;AAMO,IAAM,oBAAoB;AAAA,MAChC,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,QAAQ;AAAA,QACP,IAAI,CAAC,aAAa,UAAU;AAAA,QAC5B,IAAI,CAAC,aAAa,UAAU;AAAA,MAC7B;AAAA,MACA,SAAS,IAAIF,SAAQ,GAAG,GAAG,CAAC;AAAA,MAC5B,WAAW,CAAC;AAAA,MACZ,UAAU,CAAC;AAAA,IACZ;AAKA,IAAM,aAAaC,OAAM;AAAA,MACxB,iBAAiB,IAAIF,OAAMA,OAAM,MAAM,cAAc;AAAA,MACrD,iBAAiB;AAAA,MACjB,QAAQ;AAAA,QACP,IAAI,CAAC,aAAa,YAAY;AAAA,QAC9B,IAAI,CAAC,aAAa,YAAY;AAAA,MAC/B;AAAA,MACA,WAAW,CAAC;AAAA,MACZ,SAAS,IAAIC,SAAQ,GAAG,GAAG,CAAC;AAAA,MAC5B,UAAU,CAAC;AAAA,IACZ,CAAwB;AAMxB,IAAM,0BAA0B,CAAC,UAAiB;AACjD,iBAAW,kBAAkB;AAAA,IAC9B;AAEA,IAAM,0BAA0B,CAAC,UAAyB;AACzD,iBAAW,kBAAkB;AAAA,IAC9B;AAOA,IAAM,oBAAoB,CAAC,cAAmC;AAC7D,iBAAW,YAAY,EAAE,GAAG,UAAU;AAAA,IACvC;AAGA,IAAM,sBAAsB,MAAM;AACjC,iBAAW,YAAY,CAAC;AAAA,IACzB;AAyCA,IAAM,qBAAqB,oBAAI,IAAsC;AAAA;AAAA;;;AChDrE,SAAS,YAAY;AACrB,YAAYG,YAAW;AACvB,YAAY,YAAY;AA1DxB;AAAA;AAAA;AAmCA;AAmEA;AAAA;AAAA;;;ACtGA,SAAS,sBAAsB,oBAAoB;AACnD,SAAsD,sBAAsB,SAAAC,QAAO,WAAAC,gBAAe;AADlG,IAiCM,eA+GO,YAEA;AAlJb;AAAA;AAAA;AAGA;AAGA;AAGA;AAKA;AACA;AAkBA,IAAM,gBAAmC;AAAA,MACxC,GAAG;AAAA,MACH,WAAW;AAAA,QACV,QAAQ;AAAA,QACR,MAAM,IAAIA,SAAQ,KAAK,KAAK,GAAG;AAAA,QAC/B,UAAU,IAAIA,SAAQ,GAAG,GAAG,CAAC;AAAA,MAC9B;AAAA,MACA,UAAU;AAAA,QACT,QAAQ;AAAA,MACT;AAAA,MACA,YAAY,CAAC;AAAA,MACb,QAAQ,CAAC;AAAA,MACT,gBAAgB;AAAA,IACjB;AAkGO,IAAM,aAAa,uBAAO,OAAO;AAEjC,IAAM,aAAN,cAAyB,WAAiF;AAAA,MAChH,OAAO,OAAO;AAAA,MAEN,UAA2B;AAAA,MAC3B,qBAA+C;AAAA,MAC/C,kBAA4B,CAAC;AAAA,MAC7B,eAAkC,IAAI,kBAAkB;AAAA,MAEhE,qBAA8B;AAAA,MAE9B,YAAY,SAA6B;AACxC,cAAM;AACN,aAAK,UAAU,EAAE,GAAG,eAAe,GAAG,QAAQ;AAE9C,aAAK,cAAc,KAAK,YAAY,KAAK,IAAI,CAAyB;AACtE,aAAK,qBAAqB;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAa;AACZ,aAAK,kBAAkB,KAAK,QAAQ,UAAU,CAAC;AAE/C,aAAK,mBAAmB;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAY;AACX,eAAO;AAAA,UACN,YAAY,KAAK,oBAAoB;AAAA,UACrC,aAAa,KAAK;AAAA,UAClB,gBAAgB,KAAK,QAAQ;AAAA,QAC9B;AAAA,MACD;AAAA,MAEA,YAAY,QAAgD;AAC3D,aAAK,oBAAoB,OAAO,OAAO,KAAK;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA,MAKA,eAAqB;AAEpB,YAAI,KAAK,oBAAoB;AAC5B,eAAK,mBAAmB,QAAQ;AAChC,eAAK,qBAAqB;AAAA,QAC3B;AAGA,YAAI,KAAK,SAAS;AACjB,eAAK,QAAQ,SAAS,CAAC,UAAU;AAChC,gBAAK,MAAc,QAAQ;AAC1B,oBAAM,OAAO;AACb,mBAAK,UAAU,QAAQ;AACvB,kBAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACjC,qBAAK,SAAS,QAAQ,OAAK,EAAE,QAAQ,CAAC;AAAA,cACvC,WAAW,KAAK,UAAU;AACzB,qBAAK,SAAS,QAAQ;AAAA,cACvB;AAAA,YACD;AAAA,UACD,CAAC;AACD,eAAK,UAAU;AAAA,QAChB;AAGA,YAAI,KAAK,OAAO;AACf,eAAK,MAAM,MAAM;AACjB,eAAK,QAAQ;AAAA,QACd;AAGA,aAAK,kBAAkB,CAAC;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,qBAA2B;AAClC,YAAI,KAAK,gBAAgB,WAAW,EAAG;AAGvC,aAAK,SAAS,wBAAwB;AAAA,UACrC,UAAU,KAAK;AAAA,UACf,OAAO,KAAK;AAAA,QACb,CAAC;AAED,cAAM,WAAW,KAAK,gBAAgB,IAAI,UAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAClF,gBAAQ,IAAI,QAAQ,EAAE,KAAK,aAAW;AACrC,cAAI,QAAQ,CAAC,GAAG,QAAQ;AACvB,iBAAK,UAAU,QAAQ,CAAC,EAAE;AAAA,UAC3B;AAEA,cAAI,YAAY;AAChB,cAAI,KAAK,SAAS;AACjB,iBAAK,QAAQ,SAAS,CAAC,UAAU;AAChC,kBAAK,MAAc,OAAQ;AAAA,YAC5B,CAAC;AACD,iBAAK,QAAQ,IAAID,OAAM;AACvB,iBAAK,MAAM,OAAO,KAAK,OAAO;AAC9B,iBAAK,MAAM,MAAM;AAAA,cAChB,KAAK,QAAQ,OAAO,KAAK;AAAA,cACzB,KAAK,QAAQ,OAAO,KAAK;AAAA,cACzB,KAAK,QAAQ,OAAO,KAAK;AAAA,YAC1B;AAGA,iBAAK,uBAAuB;AAG5B,iBAAK,qBAAqB,IAAI,kBAAkB,KAAK,OAAO;AAC5D,iBAAK,mBAAmB,eAAe,KAAK,QAAQ,cAAc,CAAC,CAAC,EAAE,KAAK,MAAM;AAChF,mBAAK,SAAS,2BAA2B;AAAA,gBACxC,UAAU,KAAK;AAAA,gBACf,gBAAgB,KAAK,QAAQ,YAAY,UAAU;AAAA,cACpD,CAAC;AAAA,YACF,CAAC;AAAA,UACF;AAGA,eAAK,SAAS,uBAAuB;AAAA,YACpC,UAAU,KAAK;AAAA,YACf,SAAS,CAAC,CAAC,KAAK;AAAA,YAChB;AAAA,UACD,CAAC;AAAA,QACF,CAAC;AAAA,MACF;AAAA,MAEA,cAAc,kBAAoC;AACjD,aAAK,oBAAoB,cAAc,gBAAgB;AAAA,MACxD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,yBAA+B;AACtC,cAAM,kBAAkB,KAAK,QAAQ;AAErC,YAAI,CAAC,mBAAoB,CAAC,gBAAgB,SAAS,CAAC,gBAAgB,MAAO;AAC1E;AAAA,QACD;AAEA,YAAI,CAAC,KAAK,QAAS;AAEnB,aAAK,QAAQ,SAAS,CAAC,UAAU;AAChC,cAAK,MAAc,QAAQ;AAC1B,kBAAM,OAAO;AACb,gBAAI,gBAAgB,OAAO;AAE1B,oBAAM,cAAc,IAAI,qBAAqB;AAAA,gBAC5C,OAAO,gBAAgB;AAAA,gBACvB,mBAAmB;AAAA,gBACnB,mBAAmB;AAAA,gBACnB,KAAK;AAAA,cACN,CAAC;AACD,mBAAK,aAAa;AAClB,mBAAK,gBAAgB;AACrB,mBAAK,WAAW;AAAA,YACjB;AAAA,UACD;AAAA,QACD,CAAC;AAAA,MACF;AAAA,MAEA,IAAI,SAA0B;AAC7B,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,eAAoC;AACnC,cAAM,YAAiC;AAAA,UACtC,MAAM;AAAA,UACN,QAAQ,KAAK,gBAAgB,SAAS,IAAI,KAAK,kBAAkB;AAAA,UACjE,aAAa,CAAC,CAAC,KAAK;AAAA,UACpB,OAAO,KAAK,QAAQ,QACnB,GAAG,KAAK,QAAQ,MAAM,CAAC,KAAK,KAAK,QAAQ,MAAM,CAAC,KAAK,KAAK,QAAQ,MAAM,CAAC,KACzE;AAAA,QACF;AAGA,YAAI,KAAK,oBAAoB;AAC5B,oBAAU,mBAAmB,KAAK,mBAAmB,uBAAuB;AAC5E,oBAAU,kBAAkB,KAAK,QAAQ,YAAY,UAAU;AAAA,QAChE;AAGA,YAAI,KAAK,SAAS;AACjB,cAAI,YAAY;AAChB,cAAI,cAAc;AAClB,eAAK,QAAQ,SAAS,CAAC,UAAU;AAChC,gBAAK,MAAc,QAAQ;AAC1B;AACA,oBAAM,WAAY,MAAsB;AACxC,kBAAI,YAAY,SAAS,WAAW,UAAU;AAC7C,+BAAe,SAAS,WAAW,SAAS;AAAA,cAC7C;AAAA,YACD;AAAA,UACD,CAAC;AACD,oBAAU,YAAY;AACtB,oBAAU,cAAc;AAAA,QACzB;AAEA,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;ACtWA,OAAOE,aAAuB;AAmBvB,SAAS,2BAA2B,KAA2C;AACrF,SAAO,OAAO,KAAK,wBAAwB,cAAc,OAAO,KAAK,4BAA4B;AAClG;AAtBA,IAwBa;AAxBb;AAAA;AAAA;AAIA;AAEA;AAkBO,IAAM,aAAN,MAA+C;AAAA,MACrD,OAAO;AAAA,MACP;AAAA,MACA,eAA6C,oBAAI,IAAI;AAAA,MACrD,uBAAqD,oBAAI,IAAI;AAAA,MAC7D,cAA4C,oBAAI,IAAI;AAAA,MAEpD,aAAa,YAAY,SAAkB;AAC1C,cAAMA,QAAO,KAAK;AAClB,cAAM,eAAe,IAAIA,QAAO,MAAM,OAAO;AAC7C,eAAO;AAAA,MACR;AAAA,MAEA,YAAY,OAAc;AACzB,aAAK,QAAQ;AAAA,MACd;AAAA,MAEA,UAAU,QAAa;AACtB,cAAM,YAAY,KAAK,MAAM,gBAAgB,OAAO,QAAQ;AAC5D,eAAO,OAAO;AAEd,eAAO,KAAK,WAAW,EAAE,MAAM,OAAO,MAAM,KAAK,OAAO;AACxD,YAAI,KAAK,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,MAAM,GAAG;AAC3F,iBAAO,KAAK,iBAAiB,MAAM,IAAI;AACvC,iBAAO,KAAK,cAAc,MAAM,IAAI;AAAA,QACrC;AACA,cAAM,WAAW,KAAK,MAAM,eAAe,OAAO,cAAc,OAAO,IAAI;AAC3E,eAAO,WAAW;AAClB,YAAI,OAAO,sBAAsB,kBAAkB,YAAY;AAC9D,iBAAO,KAAK,cAAc,MAAM,IAAI;AACpC,iBAAO,sBAAsB,KAAK,MAAM,0BAA0B,IAAI;AACtE,iBAAO,oBAAoB,sBAAsB,KAAK,KAAK,KAAK,GAAG;AACnE,iBAAO,oBAAoB,sBAAsB,KAAK,KAAK,KAAK,GAAG;AACnE,iBAAO,oBAAoB,mBAAmB,IAAI;AAClD,iBAAO,oBAAoB,gBAAgB,IAAI;AAC/C,iBAAO,oBAAoB,gCAAgC,IAAI;AAC/D,iBAAO,oBAAoB,iBAAiB,CAAC;AAAA,QAC9C;AACA,aAAK,aAAa,IAAI,OAAO,MAAM,MAAM;AAAA,MAC1C;AAAA,MAEA,cAAc,QAAa;AAC1B,YAAI,OAAO,MAAM;AAChB,eAAK,YAAY,IAAI,OAAO,MAAM,MAAM;AAAA,QACzC;AAAA,MACD;AAAA,MAEA,cAAc,QAAyB;AACtC,YAAI,OAAO,UAAU;AACpB,eAAK,MAAM,eAAe,OAAO,UAAU,IAAI;AAAA,QAChD;AACA,YAAI,OAAO,MAAM;AAChB,eAAK,MAAM,gBAAgB,OAAO,IAAI;AACtC,eAAK,aAAa,OAAO,OAAO,IAAI;AACpC,eAAK,YAAY,OAAO,OAAO,IAAI;AAAA,QACpC;AAAA,MACD;AAAA,MAEA,QAAQ;AAAA,MAAE;AAAA,MAEV,OAAO,QAA4B;AAClC,cAAM,EAAE,MAAM,IAAI;AAClB,YAAI,CAAC,KAAK,OAAO;AAChB;AAAA,QACD;AACA,aAAK,gBAAgB,KAAK;AAC1B,aAAK,6BAA6B,KAAK;AACvC,aAAK,MAAM,KAAK;AAAA,MACjB;AAAA,MAEA,6BAA6B,OAAe;AAC3C,cAAM,gBAAgB,KAAK;AAC3B,iBAAS,CAAC,IAAI,QAAQ,KAAK,eAAe;AACzC,gBAAM,aAAa;AACnB,cAAI,CAAC,2BAA2B,UAAU,GAAG;AAC5C;AAAA,UACD;AACA,gBAAM,SAAS,WAAW,oBAAoB,EAAE,QAAQ,YAAY,MAAM,CAAC;AAC3E,cAAI,CAAC,QAAQ;AACZ,iBAAK,qBAAqB,OAAO,EAAE;AAAA,UACpC;AAAA,QACD;AAAA,MACD;AAAA,MAEA,gBAAgB,OAAe;AAC9B,cAAM,gBAAgB,KAAK;AAC3B,iBAAS,CAAC,IAAI,QAAQ,KAAK,eAAe;AACzC,gBAAM,aAAa;AACnB,cAAI,CAAC,WAAW,MAAM;AACrB;AAAA,UACD;AACA,cAAI,KAAK,YAAY,IAAI,WAAW,IAAI,GAAG;AAC1C,iBAAK,cAAc,UAAU;AAC7B;AAAA,UACD;AACA,eAAK,MAAM,aAAa,WAAW,KAAK,SAAS,CAAC,GAAG,CAAC,kBAAkB;AACvE,gBAAI,CAAC,eAAe;AACnB;AAAA,YACD;AAEA,kBAAM,OAAO,cAAc,QAAQ,SAAS;AAC5C,kBAAM,SAAS,cAAc,IAAI,IAAI;AACrC,gBAAI,CAAC,QAAQ;AACZ;AAAA,YACD;AACA,gBAAI,WAAW,YAAY;AAC1B,yBAAW,WAAW,QAAQ,MAAM,OAAO;AAAA,YAC5C;AAAA,UACD,CAAC;AACD,eAAK,MAAM,kBAAkB,WAAW,KAAK,SAAS,CAAC,GAAG,CAAC,kBAAkB;AAC5E,gBAAI,CAAC,eAAe;AACnB;AAAA,YACD;AAEA,kBAAM,OAAO,cAAc,QAAQ,SAAS;AAC5C,kBAAM,SAAS,cAAc,IAAI,IAAI;AACrC,gBAAI,CAAC,QAAQ;AACZ;AAAA,YACD;AACA,gBAAI,WAAW,YAAY;AAC1B,yBAAW,WAAW,QAAQ,MAAM,OAAO;AAAA,YAC5C;AACA,gBAAI,2BAA2B,MAAM,GAAG;AACvC,qBAAO,wBAAwB,EAAE,QAAQ,OAAO,YAAY,MAAM,CAAC;AACnE,mBAAK,qBAAqB,IAAI,MAAM,MAAM;AAAA,YAC3C;AAAA,UACD,CAAC;AAAA,QACF;AAAA,MACD;AAAA,MAEA,UAAU;AACT,YAAI;AACH,qBAAW,CAAC,EAAE,MAAM,KAAK,KAAK,cAAc;AAC3C,gBAAI;AAAE,mBAAK,cAAc,MAAM;AAAA,YAAG,QAAQ;AAAA,YAAa;AAAA,UACxD;AACA,eAAK,aAAa,MAAM;AACxB,eAAK,qBAAqB,MAAM;AAChC,eAAK,YAAY,MAAM;AAEvB,eAAK,QAAQ;AAAA,QACd,QAAQ;AAAA,QAAa;AAAA,MACtB;AAAA,IAED;AAAA;AAAA;;;ACvKA;AAAA,EACC,SAAAC;AAAA,EACA,SAAAC;AAAA,EACA;AAAA,EACA;AAAA,EAEA,WAAAC;AAAA,EACA;AAAA,EAEA;AAAA,EACA,kBAAAC;AAAA,EACA,QAAAC;AAAA,EACA;AAAA,OACM;AAbP,IA6Ba;AA7Bb;AAAA;AAAA;AAiBA;AAEA;AACA;AASO,IAAM,aAAN,MAA+C;AAAA,MAC9C,OAAO;AAAA,MAEd;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAuC;AAAA,MACvC,SAAwC,MAAM;AAAA,MAAE;AAAA,MAChD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGQ,iBAAwC;AAAA,MAEhD,YAAY,IAAY,QAAqBC,QAAmB;AAC/D,cAAM,QAAQ,IAAIL,OAAM;AACxB,cAAM,UAAUK,OAAM,2BAA2BJ;AACjD,cAAM,kBAAmB,UAAWI,OAAM,kBAAkB,IAAIJ,OAAMI,OAAM,eAAe;AAC3F,cAAM,aAAa;AAEnB,gBAAQ,IAAI,sCAAsCA,OAAM,gBAAgB;AAExE,YAAIA,OAAM,kBAAkB;AAC3B,eAAK,sBAAsB,OAAOA,OAAM,gBAAgB;AAAA,QACzD,WAAWA,OAAM,iBAAiB;AAEjC,uBAAa,YAAYA,OAAM,eAAe,EAAE,KAAK,aAAW;AAC/D,kBAAM,aAAa;AAAA,UACpB,CAAC;AAAA,QACF;AAEA,aAAK,QAAQ;AACb,aAAK,cAAc;AAEnB,aAAK,cAAc,KAAK;AACxB,aAAK,YAAY,OAAO,MAAM;AAC9B,YAAI,WAAW,SAAS;AACvB,eAAK,WAAW;AAAA,QACjB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,sBAAsB,OAAc,QAA2B;AAEtE,cAAM,aAAa;AAGnB,cAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc3B,aAAK,iBAAiB,IAAIF,gBAAe;AAAA,UACxC,cAAc;AAAA,UACd,gBAAgB,OAAO;AAAA,UACvB,UAAU;AAAA,YACT,OAAO,EAAE,OAAO,EAAI;AAAA,UACrB;AAAA,UACA,MAAM;AAAA;AAAA,UACN,YAAY;AAAA;AAAA,UACZ,WAAW;AAAA;AAAA,QACZ,CAAC;AAGD,cAAM,WAAW,IAAI,YAAY,GAAG,GAAG,CAAC;AACxC,cAAM,SAAS,IAAIC,MAAK,UAAU,KAAK,cAAc;AACrD,eAAO,MAAM,UAAU,GAAM;AAC7B,eAAO,gBAAgB;AACvB,cAAM,IAAI,MAAM;AAEhB,gBAAQ,IAAI,wCAAwC;AAAA,MACrD;AAAA,MAEA,QAAQ;AACP,YAAI,KAAK,QAAQ;AAChB,eAAK,OAAO,EAAE,IAAI,MAAM,QAAQ,KAAK,aAAa,SAAS,WAAW,EAAE,CAAC;AAAA,QAC1E;AAAA,MACD;AAAA,MAEA,UAAU;AACT,YAAI,KAAK,eAAgB,KAAK,YAAoB,SAAS;AAC1D,UAAC,KAAK,YAAoB,QAAQ;AAAA,QACnC;AACA,YAAI,KAAK,gBAAgB;AACxB,eAAK,eAAe,QAAQ;AAAA,QAC7B;AACA,YAAI,KAAK,OAAO;AACf,eAAK,MAAM,SAAS,CAAC,QAAa;AACjC,gBAAI,IAAI,UAAU;AACjB,kBAAI,SAAS,UAAU;AAAA,YACxB;AACA,gBAAI,IAAI,UAAU;AACjB,kBAAI,MAAM,QAAQ,IAAI,QAAQ,GAAG;AAChC,oBAAI,SAAS,QAAQ,CAAC,MAAW,EAAE,UAAU,CAAC;AAAA,cAC/C,OAAO;AACN,oBAAI,SAAS,UAAU;AAAA,cACxB;AAAA,YACD;AAAA,UACD,CAAC;AAAA,QACF;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAIA,YAAY,OAAc,QAAqB;AAE9C,YAAI,OAAO,WAAW;AACrB,gBAAM,IAAI,OAAO,SAAS;AAAA,QAC3B,OAAO;AACN,gBAAM,IAAI,OAAO,MAAkB;AAAA,QACpC;AAEA,eAAO,MAAM,KAAK;AAAA,MACnB;AAAA;AAAA;AAAA;AAAA,MAKA,cAAc,OAAc;AAC3B,cAAM,eAAe,IAAI,aAAa,UAAU,CAAC;AACjD,cAAM,IAAI,YAAY;AAEtB,cAAM,mBAAmB,IAAI,iBAAiB,UAAU,CAAC;AACzD,yBAAiB,OAAO;AACxB,yBAAiB,SAAS,IAAI,GAAG,KAAK,CAAC;AACvC,yBAAiB,aAAa;AAC9B,yBAAiB,OAAO,OAAO,OAAO;AACtC,yBAAiB,OAAO,OAAO,MAAM;AACrC,yBAAiB,OAAO,OAAO,OAAO;AACtC,yBAAiB,OAAO,OAAO,QAAQ;AACvC,yBAAiB,OAAO,OAAO,MAAM;AACrC,yBAAiB,OAAO,OAAO,SAAS;AACxC,yBAAiB,OAAO,QAAQ,QAAQ;AACxC,yBAAiB,OAAO,QAAQ,SAAS;AACzC,cAAM,IAAI,gBAAgB;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,eAAe,OAAe,QAAgB;AAC7C,aAAK,YAAY,OAAO,OAAO,MAAM;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,IAAI,QAAkBE,YAAoB,IAAIJ,SAAQ,GAAG,GAAG,CAAC,GAAG;AAC/D,eAAO,SAAS,IAAII,UAAS,GAAGA,UAAS,GAAGA,UAAS,CAAC;AACtD,aAAK,MAAM,IAAI,MAAM;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,QAAyB;AAClC,YAAI,OAAO,OAAO;AACjB,eAAK,IAAI,OAAO,OAAO,OAAO,QAAQ,QAAQ;AAAA,QAC/C,WAAW,OAAO,MAAM;AACvB,eAAK,IAAI,OAAO,MAAM,OAAO,QAAQ,QAAQ;AAAA,QAC9C;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,eAAe,QAA+B;AAC7C,cAAMA,YAAW,OAAO,OACrB,IAAIJ;AAAA,UACL,OAAO,KAAK,YAAY,EAAE;AAAA,UAC1B,OAAO,KAAK,YAAY,EAAE;AAAA,UAC1B,OAAO,KAAK,YAAY,EAAE;AAAA,QACzB,IACA,OAAO,QAAQ;AAElB,YAAI,OAAO,OAAO;AACjB,eAAK,IAAI,OAAO,OAAOI,SAAQ;AAAA,QAChC,WAAW,OAAO,MAAM;AACvB,eAAK,IAAI,OAAO,MAAMA,SAAQ;AAAA,QAC/B;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa;AACZ,cAAM,OAAO;AACb,cAAM,YAAY;AAElB,cAAM,aAAa,IAAI,WAAW,MAAM,SAAS;AACjD,aAAK,MAAM,IAAI,UAAU;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,OAAe;AAC3B,YAAI,KAAK,gBAAgB,UAAU,OAAO;AACzC,eAAK,eAAe,SAAS,MAAM,SAAS;AAAA,QAC7C;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACrPA,IAMsB;AANtB;AAAA;AAAA;AAMO,IAAe,gBAAf,MAAoC;AAAA,MAC1C,SAAgC,MAAM;AAAA,MAAE;AAAA,MACxC,QAA8B,MAAM;AAAA,MAAE;AAAA,MACtC,UAAkC,MAAM;AAAA,MAAE;AAAA,MAM1C,UAAU,SAA8B;AACvC,YAAI,OAAQ,KAAa,WAAW,YAAY;AAC/C,eAAK,OAAO,OAAO;AAAA,QACpB;AACA,YAAI,KAAK,OAAO;AACf,eAAK,MAAM,OAAO;AAAA,QACnB;AAAA,MACD;AAAA,MAEA,WAAW,SAA+B;AACzC,YAAI,OAAQ,KAAa,YAAY,YAAY;AAChD,eAAK,QAAQ,OAAO;AAAA,QACrB;AACA,YAAI,KAAK,QAAQ;AAChB,eAAK,OAAO,OAAO;AAAA,QACpB;AAAA,MACD;AAAA,MAEA,YAAY,SAAgC;AAC3C,YAAI,KAAK,SAAS;AACjB,eAAK,QAAQ,OAAO;AAAA,QACrB;AACA,YAAI,OAAQ,KAAa,aAAa,YAAY;AACjD,eAAK,SAAS,OAAO;AAAA,QACtB;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACzCA;AAAA,EACC;AAAA,EACA,eAAAC;AAAA,EACA,SAAAC;AAAA,EACA;AAAA,EACA,SAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAAC;AAAA,EACA;AAAA,EAGA,WAAAC;AAAA,OACM;AAbP,IAmBa;AAnBb;AAAA;AAAA;AAmBO,IAAM,oBAAN,MAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAsB,IAAIH,OAAM,KAAQ;AAAA,MACxC,OAAa,IAAI,KAAK;AAAA,MACtB,OAAgB,IAAIG,UAAQ;AAAA,MAC5B,SAAkB,IAAIA,UAAQ;AAAA,MAEtC,YAAY,OAAc;AACzB,aAAK,QAAQ;AAEb,cAAM,kBAAkB,IAAIJ,aAAY,GAAG,GAAG,CAAC;AAE/C,aAAK,WAAW,IAAIG;AAAA,UACnB;AAAA,UACA,IAAI,kBAAkB;AAAA,YACrB,OAAO,KAAK;AAAA,YACZ,aAAa;AAAA,YACb,SAAS;AAAA,YACT,YAAY;AAAA,UACb,CAAC;AAAA,QACF;AAEA,cAAM,QAAQ,IAAI,cAAc,eAAe;AAC/C,aAAK,YAAY,IAAI;AAAA,UACpB;AAAA,UACA,IAAI,kBAAkB,EAAE,OAAO,KAAK,cAAc,WAAW,EAAE,CAAC;AAAA,QACjE;AAEA,aAAK,YAAY,IAAID,OAAM;AAC3B,aAAK,UAAU,OAAO;AACtB,aAAK,UAAU,IAAI,KAAK,QAAQ;AAChC,aAAK,UAAU,IAAI,KAAK,SAAS;AACjC,aAAK,UAAU,UAAU;AAEzB,aAAK,MAAM,IAAI,KAAK,SAAS;AAAA,MAC9B;AAAA,MAEA,SAAS,OAA6B;AACrC,aAAK,aAAa,IAAI,KAAY;AAClC,QAAC,KAAK,SAAS,SAA+B,MAAM,IAAI,KAAK,YAAY;AACzE,QAAC,KAAK,UAAU,SAA+B,MAAM,IAAI,KAAK,YAAY;AAAA,MAC3E;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAiB,QAA2C;AAC3D,YAAI,CAAC,QAAQ;AACZ,eAAK,KAAK;AACV;AAAA,QACD;AAEA,aAAK,KAAK,cAAc,MAAM;AAC9B,YAAI,CAAC,SAAS,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,KAAK,IAAI,CAAC,GAAG;AAC7D,eAAK,KAAK;AACV;AAAA,QACD;AAEA,aAAK,KAAK,QAAQ,KAAK,IAAI;AAC3B,aAAK,KAAK,UAAU,KAAK,MAAM;AAE/B,cAAM,UAAU,IAAIF;AAAA,UACnB,KAAK,IAAI,KAAK,KAAK,GAAG,IAAI;AAAA,UAC1B,KAAK,IAAI,KAAK,KAAK,GAAG,IAAI;AAAA,UAC1B,KAAK,IAAI,KAAK,KAAK,GAAG,IAAI;AAAA,QAC3B;AACA,aAAK,SAAS,SAAS,QAAQ;AAC/B,aAAK,SAAS,WAAW;AAEzB,cAAM,WAAW,IAAI,cAAc,OAAO;AAC1C,aAAK,UAAU,SAAS,QAAQ;AAChC,aAAK,UAAU,WAAW;AAE1B,aAAK,UAAU,SAAS,KAAK,KAAK,MAAM;AACxC,aAAK,UAAU,UAAU;AAAA,MAC1B;AAAA,MAEA,OAAa;AACZ,aAAK,UAAU,UAAU;AAAA,MAC1B;AAAA,MAEA,UAAgB;AACf,aAAK,MAAM,OAAO,KAAK,SAAS;AAChC,aAAK,SAAS,SAAS,QAAQ;AAC/B,QAAC,KAAK,SAAS,SAA+B,QAAQ;AACtD,aAAK,UAAU,SAAS,QAAQ;AAChC,QAAC,KAAK,UAAU,SAA+B,QAAQ;AAAA,MACxD;AAAA,IACD;AAAA;AAAA;;;AC9GA,SAAS,WAA2B;AACpC,SAAS,iBAAiB,kBAAAK,iBAAgB,qBAAAC,oBAAmB,gBAAAC,eAAc,WAAW,WAAAC,gBAAwB;AAD9G,IAaM,mBACA,mBAEO;AAhBb;AAAA;AAAA;AAGA;AACA;AASA,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAEnB,IAAM,qBAAN,MAAyB;AAAA,MACvB;AAAA,MACA;AAAA,MACA,WAAoB,IAAIA,SAAQ,IAAI,EAAE;AAAA,MACtC,YAAuB,IAAI,UAAU;AAAA,MACrC,cAAc;AAAA,MACd,aAAgC,CAAC;AAAA,MACjC,cAAwC;AAAA,MACxC,aAAkC;AAAA,MAE1C,YAAY,OAAmB,SAAqC;AACnE,aAAK,QAAQ;AACb,aAAK,UAAU;AAAA,UACd,gBAAgB,SAAS,kBAAkB;AAAA,UAC3C,kBAAkB,SAAS,oBAAoB;AAAA,QAChD;AACA,aAAK,mBAAmB;AAAA,MACzB;AAAA,MAEQ,mBAAyB;AAChC,YAAI,KAAK,cAAc,CAAC,KAAK,MAAM,MAAO;AAE1C,aAAK,aAAa,IAAID;AAAA,UACrB,IAAIF,gBAAe;AAAA,UACnB,IAAIC,mBAAkB,EAAE,cAAc,KAAK,CAAC;AAAA,QAC7C;AACA,aAAK,MAAM,MAAM,MAAM,IAAI,KAAK,UAAU;AAC1C,aAAK,WAAW,UAAU;AAE1B,aAAK,cAAc,IAAI,kBAAkB,KAAK,MAAM,MAAM,KAAK;AAAA,MAChE;AAAA,MAEQ,sBAA4B;AACnC,YAAI,KAAK,cAAc,KAAK,MAAM,OAAO;AACxC,eAAK,MAAM,MAAM,MAAM,OAAO,KAAK,UAAU;AAC7C,eAAK,WAAW,SAAS,QAAQ;AACjC,UAAC,KAAK,WAAW,SAA+B,QAAQ;AACxD,eAAK,aAAa;AAAA,QACnB;AACA,aAAK,aAAa,QAAQ;AAC1B,aAAK,cAAc;AAAA,MACpB;AAAA,MAEA,SAAe;AACd,YAAI,CAAC,WAAW,SAAS;AACxB,cAAI,KAAK,YAAY;AACpB,iBAAK,oBAAoB;AAAA,UAC1B;AACA;AAAA,QACD;AAEA,YAAI,CAAC,KAAK,MAAM,SAAS,CAAC,KAAK,MAAM,SAAS,CAAC,KAAK,MAAM,UAAW;AAGrE,YAAI,CAAC,KAAK,YAAY;AACrB,eAAK,iBAAiB;AAAA,QACvB;AAEA,cAAM,EAAE,OAAO,UAAU,IAAI,KAAK;AAElC,YAAI,KAAK,YAAY;AACpB,gBAAM,EAAE,UAAU,OAAO,IAAI,MAAM,MAAM,YAAY;AACrD,eAAK,WAAW,SAAS,aAAa,YAAY,IAAI,gBAAgB,UAAU,CAAC,CAAC;AAClF,eAAK,WAAW,SAAS,aAAa,SAAS,IAAI,gBAAgB,QAAQ,CAAC,CAAC;AAAA,QAC9E;AACA,cAAM,OAAO,aAAa;AAC1B,cAAM,eAAe,SAAS,YAAY,SAAS;AAEnD,aAAK,UAAU,cAAc,KAAK,UAAU,UAAU,MAAM;AAC5D,cAAM,SAAS,KAAK,UAAU,IAAI,OAAO,MAAM;AAC/C,cAAM,YAAY,KAAK,UAAU,IAAI,UAAU,MAAM,EAAE,UAAU;AAEjE,cAAM,YAAY,IAAI;AAAA,UACrB,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO,EAAE;AAAA,UACxC,EAAE,GAAG,UAAU,GAAG,GAAG,UAAU,GAAG,GAAG,UAAU,EAAE;AAAA,QAClD;AACA,cAAM,MAA6B,MAAM,MAAM,QAAQ,WAAW,KAAK,QAAQ,gBAAgB,IAAI;AAEnG,YAAI,OAAO,cAAc;AAExB,gBAAM,YAAY,IAAI,UAAU;AAChC,gBAAMG,eAAkC,WAAW,UAAU;AAC7D,cAAIA,cAAa;AAChB,kBAAM,SAAS,KAAK,MAAM,UAAU,IAAIA,YAAW;AACnD,gBAAI,OAAQ,kBAAiB,MAAa;AAAA,UAC3C,OAAO;AACN,+BAAmB;AAAA,UACpB;AAEA,cAAI,KAAK,aAAa;AACrB,iBAAK,kBAAkBA,gBAAe,MAAM,QAAQ,WAAW,IAAI,GAAG;AAAA,UACvE;AAAA,QACD;AACA,aAAK,cAAc;AAEnB,cAAM,cAAc,iBAAiB;AACrC,YAAI,CAAC,aAAa;AACjB,eAAK,aAAa,KAAK;AACvB;AAAA,QACD;AACA,cAAM,gBAAqB,KAAK,MAAM,UAAU,IAAI,GAAG,WAAW,EAAE;AACpE,cAAM,eAAe,eAAe,SAAS,eAAe,QAAQ;AACpE,YAAI,CAAC,cAAc;AAClB,eAAK,aAAa,KAAK;AACvB;AAAA,QACD;AACA,gBAAQ,MAAM;AAAA,UACb,KAAK;AACJ,iBAAK,aAAa,SAAS,iBAAiB;AAC5C;AAAA,UACD,KAAK;AACJ,iBAAK,aAAa,SAAS,iBAAiB;AAC5C;AAAA,UACD;AACC,iBAAK,aAAa,SAAS,QAAQ;AACnC;AAAA,QACF;AACA,aAAK,aAAa,iBAAiB,YAAY;AAAA,MAChD;AAAA,MAEA,UAAgB;AACf,aAAK,WAAW,QAAQ,CAAC,OAAO,GAAG,CAAC;AACpC,aAAK,aAAa,CAAC;AACnB,aAAK,oBAAoB;AAAA,MAC1B;AAAA,MAEQ,kBAAkB,aAA4B,QAAiB,WAAoB,KAAa;AACvG,cAAM,OAAO,aAAa;AAC1B,gBAAQ,MAAM;AAAA,UACb,KAAK,UAAU;AACd,gBAAI,aAAa;AAChB,oBAAM,SAAS,KAAK,MAAM,UAAU,IAAI,WAAW;AACnD,kBAAI,OAAQ,mBAAkB,MAAa;AAAA,YAC5C;AACA;AAAA,UACD;AAAA,UACA,KAAK,UAAU;AACd,gBAAI,aAAa;AAChB,mBAAK,MAAM,mBAAmB,WAAW;AAAA,YAC1C;AACA;AAAA,UACD;AAAA,UACA,KAAK,SAAS;AACb,gBAAI,CAAC,KAAK,QAAQ,iBAAkB;AACpC,kBAAM,cAAc,OAAO,MAAM,EAAE,IAAI,UAAU,MAAM,EAAE,eAAe,GAAG,CAAC;AAC5E,kBAAM,UAAU,KAAK,QAAQ,iBAAiB,EAAE,UAAU,YAAY,CAAC;AACvE,gBAAI,SAAS;AACZ,sBAAQ,QAAQ,OAAO,EAAE,KAAK,CAAC,SAAS;AACvC,oBAAI,KAAM,MAAK,MAAM,YAAY,IAAI;AAAA,cACtC,CAAC,EAAE,MAAM,MAAM;AAAA,cAAE,CAAC;AAAA,YACnB;AACA;AAAA,UACD;AAAA,UACA;AACC;AAAA,QACF;AAAA,MACD;AAAA,MAEQ,qBAAqB;AAC5B,cAAM,SAAS,KAAK,MAAM,WAAW,SAAS,cAAc,KAAK,MAAM,OAAO,YAAY,SAAS;AACnG,YAAI,CAAC,OAAQ;AAEb,cAAM,cAAc,CAAC,MAAkB;AACtC,gBAAM,OAAO,OAAO,sBAAsB;AAC1C,gBAAM,KAAM,EAAE,UAAU,KAAK,QAAQ,KAAK,QAAS,IAAI;AACvD,gBAAM,IAAI,GAAI,EAAE,UAAU,KAAK,OAAO,KAAK,SAAU,IAAI;AACzD,eAAK,SAAS,IAAI,GAAG,CAAC;AAAA,QACvB;AAEA,cAAM,cAAc,CAAC,MAAkB;AACtC,eAAK,cAAc;AAAA,QACpB;AAEA,eAAO,iBAAiB,aAAa,WAAW;AAChD,eAAO,iBAAiB,aAAa,WAAW;AAEhD,aAAK,WAAW,KAAK,MAAM,OAAO,oBAAoB,aAAa,WAAW,CAAC;AAC/E,aAAK,WAAW,KAAK,MAAM,OAAO,oBAAoB,aAAa,WAAW,CAAC;AAAA,MAChF;AAAA,IACD;AAAA;AAAA;;;AClMA,SAAS,aAAAC,kBAAiB;AAD1B,IAYa;AAZb;AAAA;AAAA;AAIA;AAQO,IAAM,2BAAN,MAA8D;AAAA,MAC5D;AAAA,MAER,YAAY,OAAmB;AAC9B,aAAK,QAAQ;AAAA,MACd;AAAA,MAEA,UAAU,UAAyD;AAClE,cAAM,SAAS,MAAM,SAAS,KAAK,SAAS,CAAC;AAC7C,eAAO;AACP,eAAOA,WAAU,YAAY,MAAM;AAAA,MACpC;AAAA,MAEA,cAAc,MAA+B;AAC5C,cAAM,SAAc,KAAK,MAAM,UAAU,IAAI,IAAI,KAC7C,KAAK,MAAM,OAAO,aAAa,IAAI,IAAI,KACvC;AACJ,cAAM,SAAS,QAAQ,SAAS,QAAQ,QAAQ;AAChD,eAAO,UAAU;AAAA,MAClB;AAAA,MAEQ,WAA6B;AACpC,eAAO;AAAA,UACN,SAAS,WAAW;AAAA,UACpB,UAAU,WAAW,iBAAiB,CAAC,WAAW,eAAe,IAAI,IAAI,CAAC;AAAA,QAC3E;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACvCA,SAAS,WAAAC,gBAAe;AAAxB,IAUa;AAVb;AAAA;AAAA;AACA;AACA;AAQO,IAAM,sBAAN,MAA0B;AAAA,MACxB;AAAA,MAER,YAAY,OAAmB;AAC9B,aAAK,QAAQ;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,MAKA,sBAAmC;AAClC,cAAM,QAAQ,OAAO;AACrB,cAAM,SAAS,OAAO;AACtB,cAAM,mBAAmB,IAAIA,SAAQ,OAAO,MAAM;AAClD,eAAO,IAAI,YAAY,aAAa,aAAa,gBAAgB;AAAA,MAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,cAAc,gBAAqC,eAA4C;AAC9F,YAAI,gBAAgB;AACnB,iBAAO;AAAA,QACR;AACA,YAAI,eAAe;AAClB,iBAAO,cAAc;AAAA,QACtB;AACA,eAAO,KAAK,oBAAoB;AAAA,MACjC;AAAA,IACD;AAAA;AAAA;;;AC5CA,IAca;AAdb;AAAA;AAAA;AACA;AAaO,IAAM,uBAAN,MAA2B;AAAA,MACzB,kBAAwD,CAAC;AAAA,MACzD;AAAA,MACA;AAAA;AAAA;AAAA;AAAA,MAKR,gBAAgB,WAAmB,YAA0B;AAC5D,aAAK,YAAY;AACjB,aAAK,aAAa;AAAA,MACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,UAAU,UAAqD;AAC9D,aAAK,gBAAgB,KAAK,QAAQ;AAClC,eAAO,MAAM;AACZ,eAAK,kBAAkB,KAAK,gBAAgB,OAAO,CAAC,MAAM,MAAM,QAAQ;AAAA,QACzE;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,KAAK,OAA2B;AAE/B,mBAAW,WAAW,KAAK,iBAAiB;AAC3C,cAAI;AACH,oBAAQ,KAAK;AAAA,UACd,SAAS,GAAG;AACX,oBAAQ,MAAM,0BAA0B,CAAC;AAAA,UAC1C;AAAA,QACD;AAGA,cAAM,UAA+B;AAAA,UACpC,GAAG;AAAA,UACH,WAAW,KAAK;AAAA,UAChB,YAAY,KAAK;AAAA,QAClB;AAEA,YAAI,MAAM,SAAS,SAAS;AAC3B,uBAAa,KAAK,uBAAuB,OAAO;AAAA,QACjD,WAAW,MAAM,SAAS,YAAY;AACrC,uBAAa,KAAK,0BAA0B,OAAO;AAAA,QACpD,WAAW,MAAM,SAAS,YAAY;AACrC,uBAAa,KAAK,0BAA0B,OAAO;AAAA,QACpD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,UAAkB,oBAA0B;AACrD,aAAK,KAAK,EAAE,MAAM,SAAS,SAAS,UAAU,EAAE,CAAC;AAAA,MAClD;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,SAAiB,SAAiB,OAAqB;AACnE,cAAM,WAAW,QAAQ,IAAI,UAAU,QAAQ;AAC/C,aAAK,KAAK,EAAE,MAAM,YAAY,SAAS,UAAU,SAAS,MAAM,CAAC;AAAA,MAClE;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,UAAkB,gBAAsB;AACpD,aAAK,KAAK,EAAE,MAAM,YAAY,SAAS,UAAU,EAAE,CAAC;AAAA,MACrD;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACf,aAAK,kBAAkB,CAAC;AAAA,MACzB;AAAA,IACD;AAAA;AAAA;;;ACnGA,IASa;AATb;AAAA;AAAA;AAAA;AASO,IAAM,2BAAN,MAA+B;AAAA,MAC7B,QAA2B;AAAA,MAC3B,kBAAgD,oBAAI,IAAI;AAAA,MACxD,qBAAyF;AAAA;AAAA;AAAA;AAAA,MAKjG,OAAO,OAAyB;AAC/B,aAAK,QAAQ;AACb,aAAK,qBAAqB,CAAC,YAAY;AACtC,eAAK,kBAAkB,QAAQ,UAAU,QAAQ,OAAO;AAAA,QACzD;AACA,sBAAc,GAAG,uBAAuB,KAAK,kBAAkB;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,QAAQ,QAA+B;AACtC,aAAK,gBAAgB,IAAI,OAAO,MAAM,MAAM;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,UAAwB;AACjC,aAAK,gBAAgB,OAAO,QAAQ;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKQ,kBAAkB,UAAkB,SAAwB;AACnE,cAAM,SAAS,KAAK,gBAAgB,IAAI,QAAQ;AAChD,YAAI,CAAC,UAAU,CAAC,SAAS;AACxB,eAAK,gBAAgB,OAAO,QAAQ;AACpC;AAAA,QACD;AAEA,aAAK,OAAO,eAAe,MAAM;AACjC,aAAK,gBAAgB,OAAO,QAAQ;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACf,YAAI,KAAK,oBAAoB;AAC5B,wBAAc,IAAI,uBAAuB,KAAK,kBAAkB;AAChE,eAAK,qBAAqB;AAAA,QAC3B;AACA,aAAK,gBAAgB,MAAM;AAC3B,aAAK,QAAQ;AAAA,MACd;AAAA,IACD;AAAA;AAAA;;;AC3DO,SAAS,WAAW,MAAiC;AAC3D,SAAO,CAAC,CAAC,QAAQ,OAAO,SAAS,YAAY,OAAQ,KAAa,WAAW;AAC9E;AAKO,SAAS,WAAW,MAAqC;AAC/D,SAAO,CAAC,CAAC,QAAQ,OAAQ,KAAa,SAAS;AAChD;AAKO,SAAS,gBAAgB,MAAsC;AACrE,SAAO,CAAC,CAAC,QAAQ,OAAO,SAAS,YAAa,KAAa,aAAa,SAAS;AAClF;AAMO,SAAS,eAAe,MAAwB;AACtD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,MAAI,WAAW,IAAI,EAAG,QAAO;AAC7B,MAAI,gBAAgB,IAAI,EAAG,QAAO;AAClC,MAAI,WAAW,IAAI,EAAG,QAAO;AAC7B,MAAI,OAAQ,KAAa,SAAS,WAAY,QAAO;AAErD,SAAQ,KAAa,gBAAgB,UAAW,KAAa,aAAa,SAAS;AACpF;AAKO,SAAS,cAAc,MAAwB;AACrD,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,WAAW,IAAI,EAAG,QAAO;AAC7B,MAAI,OAAO,SAAS,WAAY,QAAO;AACvC,MAAI,WAAW,IAAI,EAAG,QAAO;AAC7B,SAAO;AACR;AA/CA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAgB,WAAAC,iBAAe;AAoCxB,SAAS,2BAAwC;AACvD,SAAO,IAAI;AAAA,IACV;AAAA,MACC,IAAI,CAAC,aAAa,YAAY;AAAA,MAC9B,IAAI,CAAC,aAAa,YAAY;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAIA,UAAQ,GAAG,GAAG,CAAC;AAAA,IACnB,CAAC;AAAA,EACF;AACD;AAmBO,SAAS,kBAAkB,UAAiB,CAAC,GAAuB;AAC1E,QAAM,WAAW,yBAAyB;AAC1C,MAAI,SAA+B,CAAC;AACpC,QAAM,WAAuB,CAAC;AAC9B,QAAM,gBAAkF,CAAC;AACzF,MAAI;AAEJ,aAAW,QAAQ,SAAS;AAC3B,QAAI,gBAAgB,IAAI,GAAG;AAC1B,eAAS;AAAA,IACV,WAAW,WAAW,IAAI,GAAG;AAC5B,eAAS,KAAK,IAAI;AAAA,IACnB,WAAW,cAAc,IAAI,KAAK,CAAC,WAAW,IAAI,GAAG;AACpD,oBAAc,KAAK,IAAI;AAAA,IACxB,WAAW,eAAe,IAAI,GAAG;AAChC,eAAS,EAAE,GAAG,QAAQ,GAAG,KAAK;AAAA,IAC/B;AAAA,EACD;AAGA,QAAM,iBAAiB,IAAI;AAAA,IAC1B,OAAO,UAAU,SAAS;AAAA,IAC1B,OAAO,mBAAmB,SAAS;AAAA,IACnC,OAAO,mBAAmB,SAAS;AAAA,IACnC,OAAO,oBAAoB,SAAS;AAAA,IACpC,OAAO,WAAW,SAAS;AAAA,IAC3B,OAAO,aAAa,SAAS;AAAA,EAC9B;AAEA,SAAO,EAAE,QAAQ,gBAAgB,UAAU,eAAe,OAAO;AAClE;AAjGA,IAsBa;AAtBb;AAAA;AAAA;AAGA;AACA;AAkBO,IAAM,cAAN,MAAkB;AAAA,MACxB,YACQ,QACA,iBACA,iBACA,kBACA,SACA,WACN;AANM;AACA;AACA;AACA;AACA;AACA;AAAA,MACJ;AAAA,IACL;AAAA;AAAA;;;AC/BA,SAAS,WAAW,eAAe,WAAW,oBAAoB;AAClE,SAAS,SAAAC,QAAO,WAAAC,iBAAwB;AASxC,SAAS,aAAAC,kBAAiB;AAO1B,SAAS,UAAAC,eAAc;AAjBvB,IAoDM,YAWO;AA/Db;AAAA;AAAA;AAGA;AACA;AACA;AAIA;AAEA;AAGA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAsBA,IAAM,aAAa;AAWZ,IAAM,aAAN,cAAyB,cAA0B;AAAA,MAClD,OAAO;AAAA,MAEd,QAAoB,EAAE,GAAG,kBAAkB;AAAA,MAC3C;AAAA,MAEA;AAAA,MACA;AAAA,MAEA,WAA4B,CAAC;AAAA,MAC7B,eAAsC,oBAAI,IAAI;AAAA,MAC9C,cAAqC,oBAAI,IAAI;AAAA,MAErC,kBAAsC,CAAC;AAAA,MACvC,kBAAuC,CAAC;AAAA,MACxC,WAAoB;AAAA,MAE5B,YAAmC,oBAAI,IAAI;AAAA,MAEnC,sBAAyD,CAAC;AAAA,MAElE,MAAM,UAAU;AAAA,MAChB,aAAkB;AAAA,MAClB,kBAAmE;AAAA,MAC3D,kBAAoC,CAAC;AAAA,MACrC,uBAAoC,oBAAI,IAAI;AAAA,MACpD,gBAA2C;AAAA,MAC3C,sBAAuD;AAAA,MAC/C,wBAA6C;AAAA,MAErD;AAAA,MACA,aAA2B;AAAA,MAC3B;AAAA,MACA,YAAiC;AAAA;AAAA,MAGzB;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,YAAY,UAAwB,CAAC,GAAG;AACvC,cAAM;AACN,aAAK,QAAQ;AACb,aAAK,QAAQ;AACb,aAAK,OAAOA,QAAO;AAGnB,aAAK,iBAAiB,IAAI,oBAAoB,IAAI;AAClD,aAAK,kBAAkB,IAAI,qBAAqB;AAChD,aAAK,sBAAsB,IAAI,yBAAyB;AAGxD,cAAM,SAAS,kBAAkB,OAAO;AACxC,aAAK,SAAS,OAAO;AACrB,aAAK,WAAW,OAAO;AACvB,aAAK,kBAAkB,OAAO;AAG9B,aAAK,UAAU;AAAA,UACd,GAAG,KAAK;AAAA,UACR,QAAQ,OAAO,OAAO;AAAA,UACtB,iBAAiB,OAAO,OAAO;AAAA,UAC/B,iBAAiB,OAAO,OAAO;AAAA,UAC/B,kBAAkB,OAAO,OAAO;AAAA,UAChC,SAAS,OAAO,OAAO;AAAA,UACvB,WAAW,OAAO,OAAO;AAAA,UACzB,UAAU,CAAC;AAAA,QACZ,CAAC;AAED,aAAK,UAAU,OAAO,OAAO,WAAW,IAAIF,UAAQ,GAAG,GAAG,CAAC;AAAA,MAC5D;AAAA,MAEQ,+BAA+B,QAAwB;AAC9D,YAAI,KAAK,UAAU;AAClB,eAAK,YAAY,MAAM;AAAA,QACxB,OAAO;AACN,eAAK,SAAS,KAAK,MAAM;AAAA,QAC1B;AAAA,MACD;AAAA,MAEQ,gCAAgC,SAA6B;AACpE,YAAI,KAAK,UAAU;AAClB,kBACE,KAAK,CAAC,WAAW,KAAK,YAAY,MAAM,CAAC,EACzC,MAAM,CAAC,MAAM,QAAQ,MAAM,gCAAgC,CAAC,CAAC;AAAA,QAChE,OAAO;AACN,eAAK,gBAAgB,KAAK,OAA4B;AAAA,QACvD;AAAA,MACD;AAAA,MAEQ,UAAUG,QAAmB;AACpC,aAAK,QAAQA;AAAA,MACd;AAAA,MAEQ,WAAW;AAClB,cAAM,EAAE,iBAAiB,gBAAgB,IAAI,KAAK;AAClD,cAAM,QAAQ,2BAA2BJ,SAAQ,kBAAkB,IAAIA,OAAM,eAAe;AAC5F,gCAAwB,KAAK;AAC7B,gCAAwB,eAAe;AAEvC,0BAAkB,KAAK,MAAM,aAAa,CAAC,CAAC;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,KAAK,IAAY,QAA6B;AACnD,aAAK,SAAS;AAGd,cAAM,cAAc,KAAK,eAAe,cAAc,QAAQ,KAAK,MAAM;AACzE,aAAK,YAAY;AACjB,aAAK,QAAQ,IAAI,WAAW,IAAI,aAAa,KAAK,KAAK;AAEvD,cAAM,eAAe,MAAM,WAAW,YAAY,KAAK,WAAW,IAAIC,UAAQ,GAAG,GAAG,CAAC,CAAC;AACtF,aAAK,QAAQ,IAAI,WAAW,YAAY;AAExC,aAAK,MAAM,MAAM;AACjB,aAAK,oBAAoB,OAAO,KAAK,KAAK;AAE1C,aAAK,gBAAgB,UAAU;AAG/B,cAAM,KAAK,uBAAuB;AAElC,aAAK,kBAAkB,sBAAsB,IAA8B;AAC3E,aAAK,WAAW;AAChB,aAAK,gBAAgB,aAAa;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,CAAS,sBAAmF;AAC3F,cAAM,QAAQ,KAAK,SAAS,SAAS,KAAK,gBAAgB,SAAS,KAAK,gBAAgB;AACxF,YAAI,UAAU;AAEd,mBAAW,SAAS,KAAK,UAAU;AAClC,eAAK,YAAY,KAAK;AACtB;AACA,gBAAM,EAAE,SAAS,OAAO,MAAM,MAAM,QAAQ,UAAU;AAAA,QACvD;AAEA,YAAI,KAAK,gBAAgB,QAAQ;AAChC,eAAK,QAAQ,GAAG,KAAK,eAAe;AACpC,qBAAW,KAAK,gBAAgB;AAChC,eAAK,kBAAkB,CAAC;AACxB,gBAAM,EAAE,SAAS,OAAO,MAAM,mBAAmB;AAAA,QAClD;AAEA,YAAI,KAAK,gBAAgB,QAAQ;AAChC,qBAAW,WAAW,KAAK,iBAAiB;AAC3C,oBAAQ,KAAK,CAAC,WAAW;AACxB,mBAAK,YAAY,MAAM;AAAA,YACxB,CAAC,EAAE,MAAM,CAAC,MAAM,QAAQ,MAAM,0CAA0C,CAAC,CAAC;AAAA,UAC3E;AACA,qBAAW,KAAK,gBAAgB;AAChC,eAAK,kBAAkB,CAAC;AACxB,gBAAM,EAAE,SAAS,OAAO,MAAM,iBAAiB;AAAA,QAChD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAc,yBAAwC;AACrD,cAAM,MAAM,KAAK,oBAAoB;AACrC,mBAAW,YAAY,KAAK;AAC3B,eAAK,gBAAgB,aAAa,UAAU,SAAS,IAAI,IAAI,SAAS,SAAS,SAAS,KAAK;AAG7F,gBAAM,IAAI,QAAc,aAAW,WAAW,SAAS,CAAC,CAAC;AAAA,QAC1D;AAAA,MACD;AAAA,MAGU,OAAO,QAAwC;AACxD,YAAI,CAAC,KAAK,SAAS,CAAC,KAAK,OAAO;AAC/B,eAAK,mBAAmB;AACxB;AAAA,QACD;AAEA,aAAK,oBAAoB;AAGzB,aAAK,wBAAwBC,WAAU,YAAY,MAAM;AACxD,eAAK,oBAAoB;AAAA,QAC1B,CAAC;AAAA,MACF;AAAA,MAEQ,sBAA4B;AACnC,YAAI,WAAW,WAAW,CAAC,KAAK,iBAAiB,KAAK,SAAS,KAAK,OAAO;AAE1E,eAAK,gBAAgB,IAAI,mBAAmB,IAAI;AAGhD,cAAI,KAAK,aAAa,CAAC,KAAK,qBAAqB;AAChD,iBAAK,sBAAsB,IAAI,yBAAyB,IAAI;AAC5D,iBAAK,UAAU,iBAAiB,KAAK,mBAAmB;AAAA,UACzD;AAAA,QACD,WAAW,CAAC,WAAW,WAAW,KAAK,eAAe;AAErD,eAAK,cAAc,QAAQ;AAC3B,eAAK,gBAAgB;AAGrB,cAAI,KAAK,WAAW;AACnB,iBAAK,UAAU,iBAAiB,IAAI;AAAA,UACrC;AACA,eAAK,sBAAsB;AAAA,QAC5B;AAAA,MACD;AAAA,MAEU,QAAQ,QAAyC;AAC1D,cAAM,EAAE,MAAM,IAAI;AAClB,YAAI,CAAC,KAAK,SAAS,CAAC,KAAK,OAAO;AAC/B,eAAK,mBAAmB;AACxB;AAAA,QACD;AACA,aAAK,MAAM,OAAO,MAAM;AACxB,aAAK,iBAAiB,OAAO,KAAK,GAAG;AAErC,mBAAW,UAAU,KAAK,iBAAiB;AAC1C,iBAAO,OAAO,KAAK,KAAK,KAAK;AAAA,QAC9B;AACA,aAAK,aAAa,QAAQ,CAAC,OAAO,QAAQ;AACzC,gBAAM,WAAW;AAAA,YAChB,GAAG;AAAA,YACH,IAAI;AAAA,UACL,CAAC;AACD,cAAI,MAAM,kBAAkB;AAC3B,iBAAK,mBAAmB,MAAM,IAAI;AAAA,UACnC;AAAA,QACD,CAAC;AACD,aAAK,MAAM,OAAO,EAAE,MAAM,CAAC;AAC3B,aAAK,MAAM,aAAa,KAAK;AAAA,MAC9B;AAAA,MAEO,YAAY;AAClB,aAAK,YAAY;AAAA,MAClB;AAAA;AAAA,MAGO,cAAc;AACpB,YAAI,WAAW,SAAS;AACvB,eAAK,eAAe,OAAO;AAAA,QAC5B;AAAA,MACD;AAAA;AAAA,MAGU,SAAS,QAA0C;AAE5D,mBAAW,UAAU,KAAK,iBAAiB;AAC1C,iBAAO,UAAU,KAAK,GAAG;AAAA,QAC1B;AACA,aAAK,kBAAkB,CAAC;AACxB,aAAK,qBAAqB,MAAM;AAChC,aAAK,aAAa,QAAQ,CAAC,UAAU;AACpC,cAAI;AAAE,kBAAM,YAAY,EAAE,IAAI,OAAO,SAAS,WAAW,EAAE,CAAC;AAAA,UAAG,QAAQ;AAAA,UAAa;AAAA,QACrF,CAAC;AACD,aAAK,aAAa,MAAM;AACxB,aAAK,YAAY,MAAM;AACvB,aAAK,UAAU,MAAM;AAErB,aAAK,OAAO,QAAQ;AACpB,aAAK,OAAO,QAAQ;AAGpB,YAAI,KAAK,uBAAuB;AAC/B,eAAK,sBAAsB;AAC3B,eAAK,wBAAwB;AAAA,QAC9B;AAEA,aAAK,eAAe,QAAQ;AAC5B,aAAK,gBAAgB;AACrB,aAAK,WAAW,iBAAiB,IAAI;AACrC,aAAK,sBAAsB;AAE3B,aAAK,oBAAoB,QAAQ;AAEjC,aAAK,WAAW;AAChB,aAAK,QAAQ;AACb,aAAK,QAAQ;AACb,aAAK,YAAY;AAEjB,aAAK,iBAAiB,QAAQ,KAAK,GAAG;AACtC,aAAK,kBAAkB;AAGvB,4BAAoB;AAEpB,uBAAe,IAAI;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,YAAY,OAAiB;AAClC,YAAI,CAAC,KAAK,SAAS,CAAC,KAAK,OAAO;AAC/B;AAAA,QACD;AACA,cAAM,SAAS,MAAM,OAAO;AAC5B,cAAM,MAAM,UAAU,KAAK,GAAG;AAC9B,eAAO,MAAM;AACb,aAAK,MAAM,UAAU,MAAM;AAG3B,YAAI,OAAO,OAAO,oBAAoB,YAAY;AACjD,qBAAW,OAAO,OAAO,gBAAgB,GAAG;AAC3C,kBAAM,MAAM,IAAI,WAAW;AAC3B,gBAAI,CAAC,KAAK,qBAAqB,IAAI,GAAG,GAAG;AACxC,oBAAM,SAAS,IAAI,WAAW,cAAc,EAAE,OAAO,KAAK,OAAO,KAAK,KAAK,IAAI,CAAC;AAChF,mBAAK,gBAAgB,KAAK,MAAM;AAChC,mBAAK,qBAAqB,IAAI,GAAG;AAAA,YAClC;AAAA,UACD;AAAA,QACD;AAEA,YAAI,OAAO,cAAc;AACxB,eAAK,MAAM,UAAU,MAAM;AAAA,QAC5B;AACA,cAAM,UAAU;AAAA,UACf,IAAI;AAAA,UACJ,SAAS,WAAW;AAAA,UACpB,QAAQ,KAAK,MAAM;AAAA,QACpB,CAAC;AACD,aAAK,iBAAiB,MAAM;AAC5B,aAAK,oBAAoB,QAAQ,MAAM;AAAA,MACxC;AAAA,MAEA,iBAAiB,OAA+C;AAC/D,YAAI,iBAAiB,YAAY;AAChC,iBAAO,EAAE,GAAG,MAAM,UAAU,EAAE;AAAA,QAC/B;AACA,eAAO;AAAA,UACN,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,KAAK,MAAM;AAAA,QACZ;AAAA,MACD;AAAA;AAAA,MAGA,iBAAiB,QAAkB;AAClC,aAAK,aAAa,IAAI,OAAO,KAAK,MAAM;AACxC,YAAI,WAAW,SAAS;AACvB,eAAK,UAAU,IAAI,OAAO,MAAM,MAAM;AAAA,QACvC;AACA,mBAAW,WAAW,KAAK,qBAAqB;AAC/C,cAAI;AACH,oBAAQ,MAAM;AAAA,UACf,SAAS,GAAG;AACX,oBAAQ,MAAM,gCAAgC,CAAC;AAAA,UAChD;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,cAAc,UAAsC,SAAwC;AAC3F,aAAK,oBAAoB,KAAK,QAAQ;AACtC,YAAI,SAAS,kBAAkB,KAAK,UAAU;AAC7C,eAAK,aAAa,QAAQ,CAAC,WAAW;AACrC,gBAAI;AAAE,uBAAS,MAAM;AAAA,YAAG,SAAS,GAAG;AAAE,sBAAQ,MAAM,+BAA+B,CAAC;AAAA,YAAG;AAAA,UACxF,CAAC;AAAA,QACF;AACA,eAAO,MAAM;AACZ,eAAK,sBAAsB,KAAK,oBAAoB,OAAO,CAAC,MAAM,MAAM,QAAQ;AAAA,QACjF;AAAA,MACD;AAAA,MAEA,UAAU,UAAyC;AAClD,eAAO,KAAK,gBAAgB,UAAU,QAAQ;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,eAAe,iBAA+D;AAC7E,YAAI;AACJ,YAAI,OAAO,oBAAoB,YAAY;AAC1C,mBAAS,gBAAgB,EAAE,OAAO,KAAK,OAAO,KAAK,KAAK,IAAI,CAAC;AAAA,QAC9D,OAAO;AACN,mBAAS;AAAA,QACV;AACA,aAAK,gBAAgB,KAAK,MAAM;AAChC,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,mBAAmB,MAAuB;AACzC,YAAI,CAAC,KAAK,SAAS,CAAC,KAAK,MAAO,QAAO;AAGvC,cAAM,YAAY,KAAK,MAAM,aAAa,IAAI,IAAI;AAClD,cAAM,SAAc,aAAa,KAAK,UAAU,IAAI,IAAI;AACxD,YAAI,CAAC,OAAQ,QAAO;AAEpB,aAAK,oBAAoB,UAAU,IAAI;AAEvC,aAAK,MAAM,cAAc,MAAM;AAE/B,YAAI,OAAO,OAAO;AACjB,eAAK,MAAM,MAAM,OAAO,OAAO,KAAK;AAAA,QACrC,WAAW,OAAO,MAAM;AACvB,eAAK,MAAM,MAAM,OAAO,OAAO,IAAI;AAAA,QACpC;AAEA,qBAAa,KAAK,KAAK,OAAO,GAAG;AAEjC,YAAI,WAA0B;AAC9B,aAAK,aAAa,QAAQ,CAAC,OAAO,QAAQ;AACzC,cAAK,MAAc,SAAS,MAAM;AACjC,uBAAW;AAAA,UACZ;AAAA,QACD,CAAC;AACD,YAAI,aAAa,MAAM;AACtB,eAAK,aAAa,OAAO,QAAQ;AAAA,QAClC;AACA,aAAK,UAAU,OAAO,IAAI;AAC1B,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,gBAAgB,MAAc;AAC7B,cAAM,MAAM,OAAO,QAAQ,OAAO,YAAY,KAAK,YAAY,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,CAAC,CAAC;AACzF,cAAM,SAAS,IAAI,KAAK,CAAC,UAAU,MAAM,SAAS,IAAI;AACtD,YAAI,CAAC,QAAQ;AACZ,kBAAQ,KAAK,UAAU,IAAI,YAAY;AAAA,QACxC;AACA,eAAO,UAAU;AAAA,MAClB;AAAA,MAEA,qBAAqB;AACpB,gBAAQ,KAAK,8BAA8B;AAAA,MAC5C;AAAA;AAAA,MAGA,OAAO,OAAe,QAAgB;AACrC,YAAI,KAAK,OAAO;AACf,eAAK,MAAM,eAAe,OAAO,MAAM;AAAA,QACxC;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,WAAW,OAA2B;AACrC,mBAAW,QAAQ,OAAO;AACzB,cAAI,CAAC,KAAM;AACX,cAAI,WAAW,IAAI,GAAG;AACrB,iBAAK,+BAA+B,IAAI;AACxC;AAAA,UACD;AACA,cAAI,OAAO,SAAS,YAAY;AAC/B,gBAAI;AACH,oBAAM,SAAU,KAAyC;AACzD,kBAAI,WAAW,MAAM,GAAG;AACvB,qBAAK,+BAA+B,MAAM;AAAA,cAC3C,WAAW,WAAW,MAAM,GAAG;AAC9B,qBAAK,gCAAgC,MAAsB;AAAA,cAC5D;AAAA,YACD,SAAS,OAAO;AACf,sBAAQ,MAAM,kCAAkC,KAAK;AAAA,YACtD;AACA;AAAA,UACD;AACA,cAAI,WAAW,IAAI,GAAG;AACrB,iBAAK,gCAAgC,IAAoB;AAAA,UAC1D;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;AC3iBA,SAAS,SAAAG,cAAa;AACtB,SAAS,WAAAC,iBAAe;AAkCjB,SAAS,gBAAgB,SAAqC;AACpE,QAAM,WAAW,sBAAsB;AACvC,MAAI,iBAAiB,CAAC;AACtB,MAAI,OAAO,QAAQ,CAAC,MAAM,UAAU;AACnC,qBAAiB,QAAQ,MAAM,KAAK,CAAC;AAAA,EACtC;AACA,QAAM,iBAAiB,EAAE,GAAG,UAAU,GAAG,eAAe;AACxD,SAAO,CAAC,gBAAgB,GAAG,OAAO;AACnC;AAGA,SAAS,wBAAmD;AAC3D,SAAO;AAAA,IACN,iBAAiB,mBAAmB;AAAA,IACpC,iBAAiB,mBAAmB,mBAAmB;AAAA,IACvD,QAAQ,mBAAmB,SAAS,EAAE,GAAG,mBAAmB,OAAO,IAAI;AAAA,IACvE,SAAS,mBAAmB;AAAA,IAC5B,WAAW,mBAAmB,YAAY,EAAE,GAAG,mBAAmB,UAAU,IAAI;AAAA,EACjF;AACD;AAtDA,IAUM,iBAWA;AArBN;AAAA;AAAA;AAGA;AAOA,IAAM,kBAA6C;AAAA,MAClD,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,QAAQ;AAAA,QACP,IAAI,CAAC,aAAa,UAAU;AAAA,QAC5B,IAAI,CAAC,aAAa,UAAU;AAAA,MAC7B;AAAA,MACA,SAAS,IAAIA,UAAQ,GAAG,GAAG,CAAC;AAAA,MAC5B,WAAW,CAAC;AAAA,IACb;AAEA,IAAM,qBAAqBD,OAAiC;AAAA,MAC3D,GAAG;AAAA,IACJ,CAAC;AAAA;AAAA;;;AC4LM,SAAS,eAAe,SAA8B;AAC5D,QAAM,WAAW,gBAAgB,OAAO;AACxC,SAAO,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAiB;AAC/C;AAtNA,IAca;AAdb;AAAA;AAAA;AAEA;AAEA;AACA;AACA;AAEA;AAMO,IAAM,QAAN,MAAY;AAAA,MAClB;AAAA,MACA,UAA6B,CAAC;AAAA;AAAA,MAEtB,mBAA+B,CAAC;AAAA;AAAA,MAGhC,iBAAmD,CAAC;AAAA,MACpD,kBAAqD,CAAC;AAAA,MACtD,mBAAuD,CAAC;AAAA,MACxD,0BAAgE,CAAC;AAAA;AAAA,MAGjE,gBAAgB,IAAI,qBAAkC;AAAA,MAE9D,YAAY,SAAuB;AAClC,aAAK,UAAU;AACf,aAAK,eAAe;AAAA,MACrB;AAAA,MAEA,MAAM,KAAK,IAAY,QAA6C;AACnE,mBAAW,WAAW,CAAC;AAEvB,cAAM,cAAc,CAAC,GAAG,KAAK,SAAS,GAAG,KAAK,gBAAgB;AAC9D,aAAK,mBAAmB,CAAC;AAEzB,aAAK,eAAe,IAAI,WAAW,WAAW;AAC9C,aAAK,aAAa,aAAa;AAG/B,aAAK,wBAAwB,QAAQ,QAAM;AAC1C,eAAK,aAAc,UAAU,EAAE;AAAA,QAChC,CAAC;AACD,aAAK,0BAA0B,CAAC;AAEhC,cAAM,cAAc,kBAAkB,gBAAgB,OAAO,YAAY;AACzE,cAAM,KAAK,aAAc,KAAK,IAAI,WAAW;AAE7C,aAAK,aAAc,cAAc,CAAC,UAAU;AAC3C,gBAAM,OAAO,KAAK,aAAc,iBAAiB,KAAK;AACtD,qBAAW,WAAW,CAAC,GAAG,WAAW,UAAU,IAAI;AAAA,QACpD,GAAG,EAAE,gBAAgB,KAAK,CAAC;AAG3B,aAAK,wBAAwB;AAAA,MAE9B;AAAA,MAEQ,0BAA0B;AACjC,YAAI,CAAC,KAAK,aAAc;AAGxB,YAAI,KAAK,eAAe,SAAS,GAAG;AACnC,eAAK,aAAa,QAAQ,CAAC,WAAW;AACrC,kBAAM,WAAW,EAAE,GAAG,QAAQ,OAAO,KAAK;AAC1C,iBAAK,eAAe,QAAQ,QAAM,GAAG,QAAQ,CAAC;AAAA,UAC/C;AAAA,QACD;AAGA,YAAI,KAAK,gBAAgB,SAAS,GAAG;AACpC,eAAK,aAAa,SAAS,CAAC,WAAW;AACtC,kBAAM,WAAW,EAAE,GAAG,QAAQ,OAAO,KAAK;AAC1C,iBAAK,gBAAgB,QAAQ,QAAM,GAAG,QAAQ,CAAC;AAAA,UAChD;AAAA,QACD;AAGA,YAAI,KAAK,iBAAiB,SAAS,GAAG;AACrC,eAAK,aAAa,UAAU,CAAC,WAAW;AACvC,kBAAM,WAAW,EAAE,GAAG,QAAQ,OAAO,KAAK;AAC1C,iBAAK,iBAAiB,QAAQ,QAAM,GAAG,QAAQ,CAAC;AAAA,UACjD;AAAA,QACD;AAAA,MACD;AAAA,MAEA,MAAM,YAAY,UAAsB;AAEvC,aAAK,iBAAiB,KAAK,GAAG,QAAQ;AACtC,YAAI,CAAC,KAAK,cAAc;AAAE;AAAA,QAAQ;AAClC,aAAK,aAAc,QAAQ,GAAG,QAAQ;AAAA,MACvC;AAAA,MAEA,OAAO,QAA4B;AAClC,aAAK,gBAAgB,GAAG,MAAM;AAC9B,aAAK,WAAW,GAAG,MAAM;AAAA,MAC1B;AAAA,MAEQ,mBAAmB,QAA4B;AACtD,YAAI,KAAK,cAAc;AAAE;AAAA,QAAQ;AAEjC,aAAK,QAAQ,KAAK,GAAI,MAAuC;AAAA,MAC9D;AAAA,MAEQ,cAAc,QAA4B;AACjD,YAAI,CAAC,KAAK,cAAc;AAAE;AAAA,QAAQ;AAClC,aAAK,aAAc,QAAQ,GAAI,MAAc;AAAA,MAC9C;AAAA,MAEA,MAAM,QAAkC;AACvC,aAAK,cAAc,UAAU,MAAM;AAAA,MACpC;AAAA;AAAA,MAGA,YAAY,WAA+C;AAC1D,aAAK,gBAAgB,KAAK,GAAG,SAAS;AAEtC,YAAI,KAAK,cAAc;AACtB,eAAK,aAAa,SAAS,CAAC,WAAW;AACtC,kBAAM,WAAW,EAAE,GAAG,QAAQ,OAAO,KAAK;AAC1C,iBAAK,gBAAgB,QAAQ,QAAM,GAAG,QAAQ,CAAC;AAAA,UAChD;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA,MAEA,WAAW,WAA8C;AACxD,aAAK,eAAe,KAAK,GAAG,SAAS;AAErC,YAAI,KAAK,cAAc;AACtB,eAAK,aAAa,QAAQ,CAAC,WAAW;AACrC,kBAAM,WAAW,EAAE,GAAG,QAAQ,OAAO,KAAK;AAC1C,iBAAK,eAAe,QAAQ,QAAM,GAAG,QAAQ,CAAC;AAAA,UAC/C;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA,MAEA,aAAa,WAAgD;AAC5D,aAAK,iBAAiB,KAAK,GAAG,SAAS;AAEvC,YAAI,KAAK,cAAc;AACtB,eAAK,aAAa,UAAU,CAAC,WAAW;AACvC,kBAAM,WAAW,EAAE,GAAG,QAAQ,OAAO,KAAK;AAC1C,iBAAK,iBAAiB,QAAQ,QAAM,GAAG,QAAQ,CAAC;AAAA,UACjD;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA,MAEA,UAAU,UAAyC;AAClD,YAAI,CAAC,KAAK,cAAc;AACvB,eAAK,wBAAwB,KAAK,QAAQ;AAC1C,iBAAO,MAAM;AACZ,iBAAK,0BAA0B,KAAK,wBAAwB,OAAO,OAAK,MAAM,QAAQ;AAAA,UACvF;AAAA,QACD;AACA,eAAO,KAAK,aAAa,UAAU,QAAQ;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,gBACC,MACA,MACsF;AACtF,cAAM,SAAS,KAAK,cAAc,SAAS,KAAK,OAAK,EAAE,SAAS,IAAI;AACpE,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,SAAsC,OAAU,SAA+B;AAC9E,aAAK,cAAc,SAAS,OAAO,OAAO;AAC1C,QAAC,cAAsB,KAAK,OAAO,OAAO;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAoC,OAAU,SAAwD;AACrG,eAAO,KAAK,cAAc,OAAO,OAAO,OAAO;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACf,aAAK,cAAc,QAAQ;AAAA,MAC5B;AAAA,IACD;AAAA;AAAA;;;AC9MA;AACA;;;ACAA;AADA,SAAS,aAAAE,kBAAiB;AAQnB,IAAM,qBAAqB;AAuB3B,SAAS,2BAAuC;AACtD,SAAOA,WAAU,YAAY,MAAM;AAClC,UAAM,SAAgC;AAAA,MACrC,UAAU,WAAW;AAAA,MACrB,WAAW,WAAW;AAAA,IACvB;AACA,WAAO,cAAc,IAAI,YAAY,oBAAoB,EAAE,OAAO,CAAC,CAAC;AAAA,EACrE,CAAC;AACF;AAMO,SAAS,qBAA2B;AAC1C,QAAM,SAAgC;AAAA,IACrC,UAAU,WAAW;AAAA,IACrB,WAAW,WAAW;AAAA,EACvB;AACA,SAAO,cAAc,IAAI,YAAY,oBAAoB,EAAE,OAAO,CAAC,CAAC;AACrE;","names":["all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","Color","proxy","Quaternion","Vector2","Vector3","Vector3","state","Vector3","Object3D","WebGLRenderer","position","Vector2","Vector3","Color","Vector3","Color","Vector3","proxy","subscribe","THREE","Group","Vector3","RAPIER","Scene","Color","Vector3","ShaderMaterial","Mesh","state","position","BoxGeometry","Color","Group","Mesh","Vector3","BufferGeometry","LineBasicMaterial","LineSegments","Vector2","hoveredUuid","subscribe","Vector2","Vector3","Color","Vector3","subscribe","nanoid","state","proxy","Vector3","subscribe"]}
1
+ {"version":3,"sources":["../src/lib/stage/zylem-stage.ts","../src/lib/collision/world.ts","../src/lib/game/game-state.ts","../src/lib/game/game-event-bus.ts","../src/lib/entities/actor.ts","../src/lib/entities/entity.ts","../src/lib/systems/transformable.system.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/src/index.ts","../src/lib/events/event-emitter-delegate.ts","../src/lib/events/zylem-events.ts","../src/lib/actions/capabilities/transform-store.ts","../src/lib/actions/capabilities/moveable.ts","../src/lib/actions/capabilities/rotatable.ts","../src/lib/actions/capabilities/transformable.ts","../src/lib/entities/parts/collision-factories.ts","../src/lib/entities/common.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/core/asset-manager.ts","../src/lib/core/loaders/texture-loader.ts","../src/lib/core/loaders/gltf-loader.ts","../src/lib/core/loaders/fbx-loader.ts","../src/lib/core/loaders/obj-loader.ts","../src/lib/core/loaders/audio-loader.ts","../src/lib/core/loaders/file-loader.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/graphics/material.ts","../src/lib/core/utility/strings.ts","../src/lib/graphics/zylem-scene.ts","../src/lib/debug/debug-state.ts","../src/lib/graphics/instance-manager.ts","../src/lib/stage/stage-state.ts","../src/lib/core/utility/vector.ts","../src/lib/core/lifecycle-base.ts","../src/lib/stage/stage-debug-delegate.ts","../src/lib/stage/debug-entity-cursor.ts","../src/lib/stage/stage-camera-debug-delegate.ts","../src/lib/stage/stage-camera-delegate.ts","../src/lib/camera/zylem-camera.ts","../src/lib/camera/perspective.ts","../src/lib/camera/third-person.ts","../src/lib/camera/fixed-2d.ts","../src/lib/camera/camera-debug-delegate.ts","../src/lib/camera/renderer-manager.ts","../src/lib/graphics/render-pass.ts","../src/lib/camera/camera-manager.ts","../src/lib/stage/stage-loading-delegate.ts","../src/lib/stage/stage-entity-model-delegate.ts","../src/lib/stage/stage-config.ts","../src/lib/core/utility/options-parser.ts","../src/lib/actions/capabilities/apply-transform.ts","../src/lib/core/vessel.ts","../src/lib/camera/camera.ts","../src/lib/stage/stage-default.ts","../src/lib/input/input-presets.ts","../src/lib/stage/stage.ts","../src/lib/stage/entity-spawner.ts","../src/lib/stage/stage-events.ts"],"sourcesContent":["import { addEntity, createWorld as createECS, removeEntity } from 'bitecs';\nimport { Color, Vector3, Vector2 } from 'three';\n\nimport { ZylemWorld } from '../collision/world';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { InstanceManager } from '../graphics/instance-manager';\nimport { resetStageVariables, setStageBackgroundColor, setStageBackgroundImage, setStageVariables, clearVariables, initialStageState } from './stage-state';\n\nimport { GameEntityInterface } from '../types/entity-types';\nimport { debugState } from '../debug/debug-state';\nimport { subscribe } from 'valtio/vanilla';\nimport { getGlobals } from \"../game/game-state\";\n\nimport { SetupContext, UpdateContext, DestroyContext } from '../core/base-node-life-cycle';\nimport { LifeCycleBase } from '../core/lifecycle-base';\nimport createTransformSystem, { StageSystem } from '../systems/transformable.system';\nimport { BaseNode } from '../core/base-node';\nimport { nanoid } from 'nanoid';\nimport { Stage } from './stage';\nimport { CameraWrapper } from '../camera/camera';\nimport { CameraManager } from '../camera/camera-manager';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { StageDebugDelegate } from './stage-debug-delegate';\nimport { StageCameraDebugDelegate } from './stage-camera-debug-delegate';\nimport { StageCameraDelegate } from './stage-camera-delegate';\nimport { StageLoadingDelegate } from './stage-loading-delegate';\nimport { StageEntityModelDelegate } from './stage-entity-model-delegate';\nimport { GameEntity } from '../entities/entity';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { LoadingEvent } from '../core/interfaces';\nimport { parseStageOptions } from './stage-config';\nimport { isBaseNode, isThenable } from '../core/utility/options-parser';\nimport type { BehaviorSystem, BehaviorSystemFactory } from '../behaviors/behavior-system';\nimport { applyTransformChanges } from '../actions/capabilities/apply-transform';\nimport { Vessel } from '../core/vessel';\nexport type { LoadingEvent };\n\nexport interface ZylemStageConfig {\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader: any | null;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\n\tstageRef?: Stage;\n}\n\ntype NodeLike = { create: Function };\nexport type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);\n\nexport type StageOptionItem = Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput;\nexport type StageOptions = [] | [Partial<ZylemStageConfig>, ...StageOptionItem[]];\n\nexport type StageState = ZylemStageConfig & { entities: GameEntityInterface[] };\n\nconst STAGE_TYPE = 'Stage';\n\n/**\n * ZylemStage orchestrates scene, physics world, entities, and lifecycle.\n *\n * Responsibilities:\n * - Manage stage configuration (background, inputs, gravity, variables)\n * - Initialize and own `ZylemScene` and `ZylemWorld`\n * - Spawn, track, and remove entities; emit entity-added events\n * - Drive per-frame updates and transform system\n */\nexport class ZylemStage extends LifeCycleBase<ZylemStage> {\n\tpublic type = STAGE_TYPE;\n\n\tstate: StageState = { ...initialStageState };\n\tgravity: Vector3;\n\n\tworld: ZylemWorld | null;\n\tscene: ZylemScene | null;\n\tinstanceManager: InstanceManager | null = null;\n\n\tchildren: Array<BaseNode> = [];\n\t_childrenMap: Map<number, BaseNode> = new Map();\n\t_removalMap: Map<number, BaseNode> = new Map();\n\n\tprivate pendingEntities: StageEntityInput[] = [];\n\tprivate pendingPromises: Promise<BaseNode>[] = [];\n\tprivate isLoaded: boolean = false;\n\n\t_debugMap: Map<string, BaseNode> = new Map();\n\n\tprivate entityAddedHandlers: Array<(entity: BaseNode) => void> = [];\n\n\tecs = createECS();\n\ttestSystem: any = null;\n\ttransformSystem: ReturnType<typeof createTransformSystem> | null = null;\n\tprivate behaviorSystems: BehaviorSystem[] = [];\n\tprivate registeredSystemKeys: Set<symbol> = new Set();\n\tdebugDelegate: StageDebugDelegate | null = null;\n\tcameraDebugDelegate: StageCameraDebugDelegate | null = null;\n\tprivate debugStateUnsubscribe: (() => void) | null = null;\n\n\tuuid: string;\n\twrapperRef: Stage | null = null;\n\tcamera?: CameraWrapper;\n\tcameras: CameraWrapper[] = [];\n\tcameraRef?: ZylemCamera | null = null;\n\t/** Camera manager for multi-camera support */\n\tcameraManagerRef: CameraManager | null = null;\n\t/** Shared renderer manager (injected by the game) */\n\trendererManager: RendererManager | null = null;\n\n\t// Delegates\n\tprivate cameraDelegate: StageCameraDelegate;\n\tprivate loadingDelegate: StageLoadingDelegate;\n\tprivate entityModelDelegate: StageEntityModelDelegate;\n\n\t/**\n\t * Create a new stage.\n\t * @param options Stage options: partial config, camera, and initial entities or factories\n\t */\n\tconstructor(options: StageOptions = []) {\n\t\tsuper();\n\t\tthis.world = null;\n\t\tthis.scene = null;\n\t\tthis.uuid = nanoid();\n\n\t\t// Initialize delegates\n\t\tthis.cameraDelegate = new StageCameraDelegate(this);\n\t\tthis.loadingDelegate = new StageLoadingDelegate();\n\t\tthis.entityModelDelegate = new StageEntityModelDelegate();\n\n\t\t// Parse the options array using the stage-config module\n\t\tconst parsed = parseStageOptions(options);\n\t\tthis.camera = parsed.camera;\n\t\tthis.cameras = parsed.cameras;\n\t\tthis.children = parsed.entities;\n\t\tthis.pendingEntities = parsed.asyncEntities;\n\t\t\n\t\t// Update state with resolved config\n\t\tthis.saveState({\n\t\t\t...this.state,\n\t\t\tinputs: parsed.config.inputs,\n\t\t\tbackgroundColor: parsed.config.backgroundColor,\n\t\t\tbackgroundImage: parsed.config.backgroundImage,\n\t\t\tbackgroundShader: parsed.config.backgroundShader,\n\t\t\tgravity: parsed.config.gravity,\n\t\t\tvariables: parsed.config.variables,\n\t\t\tentities: [],\n\t\t});\n\n\t\tthis.gravity = parsed.config.gravity ?? new Vector3(0, 0, 0);\n\t}\n\n\tprivate handleEntityImmediatelyOrQueue(entity: BaseNode): void {\n\t\tif (this.isLoaded) {\n\t\t\tthis.spawnEntity(entity);\n\t\t} else {\n\t\t\tthis.children.push(entity);\n\t\t}\n\t}\n\n\tprivate handlePromiseWithSpawnOnResolve(promise: Promise<any>): void {\n\t\tif (this.isLoaded) {\n\t\t\tpromise\n\t\t\t\t.then((entity) => this.spawnEntity(entity))\n\t\t\t\t.catch((e) => console.error('Failed to build async entity', e));\n\t\t} else {\n\t\t\tthis.pendingPromises.push(promise as Promise<BaseNode>);\n\t\t}\n\t}\n\n\tprivate saveState(state: StageState) {\n\t\tthis.state = state;\n\t}\n\n\tprivate setState() {\n\t\tconst { backgroundColor, backgroundImage } = this.state;\n\t\tconst color = backgroundColor instanceof Color ? backgroundColor : new Color(backgroundColor);\n\t\tsetStageBackgroundColor(color);\n\t\tsetStageBackgroundImage(backgroundImage);\n\t\t// Initialize reactive stage variables on load\n\t\tsetStageVariables(this.state.variables ?? {});\n\t}\n\n\t/**\n\t * Load and initialize the stage's scene and world.\n\t * Uses generator pattern to yield control to event loop for real-time progress.\n\t * @param id DOM element id for the renderer container\n\t * @param camera Optional camera override\n\t */\n\tasync load(id: string, camera?: ZylemCamera | null, rendererManager?: RendererManager | null) {\n\t\tthis.setState();\n\n\t\tif (rendererManager) {\n\t\t\tthis.rendererManager = rendererManager;\n\t\t}\n\n\t\t// Build camera manager first so we can use its primary camera as the\n\t\t// canonical camera reference. This avoids creating two separate default\n\t\t// camera instances (one for the scene and a different one in the manager).\n\t\tif (this.rendererManager) {\n\t\t\tthis.cameraManagerRef = this.cameraDelegate.buildCameraManager(\n\t\t\t\tcamera,\n\t\t\t\t...this.cameras\n\t\t\t);\n\t\t}\n\n\t\t// Derive the resolved camera from the camera manager's primary camera\n\t\t// (when available), otherwise fall back to the legacy single-camera path.\n\t\tconst zylemCamera = this.cameraManagerRef?.primaryCamera\n\t\t\t?? this.cameraDelegate.resolveCamera(camera, this.camera);\n\t\tthis.cameraRef = zylemCamera;\n\t\tthis.scene = new ZylemScene(id, zylemCamera, this.state);\n\n\t\tconst physicsWorld = await ZylemWorld.loadPhysics(this.gravity ?? new Vector3(0, 0, 0));\n\t\tthis.world = new ZylemWorld(physicsWorld);\n\n\t\t// Setup scene (lighting, etc.)\n\t\tthis.scene.setup();\n\n\t\t// Setup cameras: prefer camera manager, fall back to legacy single camera\n\t\tif (this.cameraManagerRef && this.rendererManager) {\n\t\t\tawait this.scene.setupCameraManager(this.scene.scene, this.cameraManagerRef, this.rendererManager);\n\t\t\t// Setup render pass for the primary camera (WebGL post-processing)\n\t\t\tconst primaryCam = this.cameraManagerRef.primaryCamera;\n\t\t\tif (primaryCam) {\n\t\t\t\tthis.rendererManager.setupRenderPass(this.scene.scene, primaryCam.camera);\n\t\t\t}\n\t\t\t// Start the render loop via the renderer manager\n\t\t\tthis.rendererManager.startRenderLoop((delta) => {\n\t\t\t\tthis.cameraManagerRef?.update(delta);\n\t\t\t\tthis.cameraManagerRef?.render(this.scene!.scene);\n\t\t\t});\n\t\t} else {\n\t\t\t// Legacy path: single camera manages its own renderer\n\t\t\tthis.scene.setupCamera(this.scene.scene, zylemCamera);\n\t\t}\n\n\t\tthis.entityModelDelegate.attach(this.scene);\n\n\t\t// Initialize instance manager for mesh batching\n\t\tthis.instanceManager = new InstanceManager();\n\t\tthis.instanceManager.setScene(this.scene.scene);\n\n\t\tthis.loadingDelegate.emitStart();\n\n\t\t// Run entity loading with generator pattern for real-time progress\n\t\tawait this.runEntityLoadGenerator();\n\n\t\tthis.transformSystem = createTransformSystem(this as unknown as StageSystem);\n\t\tthis.isLoaded = true;\n\t\tthis.loadingDelegate.emitComplete();\n\t}\n\n\t/**\n\t * Generator that yields between entity loads for real-time progress updates.\n\t */\n\tprivate *entityLoadGenerator(): Generator<{ current: number; total: number; name: string }> {\n\t\tconst total = this.children.length + this.pendingEntities.length + this.pendingPromises.length;\n\t\tlet current = 0;\n\n\t\tfor (const child of this.children) {\n\t\t\tthis.spawnEntity(child);\n\t\t\tcurrent++;\n\t\t\tyield { current, total, name: child.name || 'unknown' };\n\t\t}\n\n\t\tif (this.pendingEntities.length) {\n\t\t\tthis.enqueue(...this.pendingEntities);\n\t\t\tcurrent += this.pendingEntities.length;\n\t\t\tthis.pendingEntities = [];\n\t\t\tyield { current, total, name: 'pending entities' };\n\t\t}\n\n\t\tif (this.pendingPromises.length) {\n\t\t\tfor (const promise of this.pendingPromises) {\n\t\t\t\tpromise.then((entity) => {\n\t\t\t\t\tthis.spawnEntity(entity);\n\t\t\t\t}).catch((e) => console.error('Failed to resolve pending stage entity', e));\n\t\t\t}\n\t\t\tcurrent += this.pendingPromises.length;\n\t\t\tthis.pendingPromises = [];\n\t\t\tyield { current, total, name: 'async entities' };\n\t\t}\n\t}\n\n\t/**\n\t * Runs the entity load generator, yielding to the event loop between loads.\n\t * This allows the browser to process events and update the UI in real-time.\n\t */\n\tprivate runEntityLoadGenerator(): void {\n\t\tconst gen = this.entityLoadGenerator();\n\t\tfor (const progress of gen) {\n\t\t\tthis.loadingDelegate.emitProgress(`Loaded ${progress.name}`, progress.current, progress.total);\n\t\t\t// Yield to event loop so browser can process events and update UI\n\t\t\t// Use setTimeout(0) for more reliable async behavior than RAF\n\t\t\tnew Promise<void>(resolve => setTimeout(resolve, 0));\n\t\t}\n\t}\n\n\n\tprotected _setup(params: SetupContext<ZylemStage>): void {\n\t\tif (!this.scene || !this.world) {\n\t\t\tthis.logMissingEntities();\n\t\t\treturn;\n\t\t}\n\t\t// Setup debug delegate based on current state\n\t\tthis.updateDebugDelegate();\n\n\t\t// Subscribe to debugState changes for runtime toggle\n\t\tthis.debugStateUnsubscribe = subscribe(debugState, () => {\n\t\t\tthis.updateDebugDelegate();\n\t\t});\n\t}\n\n\tprivate updateDebugDelegate(): void {\n\t\tif (debugState.enabled && !this.debugDelegate && this.scene && this.world) {\n\t\t\t// Create debug delegate when debug is enabled\n\t\t\tthis.debugDelegate = new StageDebugDelegate(this);\n\t\t\t\n\t\t\t// Create and attach camera debug delegate for orbit controls\n\t\t\tif (this.cameraRef && !this.cameraDebugDelegate) {\n\t\t\t\tthis.cameraDebugDelegate = new StageCameraDebugDelegate(this);\n\t\t\t\tthis.cameraRef.setDebugDelegate(this.cameraDebugDelegate);\n\t\t\t}\n\t\t} else if (!debugState.enabled && this.debugDelegate) {\n\t\t\t// Dispose debug delegate when debug is disabled\n\t\t\tthis.debugDelegate.dispose();\n\t\t\tthis.debugDelegate = null;\n\t\t\t\n\t\t\t// Detach camera debug delegate\n\t\t\tif (this.cameraRef) {\n\t\t\t\tthis.cameraRef.setDebugDelegate(null);\n\t\t\t}\n\t\t\tthis.cameraDebugDelegate = null;\n\t\t}\n\t}\n\n\tprotected _update(params: UpdateContext<ZylemStage>): void {\n\t\tconst { delta } = params;\n\t\tif (!this.scene || !this.world) {\n\t\t\tthis.logMissingEntities();\n\t\t\treturn;\n\t\t}\n\t\tthis.world.update(params);\n\t\t// Run registered ECS behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.update(this.ecs, delta);\n\t\t}\n\t\tthis._childrenMap.forEach((child, eid) => {\n\t\t\tchild.nodeUpdate({\n\t\t\t\t...params,\n\t\t\t\tme: child,\n\t\t\t});\n\t\t\t\n\t\t\t// Apply pending transformations after update callbacks\n\t\t\tif ((child as any).transformStore) {\n\t\t\t\tapplyTransformChanges(child as any, (child as any).transformStore);\n\t\t\t}\n\t\t\t\n\t\t\tif (child.markedForRemoval) {\n\t\t\t\tthis.removeEntityByUuid(child.uuid);\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Sync physics to rendering AFTER transforms are applied\n\t\tthis.transformSystem?.system(this.ecs);\n\t\t\n\t\t// Sync instanced mesh transforms\n\t\tthis.instanceManager?.update();\n\t\tthis.scene.update({ delta });\n\t\tthis.scene.updateSkybox(delta);\n\t}\n\n\tpublic outOfLoop() {\n\t\tthis.debugUpdate();\n\t}\n\n\t/** Update debug overlays and helpers if enabled. */\n\tpublic debugUpdate() {\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugDelegate?.update();\n\t\t}\n\t}\n\n\t/** Cleanup owned resources when the stage is destroyed. */\n\tprotected _destroy(params: DestroyContext<ZylemStage>): void {\n\t\t// Cleanup behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.destroy?.(this.ecs);\n\t\t}\n\t\tthis.behaviorSystems = [];\n\t\tthis.registeredSystemKeys.clear();\n\t\tthis._childrenMap.forEach((child) => {\n\t\t\ttry { child.nodeDestroy({ me: child, globals: getGlobals() }); } catch { /* noop */ }\n\t\t\t// Clear entity-scoped variable proxy store entries\n\t\t\tclearVariables(child);\n\t\t});\n\t\tthis._childrenMap.clear();\n\t\tthis._removalMap.clear();\n\t\tthis._debugMap.clear();\n\n\t\tthis.world?.destroy();\n\t\tthis.scene?.destroy();\n\n\t\t// Cleanup debug state subscription\n\t\tif (this.debugStateUnsubscribe) {\n\t\t\tthis.debugStateUnsubscribe();\n\t\t\tthis.debugStateUnsubscribe = null;\n\t\t}\n\n\t\tthis.debugDelegate?.dispose();\n\t\tthis.debugDelegate = null;\n\t\tthis.cameraRef?.setDebugDelegate(null);\n\t\tthis.cameraDebugDelegate = null;\n\n\t\tthis.entityModelDelegate.dispose();\n\n\t\t// Dispose instance manager\n\t\tthis.instanceManager?.dispose();\n\t\tthis.instanceManager = null;\n\n\t\t// Stop renderer render loop if using renderer manager\n\t\tif (this.rendererManager) {\n\t\t\tthis.rendererManager.stopRenderLoop();\n\t\t}\n\n\t\tthis.isLoaded = false;\n\t\tthis.world = null as any;\n\t\tthis.scene = null as any;\n\t\tthis.cameraRef = null;\n\t\tthis.cameraManagerRef = null;\n\t\t// Cleanup transform system\n\t\tthis.transformSystem?.destroy(this.ecs);\n\t\tthis.transformSystem = null;\n\n\t\t// Clear reactive stage variables on unload\n\t\tresetStageVariables();\n\t\t// Clear object-scoped variables for this stage\n\t\tclearVariables(this);\n\t}\n\n\t/**\n\t * Create, register, and add an entity to the scene/world.\n\t * Safe to call only after `load` when scene/world exist.\n\t */\n\tasync spawnEntity(child: BaseNode) {\n\t\tif (!this.scene || !this.world) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the child is a Vessel, spawn each of its children individually\n\t\t// then register the Vessel itself so it participates in the update loop.\n\t\tif (child instanceof Vessel) {\n\t\t\tchild.create();\n\t\t\tfor (const childEntity of child.getChildren()) {\n\t\t\t\tif (childEntity instanceof BaseNode) {\n\t\t\t\t\tawait this.spawnEntity(childEntity);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Assign an ECS eid so the Vessel can be tracked in _childrenMap\n\t\t\tconst vesselEid = addEntity(this.ecs);\n\t\t\tchild.eid = vesselEid;\n\n\t\t\t// Run vessel lifecycle after children are spawned\n\t\t\tchild.nodeSetup({\n\t\t\t\tme: child,\n\t\t\t\tglobals: getGlobals(),\n\t\t\t\tcamera: this.scene.zylemCamera,\n\t\t\t});\n\n\t\t\tthis.addEntityToStage(child);\n\t\t\treturn;\n\t\t}\n\n\t\tconst entity = child.create();\n\t\tconst eid = addEntity(this.ecs);\n\t\tentity.eid = eid;\n\t\tthis.scene.addEntity(entity);\n\n\t\t// Auto-register behavior systems from entity refs\n\t\tif (typeof entity.getBehaviorRefs === 'function') {\n\t\t\tfor (const ref of entity.getBehaviorRefs()) {\n\t\t\t\tconst key = ref.descriptor.key;\n\t\t\t\tif (!this.registeredSystemKeys.has(key)) {\n\t\t\t\t\tconst system = ref.descriptor.systemFactory({ world: this.world, ecs: this.ecs, scene: this.scene });\n\t\t\t\t\tthis.behaviorSystems.push(system);\n\t\t\t\t\tthis.registeredSystemKeys.add(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (entity.colliderDesc) {\n\t\t\tthis.world.addEntity(entity);\n\t\t}\n\n\t\t// Recursively spawn any BaseNode children (for nested entities)\n\t\tfor (const childNode of child.getChildren()) {\n\t\t\tif (childNode instanceof BaseNode) {\n\t\t\t\tawait this.spawnEntity(childNode);\n\t\t\t}\n\t\t}\n\n\t\tchild.nodeSetup({\n\t\t\tme: child,\n\t\t\tglobals: getGlobals(),\n\t\t\tcamera: this.scene.zylemCamera,\n\t\t});\n\n\t\t// Register for instanced rendering if opted in\n\t\tthis.tryRegisterInstance(entity);\n\n\t\tthis.addEntityToStage(entity);\n\t\tthis.entityModelDelegate.observe(entity);\n\t}\n\n\t/**\n\t * Try to register an entity for instanced rendering.\n\t * Batching is enabled by default unless explicitly disabled with batched: false.\n\t */\n\tprivate tryRegisterInstance(entity: GameEntity<any>): void {\n\t\tif (!this.instanceManager) return;\n\n\t\t// Batching is disabled by default, must be explicitly enabled\n\t\tconst options = entity.options as any;\n\t\tif (options?.batched !== true) return;\n\n\t\t// Need mesh with geometry and material\n\t\tif (!entity.mesh?.geometry || !entity.materials?.length) return;\n\n\t\tconst geometry = entity.mesh.geometry;\n\t\tconst material = entity.materials[0];\n\n\t\t// Generate batch key based on entity type and options\n\t\tconst entityType = (entity.constructor as any).type?.description || 'unknown';\n\t\tconst size = options.size || { x: 1, y: 1, z: 1 };\n\t\tconst matOptions = options.material || {};\n\n\t\tconst batchKey = InstanceManager.generateBatchKey({\n\t\t\tgeometryType: entityType,\n\t\t\tdimensions: { x: size.x, y: size.y, z: size.z },\n\t\t\tmaterialPath: matOptions.path || null,\n\t\t\tshaderType: matOptions.shader ? 'custom' : 'standard',\n\t\t\tcolorHex: matOptions.color?.getHex?.() || 0xffffff,\n\t\t});\n\n\t\t// Register with instance manager\n\t\tconst instanceId = this.instanceManager.register(entity, geometry, material, batchKey);\n\n\t\tif (instanceId >= 0) {\n\t\t\tentity.batchKey = batchKey;\n\t\t\tentity.instanceId = instanceId;\n\t\t\tentity.isInstanced = true;\n\n\t\t\t// Hide the individual mesh since it's now part of an instanced batch\n\t\t\tif (entity.mesh) {\n\t\t\t\tentity.mesh.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tbuildEntityState(child: BaseNode): Partial<BaseEntityInterface> {\n\t\tif (child instanceof GameEntity) {\n\t\t\treturn { ...child.buildInfo() } as Partial<BaseEntityInterface>;\n\t\t}\n\t\treturn {\n\t\t\tuuid: child.uuid,\n\t\t\tname: child.name,\n\t\t\teid: child.eid,\n\t\t} as Partial<BaseEntityInterface>;\n\t}\n\n\t/** Add the entity to internal maps and notify listeners. */\n\taddEntityToStage(entity: BaseNode) {\n\t\tthis._childrenMap.set(entity.eid, entity);\n\t\tif (debugState.enabled) {\n\t\t\tthis._debugMap.set(entity.uuid, entity);\n\t\t}\n\t\tfor (const handler of this.entityAddedHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(entity);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('onEntityAdded handler failed', e);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Subscribe to entity-added events.\n\t * @param callback Invoked for each entity when added\n\t * @param options.replayExisting If true and stage already loaded, replays existing entities\n\t * @returns Unsubscribe function\n\t */\n\tonEntityAdded(callback: (entity: BaseNode) => void, options?: { replayExisting?: boolean }) {\n\t\tthis.entityAddedHandlers.push(callback);\n\t\tif (options?.replayExisting && this.isLoaded) {\n\t\t\tthis._childrenMap.forEach((entity) => {\n\t\t\t\ttry { callback(entity); } catch (e) { console.error('onEntityAdded replay failed', e); }\n\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tthis.entityAddedHandlers = this.entityAddedHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\treturn this.loadingDelegate.onLoading(callback);\n\t}\n\n\t/**\n\t * Register an ECS behavior system to run each frame.\n\t * @param systemOrFactory A BehaviorSystem instance or factory function\n\t * @returns this for chaining\n\t */\n\tregisterSystem(systemOrFactory: BehaviorSystem | BehaviorSystemFactory): this {\n\t\tlet system: BehaviorSystem;\n\t\tif (typeof systemOrFactory === 'function') {\n\t\tsystem = systemOrFactory({ world: this.world, ecs: this.ecs, scene: this.scene });\n\t\t} else {\n\t\t\tsystem = systemOrFactory;\n\t\t}\n\t\tthis.behaviorSystems.push(system);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Remove an entity and its resources by its UUID.\n\t * @returns true if removed, false if not found or stage not ready\n\t */\n\tremoveEntityByUuid(uuid: string): boolean {\n\t\tif (!this.scene || !this.world) return false;\n\t\t// Try mapping via world collision map first for physics-backed entities\n\t\t// @ts-ignore - collisionMap is public Map<string, GameEntity<any>>\n\t\tconst mapEntity = this.world.collisionMap.get(uuid) as any | undefined;\n\t\tconst entity: any = mapEntity ?? this._debugMap.get(uuid);\n\t\tif (!entity) return false;\n\n\t\tthis.entityModelDelegate.unobserve(uuid);\n\n\t\t// Unregister from instance manager if instanced\n\t\tif (entity.isInstanced && this.instanceManager) {\n\t\t\tthis.instanceManager.unregister(entity);\n\t\t}\n\n\t\tthis.world.destroyEntity(entity);\n\n\t\tif (entity.group) {\n\t\t\tthis.scene.scene.remove(entity.group);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.scene.scene.remove(entity.mesh);\n\t\t}\n\n\t\tremoveEntity(this.ecs, entity.eid);\n\n\t\tlet foundKey: number | null = null;\n\t\tthis._childrenMap.forEach((value, key) => {\n\t\t\tif ((value as any).uuid === uuid) {\n\t\t\t\tfoundKey = key;\n\t\t\t}\n\t\t});\n\t\tif (foundKey !== null) {\n\t\t\tthis._childrenMap.delete(foundKey);\n\t\t}\n\t\tthis._debugMap.delete(uuid);\n\t\treturn true;\n\t}\n\n\t/** Get an entity by its name; returns null if not found. */\n\tgetEntityByName(name: string) {\n\t\tconst arr = Object.entries(Object.fromEntries(this._childrenMap)).map((entry) => entry[1]);\n\t\tconst entity = arr.find((child) => child.name === name);\n\t\tif (!entity) {\n\t\t\tconsole.warn(`Entity ${name} not found`);\n\t\t}\n\t\treturn entity ?? null;\n\t}\n\n\tlogMissingEntities() {\n\t\tconsole.warn('Zylem world or scene is null');\n\t}\n\n\t// ─── Camera management forwarding ─────────────────────────────────────\n\n\t/**\n\t * Add a camera to this stage's camera manager.\n\t */\n\taddCamera(camera: ZylemCamera, name?: string): string | null {\n\t\tif (!this.cameraManagerRef) {\n\t\t\tconsole.warn('ZylemStage: CameraManager not available. Ensure stage is loaded with a RendererManager.');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.cameraManagerRef.addCamera(camera, name);\n\t}\n\n\t/**\n\t * Remove a camera from this stage's camera manager.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\treturn this.cameraManagerRef?.removeCamera(nameOrRef) ?? false;\n\t}\n\n\t/**\n\t * Set the active camera by name or reference.\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\treturn this.cameraManagerRef?.setActiveCamera(nameOrRef) ?? false;\n\t}\n\n\t/**\n\t * Get a camera by name from the camera manager.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.cameraManagerRef?.getCamera(name) ?? null;\n\t}\n\n\t/** Resize renderer viewport. */\n\tresize(width: number, height: number) {\n\t\tif (this.scene) {\n\t\t\tthis.scene.updateRenderer(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Enqueue items to be spawned. Items can be:\n\t * - BaseNode instances (immediate or deferred until load)\n\t * - Factory functions returning BaseNode or Promise<BaseNode>\n\t * - Promises resolving to BaseNode\n\t */\n\tenqueue(...items: StageEntityInput[]) {\n\t\tfor (const item of items) {\n\t\t\tif (!item) continue;\n\t\t\tif (isBaseNode(item)) {\n\t\t\t\tthis.handleEntityImmediatelyOrQueue(item);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof item === 'function') {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = (item as (() => BaseNode | Promise<any>))();\n\t\t\t\t\tif (isBaseNode(result)) {\n\t\t\t\t\t\tthis.handleEntityImmediatelyOrQueue(result);\n\t\t\t\t\t} else if (isThenable(result)) {\n\t\t\t\t\t\tthis.handlePromiseWithSpawnOnResolve(result as Promise<any>);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Error executing entity factory', error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isThenable(item)) {\n\t\t\t\tthis.handlePromiseWithSpawnOnResolve(item as Promise<any>);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { Vector3 } from 'three';\nimport RAPIER, { World } from '@dimforge/rapier3d-compat';\n\nimport { Entity } from '../interfaces/entity';\nimport { state } from '../game/game-state';\nimport { UpdateContext } from '../core/base-node-life-cycle';\nimport { ZylemActor } from '../entities/actor';\nimport { GameEntity } from '../entities/entity';\n\n/**\n * Interface for entities that handle collision events.\n */\nexport interface CollisionHandlerDelegate {\n\thandlePostCollision(params: any): boolean;\n\thandleIntersectionEvent(params: any): void;\n}\n\n/**\n * Type guard to check if an object implements CollisionHandlerDelegate.\n */\nexport function isCollisionHandlerDelegate(obj: any): obj is CollisionHandlerDelegate {\n\treturn typeof obj?.handlePostCollision === \"function\" && typeof obj?.handleIntersectionEvent === \"function\";\n}\n\nexport class ZylemWorld implements Entity<ZylemWorld> {\n\ttype = 'World';\n\tworld: World;\n\tcollisionMap: Map<string, GameEntity<any>> = new Map();\n\tcollisionBehaviorMap: Map<string, GameEntity<any>> = new Map();\n\t_removalMap: Map<string, GameEntity<any>> = new Map();\n\n\tstatic async loadPhysics(gravity: Vector3) {\n\t\tawait RAPIER.init();\n\t\tconst physicsWorld = new RAPIER.World(gravity);\n\t\treturn physicsWorld;\n\t}\n\n\tconstructor(world: World) {\n\t\tthis.world = world;\n\t}\n\n\taddEntity(entity: any) {\n\t\tconst rigidBody = this.world.createRigidBody(entity.bodyDesc);\n\t\tentity.body = rigidBody;\n\t\t// TODO: consider passing in more specific data\n\t\tentity.body.userData = { uuid: entity.uuid, ref: entity };\n\t\tif (this.world.gravity.x === 0 && this.world.gravity.y === 0 && this.world.gravity.z === 0) {\n\t\t\tentity.body.lockTranslations(true, true);\n\t\t\tentity.body.lockRotations(true, true);\n\t\t}\n\n\t\t// Create primary collider\n\t\tconst collider = this.world.createCollider(entity.colliderDesc, entity.body);\n\t\tentity.collider = collider;\n\t\tentity.colliders = [collider];\n\n\t\t// Create additional compound colliders (if any)\n\t\tif (entity.colliderDescs?.length > 1) {\n\t\t\tfor (let i = 1; i < entity.colliderDescs.length; i++) {\n\t\t\t\tconst additionalCollider = this.world.createCollider(entity.colliderDescs[i], entity.body);\n\t\t\t\tentity.colliders.push(additionalCollider);\n\t\t\t}\n\t\t}\n\n\t\tif (entity.controlledRotation || entity instanceof ZylemActor) {\n\t\t\tentity.body.lockRotations(true, true);\n\t\t\tentity.characterController = this.world.createCharacterController(0.01);\n\t\t\tentity.characterController.setMaxSlopeClimbAngle(45 * Math.PI / 180);\n\t\t\tentity.characterController.setMinSlopeSlideAngle(30 * Math.PI / 180);\n\t\t\tentity.characterController.enableSnapToGround(0.01);\n\t\t\tentity.characterController.setSlideEnabled(true);\n\t\t\tentity.characterController.setApplyImpulsesToDynamicBodies(true);\n\t\t\tentity.characterController.setCharacterMass(1);\n\t\t}\n\t\tthis.collisionMap.set(entity.uuid, entity);\n\t}\n\n\tsetForRemoval(entity: any) {\n\t\tif (entity.body) {\n\t\t\tthis._removalMap.set(entity.uuid, entity);\n\t\t}\n\t}\n\n\tdestroyEntity(entity: GameEntity<any>) {\n\t\t// Free character controller WASM resource if present\n\t\tif ((entity as any).characterController) {\n\t\t\ttry { (entity as any).characterController.free(); } catch { /* noop */ }\n\t\t\t(entity as any).characterController = null;\n\t\t}\n\t\t// Remove all colliders (compound support)\n\t\tif (entity.colliders?.length) {\n\t\t\tfor (const collider of entity.colliders) {\n\t\t\t\tthis.world.removeCollider(collider, true);\n\t\t\t}\n\t\t} else if (entity.collider) {\n\t\t\tthis.world.removeCollider(entity.collider, true);\n\t\t}\n\t\tif (entity.body) {\n\t\t\tthis.world.removeRigidBody(entity.body);\n\t\t\tthis.collisionMap.delete(entity.uuid);\n\t\t\tthis._removalMap.delete(entity.uuid);\n\t\t}\n\t}\n\n\tsetup() { }\n\n\tupdate(params: UpdateContext<any>) {\n\t\tconst { delta } = params;\n\t\tif (!this.world) {\n\t\t\treturn;\n\t\t}\n\t\tthis.updateColliders(delta);\n\t\tthis.updatePostCollisionBehaviors(delta);\n\t\tthis.world.step();\n\t}\n\n\tupdatePostCollisionBehaviors(delta: number) {\n\t\tconst dictionaryRef = this.collisionBehaviorMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as any;\n\t\t\tif (!isCollisionHandlerDelegate(gameEntity)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst active = gameEntity.handlePostCollision({ entity: gameEntity, delta });\n\t\t\tif (!active) {\n\t\t\t\tthis.collisionBehaviorMap.delete(id);\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateColliders(delta: number) {\n\t\tconst dictionaryRef = this.collisionMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as GameEntity<any>;\n\t\t\tif (!gameEntity.body) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this._removalMap.get(gameEntity.uuid)) {\n\t\t\t\tthis.destroyEntity(gameEntity);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\tthis.world.contactsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\tif (!otherCollider) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// @ts-ignore\n\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\tif (!entity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (gameEntity._collision) {\n\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t}\n\t\t});\n\t\t// Body may have been invalidated by a destroy() call inside a collision callback\n\t\tif (!gameEntity.body || gameEntity.markedForRemoval) {\n\t\t\tcontinue;\n\t\t}\n\t\tthis.world.intersectionsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\t\tif (!otherCollider) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\t\tif (!entity) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (gameEntity._collision) {\n\t\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t\t}\n\t\t\t\tif (isCollisionHandlerDelegate(entity)) {\n\t\t\t\t\tentity.handleIntersectionEvent({ entity, other: gameEntity, delta });\n\t\t\t\t\tthis.collisionBehaviorMap.set(uuid, entity);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\ttry {\n\t\t\tfor (const [, entity] of this.collisionMap) {\n\t\t\t\ttry { this.destroyEntity(entity); } catch { /* noop */ }\n\t\t\t}\n\t\t\tthis.collisionMap.clear();\n\t\t\tthis.collisionBehaviorMap.clear();\n\t\t\tthis._removalMap.clear();\n\t\t\t// Free WASM-backed Rapier world before dropping the reference\n\t\t\ttry { this.world?.free(); } catch { /* noop */ }\n\t\t\t// @ts-ignore\n\t\t\tthis.world = undefined as any;\n\t\t} catch { /* noop */ }\n\t}\n\n}","import { proxy, subscribe } from 'valtio/vanilla';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\nimport { gameEventBus } from './game-event-bus';\n\n/**\n * Internal game state store using valtio proxy for reactivity.\n */\nconst state = proxy({\n\tid: '',\n\tglobals: {} as Record<string, unknown>,\n\ttime: 0,\n});\n\n/**\n * Track active subscriptions for cleanup on game dispose.\n */\nconst activeSubscriptions: Set<() => void> = new Set();\n\n/**\n * Set a global value by path.\n * Emits a 'game:state:updated' event when the value changes.\n * @example setGlobal('score', 100)\n * @example setGlobal('player.health', 50)\n */\nexport function setGlobal(path: string, value: unknown): void {\n\tconst previousValue = getByPath(state.globals, path);\n\tsetByPath(state.globals, path, value);\n\n\tgameEventBus.emit('game:state:updated', {\n\t\tpath,\n\t\tvalue,\n\t\tpreviousValue,\n\t});\n}\n\n/**\n * Create/initialize a global with a default value.\n * Only sets the value if it doesn't already exist.\n * Use this to ensure globals have initial values before game starts.\n * @example createGlobal('score', 0)\n * @example createGlobal('player.health', 100)\n */\nexport function createGlobal<T>(path: string, defaultValue: T): T {\n\tconst existing = getByPath<T>(state.globals, path);\n\tif (existing === undefined) {\n\t\tsetByPath(state.globals, path, defaultValue);\n\t\treturn defaultValue;\n\t}\n\treturn existing;\n}\n\n/**\n * Get a global value by path.\n * @example getGlobal('score') // 100\n * @example getGlobal<number>('player.health') // 50\n */\nexport function getGlobal<T = unknown>(path: string): T | undefined {\n\treturn getByPath<T>(state.globals, path);\n}\n\n/**\n * Subscribe to changes on a global value at a specific path.\n * Returns an unsubscribe function. Subscriptions are automatically\n * cleaned up when the game is disposed.\n * @example const unsub = onGlobalChange('score', (val) => console.log(val));\n */\nexport function onGlobalChange<T = unknown>(\n\tpath: string,\n\tcallback: (value: T) => void\n): () => void {\n\tlet previous = getByPath<T>(state.globals, path);\n\tconst unsub = subscribe(state.globals, () => {\n\t\tconst current = getByPath<T>(state.globals, path);\n\t\tif (current !== previous) {\n\t\t\tprevious = current;\n\t\t\tcallback(current as T);\n\t\t}\n\t});\n\tactiveSubscriptions.add(unsub);\n\treturn () => {\n\t\tunsub();\n\t\tactiveSubscriptions.delete(unsub);\n\t};\n}\n\n/**\n * Subscribe to changes on multiple global paths.\n * Callback fires when any of the paths change, receiving all current values.\n * Subscriptions are automatically cleaned up when the game is disposed.\n * @example const unsub = onGlobalChanges(['score', 'lives'], ([score, lives]) => console.log(score, lives));\n */\nexport function onGlobalChanges<T extends unknown[] = unknown[]>(\n\tpaths: string[],\n\tcallback: (values: T) => void\n): () => void {\n\tlet previousValues = paths.map(p => getByPath(state.globals, p));\n\tconst unsub = subscribe(state.globals, () => {\n\t\tconst currentValues = paths.map(p => getByPath(state.globals, p));\n\t\tconst hasChange = currentValues.some((val, i) => val !== previousValues[i]);\n\t\tif (hasChange) {\n\t\t\tpreviousValues = currentValues;\n\t\t\tcallback(currentValues as T);\n\t\t}\n\t});\n\tactiveSubscriptions.add(unsub);\n\treturn () => {\n\t\tunsub();\n\t\tactiveSubscriptions.delete(unsub);\n\t};\n}\n\n/**\n * Get the entire globals object (read-only snapshot).\n */\nexport function getGlobals<T = Record<string, unknown>>(): T {\n\treturn state.globals as T;\n}\n\n/**\n * Initialize globals from an object. Used internally during game setup.\n */\nexport function initGlobals(globals: Record<string, unknown>): void {\n\tfor (const [key, value] of Object.entries(globals)) {\n\t\tsetByPath(state.globals, key, value);\n\t}\n}\n\n/**\n * Reset all globals. Used internally on game dispose.\n */\nexport function resetGlobals(): void {\n\tstate.globals = {};\n}\n\n/**\n * Unsubscribe all active global subscriptions.\n * Used internally on game dispose to prevent old callbacks from firing.\n */\nexport function clearGlobalSubscriptions(): void {\n\tfor (const unsub of activeSubscriptions) {\n\t\tunsub();\n\t}\n\tactiveSubscriptions.clear();\n}\n\nexport { state };","import { LoadingEvent } from '../core/interfaces';\n\n/**\n * Event types for the game event bus.\n */\nexport type GameEventType = \n\t| 'stage:loading:start'\n\t| 'stage:loading:progress'\n\t| 'stage:loading:complete'\n\t| 'game:state:updated';\n\n/**\n * Payload for stage loading events.\n */\nexport interface StageLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n/**\n * Payload for game state update events.\n */\nexport interface GameStateUpdatedPayload {\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n}\n\n/**\n * Event map for typed event handling.\n */\nexport interface GameEventMap {\n\t'stage:loading:start': StageLoadingPayload;\n\t'stage:loading:progress': StageLoadingPayload;\n\t'stage:loading:complete': StageLoadingPayload;\n\t'game:state:updated': GameStateUpdatedPayload;\n}\n\ntype EventCallback<T> = (payload: T) => void;\n\n/**\n * Simple event bus for game-stage communication.\n * Used to decouple stage loading events from direct coupling.\n */\nexport class GameEventBus {\n\tprivate listeners: Map<GameEventType, Set<EventCallback<any>>> = new Map();\n\n\t/**\n\t * Subscribe to an event type.\n\t */\n\ton<K extends GameEventType>(event: K, callback: EventCallback<GameEventMap[K]>): () => void {\n\t\tif (!this.listeners.has(event)) {\n\t\t\tthis.listeners.set(event, new Set());\n\t\t}\n\t\tthis.listeners.get(event)!.add(callback);\n\t\treturn () => this.off(event, callback);\n\t}\n\n\t/**\n\t * Unsubscribe from an event type.\n\t */\n\toff<K extends GameEventType>(event: K, callback: EventCallback<GameEventMap[K]>): void {\n\t\tthis.listeners.get(event)?.delete(callback);\n\t}\n\n\t/**\n\t * Emit an event to all subscribers.\n\t */\n\temit<K extends GameEventType>(event: K, payload: GameEventMap[K]): void {\n\t\tconst callbacks = this.listeners.get(event);\n\t\tif (!callbacks) return;\n\t\tfor (const cb of callbacks) {\n\t\t\ttry {\n\t\t\t\tcb(payload);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(`Error in event handler for ${event}`, e);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clear all listeners.\n\t */\n\tdispose(): void {\n\t\tthis.listeners.clear();\n\t}\n}\n\n/**\n * Singleton event bus instance for global game events.\n */\nexport const gameEventBus = new GameEventBus();\n","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, Mesh, MeshStandardMaterial, Group, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport { UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { EntityAssetLoader } from '../core/entity-asset-loader';\nimport { EntityLoaderDelegate } from './delegates/loader';\nimport { Vec3 } from '../core/vector';\nimport { AnimationDelegate, AnimationOptions } from './delegates/animation';\nimport { MaterialOptions } from '../graphics/material';\nimport { DebugInfoProvider } from './delegates/debug';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { commonDefaults } from './common';\nimport { standardShader } from '../graphics/shaders/standard.shader';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport type CollisionShapeType = 'capsule' | 'model';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tcollision: {\n\t\tstatic: false,\n\t\tsize: new Vector3(0.5, 0.5, 0.5),\n\t\tposition: new Vector3(0, 0, 0),\n\t},\n\tmaterial: {\n\t\tshader: standardShader\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Group | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tif (this.collisionShape === 'model') {\n\t\t\treturn this.createColliderFromModel(this.objectModel, options);\n\t\t}\n\t\treturn this.createCapsuleCollider(options);\n\t}\n\n\t/**\n\t * Create a capsule collider based on size options (character controller style).\n\t */\n\tprivate createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\t\tconst halfHeight = ((size as any).y || 1);\n\t\tconst radius = Math.max((size as any).x || 0.5, (size as any).z || 0.5);\n\t\tlet colliderDesc = ColliderDesc.capsule(halfHeight, radius);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, halfHeight + radius, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n\n\t/**\n\t * Create a collider based on model geometry (works with Mesh and SkinnedMesh).\n\t * If collision.size and collision.position are provided, use those instead of computing from geometry.\n\t */\n\tprivate createColliderFromModel(objectModel: Group | null, options: ZylemActorOptions): ColliderDesc {\n\t\tconst collisionSize = options.collision?.size;\n\t\tconst collisionPosition = options.collision?.position;\n\n\t\t// If user provided explicit size, use that instead of computing from model\n\t\tif (collisionSize) {\n\t\t\tconst halfWidth = (collisionSize as any).x / 2;\n\t\t\tconst halfHeight = (collisionSize as any).y / 2;\n\t\t\tconst halfDepth = (collisionSize as any).z / 2;\n\n\t\t\tlet colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\t\t\tcolliderDesc.setSensor(false);\n\n\t\t\t// Use user-provided position or default to center\n\t\t\tconst posX = collisionPosition ? (collisionPosition as any).x : 0;\n\t\t\tconst posY = collisionPosition ? (collisionPosition as any).y : halfHeight;\n\t\t\tconst posZ = collisionPosition ? (collisionPosition as any).z : 0;\n\t\t\tcolliderDesc.setTranslation(posX, posY, posZ);\n\t\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\t\treturn colliderDesc;\n\t\t}\n\n\t\t// Fall back to computing from model geometry\n\t\tif (!objectModel) return this.createCapsuleCollider(options);\n\n\t\t// Find first Mesh (SkinnedMesh or regular Mesh)\n\t\tlet foundGeometry: BufferGeometry | null = null;\n\t\tobjectModel.traverse((child) => {\n\t\t\tif (!foundGeometry && (child as any).isMesh) {\n\t\t\t\tfoundGeometry = (child as Mesh).geometry as BufferGeometry;\n\t\t\t}\n\t\t});\n\n\t\tif (!foundGeometry) return this.createCapsuleCollider(options);\n\n\t\tconst geometry: BufferGeometry = foundGeometry;\n\t\tgeometry.computeBoundingBox();\n\t\tconst box = geometry.boundingBox;\n\t\tif (!box) return this.createCapsuleCollider(options);\n\n\t\tconst height = box.max.y - box.min.y;\n\t\tconst width = box.max.x - box.min.x;\n\t\tconst depth = box.max.z - box.min.z;\n\n\t\t// Create box collider based on mesh bounds\n\t\tlet colliderDesc = ColliderDesc.cuboid(width / 2, height / 2, depth / 2);\n\t\tcolliderDesc.setSensor(false);\n\t\t// Position collider at center of model\n\t\tconst centerY = (box.max.y + box.min.y) / 2;\n\t\tcolliderDesc.setTranslation(0, centerY, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n}\n\nclass ActorBuilder extends EntityBuilder<ZylemActor, ZylemActorOptions> {\n\tprotected createEntity(options: Partial<ZylemActorOptions>): ZylemActor {\n\t\treturn new ZylemActor(options);\n\t}\n}\n\nexport const ACTOR_TYPE = Symbol('Actor');\n\nexport class ZylemActor extends GameEntity<ZylemActorOptions> implements EntityLoaderDelegate, DebugInfoProvider {\n\tstatic type = ACTOR_TYPE;\n\n\tprivate _object: Object3D | null = null;\n\tprivate _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\n\tcontrolledRotation: boolean = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\t// Add actor-specific update to the lifecycle callbacks\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\t/**\n\t * Initiates model and animation loading in background (deferred).\n\t * Call returns immediately; assets will be ready on subsequent updates.\n\t */\n\tload(): void {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\t// Start async loading in background\n\t\tthis.loadModelsDeferred();\n\t}\n\n\t/**\n\t * Returns current data synchronously.\n\t * May return null values if loading is still in progress.\n\t */\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\t/**\n\t * Clean up actor resources including animations, models, and groups\n\t */\n\tactorDestroy(): void {\n\t\t// Stop and dispose animation delegate\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\t// Dispose geometries and materials from loaded object\n\t\tif (this._object) {\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tconst mesh = child as SkinnedMesh;\n\t\t\t\t\tmesh.geometry?.dispose();\n\t\t\t\t\tif (Array.isArray(mesh.material)) {\n\t\t\t\t\t\tmesh.material.forEach(m => m.dispose());\n\t\t\t\t\t} else if (mesh.material) {\n\t\t\t\t\t\tmesh.material.dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._object = null;\n\t\t}\n\n\t\t// Clear group reference\n\t\tif (this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = null as any;\n\t\t}\n\n\t\t// Clear file name references\n\t\tthis._modelFileNames = [];\n\t}\n\n\t/**\n\t * Deferred loading - starts async load and updates entity when complete.\n\t * Called by synchronous load() method.\n\t */\n\tprivate loadModelsDeferred(): void {\n\t\tif (this._modelFileNames.length === 0) return;\n\n\t\t// Emit loading started event\n\t\tthis.dispatch('entity:model:loading', {\n\t\t\tentityId: this.uuid,\n\t\t\tfiles: this._modelFileNames\n\t\t});\n\n\t\tconst promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tPromise.all(promises).then(results => {\n\t\t\tif (results[0]?.object) {\n\t\t\t\tthis._object = results[0].object;\n\t\t\t}\n\t\t\t// Count meshes for the loaded event\n\t\t\tlet meshCount = 0;\n\t\t\tif (this._object) {\n\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\tif ((child as any).isMesh) meshCount++;\n\t\t\t\t});\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.attach(this._object);\n\t\t\t\tthis.group.scale.set(\n\t\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\t\tthis.options.scale?.z || 1\n\t\t\t\t);\n\n\t\t\t\t// Apply material overrides if specified\n\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t// Load animations after model is ready\n\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\tthis._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Emit model loaded event\n\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\tentityId: this.uuid,\n\t\t\t\tsuccess: !!this._object,\n\t\t\t\tmeshCount\n\t\t\t});\n\t\t});\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\t/**\n\t * Apply material overrides from options to all meshes in the loaded model.\n\t * Only applies if material options are explicitly specified (not just defaults).\n\t */\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\t// Only apply if user specified material options beyond defaults\n\t\tif (!materialOptions || (!materialOptions.color && !materialOptions.path)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) return;\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif ((child as any).isMesh) {\n\t\t\t\tconst mesh = child as Mesh;\n\t\t\t\tif (materialOptions.color) {\n\t\t\t\t\t// Create new material with the specified color\n\t\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\t\tfog: true,\n\t\t\t\t\t});\n\t\t\t\t\tmesh.castShadow = true;\n\t\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\t\tmesh.material = newMaterial;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\t/**\n\t * Provide custom debug information for the actor\n\t * This will be merged with the default debug information\n\t */\n\tgetDebugInfo(): Record<string, any> {\n\t\tconst debugInfo: Record<string, any> = {\n\t\t\ttype: 'Actor',\n\t\t\tmodels: this._modelFileNames.length > 0 ? this._modelFileNames : 'none',\n\t\t\tmodelLoaded: !!this._object,\n\t\t\tscale: this.options.scale ?\n\t\t\t\t`${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` :\n\t\t\t\t'1, 1, 1',\n\t\t};\n\n\t\t// Add animation info if available\n\t\tif (this._animationDelegate) {\n\t\t\tdebugInfo.currentAnimation = this._animationDelegate.currentAnimationKey || 'none';\n\t\t\tdebugInfo.animationsCount = this.options.animations?.length || 0;\n\t\t}\n\n\t\t// Add mesh info if model is loaded\n\t\tif (this._object) {\n\t\t\tlet meshCount = 0;\n\t\t\tlet vertexCount = 0;\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tmeshCount++;\n\t\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\t\tif (geometry && geometry.attributes.position) {\n\t\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tdebugInfo.meshCount = meshCount;\n\t\t\tdebugInfo.vertexCount = vertexCount;\n\t\t}\n\n\t\treturn debugInfo;\n\t}\n}\n\ntype ActorOptions = BaseNode | ZylemActorOptions;\n\nexport function createActor(...args: Array<ActorOptions>): ZylemActor {\n\treturn createEntity<ZylemActor, ZylemActorOptions>({\n\t\targs,\n\t\tdefaultConfig: actorDefaults,\n\t\tEntityClass: ZylemActor,\n\t\tBuilderClass: ActorBuilder,\n\t\tCollisionBuilderClass: ActorCollisionBuilder,\n\t\tentityType: ZylemActor.type\n\t});\n}","import { Mesh, Material, ShaderMaterial, Group, Color, Vector3 } from 'three';\nimport {\n\tCollider,\n\tColliderDesc,\n\tRigidBody,\n\tRigidBodyDesc,\n\tVector,\n} from '@dimforge/rapier3d-compat';\nimport { position, rotation, scale } from '../systems/transformable.system';\nimport { Vec3 } from '../core/vector';\nimport { MaterialBuilder, MaterialOptions } from '../graphics/material';\nimport { CollisionOptions } from '../collision/collision-builder';\nimport { BaseNode } from '../core/base-node';\nimport {\n\tDestroyContext,\n\tSetupContext,\n\tUpdateContext,\n\tLoadedContext,\n\tCleanupContext,\n} from '../core/base-node-life-cycle';\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from './builder';\nimport { Behavior } from '../behaviors/behavior';\nimport {\n\tEventEmitterDelegate,\n\tzylemEventBus,\n\ttype EntityEvents,\n} from '../events';\nimport type {\n\tBehaviorDescriptor,\n\tBehaviorRef,\n\tBehaviorHandle,\n} from '../behaviors/behavior-descriptor';\nimport type { TransformState } from '../actions/capabilities/transform-store';\nimport { createTransformStore } from '../actions/capabilities/transform-store';\nimport { makeTransformable } from '../actions/capabilities/transformable';\nimport type { MoveableEntity } from '../actions/capabilities/moveable';\nimport type { RotatableEntityAPI } from '../actions/capabilities/rotatable';\nimport { isCollisionComponent, type CollisionComponent } from './parts/collision-factories';\nimport type { NodeInterface } from '../core/node-interface';\nimport { commonDefaults } from './common';\nimport type { Action } from '../actions/action';\n\nexport interface CollisionContext<\n\tT,\n\tO extends GameEntityOptions,\n\tTGlobals extends Record<string, unknown> = any,\n> {\n\tentity: T;\n\t// Use 'any' for other's options type to break recursive type variance issues\n\tother: GameEntity<O | any>;\n\tglobals: TGlobals;\n}\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n\t// Use 'any' for entity and options types to avoid contravariance issues\n\t// with function parameters. Type safety is still enforced at the call site via onCollision()\n\tcollision?: ((params: CollisionContext<any, any>) => void)[];\n}\n\nexport type IBuilder<BuilderOptions = any> = {\n\tpreBuild: (options: BuilderOptions) => BuilderOptions;\n\tbuild: (options: BuilderOptions) => BuilderOptions;\n\tpostBuild: (options: BuilderOptions) => BuilderOptions;\n};\n\nexport type GameEntityOptions = {\n\tname?: string;\n\tcolor?: Color;\n\tsize?: Vec3;\n\tposition?: Vec3;\n\tbatched?: boolean;\n\tcollision?: Partial<CollisionOptions>;\n\tmaterial?: Partial<MaterialOptions>;\n\tcustom?: { [key: string]: any };\n\tcollisionType?: string;\n\tcollisionGroup?: string;\n\tcollisionFilter?: string[];\n\t_builders?: {\n\t\tmeshBuilder?: IBuilder | EntityMeshBuilder | null;\n\t\tcollisionBuilder?: IBuilder | EntityCollisionBuilder | null;\n\t\tmaterialBuilder?: MaterialBuilder | null;\n\t};\n};\n\nexport abstract class GameEntityLifeCycle {\n\tabstract _setup(params: SetupContext<this>): void;\n\tabstract _update(params: UpdateContext<this>): void;\n\tabstract _destroy(params: DestroyContext<this>): void;\n}\n\nexport interface EntityDebugInfo {\n\tbuildInfo: () => Record<string, string>;\n}\n\nexport class GameEntity<O extends GameEntityOptions>\n\textends BaseNode<O>\n\timplements GameEntityLifeCycle, EntityDebugInfo, MoveableEntity, RotatableEntityAPI {\n\tpublic behaviors: Behavior[] = [];\n\tpublic group: Group | undefined;\n\tpublic mesh: Mesh | undefined;\n\tpublic materials: Material[] | undefined;\n\tpublic bodyDesc: RigidBodyDesc | null = null;\n\tpublic body: RigidBody | null = null;\n\tpublic colliderDesc: ColliderDesc | undefined;\n\tpublic collider: Collider | undefined;\n\tpublic custom: Record<string, any> = {};\n\n\t// Compound entity support: multiple colliders and meshes\n\t/** All collider descriptions for this entity (including primary) */\n\tpublic colliderDescs: ColliderDesc[] = [];\n\t/** All colliders attached to this entity's rigid body */\n\tpublic colliders: Collider[] = [];\n\t/** Additional meshes for compound visual entities (added via add()) */\n\tpublic compoundMeshes: Mesh[] = [];\n\n\tpublic debugInfo: Record<string, any> = {};\n\tpublic debugMaterial: ShaderMaterial | undefined;\n\n\tpublic collisionDelegate: CollisionDelegate<this, O> = {\n\t\tcollision: [],\n\t};\n\tpublic collisionType?: string;\n\n\t// Instancing support\n\t/** Batch key for instanced rendering (null if not instanced) */\n\tpublic batchKey: string | null = null;\n\t/** Index within the instanced mesh batch */\n\tpublic instanceId: number = -1;\n\t/** Whether this entity uses instanced rendering */\n\tpublic isInstanced: boolean = false;\n\n\t// Event delegate for dispatch/listen API\n\tprotected eventDelegate = new EventEmitterDelegate<EntityEvents>();\n\n\t// Behavior references (new ECS pattern)\n\tprivate behaviorRefs: BehaviorRef[] = [];\n\n\t// Transform store for batched physics updates (auto-created in create())\n\tpublic transformStore: TransformState;\n\n\t// Movement & rotation methods are assigned at runtime by makeTransformable.\n\t// The `implements` clause above ensures the type contract; declarations below\n\t// satisfy the compiler while the constructor fills them in.\n\tmoveX!: (delta: number) => void;\n\tmoveY!: (delta: number) => void;\n\tmoveZ!: (delta: number) => void;\n\tmoveXY!: (deltaX: number, deltaY: number) => void;\n\tmoveXZ!: (deltaX: number, deltaZ: number) => void;\n\tmove!: (vector: Vector3) => void;\n\tresetVelocity!: () => void;\n\tmoveForwardXY!: (delta: number, rotation2DAngle: number) => void;\n\tgetPosition!: () => Vector | null;\n\tgetVelocity!: () => Vector | null;\n\tsetPosition!: (x: number, y: number, z: number) => void;\n\tsetPositionX!: (x: number) => void;\n\tsetPositionY!: (y: number) => void;\n\tsetPositionZ!: (z: number) => void;\n\twrapAroundXY!: (boundsX: number, boundsY: number) => void;\n\twrapAround3D!: (boundsX: number, boundsY: number, boundsZ: number) => void;\n\trotateInDirection!: (moveVector: Vector3) => void;\n\trotateYEuler!: (amount: number) => void;\n\trotateEuler!: (eulerRotation: Vector3) => void;\n\trotateX!: (delta: number) => void;\n\trotateY!: (delta: number) => void;\n\trotateZ!: (delta: number) => void;\n\tsetRotationY!: (y: number) => void;\n\tsetRotationX!: (x: number) => void;\n\tsetRotationZ!: (z: number) => void;\n\tsetRotationDegrees!: (x: number, y: number, z: number) => void;\n\tsetRotationDegreesY!: (y: number) => void;\n\tsetRotationDegreesX!: (x: number) => void;\n\tsetRotationDegreesZ!: (z: number) => void;\n\tsetRotation!: (x: number, y: number, z: number) => void;\n\tgetRotation!: () => any;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.transformStore = createTransformStore();\n\t\tmakeTransformable(this);\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Composable add() - accepts Mesh, CollisionComponent, or child entities\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add meshes, collision components, or child entities to this entity.\n\t * Supports fluent chaining: `entity.add(boxMesh()).add(boxCollision())`.\n\t *\n\t * - `Mesh`: First mesh becomes the primary mesh; subsequent meshes are\n\t * compound meshes grouped together.\n\t * - `CollisionComponent`: First sets bodyDesc + colliderDesc; subsequent\n\t * add extra colliders to the same rigid body.\n\t * - `NodeInterface`: Added as a child entity (delegates to BaseNode.add).\n\t */\n\tpublic add(...components: Array<NodeInterface | Mesh | CollisionComponent>): this {\n\t\tfor (const component of components) {\n\t\t\tif (component instanceof Mesh) {\n\t\t\t\tthis.addMeshComponent(component);\n\t\t\t} else if (isCollisionComponent(component)) {\n\t\t\t\tthis.addCollisionComponent(component);\n\t\t\t} else {\n\t\t\t\tsuper.add(component as NodeInterface);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tprivate addMeshComponent(mesh: Mesh): void {\n\t\tif (!this.mesh) {\n\t\t\t// First mesh becomes the primary mesh\n\t\t\tthis.mesh = mesh;\n\t\t\tif (!this.materials) {\n\t\t\t\tthis.materials = [];\n\t\t\t}\n\t\t\tif (mesh.material) {\n\t\t\t\tconst mat = mesh.material;\n\t\t\t\tif (Array.isArray(mat)) {\n\t\t\t\t\tthis.materials.push(...mat);\n\t\t\t\t} else {\n\t\t\t\t\tthis.materials.push(mat);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Subsequent meshes are compound meshes\n\t\t\tthis.compoundMeshes.push(mesh);\n\t\t\t// Ensure the entity has a group so all meshes are parented together\n\t\t\tif (!this.group) {\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.add(this.mesh);\n\t\t\t}\n\t\t\tthis.group.add(mesh);\n\t\t}\n\t}\n\n\tprivate addCollisionComponent(collision: CollisionComponent): void {\n\t\tif (!this.bodyDesc) {\n\t\t\t// First collision sets the body description and primary collider\n\t\t\tthis.bodyDesc = collision.bodyDesc;\n\t\t\tthis.colliderDesc = collision.colliderDesc;\n\t\t\tthis.colliderDescs.push(collision.colliderDesc);\n\t\t\t// Apply entity position to the body\n\t\t\tconst pos = this.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\t\tthis.bodyDesc.setTranslation(pos.x, pos.y, pos.z);\n\t\t} else {\n\t\t\t// Subsequent collisions add extra colliders to the same body\n\t\t\tthis.colliderDescs.push(collision.colliderDesc);\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Actions API -- entity-scoped, self-contained stateful actions\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tprivate _actions: Action[] = [];\n\n\t/**\n\t * Run a fire-and-forget action. Auto-removed when done.\n\t * @example `me.runAction(moveBy({ x: 10, duration: 0.3 }))`\n\t */\n\tpublic runAction<A extends Action>(action: A): A {\n\t\tthis._actions.push(action);\n\t\treturn action;\n\t}\n\n\t/**\n\t * Register a persistent action (throttle, onPress). Not removed when done.\n\t * @example `const press = entity.action(onPress())`\n\t */\n\tpublic action<A extends Action>(action: A): A {\n\t\taction.persistent = true;\n\t\tthis._actions.push(action);\n\t\treturn action;\n\t}\n\n\t/**\n\t * Tick all registered actions. Called automatically before user onUpdate callbacks.\n\t *\n\t * Resets velocity/angularVelocity accumulation before ticking so that\n\t * actions can compose via `+=` without cross-frame build-up.\n\t * (The existing move helpers like `moveXY` use `=` which doesn't accumulate,\n\t * but action composition needs additive writes on a clean slate each frame.)\n\t */\n\tpublic _tickActions(delta: number): void {\n\t\tif (this._actions.length === 0) return;\n\n\t\t// Clear accumulation from the previous frame so that\n\t\t// actions can compose via `+=` on a clean slate each frame.\n\t\tconst store = this.transformStore;\n\t\tstore.velocity.x = 0;\n\t\tstore.velocity.y = 0;\n\t\tstore.velocity.z = 0;\n\t\tstore.dirty.velocity = false;\n\t\tstore.angularVelocity.x = 0;\n\t\tstore.angularVelocity.y = 0;\n\t\tstore.angularVelocity.z = 0;\n\t\tstore.dirty.angularVelocity = false;\n\n\t\tfor (let i = this._actions.length - 1; i >= 0; i--) {\n\t\t\tconst act = this._actions[i];\n\t\t\tact.tick(this, delta);\n\t\t\tif (act.done && !act.persistent) {\n\t\t\t\tthis._actions.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\t// If every non-persistent action finished this frame, zero out\n\t\t// any velocity they wrote so the entity doesn't drift.\n\t\tif (this._actions.length === 0) {\n\t\t\tstore.velocity.x = 0;\n\t\t\tstore.velocity.y = 0;\n\t\t\tstore.velocity.z = 0;\n\t\t\tstore.dirty.velocity = false;\n\t\t\tstore.angularVelocity.x = 0;\n\t\t\tstore.angularVelocity.y = 0;\n\t\t\tstore.angularVelocity.z = 0;\n\t\t\tstore.dirty.angularVelocity = false;\n\t\t}\n\t}\n\n\tpublic create(): this {\n\t\tconst { position: setupPosition } = this.options;\n\t\tconst { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n\t\tthis.behaviors = [\n\t\t\t{ component: position, values: { x, y, z } },\n\t\t\t{ component: scale, values: { x: 0, y: 0, z: 0 } },\n\t\t\t{ component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n\t\t];\n\t\tthis.name = this.options.name || '';\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add collision callbacks\n\t */\n\tpublic onCollision(\n\t\t...callbacks: ((params: CollisionContext<this, O>) => void)[]\n\t): this {\n\t\tconst existing = this.collisionDelegate.collision ?? [];\n\t\tthis.collisionDelegate.collision = [...existing, ...callbacks];\n\t\treturn this;\n\t}\n\n\t/**\n\t * Use a behavior on this entity via typed descriptor.\n\t * Behaviors will be auto-registered as systems when the entity is spawned.\n\t * @param descriptor The behavior descriptor (import from behaviors module)\n\t * @param options Optional overrides for the behavior's default options\n\t * @returns BehaviorHandle with behavior-specific methods for lazy FSM access\n\t */\n\tpublic use<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst behaviorRef: BehaviorRef<O> = {\n\t\t\tdescriptor: descriptor as BehaviorDescriptor<O, any>,\n\t\t\toptions: { ...descriptor.defaultOptions, ...options } as O,\n\t\t};\n\t\tthis.behaviorRefs.push(behaviorRef as BehaviorRef<any>);\n\n\t\t// Create base handle\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => behaviorRef.fsm ?? null,\n\t\t\tgetOptions: () => behaviorRef.options,\n\t\t\tref: behaviorRef,\n\t\t};\n\n\t\t// Merge behavior-specific methods if createHandle is provided\n\t\tconst customMethods = descriptor.createHandle?.(behaviorRef) ?? ({} as H);\n\n\t\treturn {\n\t\t\t...baseHandle,\n\t\t\t...customMethods,\n\t\t} as BehaviorHandle<O, H>;\n\t}\n\n\t/**\n\t * Get all behavior references attached to this entity.\n\t * Used by the stage to auto-register required systems.\n\t */\n\tpublic getBehaviorRefs(): BehaviorRef[] {\n\t\treturn this.behaviorRefs;\n\t}\n\n\t/**\n\t * Entity-specific setup - resets actions for a fresh stage session.\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n\t */\n\tpublic _setup(params: SetupContext<this>): void {\n\t\t// Reset actions for the new stage session.\n\t\t// Remove completed fire-and-forget actions; reset all others\n\t\t// so they replay from the beginning.\n\t\tfor (let i = this._actions.length - 1; i >= 0; i--) {\n\t\t\tconst act = this._actions[i];\n\t\t\tif (act.done && !act.persistent) {\n\t\t\t\tthis._actions.splice(i, 1);\n\t\t\t} else {\n\t\t\t\tact.reset();\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected async _loaded(_params: LoadedContext<this>): Promise<void> { }\n\n\t/**\n\t * Entity-specific update - updates materials.\n\t * Transform changes are applied by the stage after all update callbacks complete.\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)\n\t */\n\tpublic _update(params: UpdateContext<this>): void {\n\t\tthis.updateMaterials(params);\n\t}\n\n\t/**\n\t * Entity-specific destroy -- reserved for consumer game logic.\n\t * Engine-internal resource disposal runs in _cleanup() instead.\n\t */\n\tpublic _destroy(params: DestroyContext<this>): void { }\n\n\t/**\n\t * Engine-internal resource cleanup -- runs automatically after destroy.\n\t * Disposes GPU/DOM resources (meshes, materials, debug material).\n\t *\n\t * Note: actions, collision callbacks, and behavior refs are intentionally\n\t * NOT cleared here -- they are registered by consumer code at module level\n\t * and must persist across stage reloads. Actions are reset in _setup().\n\t */\n\tprotected _cleanup(_params: CleanupContext<this>): void {\n\t\t// Dispose entity event emitter & subscriptions\n\t\tthis.disposeEvents();\n\n\t\t// Dispose compound meshes\n\t\tfor (const m of this.compoundMeshes) {\n\t\t\tm.geometry?.dispose();\n\t\t\tif (Array.isArray(m.material)) {\n\t\t\t\tm.material.forEach(mat => mat.dispose());\n\t\t\t} else {\n\t\t\t\tm.material?.dispose();\n\t\t\t}\n\t\t}\n\t\tthis.compoundMeshes.length = 0;\n\n\t\t// Dispose debug material\n\t\tthis.debugMaterial?.dispose();\n\t\tthis.debugMaterial = undefined;\n\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\n\t\t// Note: physics references (body, collider, colliders) are intentionally\n\t\t// NOT nulled here. They are needed by removeEntityByUuid() → world.destroyEntity()\n\t\t// which runs later when the stage processes markedForRemoval entities.\n\t}\n\n\tpublic _collision(other: GameEntity<O>, globals?: any): void {\n\t\tif (this.collisionDelegate.collision?.length) {\n\t\t\tconst callbacks = this.collisionDelegate.collision;\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\tcallback({ entity: this, other, globals });\n\t\t\t});\n\t\t}\n\t}\n\n\tprotected updateMaterials(params: any) {\n\t\tif (!this.materials?.length) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const material of this.materials) {\n\t\t\tif (material instanceof ShaderMaterial) {\n\t\t\t\tif (material.uniforms) {\n\t\t\t\t\tmaterial.uniforms.iTime &&\n\t\t\t\t\t\t(material.uniforms.iTime.value += params.delta);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic buildInfo(): Record<string, string> {\n\t\tconst info: Record<string, string> = {};\n\t\tinfo.name = this.name;\n\t\tinfo.uuid = this.uuid;\n\t\tinfo.eid = this.eid.toString();\n\t\treturn info;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from this entity.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof EntityEvents>(\n\t\tevent: K,\n\t\tpayload: EntityEvents[K],\n\t): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this entity instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof EntityEvents>(\n\t\tevent: K,\n\t\thandler: (payload: EntityEvents[K]) => void,\n\t): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Clean up entity event subscriptions.\n\t */\n\tdisposeEvents(): void {\n\t\tthis.eventDelegate.dispose();\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bare entity factory\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a bare entity with no mesh or collision.\n * Use `.add(boxMesh(), boxCollision())` to compose its shape.\n *\n * @example\n * ```ts\n * const box = create({ position: { x: 0, y: 5, z: 0 } })\n * .add(boxMesh({ size: { x: 2, y: 2, z: 2 } }))\n * .add(boxCollision({ size: { x: 2, y: 2, z: 2 } }));\n * ```\n */\nexport function create(options?: Partial<GameEntityOptions>): GameEntity<GameEntityOptions> {\n\tconst entity = new (GameEntity as any)() as GameEntity<GameEntityOptions>;\n\tentity.options = { ...commonDefaults, ...options } as GameEntityOptions;\n\treturn entity;\n}\n","import {\n\tdefineSystem,\n\tdefineQuery,\n\tdefineComponent,\n\tTypes,\n\tremoveQuery,\n\ttype IWorld,\n} from 'bitecs';\nimport { Quaternion } from 'three';\nimport { StageEntity } from '../interfaces/entity';\nimport RAPIER from '@dimforge/rapier3d-compat';\n\nexport type StageSystem = {\n\t_childrenMap: Map<number, StageEntity & { body: RAPIER.RigidBody }>;\n}\n\nexport const position = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32\n});\n\nexport const rotation = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32,\n\tw: Types.f32\n});\n\nexport const scale = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32\n});\n\n// Reusable quaternion to avoid allocations per frame\nconst _tempQuaternion = new Quaternion();\n\nexport type TransformSystemResult = {\n\tsystem: ReturnType<typeof defineSystem>;\n\tdestroy: (world: IWorld) => void;\n};\n\nexport default function createTransformSystem(stage: StageSystem): TransformSystemResult {\n\tconst queryTerms = [position, rotation];\n\tconst transformQuery = defineQuery(queryTerms);\n\tconst stageEntities = stage._childrenMap;\n\n\tconst system = defineSystem((world) => {\n\t\tconst entities = transformQuery(world);\n\t\tif (stageEntities === undefined) {\n\t\t\treturn world;\n\t\t}\n\n\t\tfor (const [key, stageEntity] of stageEntities) {\n\t\t\t// Early bailout - combine conditions\n\t\t\tif (!stageEntity?.body || stageEntity.markedForRemoval) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst id = entities[key];\n\t\t\tconst body = stageEntity.body;\n\t\t\tconst target = stageEntity.group ?? stageEntity.mesh;\n\n\t\t\t// Position sync\n\t\t\tconst translation = body.translation();\n\t\t\tposition.x[id] = translation.x;\n\t\t\tposition.y[id] = translation.y;\n\t\t\tposition.z[id] = translation.z;\n\n\t\t\tif (target) {\n\t\t\t\ttarget.position.set(translation.x, translation.y, translation.z);\n\t\t\t}\n\n\t\t\t// Skip rotation if controlled externally\n\t\t\tif (stageEntity.controlledRotation) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Rotation sync - reuse quaternion\n\t\t\tconst rot = body.rotation();\n\t\t\trotation.x[id] = rot.x;\n\t\t\trotation.y[id] = rot.y;\n\t\t\trotation.z[id] = rot.z;\n\t\t\trotation.w[id] = rot.w;\n\n\t\t\tif (target) {\n\t\t\t\t_tempQuaternion.set(rot.x, rot.y, rot.z, rot.w);\n\t\t\t\ttarget.setRotationFromQuaternion(_tempQuaternion);\n\t\t\t}\n\t\t}\n\n\t\treturn world;\n\t});\n\n\tconst destroy = (world: IWorld) => {\n\t\t// Remove the query from bitecs world tracking\n\t\tremoveQuery(world, transformQuery);\n\t};\n\n\treturn { system, destroy };\n}","/** Vite build flags */\nexport const DEBUG_FLAG = import.meta.env.VITE_DEBUG_FLAG === 'true';","import {\n\tCleanupContext,\n\tCleanupFunction,\n\tDestroyContext,\n\tDestroyFunction,\n\tLoadedContext,\n\tLoadedFunction,\n\tSetupContext,\n\tSetupFunction,\n\tUpdateContext,\n\tUpdateFunction,\n} from \"./base-node-life-cycle\";\nimport { DEBUG_FLAG } from \"./flags\";\nimport { nanoid } from \"nanoid\";\nimport { NodeInterface } from \"./node-interface\";\n\nexport type BaseNodeOptions<T = any> = BaseNode | Partial<T>;\n\n/**\n * Lifecycle callback arrays - each lifecycle event can have multiple callbacks\n * that execute in order.\n */\nexport interface LifecycleCallbacks<T> {\n\tsetup: Array<SetupFunction<T>>;\n\tloaded: Array<LoadedFunction<T>>;\n\tupdate: Array<UpdateFunction<T>>;\n\tdestroy: Array<DestroyFunction<T>>;\n\tcleanup: Array<CleanupFunction<T>>;\n}\n\nexport abstract class BaseNode<Options = any, T = any> implements NodeInterface {\n\tprotected parent: NodeInterface | null = null;\n\tprotected children: NodeInterface[] = [];\n\tpublic options: Options;\n\tpublic eid: number = 0;\n\tpublic uuid: string = '';\n\tpublic name: string = '';\n\tpublic markedForRemoval: boolean = false;\n\n\t/**\n\t * Lifecycle callback arrays - use onSetup(), onUpdate(), etc. to add callbacks\n\t * Uses `any` for the type parameter to avoid invariance issues when subclasses\n\t * are assigned to BaseNode references. Type safety is enforced by the public\n\t * onSetup/onUpdate/etc. methods which are typed with `this`.\n\t */\n\tprotected lifecycleCallbacks: LifecycleCallbacks<any> = {\n\t\tsetup: [],\n\t\tloaded: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcleanup: [],\n\t};\n\n\tconstructor(args: BaseNodeOptions[] = []) {\n\t\tconst options = args\n\t\t\t.filter(arg => !(arg instanceof BaseNode))\n\t\t\t.reduce((acc, opt) => ({ ...acc, ...opt }), {});\n\t\tthis.options = options as Options;\n\t\tthis.uuid = nanoid();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Fluent API for adding lifecycle callbacks\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add setup callbacks to be executed in order during nodeSetup\n\t */\n\tpublic onSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add loaded callbacks to be executed in order during nodeLoaded\n\t */\n\tpublic onLoaded(...callbacks: Array<LoadedFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.loaded.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add update callbacks to be executed in order during nodeUpdate\n\t */\n\tpublic onUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add destroy callbacks to be executed in order during nodeDestroy\n\t */\n\tpublic onDestroy(...callbacks: Array<DestroyFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.destroy.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add cleanup callbacks to be executed in order during nodeCleanup\n\t */\n\tpublic onCleanup(...callbacks: Array<CleanupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.cleanup.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend setup callbacks (run before existing ones)\n\t */\n\tpublic prependSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.unshift(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend update callbacks (run before existing ones)\n\t */\n\tpublic prependUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.unshift(...callbacks);\n\t\treturn this;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Tree structure\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic setParent(parent: NodeInterface | null): void {\n\t\tthis.parent = parent;\n\t}\n\n\tpublic getParent(): NodeInterface | null {\n\t\treturn this.parent;\n\t}\n\n\tpublic add(baseNode: NodeInterface): void {\n\t\tthis.children.push(baseNode);\n\t\tbaseNode.setParent(this);\n\t}\n\n\tpublic remove(baseNode: NodeInterface): void {\n\t\tconst index = this.children.indexOf(baseNode);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tbaseNode.setParent(null);\n\t\t}\n\t}\n\n\tpublic getChildren(): NodeInterface[] {\n\t\treturn this.children;\n\t}\n\n\tpublic isComposite(): boolean {\n\t\treturn this.children.length > 0;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Abstract methods for subclass implementation\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic abstract create(): T;\n\n\tprotected abstract _setup(params: SetupContext<this>): void;\n\n\tprotected abstract _loaded(params: LoadedContext<this>): Promise<void>;\n\n\tprotected abstract _update(params: UpdateContext<this>): void;\n\n\tprotected abstract _destroy(params: DestroyContext<this>): void;\n\n\tprotected abstract _cleanup(params: CleanupContext<this>): void;\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Node lifecycle execution - runs internal + callback arrays\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic nodeSetup(params: SetupContext<this>) {\n\t\tif (DEBUG_FLAG) { /** */ }\n\t\tthis.markedForRemoval = false;\n\t\tif (typeof this._setup === 'function') {\n\t\t\tthis._setup(params);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.setup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tthis.children.forEach(child => child.nodeSetup(params));\n\t}\n\n\tpublic nodeUpdate(params: UpdateContext<this>): void {\n\t\tif (this.markedForRemoval) {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof this._update === 'function') {\n\t\t\tthis._update(params);\n\t\t}\n\t\t// Tick entity actions before user callbacks so state is fresh\n\t\tif (typeof (this as any)._tickActions === 'function') {\n\t\t\t(this as any)._tickActions(params.delta);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.update) {\n\t\t\tcallback(params);\n\t\t}\n\t\tthis.children.forEach(child => child.nodeUpdate(params));\n\t}\n\n\tpublic nodeDestroy(params: DestroyContext<this>): void {\n\t\t// Guard against re-entry (e.g. destroy called twice during collision loop)\n\t\tif (this.markedForRemoval) return;\n\n\t\tthis.children.forEach(child => child.nodeDestroy(params));\n\n\t\t// Destroy phase -- consumer game logic (onDestroy callbacks + _destroy override)\n\t\tfor (const callback of this.lifecycleCallbacks.destroy) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._destroy === 'function') {\n\t\t\tthis._destroy(params);\n\t\t}\n\t\tthis.markedForRemoval = true;\n\n\t\t// Cleanup phase -- engine-internal resource disposal (onCleanup callbacks + _cleanup override)\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tthis._cleanup(params);\n\t\t}\n\t}\n\n\tpublic async nodeLoaded(params: LoadedContext<this>): Promise<void> {\n\t\tif (typeof this._loaded === 'function') {\n\t\t\tawait this._loaded(params);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.loaded) {\n\t\t\tcallback(params);\n\t\t}\n\t}\n\n\tpublic nodeCleanup(params: CleanupContext<this>): void {\n\t\tthis.children.forEach(child => (child as any).nodeCleanup?.(params));\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tthis._cleanup(params);\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Options\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic getOptions(): Options {\n\t\treturn this.options;\n\t}\n\n\tpublic setOptions(options: Partial<Options>): void {\n\t\tthis.options = { ...this.options, ...options };\n\t}\n}","export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n\tWildcardHandler<T>\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n\tall: EventHandlerMap<Events>;\n\n\ton<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n\ton(type: '*', handler: WildcardHandler<Events>): void;\n\n\toff<Key extends keyof Events>(\n\t\ttype: Key,\n\t\thandler?: Handler<Events[Key]>\n\t): void;\n\toff(type: '*', handler: WildcardHandler<Events>): void;\n\n\temit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n\temit<Key extends keyof Events>(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt<Events extends Record<EventType, unknown>>(\n\tall?: EventHandlerMap<Events>\n): Emitter<Events> {\n\ttype GenericEventHandler =\n\t\t| Handler<Events[keyof Events]>\n\t\t| WildcardHandler<Events>;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList<Events[keyof Events]>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList<Events>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n","import mitt, { Emitter } from 'mitt';\n\n/**\n * Event scope identifier for routing events.\n */\nexport type EventScope = 'game' | 'stage' | 'entity';\n\n/**\n * Reusable delegate for event emission and subscription.\n * Use via composition in Game, Stage, and Entity classes.\n * \n * @example\n * class Game {\n * private eventDelegate = new EventEmitterDelegate<GameEvents>();\n * \n * dispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]) {\n * this.eventDelegate.dispatch(event, payload);\n * }\n * }\n */\nexport class EventEmitterDelegate<TEvents extends Record<string, unknown>> {\n\tprivate emitter: Emitter<TEvents>;\n\tprivate unsubscribes: (() => void)[] = [];\n\n\tconstructor() {\n\t\tthis.emitter = mitt<TEvents>();\n\t}\n\n\t/**\n\t * Dispatch an event to all listeners.\n\t */\n\tdispatch<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n\t\tthis.emitter.emit(event, payload);\n\t}\n\n\t/**\n\t * Subscribe to an event. Returns an unsubscribe function.\n\t */\n\tlisten<K extends keyof TEvents>(\n\t\tevent: K,\n\t\thandler: (payload: TEvents[K]) => void\n\t): () => void {\n\t\tthis.emitter.on(event, handler);\n\t\tconst unsub = () => this.emitter.off(event, handler);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Subscribe to all events.\n\t */\n\tlistenAll(handler: (type: keyof TEvents, payload: TEvents[keyof TEvents]) => void): () => void {\n\t\tthis.emitter.on('*', handler as any);\n\t\tconst unsub = () => this.emitter.off('*', handler as any);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Clean up all subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.unsubscribes.forEach(fn => fn());\n\t\tthis.unsubscribes = [];\n\t\tthis.emitter.all.clear();\n\t}\n}\n","import mitt from 'mitt';\nimport type { LoadingEvent } from '../core/interfaces';\n\n/**\n * Payload for game loading events with stage context.\n */\nexport interface GameLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Game Events\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Payload for stage configuration sent to editor. */\nexport interface StageConfigPayload {\n\tid: string;\n\tbackgroundColor: string;\n\tbackgroundImage: string | null;\n\tgravity: { x: number; y: number; z: number };\n\tinputs: Record<string, string[]>;\n\tvariables: Record<string, unknown>;\n}\n\n/** Payload for entity configuration sent to editor. */\nexport interface EntityConfigPayload {\n\tuuid: string;\n\tname: string;\n\ttype: string;\n\tposition: { x: number; y: number; z: number };\n\trotation: { x: number; y: number; z: number };\n\tscale: { x: number; y: number; z: number };\n}\n\n/** Payload for state dispatch events from game to editor. */\nexport interface StateDispatchPayload {\n\tscope: 'game' | 'stage' | 'entity';\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n\tconfig?: {\n\t\tid: string;\n\t\taspectRatio: number;\n\t\tfullscreen: boolean;\n\t\tbodyBackground: string | undefined;\n\t\tinternalResolution: { width: number; height: number } | undefined;\n\t\tdebug: boolean;\n\t} | null;\n\tstageConfig?: StageConfigPayload | null;\n\tentities?: EntityConfigPayload[] | null;\n}\n\nexport type GameEvents = {\n\t'loading:start': GameLoadingPayload;\n\t'loading:progress': GameLoadingPayload;\n\t'loading:complete': GameLoadingPayload;\n\t'paused': { paused: boolean };\n\t'debug': { enabled: boolean };\n\t'state:dispatch': StateDispatchPayload;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stage Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type StageEvents = {\n\t'stage:loaded': { stageId: string };\n\t'stage:unloaded': { stageId: string };\n\t'stage:variable:changed': { key: string; value: unknown };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type EntityEvents = {\n\t'entity:spawned': { entityId: string; name: string };\n\t'entity:destroyed': { entityId: string };\n\t'entity:collision': { entityId: string; otherId: string };\n\t'entity:model:loading': { entityId: string; files: string[] };\n\t'entity:model:loaded': { entityId: string; success: boolean; meshCount?: number };\n\t'entity:animation:loaded': { entityId: string; animationCount: number };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Combined Event Map\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ZylemEvents = GameEvents & StageEvents & EntityEvents;\n\n/**\n * Global event bus for cross-package communication.\n * \n * Usage:\n * ```ts\n * import { zylemEventBus } from '@zylem/game-lib';\n * \n * // Subscribe\n * const unsub = zylemEventBus.on('loading:progress', (e) => console.log(e));\n * \n * // Emit\n * zylemEventBus.emit('loading:progress', { type: 'progress', progress: 0.5 });\n * \n * // Cleanup\n * unsub();\n * ```\n */\nexport const zylemEventBus = mitt<ZylemEvents>();\n","import { proxy } from 'valtio';\n\n/**\n * Transform state managed by Valtio for batched physics updates.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\tvelocity: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocity: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n/**\n * Reset a transform store to its initial clean state.\n * Called after applying changes to prepare for the next frame.\n * \n * @param store The transform store to reset\n */\nexport function resetTransformStore(store: TransformState): void {\n\t// Reset position deltas\n\tstore.position.x = 0;\n\tstore.position.y = 0;\n\tstore.position.z = 0;\n\n\t// Reset rotation to identity quaternion\n\tstore.rotation.x = 0;\n\tstore.rotation.y = 0;\n\tstore.rotation.z = 0;\n\tstore.rotation.w = 1;\n\n\t// Reset velocity\n\tstore.velocity.x = 0;\n\tstore.velocity.y = 0;\n\tstore.velocity.z = 0;\n\n\t// Reset angular velocity\n\tstore.angularVelocity.x = 0;\n\tstore.angularVelocity.y = 0;\n\tstore.angularVelocity.z = 0;\n\n\t// Clear all dirty flags\n\tstore.dirty.position = false;\n\tstore.dirty.rotation = false;\n\tstore.dirty.velocity = false;\n\tstore.dirty.angularVelocity = false;\n}\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\n\nexport interface EntityWithBody {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x = delta;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.y = delta;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.z = delta;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x = deltaX;\n\tentity.transformStore.velocity.y = deltaY;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x = deltaX;\n\tentity.transformStore.velocity.z = deltaZ;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x += vector.x;\n\tentity.transformStore.velocity.y += vector.y;\n\tentity.transformStore.velocity.z += vector.z;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","import { Euler, Vector3, MathUtils, Quaternion } from 'three';\nimport { RigidBody } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\n\nexport interface RotatableEntity {\n\tbody: RigidBody | null;\n\tgroup: any;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Rotate an entity in the direction of a movement vector\n */\nexport function rotateInDirection(entity: RotatableEntity, moveVector: Vector3): void {\n\tif (!entity.body) return;\n\tconst rotate = Math.atan2(-moveVector.x, moveVector.z);\n\trotateYEuler(entity, rotate);\n}\n\n/**\n * Rotate an entity around the Y axis using Euler angles\n */\nexport function rotateYEuler(entity: RotatableEntity, amount: number): void {\n\trotateEuler(entity, new Vector3(0, -amount, 0));\n}\n\n/**\n * Rotate an entity using Euler angles\n */\nexport function rotateEuler(entity: RotatableEntity, rotation: Vector3): void {\n\tif (!entity.group) return;\n\tconst euler = new Euler(rotation.x, rotation.y, rotation.z);\n\tentity.group.setRotationFromEuler(euler);\n}\n\n/**\n * Rotate an entity around the Y axis.\n */\nexport function rotateY(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaY = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For Y-axis rotation: q_delta = (0, deltaY, 0, deltaW)\n\tconst newW = q.w * deltaW - q.y * deltaY;\n\tconst newX = q.x * deltaW + q.z * deltaY;\n\tconst newY = q.y * deltaW + q.w * deltaY;\n\tconst newZ = q.z * deltaW - q.x * deltaY;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Rotate an entity around the X axis.\n */\nexport function rotateX(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaX = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For X-axis rotation: q_delta = (deltaX, 0, 0, deltaW)\n\tconst newW = q.w * deltaW - q.x * deltaX;\n\tconst newX = q.x * deltaW + q.w * deltaX;\n\tconst newY = q.y * deltaW + q.z * deltaX;\n\tconst newZ = q.z * deltaW - q.y * deltaX;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Rotate an entity around the Z axis.\n */\nexport function rotateZ(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaZ = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For Z-axis rotation: q_delta = (0, 0, deltaZ, deltaW)\n\tconst newW = q.w * deltaW - q.z * deltaZ;\n\tconst newX = q.x * deltaW - q.y * deltaZ;\n\tconst newY = q.y * deltaW + q.x * deltaZ;\n\tconst newZ = q.z * deltaW + q.w * deltaZ;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around Y axis.\n */\nexport function setRotationY(entity: RotatableEntity, y: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = y / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst yComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = 0;\n\tentity.transformStore.rotation.y = yComponent;\n\tentity.transformStore.rotation.z = 0;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around Y axis\n */\nexport function setRotationDegreesY(entity: RotatableEntity, y: number): void {\n\tif (!entity.body) return;\n\tsetRotationY(entity, MathUtils.degToRad(y));\n}\n\n/**\n * Set rotation around X axis.\n */\nexport function setRotationX(entity: RotatableEntity, x: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = x / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst xComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = xComponent;\n\tentity.transformStore.rotation.y = 0;\n\tentity.transformStore.rotation.z = 0;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around X axis\n */\nexport function setRotationDegreesX(entity: RotatableEntity, x: number): void {\n\tif (!entity.body) return;\n\tsetRotationX(entity, MathUtils.degToRad(x));\n}\n\n/**\n * Set rotation around Z axis.\n */\nexport function setRotationZ(entity: RotatableEntity, z: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = z / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst zComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = 0;\n\tentity.transformStore.rotation.y = 0;\n\tentity.transformStore.rotation.z = zComponent;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around Z axis\n */\nexport function setRotationDegreesZ(entity: RotatableEntity, z: number): void {\n\tif (!entity.body) return;\n\tsetRotationZ(entity, MathUtils.degToRad(z));\n}\n\n/**\n * Set rotation for all axes.\n */\nexport function setRotation(entity: RotatableEntity, x: number, y: number, z: number): void {\n\tif (!entity.transformStore) return;\n\tconst quat = new Quaternion().setFromEuler(new Euler(x, y, z));\n\tentity.transformStore.rotation.w = quat.w;\n\tentity.transformStore.rotation.x = quat.x;\n\tentity.transformStore.rotation.y = quat.y;\n\tentity.transformStore.rotation.z = quat.z;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation for all axes\n */\nexport function setRotationDegrees(entity: RotatableEntity, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tsetRotation(entity, MathUtils.degToRad(x), MathUtils.degToRad(y), MathUtils.degToRad(z));\n}\n\n/**\n * Get current rotation\n */\nexport function getRotation(entity: RotatableEntity): any {\n\tif (!entity.body) return null;\n\treturn entity.body.rotation();\n}\n\n/**\n * Rotatable entity API with bound methods\n */\nexport interface RotatableEntityAPI extends RotatableEntity {\n\trotateInDirection(moveVector: Vector3): void;\n\trotateYEuler(amount: number): void;\n\trotateEuler(rotation: Vector3): void;\n\trotateY(delta: number): void;\n\trotateX(delta: number): void;\n\trotateZ(delta: number): void;\n\tsetRotationY(y: number): void;\n\tsetRotationX(x: number): void;\n\tsetRotationZ(z: number): void;\n\tsetRotationDegrees(x: number, y: number, z: number): void;\n\tsetRotationDegreesY(y: number): void;\n\tsetRotationDegreesX(x: number): void;\n\tsetRotationDegreesZ(z: number): void;\n\tsetRotation(x: number, y: number, z: number): void;\n\tgetRotation(): any;\n}\n\n/**\n * Enhance an entity instance with rotatable methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeRotatable<T extends RotatableEntity>(entity: T): T & RotatableEntityAPI {\n\tconst rotatableEntity = entity as T & RotatableEntityAPI;\n\n\t// Create transform store if it doesn't exist\n\tif (!rotatableEntity.transformStore) {\n\t\trotatableEntity.transformStore = createTransformStore();\n\t}\n\n\trotatableEntity.rotateInDirection = (moveVector: Vector3) => rotateInDirection(entity, moveVector);\n\trotatableEntity.rotateYEuler = (amount: number) => rotateYEuler(entity, amount);\n\trotatableEntity.rotateEuler = (rotation: Vector3) => rotateEuler(entity, rotation);\n\trotatableEntity.rotateX = (delta: number) => rotateX(entity, delta);\n\trotatableEntity.rotateY = (delta: number) => rotateY(entity, delta);\n\trotatableEntity.rotateZ = (delta: number) => rotateZ(entity, delta);\n\trotatableEntity.setRotationY = (y: number) => setRotationY(entity, y);\n\trotatableEntity.setRotationX = (x: number) => setRotationX(entity, x);\n\trotatableEntity.setRotationZ = (z: number) => setRotationZ(entity, z);\n\trotatableEntity.setRotationDegreesY = (y: number) => setRotationDegreesY(entity, y);\n\trotatableEntity.setRotationDegreesX = (x: number) => setRotationDegreesX(entity, x);\n\trotatableEntity.setRotationDegreesZ = (z: number) => setRotationDegreesZ(entity, z);\n\trotatableEntity.setRotationDegrees = (x: number, y: number, z: number) => setRotationDegrees(entity, x, y, z);\n\trotatableEntity.setRotation = (x: number, y: number, z: number) => setRotation(entity, x, y, z);\n\trotatableEntity.getRotation = () => getRotation(entity);\n\n\treturn rotatableEntity;\n}","import { makeMoveable, EntityWithBody, MoveableEntity } from './moveable';\nimport { makeRotatable, RotatableEntity, RotatableEntityAPI } from './rotatable';\n\n/**\n * Enhance an entity with both movement and rotation capabilities.\n * Transform store is automatically created by makeMoveable and makeRotatable.\n */\nexport function makeTransformable<\n\tT extends RotatableEntity & EntityWithBody\n>(entity: T): T & MoveableEntity & RotatableEntityAPI {\n\tconst withMovement = makeMoveable(entity);\n\tconst withRotation = makeRotatable(withMovement);\n\treturn withRotation;\n}\n\n","import {\n\tActiveCollisionTypes,\n\tColliderDesc,\n\tRigidBodyDesc,\n\tRigidBodyType,\n} from '@dimforge/rapier3d-compat';\nimport { Vector3 } from 'three';\nimport type { Vec3 } from '../../core/vector';\nimport {\n\tgetOrCreateCollisionGroupId,\n\tcreateCollisionFilter,\n\ttype CollisionOptions,\n} from '../../collision/collision-builder';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CollisionComponent type returned by all collision factories\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A built collision component containing a rigid body description and collider description.\n * Returned by collision factory functions (boxCollision, sphereCollision, etc.)\n * and consumed by GameEntity.add().\n */\nexport interface CollisionComponent {\n\t__kind: 'collision';\n\tbodyDesc: RigidBodyDesc;\n\tcolliderDesc: ColliderDesc;\n}\n\n/**\n * Type guard for CollisionComponent.\n */\nexport function isCollisionComponent(obj: any): obj is CollisionComponent {\n\treturn obj && obj.__kind === 'collision';\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BaseCollisionOptions {\n\t/** Whether the body is static (fixed) or dynamic */\n\tstatic?: boolean;\n\t/** Whether this collider is a sensor */\n\tsensor?: boolean;\n\t/** Position offset relative to the entity origin */\n\toffset?: Vec3;\n\t/** Collision type string for group filtering */\n\tcollisionType?: string;\n\t/** Allowed collision types for filtering */\n\tcollisionFilter?: string[];\n}\n\nfunction buildBodyDesc(isStatic: boolean): RigidBodyDesc {\n\tconst type = isStatic ? RigidBodyType.Fixed : RigidBodyType.Dynamic;\n\treturn new RigidBodyDesc(type)\n\t\t.setTranslation(0, 0, 0)\n\t\t.setGravityScale(1.0)\n\t\t.setCanSleep(false)\n\t\t.setCcdEnabled(true);\n}\n\nfunction applyCollisionOptions(\n\tcolliderDesc: ColliderDesc,\n\topts: BaseCollisionOptions,\n): void {\n\tif (opts.offset) {\n\t\tcolliderDesc.setTranslation(opts.offset.x, opts.offset.y, opts.offset.z);\n\t}\n\tif (opts.sensor) {\n\t\tcolliderDesc.setSensor(true);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\t}\n\tif (opts.collisionType) {\n\t\tconst groupId = getOrCreateCollisionGroupId(opts.collisionType);\n\t\tlet filter = 0b1111111111111111;\n\t\tif (opts.collisionFilter) {\n\t\t\tfilter = createCollisionFilter(opts.collisionFilter);\n\t\t}\n\t\tcolliderDesc.setCollisionGroups((groupId << 16) | filter);\n\t}\n}\n\nfunction makeComponent(\n\tcolliderDesc: ColliderDesc,\n\topts: BaseCollisionOptions,\n): CollisionComponent {\n\tapplyCollisionOptions(colliderDesc, opts);\n\treturn {\n\t\t__kind: 'collision',\n\t\tbodyDesc: buildBodyDesc(opts.static ?? false),\n\t\tcolliderDesc,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Box\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BoxCollisionOptions extends BaseCollisionOptions {\n\t/** Box dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a box (cuboid) collision component.\n */\nexport function boxCollision(opts: BoxCollisionOptions = {}): CollisionComponent {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst desc = ColliderDesc.cuboid(size.x / 2, size.y / 2, size.z / 2);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sphere\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SphereCollisionOptions extends BaseCollisionOptions {\n\t/** Sphere radius (default: 1) */\n\tradius?: number;\n}\n\n/**\n * Create a sphere (ball) collision component.\n */\nexport function sphereCollision(opts: SphereCollisionOptions = {}): CollisionComponent {\n\tconst desc = ColliderDesc.ball(opts.radius ?? 1);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cone\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ConeCollisionOptions extends BaseCollisionOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a cone collision component.\n */\nexport function coneCollision(opts: ConeCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 1;\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cone(height / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pyramid (cone collider with 4-sided visual approximation)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PyramidCollisionOptions extends BaseCollisionOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a pyramid collision component (approximated as a cone).\n */\nexport function pyramidCollision(opts: PyramidCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 1;\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cone(height / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cylinder\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CylinderCollisionOptions extends BaseCollisionOptions {\n\t/** Top radius (default: 1) */\n\tradiusTop?: number;\n\t/** Bottom radius (default: 1) */\n\tradiusBottom?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a cylinder collision component.\n */\nexport function cylinderCollision(opts: CylinderCollisionOptions = {}): CollisionComponent {\n\tconst radius = Math.max(opts.radiusTop ?? 1, opts.radiusBottom ?? 1);\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cylinder(height / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pill (capsule)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PillCollisionOptions extends BaseCollisionOptions {\n\t/** Capsule hemisphere radius (default: 0.5) */\n\tradius?: number;\n\t/** Cylindrical section length (default: 1) */\n\tlength?: number;\n}\n\n/**\n * Create a pill (capsule) collision component.\n */\nexport function pillCollision(opts: PillCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 0.5;\n\tconst length = opts.length ?? 1;\n\tconst desc = ColliderDesc.capsule(length / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Plane (heightfield)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PlaneCollisionOptions extends BaseCollisionOptions {\n\t/** Tile dimensions (default: 10x10) */\n\ttile?: { x: number; y: number };\n\t/** Number of subdivisions per axis (default: 10) */\n\tsubdivisions?: number;\n\t/** Pre-computed height data for the heightfield */\n\theightData?: Float32Array;\n}\n\n/**\n * Create a plane (heightfield) collision component.\n * For flat planes, pass no heightData — a zeroed heightfield is used.\n */\nexport function planeCollision(opts: PlaneCollisionOptions = {}): CollisionComponent {\n\tconst tile = opts.tile ?? { x: 10, y: 10 };\n\tconst subdivisions = opts.subdivisions ?? 10;\n\tconst size = new Vector3(tile.x, 1, tile.y);\n\n\tconst totalVerts = (subdivisions + 1) * (subdivisions + 1);\n\tconst heightData = opts.heightData ?? new Float32Array(totalVerts);\n\n\tconst desc = ColliderDesc.heightfield(\n\t\tsubdivisions,\n\t\tsubdivisions,\n\t\theightData,\n\t\tsize,\n\t);\n\n\treturn makeComponent(desc, { ...opts, static: opts.static ?? true });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Zone (sensor cuboid)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ZoneCollisionOptions extends BaseCollisionOptions {\n\t/** Zone dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a zone (sensor cuboid) collision component.\n * Always a sensor; static by default.\n */\nexport function zoneCollision(opts: ZoneCollisionOptions = {}): CollisionComponent {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst desc = ColliderDesc.cuboid(size.x / 2, size.y / 2, size.z / 2);\n\tdesc.setSensor(true);\n\tdesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\treturn makeComponent(desc, { ...opts, static: opts.static ?? true, sensor: true });\n}\n","import { Color, Vector3 } from 'three';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { GameEntityOptions } from './entity';\nimport { BaseNode } from '../core/base-node';\n\nexport const commonDefaults: Partial<GameEntityOptions> = {\n position: new Vector3(0, 0, 0),\n material: {\n color: new Color('#ffffff'),\n shader: standardShader\n },\n collision: {\n static: false,\n },\n};\n\n/**\n * Merge a variadic args array (BaseNode children + options object) with defaults.\n * Returns the merged options. This replaces the createEntity() arg parsing logic.\n */\nexport function mergeArgs<T extends GameEntityOptions>(\n args: Array<BaseNode | Partial<T>>,\n defaults: Partial<T>,\n): T {\n const configArgs = args.filter(\n (arg): arg is Partial<T> => !(arg instanceof BaseNode),\n );\n let merged: Partial<T> = { ...defaults };\n for (const opt of configArgs) {\n merged = { ...merged, ...opt };\n }\n return merged as T;\n}\n","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","/**\n * Centralized Asset Manager for Zylem\n * \n * Provides caching, parallel loading, and unified access to all asset types.\n * All asset loading should funnel through this manager.\n */\n\nimport { Texture, Object3D, LoadingManager, Cache } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport mitt, { Emitter } from 'mitt';\n\nimport {\n\tAssetType,\n\tAssetLoadOptions,\n\tAssetManagerEvents,\n\tBatchLoadItem,\n\tModelLoadResult\n} from './asset-types';\n\nimport {\n\tTextureLoaderAdapter,\n\tGLTFLoaderAdapter,\n\tFBXLoaderAdapter,\n\tOBJLoaderAdapter,\n\tAudioLoaderAdapter,\n\tFileLoaderAdapter,\n\tJsonLoaderAdapter,\n\tTextureOptions,\n\tGLTFLoadOptions,\n\tFBXLoadOptions,\n\tOBJLoadOptions,\n\tFileLoadOptions\n} from './loaders';\n\n/**\n * Asset cache entry\n */\ninterface CacheEntry<T> {\n\tpromise: Promise<T>;\n\tresult?: T;\n\tloadedAt: number;\n}\n\n/**\n * AssetManager - Singleton for all asset loading\n * \n * Features:\n * - URL-based caching with deduplication\n * - Typed load methods for each asset type\n * - Batch loading with Promise.all() for parallelism\n * - Progress events via LoadingManager\n * - Clone support for shared assets (textures, models)\n */\nexport class AssetManager {\n\tprivate static instance: AssetManager | null = null;\n\n\t// Caches for different asset types\n\tprivate textureCache: Map<string, CacheEntry<Texture>> = new Map();\n\tprivate modelCache: Map<string, CacheEntry<ModelLoadResult>> = new Map();\n\tprivate audioCache: Map<string, CacheEntry<AudioBuffer>> = new Map();\n\tprivate fileCache: Map<string, CacheEntry<string | ArrayBuffer>> = new Map();\n\tprivate jsonCache: Map<string, CacheEntry<unknown>> = new Map();\n\n\t// Loaders\n\tprivate textureLoader: TextureLoaderAdapter;\n\tprivate gltfLoader: GLTFLoaderAdapter;\n\tprivate fbxLoader: FBXLoaderAdapter;\n\tprivate objLoader: OBJLoaderAdapter;\n\tprivate audioLoader: AudioLoaderAdapter;\n\tprivate fileLoader: FileLoaderAdapter;\n\tprivate jsonLoader: JsonLoaderAdapter;\n\n\t// Loading manager for progress tracking\n\tprivate loadingManager: LoadingManager;\n\n\t// Event emitter\n\tprivate events: Emitter<AssetManagerEvents>;\n\n\t// Stats\n\tprivate stats = {\n\t\ttexturesLoaded: 0,\n\t\tmodelsLoaded: 0,\n\t\taudioLoaded: 0,\n\t\tfilesLoaded: 0,\n\t\tcacheHits: 0,\n\t\tcacheMisses: 0\n\t};\n\n\tprivate constructor() {\n\t\t// Initialize loaders\n\t\tthis.textureLoader = new TextureLoaderAdapter();\n\t\tthis.gltfLoader = new GLTFLoaderAdapter();\n\t\tthis.fbxLoader = new FBXLoaderAdapter();\n\t\tthis.objLoader = new OBJLoaderAdapter();\n\t\tthis.audioLoader = new AudioLoaderAdapter();\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t\tthis.jsonLoader = new JsonLoaderAdapter();\n\n\t\t// Initialize loading manager\n\t\tthis.loadingManager = new LoadingManager();\n\t\tthis.loadingManager.onProgress = (url, loaded, total) => {\n\t\t\tthis.events.emit('batch:progress', { loaded, total });\n\t\t};\n\n\t\t// Initialize event emitter\n\t\tthis.events = mitt<AssetManagerEvents>();\n\n\t\t// Enable Three.js built-in cache\n\t\tCache.enabled = true;\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tstatic getInstance(): AssetManager {\n\t\tif (!AssetManager.instance) {\n\t\t\tAssetManager.instance = new AssetManager();\n\t\t}\n\t\treturn AssetManager.instance;\n\t}\n\n\t/**\n\t * Reset the singleton (useful for testing)\n\t */\n\tstatic resetInstance(): void {\n\t\tif (AssetManager.instance) {\n\t\t\tAssetManager.instance.clearCache();\n\t\t\tAssetManager.instance = null;\n\t\t}\n\t}\n\n\t// ==================== TEXTURE LOADING ====================\n\n\t/**\n\t * Load a texture with caching\n\t */\n\tasync loadTexture(url: string, options?: TextureOptions): Promise<Texture> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.TEXTURE,\n\t\t\tthis.textureCache,\n\t\t\t() => this.textureLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(texture) => {\n\t\t\t\tif (!options?.clone) return texture;\n\t\t\t\tconst cloned = this.textureLoader.clone(texture);\n\t\t\t\t// Re-apply per-instance texture options to the clone so that\n\t\t\t\t// different callers sharing the same cached base texture can\n\t\t\t\t// use independent repeat / wrap values.\n\t\t\t\tif (options.repeat) {\n\t\t\t\t\tcloned.repeat.copy(options.repeat);\n\t\t\t\t}\n\t\t\t\tif (options.wrapS !== undefined) {\n\t\t\t\t\tcloned.wrapS = options.wrapS;\n\t\t\t\t}\n\t\t\t\tif (options.wrapT !== undefined) {\n\t\t\t\t\tcloned.wrapT = options.wrapT;\n\t\t\t\t}\n\t\t\t\treturn cloned;\n\t\t\t}\n\t\t);\n\t}\n\n\t// ==================== MODEL LOADING ====================\n\n\t/**\n\t * Load a GLTF/GLB model with caching\n\t */\n\tasync loadGLTF(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.GLTF,\n\t\t\tthis.modelCache,\n\t\t\t() => this.gltfLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.gltfLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an FBX model with caching\n\t */\n\tasync loadFBX(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.FBX,\n\t\t\tthis.modelCache,\n\t\t\t() => this.fbxLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.fbxLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an OBJ model with caching\n\t */\n\tasync loadOBJ(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Include mtlPath in cache key for OBJ files\n\t\tconst cacheKey = options?.mtlPath ? `${url}:${options.mtlPath}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.OBJ,\n\t\t\tthis.modelCache,\n\t\t\t() => this.objLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.objLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Auto-detect model type and load\n\t */\n\tasync loadModel(url: string, options?: AssetLoadOptions): Promise<ModelLoadResult> {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\t\n\t\tswitch (ext) {\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb':\n\t\t\t\treturn this.loadGLTF(url, options);\n\t\t\tcase 'fbx':\n\t\t\t\treturn this.loadFBX(url, options);\n\t\t\tcase 'obj':\n\t\t\t\treturn this.loadOBJ(url, options);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model format: ${ext}`);\n\t\t}\n\t}\n\n\t// ==================== AUDIO LOADING ====================\n\n\t/**\n\t * Load an audio buffer with caching\n\t */\n\tasync loadAudio(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.AUDIO,\n\t\t\tthis.audioCache,\n\t\t\t() => this.audioLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t// ==================== FILE LOADING ====================\n\n\t/**\n\t * Load a raw file with caching\n\t */\n\tasync loadFile(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst cacheKey = options?.responseType ? `${url}:${options.responseType}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.FILE,\n\t\t\tthis.fileCache,\n\t\t\t() => this.fileLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Load a JSON file with caching\n\t */\n\tasync loadJSON<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.JSON,\n\t\t\tthis.jsonCache,\n\t\t\t() => this.jsonLoader.load<T>(url, options),\n\t\t\toptions\n\t\t) as Promise<T>;\n\t}\n\n\t// ==================== BATCH LOADING ====================\n\n\t/**\n\t * Load multiple assets in parallel\n\t */\n\tasync loadBatch(items: BatchLoadItem[]): Promise<Map<string, any>> {\n\t\tconst results = new Map<string, any>();\n\t\t\n\t\tconst promises = items.map(async (item) => {\n\t\t\ttry {\n\t\t\t\tlet result: any;\n\t\t\t\t\n\t\t\t\tswitch (item.type) {\n\t\t\t\t\tcase AssetType.TEXTURE:\n\t\t\t\t\t\tresult = await this.loadTexture(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.GLTF:\n\t\t\t\t\t\tresult = await this.loadGLTF(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FBX:\n\t\t\t\t\t\tresult = await this.loadFBX(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.OBJ:\n\t\t\t\t\t\tresult = await this.loadOBJ(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.AUDIO:\n\t\t\t\t\t\tresult = await this.loadAudio(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FILE:\n\t\t\t\t\t\tresult = await this.loadFile(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.JSON:\n\t\t\t\t\t\tresult = await this.loadJSON(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`Unknown asset type: ${item.type}`);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tresults.set(item.url, result);\n\t\t\t} catch (error) {\n\t\t\t\tthis.events.emit('asset:error', {\n\t\t\t\t\turl: item.url,\n\t\t\t\t\ttype: item.type,\n\t\t\t\t\terror: error as Error\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t\t\n\t\tthis.events.emit('batch:complete', { urls: items.map(i => i.url) });\n\t\t\n\t\treturn results;\n\t}\n\n\t/**\n\t * Preload assets without returning results\n\t */\n\tasync preload(items: BatchLoadItem[]): Promise<void> {\n\t\tawait this.loadBatch(items);\n\t}\n\n\t// ==================== CACHE MANAGEMENT ====================\n\n\t/**\n\t * Check if an asset is cached\n\t */\n\tisCached(url: string): boolean {\n\t\treturn this.textureCache.has(url) ||\n\t\t\tthis.modelCache.has(url) ||\n\t\t\tthis.audioCache.has(url) ||\n\t\t\tthis.fileCache.has(url) ||\n\t\t\tthis.jsonCache.has(url);\n\t}\n\n\t/**\n\t * Clear all caches or a specific URL\n\t */\n\tclearCache(url?: string): void {\n\t\tif (url) {\n\t\t\tthis.textureCache.delete(url);\n\t\t\tthis.modelCache.delete(url);\n\t\t\tthis.audioCache.delete(url);\n\t\t\tthis.fileCache.delete(url);\n\t\t\tthis.jsonCache.delete(url);\n\t\t} else {\n\t\t\tthis.textureCache.clear();\n\t\t\tthis.modelCache.clear();\n\t\t\tthis.audioCache.clear();\n\t\t\tthis.fileCache.clear();\n\t\t\tthis.jsonCache.clear();\n\t\t\tCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetStats(): typeof this.stats {\n\t\treturn { ...this.stats };\n\t}\n\n\t// ==================== EVENTS ====================\n\n\t/**\n\t * Subscribe to asset manager events\n\t */\n\ton<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.on(event, handler);\n\t}\n\n\t/**\n\t * Unsubscribe from asset manager events\n\t */\n\toff<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.off(event, handler);\n\t}\n\n\t// ==================== PRIVATE HELPERS ====================\n\n\t/**\n\t * Generic cache wrapper for loading assets\n\t */\n\tprivate async loadWithCache<T>(\n\t\turl: string,\n\t\ttype: AssetType,\n\t\tcache: Map<string, CacheEntry<T>>,\n\t\tloader: () => Promise<T>,\n\t\toptions?: AssetLoadOptions,\n\t\tcloner?: (result: T) => T\n\t): Promise<T> {\n\t\t// Check for force reload\n\t\tif (options?.forceReload) {\n\t\t\tcache.delete(url);\n\t\t}\n\n\t\t// Check cache\n\t\tconst cached = cache.get(url);\n\t\tif (cached) {\n\t\t\tthis.stats.cacheHits++;\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: true });\n\t\t\t\n\t\t\tconst result = await cached.promise;\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t}\n\n\t\t// Cache miss - start loading\n\t\tthis.stats.cacheMisses++;\n\t\tthis.events.emit('asset:loading', { url, type });\n\n\t\tconst promise = loader();\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tpromise,\n\t\t\tloadedAt: Date.now()\n\t\t};\n\t\tcache.set(url, entry);\n\n\t\ttry {\n\t\t\tconst result = await promise;\n\t\t\tentry.result = result;\n\t\t\t\n\t\t\t// Update stats\n\t\t\tthis.updateStats(type);\n\t\t\t\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: false });\n\t\t\t\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t} catch (error) {\n\t\t\t// Remove failed entry from cache\n\t\t\tcache.delete(url);\n\t\t\tthis.events.emit('asset:error', { url, type, error: error as Error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate updateStats(type: AssetType): void {\n\t\tswitch (type) {\n\t\t\tcase AssetType.TEXTURE:\n\t\t\t\tthis.stats.texturesLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.GLTF:\n\t\t\tcase AssetType.FBX:\n\t\t\tcase AssetType.OBJ:\n\t\t\t\tthis.stats.modelsLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.AUDIO:\n\t\t\t\tthis.stats.audioLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.FILE:\n\t\t\tcase AssetType.JSON:\n\t\t\t\tthis.stats.filesLoaded++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Singleton instance export for convenience\n */\nexport const assetManager = AssetManager.getInstance();","/**\n * Texture loader adapter for the Asset Manager\n */\n\nimport { TextureLoader, Texture, RepeatWrapping, Vector2, Wrapping } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface TextureOptions extends AssetLoadOptions {\n\trepeat?: Vector2;\n\twrapS?: Wrapping;\n\twrapT?: Wrapping;\n}\n\nexport class TextureLoaderAdapter implements LoaderAdapter<Texture> {\n\tprivate loader: TextureLoader;\n\n\tconstructor() {\n\t\tthis.loader = new TextureLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'tga'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: TextureOptions): Promise<Texture> {\n\t\tconst texture = await this.loader.loadAsync(url, (event) => {\n\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t}\n\t\t});\n\n\t\t// Apply texture options\n\t\tif (options?.repeat) {\n\t\t\ttexture.repeat.copy(options.repeat);\n\t\t}\n\t\ttexture.wrapS = options?.wrapS ?? RepeatWrapping;\n\t\ttexture.wrapT = options?.wrapT ?? RepeatWrapping;\n\n\t\treturn texture;\n\t}\n\n\t/**\n\t * Clone a texture for independent usage\n\t */\n\tclone(texture: Texture): Texture {\n\t\tconst cloned = texture.clone();\n\t\tcloned.needsUpdate = true;\n\t\treturn cloned;\n\t}\n}\n","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface GLTFLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parseAsync pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers, so this mainly\n\t * provides a cleaner async/await pattern rather than performance gains\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class GLTFLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: GLTFLoader;\n\n\tconstructor() {\n\t\tthis.loader = new GLTFLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['gltf', 'glb'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parseAsync\n\t * Both fetch and parsing are async, keeping the main thread responsive\n\t */\n\tprivate async loadWithAsyncFetch(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using GLTFLoader.parseAsync\n\t\t\t// The url is passed as the path for resolving relative resources\n\t\t\tconst gltf = await this.loader.parseAsync(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject: gltf.scene,\n\t\t\t\tanimations: gltf.animations,\n\t\t\t\tgltf\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch GLTF load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(gltf: GLTF) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject: gltf.scene,\n\t\t\t\t\t\tanimations: gltf.animations,\n\t\t\t\t\t\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded GLTF scene for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone()),\n\t\t\tgltf: result.gltf\n\t\t};\n\t}\n}\n","/**\n * FBX loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parse\n */\n\nimport { Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface FBXLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parse pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class FBXLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: FBXLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FBXLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'fbx';\n\t}\n\n\tasync load(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parse\n\t */\n\tprivate async loadWithAsyncFetch(url: string, _options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using FBXLoader.parse\n\t\t\tconst object = this.loader.parse(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject,\n\t\t\t\tanimations: (object as any).animations || []\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch FBX load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, _options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: (object as any).animations || []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded FBX object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone())\n\t\t};\n\t}\n}\n","/**\n * OBJ loader adapter for the Asset Manager\n * Supports optional MTL (material) file loading\n */\n\nimport { Object3D, Group } from 'three';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { MTLLoader } from 'three/addons/loaders/MTLLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface OBJLoadOptions extends AssetLoadOptions {\n\t/** Path to MTL material file */\n\tmtlPath?: string;\n}\n\nexport class OBJLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: OBJLoader;\n\tprivate mtlLoader: MTLLoader;\n\n\tconstructor() {\n\t\tthis.loader = new OBJLoader();\n\t\tthis.mtlLoader = new MTLLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'obj';\n\t}\n\n\tasync load(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Load MTL first if provided\n\t\tif (options?.mtlPath) {\n\t\t\tawait this.loadMTL(options.mtlPath);\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Group) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async loadMTL(url: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.mtlLoader.load(\n\t\t\t\turl,\n\t\t\t\t(materials) => {\n\t\t\t\t\tmaterials.preload();\n\t\t\t\t\tthis.loader.setMaterials(materials);\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded OBJ object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: []\n\t\t};\n\t}\n}\n","/**\n * Audio loader adapter for the Asset Manager\n */\n\nimport { AudioLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport class AudioLoaderAdapter implements LoaderAdapter<AudioBuffer> {\n\tprivate loader: AudioLoader;\n\n\tconstructor() {\n\t\tthis.loader = new AudioLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['mp3', 'ogg', 'wav', 'flac', 'aac', 'm4a'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(buffer) => resolve(buffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n","/**\n * File loader adapter for the Asset Manager\n */\n\nimport { FileLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface FileLoadOptions extends AssetLoadOptions {\n\tresponseType?: 'text' | 'arraybuffer' | 'blob' | 'json';\n}\n\nexport class FileLoaderAdapter implements LoaderAdapter<string | ArrayBuffer> {\n\tprivate loader: FileLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FileLoader();\n\t}\n\n\tisSupported(_url: string): boolean {\n\t\t// FileLoader can handle any file type\n\t\treturn true;\n\t}\n\n\tasync load(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst responseType = options?.responseType ?? 'text';\n\t\tthis.loader.setResponseType(responseType as any);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(data) => resolve(data as string | ArrayBuffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n\n/**\n * JSON loader using FileLoader\n */\nexport class JsonLoaderAdapter implements LoaderAdapter<unknown> {\n\tprivate fileLoader: FileLoaderAdapter;\n\n\tconstructor() {\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'json';\n\t}\n\n\tasync load<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\tconst data = await this.fileLoader.load(url, { ...options, responseType: 'json' });\n\t\treturn data as T;\n\t}\n}\n","/**\n * Entity Asset Loader - Refactored to use AssetManager\n * \n * This module provides a compatibility layer for existing code that uses EntityAssetLoader.\n * All loading now goes through the centralized AssetManager for caching.\n */\n\nimport { AnimationClip, Object3D } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport { assetManager } from './asset-manager';\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\n/**\n * EntityAssetLoader - Uses AssetManager for all model loading\n * \n * This class is now a thin wrapper around AssetManager, providing backward\n * compatibility for existing code while benefiting from centralized caching.\n */\nexport class EntityAssetLoader {\n\t/**\n\t * Load a model file (FBX, GLTF, GLB, OBJ) using the asset manager\n\t */\n\tasync loadFile(file: string): Promise<AssetLoaderResult> {\n\t\tconst ext = file.split('.').pop()?.toLowerCase();\n\n\t\tswitch (ext) {\n\t\t\tcase 'fbx': {\n\t\t\t\tconst result = await assetManager.loadFBX(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tanimation: result.animations?.[0]\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb': {\n\t\t\t\tconst result = await assetManager.loadGLTF(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tgltf: result.gltf\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'obj': {\n\t\t\t\tconst result = await assetManager.loadOBJ(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\t}\n}\n","import {\n\tAnimationAction,\n\tAnimationClip,\n\tAnimationMixer,\n\tLoopOnce,\n\tLoopRepeat,\n\tObject3D,\n} from 'three';\nimport { EntityAssetLoader, AssetLoaderResult } from '../../core/entity-asset-loader';\n\nexport type AnimationOptions = {\n\tkey: string;\n\tpauseAtEnd?: boolean;\n\tpauseAtPercentage?: number;\n\tfadeToKey?: string;\n\tfadeDuration?: number;\n};\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport class AnimationDelegate {\n\tprivate _mixer: AnimationMixer | null = null;\n\tprivate _actions: Record<string, AnimationAction> = {};\n\tprivate _animations: AnimationClip[] = [];\n\tprivate _currentAction: AnimationAction | null = null;\n\n\tprivate _pauseAtPercentage = 0;\n\tprivate _isPaused = false;\n\tprivate _queuedKey: string | null = null;\n\tprivate _fadeDuration = 0.5;\n\n\tprivate _currentKey: string = '';\n\tprivate _assetLoader = new EntityAssetLoader();\n\n\tconstructor(private target: Object3D) { }\n\n\tasync loadAnimations(animations: AnimationObject[]): Promise<void> {\n\t\tif (!animations.length) return;\n\n\t\tconst results = await Promise.all(animations.map(a => this._assetLoader.loadFile(a.path)));\n\t\t\n\t\t// Build animations list while preserving original key mapping\n\t\t// Filter to only successful loads and pair with their original keys\n\t\tconst loadedAnimations: { key: string; clip: AnimationClip }[] = [];\n\t\tresults.forEach((result, i) => {\n\t\t\tif (result.animation) {\n\t\t\t\tloadedAnimations.push({\n\t\t\t\t\tkey: animations[i].key || i.toString(),\n\t\t\t\t\tclip: result.animation\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif (!loadedAnimations.length) return;\n\n\t\tthis._animations = loadedAnimations.map(a => a.clip);\n\t\tthis._mixer = new AnimationMixer(this.target);\n\t\t\n\t\t// Create actions with correct key mapping\n\t\tloadedAnimations.forEach(({ key, clip }) => {\n\t\t\tthis._actions[key] = this._mixer!.clipAction(clip);\n\t\t});\n\n\t\tthis.playAnimation({ key: loadedAnimations[0].key });\n\t}\n\n\tupdate(delta: number): void {\n\t\tif (!this._mixer || !this._currentAction) return;\n\n\t\tthis._mixer.update(delta);\n\n\t\tconst pauseAtTime = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);\n\t\tif (\n\t\t\t!this._isPaused &&\n\t\t\tthis._pauseAtPercentage > 0 &&\n\t\t\tthis._currentAction.time >= pauseAtTime\n\t\t) {\n\t\t\tthis._currentAction.time = pauseAtTime;\n\t\t\tthis._currentAction.paused = true;\n\t\t\tthis._isPaused = true;\n\n\t\t\tif (this._queuedKey !== null) {\n\t\t\t\tconst next = this._actions[this._queuedKey];\n\t\t\t\tnext.reset().play();\n\t\t\t\tthis._currentAction.crossFadeTo(next, this._fadeDuration, false);\n\t\t\t\tthis._currentAction = next;\n\t\t\t\tthis._currentKey = this._queuedKey;\n\t\t\t\tthis._queuedKey = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tplayAnimation(opts: AnimationOptions): void {\n\t\tif (!this._mixer) return;\n\t\tconst { key, pauseAtPercentage = 0, pauseAtEnd = false, fadeToKey, fadeDuration = 0.5 } = opts;\n\t\tif (key === this._currentKey) return;\n\n\t\t// Check if the new action exists BEFORE stopping the current animation\n\t\t// This prevents T-posing when an animation key doesn't exist\n\t\tconst action = this._actions[key];\n\t\tif (!action) return;\n\n\t\tthis._queuedKey = fadeToKey || null;\n\t\tthis._fadeDuration = fadeDuration;\n\n\t\tthis._pauseAtPercentage = pauseAtEnd ? 100 : pauseAtPercentage;\n\t\tthis._isPaused = false;\n\n\t\tconst prev = this._currentAction;\n\t\t// Don't stop prev here - crossFadeTo needs it playing for smooth transition\n\n\t\tif (this._pauseAtPercentage > 0) {\n\t\t\taction.setLoop(LoopOnce, Infinity);\n\t\t\taction.clampWhenFinished = true;\n\t\t} else {\n\t\t\taction.setLoop(LoopRepeat, Infinity);\n\t\t\taction.clampWhenFinished = false;\n\t\t}\n\n\t\t// Start the new action\n\t\taction.reset().play();\n\n\t\t// Crossfade from previous if it exists\n\t\tif (prev) {\n\t\t\tprev.crossFadeTo(action, fadeDuration, false);\n\t\t}\n\n\t\tthis._currentAction = action;\n\t\tthis._currentKey = key;\n\t}\n\n\t/**\n\t * Dispose of all animation resources\n\t */\n\tdispose(): void {\n\t\t// Stop all actions\n\t\tObject.values(this._actions).forEach(action => {\n\t\t\taction.stop();\n\t\t});\n\n\t\t// Stop and uncache mixer\n\t\tif (this._mixer) {\n\t\t\tthis._mixer.stopAllAction();\n\t\t\tthis._mixer.uncacheRoot(this.target);\n\t\t\tthis._mixer = null;\n\t\t}\n\n\t\t// Clear references\n\t\tthis._actions = {};\n\t\tthis._animations = [];\n\t\tthis._currentAction = null;\n\t\tthis._currentKey = '';\n\t}\n\n\tget currentAnimationKey() { return this._currentKey; }\n\tget animations() { return this._animations; }\n}\n","import { Color, Material, Vector2, Vector3 } from 'three';\nimport {\n\tMeshPhongMaterial,\n\tMeshStandardMaterial,\n\tRepeatWrapping,\n\tShaderMaterial,\n} from 'three';\nimport {\n\tMeshBasicNodeMaterial,\n\tMeshStandardNodeMaterial,\n} from 'three/webgpu';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\nimport { standardShader } from './shaders/standard.shader';\nimport { assetManager } from '../core/asset-manager';\n\n/**\n * GLSL shader object (traditional approach for WebGL)\n */\nexport type ZylemShaderObject = { fragment: string; vertex: string };\n\n/**\n * TSL shader type (for WebGPU)\n * colorNode should be a TSL node that returns the fragment color\n */\nexport type ZylemTSLShader = {\n\tcolorNode: any; // TSL node - use any since Three.js types are still evolving\n\ttransparent?: boolean;\n};\n\n/**\n * Combined shader type supporting both GLSL and TSL\n */\nexport type ZylemShader = ZylemShaderObject | ZylemTSLShader;\n\n/**\n * Check if a shader is a TSL shader\n */\nexport function isTSLShader(shader: ZylemShader): shader is ZylemTSLShader {\n\treturn 'colorNode' in shader;\n}\n\n/**\n * Check if a shader is a GLSL shader\n */\nexport function isGLSLShader(shader: ZylemShader): shader is ZylemShaderObject {\n\treturn 'fragment' in shader && 'vertex' in shader;\n}\n\nexport interface MaterialOptions {\n\tpath?: string;\n\tnormalMap?: string;\n\trepeat?: Vector2;\n\tshader?: ZylemShader;\n\tcolor?: Color;\n\t/**\n\t * When true, prefer TSL/NodeMaterial (for WebGPU)\n\t * When false, prefer GLSL/ShaderMaterial (for WebGL)\n\t */\n\tuseTSL?: boolean;\n}\n\ntype BatchGeometryMap = Map<symbol, number>;\n\ninterface BatchMaterialMapObject {\n\tgeometryMap: BatchGeometryMap;\n\tmaterial: Material;\n}\n\ntype BatchKey = ReturnType<typeof shortHash>;\n\nexport type TexturePath = string | null;\n\nexport class MaterialBuilder {\n\tstatic batchMaterialMap: Map<BatchKey, BatchMaterialMapObject> = new Map();\n\n\tmaterials: Material[] = [];\n\n\t/** Whether to use TSL/NodeMaterial (for WebGPU compatibility) */\n\tprivate useTSL: boolean;\n\n\tconstructor(useTSL: boolean = false) {\n\t\tthis.useTSL = useTSL;\n\t}\n\n\tbatchMaterial(options: Partial<MaterialOptions>, entityType: symbol) {\n\t\tconst batchKey = shortHash(sortedStringify(options));\n\t\tconst mappedObject = MaterialBuilder.batchMaterialMap.get(batchKey);\n\t\tif (mappedObject) {\n\t\t\tconst count = mappedObject.geometryMap.get(entityType);\n\t\t\tif (count) {\n\t\t\t\tmappedObject.geometryMap.set(entityType, count + 1);\n\t\t\t} else {\n\t\t\t\tmappedObject.geometryMap.set(entityType, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tMaterialBuilder.batchMaterialMap.set(batchKey, {\n\t\t\t\tgeometryMap: new Map([[entityType, 1]]),\n\t\t\t\tmaterial: this.materials[0],\n\t\t\t});\n\t\t}\n\t}\n\n\tbuild(options: Partial<MaterialOptions>, entityType: symbol): void {\n\t\tconst { path, normalMap, repeat, color, shader, useTSL } = options;\n\t\t\n\t\t// Override TSL preference if specified in options\n\t\tconst shouldUseTSL = useTSL ?? this.useTSL;\n\n\t\t// If shader is provided, use it\n\t\tif (shader) {\n\t\t\tif (isTSLShader(shader)) {\n\t\t\t\t// TSL shader provided directly\n\t\t\t\tthis.setTSLShader(shader);\n\t\t\t} else if (isGLSLShader(shader)) {\n\t\t\t\t// GLSL shader provided\n\t\t\t\tif (shouldUseTSL) {\n\t\t\t\t\tconsole.warn('MaterialBuilder: GLSL shader provided but TSL mode requested. Using GLSL.');\n\t\t\t\t}\n\t\t\t\tthis.setShader(shader);\n\t\t\t}\n\t\t} else if (path) {\n\t\t\t// Texture path provided\n\t\t\tthis.setTexture(path, repeat, shouldUseTSL);\n\t\t}\n\n\t\tif (color) {\n\t\t\tthis.withColor(color, shouldUseTSL);\n\t\t}\n\n\t\tif (this.materials.length === 0) {\n\t\t\tthis.setColor(new Color('#ffffff'), shouldUseTSL);\n\t\t}\n\n\t\t// Apply normal map if present (to the last added material)\n\t\tif (normalMap && this.materials.length > 0) {\n\t\t\tthis.setNormalMap(normalMap, repeat);\n\t\t}\n\n\t\tthis.batchMaterial(options, entityType);\n\t}\n\n\twithColor(color: Color, useTSL: boolean = false): this {\n\t\tthis.setColor(color, useTSL);\n\t\treturn this;\n\t}\n\n\twithShader(shader: ZylemShaderObject): this {\n\t\tthis.setShader(shader);\n\t\treturn this;\n\t}\n\n\twithTSLShader(shader: ZylemTSLShader): this {\n\t\tthis.setTSLShader(shader);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set texture - loads in background (deferred).\n\t * Material is created immediately with null map, texture applies when loaded.\n\t */\n\tsetTexture(texturePath: TexturePath = null, repeat: Vector2 = new Vector2(1, 1), useTSL: boolean = false): void {\n\t\tif (!texturePath) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (useTSL) {\n\t\t\t// For TSL/WebGPU, use NodeMaterial\n\t\t\tconst material = new MeshStandardNodeMaterial();\n\t\t\tthis.materials.push(material);\n\n\t\t\t// Load texture in background and apply when ready\n\t\t\tassetManager.loadTexture(texturePath as string, {\n\t\t\t\tclone: true,\n\t\t\t\trepeat,\n\t\t\t}).then((texture) => {\n\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\tmaterial.map = texture;\n\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t});\n\t\t} else {\n\t\t\t// For WebGL, use traditional material\n\t\t\tconst material = new MeshPhongMaterial({\n\t\t\t\tmap: null,\n\t\t\t});\n\t\t\tthis.materials.push(material);\n\n\t\t\t// Load texture in background and apply when ready\n\t\t\tassetManager\n\t\t\t\t.loadTexture(texturePath as string, {\n\t\t\t\t\tclone: true,\n\t\t\t\t\trepeat,\n\t\t\t\t})\n\t\t\t\t.then((texture) => {\n\t\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\t\tmaterial.map = texture;\n\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Set normal map for the current material\n\t */\n\tsetNormalMap(normalMapPath: string, repeat: Vector2 = new Vector2(1, 1)): void {\n\t\tconst material = this.materials[this.materials.length - 1];\n\t\tif (!material) return;\n\n\t\tassetManager\n\t\t\t.loadTexture(normalMapPath, {\n\t\t\t\tclone: true,\n\t\t\t\trepeat,\n\t\t\t})\n\t\t\t.then((texture) => {\n\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\t\n\t\t\t\tif (material instanceof MeshStandardMaterial \n\t\t\t\t\t|| material instanceof MeshPhongMaterial\n\t\t\t\t\t|| material instanceof MeshStandardNodeMaterial) {\n\t\t\t\t\tmaterial.normalMap = texture;\n\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t} else if (material instanceof ShaderMaterial) {\n\t\t\t\t\t// Support for custom shaders if they have tNormal or normalMap uniform\n\t\t\t\t\tif (material.uniforms.tNormal) {\n\t\t\t\t\t\tmaterial.uniforms.tNormal.value = texture;\n\t\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (material.uniforms.normalMap) {\n\t\t\t\t\t\tmaterial.uniforms.normalMap.value = texture;\n\t\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tsetColor(color: Color, useTSL: boolean = false) {\n\t\tif (useTSL) {\n\t\t\t// TSL/WebGPU compatible material\n\t\t\tconst material = new MeshStandardNodeMaterial();\n\t\t\tmaterial.color = color;\n\t\t\tthis.materials.push(material);\n\t\t} else {\n\t\t\t// WebGL compatible material\n\t\t\tconst material = new MeshStandardMaterial({\n\t\t\t\tcolor: color,\n\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\tfog: true,\n\t\t\t});\n\t\t\tthis.materials.push(material);\n\t\t}\n\t}\n\n\t/**\n\t * Set GLSL shader (WebGL only)\n\t */\n\tsetShader(customShader: ZylemShaderObject) {\n\t\tconst { fragment, vertex } = customShader ?? standardShader;\n\n\t\tconst shader = new ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiResolution: { value: new Vector3(1, 1, 1) },\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tnormalMap: { value: null },\n\t\t\t\tlightDir: { value: new Vector3(1, 1, 1) },\n\t\t\t\tnormalStrength: { value: 1.0 },\n\t\t\t},\n\t\t\tvertexShader: vertex,\n\t\t\tfragmentShader: fragment,\n\t\t\ttransparent: true,\n\t\t});\n\t\tthis.materials.push(shader);\n\t}\n\n\t/**\n\t * Set TSL shader (WebGPU compatible)\n\t */\n\tsetTSLShader(tslShader: ZylemTSLShader) {\n\t\tconst material = new MeshBasicNodeMaterial();\n\t\tmaterial.colorNode = tslShader.colorNode;\n\t\tif (tslShader.transparent) {\n\t\t\tmaterial.transparent = true;\n\t\t}\n\t\tthis.materials.push(material);\n\t}\n}\n\n// Re-export TSL utilities for shader authoring\nexport {\n\tuniform,\n\tuv,\n\ttime,\n\tvec3,\n\tvec4,\n\tfloat,\n\tFn,\n} from 'three/tsl';\n","export function sortedStringify(obj: Record<string, any>) {\n\tconst sortedObj = Object.keys(obj)\n\t\t.sort()\n\t\t.reduce((acc: Record<string, any>, key: string) => {\n\t\t\tacc[key] = obj[key];\n\t\t\treturn acc;\n\t\t}, {} as Record<string, any>);\n\n\treturn JSON.stringify(sortedObj);\n}\n\nexport function shortHash(objString: string) {\n\tlet hash = 0;\n\tfor (let i = 0; i < objString.length; i++) {\n\t\thash = Math.imul(31, hash) + objString.charCodeAt(i) | 0;\n\t}\n\treturn hash.toString(36);\n}","import {\n\tScene,\n\tColor,\n\tAmbientLight,\n\tDirectionalLight,\n\tObject3D,\n\tVector3,\n\tGridHelper,\n\tBoxGeometry,\n\tShaderMaterial,\n\tMesh,\n\tBackSide,\n\tMaterial,\n\tTexture,\n\tLight,\n} from 'three';\nimport { MeshBasicNodeMaterial } from 'three/webgpu';\nimport { Entity, LifecycleFunction } from '../interfaces/entity';\nimport { GameEntity } from '../entities/entity';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { CameraManager } from '../camera/camera-manager';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { debugState } from '../debug/debug-state';\nimport { SetupFunction } from '../core/base-node-life-cycle';\nimport { getGlobals } from '../game/game-state';\nimport { assetManager } from '../core/asset-manager';\nimport { ZylemShader, isTSLShader, isGLSLShader } from './material';\n\ninterface SceneState {\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader?: ZylemShader | null;\n}\n\nexport class ZylemScene implements Entity<ZylemScene> {\n\tpublic type = 'Scene';\n\n\t_setup?: SetupFunction<ZylemScene>;\n\tscene!: Scene;\n\t/** @deprecated Use cameraManager instead */\n\tzylemCamera!: ZylemCamera;\n\tcameraManager: CameraManager | null = null;\n\tcontainerElement: HTMLElement | null = null;\n\tupdate: LifecycleFunction<ZylemScene> = () => { };\n\t_collision?: ((entity: any, other: any, globals?: any) => void) | undefined;\n\t_destroy?: ((globals?: any) => void) | undefined;\n\tname?: string | undefined;\n\ttag?: Set<string> | undefined;\n\n\t// Skybox for background shaders (supports both GLSL ShaderMaterial and TSL MeshBasicNodeMaterial)\n\tprivate skyboxMaterial: Material | null = null;\n\n\tconstructor(id: string, camera: ZylemCamera, state: SceneState) {\n\t\tconst scene = new Scene();\n\t\tconst isColor = state.backgroundColor instanceof Color;\n\t\tconst backgroundColor = (isColor) ? state.backgroundColor : new Color(state.backgroundColor);\n\t\tscene.background = backgroundColor as Color;\n\t\t\n\t\tconsole.log('ZylemScene state.backgroundShader:', state.backgroundShader);\n\t\t\n\t\tif (state.backgroundShader) {\n\t\t\tthis.setupBackgroundShader(scene, state.backgroundShader);\n\t\t} else if (state.backgroundImage) {\n\t\t\t// Load background image asynchronously via asset manager\n\t\t\tassetManager.loadTexture(state.backgroundImage).then(texture => {\n\t\t\t\tscene.background = texture;\n\t\t\t});\n\t\t}\n\n\t\tthis.scene = scene;\n\t\tthis.zylemCamera = camera;\n\n\t\tthis.setupLighting(scene);\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugScene();\n\t\t}\n\t}\n\n\t/**\n\t * Create a large inverted box with the shader for skybox effect\n\t * Supports both GLSL (ShaderMaterial) and TSL (MeshBasicNodeMaterial) shaders\n\t */\n\tprivate setupBackgroundShader(scene: Scene, shader: ZylemShader) {\n\t\t// Clear the solid color background\n\t\tscene.background = null;\n\n\t\tif (isTSLShader(shader)) {\n\t\t\t// TSL shader - use MeshBasicNodeMaterial for WebGPU\n\t\t\tthis.skyboxMaterial = new MeshBasicNodeMaterial();\n\t\t\t(this.skyboxMaterial as MeshBasicNodeMaterial).colorNode = shader.colorNode;\n\t\t\tif (shader.transparent) {\n\t\t\t\tthis.skyboxMaterial.transparent = true;\n\t\t\t}\n\t\t\tthis.skyboxMaterial.side = BackSide;\n\t\t\tthis.skyboxMaterial.depthWrite = false;\n\t\t\tconsole.log('Skybox created with TSL shader');\n\t\t} else if (isGLSLShader(shader)) {\n\t\t\t// GLSL shader - use ShaderMaterial for WebGL\n\t\t\t// Skybox vertex shader with depth trick (pos.xyww ensures depth = 1.0)\n\t\t\tconst skyboxVertexShader = `\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvarying vec3 vWorldPosition;\n\t\t\t\t\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tvec4 worldPosition = modelMatrix * vec4(position, 1.0);\n\t\t\t\t\tvWorldPosition = worldPosition.xyz;\n\t\t\t\t\tvec4 pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n\t\t\t\t\tgl_Position = pos.xyww; // Ensures depth is always 1.0 (farthest)\n\t\t\t\t}\n\t\t\t`;\n\n\t\t\t// Create shader material with skybox-specific settings\n\t\t\tthis.skyboxMaterial = new ShaderMaterial({\n\t\t\t\tvertexShader: skyboxVertexShader,\n\t\t\t\tfragmentShader: shader.fragment,\n\t\t\t\tuniforms: {\n\t\t\t\t\tiTime: { value: 0.0 },\n\t\t\t\t},\n\t\t\t\tside: BackSide, // Render on inside of geometry\n\t\t\t\tdepthWrite: false, // Don't write to depth buffer\n\t\t\t\tdepthTest: true, // But do test depth\n\t\t\t});\n\t\t\tconsole.log('Skybox created with GLSL shader');\n\t\t}\n\n\t\t// Use BoxGeometry for skybox\n\t\tconst geometry = new BoxGeometry(1, 1, 1);\n\t\tconst skybox = new Mesh(geometry, this.skyboxMaterial!);\n\t\tskybox.scale.setScalar(100000); // Scale up significantly\n\t\tskybox.frustumCulled = false; // Always render\n\t\tscene.add(skybox);\n\t}\n\n\tsetup() {\n\t\tif (this._setup) {\n\t\t\tthis._setup({ me: this, camera: this.zylemCamera, globals: getGlobals() });\n\t\t}\n\t}\n\n\tdestroy() {\n\t\t// Destroy via camera manager if available, otherwise legacy single camera\n\t\tif (this.cameraManager) {\n\t\t\tthis.cameraManager.dispose();\n\t\t\tthis.cameraManager = null;\n\t\t} else if (this.zylemCamera && (this.zylemCamera as any).destroy) {\n\t\t\t(this.zylemCamera as any).destroy();\n\t\t}\n\t\tif (this.skyboxMaterial) {\n\t\t\tthis.skyboxMaterial.dispose();\n\t\t}\n\t\tif (this.scene) {\n\t\t\t// Dispose background texture if present\n\t\t\tif (this.scene.background instanceof Texture) {\n\t\t\t\tthis.scene.background.dispose();\n\t\t\t\tthis.scene.background = null;\n\t\t\t}\n\n\t\t\tthis.scene.traverse((obj: any) => {\n\t\t\t\tif (obj.geometry) {\n\t\t\t\t\tobj.geometry.dispose?.();\n\t\t\t\t}\n\t\t\t\tif (obj.material) {\n\t\t\t\t\tconst materials = Array.isArray(obj.material) ? obj.material : [obj.material];\n\t\t\t\t\tfor (const mat of materials) {\n\t\t\t\t\t\t// Dispose all texture maps on the material\n\t\t\t\t\t\tif (mat.map) mat.map.dispose?.();\n\t\t\t\t\t\tif (mat.normalMap) mat.normalMap.dispose?.();\n\t\t\t\t\t\tif (mat.aoMap) mat.aoMap.dispose?.();\n\t\t\t\t\t\tif (mat.emissiveMap) mat.emissiveMap.dispose?.();\n\t\t\t\t\t\tif (mat.roughnessMap) mat.roughnessMap.dispose?.();\n\t\t\t\t\t\tif (mat.metalnessMap) mat.metalnessMap.dispose?.();\n\t\t\t\t\t\tif (mat.envMap) mat.envMap.dispose?.();\n\t\t\t\t\t\tif (mat.lightMap) mat.lightMap.dispose?.();\n\t\t\t\t\t\tif (mat.bumpMap) mat.bumpMap.dispose?.();\n\t\t\t\t\t\tif (mat.displacementMap) mat.displacementMap.dispose?.();\n\t\t\t\t\t\tif (mat.alphaMap) mat.alphaMap.dispose?.();\n\t\t\t\t\t\tmat.dispose?.();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Dispose shadow map render targets on lights\n\t\t\t\tif ((obj as Light).isLight && (obj as any).shadow?.map) {\n\t\t\t\t\t(obj as any).shadow.map.dispose();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.scene.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Setup camera with the scene.\n\t * Supports both legacy single camera and CameraManager modes.\n\t */\n\tsetupCamera(scene: Scene, camera: ZylemCamera, rendererManager?: RendererManager) {\n\t\t// Add camera rig or camera directly to scene\n\t\tthis.addCameraToScene(scene, camera);\n\n\t\tif (rendererManager) {\n\t\t\t// New path: camera setup with shared renderer manager\n\t\t\tcamera.setup(scene, rendererManager);\n\t\t} else {\n\t\t\t// Legacy path: camera handles its own renderer\n\t\t\tcamera.setupLegacy(scene);\n\t\t}\n\t}\n\n\t/**\n\t * Setup with a CameraManager (multi-camera support).\n\t */\n\tasync setupCameraManager(scene: Scene, cameraManager: CameraManager, rendererManager: RendererManager): Promise<void> {\n\t\tthis.cameraManager = cameraManager;\n\n\t\t// Add all active cameras to the scene\n\t\tfor (const camera of cameraManager.activeCameras) {\n\t\t\tthis.addCameraToScene(scene, camera);\n\t\t}\n\n\t\t// Setup the camera manager (initializes all cameras)\n\t\tawait cameraManager.setup(scene, rendererManager);\n\t}\n\n\t/**\n\t * Add a camera (rig or direct) to the scene graph.\n\t */\n\tprivate addCameraToScene(scene: Scene, camera: ZylemCamera): void {\n\t\tif (camera.cameraRig) {\n\t\t\tscene.add(camera.cameraRig);\n\t\t} else {\n\t\t\tscene.add(camera.camera as Object3D);\n\t\t}\n\t}\n\n\t/**\n\t * Setup scene lighting\n\t */\n\tsetupLighting(scene: Scene) {\n\t\tconst ambientLight = new AmbientLight(0xffffff, 2);\n\t\tscene.add(ambientLight);\n\n\t\tconst directionalLight = new DirectionalLight(0xffffff, 2);\n\t\tdirectionalLight.name = 'Light';\n\t\tdirectionalLight.position.set(0, 100, 0);\n\t\tdirectionalLight.castShadow = true;\n\t\tdirectionalLight.shadow.camera.near = 0.1;\n\t\tdirectionalLight.shadow.camera.far = 2000;\n\t\tdirectionalLight.shadow.camera.left = -100;\n\t\tdirectionalLight.shadow.camera.right = 100;\n\t\tdirectionalLight.shadow.camera.top = 100;\n\t\tdirectionalLight.shadow.camera.bottom = -100;\n\t\tdirectionalLight.shadow.mapSize.width = 2048;\n\t\tdirectionalLight.shadow.mapSize.height = 2048;\n\t\tscene.add(directionalLight);\n\t}\n\n\t/**\n\t * Update renderer size - delegates to camera manager or camera\n\t */\n\tupdateRenderer(width: number, height: number) {\n\t\tif (this.cameraManager) {\n\t\t\t// Resize all cameras\n\t\t\tfor (const camera of this.cameraManager.allCameras) {\n\t\t\t\tcamera.resize(width, height);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.zylemCamera.resize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Add object to scene\n\t */\n\tadd(object: Object3D, position: Vector3 = new Vector3(0, 0, 0)) {\n\t\tobject.position.set(position.x, position.y, position.z);\n\t\tthis.scene.add(object);\n\t}\n\n\t/**\n\t * Add game entity to scene\n\t */\n\taddEntity(entity: GameEntity<any>) {\n\t\tif (entity.group) {\n\t\t\tthis.add(entity.group, entity.options.position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, entity.options.position);\n\t\t}\n\t}\n\n\t/**\n\t * Add an entity's group or mesh to the scene (for late-loaded models).\n\t * Uses entity's current body position if physics is active.\n\t */\n\taddEntityGroup(entity: GameEntity<any>): void {\n\t\tconst position = entity.body\n\t\t\t? new Vector3(\n\t\t\t\tentity.body.translation().x,\n\t\t\t\tentity.body.translation().y,\n\t\t\t\tentity.body.translation().z\n\t\t\t )\n\t\t\t: entity.options.position;\n\n\t\tif (entity.group) {\n\t\t\tthis.add(entity.group, position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, position);\n\t\t}\n\t}\n\n\t/**\n\t * Add debug helpers to scene\n\t */\n\tdebugScene() {\n\t\tconst size = 1000;\n\t\tconst divisions = 100;\n\n\t\tconst gridHelper = new GridHelper(size, divisions);\n\t\tthis.scene.add(gridHelper);\n\t}\n\n\t/**\n\t * Update skybox shader uniforms (only applies to GLSL ShaderMaterial)\n\t * TSL shaders use the time node which auto-updates\n\t */\n\tupdateSkybox(delta: number) {\n\t\tif (this.skyboxMaterial && this.skyboxMaterial instanceof ShaderMaterial) {\n\t\t\tif (this.skyboxMaterial.uniforms?.iTime) {\n\t\t\t\tthis.skyboxMaterial.uniforms.iTime.value += delta;\n\t\t\t}\n\t\t}\n\t}\n}\n","import { proxy } from 'valtio';\nimport type { GameEntity } from '../entities/entity';\n\nexport type DebugTools = 'select' | 'translate' | 'rotate' | 'scale' | 'delete' | 'none';\n\nexport interface DebugState {\n\tenabled: boolean;\n\tpaused: boolean;\n\ttool: DebugTools;\n\tselectedEntity: GameEntity<any> | null;\n\thoveredEntity: GameEntity<any> | null;\n\tflags: Set<string>;\n}\n\nexport const debugState = proxy<DebugState>({\n\tenabled: false,\n\tpaused: false,\n\ttool: 'none',\n\tselectedEntity: null,\n\thoveredEntity: null,\n\tflags: new Set(),\n});\n\nexport function isPaused(): boolean {\n\treturn debugState.paused;\n}\n\nexport function setPaused(paused: boolean): void {\n\tdebugState.paused = paused;\n}\n\nexport function setDebugFlag(flag: string, value: boolean): void {\n\tif (value) {\n\t\tdebugState.flags.add(flag);\n\t} else {\n\t\tdebugState.flags.delete(flag);\n\t}\n}\n\nexport function getDebugTool(): DebugTools {\n\treturn debugState.tool;\n}\n\nexport function setDebugTool(tool: DebugTools): void {\n\tdebugState.tool = tool;\n}\n\nexport function getSelectedEntity(): GameEntity<any> | null {\n\treturn debugState.selectedEntity;\n}\n\nexport function setSelectedEntity(entity: GameEntity<any> | null): void {\n\tdebugState.selectedEntity = entity;\n}\n\nexport function getHoveredEntity(): GameEntity<any> | null {\n\treturn debugState.hoveredEntity;\n}\n\nexport function setHoveredEntity(entity: GameEntity<any> | null): void {\n\tdebugState.hoveredEntity = entity;\n}\n\nexport function resetHoveredEntity(): void {\n\tdebugState.hoveredEntity = null;\n}\n","import { BufferGeometry, InstancedMesh, Material, Matrix4, Object3D, Vector3, Quaternion } from 'three';\nimport type { GameEntity, GameEntityOptions } from '../entities/entity';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\n\n/**\n * Represents a batch of entities sharing the same geometry and material\n */\nexport interface BatchGroup {\n\t/** Unique key identifying this batch */\n\tkey: string;\n\t/** The instanced mesh for rendering */\n\tinstancedMesh: InstancedMesh;\n\t/** Original geometry */\n\tgeometry: BufferGeometry;\n\t/** Original material */\n\tmaterial: Material;\n\t/** Map of entity UUID to instance index */\n\tentityMap: Map<string, number>;\n\t/** List of entities in this batch (by their index) */\n\tentities: (GameEntity<any> | null)[];\n\t/** Indices that have been freed and can be reused */\n\tfreeIndices: number[];\n\t/** Active indices for fast iteration */\n\tactiveIndices: number[];\n\t/** Dirty flags for transforms that need syncing */\n\tdirtyIndices: Set<number>;\n\t/** Maximum capacity */\n\tcapacity: number;\n}\n\n/**\n * Configuration for batch key generation\n */\nexport interface BatchKeyConfig {\n\tgeometryType: string;\n\tdimensions: Record<string, number>;\n\tmaterialPath?: string | null;\n\tshaderType?: 'standard' | 'custom';\n\tcolorHex?: number;\n}\n\n/**\n * Manages instanced mesh batching for entities\n */\nexport class InstanceManager {\n\tprivate batches: Map<string, BatchGroup> = new Map();\n\tprivate entityToBatch: Map<string, string> = new Map(); // entity UUID -> batch key\n\tprivate scene: Object3D | null = null;\n\n\t/** Default initial capacity for new batches */\n\tstatic DEFAULT_CAPACITY = 128;\n\t/** Factor to grow batch when full */\n\tstatic GROWTH_FACTOR = 2;\n\n\t/**\n\t * Set the scene to add instanced meshes to\n\t */\n\tsetScene(scene: Object3D): void {\n\t\tthis.scene = scene;\n\t}\n\n\t/**\n\t * Generate a batch key from configuration\n\t */\n\tstatic generateBatchKey(config: BatchKeyConfig): string {\n\t\tconst keyData = {\n\t\t\tgeo: `${config.geometryType}:${sortedStringify(config.dimensions)}`,\n\t\t\tmat: config.materialPath || 'none',\n\t\t\tshader: config.shaderType || 'standard',\n\t\t\tcolor: config.colorHex ?? 0xffffff,\n\t\t};\n\t\treturn shortHash(sortedStringify(keyData));\n\t}\n\n\t/**\n\t * Register an entity with the instance manager\n\t * @returns The instance index, or -1 if registration failed\n\t */\n\tregister(\n\t\tentity: GameEntity<any>,\n\t\tgeometry: BufferGeometry,\n\t\tmaterial: Material,\n\t\tbatchKey: string\n\t): number {\n\t\tlet batch = this.batches.get(batchKey);\n\n\t\tif (!batch) {\n\t\t\tbatch = this.createBatch(batchKey, geometry, material);\n\t\t}\n\n\t\t// Get an index for this entity\n\t\tlet index: number;\n\t\tif (batch.freeIndices.length > 0) {\n\t\t\tindex = batch.freeIndices.pop()!;\n\t\t} else {\n\t\t\tindex = batch.entities.length;\n\t\t\tif (index >= batch.capacity) {\n\t\t\t\tthis.growBatch(batch);\n\t\t\t}\n\t\t\tbatch.entities.push(null);\n\t\t}\n\n\t\t// Store entity reference\n\t\tbatch.entities[index] = entity;\n\t\tbatch.entityMap.set(entity.uuid, index);\n\t\tthis.entityToBatch.set(entity.uuid, batchKey);\n\n\t\t// Update visible instance count\n\t\tbatch.instancedMesh.count = Math.max(batch.instancedMesh.count, index + 1);\n\n\t\t// Add to active list\n\t\tbatch.activeIndices.push(index);\n\n\t\t// Mark dirty for initial transform sync\n\t\tbatch.dirtyIndices.add(index);\n\n\t\treturn index;\n\t}\n\n\t/**\n\t * Unregister an entity from the instance manager\n\t */\n\tunregister(entity: GameEntity<any>): void {\n\t\tconst batchKey = this.entityToBatch.get(entity.uuid);\n\t\tif (!batchKey) return;\n\n\t\tconst batch = this.batches.get(batchKey);\n\t\tif (!batch) return;\n\n\t\tconst index = batch.entityMap.get(entity.uuid);\n\t\tif (index === undefined) return;\n\n\t\t// Clear the entity slot\n\t\tbatch.entities[index] = null;\n\t\tbatch.entityMap.delete(entity.uuid);\n\t\tthis.entityToBatch.delete(entity.uuid);\n\t\tbatch.freeIndices.push(index);\n\t\t// Remove from active list (swap and pop for O(1))\n\t\tconst idxInActive = batch.activeIndices.indexOf(index);\n\t\tif (idxInActive !== -1) {\n\t\t\tconst last = batch.activeIndices.pop()!;\n\t\t\tif (idxInActive < batch.activeIndices.length) {\n\t\t\t\tbatch.activeIndices[idxInActive] = last;\n\t\t\t}\n\t\t}\n\t\tbatch.dirtyIndices.delete(index);\n\n\t\t// Hide the instance by scaling to zero\n\t\tconst matrix = new Matrix4();\n\t\tmatrix.makeScale(0, 0, 0);\n\t\tbatch.instancedMesh.setMatrixAt(index, matrix);\n\t\tbatch.instancedMesh.instanceMatrix.needsUpdate = true;\n\t}\n\n\t/**\n\t * Mark an entity's transform as dirty (needs syncing)\n\t */\n\tmarkDirty(entity: GameEntity<any>): void {\n\t\tconst batchKey = this.entityToBatch.get(entity.uuid);\n\t\tif (!batchKey) return;\n\n\t\tconst batch = this.batches.get(batchKey);\n\t\tif (!batch) return;\n\n\t\tconst index = batch.entityMap.get(entity.uuid);\n\t\tif (index !== undefined) {\n\t\t\tbatch.dirtyIndices.add(index);\n\t\t}\n\t}\n\n\t/**\n\t * Update all dirty instance transforms\n\t * Call this once per frame\n\t */\n\t/**\n\t * Update all active instance transforms\n\t * Call this once per frame\n\t */\n\tupdate(): void {\n\t\tconst matrix = new Matrix4();\n\t\tconst pos = new Vector3();\n\t\tconst quat = new Quaternion();\n\t\tconst scale = new Vector3(1, 1, 1);\n\n\t\tfor (const batch of this.batches.values()) {\n\t\t\tif (batch.activeIndices.length === 0) continue;\n\n\t\t\tlet needsUpdate = false;\n\t\t\t// Check if we have explicit dirty updates\n\t\t\tif (batch.dirtyIndices.size > 0) {\n\t\t\t\tfor (const index of batch.dirtyIndices) {\n\t\t\t\t\tthis.updateInstanceMatrix(batch, index, matrix, pos, quat, scale);\n\t\t\t\t}\n\t\t\t\tbatch.dirtyIndices.clear();\n\t\t\t\tneedsUpdate = true;\n\t\t\t}\n\n\t\t\t// Also update all active dynamic entities (assumed dynamic if they have a body)\n\t\t\tfor (const index of batch.activeIndices) {\n\t\t\t\tconst entity = batch.entities[index];\n\t\t\t\t// Optimization: Only update if it has a physics body (dynamic)\n\t\t\t\tif (entity && entity.body) {\n\t\t\t\t\tthis.updateInstanceMatrix(batch, index, matrix, pos, quat, scale);\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (needsUpdate) {\n\t\t\t\tbatch.instancedMesh.instanceMatrix.needsUpdate = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate updateInstanceMatrix(batch: BatchGroup, index: number, matrix: Matrix4, pos: Vector3, quat: Quaternion, scale: Vector3) {\n\t\tconst entity = batch.entities[index];\n\t\tif (!entity) return;\n\n\t\tif (entity.body) {\n\t\t\tconst translation = entity.body.translation();\n\t\t\tconst rotation = entity.body.rotation();\n\t\t\tpos.set(translation.x, translation.y, translation.z);\n\t\t\tquat.set(rotation.x, rotation.y, rotation.z, rotation.w);\n\t\t\tmatrix.compose(pos, quat, scale);\n\t\t} else if (entity.mesh) {\n\t\t\tentity.mesh.updateMatrix();\n\t\t\tmatrix.copy(entity.mesh.matrix);\n\t\t} else if (entity.group) {\n\t\t\tentity.group.updateMatrix();\n\t\t\tmatrix.copy(entity.group.matrix);\n\t\t}\n\n\t\tbatch.instancedMesh.setMatrixAt(index, matrix);\n\t}\n\n\t/**\n\t * Get batch info for an entity\n\t */\n\tgetBatchInfo(entity: GameEntity<any>): { batchKey: string; instanceId: number } | null {\n\t\tconst batchKey = this.entityToBatch.get(entity.uuid);\n\t\tif (!batchKey) return null;\n\n\t\tconst batch = this.batches.get(batchKey);\n\t\tif (!batch) return null;\n\n\t\tconst instanceId = batch.entityMap.get(entity.uuid);\n\t\tif (instanceId === undefined) return null;\n\n\t\treturn { batchKey, instanceId };\n\t}\n\n\t/**\n\t * Get statistics about current batching\n\t */\n\tgetStats(): { batchCount: number; totalInstances: number; batches: { key: string; count: number; capacity: number }[] } {\n\t\tlet totalInstances = 0;\n\t\tconst batches: { key: string; count: number; capacity: number }[] = [];\n\n\t\tfor (const [key, batch] of this.batches) {\n\t\t\tconst count = batch.entityMap.size;\n\t\t\ttotalInstances += count;\n\t\t\tbatches.push({ key, count, capacity: batch.capacity });\n\t\t}\n\n\t\treturn { batchCount: this.batches.size, totalInstances, batches };\n\t}\n\n\t/**\n\t * Dispose all batches and release resources\n\t */\n\tdispose(): void {\n\t\tfor (const batch of this.batches.values()) {\n\t\t\tif (this.scene) {\n\t\t\t\tthis.scene.remove(batch.instancedMesh);\n\t\t\t}\n\t\t\tbatch.instancedMesh.dispose();\n\t\t\tbatch.geometry.dispose();\n\t\t}\n\t\tthis.batches.clear();\n\t\tthis.entityToBatch.clear();\n\t}\n\n\t/**\n\t * Create a new batch group\n\t */\n\tprivate createBatch(key: string, geometry: BufferGeometry, material: Material): BatchGroup {\n\t\tconst capacity = InstanceManager.DEFAULT_CAPACITY;\n\t\tconst instancedMesh = new InstancedMesh(geometry, material, capacity);\n\t\tinstancedMesh.count = 0; // Start with zero visible instances\n\t\tinstancedMesh.frustumCulled = false; // Let individual instances handle culling\n\n\t\t// Initialize all matrices to hidden (zero scale)\n\t\tconst hiddenMatrix = new Matrix4().makeScale(0, 0, 0);\n\t\tfor (let i = 0; i < capacity; i++) {\n\t\t\tinstancedMesh.setMatrixAt(i, hiddenMatrix);\n\t\t}\n\t\tinstancedMesh.instanceMatrix.needsUpdate = true;\n\n\t\tconst batch: BatchGroup = {\n\t\t\tkey,\n\t\t\tinstancedMesh,\n\t\t\tgeometry,\n\t\t\tmaterial,\n\t\t\tentityMap: new Map(),\n\t\t\tentities: [],\n\t\t\tfreeIndices: [],\n\t\t\tactiveIndices: [],\n\t\t\tdirtyIndices: new Set(),\n\t\t\tcapacity,\n\t\t};\n\n\t\tthis.batches.set(key, batch);\n\n\t\tif (this.scene) {\n\t\t\tthis.scene.add(instancedMesh);\n\t\t}\n\n\t\treturn batch;\n\t}\n\n\t/**\n\t * Grow a batch's capacity\n\t */\n\tprivate growBatch(batch: BatchGroup): void {\n\t\tconst newCapacity = batch.capacity * InstanceManager.GROWTH_FACTOR;\n\n\t\t// Create new instanced mesh with larger capacity\n\t\tconst newInstancedMesh = new InstancedMesh(batch.geometry, batch.material, newCapacity);\n\t\tnewInstancedMesh.count = batch.instancedMesh.count;\n\t\tnewInstancedMesh.frustumCulled = false;\n\n\t\t// Copy existing matrices\n\t\tconst matrix = new Matrix4();\n\t\tfor (let i = 0; i < batch.capacity; i++) {\n\t\t\tbatch.instancedMesh.getMatrixAt(i, matrix);\n\t\t\tnewInstancedMesh.setMatrixAt(i, matrix);\n\t\t}\n\n\t\t// Initialize new slots as hidden\n\t\tconst hiddenMatrix = new Matrix4().makeScale(0, 0, 0);\n\t\tfor (let i = batch.capacity; i < newCapacity; i++) {\n\t\t\tnewInstancedMesh.setMatrixAt(i, hiddenMatrix);\n\t\t}\n\t\tnewInstancedMesh.instanceMatrix.needsUpdate = true;\n\n\t\t// Swap meshes\n\t\tif (this.scene) {\n\t\t\tthis.scene.remove(batch.instancedMesh);\n\t\t\tthis.scene.add(newInstancedMesh);\n\t\t}\n\t\tbatch.instancedMesh.dispose();\n\t\tbatch.instancedMesh = newInstancedMesh;\n\t\tbatch.capacity = newCapacity;\n\t}\n}\n","import { Color, Vector3 } from 'three';\nimport { proxy, subscribe } from 'valtio/vanilla';\nimport { BaseEntityInterface, GameEntityInterface } from '../types/entity-types';\nimport { StageStateInterface } from '../types/stage-types';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\nimport { ZylemBlueColor } from '../core/utility/vector';\n\n/**\n * Initial stage state with default values.\n * Exported for use in ZylemStage construction.\n */\nexport const initialStageState = {\n\tbackgroundColor: ZylemBlueColor,\n\tbackgroundImage: null,\n\tbackgroundShader: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard'],\n\t\tp2: ['gamepad-2', 'keyboard'],\n\t},\n\tgravity: new Vector3(0, 0, 0),\n\tvariables: {},\n\tentities: [] as GameEntityInterface[],\n};\n\n/**\n * Stage state proxy for reactive updates.\n */\nconst stageState = proxy({\n\tbackgroundColor: new Color(Color.NAMES.cornflowerblue),\n\tbackgroundImage: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard-1'],\n\t\tp2: ['gamepad-2', 'keyboard-2'],\n\t},\n\tvariables: {},\n\tgravity: new Vector3(0, 0, 0),\n\tentities: [],\n} as StageStateInterface);\n\n// ============================================================\n// Stage state setters (internal use)\n// ============================================================\n\nconst setStageBackgroundColor = (value: Color) => {\n\tstageState.backgroundColor = value;\n};\n\nconst setStageBackgroundImage = (value: string | null) => {\n\tstageState.backgroundImage = value;\n};\n\nconst setEntitiesToStage = (entities: Partial<BaseEntityInterface>[]) => {\n\tstageState.entities = entities;\n};\n\n/** Replace the entire stage variables object (used on stage load). */\nconst setStageVariables = (variables: Record<string, any>) => {\n\tstageState.variables = { ...variables };\n};\n\n/** Reset all stage variables (used on stage unload). */\nconst resetStageVariables = () => {\n\tstageState.variables = {};\n};\n\nconst stageStateToString = (state: StageStateInterface) => {\n\tlet string = `\\n`;\n\tfor (const key in state) {\n\t\tconst value = state[key as keyof StageStateInterface];\n\t\tstring += `${key}:\\n`;\n\t\tif (key === 'entities') {\n\t\t\tfor (const entity of state.entities) {\n\t\t\t\tstring += ` ${entity.uuid}: ${entity.name}\\n`;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tfor (const subKey in value as Record<string, any>) {\n\t\t\t\tconst subValue = value?.[subKey as keyof typeof value];\n\t\t\t\tif (subValue) {\n\t\t\t\t\tstring += ` ${subKey}: ${subValue}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof value === 'string') {\n\t\t\tstring += ` ${key}: ${value}\\n`;\n\t\t}\n\t}\n\treturn string;\n};\n\n// ============================================================\n// Object-scoped variable storage (WeakMap-based)\n// ============================================================\n\n/**\n * WeakMap to store variables keyed by object reference.\n * Variables are automatically garbage collected when the target is collected.\n */\nconst variableStore = new WeakMap<object, Record<string, unknown>>();\n\n/**\n * Separate proxy store for reactivity. We need a regular Map for subscriptions\n * since WeakMap doesn't support iteration/subscriptions.\n */\nconst variableProxyStore = new Map<object, ReturnType<typeof proxy>>();\n\nfunction getOrCreateVariableProxy(target: object): Record<string, unknown> {\n\tlet store = variableProxyStore.get(target) as Record<string, unknown> | undefined;\n\tif (!store) {\n\t\tstore = proxy({});\n\t\tvariableProxyStore.set(target, store);\n\t}\n\treturn store;\n}\n\n/**\n * Set a variable on an object by path.\n * @example setVariable(stage1, 'totalAngle', 0.5)\n * @example setVariable(entity, 'enemy.count', 10)\n */\nexport function setVariable(target: object, path: string, value: unknown): void {\n\tconst store = getOrCreateVariableProxy(target);\n\tsetByPath(store, path, value);\n}\n\n/**\n * Create/initialize a variable with a default value on a target object.\n * Only sets the value if it doesn't already exist.\n * @example createVariable(stage1, 'totalAngle', 0)\n * @example createVariable(entity, 'enemy.count', 10)\n */\nexport function createVariable<T>(target: object, path: string, defaultValue: T): T {\n\tconst store = getOrCreateVariableProxy(target);\n\tconst existing = getByPath<T>(store, path);\n\tif (existing === undefined) {\n\t\tsetByPath(store, path, defaultValue);\n\t\treturn defaultValue;\n\t}\n\treturn existing;\n}\n\n/**\n * Get a variable from an object by path.\n * @example getVariable(stage1, 'totalAngle') // 0.5\n * @example getVariable<number>(entity, 'enemy.count') // 10\n */\nexport function getVariable<T = unknown>(target: object, path: string): T | undefined {\n\tconst store = variableProxyStore.get(target);\n\tif (!store) return undefined;\n\treturn getByPath<T>(store, path);\n}\n\n/**\n * Subscribe to changes on a variable at a specific path for a target object.\n * Returns an unsubscribe function.\n * @example const unsub = onVariableChange(stage1, 'score', (val) => console.log(val));\n */\nexport function onVariableChange<T = unknown>(\n\ttarget: object,\n\tpath: string,\n\tcallback: (value: T) => void\n): () => void {\n\tconst store = getOrCreateVariableProxy(target);\n\tlet previous = getByPath<T>(store, path);\n\treturn subscribe(store, () => {\n\t\tconst current = getByPath<T>(store, path);\n\t\tif (current !== previous) {\n\t\t\tprevious = current;\n\t\t\tcallback(current as T);\n\t\t}\n\t});\n}\n\n/**\n * Subscribe to changes on multiple variable paths for a target object.\n * Callback fires when any of the paths change, receiving all current values.\n * Returns an unsubscribe function.\n * @example const unsub = onVariableChanges(stage1, ['count', 'total'], ([count, total]) => console.log(count, total));\n */\nexport function onVariableChanges<T extends unknown[] = unknown[]>(\n\ttarget: object,\n\tpaths: string[],\n\tcallback: (values: T) => void\n): () => void {\n\tconst store = getOrCreateVariableProxy(target);\n\tlet previousValues = paths.map(p => getByPath(store, p));\n\treturn subscribe(store, () => {\n\t\tconst currentValues = paths.map(p => getByPath(store, p));\n\t\tconst hasChange = currentValues.some((val, i) => val !== previousValues[i]);\n\t\tif (hasChange) {\n\t\t\tpreviousValues = currentValues;\n\t\t\tcallback(currentValues as T);\n\t\t}\n\t});\n}\n\n/**\n * Clear all variables for a target object. Used on stage/entity dispose.\n */\nexport function clearVariables(target: object): void {\n\tvariableProxyStore.delete(target);\n}\n\n// ============================================================\n// Legacy stage variable functions (internal, for stage defaults)\n// ============================================================\n\nconst setStageVariable = (key: string, value: any) => {\n\tstageState.variables[key] = value;\n};\n\nconst getStageVariable = (key: string) => {\n\tif (stageState.variables.hasOwnProperty(key)) {\n\t\treturn stageState.variables[key];\n\t} else {\n\t\tconsole.warn(`Stage variable ${key} not found`);\n\t}\n};\n\nexport {\n\tstageState,\n\t\n\tsetStageBackgroundColor,\n\tsetStageBackgroundImage,\n\t\n\tstageStateToString,\n\tsetStageVariable,\n\tgetStageVariable,\n\tsetStageVariables,\n\tresetStageVariables,\n};","import { Color, Vector3 as ThreeVector3 } from 'three';\nimport { Vector3 } from '@dimforge/rapier3d-compat';\n\n// TODO: needs implementations\n/**\n * @deprecated This type is deprecated.\n */\nexport type Vect3 = ThreeVector3 | Vector3;\n\nexport const ZylemBlueColor = new Color('#0333EC');\nexport const ZylemBlue = '#0333EC';\nexport const ZylemBlueTransparent = '#0333ECA0';\nexport const ZylemGoldText = '#DAA420';\n\nexport const Vec0 = new Vector3(0, 0, 0);\nexport const Vec1 = new Vector3(1, 1, 1);","import { DestroyContext, DestroyFunction, SetupContext, SetupFunction, UpdateContext, UpdateFunction } from './base-node-life-cycle';\n\n/**\n * Provides BaseNode-like lifecycle without ECS/children. Consumers implement\n * the protected hooks and may assign public setup/update/destroy callbacks.\n */\nexport abstract class LifeCycleBase<TSelf> {\n\tupdate: UpdateFunction<TSelf> = () => { };\n\tsetup: SetupFunction<TSelf> = () => { };\n\tdestroy: DestroyFunction<TSelf> = () => { };\n\n\tprotected abstract _setup(context: SetupContext<TSelf>): void;\n\tprotected abstract _update(context: UpdateContext<TSelf>): void;\n\tprotected abstract _destroy(context: DestroyContext<TSelf>): void;\n\n\tnodeSetup(context: SetupContext<TSelf>) {\n\t\tif (typeof (this as any)._setup === 'function') {\n\t\t\tthis._setup(context);\n\t\t}\n\t\tif (this.setup) {\n\t\t\tthis.setup(context);\n\t\t}\n\t}\n\n\tnodeUpdate(context: UpdateContext<TSelf>) {\n\t\tif (typeof (this as any)._update === 'function') {\n\t\t\tthis._update(context);\n\t\t}\n\t\tif (this.update) {\n\t\t\tthis.update(context);\n\t\t}\n\t}\n\n\tnodeDestroy(context: DestroyContext<TSelf>) {\n\t\tif (this.destroy) {\n\t\t\tthis.destroy(context);\n\t\t}\n\t\tif (typeof (this as any)._destroy === 'function') {\n\t\t\tthis._destroy(context);\n\t\t}\n\t}\n}\n\n\n","import { Ray, RayColliderToi } from '@dimforge/rapier3d-compat';\nimport { BufferAttribute, BufferGeometry, LineBasicMaterial, LineSegments, Raycaster, Vector2, Vector3 } from 'three';\nimport { ZylemStage } from './zylem-stage';\nimport { debugState, DebugTools, getDebugTool, getHoveredEntity, resetHoveredEntity, setHoveredEntity, setSelectedEntity } from '../debug/debug-state';\nimport { DebugEntityCursor } from './debug-entity-cursor';\n\nexport type AddEntityFactory = (params: { position: Vector3; normal?: Vector3 }) => Promise<any> | any;\n\nexport interface StageDebugDelegateOptions {\n\tmaxRayDistance?: number;\n\taddEntityFactory?: AddEntityFactory | null;\n}\n\nconst SELECT_TOOL_COLOR = 0x22ff22;\nconst DELETE_TOOL_COLOR = 0xff3333;\n\nexport class StageDebugDelegate {\n\tprivate stage: ZylemStage;\n\tprivate options: Required<StageDebugDelegateOptions>;\n\tprivate mouseNdc: Vector2 = new Vector2(-2, -2);\n\tprivate raycaster: Raycaster = new Raycaster();\n\tprivate isMouseDown = false;\n\tprivate disposeFns: Array<() => void> = [];\n\tprivate debugCursor: DebugEntityCursor | null = null;\n\tprivate debugLines: LineSegments | null = null;\n\n\tconstructor(stage: ZylemStage, options?: StageDebugDelegateOptions) {\n\t\tthis.stage = stage;\n\t\tthis.options = {\n\t\t\tmaxRayDistance: options?.maxRayDistance ?? 5_000,\n\t\t\taddEntityFactory: options?.addEntityFactory ?? null,\n\t\t};\n\t\tthis.attachDomListeners();\n\t}\n\n\tprivate initDebugVisuals(): void {\n\t\tif (this.debugLines || !this.stage.scene) return;\n\n\t\tthis.debugLines = new LineSegments(\n\t\t\tnew BufferGeometry(),\n\t\t\tnew LineBasicMaterial({ vertexColors: true })\n\t\t);\n\t\tthis.stage.scene.scene.add(this.debugLines);\n\t\tthis.debugLines.visible = true;\n\n\t\tthis.debugCursor = new DebugEntityCursor(this.stage.scene.scene);\n\t}\n\n\tprivate disposeDebugVisuals(): void {\n\t\tif (this.debugLines && this.stage.scene) {\n\t\t\tthis.stage.scene.scene.remove(this.debugLines);\n\t\t\tthis.debugLines.geometry.dispose();\n\t\t\t(this.debugLines.material as LineBasicMaterial).dispose();\n\t\t\tthis.debugLines = null;\n\t\t}\n\t\tthis.debugCursor?.dispose();\n\t\tthis.debugCursor = null;\n\t}\n\n\tupdate(): void {\n\t\tif (!debugState.enabled) {\n\t\t\tif (this.debugLines) {\n\t\t\t\tthis.disposeDebugVisuals();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.stage.scene || !this.stage.world || !this.stage.cameraRef) return;\n\n\t\t// Initialize visuals if not already created\n\t\tif (!this.debugLines) {\n\t\t\tthis.initDebugVisuals();\n\t\t}\n\n\t\tconst { world, cameraRef } = this.stage;\n\n\t\tif (this.debugLines) {\n\t\t\tconst { vertices, colors } = world.world.debugRender();\n\t\t\tthis.debugLines.geometry.setAttribute('position', new BufferAttribute(vertices, 3));\n\t\t\tthis.debugLines.geometry.setAttribute('color', new BufferAttribute(colors, 4));\n\t\t}\n\t\tconst tool = getDebugTool();\n\t\tconst isCursorTool = tool === 'select' || tool === 'delete';\n\n\t\tthis.raycaster.setFromCamera(this.mouseNdc, cameraRef.camera);\n\t\tconst origin = this.raycaster.ray.origin.clone();\n\t\tconst direction = this.raycaster.ray.direction.clone().normalize();\n\n\t\tconst rapierRay = new Ray(\n\t\t\t{ x: origin.x, y: origin.y, z: origin.z },\n\t\t\t{ x: direction.x, y: direction.y, z: direction.z },\n\t\t);\n\t\tconst hit: RayColliderToi | null = world.world.castRay(rapierRay, this.options.maxRayDistance, true);\n\n\t\tif (hit && isCursorTool) {\n\t\t\t// @ts-ignore - access compat object's parent userData mapping back to GameEntity\n\t\t\tconst rigidBody = hit.collider?._parent;\n\t\t\tconst hoveredUuid: string | undefined = rigidBody?.userData?.uuid;\n\t\t\tif (hoveredUuid) {\n\t\t\t\tconst entity = this.stage._debugMap.get(hoveredUuid);\n\t\t\t\tif (entity) setHoveredEntity(entity as any);\n\t\t\t} else {\n\t\t\t\tresetHoveredEntity();\n\t\t\t}\n\n\t\t\tif (this.isMouseDown) {\n\t\t\t\tthis.handleActionOnHit(hoveredUuid ?? null, origin, direction, hit.toi);\n\t\t\t}\n\t\t}\n\t\tthis.isMouseDown = false;\n\n\t\tconst hoveredUuid = getHoveredEntity();\n\t\tif (!hoveredUuid) {\n\t\t\tthis.debugCursor?.hide();\n\t\t\treturn;\n\t\t}\n\t\tconst hoveredEntity: any = this.stage._debugMap.get(`${hoveredUuid}`);\n\t\tconst targetObject = hoveredEntity?.group ?? hoveredEntity?.mesh ?? null;\n\t\tif (!targetObject) {\n\t\t\tthis.debugCursor?.hide();\n\t\t\treturn;\n\t\t}\n\t\tswitch (tool) {\n\t\t\tcase 'select':\n\t\t\t\tthis.debugCursor?.setColor(SELECT_TOOL_COLOR);\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tthis.debugCursor?.setColor(DELETE_TOOL_COLOR);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.debugCursor?.setColor(0xffffff);\n\t\t\t\tbreak;\n\t\t}\n\t\tthis.debugCursor?.updateFromObject(targetObject);\n\t}\n\n\tdispose(): void {\n\t\tthis.disposeFns.forEach((fn) => fn());\n\t\tthis.disposeFns = [];\n\t\tthis.disposeDebugVisuals();\n\t}\n\n\tprivate handleActionOnHit(hoveredUuid: string | null, origin: Vector3, direction: Vector3, toi: number) {\n\t\tconst tool = getDebugTool();\n\t\tswitch (tool) {\n\t\t\tcase 'select': {\n\t\t\t\tif (hoveredUuid) {\n\t\t\t\t\tconst entity = this.stage._debugMap.get(hoveredUuid);\n\t\t\t\t\tif (entity) setSelectedEntity(entity as any);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'delete': {\n\t\t\t\tif (hoveredUuid) {\n\t\t\t\t\tthis.stage.removeEntityByUuid(hoveredUuid);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\tif (!this.options.addEntityFactory) break;\n\t\t\t\tconst hitPosition = origin.clone().add(direction.clone().multiplyScalar(toi));\n\t\t\t\tconst newNode = this.options.addEntityFactory({ position: hitPosition });\n\t\t\t\tif (newNode) {\n\t\t\t\t\tPromise.resolve(newNode).then((node) => {\n\t\t\t\t\t\tif (node) this.stage.spawnEntity(node);\n\t\t\t\t\t}).catch(() => { });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate attachDomListeners() {\n\t\tconst canvas = this.stage.cameraRef?.renderer.domElement ?? this.stage.scene?.zylemCamera.renderer.domElement;\n\t\tif (!canvas) return;\n\n\t\tconst onMouseMove = (e: MouseEvent) => {\n\t\t\tconst rect = canvas.getBoundingClientRect();\n\t\t\tconst x = ((e.clientX - rect.left) / rect.width) * 2 - 1;\n\t\t\tconst y = -(((e.clientY - rect.top) / rect.height) * 2 - 1);\n\t\t\tthis.mouseNdc.set(x, y);\n\t\t};\n\n\t\tconst onMouseDown = (e: MouseEvent) => {\n\t\t\tthis.isMouseDown = true;\n\t\t};\n\n\t\tcanvas.addEventListener('mousemove', onMouseMove);\n\t\tcanvas.addEventListener('mousedown', onMouseDown);\n\n\t\tthis.disposeFns.push(() => canvas.removeEventListener('mousemove', onMouseMove));\n\t\tthis.disposeFns.push(() => canvas.removeEventListener('mousedown', onMouseDown));\n\t}\n}\n\n\n","import {\n\tBox3,\n\tBoxGeometry,\n\tColor,\n\tEdgesGeometry,\n\tGroup,\n\tLineBasicMaterial,\n\tLineSegments,\n\tMesh,\n\tMeshBasicMaterial,\n\tObject3D,\n\tScene,\n\tVector3,\n} from 'three';\n\n/**\n * Debug overlay that displays an axis-aligned bounding box around a target Object3D.\n * Shows a semi-transparent fill plus a wireframe outline. Intended for SELECT/DELETE tools.\n */\nexport class DebugEntityCursor {\n\tprivate scene: Scene;\n\tprivate container: Group;\n\tprivate fillMesh: Mesh;\n\tprivate edgeLines: LineSegments;\n\tprivate currentColor: Color = new Color(0x00ff00);\n\tprivate bbox: Box3 = new Box3();\n\tprivate size: Vector3 = new Vector3();\n\tprivate center: Vector3 = new Vector3();\n\n\tconstructor(scene: Scene) {\n\t\tthis.scene = scene;\n\n\t\tconst initialGeometry = new BoxGeometry(1, 1, 1);\n\n\t\tthis.fillMesh = new Mesh(\n\t\t\tinitialGeometry,\n\t\t\tnew MeshBasicMaterial({\n\t\t\t\tcolor: this.currentColor,\n\t\t\t\ttransparent: true,\n\t\t\t\topacity: 0.12,\n\t\t\t\tdepthWrite: false,\n\t\t\t})\n\t\t);\n\n\t\tconst edges = new EdgesGeometry(initialGeometry);\n\t\tthis.edgeLines = new LineSegments(\n\t\t\tedges,\n\t\t\tnew LineBasicMaterial({ color: this.currentColor, linewidth: 1 })\n\t\t);\n\n\t\tthis.container = new Group();\n\t\tthis.container.name = 'DebugEntityCursor';\n\t\tthis.container.add(this.fillMesh);\n\t\tthis.container.add(this.edgeLines);\n\t\tthis.container.visible = false;\n\n\t\tthis.scene.add(this.container);\n\t}\n\n\tsetColor(color: Color | number): void {\n\t\tthis.currentColor.set(color as any);\n\t\t(this.fillMesh.material as MeshBasicMaterial).color.set(this.currentColor);\n\t\t(this.edgeLines.material as LineBasicMaterial).color.set(this.currentColor);\n\t}\n\n\t/**\n\t * Update the cursor to enclose the provided Object3D using a world-space AABB.\n\t */\n\tupdateFromObject(object: Object3D | null | undefined): void {\n\t\tif (!object) {\n\t\t\tthis.hide();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.bbox.setFromObject(object);\n\t\tif (!isFinite(this.bbox.min.x) || !isFinite(this.bbox.max.x)) {\n\t\t\tthis.hide();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.bbox.getSize(this.size);\n\t\tthis.bbox.getCenter(this.center);\n\n\t\tconst newGeom = new BoxGeometry(\n\t\t\tMath.max(this.size.x, 1e-6),\n\t\t\tMath.max(this.size.y, 1e-6),\n\t\t\tMath.max(this.size.z, 1e-6)\n\t\t);\n\t\tthis.fillMesh.geometry.dispose();\n\t\tthis.fillMesh.geometry = newGeom;\n\n\t\tconst newEdges = new EdgesGeometry(newGeom);\n\t\tthis.edgeLines.geometry.dispose();\n\t\tthis.edgeLines.geometry = newEdges;\n\n\t\tthis.container.position.copy(this.center);\n\t\tthis.container.visible = true;\n\t}\n\n\thide(): void {\n\t\tthis.container.visible = false;\n\t}\n\n\tdispose(): void {\n\t\tthis.scene.remove(this.container);\n\t\tthis.fillMesh.geometry.dispose();\n\t\t(this.fillMesh.material as MeshBasicMaterial).dispose();\n\t\tthis.edgeLines.geometry.dispose();\n\t\t(this.edgeLines.material as LineBasicMaterial).dispose();\n\t}\n}\n\n\n","import { Object3D } from 'three';\nimport { subscribe } from 'valtio/vanilla';\n\nimport type { CameraDebugDelegate, CameraDebugState } from '../camera/zylem-camera';\nimport { debugState } from '../debug/debug-state';\nimport type { ZylemStage } from './zylem-stage';\n\nconst cloneSelected = (selected: string[]): string[] => [...selected];\n\n/**\n * Debug delegate that bridges the stage's entity map and debug state to the camera.\n */\nexport class StageCameraDebugDelegate implements CameraDebugDelegate {\n\tprivate stage: ZylemStage;\n\n\tconstructor(stage: ZylemStage) {\n\t\tthis.stage = stage;\n\t}\n\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void {\n\t\tconst notify = () => listener(this.snapshot());\n\t\tnotify();\n\t\treturn subscribe(debugState, notify);\n\t}\n\n\tresolveTarget(uuid: string): Object3D | null {\n\t\tconst entity: any = this.stage._debugMap.get(uuid)\n\t\t\t|| this.stage.world?.collisionMap.get(uuid)\n\t\t\t|| null;\n\t\tconst target = entity?.group ?? entity?.mesh ?? null;\n\t\treturn target ?? null;\n\t}\n\n\tprivate snapshot(): CameraDebugState {\n\t\treturn {\n\t\t\tenabled: debugState.enabled,\n\t\t\tselected: debugState.selectedEntity ? [debugState.selectedEntity.uuid] : [],\n\t\t};\n\t}\n}\n\n","import { Vector2 } from 'three';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { Perspectives } from '../camera/perspective';\nimport { CameraWrapper } from '../camera/camera';\nimport { CameraManager } from '../camera/camera-manager';\nimport type { ZylemStage } from './zylem-stage';\n\n/**\n * Delegate for camera creation and management within a stage.\n * Accepts an injected stage reference for context.\n */\nexport class StageCameraDelegate {\n\tprivate stage: ZylemStage;\n\n\tconstructor(stage: ZylemStage) {\n\t\tthis.stage = stage;\n\t}\n\n\t/**\n\t * Create a default third-person camera based on window size.\n\t */\n\tcreateDefaultCamera(): ZylemCamera {\n\t\tconst width = window.innerWidth;\n\t\tconst height = window.innerHeight;\n\t\tconst screenResolution = new Vector2(width, height);\n\t\treturn new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t}\n\n\t/**\n\t * Resolve the camera to use for the stage.\n\t * Uses the provided camera, stage camera wrapper, or creates a default.\n\t * \n\t * @param cameraOverride Optional camera override\n\t * @param cameraWrapper Optional camera wrapper from stage options\n\t * @returns The resolved ZylemCamera instance\n\t */\n\tresolveCamera(cameraOverride?: ZylemCamera | null, cameraWrapper?: CameraWrapper): ZylemCamera {\n\t\tif (cameraOverride) {\n\t\t\treturn cameraOverride;\n\t\t}\n\t\tif (cameraWrapper) {\n\t\t\treturn cameraWrapper.cameraRef;\n\t\t}\n\t\treturn this.createDefaultCamera();\n\t}\n\n\t/**\n\t * Build a CameraManager from stage options.\n\t * Supports single camera (backward compatible) and multiple cameras.\n\t * \n\t * @param cameraOverride Optional camera override from game-level config\n\t * @param cameraWrappers Camera wrappers from stage options (can be single or array)\n\t * @returns A CameraManager populated with the resolved cameras\n\t */\n\tbuildCameraManager(\n\t\tcameraOverride?: ZylemCamera | null,\n\t\t...cameraWrappers: (CameraWrapper | undefined)[]\n\t): CameraManager {\n\t\tconst manager = new CameraManager();\n\n\t\t// If there's a camera override, use it as the primary\n\t\tif (cameraOverride) {\n\t\t\tmanager.addCamera(cameraOverride, cameraOverride.name || 'main');\n\t\t\treturn manager;\n\t\t}\n\n\t\t// Add cameras from wrappers\n\t\tconst validWrappers = cameraWrappers.filter((w): w is CameraWrapper => w !== undefined);\n\n\t\tif (validWrappers.length > 0) {\n\t\t\tfor (const wrapper of validWrappers) {\n\t\t\t\tconst cam = wrapper.cameraRef;\n\t\t\t\tmanager.addCamera(cam, cam.name || undefined);\n\t\t\t}\n\t\t} else {\n\t\t\t// No cameras provided: create a default\n\t\t\tconst defaultCam = this.createDefaultCamera();\n\t\t\tmanager.addCamera(defaultCam, 'default');\n\t\t}\n\n\t\treturn manager;\n\t}\n}\n","import { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, Scene } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { ThirdPersonCamera } from './third-person';\nimport { Fixed2DCamera } from './fixed-2d';\nimport { StageEntity } from '../interfaces/entity';\nimport { CameraOrbitController, CameraDebugDelegate } from './camera-debug-delegate';\nimport { RendererManager, DEFAULT_VIEWPORT } from './renderer-manager';\nimport type { ZylemRenderer, RendererType, Viewport } from './renderer-manager';\n\n// Re-export for backwards compatibility\nexport type { CameraDebugState, CameraDebugDelegate } from './camera-debug-delegate';\nexport type { RendererType, ZylemRenderer } from './renderer-manager';\nexport { isWebGPUSupported } from './renderer-manager';\n\n/**\n * Interface for perspective-specific camera controllers\n */\nexport interface PerspectiveController {\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }): void;\n\tupdate(delta: number): void;\n\tresize(width: number, height: number): void;\n}\n\n/**\n * ZylemCamera is a lightweight camera wrapper that manages the Three.js camera,\n * perspective controller, and viewport configuration. It no longer owns a renderer;\n * rendering is handled by RendererManager.\n */\nexport class ZylemCamera {\n\tcameraRig: Object3D | null = null;\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\t_perspective: PerspectiveType;\n\tfrustumSize = 10;\n\trendererType: RendererType;\n\tsceneRef: Scene | null = null;\n\n\t/** Name for camera manager lookup */\n\tname: string = '';\n\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Default is fullscreen: { x: 0, y: 0, width: 1, height: 1 }\n\t */\n\tviewport: Viewport = { ...DEFAULT_VIEWPORT };\n\n\t/**\n\t * Multiple targets for the camera to follow/frame.\n\t * Replaces the old single `target` property.\n\t */\n\ttargets: StageEntity[] = [];\n\n\t/**\n\t * @deprecated Use `targets` array instead. This getter/setter is kept for backward compatibility.\n\t */\n\tget target(): StageEntity | null {\n\t\treturn this.targets.length > 0 ? this.targets[0] : null;\n\t}\n\n\tset target(entity: StageEntity | null) {\n\t\tif (entity) {\n\t\t\tif (this.targets.length === 0) {\n\t\t\t\tthis.targets.push(entity);\n\t\t\t} else {\n\t\t\t\tthis.targets[0] = entity;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.targets = [];\n\t\t}\n\t}\n\n\t// Perspective controller delegation\n\tperspectiveController: PerspectiveController | null = null;\n\n\t// Orbit controls\n\tprivate orbitController: CameraOrbitController | null = null;\n\tprivate _useOrbitalControls = false;\n\n\t/** Reference to the shared renderer manager (set during setup) */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\tconstructor(perspective: PerspectiveType, screenResolution: Vector2, frustumSize: number = 10, rendererType: RendererType = 'webgl') {\n\t\tthis._perspective = perspective;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.frustumSize = frustumSize;\n\t\tthis.rendererType = rendererType;\n\n\t\t// Create camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Setup camera rig only for perspectives that need it (e.g., third-person following)\n\t\tif (this.needsRig()) {\n\t\t\tthis.cameraRig = new Object3D();\n\t\t\tthis.cameraRig.position.set(0, 3, 10);\n\t\t\tthis.cameraRig.add(this.camera);\n\t\t\tthis.camera.lookAt(new Vector3(0, 2, 0));\n\t\t} else {\n\t\t\t// Position camera directly for non-rig perspectives\n\t\t\tthis.camera.position.set(0, 0, 10);\n\t\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\t\t}\n\n\t\t// Initialize perspective controller\n\t\tthis.initializePerspectiveController();\n\t}\n\n\t/**\n\t * Setup the camera with a scene and renderer manager.\n\t * The renderer manager provides shared rendering infrastructure.\n\t */\n\tasync setup(scene: Scene, rendererManager?: RendererManager): Promise<void> {\n\t\tthis.sceneRef = scene;\n\n\t\tif (rendererManager) {\n\t\t\tthis._rendererManager = rendererManager;\n\t\t}\n\n\t\t// Ensure renderer manager is initialized\n\t\tif (this._rendererManager && !this._rendererManager.initialized) {\n\t\t\tawait this._rendererManager.initRenderer();\n\t\t}\n\n\t\t// Setup perspective controller\n\t\tif (this.perspectiveController && this._rendererManager) {\n\t\t\tthis.perspectiveController.setup({\n\t\t\t\tscreenResolution: this.screenResolution,\n\t\t\t\trenderer: this._rendererManager.renderer,\n\t\t\t\tscene: scene,\n\t\t\t\tcamera: this\n\t\t\t});\n\t\t}\n\n\t\t// Initialize orbit controller if renderer is available\n\t\tif (this._rendererManager) {\n\t\t\tthis.orbitController = new CameraOrbitController(\n\t\t\t\tthis.camera,\n\t\t\t\tthis._rendererManager.renderer.domElement,\n\t\t\t\tthis.cameraRig\n\t\t\t);\n\t\t\tthis.orbitController.setScene(scene);\n\n\t\t\t// If orbital controls were requested, enable them\n\t\t\tif (this._useOrbitalControls) {\n\t\t\t\tthis.orbitController.enableUserOrbitControls();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Legacy setup method for backward compatibility.\n\t * Creates a temporary RendererManager internally.\n\t * @deprecated Use setup(scene, rendererManager) instead.\n\t */\n\tasync setupLegacy(scene: Scene): Promise<void> {\n\t\tif (!this._rendererManager) {\n\t\t\tthis._rendererManager = new RendererManager(this.screenResolution, this.rendererType);\n\t\t\tawait this._rendererManager.initRenderer();\n\n\t\t\t// Setup render pass for WebGL\n\t\t\tthis._rendererManager.setupRenderPass(scene, this.camera);\n\n\t\t\t// Start render loop\n\t\t\tthis._rendererManager.startRenderLoop((delta) => {\n\t\t\t\tthis.update(delta);\n\t\t\t\tif (this._rendererManager && this.sceneRef) {\n\t\t\t\t\tthis._rendererManager.render(this.sceneRef, this.camera);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tawait this.setup(scene, this._rendererManager);\n\t}\n\n\t/**\n\t * Update camera controllers (called each frame).\n\t * Does NOT render -- rendering is handled by RendererManager.\n\t */\n\tupdate(delta: number): void {\n\t\t// Update orbit controls (if debug mode or user orbital controls enabled)\n\t\tthis.orbitController?.update();\n\n\t\t// Skip perspective controller updates when orbit controls are active\n\t\tif (this.perspectiveController && !this.isDebugModeActive() && !this._useOrbitalControls) {\n\t\t\tthis.perspectiveController.update(delta);\n\t\t}\n\t}\n\n\t/**\n\t * Check if debug mode is active (orbit controls taking over camera)\n\t */\n\tisDebugModeActive(): boolean {\n\t\treturn this.orbitController?.isActive ?? false;\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = true;\n\t\tthis.orbitController?.enableUserOrbitControls();\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = false;\n\t\tthis.orbitController?.disableUserOrbitControls();\n\t}\n\n\t/**\n\t * Whether user orbital controls are enabled.\n\t */\n\tget useOrbitalControls(): boolean {\n\t\treturn this._useOrbitalControls;\n\t}\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tif (!this.targets.includes(entity)) {\n\t\t\tthis.targets.push(entity);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a target entity.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tconst index = this.targets.indexOf(entity);\n\t\tif (index !== -1) {\n\t\t\tthis.targets.splice(index, 1);\n\t\t}\n\t}\n\n\t/**\n\t * Clear all targets.\n\t */\n\tclearTargets(): void {\n\t\tthis.targets = [];\n\t}\n\n\t/**\n\t * Dispose camera resources (not the renderer -- that's managed by RendererManager).\n\t */\n\tdestroy(): void {\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis.sceneRef = null;\n\t\tthis.targets = [];\n\t\tthis._rendererManager = null;\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null): void {\n\t\tthis.orbitController?.setDebugDelegate(delegate);\n\t}\n\n\t/**\n\t * Resize camera projection.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tthis.camera.aspect = width / height;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.perspectiveController) {\n\t\t\tthis.perspectiveController.resize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.viewport = { x, y, width, height };\n\t}\n\n\t/**\n\t * Create camera based on perspective type\n\t */\n\tprivate createCameraForPerspective(aspectRatio: number): Camera {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn this.createFirstPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn this.createIsometricCamera(aspectRatio);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\t\treturn this.createFlat2DCamera(aspectRatio);\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn this.createFixed2DCamera(aspectRatio);\n\t\t\tdefault:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize perspective-specific controller\n\t */\n\tprivate initializePerspectiveController(): void {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t\t\tbreak;\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\tthis.perspectiveController = new Fixed2DCamera();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t}\n\t}\n\n\tprivate createThirdPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createFirstPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createIsometricCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFlat2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFixed2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn this.createFlat2DCamera(aspectRatio);\n\t}\n\n\t// Movement methods\n\tprivate moveCamera(position: Vector3): void {\n\t\tif (this._perspective === Perspectives.Flat2D || this._perspective === Perspectives.Fixed2D) {\n\t\t\tthis.frustumSize = position.z;\n\t\t}\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.position.set(position.x, position.y, position.z);\n\t\t} else {\n\t\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t\t}\n\t}\n\n\tmove(position: Vector3): void {\n\t\tthis.moveCamera(position);\n\t}\n\n\trotate(pitch: number, yaw: number, roll: number): void {\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.rotateX(pitch);\n\t\t\tthis.cameraRig.rotateY(yaw);\n\t\t\tthis.cameraRig.rotateZ(roll);\n\t\t} else {\n\t\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t\t(this.camera as Object3D).rotateZ(roll);\n\t\t}\n\t}\n\n\t/**\n\t * Check if this perspective type needs a camera rig\n\t */\n\tprivate needsRig(): boolean {\n\t\treturn this._perspective === Perspectives.ThirdPerson;\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t * @deprecated Access via RendererManager instead.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\tif (this._rendererManager) {\n\t\t\treturn this._rendererManager.getDomElement();\n\t\t}\n\t\tthrow new Error('ZylemCamera: No renderer manager available. Call setup() first.');\n\t}\n\n\t/**\n\t * Get the renderer manager reference.\n\t */\n\tgetRendererManager(): RendererManager | null {\n\t\treturn this._rendererManager;\n\t}\n\n\t/**\n\t * Set the renderer manager reference (used by CameraManager during setup).\n\t */\n\tsetRendererManager(manager: RendererManager): void {\n\t\tthis._rendererManager = manager;\n\t}\n\n\t// ─── Legacy compatibility methods ────────────────────────────────────────\n\n\t/**\n\t * @deprecated Renderer is now owned by RendererManager\n\t */\n\tget renderer(): any {\n\t\treturn this._rendererManager?.renderer;\n\t}\n\n\t/**\n\t * @deprecated Composer is now owned by RendererManager\n\t */\n\tget composer(): any {\n\t\treturn this._rendererManager?.composer;\n\t}\n\n\t/**\n\t * @deprecated Use RendererManager.setPixelRatio() instead\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tthis._rendererManager?.setPixelRatio(dpr);\n\t}\n}\n","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];","import { Scene, Vector2, Vector3 } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { ZylemRenderer } from './renderer-manager';\n\n/**\n * Third-person camera controller that supports multiple targets.\n *\n * - 0 targets: stays at configured position, looks at world origin\n * - 1 target: classic third-person follow (lerp to target + offset)\n * - 2+ targets: weighted-center framing -- computes centroid of all targets,\n * zooms out based on max distance between them, and looks at centroid\n */\nexport class ThirdPersonCamera implements PerspectiveController {\n\tdistance: Vector3;\n\tscreenResolution: Vector2 | null = null;\n\trenderer: ZylemRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\t/** Padding multiplier when framing multiple targets. Higher = more zoom out. */\n\tpaddingFactor = 1.5;\n\n\t/** Minimum camera distance when multi-framing (prevents extreme zoom-in). */\n\tminDistance = 5;\n\n\t/** Lerp factor for camera position smoothing. */\n\tlerpFactor = 0.1;\n\n\tconstructor() {\n\t\tthis.distance = new Vector3(0, 5, 8);\n\t}\n\n\t/**\n\t * Setup the third person camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\t}\n\n\t/**\n\t * Update the third person camera.\n\t * Handles 0, 1, and multi-target scenarios.\n\t */\n\tupdate(delta: number) {\n\t\tif (!this.cameraRef) return;\n\n\t\tconst targets = this.cameraRef.targets;\n\n\t\tif (targets.length === 0) {\n\t\t\t// No targets: look at world origin, stay at current position\n\t\t\tthis.cameraRef.camera.lookAt(new Vector3(0, 0, 0));\n\t\t\treturn;\n\t\t}\n\n\t\tif (targets.length === 1) {\n\t\t\t// Single target: classic third-person follow\n\t\t\tthis.updateSingleTarget(targets[0]);\n\t\t\treturn;\n\t\t}\n\n\t\t// Multiple targets: weighted-center framing\n\t\tthis.updateMultiTarget(targets);\n\t}\n\n\t/**\n\t * Classic single-target follow: lerp to target position + offset, lookAt target.\n\t */\n\tprivate updateSingleTarget(target: { group: { position: Vector3 } }) {\n\t\tconst useTarget = target.group?.position || new Vector3(0, 0, 0);\n\t\tconst desiredCameraPosition = useTarget.clone().add(this.distance);\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, this.lerpFactor);\n\t\tthis.cameraRef!.camera.lookAt(useTarget);\n\t}\n\n\t/**\n\t * Multi-target framing: compute centroid, measure spread, zoom out to fit all.\n\t */\n\tprivate updateMultiTarget(targets: Array<{ group: { position: Vector3 } }>) {\n\t\t// Compute centroid (average position of all targets)\n\t\tconst centroid = new Vector3();\n\t\tfor (const t of targets) {\n\t\t\tcentroid.add(t.group.position);\n\t\t}\n\t\tcentroid.divideScalar(targets.length);\n\n\t\t// Compute max distance from centroid to any target\n\t\tlet maxDistFromCentroid = 0;\n\t\tfor (const t of targets) {\n\t\t\tconst dist = centroid.distanceTo(t.group.position);\n\t\t\tif (dist > maxDistFromCentroid) {\n\t\t\t\tmaxDistFromCentroid = dist;\n\t\t\t}\n\t\t}\n\n\t\t// Scale the camera distance based on the spread of targets\n\t\tconst dynamicDistance = Math.max(maxDistFromCentroid * this.paddingFactor, this.minDistance);\n\n\t\t// Compute desired camera position: centroid + offset direction scaled by dynamic distance\n\t\tconst offsetDirection = this.distance.clone().normalize();\n\t\tconst desiredCameraPosition = centroid.clone().add(\n\t\t\toffsetDirection.multiplyScalar(dynamicDistance)\n\t\t);\n\n\t\t// Preserve the vertical offset proportionally\n\t\tconst baseLen = this.distance.length();\n\t\tif (baseLen > 0) {\n\t\t\tconst heightRatio = this.distance.y / baseLen;\n\t\t\tdesiredCameraPosition.y = centroid.y + dynamicDistance * heightRatio;\n\t\t}\n\n\t\t// Smooth camera movement\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, this.lerpFactor);\n\t\tthis.cameraRef!.camera.lookAt(centroid);\n\t}\n\n\t/**\n\t * Handle resize events\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Set the distance offset from the target\n\t */\n\tsetDistance(distance: Vector3) {\n\t\tthis.distance = distance;\n\t}\n}\n","import { Scene, Vector2 } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { ZylemRenderer } from './renderer-manager';\n\n/**\n * Fixed 2D Camera Controller\n * Maintains a static 2D camera view with no automatic following or movement\n */\nexport class Fixed2DCamera implements PerspectiveController {\n\tscreenResolution: Vector2 | null = null;\n\trenderer: ZylemRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\t// Fixed 2D camera doesn't need any initial setup parameters\n\t}\n\n\t/**\n\t * Setup the fixed 2D camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\n\t\t// Position camera for 2D view (looking down the Z-axis)\n\t\tthis.cameraRef.camera.position.set(0, 0, 10);\n\t\tthis.cameraRef.camera.lookAt(0, 0, 0);\n\t}\n\n\t/**\n\t * Update the fixed 2D camera\n\t * Fixed cameras don't need to update position/rotation automatically\n\t */\n\tupdate(delta: number) {\n\t\t// Fixed 2D camera maintains its position and orientation\n\t\t// No automatic updates needed for a truly fixed camera\n\t}\n\n\t/**\n\t * Handle resize events for 2D camera\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\n\t\t// For orthographic cameras, we might need to adjust the frustum\n\t\t// This is handled in the main ZylemCamera resize method\n\t}\n}\n","import { Object3D, Vector3, Quaternion, Camera, Scene } from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\nexport interface CameraDebugState {\n\tenabled: boolean;\n\tselected: string[];\n}\n\nexport interface CameraDebugDelegate {\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void;\n\tresolveTarget(uuid: string): Object3D | null;\n}\n\n/**\n * Manages orbit controls for a camera.\n * Supports two modes:\n * 1. **Debug mode**: orbit controls activated by the debug system, with save/restore of camera state\n * 2. **User mode**: orbit controls enabled by the user via `useOrbitalControls` camera option\n *\n * These modes are independent -- debug mode takes precedence but user mode\n * keeps orbit controls active even outside debug.\n */\nexport class CameraOrbitController {\n\tprivate camera: Camera;\n\tprivate domElement: HTMLElement;\n\tprivate cameraRig: Object3D | null = null;\n\tprivate sceneRef: Scene | null = null;\n\t\n\tprivate orbitControls: OrbitControls | null = null;\n\tprivate orbitTarget: Object3D | null = null;\n\tprivate orbitTargetWorldPos: Vector3 = new Vector3();\n\n\tprivate debugDelegate: CameraDebugDelegate | null = null;\n\tprivate debugUnsubscribe: (() => void) | null = null;\n\tprivate debugStateSnapshot: CameraDebugState = { enabled: false, selected: [] };\n\n\t// Saved camera state for restoration when exiting debug mode\n\tprivate savedCameraPosition: Vector3 | null = null;\n\tprivate savedCameraQuaternion: Quaternion | null = null;\n\tprivate savedCameraZoom: number | null = null;\n\tprivate savedCameraLocalPosition: Vector3 | null = null;\n\n\t// Saved debug camera state for restoration when re-entering debug mode\n\tprivate savedDebugCameraPosition: Vector3 | null = null;\n\tprivate savedDebugCameraQuaternion: Quaternion | null = null;\n\tprivate savedDebugCameraZoom: number | null = null;\n\tprivate savedDebugOrbitTarget: Vector3 | null = null;\n\n\t/** Whether user-configured orbital controls are enabled (independent of debug) */\n\tprivate _userOrbitEnabled = false;\n\n\tconstructor(camera: Camera, domElement: HTMLElement, cameraRig?: Object3D | null) {\n\t\tthis.camera = camera;\n\t\tthis.domElement = domElement;\n\t\tthis.cameraRig = cameraRig ?? null;\n\t}\n\n\t/**\n\t * Set the scene reference for adding/removing camera when detaching from rig.\n\t */\n\tsetScene(scene: Scene | null): void {\n\t\tthis.sceneRef = scene;\n\t}\n\n\t/**\n\t * Check if debug mode is currently active (orbit controls enabled via debug system).\n\t */\n\tget isActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled;\n\t}\n\n\t/**\n\t * Check if any orbit controls are currently active (debug or user).\n\t */\n\tget isOrbitActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled || this._userOrbitEnabled;\n\t}\n\n\t/**\n\t * Update orbit controls each frame.\n\t * Should be called from the camera's update loop.\n\t */\n\tupdate() {\n\t\tif (this.orbitControls && this.orbitTarget) {\n\t\t\tthis.orbitTarget.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t}\n\t\tthis.orbitControls?.update();\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t * These orbit controls persist until explicitly disabled.\n\t */\n\tenableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = true;\n\t\tif (!this.orbitControls) {\n\t\t\tthis.enableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t * Will not disable orbit controls if debug mode is active.\n\t */\n\tdisableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = false;\n\t\t// Only disable orbit controls if debug mode isn't also using them\n\t\tif (!this.debugStateSnapshot.enabled) {\n\t\t\tthis.disableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tif (this.debugDelegate === delegate) {\n\t\t\treturn;\n\t\t}\n\t\tthis.detachDebugDelegate();\n\t\tthis.debugDelegate = delegate;\n\t\tif (!delegate) {\n\t\t\tthis.applyDebugState({ enabled: false, selected: [] });\n\t\t\treturn;\n\t\t}\n\t\tconst unsubscribe = delegate.subscribe((state) => {\n\t\t\tthis.applyDebugState(state);\n\t\t});\n\t\tthis.debugUnsubscribe = () => {\n\t\t\tunsubscribe?.();\n\t\t};\n\t}\n\n\t/**\n\t * Clean up resources.\n\t */\n\tdispose() {\n\t\tthis.disableOrbitControls();\n\t\tthis.detachDebugDelegate();\n\t}\n\n\t/**\n\t * Get the current debug state snapshot.\n\t */\n\tget debugState(): CameraDebugState {\n\t\treturn this.debugStateSnapshot;\n\t}\n\n\tprivate applyDebugState(state: CameraDebugState) {\n\t\tconst wasEnabled = this.debugStateSnapshot.enabled;\n\t\tthis.debugStateSnapshot = {\n\t\t\tenabled: state.enabled,\n\t\t\tselected: [...state.selected],\n\t\t};\n\t\tif (state.enabled && !wasEnabled) {\n\t\t\t// Entering debug mode: save game camera state, detach from rig, restore debug camera state if available\n\t\t\tthis.saveCameraState();\n\t\t\tthis.detachCameraFromRig();\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.restoreDebugCameraState();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else if (!state.enabled && wasEnabled) {\n\t\t\t// Exiting debug mode: save debug camera state, then restore game camera state\n\t\t\tthis.saveDebugCameraState();\n\t\t\tthis.orbitTarget = null;\n\t\t\t// Only disable orbit controls if user mode isn't keeping them on\n\t\t\tif (!this._userOrbitEnabled) {\n\t\t\t\tthis.disableOrbitControls();\n\t\t\t}\n\t\t\tthis.reattachCameraToRig();\n\t\t\tthis.restoreCameraState();\n\t\t} else if (state.enabled) {\n\t\t\t// Still in debug mode, just update target\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t}\n\t}\n\n\tprivate enableOrbitControls() {\n\t\tif (this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls = new OrbitControls(this.camera, this.domElement);\n\t\tthis.orbitControls.enableDamping = true;\n\t\tthis.orbitControls.dampingFactor = 0.05;\n\t\tthis.orbitControls.screenSpacePanning = false;\n\t\tthis.orbitControls.minDistance = 1;\n\t\tthis.orbitControls.maxDistance = 500;\n\t\tthis.orbitControls.maxPolarAngle = Math.PI / 2;\n\t\t// Default target to origin\n\t\tthis.orbitControls.target.set(0, 0, 0);\n\t}\n\n\tprivate disableOrbitControls() {\n\t\tif (!this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls.dispose();\n\t\tthis.orbitControls = null;\n\t}\n\n\tprivate updateOrbitTargetFromSelection(selected: string[]) {\n\t\t// Default to origin when no entity is selected\n\t\tif (!this.debugDelegate || selected.length === 0) {\n\t\t\tthis.orbitTarget = null;\n\t\t\tif (this.orbitControls) {\n\t\t\t\tthis.orbitControls.target.set(0, 0, 0);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tfor (let i = selected.length - 1; i >= 0; i -= 1) {\n\t\t\tconst uuid = selected[i];\n\t\t\tconst targetObject = this.debugDelegate.resolveTarget(uuid);\n\t\t\tif (targetObject) {\n\t\t\t\tthis.orbitTarget = targetObject;\n\t\t\t\tif (this.orbitControls) {\n\t\t\t\t\ttargetObject.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.orbitTarget = null;\n\t}\n\n\tprivate detachDebugDelegate() {\n\t\tif (this.debugUnsubscribe) {\n\t\t\ttry {\n\t\t\t\tthis.debugUnsubscribe();\n\t\t\t} catch { /* noop */ }\n\t\t}\n\t\tthis.debugUnsubscribe = null;\n\t\tthis.debugDelegate = null;\n\t}\n\n\t/**\n\t * Save camera position, rotation, and zoom before entering debug mode.\n\t */\n\tprivate saveCameraState() {\n\t\tthis.savedCameraPosition = this.camera.position.clone();\n\t\tthis.savedCameraQuaternion = this.camera.quaternion.clone();\n\t\t// Save zoom for orthographic/perspective cameras\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t}\n\n\t/**\n\t * Restore camera position, rotation, and zoom when exiting debug mode.\n\t */\n\tprivate restoreCameraState() {\n\t\tif (this.savedCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraPosition);\n\t\t\tthis.savedCameraPosition = null;\n\t\t}\n\t\tif (this.savedCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedCameraQuaternion);\n\t\t\tthis.savedCameraQuaternion = null;\n\t\t}\n\t\tif (this.savedCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t\tthis.savedCameraZoom = null;\n\t\t}\n\t}\n\n\t/**\n\t * Save debug camera state when exiting debug mode.\n\t */\n\tprivate saveDebugCameraState() {\n\t\tthis.savedDebugCameraPosition = this.camera.position.clone();\n\t\tthis.savedDebugCameraQuaternion = this.camera.quaternion.clone();\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedDebugCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t\tif (this.orbitControls) {\n\t\t\tthis.savedDebugOrbitTarget = this.orbitControls.target.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Restore debug camera state when re-entering debug mode.\n\t */\n\tprivate restoreDebugCameraState() {\n\t\tif (this.savedDebugCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedDebugCameraPosition);\n\t\t}\n\t\tif (this.savedDebugCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedDebugCameraQuaternion);\n\t\t}\n\t\tif (this.savedDebugCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedDebugCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t}\n\t\tif (this.savedDebugOrbitTarget && this.orbitControls) {\n\t\t\tthis.orbitControls.target.copy(this.savedDebugOrbitTarget);\n\t\t}\n\t}\n\n\t/**\n\t * Detach camera from its rig to allow free orbit movement in debug mode.\n\t * Preserves the camera's world position.\n\t */\n\tprivate detachCameraFromRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent !== this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Save the camera's local position for later restoration\n\t\tthis.savedCameraLocalPosition = this.camera.position.clone();\n\n\t\t// Get camera's world position before detaching\n\t\tconst worldPos = new Vector3();\n\t\tthis.camera.getWorldPosition(worldPos);\n\n\t\t// Remove camera from rig\n\t\tthis.cameraRig.remove(this.camera);\n\n\t\t// Add camera directly to scene if scene ref is available\n\t\tif (this.sceneRef) {\n\t\t\tthis.sceneRef.add(this.camera);\n\t\t}\n\n\t\t// Set camera's position to its previous world position\n\t\tthis.camera.position.copy(worldPos);\n\t}\n\n\t/**\n\t * Reattach camera to its rig when exiting debug mode.\n\t * Restores the camera's local position relative to the rig.\n\t */\n\tprivate reattachCameraToRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent === this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove camera from scene if it's there\n\t\tif (this.sceneRef && this.camera.parent === this.sceneRef) {\n\t\t\tthis.sceneRef.remove(this.camera);\n\t\t}\n\n\t\t// Add camera back to rig\n\t\tthis.cameraRig.add(this.camera);\n\n\t\t// Restore camera's local position\n\t\tif (this.savedCameraLocalPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraLocalPosition);\n\t\t\tthis.savedCameraLocalPosition = null;\n\t\t}\n\t}\n}\n","import { Vector2, WebGLRenderer, Scene, Camera, PerspectiveCamera } from 'three';\nimport { WebGPURenderer } from 'three/webgpu';\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport RenderPass from '../graphics/render-pass';\nimport type { ZylemCamera } from './zylem-camera';\n\n/**\n * Renderer type option for choosing rendering backend\n * - 'auto': Try WebGPU first, fall back to WebGL\n * - 'webgpu': Force WebGPU (error if not supported)\n * - 'webgl': Force WebGL\n */\nexport type RendererType = 'auto' | 'webgpu' | 'webgl';\n\n/**\n * Union type for renderer instances\n */\nexport type ZylemRenderer = WebGLRenderer | WebGPURenderer;\n\n/**\n * Viewport definition in normalized coordinates (0-1).\n * Represents a rectangular region of the canvas for camera rendering.\n */\nexport interface Viewport {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\n/** Default fullscreen viewport */\nexport const DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, width: 1, height: 1 };\n\n/**\n * Check if WebGPU is supported in the current browser\n */\nexport async function isWebGPUSupported(): Promise<boolean> {\n\tif (!('gpu' in navigator)) return false;\n\ttry {\n\t\tconst adapter = await (navigator as any).gpu.requestAdapter();\n\t\treturn adapter !== null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * RendererManager owns the shared WebGL/WebGPU renderer, canvas element,\n * effect composer, and render loop. There is one RendererManager per game.\n *\n * It iterates active cameras and renders each with its configured viewport.\n */\nexport class RendererManager {\n\trenderer!: ZylemRenderer;\n\tcomposer!: EffectComposer;\n\tscreenResolution: Vector2;\n\trendererType: RendererType;\n\tprivate _isWebGPU = false;\n\tprivate _initialized = false;\n\tprivate _sceneRef: Scene | null = null;\n\n\tconstructor(screenResolution?: Vector2, rendererType: RendererType = 'webgl') {\n\t\tthis.screenResolution = screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\t\tthis.rendererType = rendererType;\n\t}\n\n\t/**\n\t * Check if the renderer has been initialized\n\t */\n\tget initialized(): boolean {\n\t\treturn this._initialized;\n\t}\n\n\t/**\n\t * Check if using WebGPU renderer\n\t */\n\tget isWebGPU(): boolean {\n\t\treturn this._isWebGPU;\n\t}\n\n\t/**\n\t * Initialize the renderer (must be called before rendering).\n\t * Async because WebGPU requires async initialization.\n\t */\n\tasync initRenderer(): Promise<void> {\n\t\tif (this._initialized) return;\n\n\t\tlet useWebGPU = false;\n\n\t\tif (this.rendererType === 'webgpu') {\n\t\t\tuseWebGPU = true;\n\t\t} else if (this.rendererType === 'auto') {\n\t\t\tuseWebGPU = await isWebGPUSupported();\n\t\t}\n\n\t\tif (useWebGPU) {\n\t\t\ttry {\n\t\t\t\tthis.renderer = new WebGPURenderer({ antialias: true });\n\t\t\t\tawait this.renderer.init();\n\t\t\t\tthis._isWebGPU = true;\n\t\t\t\tconsole.log('RendererManager: Using WebGPU renderer');\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn('RendererManager: WebGPU init failed, falling back to WebGL', e);\n\t\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\t\tthis._isWebGPU = false;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\tthis._isWebGPU = false;\n\t\t\tconsole.log('RendererManager: Using WebGL renderer');\n\t\t}\n\n\t\tthis.renderer.setSize(this.screenResolution.x, this.screenResolution.y);\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.shadowMap.enabled = true;\n\t\t}\n\n\t\t// Initialize composer (WebGPU uses different post-processing)\n\t\tif (!this._isWebGPU) {\n\t\t\tthis.composer = new EffectComposer(this.renderer as WebGLRenderer);\n\t\t}\n\n\t\tthis._initialized = true;\n\t}\n\n\t/**\n\t * Set the current scene reference for rendering.\n\t */\n\tsetScene(scene: Scene): void {\n\t\tthis._sceneRef = scene;\n\t}\n\n\t/**\n\t * Setup post-processing render pass for a camera (WebGL only).\n\t */\n\tsetupRenderPass(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU || !this.composer) return;\n\n\t\t// Dispose old passes before adding new ones (prevents GPU leak on stage transitions)\n\t\tif (this.composer.passes.length > 0) {\n\t\t\tthis.composer.passes.forEach((p: any) => { try { p.dispose?.(); } catch { /* noop */ } });\n\t\t\tthis.composer.passes.length = 0;\n\t\t}\n\n\t\tconst renderResolution = this.screenResolution.clone().divideScalar(2);\n\t\trenderResolution.x |= 0;\n\t\trenderResolution.y |= 0;\n\t\tconst pass = new RenderPass(renderResolution, scene, camera);\n\t\tthis.composer.addPass(pass);\n\t}\n\n\t/**\n\t * Start the render loop. Calls the provided callback each frame.\n\t */\n\tstartRenderLoop(onFrame: (delta: number) => void): void {\n\t\tthis.renderer.setAnimationLoop((delta: number) => {\n\t\t\tonFrame(delta || 0);\n\t\t});\n\t}\n\n\t/**\n\t * Stop the render loop.\n\t */\n\tstopRenderLoop(): void {\n\t\ttry {\n\t\t\tthis.renderer.setAnimationLoop(null as any);\n\t\t} catch { /* noop */ }\n\t}\n\n\t/**\n\t * Render a scene from a single camera's perspective.\n\t * Sets the viewport based on the camera's viewport config.\n\t */\n\trenderCamera(scene: Scene, camera: ZylemCamera): void {\n\t\tconst vp = camera.viewport;\n\t\tconst w = this.screenResolution.x;\n\t\tconst h = this.screenResolution.y;\n\n\t\t// Set scissor and viewport for this camera\n\t\tconst pixelX = Math.floor(vp.x * w);\n\t\tconst pixelY = Math.floor(vp.y * h);\n\t\tconst pixelW = Math.floor(vp.width * w);\n\t\tconst pixelH = Math.floor(vp.height * h);\n\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setViewport(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissor(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissorTest(true);\n\t\t}\n\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera.camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Render a scene from multiple cameras, each with their own viewport.\n\t * Cameras are rendered in order (first = bottom layer, last = top layer).\n\t */\n\trenderCameras(scene: Scene, cameras: ZylemCamera[]): void {\n\t\tif (!scene || cameras.length === 0) return;\n\n\t\t// Clear the full canvas first\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t\tthis.renderer.clear();\n\t\t}\n\n\t\tfor (const cam of cameras) {\n\t\t\tthis.renderCamera(scene, cam);\n\t\t}\n\n\t\t// Restore scissor test state\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t}\n\t}\n\n\t/**\n\t * Simple single-camera render (backwards compatible).\n\t * Uses the full viewport for a single camera.\n\t */\n\trender(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Resize the renderer and update resolution.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\t\tthis.renderer.setSize(width, height, false);\n\t\tif (this.composer) {\n\t\t\tthis.composer.setSize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Update renderer pixel ratio (DPR).\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tconst safe = Math.max(1, Number.isFinite(dpr) ? dpr : 1);\n\t\tthis.renderer.setPixelRatio(safe);\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\treturn this.renderer.domElement;\n\t}\n\n\t/**\n\t * Dispose renderer, composer, and related resources.\n\t */\n\tdispose(): void {\n\t\tthis.stopRenderLoop();\n\t\ttry {\n\t\t\tthis.composer?.passes?.forEach((p: any) => p.dispose?.());\n\t\t\t(this.composer as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderer.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis._sceneRef = null;\n\t\tthis._initialized = false;\n\t}\n}\n","import * as THREE from 'three';\nimport { standardShader } from './shaders/standard.shader';\nimport { WebGLRenderer, WebGLRenderTarget } from 'three';\nimport { Pass, FullScreenQuad } from 'three/addons/postprocessing/Pass.js';\n\nexport default class RenderPass extends Pass {\n\tfsQuad: FullScreenQuad;\n\tresolution: THREE.Vector2;\n\tscene: THREE.Scene;\n\tcamera: THREE.Camera;\n\trgbRenderTarget: WebGLRenderTarget;\n\tnormalRenderTarget: WebGLRenderTarget;\n\tnormalMaterial: THREE.Material;\n\n\tconstructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera) {\n\t\tsuper();\n\t\tthis.resolution = resolution;\n\t\tthis.fsQuad = new FullScreenQuad(this.material());\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.rgbRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\t\tthis.normalRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\n\t\tthis.normalMaterial = new THREE.MeshNormalMaterial();\n\t}\n\n\trender(\n\t\trenderer: WebGLRenderer,\n\t\twriteBuffer: WebGLRenderTarget\n\t) {\n\t\trenderer.setRenderTarget(this.rgbRenderTarget);\n\t\trenderer.render(this.scene, this.camera);\n\n\t\tconst overrideMaterial_old = this.scene.overrideMaterial;\n\t\trenderer.setRenderTarget(this.normalRenderTarget);\n\t\tthis.scene.overrideMaterial = this.normalMaterial;\n\t\trenderer.render(this.scene, this.camera);\n\t\tthis.scene.overrideMaterial = overrideMaterial_old;\n\n\t\t// @ts-ignore\n\t\tconst uniforms = this.fsQuad.material.uniforms;\n\t\tuniforms.tDiffuse.value = this.rgbRenderTarget.texture;\n\t\tuniforms.tDepth.value = this.rgbRenderTarget.depthTexture;\n\t\tuniforms.tNormal.value = this.normalRenderTarget.texture;\n\t\tuniforms.iTime.value += 0.01;\n\n\t\tif (this.renderToScreen) {\n\t\t\trenderer.setRenderTarget(null);\n\t\t} else {\n\t\t\trenderer.setRenderTarget(writeBuffer);\n\t\t}\n\t\tthis.fsQuad.render(renderer);\n\t}\n\n\tmaterial() {\n\t\treturn new THREE.ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tresolution: {\n\t\t\t\t\tvalue: new THREE.Vector4(\n\t\t\t\t\t\tthis.resolution.x,\n\t\t\t\t\t\tthis.resolution.y,\n\t\t\t\t\t\t1 / this.resolution.x,\n\t\t\t\t\t\t1 / this.resolution.y,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t},\n\t\t\tvertexShader: standardShader.vertex,\n\t\t\tfragmentShader: standardShader.fragment\n\t\t});\n\t}\n\n\tdispose() {\n\t\ttry {\n\t\t\tthis.fsQuad?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.rgbRenderTarget as any)?.dispose?.();\n\t\t\t(this.normalRenderTarget as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.normalMaterial as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t}\n}\n","import { Vector2, Scene } from 'three';\nimport { ZylemCamera } from './zylem-camera';\nimport { RendererManager } from './renderer-manager';\nimport { Perspectives } from './perspective';\nimport { nanoid } from 'nanoid';\n\n/**\n * CameraManager orchestrates multiple cameras per stage.\n *\n * Responsibilities:\n * - Named camera registry (add/remove/get by name or reference)\n * - Active camera list management (determines which cameras render)\n * - Always-available debug camera with orbit controls\n * - Per-frame update of all active cameras' perspective controllers\n * - Coordinating rendering via RendererManager for all active viewports\n */\nexport class CameraManager {\n\t/** Named camera registry */\n\tprivate cameras: Map<string, ZylemCamera> = new Map();\n\n\t/** Currently active cameras, ordered by render layer (first = bottom) */\n\tprivate _activeCameras: ZylemCamera[] = [];\n\n\t/** Auto-created debug camera with orbit controls */\n\tprivate _debugCamera: ZylemCamera | null = null;\n\n\t/** Reference to the shared renderer manager */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\t/** Scene reference */\n\tprivate _sceneRef: Scene | null = null;\n\n\t/** Counter for auto-generated camera names */\n\tprivate _autoNameCounter = 0;\n\n\tconstructor() {\n\t\t// Debug camera is created lazily during setup when we have screen resolution\n\t}\n\n\t/**\n\t * Get the list of currently active cameras.\n\t */\n\tget activeCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn this._activeCameras;\n\t}\n\n\t/**\n\t * Get the primary active camera (first in the active list).\n\t */\n\tget primaryCamera(): ZylemCamera | null {\n\t\treturn this._activeCameras.length > 0 ? this._activeCameras[0] : null;\n\t}\n\n\t/**\n\t * Get the debug camera.\n\t */\n\tget debugCamera(): ZylemCamera | null {\n\t\treturn this._debugCamera;\n\t}\n\n\t/**\n\t * Get all registered cameras.\n\t */\n\tget allCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn Array.from(this.cameras.values());\n\t}\n\n\t/**\n\t * Add a camera to the manager.\n\t * If no name is provided, one is auto-generated.\n\t * The first camera added becomes the active camera.\n\t *\n\t * @param camera The ZylemCamera instance to add\n\t * @param name Optional name for lookup\n\t * @returns The assigned name\n\t */\n\taddCamera(camera: ZylemCamera, name?: string): string {\n\t\tconst resolvedName = name || camera.name || `camera_${this._autoNameCounter++}`;\n\t\tcamera.name = resolvedName;\n\t\tthis.cameras.set(resolvedName, camera);\n\n\t\t// First camera added automatically becomes active\n\t\tif (this._activeCameras.length === 0) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\n\t\treturn resolvedName;\n\t}\n\n\t/**\n\t * Remove a camera by name or reference.\n\t * Cannot remove the debug camera via this method.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tlet name: string | undefined;\n\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\tname = nameOrRef;\n\t\t} else {\n\t\t\t// Find by reference\n\t\t\tfor (const [key, cam] of this.cameras.entries()) {\n\t\t\t\tif (cam === nameOrRef) {\n\t\t\t\t\tname = key;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!name) return false;\n\n\t\tconst camera = this.cameras.get(name);\n\t\tif (!camera) return false;\n\n\t\t// Prevent removing the debug camera\n\t\tif (camera === this._debugCamera) {\n\t\t\tconsole.warn('CameraManager: Cannot remove the debug camera');\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.cameras.delete(name);\n\n\t\t// Remove from active cameras\n\t\tconst activeIndex = this._activeCameras.indexOf(camera);\n\t\tif (activeIndex !== -1) {\n\t\t\tthis._activeCameras.splice(activeIndex, 1);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set a camera as the primary active camera (replaces all active cameras\n\t * except additional viewport cameras).\n\t *\n\t * @param nameOrRef Camera name or reference to activate\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) {\n\t\t\tconsole.warn(`CameraManager: Camera not found: ${nameOrRef}`);\n\t\t\treturn false;\n\t\t}\n\n\t\t// Set as the sole active camera (keeping PiP cameras if any)\n\t\tconst pipCameras = this._activeCameras.filter(c => {\n\t\t\treturn c !== this._activeCameras[0] && c.viewport.width < 1;\n\t\t});\n\n\t\tthis._activeCameras = [camera, ...pipCameras];\n\t\treturn true;\n\t}\n\n\t/**\n\t * Add a camera as an additional active camera (for split-screen or PiP).\n\t */\n\taddActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tif (!this._activeCameras.includes(camera)) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a camera from the active render list (does not remove from registry).\n\t */\n\tdeactivateCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tconst index = this._activeCameras.indexOf(camera);\n\t\tif (index !== -1) {\n\t\t\tthis._activeCameras.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get a camera by name.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.cameras.get(name) ?? null;\n\t}\n\n\t/**\n\t * Setup all cameras with the given scene and renderer manager.\n\t * Also creates the debug camera.\n\t */\n\tasync setup(scene: Scene, rendererManager: RendererManager): Promise<void> {\n\t\tthis._sceneRef = scene;\n\t\tthis._rendererManager = rendererManager;\n\n\t\t// Create the debug camera\n\t\tthis.createDebugCamera(rendererManager.screenResolution);\n\n\t\t// Setup all registered cameras\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.setRendererManager(rendererManager);\n\t\t\tawait camera.setup(scene, rendererManager);\n\t\t}\n\n\t\t// Setup the debug camera\n\t\tif (this._debugCamera) {\n\t\t\tthis._debugCamera.setRendererManager(rendererManager);\n\t\t\tawait this._debugCamera.setup(scene, rendererManager);\n\t\t}\n\t}\n\n\t/**\n\t * Update all active cameras' controllers.\n\t */\n\tupdate(delta: number): void {\n\t\tfor (const camera of this._activeCameras) {\n\t\t\tcamera.update(delta);\n\t\t}\n\t}\n\n\t/**\n\t * Render all active cameras through the renderer manager.\n\t */\n\trender(scene: Scene): void {\n\t\tif (!this._rendererManager || this._activeCameras.length === 0) return;\n\t\tthis._rendererManager.renderCameras(scene, this._activeCameras as ZylemCamera[]);\n\t}\n\n\t/**\n\t * Create a default third-person camera if no cameras have been added.\n\t */\n\tensureDefaultCamera(): ZylemCamera {\n\t\tif (this.cameras.size === 0 || this._activeCameras.length === 0) {\n\t\t\tconst screenRes = this._rendererManager?.screenResolution\n\t\t\t\t|| new Vector2(window.innerWidth, window.innerHeight);\n\t\t\tconst defaultCam = new ZylemCamera(Perspectives.ThirdPerson, screenRes);\n\t\t\tthis.addCamera(defaultCam, 'default');\n\t\t\treturn defaultCam;\n\t\t}\n\t\treturn this._activeCameras[0];\n\t}\n\n\t/**\n\t * Dispose all cameras and cleanup.\n\t */\n\tdispose(): void {\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.destroy();\n\t\t}\n\t\tthis._debugCamera?.destroy();\n\t\tthis.cameras.clear();\n\t\tthis._activeCameras = [];\n\t\tthis._debugCamera = null;\n\t\tthis._rendererManager = null;\n\t\tthis._sceneRef = null;\n\t}\n\n\t/**\n\t * Create the always-available debug camera with orbit controls.\n\t */\n\tprivate createDebugCamera(screenResolution: Vector2): void {\n\t\tthis._debugCamera = new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t\tthis._debugCamera.name = '__debug__';\n\t\tthis._debugCamera.enableOrbitalControls();\n\t\t// Debug camera is NOT added to the active cameras by default;\n\t\t// it's activated via the debug system\n\t}\n\n\t/**\n\t * Resolve a camera from a name or reference.\n\t */\n\tprivate resolveCamera(nameOrRef: string | ZylemCamera): ZylemCamera | null {\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\treturn this.cameras.get(nameOrRef) ?? null;\n\t\t}\n\t\t// Check if the reference exists in our registry\n\t\tfor (const cam of this.cameras.values()) {\n\t\t\tif (cam === nameOrRef) return cam;\n\t\t}\n\t\treturn null;\n\t}\n}\n","import { LoadingEvent } from '../core/interfaces';\nimport { gameEventBus, StageLoadingPayload } from '../game/game-event-bus';\n\n/**\n * Event name for stage loading events.\n * Dispatched via window for cross-application communication.\n */\nexport const STAGE_LOADING_EVENT = 'STAGE_LOADING_EVENT';\n\n/**\n * Delegate for managing loading events and progress within a stage.\n * Handles subscription to loading events and broadcasting progress.\n * Emits to game event bus for game-level observation.\n */\nexport class StageLoadingDelegate {\n\tprivate loadingHandlers: Array<(event: LoadingEvent) => void> = [];\n\tprivate stageName?: string;\n\tprivate stageIndex?: number;\n\n\t/**\n\t * Set stage context for event bus emissions.\n\t */\n\tsetStageContext(stageName: string, stageIndex: number): void {\n\t\tthis.stageName = stageName;\n\t\tthis.stageIndex = stageIndex;\n\t}\n\n\t/**\n\t * Subscribe to loading events.\n\t * \n\t * @param callback Invoked for each loading event (start, progress, complete)\n\t * @returns Unsubscribe function\n\t */\n\tonLoading(callback: (event: LoadingEvent) => void): () => void {\n\t\tthis.loadingHandlers.push(callback);\n\t\treturn () => {\n\t\t\tthis.loadingHandlers = this.loadingHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\t/**\n\t * Emit a loading event to all subscribers and to the game event bus.\n\t * \n\t * @param event The loading event to broadcast\n\t */\n\temit(event: LoadingEvent): void {\n\t\t// Dispatch to direct subscribers\n\t\tfor (const handler of this.loadingHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(event);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Loading handler failed', e);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Emit to game event bus for game-level observation\n\t\tconst payload: StageLoadingPayload = {\n\t\t\t...event,\n\t\t\tstageName: this.stageName,\n\t\t\tstageIndex: this.stageIndex,\n\t\t};\n\t\t\n\t\tif (event.type === 'start') {\n\t\t\tgameEventBus.emit('stage:loading:start', payload);\n\t\t} else if (event.type === 'progress') {\n\t\t\tgameEventBus.emit('stage:loading:progress', payload);\n\t\t} else if (event.type === 'complete') {\n\t\t\tgameEventBus.emit('stage:loading:complete', payload);\n\t\t}\n\t}\n\n\t/**\n\t * Emit a start loading event.\n\t */\n\temitStart(message: string = 'Loading stage...'): void {\n\t\tthis.emit({ type: 'start', message, progress: 0 });\n\t}\n\n\t/**\n\t * Emit a progress loading event.\n\t */\n\temitProgress(message: string, current: number, total: number): void {\n\t\tconst progress = total > 0 ? current / total : 0;\n\t\tthis.emit({ type: 'progress', message, progress, current, total });\n\t}\n\n\t/**\n\t * Emit a complete loading event.\n\t */\n\temitComplete(message: string = 'Stage loaded'): void {\n\t\tthis.emit({ type: 'complete', message, progress: 1 });\n\t}\n\n\t/**\n\t * Clear all loading handlers.\n\t */\n\tdispose(): void {\n\t\tthis.loadingHandlers = [];\n\t}\n}\n","import { zylemEventBus } from '../events';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { GameEntity } from '../entities/entity';\n\n/**\n * Delegate for handling deferred model loading in entities.\n * Subscribes to model:loaded events and adds entity groups to the scene\n * when they become available after async loading completes.\n */\nexport class StageEntityModelDelegate {\n\tprivate scene: ZylemScene | null = null;\n\tprivate pendingEntities: Map<string, GameEntity<any>> = new Map();\n\tprivate modelLoadedHandler: ((payload: { entityId: string; success: boolean }) => void) | null = null;\n\n\t/**\n\t * Initialize the delegate with the scene reference and start listening.\n\t */\n\tattach(scene: ZylemScene): void {\n\t\tthis.scene = scene;\n\t\tthis.modelLoadedHandler = (payload) => {\n\t\t\tthis.handleModelLoaded(payload.entityId, payload.success);\n\t\t};\n\t\tzylemEventBus.on('entity:model:loaded', this.modelLoadedHandler);\n\t}\n\n\t/**\n\t * Register an entity for observation.\n\t * When its model loads, the group will be added to the scene.\n\t */\n\tobserve(entity: GameEntity<any>): void {\n\t\tthis.pendingEntities.set(entity.uuid, entity);\n\t}\n\n\t/**\n\t * Unregister an entity (e.g., when removed before model loads).\n\t */\n\tunobserve(entityId: string): void {\n\t\tthis.pendingEntities.delete(entityId);\n\t}\n\n\t/**\n\t * Handle model loaded event - add group to scene if entity is pending.\n\t */\n\tprivate handleModelLoaded(entityId: string, success: boolean): void {\n\t\tconst entity = this.pendingEntities.get(entityId);\n\t\tif (!entity || !success) {\n\t\t\tthis.pendingEntities.delete(entityId);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.scene?.addEntityGroup(entity);\n\t\tthis.pendingEntities.delete(entityId);\n\t}\n\n\t/**\n\t * Cleanup all subscriptions and pending entities.\n\t */\n\tdispose(): void {\n\t\tif (this.modelLoadedHandler) {\n\t\t\tzylemEventBus.off('entity:model:loaded', this.modelLoadedHandler);\n\t\t\tthis.modelLoadedHandler = null;\n\t\t}\n\t\tthis.pendingEntities.clear();\n\t\tthis.scene = null;\n\t}\n}\n","import { Color, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { CameraWrapper } from '../camera/camera';\nimport { isBaseNode, isCameraWrapper, isConfigObject, isEntityInput } from '../core/utility/options-parser';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport type { ZylemShader } from '../graphics/material';\n\n/**\n * Stage configuration type for user-facing options.\n */\nexport type StageConfigLike = Partial<{\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader: ZylemShader;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\n}>;\n\n/**\n * Internal stage configuration class.\n */\nexport class StageConfig {\n\tconstructor(\n\t\tpublic inputs: Record<string, string[]>,\n\t\tpublic backgroundColor: Color | string,\n\t\tpublic backgroundImage: string | null,\n\t\tpublic backgroundShader: ZylemShader | null,\n\t\tpublic gravity: Vector3,\n\t\tpublic variables: Record<string, any>,\n\t) { }\n}\n\n/**\n * Create default stage configuration.\n */\nexport function createDefaultStageConfig(): StageConfig {\n\treturn new StageConfig(\n\t\t{\n\t\t\tp1: ['gamepad-1', 'keyboard-1'],\n\t\t\tp2: ['gamepad-2', 'keyboard-2'],\n\t\t},\n\t\tZylemBlueColor,\n\t\tnull,\n\t\tnull,\n\t\tnew Vector3(0, 0, 0),\n\t\t{},\n\t);\n}\n\n/**\n * Result of parsing stage options.\n */\nexport interface ParsedStageOptions {\n\tconfig: StageConfig;\n\tentities: BaseNode[];\n\tasyncEntities: Array<BaseNode | Promise<any> | (() => BaseNode | Promise<any>)>;\n\t/** @deprecated Use `cameras` array instead for multi-camera support */\n\tcamera?: CameraWrapper;\n\t/** All camera wrappers found in stage options */\n\tcameras: CameraWrapper[];\n}\n\n/**\n * Parse stage options array and resolve configuration.\n * Separates config objects, camera wrappers, and entity inputs.\n * \n * @param options Stage options array\n * @returns Parsed stage options with resolved config, entities, and camera\n */\nexport function parseStageOptions(options: any[] = []): ParsedStageOptions {\n\tconst defaults = createDefaultStageConfig();\n\tlet config: Partial<StageConfig> = {};\n\tconst entities: BaseNode[] = [];\n\tconst asyncEntities: Array<BaseNode | Promise<any> | (() => BaseNode | Promise<any>)> = [];\n\tconst cameras: CameraWrapper[] = [];\n\n\tfor (const item of options) {\n\t\tif (isCameraWrapper(item)) {\n\t\t\tcameras.push(item);\n\t\t} else if (isBaseNode(item)) {\n\t\t\tentities.push(item);\n\t\t} else if (isEntityInput(item) && !isBaseNode(item)) {\n\t\t\tasyncEntities.push(item);\n\t\t} else if (isConfigObject(item)) {\n\t\t\tconfig = { ...config, ...item };\n\t\t}\n\t}\n\n\t// Merge user config with defaults\n\tconst resolvedConfig = new StageConfig(\n\t\tconfig.inputs ?? defaults.inputs,\n\t\tconfig.backgroundColor ?? defaults.backgroundColor,\n\t\tconfig.backgroundImage ?? defaults.backgroundImage,\n\t\tconfig.backgroundShader ?? defaults.backgroundShader,\n\t\tconfig.gravity ?? defaults.gravity,\n\t\tconfig.variables ?? defaults.variables,\n\t);\n\n\t// Backward compat: first camera is the legacy `camera` field\n\tconst camera = cameras.length > 0 ? cameras[0] : undefined;\n\n\treturn { config: resolvedConfig, entities, asyncEntities, camera, cameras };\n}\n\n/**\n * Factory for authoring stage configuration objects in user code.\n * Returns a plain object that can be passed to `createStage(...)`.\n */\nexport function stageConfig(config: StageConfigLike): StageConfigLike {\n\treturn { ...config };\n}\n","import { BaseNode } from '../base-node';\nimport { CameraWrapper } from '../../camera/camera';\n\n/**\n * Check if an item is a BaseNode (has a create function).\n */\nexport function isBaseNode(item: unknown): item is BaseNode {\n\treturn !!item && typeof item === 'object' && typeof (item as any).create === 'function';\n}\n\n/**\n * Check if an item is a Promise-like (thenable).\n */\nexport function isThenable(item: unknown): item is Promise<any> {\n\treturn !!item && typeof (item as any).then === 'function';\n}\n\n/**\n * Check if an item is a CameraWrapper.\n */\nexport function isCameraWrapper(item: unknown): item is CameraWrapper {\n\treturn !!item && typeof item === 'object' && (item as any).constructor?.name === 'CameraWrapper';\n}\n\n/**\n * Check if an item is a plain config object (not a special type).\n * Excludes BaseNode, CameraWrapper, functions, and promises.\n */\nexport function isConfigObject(item: unknown): boolean {\n\tif (!item || typeof item !== 'object') return false;\n\tif (isBaseNode(item)) return false;\n\tif (isCameraWrapper(item)) return false;\n\tif (isThenable(item)) return false;\n\tif (typeof (item as any).then === 'function') return false;\n\t// Must be a plain object\n\treturn (item as any).constructor === Object || (item as any).constructor?.name === 'Object';\n}\n\n/**\n * Check if an item is an entity input (BaseNode, Promise, or factory function).\n */\nexport function isEntityInput(item: unknown): boolean {\n\tif (!item) return false;\n\tif (isBaseNode(item)) return true;\n\tif (typeof item === 'function') return true;\n\tif (isThenable(item)) return true;\n\treturn false;\n}\n","import { RigidBody } from '@dimforge/rapier3d-compat';\nimport { TransformState } from './transform-store';\n\n/**\n * Entity that can have transformations applied from a store\n */\nexport interface TransformableEntity {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Apply accumulated transformations from the store to the physics body.\n * \n * This is called automatically after onUpdate() callbacks complete,\n * flushing all pending transformations to the physics engine in a single batch.\n * \n * Flow:\n * 1. Check dirty flags to see what changed\n * 2. Apply changes to RigidBody\n * 3. Reset store for next frame\n * \n * @param entity Entity with physics body and transform store\n * @param store Transform store containing pending changes\n */\nexport function applyTransformChanges(\n\tentity: TransformableEntity,\n\tstore: TransformState\n): void {\n\tif (!entity.body) return;\n\n\t// Apply velocity if dirty\n\tif (store.dirty.velocity) {\n\t\tentity.body.setLinvel(store.velocity, true);\n\t}\n\n\t// Apply rotation if dirty\n\tif (store.dirty.rotation) {\n\t\tentity.body.setRotation(store.rotation, true);\n\t}\n\n\t// Apply angular velocity if dirty\n\tif (store.dirty.angularVelocity) {\n\t\tentity.body.setAngvel(store.angularVelocity, true);\n\t}\n\n\t// Apply position deltas if dirty\n\tif (store.dirty.position) {\n\t\tconst current = entity.body.translation();\n\t\tentity.body.setTranslation(\n\t\t\t{\n\t\t\t\tx: current.x + store.position.x,\n\t\t\t\ty: current.y + store.position.y,\n\t\t\t\tz: current.z + store.position.z,\n\t\t\t},\n\t\t\ttrue\n\t\t);\n\t}\n}\n","import { BaseNode } from './base-node';\nimport {\n\tSetupContext,\n\tUpdateContext,\n\tDestroyContext,\n\tLoadedContext,\n\tCleanupContext,\n} from './base-node-life-cycle';\nimport type { NodeInterface } from './node-interface';\n\nconst VESSEL_TYPE = Symbol('vessel');\n\n/**\n * A Vessel is an empty container entity that holds child entities.\n * It has no geometry, physics, or rendering of its own, but propagates\n * lifecycle events to its children and provides a logical grouping mechanism.\n *\n * Child entities added to a Vessel will be individually spawned into the\n * stage's physics world and render scene when the Vessel is spawned.\n */\nexport class Vessel extends BaseNode<{}, Vessel> {\n\tstatic type = VESSEL_TYPE;\n\n\tprotected _setup(_params: SetupContext<this>): void { }\n\n\tprotected async _loaded(_params: LoadedContext<this>): Promise<void> { }\n\n\tprotected _update(_params: UpdateContext<this>): void { }\n\n\tprotected _destroy(_params: DestroyContext<this>): void { }\n\n\tprotected _cleanup(_params: CleanupContext<this>): void { }\n\n\tpublic create(): this {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add one or more child entities to this vessel.\n\t * Overrides parent to support multiple arguments.\n\t * @returns this for chaining\n\t */\n\tpublic add(...nodes: NodeInterface[]): this {\n\t\tfor (const node of nodes) {\n\t\t\tsuper.add(node);\n\t\t}\n\t\treturn this;\n\t}\n}\n\n/**\n * Create a vessel containing the given child entities.\n * @param args Child BaseNode entities to add\n * @returns A new Vessel with the children added\n */\nexport function vessel(...args: Array<BaseNode>): Vessel {\n\tconst instance = new Vessel();\n\targs.forEach(arg => instance.add(arg));\n\treturn instance;\n}\n","import { Vector2, Vector3 } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\nimport { RendererType, Viewport, DEFAULT_VIEWPORT } from \"./renderer-manager\";\nimport { StageEntity } from \"../interfaces/entity\";\n\nexport interface CameraOptions {\n\tperspective?: PerspectiveType;\n\tposition?: Vector3 | { x: number; y: number; z: number };\n\ttarget?: Vector3 | { x: number; y: number; z: number } | any;\n\tzoom?: number;\n\tscreenResolution?: Vector2;\n\t/**\n\t * Renderer type: 'auto' | 'webgpu' | 'webgl'\n\t * Use 'webgpu' for TSL shaders\n\t * @default 'webgl'\n\t */\n\trendererType?: RendererType;\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Can be toggled at runtime via enableOrbitalControls() / disableOrbitalControls().\n\t * @default false\n\t */\n\tuseOrbitalControls?: boolean;\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Defines where this camera renders on the canvas.\n\t * @default { x: 0, y: 0, width: 1, height: 1 } (fullscreen)\n\t */\n\tviewport?: Viewport;\n\t/**\n\t * Optional name for camera manager lookup.\n\t */\n\tname?: string;\n}\n\n/**\n * CameraWrapper is the user-facing camera handle returned by createCamera().\n * It provides convenience methods for target management, orbital controls, and viewport configuration.\n */\nexport class CameraWrapper {\n\tcameraRef: ZylemCamera;\n\n\tconstructor(camera: ZylemCamera) {\n\t\tthis.cameraRef = camera;\n\t}\n\n\t// ─── Target management ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t * With multiple targets, the camera auto-frames to include all of them.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.addTarget(entity);\n\t}\n\n\t/**\n\t * Remove a target entity from the camera.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.removeTarget(entity);\n\t}\n\n\t/**\n\t * Clear all targets. Camera will look at world origin.\n\t */\n\tclearTargets(): void {\n\t\tthis.cameraRef.clearTargets();\n\t}\n\n\t// ─── Orbital controls ───────────────────────────────────────────────────\n\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Allows the user to orbit, pan, and zoom the camera.\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis.cameraRef.enableOrbitalControls();\n\t}\n\n\t/**\n\t * Disable orbital controls for this camera.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis.cameraRef.disableOrbitalControls();\n\t}\n\n\t// ─── Viewport ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t * @param x Left edge (0 = left of canvas)\n\t * @param y Bottom edge (0 = bottom of canvas)\n\t * @param width Width as fraction of canvas\n\t * @param height Height as fraction of canvas\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.cameraRef.setViewport(x, y, width, height);\n\t}\n}\n\n/**\n * Create a camera with the given options.\n * Returns a CameraWrapper for convenient access to camera features.\n */\nexport function createCamera(options: CameraOptions): CameraWrapper {\n\tconst screenResolution = options.screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\tlet frustumSize = 10;\n\tif (options.perspective === 'fixed-2d') {\n\t\tfrustumSize = options.zoom || 10;\n\t}\n\tconst zylemCamera = new ZylemCamera(\n\t\toptions.perspective || 'third-person',\n\t\tscreenResolution,\n\t\tfrustumSize,\n\t\toptions.rendererType || 'webgl'\n\t);\n\n\t// Set camera name if provided\n\tif (options.name) {\n\t\tzylemCamera.name = options.name;\n\t}\n\n\t// Set initial position and target\n\tconst position = options.position \n\t\t? (options.position instanceof Vector3 ? options.position : new Vector3(options.position.x, options.position.y, options.position.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tconst target = options.target\n\t\t? (options.target instanceof Vector3 ? options.target : new Vector3(options.target.x, options.target.y, options.target.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tzylemCamera.move(position);\n\tzylemCamera.camera.lookAt(target);\n\n\t// Set viewport if provided\n\tif (options.viewport) {\n\t\tzylemCamera.viewport = { ...options.viewport };\n\t}\n\n\t// Configure orbital controls\n\tif (options.useOrbitalControls) {\n\t\t// Mark for enablement -- actual OrbitControls are created during setup()\n\t\t// when the renderer DOM element is available\n\t\t(zylemCamera as any)._useOrbitalControls = true;\n\t}\n\n\treturn new CameraWrapper(zylemCamera);\n}\n","import { proxy } from 'valtio/vanilla';\nimport { Vector3 } from 'three';\nimport type { StageOptions, ZylemStageConfig } from './zylem-stage';\nimport { ZylemBlueColor } from '../core/utility/vector';\n\n/**\n * Reactive defaults for building `Stage` instances. These values are applied\n * automatically by the `stage()` builder and can be changed at runtime to\n * influence future stage creations.\n */\nconst initialDefaults: Partial<ZylemStageConfig> = {\n\tbackgroundColor: ZylemBlueColor,\n\tbackgroundImage: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard'],\n\t\tp2: ['gamepad-2', 'keyboard'],\n\t},\n\tgravity: new Vector3(0, 0, 0),\n\tvariables: {},\n};\n\nconst stageDefaultsState = proxy<Partial<ZylemStageConfig>>({\n\t...initialDefaults,\n});\n\n/** Replace multiple defaults at once (shallow merge). */\nfunction setStageDefaults(partial: Partial<ZylemStageConfig>): void {\n\tObject.assign(stageDefaultsState, partial);\n}\n\n/** Reset defaults back to library defaults. */\nfunction resetStageDefaults(): void {\n\tObject.assign(stageDefaultsState, initialDefaults);\n}\n\nexport function getStageOptions(options: StageOptions): StageOptions {\n\tconst defaults = getStageDefaultConfig();\n\tlet originalConfig = {};\n\tif (typeof options[0] === 'object') {\n\t\toriginalConfig = options.shift() ?? {};\n\t}\n\tconst combinedConfig = { ...defaults, ...originalConfig };\n\treturn [combinedConfig, ...options] as StageOptions;\n}\n\n/** Get a plain object copy of the current defaults. */\nfunction getStageDefaultConfig(): Partial<ZylemStageConfig> {\n\treturn {\n\t\tbackgroundColor: stageDefaultsState.backgroundColor,\n\t\tbackgroundImage: stageDefaultsState.backgroundImage ?? null,\n\t\tinputs: stageDefaultsState.inputs ? { ...stageDefaultsState.inputs } : undefined,\n\t\tgravity: stageDefaultsState.gravity,\n\t\tvariables: stageDefaultsState.variables ? { ...stageDefaultsState.variables } : undefined,\n\t};\n}\n\n\n","import { InputPlayer } from './input';\nimport { GameInputConfig, GameInputPlayerConfig, KeyboardMapping } from '../game/game-interfaces';\n\n/**\n * Creates a GameInputConfig scoped to a single player.\n */\nfunction playerKeyMapping(player: InputPlayer, keyMapping: KeyboardMapping): GameInputConfig {\n\treturn { [player]: { key: keyMapping } } as GameInputConfig;\n}\n\n/**\n * Maps arrow keys to axes (Horizontal/Vertical) for the given player.\n * @example stage.setInputConfiguration(useArrowsForAxes('p1'));\n */\nexport function useArrowsForAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'ArrowLeft': ['axes.Left'],\n\t\t'ArrowRight': ['axes.Right'],\n\t\t'ArrowUp': ['axes.Up'],\n\t\t'ArrowDown': ['axes.Down'],\n\t});\n}\n\n/**\n * Maps arrow keys to directions (Up/Down/Left/Right) for the given player.\n * Useful when `includeDefaults` is false and you still want arrow-key directions.\n * @example stage.setInputConfiguration(useArrowsForDirections('p1'));\n */\nexport function useArrowsForDirections(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'ArrowLeft': ['directions.Left'],\n\t\t'ArrowRight': ['directions.Right'],\n\t\t'ArrowUp': ['directions.Up'],\n\t\t'ArrowDown': ['directions.Down'],\n\t});\n}\n\n/**\n * Maps W/A/S/D keys to directions (Up/Down/Left/Right) for the given player.\n * @example stage.setInputConfiguration(useWASDForDirections('p1'));\n */\nexport function useWASDForDirections(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'w': ['directions.Up'],\n\t\t's': ['directions.Down'],\n\t\t'a': ['directions.Left'],\n\t\t'd': ['directions.Right'],\n\t});\n}\n\n/**\n * Maps W/A/S/D keys to axes (Horizontal/Vertical) for the given player.\n * @example stage.setInputConfiguration(useWASDForAxes('p1'));\n */\nexport function useWASDForAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'a': ['axes.Left'],\n\t\t'd': ['axes.Right'],\n\t\t'w': ['axes.Up'],\n\t\t's': ['axes.Down'],\n\t});\n}\n\n/**\n * Maps I/J/K/L keys to axes (Horizontal/Vertical) for the given player.\n * @example stage.setInputConfiguration(useIJKLForAxes('p1'));\n */\nexport function useIJKLForAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'j': ['axes.Left'],\n\t\t'l': ['axes.Right'],\n\t\t'i': ['axes.Up'],\n\t\t'k': ['axes.Down'],\n\t});\n}\n\n/**\n * Maps I/J/K/L keys to directions (Up/Down/Left/Right) for the given player.\n * @example stage.setInputConfiguration(useIJKLForDirections('p1'));\n */\nexport function useIJKLForDirections(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'j': ['directions.Left'],\n\t\t'l': ['directions.Right'],\n\t\t'i': ['directions.Up'],\n\t\t'k': ['directions.Down'],\n\t});\n}\n\nconst INPUT_PLAYERS: (keyof GameInputConfig)[] = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8'];\n\n/**\n * Deep-merges multiple GameInputConfig objects into one.\n * At the player level, configs are merged (both apply).\n * At the key level, later configs win on conflict.\n * @example mergeInputConfigs(useArrowsForAxes('p1'), useWASDForDirections('p1'));\n */\nexport function mergeInputConfigs(...configs: GameInputConfig[]): GameInputConfig {\n\tconst result: GameInputConfig = {};\n\n\tfor (const config of configs) {\n\t\tfor (const player of INPUT_PLAYERS) {\n\t\t\tconst source = config[player];\n\t\t\tif (!source) continue;\n\n\t\t\tconst target: GameInputPlayerConfig = result[player] ?? {};\n\t\t\tresult[player] = {\n\t\t\t\tkey: { ...target.key, ...source.key },\n\t\t\t\tmouse: { ...target.mouse, ...source.mouse },\n\t\t\t\tincludeDefaults: source.includeDefaults ?? target.includeDefaults,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { BaseNode } from '../core/base-node';\nimport { DestroyFunction, SetupContext, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';\nimport { LoadingEvent, StageOptionItem, StageOptions, ZylemStage } from './zylem-stage';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { CameraWrapper } from '../camera/camera';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { stageState } from './stage-state';\nimport { getStageOptions } from './stage-default';\nimport { EntityTypeMap } from '../types/entity-type-map';\nimport { EventEmitterDelegate, zylemEventBus, type StageEvents } from '../events';\nimport { GameInputConfig } from '../game/game-interfaces';\nimport { mergeInputConfigs } from '../input/input-presets';\n\ntype NodeLike = { create: Function };\ntype AnyNode = NodeLike | Promise<NodeLike>;\ntype EntityInput = AnyNode | (() => AnyNode) | (() => Promise<any>);\n\nexport class Stage {\n\twrappedStage: ZylemStage | null;\n\toptions: StageOptionItem[] = [];\n\t// Entities added after construction, consumed on each load\n\tprivate _pendingEntities: BaseNode[] = [];\n\n\t// Lifecycle callback arrays\n\tprivate setupCallbacks: Array<SetupFunction<ZylemStage>> = [];\n\tprivate updateCallbacks: Array<UpdateFunction<ZylemStage>> = [];\n\tprivate destroyCallbacks: Array<DestroyFunction<ZylemStage>> = [];\n\tprivate pendingLoadingCallbacks: Array<(event: LoadingEvent) => void> = [];\n\n\t// Event delegate for dispatch/listen API\n\tprivate eventDelegate = new EventEmitterDelegate<StageEvents>();\n\n\t/** Per-stage input configuration overrides. Merged with game-level defaults on stage load. */\n\tinputConfig: GameInputConfig | null = null;\n\n\t/**\n\t * Callback set by the game to trigger input reconfiguration\n\t * when this stage's input config changes at runtime.\n\t * @internal\n\t */\n\tonInputConfigChanged: (() => void) | null = null;\n\n\tconstructor(options: StageOptions) {\n\t\tthis.options = options;\n\t\tthis.wrappedStage = null;\n\t}\n\n\t/**\n\t * Set composable input configuration for this stage.\n\t * Multiple configs are deep-merged (later configs win on key conflicts).\n\t * If this stage is currently active, the change takes effect immediately.\n\t * @example stage.setInputConfiguration(useArrowsForAxes('p1'), useWASDForDirections('p2'));\n\t */\n\tsetInputConfiguration(...configs: GameInputConfig[]): this {\n\t\tthis.inputConfig = mergeInputConfigs(...configs);\n\t\tif (this.onInputConfigChanged) {\n\t\t\tthis.onInputConfigChanged();\n\t\t}\n\t\treturn this;\n\t}\n\n\tasync load(id: string, camera?: ZylemCamera | CameraWrapper | null, rendererManager?: RendererManager | null) {\n\t\tstageState.entities = [];\n\t\t// Combine original options with pending entities, then clear pending\n\t\tconst loadOptions = [...this.options, ...this._pendingEntities] as StageOptions;\n\t\tthis._pendingEntities = [];\n\t\t\n\t\tthis.wrappedStage = new ZylemStage(loadOptions);\n\t\tthis.wrappedStage.wrapperRef = this;\n\n\t\t// Flush pending loading callbacks BEFORE load so we catch start/progress events\n\t\tthis.pendingLoadingCallbacks.forEach(cb => {\n\t\t\tthis.wrappedStage!.onLoading(cb);\n\t\t});\n\t\tthis.pendingLoadingCallbacks = [];\n\n\t\tconst zylemCamera = camera instanceof CameraWrapper ? camera.cameraRef : camera;\n\t\tawait this.wrappedStage!.load(id, zylemCamera, rendererManager);\n\n\t\tthis.wrappedStage!.onEntityAdded((child) => {\n\t\t\tconst next = this.wrappedStage!.buildEntityState(child);\n\t\t\tstageState.entities = [...stageState.entities, next];\n\t\t}, { replayExisting: true });\n\n\t\t// Apply lifecycle callbacks to wrapped stage\n\t\tthis.applyLifecycleCallbacks();\n\n\t}\n\n\tprivate applyLifecycleCallbacks() {\n\t\tif (!this.wrappedStage) return;\n\n\t\t// Compose setup callbacks into a single function\n\t\tif (this.setupCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.setup = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.setupCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\n\t\t// Compose update callbacks\n\t\tif (this.updateCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.update = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.updateCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\n\t\t// Compose destroy callbacks\n\t\tif (this.destroyCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.destroy = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.destroyCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t}\n\n\tasync addEntities(entities: BaseNode[]) {\n\t\t// Store in pending, don't mutate options\n\t\tthis._pendingEntities.push(...entities);\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.enqueue(...entities);\n\t}\n\n\tadd(...inputs: Array<EntityInput>) {\n\t\tthis.addToBlueprints(...inputs);\n\t\tthis.addToStage(...inputs);\n\t}\n\n\tprivate addToBlueprints(...inputs: Array<EntityInput>) {\n\t\tif (this.wrappedStage) { return; }\n\t\t// Add to options (persistent) so they're available on reload\n\t\tthis.options.push(...(inputs as unknown as StageOptionItem[]));\n\t}\n\n\tprivate addToStage(...inputs: Array<EntityInput>) {\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.enqueue(...(inputs as any));\n\t}\n\n\tstart(params: SetupContext<ZylemStage>) {\n\t\tthis.wrappedStage?.nodeSetup(params);\n\t}\n\n\t// Fluent API for adding lifecycle callbacks\n\tonUpdate(...callbacks: UpdateFunction<ZylemStage>[]): this {\n\t\tthis.updateCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the update callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.update = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.updateCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonSetup(...callbacks: SetupFunction<ZylemStage>[]): this {\n\t\tthis.setupCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the setup callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.setup = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.setupCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonDestroy(...callbacks: DestroyFunction<ZylemStage>[]): this {\n\t\tthis.destroyCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the destroy callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.destroy = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.destroyCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\tif (!this.wrappedStage) { \n\t\t\tthis.pendingLoadingCallbacks.push(callback);\n\t\t\treturn () => {\n\t\t\t\tthis.pendingLoadingCallbacks = this.pendingLoadingCallbacks.filter(c => c !== callback);\n\t\t\t};\n\t\t}\n\t\treturn this.wrappedStage.onLoading(callback);\n\t}\n\n\t/**\n\t * Find an entity by name on the current stage.\n\t * @param name The name of the entity to find\n\t * @param type Optional type symbol for type inference (e.g., TEXT_TYPE, SPRITE_TYPE)\n\t * @returns The entity if found, or undefined\n\t * @example stage.getEntityByName('scoreText', TEXT_TYPE)\n\t */\n\tgetEntityByName<T extends symbol | void = void>(\n\t\tname: string,\n\t\ttype?: T\n\t): T extends keyof EntityTypeMap ? EntityTypeMap[T] | undefined : BaseNode | undefined {\n\t\tconst entity = this.wrappedStage?.children.find(c => c.name === name);\n\t\treturn entity as any;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Camera management\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add a camera to this stage.\n\t * @param camera The ZylemCamera or CameraWrapper to add\n\t * @param name Optional name for lookup\n\t */\n\taddCamera(camera: ZylemCamera | CameraWrapper, name?: string): string | null {\n\t\tconst zylemCam = camera instanceof CameraWrapper ? camera.cameraRef : camera;\n\t\treturn this.wrappedStage?.addCamera(zylemCam, name) ?? null;\n\t}\n\n\t/**\n\t * Remove a camera from this stage by name or reference.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera | CameraWrapper): boolean {\n\t\tif (nameOrRef instanceof CameraWrapper) {\n\t\t\treturn this.wrappedStage?.removeCamera(nameOrRef.cameraRef) ?? false;\n\t\t}\n\t\treturn this.wrappedStage?.removeCamera(nameOrRef) ?? false;\n\t}\n\n\t/**\n\t * Set the active camera by name or reference.\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera | CameraWrapper): boolean {\n\t\tif (nameOrRef instanceof CameraWrapper) {\n\t\t\treturn this.wrappedStage?.setActiveCamera(nameOrRef.cameraRef) ?? false;\n\t\t}\n\t\treturn this.wrappedStage?.setActiveCamera(nameOrRef) ?? false;\n\t}\n\n\t/**\n\t * Get a camera by name from the camera manager.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.wrappedStage?.getCamera(name) ?? null;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from the stage.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof StageEvents>(event: K, payload: StageEvents[K]): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this stage instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof StageEvents>(event: K, handler: (payload: StageEvents[K]) => void): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Clean up stage resources including event subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.eventDelegate.dispose();\n\t}\n}\n\n/**\n * Create a stage with optional camera\n */\nexport function createStage(...options: StageOptions): Stage {\n\tconst _options = getStageOptions(options);\n\treturn new Stage([..._options] as StageOptions);\n}","import { Euler, Quaternion, Vector2 } from \"three\";\nimport { GameEntity } from \"../entities\";\nimport { Stage } from \"./stage\";\n\nexport interface EntitySpawner {\n\tspawn: (stage: Stage, x: number, y: number) => Promise<GameEntity<any>>;\n\tspawnRelative: (source: any, stage: Stage, offset?: Vector2) => Promise<any | void>;\n}\n\nexport function entitySpawner(factory: (x: number, y: number) => Promise<any> | GameEntity<any>): EntitySpawner {\n\treturn {\n\t\tspawn: async (stage: Stage, x: number, y: number) => {\n\t\t\tconst instance = await Promise.resolve(factory(x, y));\n\t\t\tstage.add(instance);\n\t\t\treturn instance;\n\t\t},\n\t\tspawnRelative: async (source: any, stage: Stage, offset: Vector2 = new Vector2(0, 1)) => {\n\t\t\tif (!source.body) {\n\t\t\t\tconsole.warn('body missing for entity during spawnRelative');\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { x, y, z } = source.body.translation();\n\t\t\tlet rz = (source as any)._rotation2DAngle ?? 0;\n\t\t\ttry {\n\t\t\t\tconst r = source.body.rotation();\n\t\t\t\tconst q = new Quaternion(r.x, r.y, r.z, r.w);\n\t\t\t\tconst e = new Euler().setFromQuaternion(q, 'XYZ');\n\t\t\t\trz = e.z;\n\t\t\t} catch { /* use fallback angle */ }\n\n\t\t\tconst offsetX = Math.sin(-rz) * (offset.x ?? 0);\n\t\t\tconst offsetY = Math.cos(-rz) * (offset.y ?? 0);\n\n\t\t\tconst instance = await Promise.resolve(factory(x + offsetX, y + offsetY));\n\t\t\tstage.add(instance);\n\t\t\treturn instance;\n\t\t}\n\t};\n}","import { subscribe } from 'valtio/vanilla';\nimport { stageState } from './stage-state';\nimport type { StageStateInterface } from '../types/stage-types';\n\n/**\n * Event name for stage state changes.\n * Dispatched when the stage state proxy is updated.\n */\nexport const STAGE_STATE_CHANGE = 'STAGE_STATE_CHANGE';\n\n/**\n * Event detail payload for STAGE_STATE_CHANGE events.\n */\nexport interface StageStateChangeEvent {\n\tentities: StageStateInterface['entities'];\n\tvariables: StageStateInterface['variables'];\n}\n\n/**\n * Initialize the stage state dispatcher.\n * Subscribes to stageState changes and dispatches STAGE_STATE_CHANGE events to the window.\n * \n * @returns Unsubscribe function to stop dispatching events.\n * \n * @example\n * // Start dispatching stage state changes\n * const unsubscribe = initStageStateDispatcher();\n * \n * // Later, stop dispatching\n * unsubscribe();\n */\nexport function initStageStateDispatcher(): () => void {\n\treturn subscribe(stageState, () => {\n\t\tconst detail: StageStateChangeEvent = {\n\t\t\tentities: stageState.entities,\n\t\t\tvariables: stageState.variables,\n\t\t};\n\t\twindow.dispatchEvent(new CustomEvent(STAGE_STATE_CHANGE, { detail }));\n\t});\n}\n\n/**\n * Manually dispatch the current stage state.\n * Useful for initial sync when a listener is added.\n */\nexport function dispatchStageState(): void {\n\tconst detail: StageStateChangeEvent = {\n\t\tentities: stageState.entities,\n\t\tvariables: stageState.variables,\n\t};\n\twindow.dispatchEvent(new CustomEvent(STAGE_STATE_CHANGE, { detail }));\n}\n"],"mappings":"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","names":["Color","Vector3","ActiveCollisionTypes","ColliderDesc","MeshStandardMaterial","Group","Vector3","all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","proxy","position","Vector3","Quaternion","Vector3","rotation","Quaternion","Vector3","Vector3","Vector3","Color","Vector2","Vector3","RepeatWrapping","ShaderMaterial","Vector3","Group","MeshStandardMaterial","Color","Vector3","ShaderMaterial","Mesh","Texture","MeshBasicNodeMaterial","proxy","state","Color","MeshBasicNodeMaterial","ShaderMaterial","Mesh","Texture","position","Vector3","Vector3","Quaternion","Vector3","Quaternion","scale","rotation","Color","Vector3","proxy","subscribe","Color","Vector3","Vector3","Vector3","proxy","Color","subscribe","nanoid","BufferGeometry","LineBasicMaterial","LineSegments","Vector2","BoxGeometry","Color","Group","Mesh","Vector3","Vector2","LineSegments","BufferGeometry","LineBasicMaterial","hoveredUuid","subscribe","subscribe","Vector2","PerspectiveCamera","Vector3","Object3D","Vector3","Vector3","state","Vector2","WebGLRenderer","Vector2","WebGLRenderer","Object3D","Vector3","PerspectiveCamera","position","Vector2","Vector2","Vector2","Vector3","Vector3","nanoid","Vector3","state","Color","subscribe","Vector2","Vector3","proxy","Vector3","Vector3","proxy","Euler","Quaternion","Vector2","subscribe","subscribe"]}