@jamesyong42/infinite-canvas 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands.ts","../src/ecs/define.ts","../src/ecs/world.ts","../src/ecs/scheduler.ts","../src/components.ts","../src/math.ts","../src/profiler.ts","../src/resources.ts","../src/snap.ts","../src/spatial.ts","../src/systems.ts","../src/engine.ts","../src/react/InfiniteCanvas.tsx","../src/react/SelectionOverlaySlot.tsx","../src/react/context.ts","../src/react/WidgetProvider.tsx","../src/react/WidgetSlot.tsx","../src/react/hooks.ts","../src/react/registry.ts","../src/react/webgl/GridRenderer.ts","../src/react/webgl/SelectionRenderer.ts","../src/react/webgl/WebGLWidgetLayer.tsx","../src/react/webgl/WebGLWidgetSlot.tsx","../src/react/widget-hooks.ts"],"sourcesContent":["// Engine\nexport {\n\tcreateLayoutEngine,\n\tcreateCanvasEngine,\n\tSpatialIndexResource,\n} from './engine.js';\nexport type {\n\tLayoutEngine,\n\tLayoutEngineConfig,\n\tCanvasEngine,\n\tCanvasEngineConfig,\n\tAddWidgetOptions,\n\tPointerDirective,\n\tResizeHandlePos,\n\tModifiers,\n\tVisibleEntity,\n\tFrameChanges,\n} from './engine.js';\n\n// React component\nexport { InfiniteCanvas } from './react/InfiniteCanvas.js';\n\n// Context hooks\nexport {\n\tuseLayoutEngine,\n\tuseEngine,\n\tuseContainerRef,\n\tuseWidgetResolver,\n\tWidgetResolverProvider,\n} from './react/context.js';\nexport type { WidgetResolver, ResolvedWidget, WidgetSurface } from './react/context.js';\n\n// ECS subscription hooks\nexport {\n\tuseComponent,\n\tuseTag,\n\tuseResource,\n\tuseQuery,\n\tuseTaggedEntities,\n} from './react/hooks.js';\n\n// Widget hooks\nexport {\n\tuseWidgetData,\n\tuseBreakpoint,\n\tuseChildren,\n\tuseWidgetChildren,\n\tuseIsSelected,\n\tuseUpdateWidget,\n\tuseUpdateData,\n} from './react/widget-hooks.js';\n\n// Widget registry & provider\nexport { createWidgetRegistry } from './react/registry.js';\nexport type { WidgetDef, WidgetRegistry } from './react/registry.js';\nexport { WidgetProvider } from './react/WidgetProvider.js';\n\n// Built-in components & tags\nexport {\n\tTransform2D,\n\tWorldBounds,\n\tZIndex,\n\tParent,\n\tChildren,\n\tWidget,\n\tWidgetData,\n\tWidgetBreakpoint,\n\tContainer,\n\tSelectable,\n\tDraggable,\n\tResizable,\n\tLocked,\n\tSelected,\n\tActive,\n\tVisible,\n} from './components.js';\n\n// Resources\nexport {\n\tCameraResource,\n\tViewportResource,\n\tZoomConfigResource,\n\tBreakpointConfigResource,\n\tNavigationStackResource,\n} from './resources.js';\nexport type { Breakpoint, NavigationFrame } from './resources.js';\n\n// Math\nexport {\n\tscreenToWorld,\n\tworldToScreen,\n\tintersectsAABB,\n\tpointInAABB,\n\tworldBoundsToAABB,\n\tclamp,\n} from './math.js';\nexport type { Vec2, Rect, AABB } from './math.js';\n\n// Commands\nexport { CommandBuffer, MoveCommand, ResizeCommand, SetComponentCommand } from './commands.js';\nexport type { Command } from './commands.js';\n\n// Grid & selection config (commonly needed for InfiniteCanvas props)\nexport { DEFAULT_GRID_CONFIG } from './react/webgl/GridRenderer.js';\nexport type { GridConfig } from './react/webgl/GridRenderer.js';\nexport { DEFAULT_SELECTION_CONFIG } from './react/webgl/SelectionRenderer.js';\nexport type { SelectionConfig, SelectionBounds } from './react/webgl/SelectionRenderer.js';\n\n// Snap types (for reading snap guide state)\nexport type { SnapGuide, EqualSpacingIndicator, SnapResult, EntityBounds } from './snap.js';\n\n// ECS types (commonly needed)\nexport type {\n\tEntityId,\n\tComponentType,\n\tTagType,\n\tResourceType,\n\tComponentInit,\n\tUnsubscribe,\n} from './ecs/types.js';\n\n// Profiler types (commonly needed)\nexport type { FrameSample, ProfilerStats } from './profiler.js';\n","import type { ComponentType, EntityId, World } from './ecs/index.js';\n\n// === Command Interface ===\n\nexport interface Command {\n\texecute(world: World): void;\n\tundo(world: World): void;\n}\n\n// === Command Buffer with Undo/Redo ===\n\nexport class CommandBuffer {\n\tprivate undoStack: Command[][] = [];\n\tprivate redoStack: Command[][] = [];\n\tprivate currentGroup: Command[] | null = null;\n\n\t/** Start grouping commands (e.g., on pointerdown). All commands until endGroup() are one undo step. */\n\tbeginGroup() {\n\t\tthis.currentGroup = [];\n\t}\n\n\t/** Execute a command and record it for undo. */\n\texecute(command: Command, world: World) {\n\t\tcommand.execute(world);\n\n\t\tif (this.currentGroup) {\n\t\t\tthis.currentGroup.push(command);\n\t\t} else {\n\t\t\t// Single command = its own undo group\n\t\t\tthis.undoStack.push([command]);\n\t\t\tthis.redoStack.length = 0;\n\t\t}\n\t}\n\n\t/** Close the current group — all commands since beginGroup() become one undo step. */\n\tendGroup() {\n\t\tif (this.currentGroup && this.currentGroup.length > 0) {\n\t\t\tthis.undoStack.push(this.currentGroup);\n\t\t\tthis.redoStack.length = 0;\n\t\t}\n\t\tthis.currentGroup = null;\n\t}\n\n\t/** Undo the last command group. */\n\tundo(world: World): boolean {\n\t\t// Close any open group first\n\t\tif (this.currentGroup) {\n\t\t\tthis.endGroup();\n\t\t}\n\n\t\tconst group = this.undoStack.pop();\n\t\tif (!group) return false;\n\n\t\t// Undo in reverse order\n\t\tfor (let i = group.length - 1; i >= 0; i--) {\n\t\t\tgroup[i].undo(world);\n\t\t}\n\t\tthis.redoStack.push(group);\n\t\treturn true;\n\t}\n\n\t/** Redo the last undone command group. */\n\tredo(world: World): boolean {\n\t\tconst group = this.redoStack.pop();\n\t\tif (!group) return false;\n\n\t\tfor (const cmd of group) {\n\t\t\tcmd.execute(world);\n\t\t}\n\t\tthis.undoStack.push(group);\n\t\treturn true;\n\t}\n\n\tcanUndo(): boolean {\n\t\treturn (\n\t\t\tthis.undoStack.length > 0 || (this.currentGroup !== null && this.currentGroup.length > 0)\n\t\t);\n\t}\n\n\tcanRedo(): boolean {\n\t\treturn this.redoStack.length > 0;\n\t}\n\n\tclear() {\n\t\tthis.undoStack.length = 0;\n\t\tthis.redoStack.length = 0;\n\t\tthis.currentGroup = null;\n\t}\n\n\tget undoSize(): number {\n\t\treturn this.undoStack.length;\n\t}\n\tget redoSize(): number {\n\t\treturn this.redoStack.length;\n\t}\n}\n\n// === Built-in Commands ===\n\nexport class MoveCommand implements Command {\n\tconstructor(\n\t\tprivate entityIds: EntityId[],\n\t\tprivate dx: number,\n\t\tprivate dy: number,\n\t\tprivate transformType: ComponentType<{ x: number; y: number }>,\n\t) {}\n\n\texecute(world: World) {\n\t\tfor (const id of this.entityIds) {\n\t\t\tconst t = world.getComponent(id, this.transformType);\n\t\t\tif (t) {\n\t\t\t\tworld.setComponent(id, this.transformType, { x: t.x + this.dx, y: t.y + this.dy });\n\t\t\t}\n\t\t}\n\t}\n\n\tundo(world: World) {\n\t\tfor (const id of this.entityIds) {\n\t\t\tconst t = world.getComponent(id, this.transformType);\n\t\t\tif (t) {\n\t\t\t\tworld.setComponent(id, this.transformType, { x: t.x - this.dx, y: t.y - this.dy });\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class ResizeCommand implements Command {\n\tstatic readonly MIN_SIZE = 20;\n\n\tconstructor(\n\t\tprivate entityId: EntityId,\n\t\tprivate before: { x: number; y: number; width: number; height: number },\n\t\tprivate after: { x: number; y: number; width: number; height: number },\n\t\tprivate transformType: ComponentType<{ x: number; y: number; width: number; height: number }>,\n\t) {\n\t\t// Enforce min-size so redo always produces valid bounds\n\t\tthis.after = {\n\t\t\t...after,\n\t\t\twidth: Math.max(ResizeCommand.MIN_SIZE, after.width),\n\t\t\theight: Math.max(ResizeCommand.MIN_SIZE, after.height),\n\t\t};\n\t}\n\n\texecute(world: World) {\n\t\tworld.setComponent(this.entityId, this.transformType, this.after);\n\t}\n\n\tundo(world: World) {\n\t\tworld.setComponent(this.entityId, this.transformType, this.before);\n\t}\n}\n\nexport class SetComponentCommand<T> implements Command {\n\tconstructor(\n\t\tprivate entityId: EntityId,\n\t\tprivate type: ComponentType<T>,\n\t\tprivate before: Partial<T>,\n\t\tprivate after: Partial<T>,\n\t) {}\n\n\texecute(world: World) {\n\t\tworld.setComponent(this.entityId, this.type, this.after);\n\t}\n\n\tundo(world: World) {\n\t\tworld.setComponent(this.entityId, this.type, this.before);\n\t}\n}\n","import type { ComponentType, ResourceType, SystemDef, TagType } from './types.js';\n\n/**\n * Define a component type. Components hold data attached to entities.\n *\n * @example\n * const Transform2D = defineComponent('Transform2D', {\n * x: 0, y: 0, width: 100, height: 100, rotation: 0,\n * });\n */\nexport function defineComponent<T extends Record<string, any>>(\n\tname: string,\n\tdefaults: T,\n): ComponentType<T> {\n\treturn Object.freeze({ name, defaults, __kind: 'component' as const });\n}\n\n/**\n * Define a tag type. Tags are markers with no data — used for boolean state.\n *\n * @example\n * const Selected = defineTag('Selected');\n */\nexport function defineTag(name: string): TagType {\n\treturn Object.freeze({ name, __kind: 'tag' as const });\n}\n\n/**\n * Define a resource type. Resources are global singletons (camera, viewport, etc.)\n *\n * @example\n * const Camera = defineResource('Camera', { x: 0, y: 0, zoom: 1 });\n */\nexport function defineResource<T extends Record<string, any>>(\n\tname: string,\n\tdefaults: T,\n): ResourceType<T> {\n\treturn Object.freeze({ name, defaults, __kind: 'resource' as const });\n}\n\n/**\n * Define a system. Systems are named functions that query and transform ECS data.\n *\n * @example\n * const mySystem = defineSystem({\n * name: 'physics',\n * after: 'layout',\n * execute: (world) => {\n * for (const entity of world.query(Transform2D, Velocity)) { ... }\n * },\n * });\n */\nexport function defineSystem(def: SystemDef): SystemDef {\n\treturn def;\n}\n","import type {\n\tComponentChangedHandler,\n\tComponentType,\n\tEntityId,\n\tFrameHandler,\n\tQueryResult,\n\tResourceType,\n\tTagChangedHandler,\n\tTagType,\n\tUnsubscribe,\n\tWorld,\n} from './types.js';\n\n/** Internal storage for a single component type */\ninterface ComponentStore<T = any> {\n\tdata: Map<EntityId, T>;\n\tdirty: Set<EntityId>;\n\tadded: Set<EntityId>;\n\thandlers: Map<EntityId | '*', Set<ComponentChangedHandler<T>>>;\n}\n\n/** Internal storage for a single tag type */\ninterface TagStore {\n\tentities: Set<EntityId>;\n\taddedHandlers: Map<EntityId | '*', Set<TagChangedHandler>>;\n\tremovedHandlers: Map<EntityId | '*', Set<TagChangedHandler>>;\n}\n\nexport function createWorld(): World {\n\tlet nextEntityId = 1;\n\tlet currentTick = 0;\n\tconst alive = new Set<EntityId>();\n\n\t// Component storage: one Map per component type\n\tconst components = new Map<string, ComponentStore>();\n\t// Tag storage: one Set per tag type\n\tconst tags = new Map<string, TagStore>();\n\t// Resources: one value per resource type\n\tconst resources = new Map<string, any>();\n\t// Frame handlers\n\tconst frameHandlers = new Set<FrameHandler>();\n\n\t// === Query cache ===\n\t// Key: sorted type names joined by '|' (e.g., \"Transform2D|Visible\")\n\t// Value: live Set<EntityId> of entities matching all types in the key\n\tconst queryCache = new Map<string, Set<EntityId>>();\n\t// Reverse index: typeName → Set<queryKey> — which cached queries use this type\n\tconst typeToQueries = new Map<string, Set<string>>();\n\t// Store the type names per query key for re-evaluation\n\tconst queryKeyTypes = new Map<string, { components: string[]; tags: string[] }>();\n\n\tfunction getQueryKey(types: (ComponentType | TagType)[]): string {\n\t\treturn types\n\t\t\t.map((t) => t.name)\n\t\t\t.sort()\n\t\t\t.join('|');\n\t}\n\n\tfunction buildQueryResult(compNames: string[], tagNames: string[]): Set<EntityId> {\n\t\tconst result = new Set<EntityId>();\n\n\t\t// Find smallest set to start iteration\n\t\tlet smallest: Set<EntityId> | null = null;\n\t\tlet smallestSize = Number.POSITIVE_INFINITY;\n\n\t\tfor (const name of compNames) {\n\t\t\tconst store = components.get(name);\n\t\t\tif (!store || store.data.size === 0) return result; // empty — no matches\n\t\t\tif (store.data.size < smallestSize) {\n\t\t\t\tsmallestSize = store.data.size;\n\t\t\t\tsmallest = new Set(store.data.keys());\n\t\t\t}\n\t\t}\n\t\tfor (const name of tagNames) {\n\t\t\tconst store = tags.get(name);\n\t\t\tif (!store || store.entities.size === 0) return result;\n\t\t\tif (store.entities.size < smallestSize) {\n\t\t\t\tsmallestSize = store.entities.size;\n\t\t\t\tsmallest = store.entities;\n\t\t\t}\n\t\t}\n\n\t\tif (!smallest) return result;\n\n\t\tfor (const entity of smallest) {\n\t\t\tif (!alive.has(entity)) continue;\n\t\t\tif (matchesQuery(entity, compNames, tagNames)) {\n\t\t\t\tresult.add(entity);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tfunction matchesQuery(entity: EntityId, compNames: string[], tagNames: string[]): boolean {\n\t\tfor (const name of compNames) {\n\t\t\tconst store = components.get(name);\n\t\t\tif (!store || !store.data.has(entity)) return false;\n\t\t}\n\t\tfor (const name of tagNames) {\n\t\t\tconst store = tags.get(name);\n\t\t\tif (!store || !store.entities.has(entity)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Update all cached queries that include this type name */\n\tfunction updateCachesForEntity(typeName: string, entity: EntityId) {\n\t\tconst queryKeys = typeToQueries.get(typeName);\n\t\tif (!queryKeys) return;\n\t\tfor (const key of queryKeys) {\n\t\t\tconst cached = queryCache.get(key);\n\t\t\tconst types = queryKeyTypes.get(key);\n\t\t\tif (!cached || !types) continue;\n\t\t\tif (matchesQuery(entity, types.components, types.tags)) {\n\t\t\t\tcached.add(entity);\n\t\t\t} else {\n\t\t\t\tcached.delete(entity);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Remove entity from all cached queries */\n\tfunction removeCachesForEntity(entity: EntityId) {\n\t\tfor (const cached of queryCache.values()) {\n\t\t\tcached.delete(entity);\n\t\t}\n\t}\n\n\tfunction getComponentStore<T>(type: ComponentType<T>): ComponentStore<T> {\n\t\tlet store = components.get(type.name);\n\t\tif (!store) {\n\t\t\tstore = {\n\t\t\t\tdata: new Map(),\n\t\t\t\tdirty: new Set(),\n\t\t\t\tadded: new Set(),\n\t\t\t\thandlers: new Map(),\n\t\t\t};\n\t\t\tcomponents.set(type.name, store);\n\t\t}\n\t\treturn store;\n\t}\n\n\tfunction getTagStore(type: TagType): TagStore {\n\t\tlet store = tags.get(type.name);\n\t\tif (!store) {\n\t\t\tstore = {\n\t\t\t\tentities: new Set(),\n\t\t\t\taddedHandlers: new Map(),\n\t\t\t\tremovedHandlers: new Map(),\n\t\t\t};\n\t\t\ttags.set(type.name, store);\n\t\t}\n\t\treturn store;\n\t}\n\n\tfunction hasListeners(store: ComponentStore): boolean {\n\t\tif (store.handlers.size === 0) return false;\n\t\tfor (const set of store.handlers.values()) {\n\t\t\tif (set.size > 0) return true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tfunction emitComponentChanged<T>(\n\t\tstore: ComponentStore<T>,\n\t\tentityId: EntityId,\n\t\tprev: T | undefined,\n\t\tnext: T,\n\t) {\n\t\tconst entityHandlers = store.handlers.get(entityId);\n\t\tif (entityHandlers) {\n\t\t\tfor (const h of entityHandlers) h(entityId, prev, next);\n\t\t}\n\t\tconst wildcardHandlers = store.handlers.get('*');\n\t\tif (wildcardHandlers) {\n\t\t\tfor (const h of wildcardHandlers) h(entityId, prev, next);\n\t\t}\n\t}\n\n\tfunction emitTagAdded(store: TagStore, entityId: EntityId) {\n\t\tconst entityHandlers = store.addedHandlers.get(entityId);\n\t\tif (entityHandlers) {\n\t\t\tfor (const h of entityHandlers) h(entityId);\n\t\t}\n\t\tconst wildcardHandlers = store.addedHandlers.get('*');\n\t\tif (wildcardHandlers) {\n\t\t\tfor (const h of wildcardHandlers) h(entityId);\n\t\t}\n\t}\n\n\tfunction emitTagRemoved(store: TagStore, entityId: EntityId) {\n\t\tconst entityHandlers = store.removedHandlers.get(entityId);\n\t\tif (entityHandlers) {\n\t\t\tfor (const h of entityHandlers) h(entityId);\n\t\t}\n\t\tconst wildcardHandlers = store.removedHandlers.get('*');\n\t\tif (wildcardHandlers) {\n\t\t\tfor (const h of wildcardHandlers) h(entityId);\n\t\t}\n\t}\n\n\tconst world: World = {\n\t\tget currentTick() {\n\t\t\treturn currentTick;\n\t\t},\n\n\t\tget entityCount() {\n\t\t\treturn alive.size;\n\t\t},\n\n\t\t// === Entity lifecycle ===\n\n\t\tcreateEntity(): EntityId {\n\t\t\tconst id = nextEntityId++;\n\t\t\talive.add(id);\n\t\t\treturn id;\n\t\t},\n\n\t\tdestroyEntity(id: EntityId) {\n\t\t\tif (!alive.has(id)) return;\n\t\t\talive.delete(id);\n\t\t\t// Remove from all cached queries\n\t\t\tremoveCachesForEntity(id);\n\t\t\t// Remove all components\n\t\t\tfor (const store of components.values()) {\n\t\t\t\tstore.data.delete(id);\n\t\t\t\tstore.dirty.delete(id);\n\t\t\t\tstore.added.delete(id);\n\t\t\t\tstore.handlers.delete(id);\n\t\t\t}\n\t\t\t// Remove all tags\n\t\t\tfor (const store of tags.values()) {\n\t\t\t\tstore.entities.delete(id);\n\t\t\t\tstore.addedHandlers.delete(id);\n\t\t\t\tstore.removedHandlers.delete(id);\n\t\t\t}\n\t\t},\n\n\t\tentityExists(id: EntityId): boolean {\n\t\t\treturn alive.has(id);\n\t\t},\n\n\t\t// === Component access ===\n\n\t\taddComponent<T>(entity: EntityId, type: ComponentType<T>, data: T) {\n\t\t\tconst store = getComponentStore(type);\n\t\t\tconst merged = { ...type.defaults, ...data };\n\t\t\tstore.data.set(entity, merged);\n\t\t\tstore.dirty.add(entity);\n\t\t\tstore.added.add(entity);\n\t\t\t// Update cached queries that include this component\n\t\t\tupdateCachesForEntity(type.name, entity);\n\t\t\temitComponentChanged(store, entity, undefined, merged);\n\t\t},\n\n\t\tremoveComponent<T>(entity: EntityId, type: ComponentType<T>) {\n\t\t\tconst store = getComponentStore(type);\n\t\t\tstore.data.delete(entity);\n\t\t\tstore.dirty.delete(entity);\n\t\t\t// Update cached queries — entity may no longer match\n\t\t\tupdateCachesForEntity(type.name, entity);\n\t\t},\n\n\t\tgetComponent<T>(entity: EntityId, type: ComponentType<T>): T | undefined {\n\t\t\tconst store = getComponentStore(type);\n\t\t\treturn store.data.get(entity);\n\t\t},\n\n\t\thasComponent(entity: EntityId, type: ComponentType): boolean {\n\t\t\tconst store = getComponentStore(type);\n\t\t\treturn store.data.has(entity);\n\t\t},\n\n\t\t// P2: Only allocate prev object when there are listeners\n\t\tsetComponent<T>(entity: EntityId, type: ComponentType<T>, data: Partial<T>) {\n\t\t\tconst store = getComponentStore(type);\n\t\t\tconst existing = store.data.get(entity);\n\t\t\tif (!existing) return;\n\t\t\tif (hasListeners(store)) {\n\t\t\t\tconst prev = { ...existing };\n\t\t\t\tconst next = Object.assign(existing, data);\n\t\t\t\tstore.data.set(entity, next);\n\t\t\t\tstore.dirty.add(entity);\n\t\t\t\temitComponentChanged(store, entity, prev, next);\n\t\t\t} else {\n\t\t\t\tObject.assign(existing, data);\n\t\t\t\tstore.dirty.add(entity);\n\t\t\t}\n\t\t},\n\n\t\t// === Tag access ===\n\n\t\taddTag(entity: EntityId, type: TagType) {\n\t\t\tconst store = getTagStore(type);\n\t\t\tif (store.entities.has(entity)) return;\n\t\t\tstore.entities.add(entity);\n\t\t\t// Update cached queries that include this tag\n\t\t\tupdateCachesForEntity(type.name, entity);\n\t\t\temitTagAdded(store, entity);\n\t\t},\n\n\t\tremoveTag(entity: EntityId, type: TagType) {\n\t\t\tconst store = getTagStore(type);\n\t\t\tif (!store.entities.has(entity)) return;\n\t\t\tstore.entities.delete(entity);\n\t\t\t// Update cached queries — entity may no longer match\n\t\t\tupdateCachesForEntity(type.name, entity);\n\t\t\temitTagRemoved(store, entity);\n\t\t},\n\n\t\thasTag(entity: EntityId, type: TagType): boolean {\n\t\t\tconst store = getTagStore(type);\n\t\t\treturn store.entities.has(entity);\n\t\t},\n\n\t\t// === Queries (cached) ===\n\n\t\tquery(...types: (ComponentType | TagType)[]): QueryResult {\n\t\t\tif (types.length === 0) return [...alive];\n\n\t\t\tconst key = getQueryKey(types);\n\n\t\t\t// Return from cache if available\n\t\t\tlet cached = queryCache.get(key);\n\t\t\tif (cached) return [...cached];\n\n\t\t\t// Build cache on first call\n\t\t\tconst compNames: string[] = [];\n\t\t\tconst tagNames: string[] = [];\n\t\t\tfor (const type of types) {\n\t\t\t\tif (type.__kind === 'component') compNames.push(type.name);\n\t\t\t\telse tagNames.push(type.name);\n\t\t\t}\n\n\t\t\tcached = buildQueryResult(compNames, tagNames);\n\t\t\tqueryCache.set(key, cached);\n\t\t\tqueryKeyTypes.set(key, { components: compNames, tags: tagNames });\n\n\t\t\t// Register reverse index so cache updates on add/remove\n\t\t\tfor (const name of [...compNames, ...tagNames]) {\n\t\t\t\tlet queryKeys = typeToQueries.get(name);\n\t\t\t\tif (!queryKeys) {\n\t\t\t\t\tqueryKeys = new Set();\n\t\t\t\t\ttypeToQueries.set(name, queryKeys);\n\t\t\t\t}\n\t\t\t\tqueryKeys.add(key);\n\t\t\t}\n\n\t\t\treturn [...cached];\n\t\t},\n\n\t\tqueryChanged(type: ComponentType): QueryResult {\n\t\t\tconst store = getComponentStore(type);\n\t\t\treturn [...store.dirty];\n\t\t},\n\n\t\tqueryAdded(type: ComponentType): QueryResult {\n\t\t\tconst store = getComponentStore(type);\n\t\t\treturn [...store.added];\n\t\t},\n\n\t\tqueryTagged(type: TagType): QueryResult {\n\t\t\tconst store = getTagStore(type);\n\t\t\treturn [...store.entities];\n\t\t},\n\n\t\t// === Resources ===\n\n\t\tgetResource<T>(type: ResourceType<T>): T {\n\t\t\tif (!resources.has(type.name)) {\n\t\t\t\tresources.set(type.name, { ...type.defaults });\n\t\t\t}\n\t\t\treturn resources.get(type.name);\n\t\t},\n\n\t\tsetResource<T>(type: ResourceType<T>, data: Partial<T>) {\n\t\t\tconst existing = world.getResource(type);\n\t\t\tObject.assign(existing as Record<string, unknown>, data);\n\t\t},\n\n\t\t// === Events ===\n\n\t\tonComponentChanged<T>(\n\t\t\ttype: ComponentType<T>,\n\t\t\thandler: ComponentChangedHandler<T>,\n\t\t\tentityId?: EntityId,\n\t\t): Unsubscribe {\n\t\t\tconst store = getComponentStore(type);\n\t\t\tconst key: EntityId | '*' = entityId ?? '*';\n\t\t\tlet handlers = store.handlers.get(key);\n\t\t\tif (!handlers) {\n\t\t\t\thandlers = new Set();\n\t\t\t\tstore.handlers.set(key, handlers);\n\t\t\t}\n\t\t\thandlers.add(handler);\n\t\t\treturn () => handlers!.delete(handler);\n\t\t},\n\n\t\tonTagAdded(type: TagType, handler: TagChangedHandler, entityId?: EntityId): Unsubscribe {\n\t\t\tconst store = getTagStore(type);\n\t\t\tconst key: EntityId | '*' = entityId ?? '*';\n\t\t\tlet handlers = store.addedHandlers.get(key);\n\t\t\tif (!handlers) {\n\t\t\t\thandlers = new Set();\n\t\t\t\tstore.addedHandlers.set(key, handlers);\n\t\t\t}\n\t\t\thandlers.add(handler);\n\t\t\treturn () => handlers!.delete(handler);\n\t\t},\n\n\t\tonTagRemoved(type: TagType, handler: TagChangedHandler, entityId?: EntityId): Unsubscribe {\n\t\t\tconst store = getTagStore(type);\n\t\t\tconst key: EntityId | '*' = entityId ?? '*';\n\t\t\tlet handlers = store.removedHandlers.get(key);\n\t\t\tif (!handlers) {\n\t\t\t\thandlers = new Set();\n\t\t\t\tstore.removedHandlers.set(key, handlers);\n\t\t\t}\n\t\t\thandlers.add(handler);\n\t\t\treturn () => handlers!.delete(handler);\n\t\t},\n\n\t\tonFrame(handler: FrameHandler): Unsubscribe {\n\t\t\tframeHandlers.add(handler);\n\t\t\treturn () => frameHandlers.delete(handler);\n\t\t},\n\n\t\t// Frame lifecycle\n\t\tclearDirty() {\n\t\t\tfor (const store of components.values()) {\n\t\t\t\tstore.dirty.clear();\n\t\t\t\tstore.added.clear();\n\t\t\t}\n\t\t},\n\n\t\tincrementTick() {\n\t\t\tcurrentTick++;\n\t\t},\n\n\t\temitFrame() {\n\t\t\tfor (const h of frameHandlers) h();\n\t\t},\n\t};\n\n\treturn world;\n}\n","import type { Profiler } from '../profiler.js';\nimport type { SystemDef, World } from './types.js';\n\n/**\n * Manages system registration and ordered execution.\n * Systems declare after/before constraints and are topologically sorted.\n */\nexport class SystemScheduler {\n\tprivate systems: SystemDef[] = [];\n\tprivate sorted: SystemDef[] | null = null;\n\tprofiler: Profiler | null = null;\n\n\tregister(system: SystemDef) {\n\t\t// Replace if system with same name exists\n\t\tthis.systems = this.systems.filter((s) => s.name !== system.name);\n\t\tthis.systems.push(system);\n\t\tthis.sorted = null; // invalidate sort\n\t}\n\n\tremove(name: string) {\n\t\tthis.systems = this.systems.filter((s) => s.name !== name);\n\t\tthis.sorted = null;\n\t}\n\n\t/**\n\t * Execute all systems in dependency order.\n\t */\n\texecute(world: World) {\n\t\tif (!this.sorted) {\n\t\t\tthis.sorted = this.topoSort();\n\t\t}\n\t\tconst p = this.profiler;\n\t\tfor (const system of this.sorted) {\n\t\t\tif (p) p.beginSystem(system.name);\n\t\t\tsystem.execute(world);\n\t\t\tif (p) p.endSystem(system.name);\n\t\t}\n\t}\n\n\tgetSystemNames(): string[] {\n\t\tif (!this.sorted) {\n\t\t\tthis.sorted = this.topoSort();\n\t\t}\n\t\treturn this.sorted.map((s) => s.name);\n\t}\n\n\t/**\n\t * Topological sort based on after/before constraints.\n\t * Falls back to registration order for unconstrained systems.\n\t */\n\tprivate topoSort(): SystemDef[] {\n\t\tconst byName = new Map<string, SystemDef>();\n\t\tfor (const s of this.systems) {\n\t\t\tbyName.set(s.name, s);\n\t\t}\n\n\t\t// Build adjacency list: edges[a] = [b] means a must run before b\n\t\tconst edges = new Map<string, Set<string>>();\n\t\tconst inDegree = new Map<string, number>();\n\n\t\tfor (const s of this.systems) {\n\t\t\tif (!edges.has(s.name)) edges.set(s.name, new Set());\n\t\t\tif (!inDegree.has(s.name)) inDegree.set(s.name, 0);\n\t\t}\n\n\t\tfor (const s of this.systems) {\n\t\t\tconst afters = Array.isArray(s.after) ? s.after : s.after ? [s.after] : [];\n\t\t\tfor (const dep of afters) {\n\t\t\t\t// dep must run before s\n\t\t\t\tif (byName.has(dep)) {\n\t\t\t\t\tif (!edges.has(dep)) edges.set(dep, new Set());\n\t\t\t\t\tedges.get(dep)!.add(s.name);\n\t\t\t\t\tinDegree.set(s.name, (inDegree.get(s.name) || 0) + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst befores = Array.isArray(s.before) ? s.before : s.before ? [s.before] : [];\n\t\t\tfor (const dep of befores) {\n\t\t\t\t// s must run before dep\n\t\t\t\tif (byName.has(dep)) {\n\t\t\t\t\tif (!edges.has(s.name)) edges.set(s.name, new Set());\n\t\t\t\t\tedges.get(s.name)!.add(dep);\n\t\t\t\t\tinDegree.set(dep, (inDegree.get(dep) || 0) + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Kahn's algorithm — stable sort (preserves registration order for ties)\n\t\tconst queue: string[] = [];\n\t\tconst registrationOrder = new Map<string, number>();\n\t\tfor (let i = 0; i < this.systems.length; i++) {\n\t\t\tregistrationOrder.set(this.systems[i].name, i);\n\t\t}\n\n\t\tfor (const s of this.systems) {\n\t\t\tif ((inDegree.get(s.name) || 0) === 0) {\n\t\t\t\tqueue.push(s.name);\n\t\t\t}\n\t\t}\n\t\t// Sort queue by registration order for stability\n\t\tqueue.sort((a, b) => (registrationOrder.get(a) || 0) - (registrationOrder.get(b) || 0));\n\n\t\tconst result: SystemDef[] = [];\n\t\twhile (queue.length > 0) {\n\t\t\tconst name = queue.shift()!;\n\t\t\tconst system = byName.get(name);\n\t\t\tif (system) result.push(system);\n\n\t\t\tconst neighbors = edges.get(name) || new Set();\n\t\t\tconst newReady: string[] = [];\n\t\t\tfor (const neighbor of neighbors) {\n\t\t\t\tconst deg = (inDegree.get(neighbor) || 0) - 1;\n\t\t\t\tinDegree.set(neighbor, deg);\n\t\t\t\tif (deg === 0) {\n\t\t\t\t\tnewReady.push(neighbor);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Sort newly ready by registration order\n\t\t\tnewReady.sort((a, b) => (registrationOrder.get(a) || 0) - (registrationOrder.get(b) || 0));\n\t\t\tqueue.push(...newReady);\n\t\t}\n\n\t\tif (result.length !== this.systems.length) {\n\t\t\tconst missing = this.systems\n\t\t\t\t.filter((s) => !result.find((r) => r.name === s.name))\n\t\t\t\t.map((s) => s.name);\n\t\t\tthrow new Error(`Circular system dependency detected involving: ${missing.join(', ')}`);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { defineComponent, defineTag } from './ecs/index.js';\nimport type { EntityId } from './ecs/index.js';\n\n// === Spatial ===\nexport const Transform2D = defineComponent('Transform2D', {\n\tx: 0,\n\ty: 0,\n\twidth: 100,\n\theight: 100,\n\trotation: 0,\n});\n\nexport const WorldBounds = defineComponent('WorldBounds', {\n\tworldX: 0,\n\tworldY: 0,\n\tworldWidth: 0,\n\tworldHeight: 0,\n});\n\nexport const ZIndex = defineComponent('ZIndex', { value: 0 });\n\n// === Hierarchy ===\nexport const Parent = defineComponent('Parent', { id: 0 as EntityId });\nexport const Children = defineComponent('Children', { ids: [] as EntityId[] });\n\n// === Widget ===\nexport const Widget = defineComponent('Widget', {\n\tsurface: 'dom' as 'dom' | 'webgl' | 'webview',\n\ttype: '' as string,\n});\n\nexport const WidgetData = defineComponent('WidgetData', {\n\tdata: {} as Record<string, any>,\n});\n\nexport const WidgetBreakpoint = defineComponent('WidgetBreakpoint', {\n\tcurrent: 'normal' as 'micro' | 'compact' | 'normal' | 'expanded' | 'detailed',\n\tscreenWidth: 0,\n\tscreenHeight: 0,\n});\n\n// === Container ===\nexport const Container = defineComponent('Container', { enterable: true });\n\n// === Tags ===\nexport const Selectable = defineTag('Selectable');\nexport const Draggable = defineTag('Draggable');\nexport const Resizable = defineTag('Resizable');\nexport const Locked = defineTag('Locked');\nexport const Selected = defineTag('Selected');\nexport const Active = defineTag('Active');\nexport const Visible = defineTag('Visible');\n","export interface Vec2 {\n\tx: number;\n\ty: number;\n}\n\nexport interface Rect {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\nexport interface AABB {\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n}\n\n/** Convert WorldBounds-shaped data to AABB */\nexport function worldBoundsToAABB(wb: {\n\tworldX: number;\n\tworldY: number;\n\tworldWidth: number;\n\tworldHeight: number;\n}): AABB {\n\treturn {\n\t\tminX: wb.worldX,\n\t\tminY: wb.worldY,\n\t\tmaxX: wb.worldX + wb.worldWidth,\n\t\tmaxY: wb.worldY + wb.worldHeight,\n\t};\n}\n\n/** Convert a Rect to AABB */\nexport function rectToAABB(r: Rect): AABB {\n\treturn {\n\t\tminX: r.x,\n\t\tminY: r.y,\n\t\tmaxX: r.x + r.width,\n\t\tmaxY: r.y + r.height,\n\t};\n}\n\n/** Convert AABB to Rect */\nexport function aabbToRect(a: AABB): Rect {\n\treturn {\n\t\tx: a.minX,\n\t\ty: a.minY,\n\t\twidth: a.maxX - a.minX,\n\t\theight: a.maxY - a.minY,\n\t};\n}\n\n/** Test if two AABBs overlap */\nexport function intersectsAABB(a: AABB, b: AABB): boolean {\n\treturn a.maxX >= b.minX && a.minX <= b.maxX && a.maxY >= b.minY && a.minY <= b.maxY;\n}\n\n/** Test if a point is inside an AABB */\nexport function pointInAABB(px: number, py: number, a: AABB): boolean {\n\treturn px >= a.minX && px <= a.maxX && py >= a.minY && py <= a.maxY;\n}\n\n/** Convert screen coordinates to world coordinates */\nexport function screenToWorld(\n\tscreenX: number,\n\tscreenY: number,\n\tcamera: { x: number; y: number; zoom: number },\n): Vec2 {\n\treturn {\n\t\tx: screenX / camera.zoom + camera.x,\n\t\ty: screenY / camera.zoom + camera.y,\n\t};\n}\n\n/** Convert world coordinates to screen coordinates */\nexport function worldToScreen(\n\tworldX: number,\n\tworldY: number,\n\tcamera: { x: number; y: number; zoom: number },\n): Vec2 {\n\treturn {\n\t\tx: (worldX - camera.x) * camera.zoom,\n\t\ty: (worldY - camera.y) * camera.zoom,\n\t};\n}\n\n/** Clamp a value between min and max */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.max(min, Math.min(max, value));\n}\n","/**\n * Performance profiler with User Timing API integration.\n * Zero-cost when disabled — all methods are no-ops.\n * When enabled, data shows in Chrome DevTools Performance tab.\n */\n\nexport interface FrameSample {\n\ttick: number;\n\ttimestamp: number;\n\t/** Total tick duration (ms) */\n\ttotalMs: number;\n\t/** Per-system durations (ms) */\n\tsystems: Record<string, number>;\n\t/** Visible entity computation (ms) */\n\tvisibilityMs: number;\n\t/** Entity counts at this frame */\n\tentityCount: number;\n\tvisibleCount: number;\n}\n\nexport interface ProfilerStats {\n\t/** Frames per second (based on tick rate, not rAF) */\n\tfps: number;\n\t/** Frame time stats (ms) */\n\tframeTime: { avg: number; p50: number; p95: number; p99: number; max: number };\n\t/** Per-system average time (ms) */\n\tsystemAvg: Record<string, number>;\n\t/** Per-system p95 time (ms) */\n\tsystemP95: Record<string, number>;\n\t/** Frame budget utilization at 60fps (%) */\n\tbudgetUsed: number;\n\t/** Total samples in buffer */\n\tsampleCount: number;\n}\n\nconst RING_SIZE = 300; // ~5 seconds at 60fps\n\nexport class Profiler {\n\tprivate enabled = false;\n\tprivate ring: FrameSample[] = [];\n\tprivate writeIdx = 0;\n\tprivate filled = false;\n\n\t// Scratch state for current frame\n\tprivate frameStart = 0;\n\tprivate currentSystems: Record<string, number> = {};\n\tprivate visibilityMs = 0;\n\tprivate currentTick = 0;\n\n\t/** Enable/disable profiling. When disabled, all methods are no-ops. */\n\tsetEnabled(on: boolean) {\n\t\tthis.enabled = on;\n\t\tif (!on) {\n\t\t\tthis.ring = [];\n\t\t\tthis.writeIdx = 0;\n\t\t\tthis.filled = false;\n\t\t}\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn this.enabled;\n\t}\n\n\t/** Call at the start of engine.tick() */\n\tbeginFrame(tick: number) {\n\t\tif (!this.enabled) return;\n\t\tthis.currentTick = tick;\n\t\tthis.currentSystems = {};\n\t\tthis.visibilityMs = 0;\n\t\tthis.frameStart = performance.now();\n\t\tperformance.mark('ic-frame-start');\n\t}\n\n\t/** Call around each system execution */\n\tbeginSystem(name: string) {\n\t\tif (!this.enabled) return;\n\t\tperformance.mark(`ic-sys-${name}-start`);\n\t}\n\n\tendSystem(name: string) {\n\t\tif (!this.enabled) return;\n\t\tperformance.mark(`ic-sys-${name}-end`);\n\t\ttry {\n\t\t\tconst measure = performance.measure(\n\t\t\t\t`ic:${name}`,\n\t\t\t\t`ic-sys-${name}-start`,\n\t\t\t\t`ic-sys-${name}-end`,\n\t\t\t);\n\t\t\tthis.currentSystems[name] = measure.duration;\n\t\t} catch {\n\t\t\t// marks may be cleared\n\t\t}\n\t\tperformance.clearMarks(`ic-sys-${name}-start`);\n\t\tperformance.clearMarks(`ic-sys-${name}-end`);\n\t}\n\n\t/** Call around the visibility computation phase */\n\tbeginVisibility() {\n\t\tif (!this.enabled) return;\n\t\tperformance.mark('ic-vis-start');\n\t}\n\n\tendVisibility() {\n\t\tif (!this.enabled) return;\n\t\tperformance.mark('ic-vis-end');\n\t\ttry {\n\t\t\tconst measure = performance.measure('ic:visibility', 'ic-vis-start', 'ic-vis-end');\n\t\t\tthis.visibilityMs = measure.duration;\n\t\t} catch {\n\t\t\t// marks may be cleared\n\t\t}\n\t\tperformance.clearMarks('ic-vis-start');\n\t\tperformance.clearMarks('ic-vis-end');\n\t}\n\n\t/** Call at the end of engine.tick() */\n\tendFrame(entityCount: number, visibleCount: number) {\n\t\tif (!this.enabled) return;\n\t\tperformance.mark('ic-frame-end');\n\n\t\tlet totalMs = 0;\n\t\ttry {\n\t\t\tconst measure = performance.measure('ic:frame', 'ic-frame-start', 'ic-frame-end');\n\t\t\ttotalMs = measure.duration;\n\t\t} catch {\n\t\t\ttotalMs = performance.now() - this.frameStart;\n\t\t}\n\t\tperformance.clearMarks('ic-frame-start');\n\t\tperformance.clearMarks('ic-frame-end');\n\n\t\tconst sample: FrameSample = {\n\t\t\ttick: this.currentTick,\n\t\t\ttimestamp: performance.now(),\n\t\t\ttotalMs,\n\t\t\tsystems: { ...this.currentSystems },\n\t\t\tvisibilityMs: this.visibilityMs,\n\t\t\tentityCount,\n\t\t\tvisibleCount,\n\t\t};\n\n\t\t// Write to ring buffer\n\t\tif (this.ring.length < RING_SIZE) {\n\t\t\tthis.ring.push(sample);\n\t\t} else {\n\t\t\tthis.ring[this.writeIdx] = sample;\n\t\t}\n\t\tthis.writeIdx = (this.writeIdx + 1) % RING_SIZE;\n\t\tif (this.ring.length >= RING_SIZE) this.filled = true;\n\t}\n\n\t/** Get the last N frame samples (newest first) */\n\tgetSamples(count?: number): FrameSample[] {\n\t\tconst n = Math.min(count ?? this.ring.length, this.ring.length);\n\t\tconst result: FrameSample[] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst idx = (this.writeIdx - 1 - i + this.ring.length) % this.ring.length;\n\t\t\tif (idx >= 0 && idx < this.ring.length) {\n\t\t\t\tresult.push(this.ring[idx]);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Compute rolling statistics from the ring buffer */\n\tgetStats(): ProfilerStats {\n\t\tconst samples = this.ring;\n\t\tconst n = samples.length;\n\n\t\tif (n === 0) {\n\t\t\treturn {\n\t\t\t\tfps: 0,\n\t\t\t\tframeTime: { avg: 0, p50: 0, p95: 0, p99: 0, max: 0 },\n\t\t\t\tsystemAvg: {},\n\t\t\t\tsystemP95: {},\n\t\t\t\tbudgetUsed: 0,\n\t\t\t\tsampleCount: 0,\n\t\t\t};\n\t\t}\n\n\t\t// Frame times sorted for percentiles\n\t\tconst frameTimes = samples.map((s) => s.totalMs).sort((a, b) => a - b);\n\n\t\t// FPS from time span\n\t\tconst newest = samples[this.filled ? (this.writeIdx - 1 + RING_SIZE) % RING_SIZE : n - 1];\n\t\tconst oldest = samples[this.filled ? this.writeIdx : 0];\n\t\tconst spanMs = newest.timestamp - oldest.timestamp;\n\t\tconst fps = spanMs > 0 ? Math.round(((n - 1) / spanMs) * 1000) : 0;\n\n\t\t// Percentiles\n\t\tconst percentile = (sorted: number[], p: number) => {\n\t\t\tconst idx = Math.floor((p / 100) * (sorted.length - 1));\n\t\t\treturn sorted[idx] ?? 0;\n\t\t};\n\n\t\tconst avg = frameTimes.reduce((a, b) => a + b, 0) / n;\n\n\t\t// Per-system stats\n\t\tconst systemNames = new Set<string>();\n\t\tfor (const s of samples) {\n\t\t\tfor (const name of Object.keys(s.systems)) systemNames.add(name);\n\t\t}\n\n\t\tconst systemAvg: Record<string, number> = {};\n\t\tconst systemP95: Record<string, number> = {};\n\t\tfor (const name of systemNames) {\n\t\t\tconst times = samples.map((s) => s.systems[name] ?? 0).sort((a, b) => a - b);\n\t\t\tsystemAvg[name] = times.reduce((a, b) => a + b, 0) / n;\n\t\t\tsystemP95[name] = percentile(times, 95);\n\t\t}\n\n\t\treturn {\n\t\t\tfps,\n\t\t\tframeTime: {\n\t\t\t\tavg,\n\t\t\t\tp50: percentile(frameTimes, 50),\n\t\t\t\tp95: percentile(frameTimes, 95),\n\t\t\t\tp99: percentile(frameTimes, 99),\n\t\t\t\tmax: frameTimes[frameTimes.length - 1],\n\t\t\t},\n\t\t\tsystemAvg,\n\t\t\tsystemP95,\n\t\t\tbudgetUsed: (avg / 16.67) * 100,\n\t\t\tsampleCount: n,\n\t\t};\n\t}\n\n\t/** Clear all collected data */\n\tclear() {\n\t\tthis.ring = [];\n\t\tthis.writeIdx = 0;\n\t\tthis.filled = false;\n\t}\n}\n","import { defineResource } from './ecs/index.js';\nimport type { EntityId } from './ecs/index.js';\n\nexport interface NavigationFrame {\n\tcontainerId: EntityId | null;\n\tcamera: { x: number; y: number; zoom: number };\n}\n\nexport const CameraResource = defineResource('Camera', {\n\tx: 0,\n\ty: 0,\n\tzoom: 1,\n});\n\nexport const ViewportResource = defineResource('Viewport', {\n\twidth: 0,\n\theight: 0,\n\tdpr: 1,\n});\n\nexport const ZoomConfigResource = defineResource('ZoomConfig', {\n\tmin: 0.1,\n\tmax: 5.0,\n});\n\nexport const BreakpointConfigResource = defineResource('BreakpointConfig', {\n\tmicro: 40,\n\tcompact: 120,\n\tnormal: 500,\n\texpanded: 1200,\n});\n\nexport const NavigationStackResource = defineResource('NavigationStack', {\n\tframes: [{ containerId: null, camera: { x: 0, y: 0, zoom: 1 } }] as NavigationFrame[],\n\tchanged: false,\n});\n\nexport type Breakpoint = 'micro' | 'compact' | 'normal' | 'expanded' | 'detailed';\n","/**\n * Snap guide computation for alignment during drag operations.\n * Implements Figma-style snapping:\n * 1. Edge/center alignment guides\n * 2. Equal spacing snap + indicators\n */\n\nexport interface SnapGuide {\n\t/** Axis this guide aligns on */\n\taxis: 'x' | 'y';\n\t/** World-space coordinate of the alignment line */\n\tposition: number;\n\t/** What kind of alignment */\n\ttype: 'edge' | 'center';\n}\n\nexport interface EqualSpacingIndicator {\n\t/** Axis along which the equal gaps run */\n\taxis: 'x' | 'y';\n\t/** The equal gap value (world units) */\n\tgap: number;\n\t/** Pairs of (from, to) marking each equal gap segment */\n\tsegments: { from: number; to: number }[];\n\t/** Position on the perpendicular axis (for rendering) */\n\tperpPosition: number;\n}\n\nexport interface SnapResult {\n\t/** Snap-corrected delta (world units). Apply to entity position. */\n\tsnapDx: number;\n\tsnapDy: number;\n\t/** Active alignment guide lines to render */\n\tguides: SnapGuide[];\n\t/** Equal spacing indicators */\n\tspacings: EqualSpacingIndicator[];\n}\n\nexport interface EntityBounds {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\n/**\n * Compute snap guides for a dragged entity against reference entities.\n */\nexport function computeSnapGuides(\n\tdragged: EntityBounds,\n\treferences: EntityBounds[],\n\tthreshold: number,\n): SnapResult {\n\tconst guides: SnapGuide[] = [];\n\tconst spacings: EqualSpacingIndicator[] = [];\n\tlet snapDx = 0;\n\tlet snapDy = 0;\n\n\t// Dragged entity edges and center\n\tconst dLeft = dragged.x;\n\tconst dRight = dragged.x + dragged.width;\n\tconst dCenterX = dragged.x + dragged.width / 2;\n\tconst dTop = dragged.y;\n\tconst dBottom = dragged.y + dragged.height;\n\tconst dCenterY = dragged.y + dragged.height / 2;\n\n\tlet bestSnapX = Number.POSITIVE_INFINITY;\n\tlet bestSnapY = Number.POSITIVE_INFINITY;\n\tlet bestDx = 0;\n\tlet bestDy = 0;\n\tconst xGuides: SnapGuide[] = [];\n\tconst yGuides: SnapGuide[] = [];\n\n\t// --- Phase 1: Edge/center alignment ---\n\n\tfor (const ref of references) {\n\t\tconst rLeft = ref.x;\n\t\tconst rRight = ref.x + ref.width;\n\t\tconst rCenterX = ref.x + ref.width / 2;\n\t\tconst rTop = ref.y;\n\t\tconst rBottom = ref.y + ref.height;\n\t\tconst rCenterY = ref.y + ref.height / 2;\n\n\t\t// X-axis alignment (vertical guide lines)\n\t\tconst xPairs: [number, number, 'edge' | 'center'][] = [\n\t\t\t[dLeft, rLeft, 'edge'],\n\t\t\t[dLeft, rRight, 'edge'],\n\t\t\t[dRight, rLeft, 'edge'],\n\t\t\t[dRight, rRight, 'edge'],\n\t\t\t[dCenterX, rCenterX, 'center'],\n\t\t\t[dLeft, rCenterX, 'edge'],\n\t\t\t[dRight, rCenterX, 'edge'],\n\t\t];\n\n\t\tfor (const [dVal, rVal, type] of xPairs) {\n\t\t\tconst dist = Math.abs(dVal - rVal);\n\t\t\tif (dist <= threshold) {\n\t\t\t\tconst dx = rVal - dVal;\n\t\t\t\tif (dist < bestSnapX) {\n\t\t\t\t\tbestSnapX = dist;\n\t\t\t\t\tbestDx = dx;\n\t\t\t\t\txGuides.length = 0;\n\t\t\t\t}\n\t\t\t\tif (dist <= bestSnapX + 0.01) {\n\t\t\t\t\txGuides.push({ axis: 'x', position: rVal, type });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Y-axis alignment (horizontal guide lines)\n\t\tconst yPairs: [number, number, 'edge' | 'center'][] = [\n\t\t\t[dTop, rTop, 'edge'],\n\t\t\t[dTop, rBottom, 'edge'],\n\t\t\t[dBottom, rTop, 'edge'],\n\t\t\t[dBottom, rBottom, 'edge'],\n\t\t\t[dCenterY, rCenterY, 'center'],\n\t\t\t[dTop, rCenterY, 'edge'],\n\t\t\t[dBottom, rCenterY, 'edge'],\n\t\t];\n\n\t\tfor (const [dVal, rVal, type] of yPairs) {\n\t\t\tconst dist = Math.abs(dVal - rVal);\n\t\t\tif (dist <= threshold) {\n\t\t\t\tconst dy = rVal - dVal;\n\t\t\t\tif (dist < bestSnapY) {\n\t\t\t\t\tbestSnapY = dist;\n\t\t\t\t\tbestDy = dy;\n\t\t\t\t\tyGuides.length = 0;\n\t\t\t\t}\n\t\t\t\tif (dist <= bestSnapY + 0.01) {\n\t\t\t\t\tyGuides.push({ axis: 'y', position: rVal, type });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Phase 2: Equal spacing snap ---\n\t// Check if we can place the dragged entity so that the gap to its\n\t// left and right (or top and bottom) neighbors are equal.\n\n\tconst eqResult = computeEqualSpacing(dragged, references, threshold);\n\n\t// Merge: alignment snap takes priority, equal spacing fills in the other axis\n\tif (bestSnapX <= threshold) {\n\t\tsnapDx = bestDx;\n\t} else if (eqResult.snapDx !== undefined) {\n\t\tsnapDx = eqResult.snapDx;\n\t}\n\tif (bestSnapY <= threshold) {\n\t\tsnapDy = bestDy;\n\t} else if (eqResult.snapDy !== undefined) {\n\t\tsnapDy = eqResult.snapDy;\n\t}\n\n\t// Collect alignment guides\n\tif (bestSnapX <= threshold) {\n\t\tconst seen = new Set<number>();\n\t\tfor (const g of xGuides) {\n\t\t\tif (!seen.has(g.position)) {\n\t\t\t\tseen.add(g.position);\n\t\t\t\tguides.push(g);\n\t\t\t}\n\t\t}\n\t}\n\tif (bestSnapY <= threshold) {\n\t\tconst seen = new Set<number>();\n\t\tfor (const g of yGuides) {\n\t\t\tif (!seen.has(g.position)) {\n\t\t\t\tseen.add(g.position);\n\t\t\t\tguides.push(g);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Collect equal spacing indicators (after applying snap)\n\tconst snappedBounds: EntityBounds = {\n\t\tx: dragged.x + snapDx,\n\t\ty: dragged.y + snapDy,\n\t\twidth: dragged.width,\n\t\theight: dragged.height,\n\t};\n\tconst eqFinal = computeEqualSpacing(snappedBounds, references, threshold * 0.5);\n\tspacings.push(...eqFinal.indicators);\n\n\treturn { snapDx, snapDy, guides, spacings };\n}\n\n// --- Equal spacing computation ---\n\ninterface EqualSpacingResult {\n\tsnapDx?: number;\n\tsnapDy?: number;\n\tindicators: EqualSpacingIndicator[];\n}\n\nfunction computeEqualSpacing(\n\tdragged: EntityBounds,\n\treferences: EntityBounds[],\n\tthreshold: number,\n): EqualSpacingResult {\n\tconst indicators: EqualSpacingIndicator[] = [];\n\tlet snapDx: number | undefined;\n\tlet snapDy: number | undefined;\n\n\t// Check X-axis (horizontal spacing)\n\tconst xResult = checkAxisSpacing(dragged, references, threshold, 'x');\n\tif (xResult) {\n\t\tsnapDx = xResult.snap;\n\t\tindicators.push(...xResult.indicators);\n\t}\n\n\t// Check Y-axis (vertical spacing)\n\tconst yResult = checkAxisSpacing(dragged, references, threshold, 'y');\n\tif (yResult) {\n\t\tsnapDy = yResult.snap;\n\t\tindicators.push(...yResult.indicators);\n\t}\n\n\treturn { snapDx, snapDy, indicators };\n}\n\nfunction checkAxisSpacing(\n\tdragged: EntityBounds,\n\treferences: EntityBounds[],\n\tthreshold: number,\n\taxis: 'x' | 'y',\n): { snap: number; indicators: EqualSpacingIndicator[] } | null {\n\tconst isX = axis === 'x';\n\n\t// Get position/size accessors based on axis\n\tconst pos = (b: EntityBounds) => (isX ? b.x : b.y);\n\tconst size = (b: EntityBounds) => (isX ? b.width : b.height);\n\tconst perpPos = (b: EntityBounds) => (isX ? b.y : b.x);\n\tconst perpSize = (b: EntityBounds) => (isX ? b.height : b.width);\n\tconst end = (b: EntityBounds) => pos(b) + size(b);\n\n\t// Filter to entities on the same perpendicular band (overlapping)\n\tconst neighbors = references.filter(\n\t\t(ref) =>\n\t\t\tperpPos(ref) < perpPos(dragged) + perpSize(dragged) &&\n\t\t\tperpPos(ref) + perpSize(ref) > perpPos(dragged),\n\t);\n\n\tif (neighbors.length < 1) return null;\n\n\t// Sort neighbors by position on this axis\n\tconst sorted = [...neighbors].sort((a, b) => pos(a) - pos(b));\n\n\t// Find existing gaps between consecutive reference entities\n\tconst refGaps: { from: EntityBounds; to: EntityBounds; gap: number }[] = [];\n\tfor (let i = 0; i < sorted.length - 1; i++) {\n\t\tconst gap = pos(sorted[i + 1]) - end(sorted[i]);\n\t\tif (gap > 0.1) {\n\t\t\trefGaps.push({ from: sorted[i], to: sorted[i + 1], gap });\n\t\t}\n\t}\n\n\tlet bestSnap: number | null = null;\n\tlet bestIndicators: EqualSpacingIndicator[] = [];\n\tlet bestDiff = Number.POSITIVE_INFINITY;\n\n\t// Case 1: Between two neighbors (left gap ≈ right gap)\n\t// Find the nearest left and right neighbors\n\tlet leftN: EntityBounds | null = null;\n\tlet rightN: EntityBounds | null = null;\n\tfor (const ref of sorted) {\n\t\tif (end(ref) <= pos(dragged) + threshold) {\n\t\t\tif (!leftN || end(ref) > end(leftN)) leftN = ref;\n\t\t}\n\t\tif (pos(ref) >= end(dragged) - threshold) {\n\t\t\tif (!rightN || pos(ref) < pos(rightN)) rightN = ref;\n\t\t}\n\t}\n\n\tif (leftN && rightN) {\n\t\tconst lGap = pos(dragged) - end(leftN);\n\t\tconst rGap = pos(rightN) - end(dragged);\n\t\tconst diff = Math.abs(lGap - rGap);\n\t\tif (diff <= threshold && diff < bestDiff) {\n\t\t\tconst idealPos = (end(leftN) + pos(rightN) - size(dragged)) / 2;\n\t\t\tconst snap = idealPos - pos(dragged);\n\t\t\tconst equalGap = (pos(rightN) - end(leftN) - size(dragged)) / 2;\n\t\t\tif (equalGap > 0.1) {\n\t\t\t\tconst perpY = computePerpCenter(dragged, [leftN, rightN], isX);\n\t\t\t\tbestSnap = snap;\n\t\t\t\tbestDiff = diff;\n\t\t\t\tbestIndicators = [\n\t\t\t\t\t{\n\t\t\t\t\t\taxis,\n\t\t\t\t\t\tgap: equalGap,\n\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t{ from: end(leftN), to: idealPos },\n\t\t\t\t\t\t\t{ from: idealPos + size(dragged), to: pos(rightN) },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tperpPosition: perpY,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Case 2: Extend pattern — dragged at the end or beginning of a row\n\t// Find gaps in the existing reference layout and try to match\n\tfor (const refGap of refGaps) {\n\t\tconst patternGap = refGap.gap;\n\n\t\t// Try placing dragged to the right of the rightmost entity in this pattern\n\t\tif (rightN === null || pos(refGap.to) >= end(dragged) - threshold * 2) {\n\t\t\t// Find the rightmost entity in the chain with this gap\n\t\t\tconst chainEnd = refGap.to;\n\t\t\t// Check: dragged gap to chainEnd matches patternGap?\n\t\t\tconst dragGap = pos(dragged) - end(chainEnd);\n\t\t\tconst diff = Math.abs(dragGap - patternGap);\n\t\t\tif (diff <= threshold && diff < bestDiff) {\n\t\t\t\tconst idealPos = end(chainEnd) + patternGap;\n\t\t\t\tconst snap = idealPos - pos(dragged);\n\t\t\t\tconst perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);\n\t\t\t\tbestSnap = snap;\n\t\t\t\tbestDiff = diff;\n\t\t\t\t// Show all equal gaps: the existing one + the new one\n\t\t\t\tbestIndicators = [\n\t\t\t\t\t{\n\t\t\t\t\t\taxis,\n\t\t\t\t\t\tgap: patternGap,\n\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t{ from: end(refGap.from), to: pos(refGap.to) },\n\t\t\t\t\t\t\t{ from: end(chainEnd), to: idealPos },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tperpPosition: perpY,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\n\t\t// Try placing dragged to the left of the leftmost entity in this pattern\n\t\tif (leftN === null || end(refGap.from) <= pos(dragged) + threshold * 2) {\n\t\t\tconst chainStart = refGap.from;\n\t\t\tconst dragGap = pos(chainStart) - end(dragged);\n\t\t\tconst diff = Math.abs(dragGap - patternGap);\n\t\t\tif (diff <= threshold && diff < bestDiff) {\n\t\t\t\tconst idealPos = pos(chainStart) - patternGap - size(dragged);\n\t\t\t\tconst snap = idealPos - pos(dragged);\n\t\t\t\tconst perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);\n\t\t\t\tbestSnap = snap;\n\t\t\t\tbestDiff = diff;\n\t\t\t\tbestIndicators = [\n\t\t\t\t\t{\n\t\t\t\t\t\taxis,\n\t\t\t\t\t\tgap: patternGap,\n\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t{ from: idealPos + size(dragged), to: pos(chainStart) },\n\t\t\t\t\t\t\t{ from: end(refGap.from), to: pos(refGap.to) },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tperpPosition: perpY,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (bestSnap !== null) {\n\t\treturn { snap: bestSnap, indicators: bestIndicators };\n\t}\n\treturn null;\n}\n\nfunction computePerpCenter(dragged: EntityBounds, refs: EntityBounds[], isX: boolean): number {\n\tconst perpPos = (b: EntityBounds) => (isX ? b.y : b.x);\n\tconst perpSize = (b: EntityBounds) => (isX ? b.height : b.width);\n\tconst allBounds = [dragged, ...refs];\n\tconst maxStart = Math.max(...allBounds.map(perpPos));\n\tconst minEnd = Math.min(...allBounds.map((b) => perpPos(b) + perpSize(b)));\n\treturn maxStart + (minEnd - maxStart) / 2;\n}\n","import RBushImport from 'rbush';\n// Handle CJS/ESM interop — rbush exports differently depending on context\nconst RBush = (\n\ttypeof (RBushImport as any).default === 'function' ? (RBushImport as any).default : RBushImport\n) as typeof RBushImport;\nimport type { EntityId } from './ecs/index.js';\nimport type { AABB } from './math.js';\n\nexport interface SpatialEntry extends AABB {\n\tentityId: EntityId;\n}\n\n/**\n * Spatial index backed by an R-tree (rbush).\n * Stores world-space AABBs for fast viewport culling and hit testing.\n */\nexport class SpatialIndex {\n\tprivate tree = new RBush<SpatialEntry>();\n\tprivate entries = new Map<EntityId, SpatialEntry>();\n\n\tupsert(entityId: EntityId, bounds: AABB) {\n\t\tconst existing = this.entries.get(entityId);\n\t\tif (existing) {\n\t\t\t// Fix #8: Pass known reference directly — O(log n) instead of O(n) comparator scan\n\t\t\tthis.tree.remove(existing);\n\t\t}\n\t\tconst entry: SpatialEntry = { ...bounds, entityId };\n\t\tthis.entries.set(entityId, entry);\n\t\tthis.tree.insert(entry);\n\t}\n\n\tremove(entityId: EntityId) {\n\t\tconst existing = this.entries.get(entityId);\n\t\tif (existing) {\n\t\t\tthis.tree.remove(existing);\n\t\t\tthis.entries.delete(entityId);\n\t\t}\n\t}\n\n\t/** Query all entries intersecting the given AABB */\n\tsearch(bounds: AABB): SpatialEntry[] {\n\t\treturn this.tree.search(bounds);\n\t}\n\n\t/** Find the topmost entity at a point (by z-order — caller sorts) */\n\tsearchPoint(x: number, y: number, tolerance = 0): SpatialEntry[] {\n\t\treturn this.tree.search({\n\t\t\tminX: x - tolerance,\n\t\t\tminY: y - tolerance,\n\t\t\tmaxX: x + tolerance,\n\t\t\tmaxY: y + tolerance,\n\t\t});\n\t}\n\n\tclear() {\n\t\tthis.tree.clear();\n\t\tthis.entries.clear();\n\t}\n\n\tget size(): number {\n\t\treturn this.entries.size;\n\t}\n}\n","import {\n\tActive,\n\tChildren,\n\tParent,\n\tTransform2D,\n\tVisible,\n\tWidget,\n\tWidgetBreakpoint,\n\tWorldBounds,\n} from './components.js';\nimport { defineSystem } from './ecs/index.js';\nimport type { World } from './ecs/index.js';\nimport { SpatialIndexResource } from './engine.js';\nimport { intersectsAABB, worldBoundsToAABB } from './math.js';\nimport {\n\tBreakpointConfigResource,\n\tCameraResource,\n\tNavigationStackResource,\n\tViewportResource,\n} from './resources.js';\nimport type { Breakpoint } from './resources.js';\n\n/**\n * Propagate transforms down the parent-child hierarchy.\n * Computes WorldBounds for every entity with Transform2D.\n * Uses change detection — only processes dirty entities and their descendants.\n */\nexport const transformPropagateSystem = defineSystem({\n\tname: 'transformPropagate',\n\texecute: (world: World) => {\n\t\tconst changed = world.queryChanged(Transform2D);\n\t\tconst processed = new Set<number>();\n\n\t\tfor (const entity of changed) {\n\t\t\tpropagateEntity(world, entity, processed);\n\t\t}\n\n\t\tfor (const entity of world.queryAdded(Transform2D)) {\n\t\t\tif (!processed.has(entity)) {\n\t\t\t\tpropagateEntity(world, entity, processed);\n\t\t\t}\n\t\t}\n\t},\n});\n\nfunction propagateEntity(world: World, entity: number, processed: Set<number>) {\n\tif (processed.has(entity)) return;\n\tprocessed.add(entity);\n\n\tconst transform = world.getComponent(entity, Transform2D);\n\tif (!transform) return;\n\n\tlet worldX = transform.x;\n\tlet worldY = transform.y;\n\n\tconst parentComp = world.getComponent(entity, Parent);\n\tif (parentComp && world.entityExists(parentComp.id)) {\n\t\tconst parentBounds = world.getComponent(parentComp.id, WorldBounds);\n\t\tif (parentBounds) {\n\t\t\tworldX += parentBounds.worldX;\n\t\t\tworldY += parentBounds.worldY;\n\t\t}\n\t}\n\n\tif (!world.hasComponent(entity, WorldBounds)) {\n\t\tworld.addComponent(entity, WorldBounds, {\n\t\t\tworldX,\n\t\t\tworldY,\n\t\t\tworldWidth: transform.width,\n\t\t\tworldHeight: transform.height,\n\t\t});\n\t} else {\n\t\tworld.setComponent(entity, WorldBounds, {\n\t\t\tworldX,\n\t\t\tworldY,\n\t\t\tworldWidth: transform.width,\n\t\t\tworldHeight: transform.height,\n\t\t});\n\t}\n\n\tconst children = world.getComponent(entity, Children);\n\tif (children) {\n\t\tfor (const childId of children.ids) {\n\t\t\tpropagateEntity(world, childId, processed);\n\t\t}\n\t}\n}\n\n/**\n * Filter entities to the active navigation layer.\n * Only runs when navigation stack changes.\n */\nexport const navigationFilterSystem = defineSystem({\n\tname: 'navigationFilter',\n\tafter: 'transformPropagate',\n\texecute: (world: World) => {\n\t\tconst navStack = world.getResource(NavigationStackResource);\n\t\tif (!navStack.changed) return;\n\n\t\tconst currentFrame = navStack.frames[navStack.frames.length - 1];\n\n\t\tfor (const entity of world.queryTagged(Active)) {\n\t\t\tworld.removeTag(entity, Active);\n\t\t}\n\n\t\tif (currentFrame.containerId === null) {\n\t\t\tfor (const entity of world.query(Transform2D)) {\n\t\t\t\tif (!world.hasComponent(entity, Parent)) {\n\t\t\t\t\tworld.addTag(entity, Active);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst children = world.getComponent(currentFrame.containerId, Children);\n\t\t\tif (children) {\n\t\t\t\tfor (const childId of children.ids) {\n\t\t\t\t\tworld.addTag(childId, Active);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tnavStack.changed = false;\n\t},\n});\n\n/**\n * Viewport culling — mark Active entities that intersect the viewport as Visible.\n */\nexport const cullSystem = defineSystem({\n\tname: 'cull',\n\tafter: 'navigationFilter',\n\texecute: (world: World) => {\n\t\tconst camera = world.getResource(CameraResource);\n\t\tconst viewport = world.getResource(ViewportResource);\n\t\tif (viewport.width === 0 || viewport.height === 0) return;\n\n\t\tconst res = world.getResource(SpatialIndexResource);\n\t\tconst spatialIndex = res.instance;\n\n\t\tconst overscan = 200 / camera.zoom;\n\t\tconst vpWorldAABB = {\n\t\t\tminX: camera.x - overscan,\n\t\t\tminY: camera.y - overscan,\n\t\t\tmaxX: camera.x + viewport.width / camera.zoom + overscan,\n\t\t\tmaxY: camera.y + viewport.height / camera.zoom + overscan,\n\t\t};\n\n\t\tfor (const entity of world.queryTagged(Visible)) {\n\t\t\tworld.removeTag(entity, Visible);\n\t\t}\n\n\t\tif (spatialIndex && spatialIndex.size > 0) {\n\t\t\tconst candidates = spatialIndex.search(vpWorldAABB);\n\t\t\tfor (const entry of candidates) {\n\t\t\t\tif (world.hasTag(entry.entityId, Active)) {\n\t\t\t\t\tworld.addTag(entry.entityId, Visible);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const entity of world.queryTagged(Active)) {\n\t\t\t\tconst wb = world.getComponent(entity, WorldBounds);\n\t\t\t\tif (wb && intersectsAABB(worldBoundsToAABB(wb), vpWorldAABB)) {\n\t\t\t\t\tworld.addTag(entity, Visible);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n});\n\n/**\n * Compute breakpoints for visible widgets based on screen size.\n * Fix #10: Always update screenWidth/screenHeight even if breakpoint tier doesn't change.\n */\nexport const breakpointSystem = defineSystem({\n\tname: 'breakpoint',\n\tafter: 'cull',\n\texecute: (world: World) => {\n\t\tconst camera = world.getResource(CameraResource);\n\t\tconst config = world.getResource(BreakpointConfigResource);\n\n\t\tfor (const entity of world.query(Widget, Visible)) {\n\t\t\tconst transform = world.getComponent(entity, Transform2D);\n\t\t\tif (!transform) continue;\n\n\t\t\tconst screenWidth = transform.width * camera.zoom;\n\t\t\tconst screenHeight = transform.height * camera.zoom;\n\n\t\t\tlet bp: Breakpoint;\n\t\t\tif (screenWidth < config.micro) bp = 'micro';\n\t\t\telse if (screenWidth < config.compact) bp = 'compact';\n\t\t\telse if (screenWidth < config.normal) bp = 'normal';\n\t\t\telse if (screenWidth < config.expanded) bp = 'expanded';\n\t\t\telse bp = 'detailed';\n\n\t\t\tconst existing = world.getComponent(entity, WidgetBreakpoint);\n\t\t\tif (!existing) {\n\t\t\t\tworld.addComponent(entity, WidgetBreakpoint, {\n\t\t\t\t\tcurrent: bp,\n\t\t\t\t\tscreenWidth,\n\t\t\t\t\tscreenHeight,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Fix #10: Update if breakpoint tier changed OR screen dimensions changed significantly\n\t\t\t\tconst bpChanged = existing.current !== bp;\n\t\t\t\tconst sizeChanged =\n\t\t\t\t\tMath.abs(existing.screenWidth - screenWidth) > 1 ||\n\t\t\t\t\tMath.abs(existing.screenHeight - screenHeight) > 1;\n\n\t\t\t\tif (bpChanged || sizeChanged) {\n\t\t\t\t\tworld.setComponent(entity, WidgetBreakpoint, {\n\t\t\t\t\t\tcurrent: bp,\n\t\t\t\t\t\tscreenWidth,\n\t\t\t\t\t\tscreenHeight,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n});\n\n/**\n * Sort visible entities by z-index (handled in engine.tick()).\n */\nexport const sortSystem = defineSystem({\n\tname: 'sort',\n\tafter: 'breakpoint',\n\texecute: (_world: World) => {\n\t\t// Sorting is done in engine.tick() after systems run\n\t},\n});\n","import { CommandBuffer, MoveCommand, ResizeCommand } from './commands.js';\nimport type { Command } from './commands.js';\nimport {\n\tActive,\n\tChildren,\n\tContainer,\n\tDraggable,\n\tParent,\n\tResizable,\n\tSelectable,\n\tSelected,\n\tTransform2D,\n\tVisible,\n\tWidget,\n\tWidgetBreakpoint,\n\tWidgetData,\n\tWorldBounds,\n\tZIndex,\n} from './components.js';\nimport type {\n\tComponentInit,\n\tComponentType,\n\tEntityId,\n\tSystemDef,\n\tTagType,\n\tUnsubscribe,\n\tWorld,\n} from './ecs/index.js';\nimport { SystemScheduler, createWorld, defineResource } from './ecs/index.js';\nimport { clamp, pointInAABB, screenToWorld, worldBoundsToAABB } from './math.js';\nimport { Profiler } from './profiler.js';\nimport {\n\tBreakpointConfigResource,\n\tCameraResource,\n\tNavigationStackResource,\n\tViewportResource,\n\tZoomConfigResource,\n} from './resources.js';\nimport type { Breakpoint } from './resources.js';\nimport { computeSnapGuides } from './snap.js';\nimport type { EqualSpacingIndicator, SnapGuide, SnapResult } from './snap.js';\nimport { SpatialIndex } from './spatial.js';\nimport {\n\tbreakpointSystem,\n\tcullSystem,\n\tnavigationFilterSystem,\n\tsortSystem,\n\ttransformPropagateSystem,\n} from './systems.js';\n\n// === Fix #11: SpatialIndex as a proper resource ===\nexport const SpatialIndexResource = defineResource('SpatialIndex', {\n\tinstance: null as SpatialIndex | null,\n});\n\n// === Pointer Directives ===\n\nexport type PointerDirective =\n\t| { action: 'passthrough' }\n\t| { action: 'passthrough-track-drag' }\n\t| { action: 'capture-drag' }\n\t| { action: 'capture-resize'; handle: ResizeHandlePos }\n\t| { action: 'capture-marquee' };\n\nexport type ResizeHandlePos = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';\n\nexport interface Modifiers {\n\tshift: boolean;\n\tctrl: boolean;\n\talt: boolean;\n\tmeta: boolean;\n}\n\n// === Input state machine ===\n\ntype InputState =\n\t| { mode: 'idle' }\n\t| { mode: 'tracking'; entityId: EntityId; startX: number; startY: number }\n\t| {\n\t\t\tmode: 'dragging';\n\t\t\tentityId: EntityId;\n\t\t\tstartScreenX: number;\n\t\t\tstartScreenY: number;\n\t\t\tstartPositions: Map<EntityId, { x: number; y: number }>;\n\t\t\toriginalZIndices: Map<EntityId, number>;\n\t }\n\t| {\n\t\t\tmode: 'resizing';\n\t\t\tentityId: EntityId;\n\t\t\thandle: ResizeHandlePos;\n\t\t\tstartX: number;\n\t\t\tstartY: number;\n\t\t\tstartBounds: { x: number; y: number; width: number; height: number };\n\t }\n\t| { mode: 'marquee'; startX: number; startY: number };\n\nconst DEAD_ZONE_PX = 4;\n\n// === Visible entity for renderers ===\n\nexport interface VisibleEntity {\n\tentityId: EntityId;\n\tworldX: number;\n\tworldY: number;\n\tworldWidth: number;\n\tworldHeight: number;\n\tbreakpoint: Breakpoint;\n\tzIndex: number;\n\tsurface: string;\n\twidgetType: string;\n}\n\n// === Frame changes ===\n\nexport interface FrameChanges {\n\tpositionsChanged: EntityId[];\n\tbreakpointsChanged: EntityId[];\n\tentered: EntityId[];\n\texited: EntityId[];\n\tcameraChanged: boolean;\n\tnavigationChanged: boolean;\n\tselectionChanged: boolean;\n}\n\n// === Engine Config ===\n\nexport interface AddWidgetOptions {\n\ttype: string;\n\tposition: { x: number; y: number };\n\tsize: { width: number; height: number };\n\trotation?: number;\n\tdata?: Record<string, unknown>;\n\tsurface?: 'dom' | 'webgl';\n\tzIndex?: number;\n\tselectable?: boolean;\n\tdraggable?: boolean;\n\tresizable?: boolean;\n\tparent?: EntityId;\n}\n\nexport interface LayoutEngineConfig {\n\tmaxEntities?: number;\n\tzoom?: { min: number; max: number };\n\tbreakpoints?: { micro: number; compact: number; normal: number; expanded: number };\n}\n\n// === Engine ===\n\nexport interface LayoutEngine {\n\treadonly world: World;\n\n\t// Entity CRUD\n\tcreateEntity(inits?: ComponentInit[]): EntityId;\n\taddWidget(opts: AddWidgetOptions): EntityId;\n\tdestroyEntity(id: EntityId): void;\n\n\t// Shorthand\n\tget<T>(entity: EntityId, type: ComponentType<T>): T | undefined;\n\tset<T>(entity: EntityId, type: ComponentType<T>, data: Partial<T>): void;\n\thas(entity: EntityId, type: ComponentType | TagType): boolean;\n\n\t// Extensions\n\tregisterSystem(system: SystemDef): void;\n\tremoveSystem(name: string): void;\n\n\t// Camera\n\tgetCamera(): { x: number; y: number; zoom: number };\n\tpanBy(dx: number, dy: number): void;\n\tpanTo(worldX: number, worldY: number): void;\n\tzoomAtPoint(screenX: number, screenY: number, delta: number): void;\n\tzoomTo(zoom: number): void;\n\tzoomToFit(entityIds?: EntityId[], padding?: number): void;\n\n\t// Viewport\n\tsetViewport(width: number, height: number, dpr?: number): void;\n\n\t// Pointer input\n\thandlePointerDown(\n\t\tscreenX: number,\n\t\tscreenY: number,\n\t\tbutton: number,\n\t\tmodifiers: Modifiers,\n\t): PointerDirective;\n\thandlePointerMove(screenX: number, screenY: number, modifiers: Modifiers): PointerDirective;\n\thandlePointerUp(): PointerDirective;\n\n\t// Selection & Hover\n\tgetSelectedEntities(): EntityId[];\n\tgetHoveredEntity(): EntityId | null;\n\n\t// Navigation\n\tenterContainer(entity: EntityId): void;\n\texitContainer(): void;\n\tgetActiveContainer(): EntityId | null;\n\tgetNavigationDepth(): number;\n\n\t// Commands + Undo/Redo\n\texecute(command: Command): void;\n\tbeginCommandGroup(): void;\n\tendCommandGroup(): void;\n\tundo(): boolean;\n\tredo(): boolean;\n\tcanUndo(): boolean;\n\tcanRedo(): boolean;\n\n\t// Frame\n\tmarkDirty(): void;\n\ttick(): void;\n\tflushIfDirty(): boolean;\n\n\t// Output\n\tgetVisibleEntities(): VisibleEntity[];\n\tgetFrameChanges(): FrameChanges;\n\n\t// Spatial index (exposed for systems)\n\tgetSpatialIndex(): SpatialIndex;\n\n\t// Snap guides\n\tgetSnapGuides(): SnapGuide[];\n\tgetEqualSpacing(): EqualSpacingIndicator[];\n\tsetSnapEnabled(on: boolean): void;\n\tsetSnapThreshold(worldPx: number): void;\n\n\t// Performance profiling\n\treadonly profiler: Profiler;\n\n\t// Events\n\tonFrame(handler: () => void): Unsubscribe;\n\n\t// Lifecycle\n\tdestroy(): void;\n}\n\nexport function createLayoutEngine(config?: LayoutEngineConfig): LayoutEngine {\n\tconst world = createWorld();\n\tconst scheduler = new SystemScheduler();\n\tconst spatialIndex = new SpatialIndex();\n\tconst profiler = new Profiler();\n\tscheduler.profiler = profiler;\n\n\t// Fix #11: Store spatial index as a proper resource\n\tworld.setResource(SpatialIndexResource, { instance: spatialIndex });\n\n\tconst commandBuffer = new CommandBuffer();\n\n\t// Apply config\n\tif (config?.zoom) {\n\t\tworld.setResource(ZoomConfigResource, config.zoom);\n\t}\n\tif (config?.breakpoints) {\n\t\tworld.setResource(BreakpointConfigResource, config.breakpoints);\n\t}\n\n\t// Register built-in systems\n\tscheduler.register(transformPropagateSystem);\n\tscheduler.register(navigationFilterSystem);\n\tscheduler.register(cullSystem);\n\tscheduler.register(breakpointSystem);\n\tscheduler.register(sortSystem);\n\n\t// P3: Wire spatial index reactively via observer instead of per-frame system scan\n\tworld.onComponentChanged(WorldBounds, (entityId, _prev, wb) => {\n\t\tif (wb) {\n\t\t\tspatialIndex.upsert(entityId, worldBoundsToAABB(wb));\n\t\t}\n\t});\n\n\t// Initialize navigation — mark root entities as Active on first tick\n\tworld.setResource(NavigationStackResource, { changed: true });\n\n\t// State\n\tlet inputState: InputState = { mode: 'idle' };\n\tlet hoveredEntity: EntityId | null = null;\n\tlet snapEnabled = true;\n\tlet snapThreshold = 5; // world units\n\tlet currentSnap: SnapResult = { snapDx: 0, snapDy: 0, guides: [], spacings: [] };\n\tlet dirty = false;\n\tlet cameraChangedThisTick = false;\n\tlet selectionChangedThisTick = false; // Fix #2: proper selection tracking\n\tlet prevVisible = new Set<EntityId>();\n\tlet currentVisible: VisibleEntity[] = [];\n\tlet frameChanges: FrameChanges = {\n\t\tpositionsChanged: [],\n\t\tbreakpointsChanged: [],\n\t\tentered: [],\n\t\texited: [],\n\t\tcameraChanged: false,\n\t\tnavigationChanged: false,\n\t\tselectionChanged: false,\n\t};\n\n\tfunction markDirtyInternal() {\n\t\tdirty = true;\n\t}\n\n\tfunction hitTest(screenX: number, screenY: number): EntityId | null {\n\t\tconst camera = world.getResource(CameraResource);\n\t\tconst worldPos = screenToWorld(screenX, screenY, camera);\n\t\tconst tolerance = 2 / camera.zoom;\n\t\tconst candidates = spatialIndex.searchPoint(worldPos.x, worldPos.y, tolerance);\n\n\t\t// Filter to Active entities, sort by z-index (highest first)\n\t\tconst active = candidates\n\t\t\t.filter((c) => world.hasTag(c.entityId, Active))\n\t\t\t.sort((a, b) => {\n\t\t\t\tconst zA = world.getComponent(a.entityId, ZIndex)?.value ?? 0;\n\t\t\t\tconst zB = world.getComponent(b.entityId, ZIndex)?.value ?? 0;\n\t\t\t\treturn zB - zA;\n\t\t\t});\n\n\t\tfor (const candidate of active) {\n\t\t\tconst wb = world.getComponent(candidate.entityId, WorldBounds);\n\t\t\tif (wb && pointInAABB(worldPos.x, worldPos.y, worldBoundsToAABB(wb))) {\n\t\t\t\treturn candidate.entityId;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tfunction hitTestResizeHandle(\n\t\tscreenX: number,\n\t\tscreenY: number,\n\t): { entityId: EntityId; handle: ResizeHandlePos } | null {\n\t\tconst selected = engine.getSelectedEntities();\n\t\tif (selected.length !== 1) return null;\n\n\t\tconst entity = selected[0];\n\t\tconst wb = world.getComponent(entity, WorldBounds);\n\t\tif (!wb || !world.hasTag(entity, Resizable)) return null;\n\n\t\tconst camera = world.getResource(CameraResource);\n\t\tconst worldPos = screenToWorld(screenX, screenY, camera);\n\t\tconst handleSize = 8 / camera.zoom;\n\n\t\tconst x = wb.worldX;\n\t\tconst y = wb.worldY;\n\t\tconst w = wb.worldWidth;\n\t\tconst h = wb.worldHeight;\n\n\t\tconst handles: { pos: ResizeHandlePos; cx: number; cy: number }[] = [\n\t\t\t{ pos: 'nw', cx: x, cy: y },\n\t\t\t{ pos: 'n', cx: x + w / 2, cy: y },\n\t\t\t{ pos: 'ne', cx: x + w, cy: y },\n\t\t\t{ pos: 'e', cx: x + w, cy: y + h / 2 },\n\t\t\t{ pos: 'se', cx: x + w, cy: y + h },\n\t\t\t{ pos: 's', cx: x + w / 2, cy: y + h },\n\t\t\t{ pos: 'sw', cx: x, cy: y + h },\n\t\t\t{ pos: 'w', cx: x, cy: y + h / 2 },\n\t\t];\n\n\t\tfor (const handle of handles) {\n\t\t\tif (\n\t\t\t\tMath.abs(worldPos.x - handle.cx) <= handleSize &&\n\t\t\t\tMath.abs(worldPos.y - handle.cy) <= handleSize\n\t\t\t) {\n\t\t\t\treturn { entityId: entity, handle: handle.pos };\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Fix #2: track selection changes explicitly\n\tfunction selectEntity(entity: EntityId, additive: boolean) {\n\t\tif (!world.hasTag(entity, Selectable)) return;\n\n\t\tif (additive) {\n\t\t\tif (world.hasTag(entity, Selected)) {\n\t\t\t\tworld.removeTag(entity, Selected);\n\t\t\t} else {\n\t\t\t\tworld.addTag(entity, Selected);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const e of world.queryTagged(Selected)) {\n\t\t\t\tif (e !== entity) world.removeTag(e, Selected);\n\t\t\t}\n\t\t\tworld.addTag(entity, Selected);\n\t\t}\n\t\tselectionChangedThisTick = true;\n\t}\n\n\tfunction clearSelection() {\n\t\tconst selected = world.queryTagged(Selected);\n\t\tif (selected.length > 0) {\n\t\t\tfor (const e of selected) {\n\t\t\t\tworld.removeTag(e, Selected);\n\t\t\t}\n\t\t\tselectionChangedThisTick = true;\n\t\t}\n\t}\n\n\tconst engine: LayoutEngine = {\n\t\tworld,\n\n\t\t// === Entity CRUD ===\n\n\t\tcreateEntity(inits?: ComponentInit[]): EntityId {\n\t\t\tconst entity = world.createEntity();\n\t\t\tif (inits) {\n\t\t\t\tfor (const init of inits) {\n\t\t\t\t\tconst type = init[0];\n\t\t\t\t\tif (type.__kind === 'tag') {\n\t\t\t\t\t\tworld.addTag(entity, type as TagType);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tworld.addComponent(entity, type as ComponentType, init[1] ?? {});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tmarkDirtyInternal();\n\t\t\treturn entity;\n\t\t},\n\n\t\taddWidget(opts: AddWidgetOptions): EntityId {\n\t\t\tconst inits: ComponentInit[] = [\n\t\t\t\t[\n\t\t\t\t\tTransform2D,\n\t\t\t\t\t{\n\t\t\t\t\t\tx: opts.position.x,\n\t\t\t\t\t\ty: opts.position.y,\n\t\t\t\t\t\twidth: opts.size.width,\n\t\t\t\t\t\theight: opts.size.height,\n\t\t\t\t\t\trotation: opts.rotation ?? 0,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t[Widget, { surface: opts.surface ?? 'dom', type: opts.type }],\n\t\t\t];\n\t\t\tif (opts.data !== undefined) {\n\t\t\t\tinits.push([WidgetData, { data: opts.data }]);\n\t\t\t}\n\t\t\tinits.push([ZIndex, { value: opts.zIndex ?? 0 }]);\n\t\t\tif (opts.selectable !== false) inits.push([Selectable]);\n\t\t\tif (opts.draggable !== false) inits.push([Draggable]);\n\t\t\tif (opts.resizable !== false) inits.push([Resizable]);\n\t\t\tif (opts.parent !== undefined) {\n\t\t\t\tinits.push([Parent, { id: opts.parent }]);\n\t\t\t}\n\t\t\treturn engine.createEntity(inits);\n\t\t},\n\n\t\tdestroyEntity(id: EntityId) {\n\t\t\tspatialIndex.remove(id);\n\t\t\tworld.destroyEntity(id);\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tget<T>(entity: EntityId, type: ComponentType<T>): T | undefined {\n\t\t\treturn world.getComponent(entity, type);\n\t\t},\n\n\t\tset<T>(entity: EntityId, type: ComponentType<T>, data: Partial<T>) {\n\t\t\tworld.setComponent(entity, type, data);\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\thas(entity: EntityId, type: ComponentType | TagType): boolean {\n\t\t\tif (type.__kind === 'tag') return world.hasTag(entity, type as TagType);\n\t\t\treturn world.hasComponent(entity, type as ComponentType);\n\t\t},\n\n\t\t// === Extensions ===\n\n\t\tregisterSystem(system: SystemDef) {\n\t\t\tscheduler.register(system);\n\t\t},\n\n\t\tremoveSystem(name: string) {\n\t\t\tscheduler.remove(name);\n\t\t},\n\n\t\t// === Camera ===\n\n\t\tgetCamera() {\n\t\t\treturn world.getResource(CameraResource);\n\t\t},\n\n\t\tpanBy(dx: number, dy: number) {\n\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\tcamera.x -= dx / camera.zoom;\n\t\t\tcamera.y -= dy / camera.zoom;\n\t\t\tcameraChangedThisTick = true;\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tpanTo(worldX: number, worldY: number) {\n\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\tconst viewport = world.getResource(ViewportResource);\n\t\t\tcamera.x = worldX - viewport.width / (2 * camera.zoom);\n\t\t\tcamera.y = worldY - viewport.height / (2 * camera.zoom);\n\t\t\tcameraChangedThisTick = true;\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tzoomAtPoint(screenX: number, screenY: number, delta: number) {\n\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\tconst zoomConfig = world.getResource(ZoomConfigResource);\n\n\t\t\tconst worldBefore = screenToWorld(screenX, screenY, camera);\n\t\t\tconst newZoom = clamp(camera.zoom * (1 + delta), zoomConfig.min, zoomConfig.max);\n\t\t\tcamera.zoom = newZoom;\n\t\t\tcamera.x = worldBefore.x - screenX / newZoom;\n\t\t\tcamera.y = worldBefore.y - screenY / newZoom;\n\t\t\tcameraChangedThisTick = true;\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tzoomTo(zoom: number) {\n\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\tconst zoomConfig = world.getResource(ZoomConfigResource);\n\t\t\tconst viewport = world.getResource(ViewportResource);\n\t\t\tconst centerWorldX = camera.x + viewport.width / (2 * camera.zoom);\n\t\t\tconst centerWorldY = camera.y + viewport.height / (2 * camera.zoom);\n\t\t\tcamera.zoom = clamp(zoom, zoomConfig.min, zoomConfig.max);\n\t\t\tcamera.x = centerWorldX - viewport.width / (2 * camera.zoom);\n\t\t\tcamera.y = centerWorldY - viewport.height / (2 * camera.zoom);\n\t\t\tcameraChangedThisTick = true;\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tzoomToFit(entityIds?: EntityId[], padding = 50) {\n\t\t\tconst viewport = world.getResource(ViewportResource);\n\t\t\tif (viewport.width === 0) return;\n\n\t\t\tconst entities = entityIds ?? world.queryTagged(Active);\n\t\t\tif (entities.length === 0) return;\n\n\t\t\tlet minX = Number.POSITIVE_INFINITY,\n\t\t\t\tminY = Number.POSITIVE_INFINITY,\n\t\t\t\tmaxX = Number.NEGATIVE_INFINITY,\n\t\t\t\tmaxY = Number.NEGATIVE_INFINITY;\n\t\t\tfor (const e of entities) {\n\t\t\t\tconst wb = world.getComponent(e, WorldBounds);\n\t\t\t\tif (!wb) continue;\n\t\t\t\tminX = Math.min(minX, wb.worldX);\n\t\t\t\tminY = Math.min(minY, wb.worldY);\n\t\t\t\tmaxX = Math.max(maxX, wb.worldX + wb.worldWidth);\n\t\t\t\tmaxY = Math.max(maxY, wb.worldY + wb.worldHeight);\n\t\t\t}\n\t\t\tif (!isFinite(minX)) return;\n\n\t\t\tconst contentWidth = maxX - minX + padding * 2;\n\t\t\tconst contentHeight = maxY - minY + padding * 2;\n\t\t\tconst zoomConfig = world.getResource(ZoomConfigResource);\n\t\t\tconst zoom = clamp(\n\t\t\t\tMath.min(viewport.width / contentWidth, viewport.height / contentHeight),\n\t\t\t\tzoomConfig.min,\n\t\t\t\tzoomConfig.max,\n\t\t\t);\n\n\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\tcamera.zoom = zoom;\n\t\t\tcamera.x = minX - padding - (viewport.width / zoom - contentWidth) / 2;\n\t\t\tcamera.y = minY - padding - (viewport.height / zoom - contentHeight) / 2;\n\t\t\tcameraChangedThisTick = true;\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\t// === Viewport ===\n\n\t\tsetViewport(width: number, height: number, dpr?: number) {\n\t\t\tworld.setResource(ViewportResource, { width, height, dpr: dpr ?? 1 });\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\t// === Commands + Undo/Redo ===\n\n\t\texecute(command: Command) {\n\t\t\tcommandBuffer.execute(command, world);\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tbeginCommandGroup() {\n\t\t\tcommandBuffer.beginGroup();\n\t\t},\n\n\t\tendCommandGroup() {\n\t\t\tcommandBuffer.endGroup();\n\t\t},\n\n\t\tundo(): boolean {\n\t\t\tconst did = commandBuffer.undo(world);\n\t\t\tif (did) markDirtyInternal();\n\t\t\treturn did;\n\t\t},\n\n\t\tredo(): boolean {\n\t\t\tconst did = commandBuffer.redo(world);\n\t\t\tif (did) markDirtyInternal();\n\t\t\treturn did;\n\t\t},\n\n\t\tcanUndo(): boolean {\n\t\t\treturn commandBuffer.canUndo();\n\t\t},\n\n\t\tcanRedo(): boolean {\n\t\t\treturn commandBuffer.canRedo();\n\t\t},\n\n\t\t// === Pointer Input ===\n\n\t\thandlePointerDown(screenX, screenY, _button, modifiers): PointerDirective {\n\t\t\t// Check resize handles first\n\t\t\tconst handleHit = hitTestResizeHandle(screenX, screenY);\n\t\t\tif (handleHit) {\n\t\t\t\tconst t = world.getComponent(handleHit.entityId, Transform2D)!;\n\t\t\t\tcommandBuffer.beginGroup(); // undo group for entire resize\n\t\t\t\tinputState = {\n\t\t\t\t\tmode: 'resizing',\n\t\t\t\t\tentityId: handleHit.entityId,\n\t\t\t\t\thandle: handleHit.handle,\n\t\t\t\t\tstartX: screenX,\n\t\t\t\t\tstartY: screenY,\n\t\t\t\t\tstartBounds: { x: t.x, y: t.y, width: t.width, height: t.height },\n\t\t\t\t};\n\t\t\t\tmarkDirtyInternal();\n\t\t\t\treturn { action: 'capture-resize', handle: handleHit.handle };\n\t\t\t}\n\n\t\t\t// Hit test entities\n\t\t\tconst hitEntity = hitTest(screenX, screenY);\n\n\t\t\tif (hitEntity !== null) {\n\t\t\t\tselectEntity(hitEntity, modifiers.shift);\n\t\t\t\tif (world.hasTag(hitEntity, Draggable)) {\n\t\t\t\t\tinputState = { mode: 'tracking', entityId: hitEntity, startX: screenX, startY: screenY };\n\t\t\t\t}\n\t\t\t\tmarkDirtyInternal();\n\t\t\t\treturn { action: 'passthrough-track-drag' };\n\t\t\t}\n\n\t\t\t// Empty canvas\n\t\t\tclearSelection();\n\t\t\tinputState = { mode: 'marquee', startX: screenX, startY: screenY };\n\t\t\tmarkDirtyInternal();\n\t\t\treturn { action: 'capture-marquee' };\n\t\t},\n\n\t\thandlePointerMove(screenX, screenY, _modifiers): PointerDirective {\n\t\t\tif (inputState.mode === 'tracking') {\n\t\t\t\tconst dx = screenX - inputState.startX;\n\t\t\t\tconst dy = screenY - inputState.startY;\n\t\t\t\tif (Math.abs(dx) > DEAD_ZONE_PX || Math.abs(dy) > DEAD_ZONE_PX) {\n\t\t\t\t\t// Fix #5: Save original z-indices, temporarily bring to top\n\t\t\t\t\tconst originalZIndices = new Map<EntityId, number>();\n\t\t\t\t\tlet maxZ = 0;\n\t\t\t\t\tfor (const e of world.queryTagged(Active)) {\n\t\t\t\t\t\tconst z = world.getComponent(e, ZIndex);\n\t\t\t\t\t\tif (z && z.value > maxZ) maxZ = z.value;\n\t\t\t\t\t}\n\t\t\t\t\tfor (const e of world.queryTagged(Selected)) {\n\t\t\t\t\t\tconst z = world.getComponent(e, ZIndex);\n\t\t\t\t\t\toriginalZIndices.set(e, z?.value ?? 0);\n\t\t\t\t\t\tworld.setComponent(e, ZIndex, { value: maxZ + 1 });\n\t\t\t\t\t}\n\n\t\t\t\t\t// Capture start positions for all selected entities\n\t\t\t\t\tconst startPositions = new Map<EntityId, { x: number; y: number }>();\n\t\t\t\t\tfor (const e of world.queryTagged(Selected)) {\n\t\t\t\t\t\tconst t = world.getComponent(e, Transform2D);\n\t\t\t\t\t\tif (t) startPositions.set(e, { x: t.x, y: t.y });\n\t\t\t\t\t}\n\n\t\t\t\t\t// Start undo group for the entire drag operation\n\t\t\t\t\tcommandBuffer.beginGroup();\n\n\t\t\t\t\tinputState = {\n\t\t\t\t\t\tmode: 'dragging',\n\t\t\t\t\t\tentityId: inputState.entityId,\n\t\t\t\t\t\tstartScreenX: screenX,\n\t\t\t\t\t\tstartScreenY: screenY,\n\t\t\t\t\t\tstartPositions,\n\t\t\t\t\t\toriginalZIndices,\n\t\t\t\t\t};\n\t\t\t\t\tmarkDirtyInternal();\n\t\t\t\t\treturn { action: 'capture-drag' };\n\t\t\t\t}\n\t\t\t\treturn { action: 'passthrough' };\n\t\t\t}\n\n\t\t\tif (inputState.mode === 'dragging') {\n\t\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\t\tconst totalDx = (screenX - inputState.startScreenX) / camera.zoom;\n\t\t\t\tconst totalDy = (screenY - inputState.startScreenY) / camera.zoom;\n\n\t\t\t\t// Compute snap guides against visible non-dragged entities\n\t\t\t\tif (snapEnabled && inputState.startPositions.size > 0) {\n\t\t\t\t\t// Build dragged bounds (use first entity as reference for snap)\n\t\t\t\t\tconst draggedIds = new Set(inputState.startPositions.keys());\n\t\t\t\t\tconst firstId = inputState.startPositions.keys().next().value!;\n\t\t\t\t\tconst firstStart = inputState.startPositions.get(firstId)!;\n\t\t\t\t\tconst firstT = world.getComponent(firstId, Transform2D);\n\t\t\t\t\tif (firstT) {\n\t\t\t\t\t\tconst draggedBounds = {\n\t\t\t\t\t\t\tx: firstStart.x + totalDx,\n\t\t\t\t\t\t\ty: firstStart.y + totalDy,\n\t\t\t\t\t\t\twidth: firstT.width,\n\t\t\t\t\t\t\theight: firstT.height,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect reference bounds from visible entities\n\t\t\t\t\t\tconst refs = [];\n\t\t\t\t\t\tfor (const entity of world.queryTagged(Active)) {\n\t\t\t\t\t\t\tif (draggedIds.has(entity)) continue;\n\t\t\t\t\t\t\tconst wb = world.getComponent(entity, WorldBounds);\n\t\t\t\t\t\t\tif (wb) {\n\t\t\t\t\t\t\t\trefs.push({\n\t\t\t\t\t\t\t\t\tx: wb.worldX,\n\t\t\t\t\t\t\t\t\ty: wb.worldY,\n\t\t\t\t\t\t\t\t\twidth: wb.worldWidth,\n\t\t\t\t\t\t\t\t\theight: wb.worldHeight,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentSnap = computeSnapGuides(draggedBounds, refs, snapThreshold / camera.zoom);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrentSnap = { snapDx: 0, snapDy: 0, guides: [], spacings: [] };\n\t\t\t\t}\n\n\t\t\t\t// Apply snap-corrected positions\n\t\t\t\tconst finalDx = totalDx + currentSnap.snapDx;\n\t\t\t\tconst finalDy = totalDy + currentSnap.snapDy;\n\t\t\t\tfor (const [e, start] of inputState.startPositions) {\n\t\t\t\t\tworld.setComponent(e, Transform2D, {\n\t\t\t\t\t\tx: start.x + finalDx,\n\t\t\t\t\t\ty: start.y + finalDy,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tmarkDirtyInternal();\n\t\t\t\treturn { action: 'capture-drag' };\n\t\t\t}\n\n\t\t\tif (inputState.mode === 'resizing') {\n\t\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\t\tconst dx = (screenX - inputState.startX) / camera.zoom;\n\t\t\t\tconst dy = (screenY - inputState.startY) / camera.zoom;\n\t\t\t\tconst { x, y, width: w, height: h } = inputState.startBounds;\n\t\t\t\tconst handle = inputState.handle;\n\t\t\t\tconst MIN_SIZE = 20;\n\n\t\t\t\tlet newX = x,\n\t\t\t\t\tnewY = y,\n\t\t\t\t\tnewW = w,\n\t\t\t\t\tnewH = h;\n\n\t\t\t\tif (handle.includes('e')) {\n\t\t\t\t\tnewW = Math.max(MIN_SIZE, w + dx);\n\t\t\t\t}\n\t\t\t\tif (handle.includes('w')) {\n\t\t\t\t\tnewX = x + dx;\n\t\t\t\t\tnewW = Math.max(MIN_SIZE, w - dx);\n\t\t\t\t}\n\t\t\t\tif (handle.includes('s')) {\n\t\t\t\t\tnewH = Math.max(MIN_SIZE, h + dy);\n\t\t\t\t}\n\t\t\t\tif (handle.includes('n')) {\n\t\t\t\t\tnewY = y + dy;\n\t\t\t\t\tnewH = Math.max(MIN_SIZE, h - dy);\n\t\t\t\t}\n\n\t\t\t\tworld.setComponent(inputState.entityId, Transform2D, {\n\t\t\t\t\tx: newX,\n\t\t\t\t\ty: newY,\n\t\t\t\t\twidth: newW,\n\t\t\t\t\theight: newH,\n\t\t\t\t});\n\t\t\t\tmarkDirtyInternal();\n\t\t\t\treturn { action: 'capture-resize', handle: inputState.handle };\n\t\t\t}\n\n\t\t\tif (inputState.mode === 'marquee') {\n\t\t\t\t// TODO: marquee selection in Phase 7\n\t\t\t\treturn { action: 'capture-marquee' };\n\t\t\t}\n\n\t\t\t// Hover tracking in idle mode\n\t\t\tif (inputState.mode === 'idle') {\n\t\t\t\tconst hit = hitTest(screenX, screenY);\n\t\t\t\tif (hit !== hoveredEntity) {\n\t\t\t\t\thoveredEntity = hit;\n\t\t\t\t\tmarkDirtyInternal();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { action: 'passthrough' };\n\t\t},\n\n\t\thandlePointerUp(): PointerDirective {\n\t\t\tconst prevState = inputState;\n\n\t\t\tif (prevState.mode === 'dragging') {\n\t\t\t\t// Fix #5: Restore original z-indices on drag end\n\t\t\t\tfor (const [entity, originalZ] of prevState.originalZIndices) {\n\t\t\t\t\tworld.setComponent(entity, ZIndex, { value: originalZ });\n\t\t\t\t}\n\t\t\t\t// Compute total delta from any moved entity\n\t\t\t\tconst entityIds = [...prevState.startPositions.keys()];\n\t\t\t\tif (entityIds.length > 0) {\n\t\t\t\t\tconst firstId = entityIds[0];\n\t\t\t\t\tconst start = prevState.startPositions.get(firstId)!;\n\t\t\t\t\tconst current = world.getComponent(firstId, Transform2D);\n\t\t\t\t\tif (current) {\n\t\t\t\t\t\tconst totalDx = current.x - start.x;\n\t\t\t\t\t\tconst totalDy = current.y - start.y;\n\t\t\t\t\t\tif (totalDx !== 0 || totalDy !== 0) {\n\t\t\t\t\t\t\t// Revert all to start positions, then commit as single command\n\t\t\t\t\t\t\tfor (const [e, s] of prevState.startPositions) {\n\t\t\t\t\t\t\t\tworld.setComponent(e, Transform2D, { x: s.x, y: s.y });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcommandBuffer.execute(\n\t\t\t\t\t\t\t\tnew MoveCommand(entityIds, totalDx, totalDy, Transform2D),\n\t\t\t\t\t\t\t\tworld,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommandBuffer.endGroup();\n\t\t\t\tcurrentSnap = { snapDx: 0, snapDy: 0, guides: [], spacings: [] };\n\t\t\t}\n\n\t\t\tif (prevState.mode === 'resizing') {\n\t\t\t\t// Capture final bounds before reverting\n\t\t\t\tconst t = world.getComponent(prevState.entityId, Transform2D);\n\t\t\t\tif (t) {\n\t\t\t\t\tconst finalBounds = { x: t.x, y: t.y, width: t.width, height: t.height };\n\t\t\t\t\tconst sb = prevState.startBounds;\n\t\t\t\t\t// Revert to start bounds so the command's execute() applies cleanly\n\t\t\t\t\tworld.setComponent(prevState.entityId, Transform2D, sb);\n\t\t\t\t\tcommandBuffer.execute(\n\t\t\t\t\t\tnew ResizeCommand(prevState.entityId, sb, finalBounds, Transform2D),\n\t\t\t\t\t\tworld,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcommandBuffer.endGroup();\n\t\t\t}\n\n\t\t\t// Fix #12: TODO — emit a 'widget-clicked' event when prevState.mode === 'tracking'\n\n\t\t\tinputState = { mode: 'idle' };\n\n\t\t\tif (prevState.mode === 'dragging' || prevState.mode === 'resizing') {\n\t\t\t\tmarkDirtyInternal();\n\t\t\t}\n\n\t\t\treturn { action: 'passthrough' };\n\t\t},\n\n\t\t// === Selection ===\n\n\t\tgetSelectedEntities(): EntityId[] {\n\t\t\treturn world.queryTagged(Selected);\n\t\t},\n\n\t\tgetHoveredEntity(): EntityId | null {\n\t\t\treturn hoveredEntity;\n\t\t},\n\n\t\t// === Snap Guides ===\n\n\t\tgetSnapGuides(): SnapGuide[] {\n\t\t\treturn currentSnap.guides;\n\t\t},\n\n\t\tgetEqualSpacing(): EqualSpacingIndicator[] {\n\t\t\treturn currentSnap.spacings;\n\t\t},\n\n\t\tsetSnapEnabled(on: boolean) {\n\t\t\tsnapEnabled = on;\n\t\t},\n\n\t\tsetSnapThreshold(worldPx: number) {\n\t\t\tsnapThreshold = worldPx;\n\t\t},\n\n\t\t// === Navigation ===\n\n\t\tenterContainer(entity: EntityId) {\n\t\t\tif (!world.hasComponent(entity, Container)) return;\n\t\t\tif (!world.hasComponent(entity, Children)) return;\n\n\t\t\tconst navStack = world.getResource(NavigationStackResource);\n\t\t\tconst camera = world.getResource(CameraResource);\n\n\t\t\tconst currentFrame = navStack.frames[navStack.frames.length - 1];\n\t\t\tcurrentFrame.camera = { x: camera.x, y: camera.y, zoom: camera.zoom };\n\n\t\t\tnavStack.frames.push({\n\t\t\t\tcontainerId: entity,\n\t\t\t\tcamera: { x: camera.x, y: camera.y, zoom: camera.zoom },\n\t\t\t});\n\t\t\tnavStack.changed = true;\n\n\t\t\tclearSelection();\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\texitContainer() {\n\t\t\tconst navStack = world.getResource(NavigationStackResource);\n\t\t\tif (navStack.frames.length <= 1) return;\n\n\t\t\tnavStack.frames.pop();\n\t\t\tnavStack.changed = true;\n\n\t\t\tconst parentFrame = navStack.frames[navStack.frames.length - 1];\n\t\t\tconst camera = world.getResource(CameraResource);\n\t\t\tcamera.x = parentFrame.camera.x;\n\t\t\tcamera.y = parentFrame.camera.y;\n\t\t\tcamera.zoom = parentFrame.camera.zoom;\n\n\t\t\tclearSelection();\n\t\t\tcameraChangedThisTick = true;\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tgetActiveContainer(): EntityId | null {\n\t\t\tconst navStack = world.getResource(NavigationStackResource);\n\t\t\treturn navStack.frames[navStack.frames.length - 1].containerId;\n\t\t},\n\n\t\tgetNavigationDepth(): number {\n\t\t\treturn world.getResource(NavigationStackResource).frames.length - 1;\n\t\t},\n\n\t\t// === Frame ===\n\n\t\tmarkDirty() {\n\t\t\tmarkDirtyInternal();\n\t\t},\n\n\t\tprofiler,\n\n\t\ttick() {\n\t\t\tprofiler.beginFrame(world.currentTick);\n\n\t\t\t// Run all systems\n\t\t\tscheduler.execute(world);\n\n\t\t\t// Compute visible entities for renderers\n\t\t\tprofiler.beginVisibility();\n\t\t\tconst newVisible: VisibleEntity[] = [];\n\t\t\tconst newVisibleSet = new Set<EntityId>();\n\n\t\t\tfor (const entity of world.query(Widget, Visible)) {\n\t\t\t\tconst wb = world.getComponent(entity, WorldBounds);\n\t\t\t\tconst widget = world.getComponent(entity, Widget);\n\t\t\t\tconst bp = world.getComponent(entity, WidgetBreakpoint);\n\t\t\t\tconst zIdx = world.getComponent(entity, ZIndex);\n\t\t\t\tif (!wb || !widget) continue;\n\n\t\t\t\tnewVisibleSet.add(entity);\n\t\t\t\tnewVisible.push({\n\t\t\t\t\tentityId: entity,\n\t\t\t\t\tworldX: wb.worldX,\n\t\t\t\t\tworldY: wb.worldY,\n\t\t\t\t\tworldWidth: wb.worldWidth,\n\t\t\t\t\tworldHeight: wb.worldHeight,\n\t\t\t\t\tbreakpoint: bp?.current ?? 'normal',\n\t\t\t\t\tzIndex: zIdx?.value ?? 0,\n\t\t\t\t\tsurface: widget.surface,\n\t\t\t\t\twidgetType: widget.type,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Sort by z-index\n\t\t\tnewVisible.sort((a, b) => a.zIndex - b.zIndex);\n\t\t\tprofiler.endVisibility();\n\n\t\t\t// Compute frame changes\n\t\t\tconst entered: EntityId[] = [];\n\t\t\tconst exited: EntityId[] = [];\n\t\t\tfor (const entity of newVisibleSet) {\n\t\t\t\tif (!prevVisible.has(entity)) entered.push(entity);\n\t\t\t}\n\t\t\tfor (const entity of prevVisible) {\n\t\t\t\tif (!newVisibleSet.has(entity)) exited.push(entity);\n\t\t\t}\n\n\t\t\t// Fix #2: Use selectionChangedThisTick instead of wrong breakpoint check\n\t\t\tframeChanges = {\n\t\t\t\tpositionsChanged: world.queryChanged(WorldBounds),\n\t\t\t\tbreakpointsChanged: world.queryChanged(WidgetBreakpoint),\n\t\t\t\tentered,\n\t\t\t\texited,\n\t\t\t\tcameraChanged: cameraChangedThisTick,\n\t\t\t\tnavigationChanged: false,\n\t\t\t\tselectionChanged: selectionChangedThisTick,\n\t\t\t};\n\n\t\t\tcurrentVisible = newVisible;\n\t\t\tprevVisible = newVisibleSet;\n\t\t\tcameraChangedThisTick = false;\n\t\t\tselectionChangedThisTick = false;\n\n\t\t\tprofiler.endFrame(world.entityCount, newVisible.length);\n\n\t\t\t// Clear dirty sets and increment tick\n\t\t\tworld.clearDirty();\n\t\t\tworld.incrementTick();\n\t\t\tworld.emitFrame();\n\n\t\t\tdirty = false;\n\t\t},\n\n\t\tflushIfDirty(): boolean {\n\t\t\tif (!dirty) return false;\n\t\t\tengine.tick();\n\t\t\treturn true;\n\t\t},\n\n\t\t// === Output ===\n\n\t\tgetVisibleEntities(): VisibleEntity[] {\n\t\t\treturn currentVisible;\n\t\t},\n\n\t\tgetFrameChanges(): FrameChanges {\n\t\t\treturn frameChanges;\n\t\t},\n\n\t\t// Fix #11: Expose spatial index properly\n\t\tgetSpatialIndex(): SpatialIndex {\n\t\t\treturn spatialIndex;\n\t\t},\n\n\t\t// === Events ===\n\n\t\tonFrame(handler: () => void): Unsubscribe {\n\t\t\treturn world.onFrame(handler);\n\t\t},\n\n\t\t// === Lifecycle ===\n\n\t\tdestroy() {\n\t\t\tspatialIndex.clear();\n\t\t},\n\t};\n\n\treturn engine;\n}\n\n/** @deprecated Use LayoutEngine instead */\nexport type CanvasEngine = LayoutEngine;\n/** @deprecated Use LayoutEngineConfig instead */\nexport type CanvasEngineConfig = LayoutEngineConfig;\n/** @deprecated Use createLayoutEngine instead */\nexport const createCanvasEngine = createLayoutEngine;\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { Vector2 } from 'three';\nimport { Widget, WorldBounds } from '../components.js';\nimport type { EntityId } from '../ecs/types.js';\nimport type { LayoutEngine } from '../engine.js';\nimport { SelectionOverlaySlot } from './SelectionOverlaySlot.js';\nimport { WidgetProvider } from './WidgetProvider.js';\nimport { WidgetSlot } from './WidgetSlot.js';\nimport { ContainerRefProvider, EngineProvider, useWidgetResolver } from './context.js';\nimport { createWidgetRegistry } from './registry.js';\nimport type { WidgetDef } from './registry.js';\nimport { GridRenderer } from './webgl/GridRenderer.js';\nimport type { GridConfig } from './webgl/GridRenderer.js';\nimport { SelectionRenderer } from './webgl/SelectionRenderer.js';\nimport type { SelectionBounds, SelectionConfig } from './webgl/SelectionRenderer.js';\nimport { WebGLWidgetLayer } from './webgl/WebGLWidgetLayer.js';\n\ninterface InfiniteCanvasProps {\n\tengine: LayoutEngine;\n\t/** Widget definitions. When provided, WidgetProvider is created internally. */\n\twidgets?: WidgetDef[];\n\t/** Grid configuration. Pass `false` to disable the grid entirely. */\n\tgrid?: Partial<GridConfig> | false;\n\t/** Selection style configuration. */\n\tselection?: Partial<SelectionConfig>;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n\tchildren?: React.ReactNode;\n}\n\nexport function InfiniteCanvas({\n\tengine,\n\twidgets,\n\tgrid,\n\tselection,\n\tclassName,\n\tstyle,\n\tchildren,\n}: InfiniteCanvasProps) {\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\n\t// When widgets prop is provided, create an internal registry\n\tconst internalRegistry = useMemo(\n\t\t() => (widgets ? createWidgetRegistry(widgets) : null),\n\t\t[widgets],\n\t);\n\tconst webglCanvasRef = useRef<HTMLCanvasElement>(null);\n\tconst gridRendererRef = useRef<GridRenderer | null>(null);\n\tconst selectionRendererRef = useRef<SelectionRenderer | null>(null);\n\tconst cameraLayerRef = useRef<HTMLDivElement>(null);\n\tconst slotRefs = useRef(new Map<EntityId, HTMLDivElement>());\n\tconst [visibleEntities, setVisibleEntities] = useState<EntityId[]>([]);\n\n\t// Register slot ref for batch updater\n\tconst registerSlotRef = useCallback((entityId: EntityId, el: HTMLDivElement | null) => {\n\t\tif (el) {\n\t\t\tslotRefs.current.set(entityId, el);\n\t\t} else {\n\t\t\tslotRefs.current.delete(entityId);\n\t\t}\n\t}, []);\n\n\t// Initialize GridRenderer + set viewport size on mount/resize\n\tuseLayoutEffect(() => {\n\t\tconst container = containerRef.current;\n\t\tconst canvas = webglCanvasRef.current;\n\t\tif (!container || !canvas) return;\n\n\t\tconst gridEnabled = grid !== false;\n\t\tlet gridInst: GridRenderer | null = null;\n\t\tif (gridEnabled) {\n\t\t\tgridInst = new GridRenderer(canvas);\n\t\t\tgridRendererRef.current = gridInst;\n\t\t}\n\n\t\t// SelectionRenderer shares the WebGLRenderer from GridRenderer\n\t\tconst selInst = new SelectionRenderer();\n\t\tselectionRendererRef.current = selInst;\n\n\t\tconst updateSize = () => {\n\t\t\tconst rect = container.getBoundingClientRect();\n\t\t\tconst dpr = window.devicePixelRatio;\n\t\t\tengine.setViewport(rect.width, rect.height, dpr);\n\t\t\tcanvas.style.width = `${rect.width}px`;\n\t\t\tcanvas.style.height = `${rect.height}px`;\n\t\t\tif (gridInst) {\n\t\t\t\tgridInst.setSize(rect.width, rect.height, dpr);\n\t\t\t}\n\t\t\tselInst.setSize(new Vector2(rect.width * dpr, rect.height * dpr), dpr);\n\t\t};\n\n\t\tupdateSize();\n\t\tconst observer = new ResizeObserver(updateSize);\n\t\tobserver.observe(container);\n\t\treturn () => {\n\t\t\tobserver.disconnect();\n\t\t\tif (gridInst) {\n\t\t\t\tgridInst.dispose();\n\t\t\t\tgridRendererRef.current = null;\n\t\t\t}\n\t\t\tselInst.dispose();\n\t\t\tselectionRendererRef.current = null;\n\t\t};\n\t}, [engine, grid]);\n\n\t// Apply grid + selection config on every render\n\tuseEffect(() => {\n\t\tconst gridR = gridRendererRef.current;\n\t\tif (gridR && grid !== false) {\n\t\t\tconst isDark = document.documentElement.classList.contains('dark');\n\t\t\tgridR.setConfig({\n\t\t\t\tdotColor: isDark ? [1, 1, 1] : [0, 0, 0],\n\t\t\t\tdotAlpha: isDark ? 0.12 : 0.18,\n\t\t\t\t...grid,\n\t\t\t});\n\t\t}\n\t\tconst selR = selectionRendererRef.current;\n\t\tif (selR && selection) {\n\t\t\tselR.setConfig(selection);\n\t\t}\n\t\tengine.markDirty();\n\t});\n\n\t// Wheel handler — pan/zoom (gesture channel, always active)\n\tuseEffect(() => {\n\t\tconst container = containerRef.current;\n\t\tif (!container) return;\n\n\t\tconst onWheel = (e: WheelEvent) => {\n\t\t\te.preventDefault();\n\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t// Pinch zoom or ctrl+scroll\n\t\t\t\tconst rect = container.getBoundingClientRect();\n\t\t\t\tengine.zoomAtPoint(e.clientX - rect.left, e.clientY - rect.top, -e.deltaY * 0.01);\n\t\t\t} else {\n\t\t\t\t// Two-finger scroll pan\n\t\t\t\tengine.panBy(-e.deltaX, -e.deltaY);\n\t\t\t}\n\t\t};\n\n\t\tcontainer.addEventListener('wheel', onWheel, { passive: false });\n\t\treturn () => container.removeEventListener('wheel', onWheel);\n\t}, [engine]);\n\n\t// Touch gesture handler — iOS Freeform-style interactions\n\t// 1 finger on background → pan; 1 finger on entity → select/drag;\n\t// 2 fingers → pinch-to-zoom + pan; double-tap → zoom step / enter container\n\tuseEffect(() => {\n\t\tconst container = containerRef.current;\n\t\tif (!container) return;\n\n\t\ttype TouchGesture =\n\t\t\t| { type: 'idle' }\n\t\t\t| { type: 'pending-pan'; x: number; y: number; time: number }\n\t\t\t| { type: 'panning'; lastX: number; lastY: number }\n\t\t\t| { type: 'pending-entity'; x: number; y: number; time: number }\n\t\t\t| { type: 'entity-dragging' }\n\t\t\t| { type: 'pinching'; lastDist: number; lastCx: number; lastCy: number };\n\n\t\tlet gesture: TouchGesture = { type: 'idle' };\n\t\tlet lastTapTime = 0;\n\t\tlet lastTapX = 0;\n\t\tlet lastTapY = 0;\n\t\tconst DEAD_ZONE = 8;\n\t\tconst DOUBLE_TAP_MS = 300;\n\t\tconst DOUBLE_TAP_DIST = 30;\n\n\t\tfunction isOnWidget(target: EventTarget | null): boolean {\n\t\t\tlet el = target as HTMLElement | null;\n\t\t\twhile (el && el !== container) {\n\t\t\t\tif (el.hasAttribute('data-widget-slot')) return true;\n\t\t\t\tel = el.parentElement;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tfunction isInteractive(target: EventTarget | null): boolean {\n\t\t\tconst el = target as HTMLElement | null;\n\t\t\tif (!el) return false;\n\t\t\tconst tag = el.tagName;\n\t\t\treturn (\n\t\t\t\ttag === 'INPUT' ||\n\t\t\t\ttag === 'TEXTAREA' ||\n\t\t\t\ttag === 'BUTTON' ||\n\t\t\t\ttag === 'SELECT' ||\n\t\t\t\tel.isContentEditable ||\n\t\t\t\tel.closest('button') !== null\n\t\t\t);\n\t\t}\n\n\t\tfunction getRect() {\n\t\t\treturn container!.getBoundingClientRect();\n\t\t}\n\n\t\tfunction touchDist(t1: Touch, t2: Touch) {\n\t\t\tconst dx = t1.clientX - t2.clientX;\n\t\t\tconst dy = t1.clientY - t2.clientY;\n\t\t\treturn Math.sqrt(dx * dx + dy * dy);\n\t\t}\n\n\t\tfunction touchCenter(t1: Touch, t2: Touch, rect: DOMRect) {\n\t\t\treturn {\n\t\t\t\tx: (t1.clientX + t2.clientX) / 2 - rect.left,\n\t\t\t\ty: (t1.clientY + t2.clientY) / 2 - rect.top,\n\t\t\t};\n\t\t}\n\n\t\tfunction cancelEngineGesture() {\n\t\t\tif (gesture.type === 'pending-entity' || gesture.type === 'entity-dragging') {\n\t\t\t\tengine.handlePointerUp();\n\t\t\t}\n\t\t}\n\n\t\tconst noMods = { shift: false, ctrl: false, alt: false, meta: false };\n\n\t\tfunction onTouchStart(e: TouchEvent) {\n\t\t\tconst rect = getRect();\n\t\t\tconst touches = e.touches;\n\n\t\t\t// --- 2+ fingers → pinch (override everything) ---\n\t\t\tif (touches.length >= 2) {\n\t\t\t\te.preventDefault();\n\t\t\t\tcancelEngineGesture();\n\t\t\t\tconst dist = touchDist(touches[0], touches[1]);\n\t\t\t\tconst center = touchCenter(touches[0], touches[1], rect);\n\t\t\t\tgesture = { type: 'pinching', lastDist: dist, lastCx: center.x, lastCy: center.y };\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// --- 1 finger ---\n\t\t\tconst touch = touches[0];\n\t\t\tconst x = touch.clientX - rect.left;\n\t\t\tconst y = touch.clientY - rect.top;\n\n\t\t\t// Let interactive elements (buttons, inputs) handle their own touch\n\t\t\tif (isInteractive(e.target)) return;\n\n\t\t\te.preventDefault();\n\n\t\t\t// Double-tap detection\n\t\t\tconst now = Date.now();\n\t\t\tif (\n\t\t\t\tnow - lastTapTime < DOUBLE_TAP_MS &&\n\t\t\t\tMath.abs(x - lastTapX) < DOUBLE_TAP_DIST &&\n\t\t\t\tMath.abs(y - lastTapY) < DOUBLE_TAP_DIST\n\t\t\t) {\n\t\t\t\tlastTapTime = 0;\n\t\t\t\t// Hit test to check for entity\n\t\t\t\tconst directive = engine.handlePointerDown(x, y, 0, noMods);\n\t\t\t\tif (directive.action === 'passthrough-track-drag') {\n\t\t\t\t\t// Double-tap on entity → enter container\n\t\t\t\t\tconst selected = engine.getSelectedEntities();\n\t\t\t\t\tengine.handlePointerUp();\n\t\t\t\t\tif (selected.length === 1) {\n\t\t\t\t\t\tengine.enterContainer(selected[0]);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Double-tap on empty → zoom step\n\t\t\t\t\tengine.handlePointerUp();\n\t\t\t\t\tconst camera = engine.getCamera();\n\t\t\t\t\tconst target = camera.zoom < 0.9 ? 1 : camera.zoom < 1.8 ? 2 : 1;\n\t\t\t\t\tengine.zoomAtPoint(x, y, (target - camera.zoom) / camera.zoom);\n\t\t\t\t}\n\t\t\t\tengine.markDirty();\n\t\t\t\tgesture = { type: 'idle' };\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (isOnWidget(e.target)) {\n\t\t\t\t// Touch on entity → delegate to engine\n\t\t\t\tengine.handlePointerDown(x, y, 0, noMods);\n\t\t\t\tgesture = { type: 'pending-entity', x, y, time: now };\n\t\t\t} else {\n\t\t\t\t// Touch on empty space → prepare to pan (don't tell engine yet)\n\t\t\t\tgesture = { type: 'pending-pan', x, y, time: now };\n\t\t\t}\n\t\t}\n\n\t\tfunction onTouchMove(e: TouchEvent) {\n\t\t\te.preventDefault();\n\t\t\tconst rect = getRect();\n\t\t\tconst touches = e.touches;\n\n\t\t\t// --- Pinch ---\n\t\t\tif (gesture.type === 'pinching' && touches.length >= 2) {\n\t\t\t\tconst dist = touchDist(touches[0], touches[1]);\n\t\t\t\tconst center = touchCenter(touches[0], touches[1], rect);\n\t\t\t\tconst scale = dist / gesture.lastDist;\n\t\t\t\tengine.zoomAtPoint(center.x, center.y, scale - 1);\n\t\t\t\tengine.panBy(center.x - gesture.lastCx, center.y - gesture.lastCy);\n\t\t\t\tgesture.lastDist = dist;\n\t\t\t\tgesture.lastCx = center.x;\n\t\t\t\tgesture.lastCy = center.y;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Transition to pinch if second finger added\n\t\t\tif (touches.length >= 2) {\n\t\t\t\tcancelEngineGesture();\n\t\t\t\tconst dist = touchDist(touches[0], touches[1]);\n\t\t\t\tconst center = touchCenter(touches[0], touches[1], rect);\n\t\t\t\tgesture = { type: 'pinching', lastDist: dist, lastCx: center.x, lastCy: center.y };\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (touches.length < 1) return;\n\t\t\tconst touch = touches[0];\n\t\t\tconst x = touch.clientX - rect.left;\n\t\t\tconst y = touch.clientY - rect.top;\n\n\t\t\t// Pending pan → check dead zone\n\t\t\tif (gesture.type === 'pending-pan') {\n\t\t\t\tif (Math.abs(x - gesture.x) > DEAD_ZONE || Math.abs(y - gesture.y) > DEAD_ZONE) {\n\t\t\t\t\tgesture = { type: 'panning', lastX: x, lastY: y };\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Active panning\n\t\t\tif (gesture.type === 'panning') {\n\t\t\t\tengine.panBy(x - gesture.lastX, y - gesture.lastY);\n\t\t\t\tgesture.lastX = x;\n\t\t\t\tgesture.lastY = y;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Entity drag → delegate to engine\n\t\t\tif (gesture.type === 'pending-entity' || gesture.type === 'entity-dragging') {\n\t\t\t\tengine.handlePointerMove(x, y, noMods);\n\t\t\t\tif (gesture.type === 'pending-entity') {\n\t\t\t\t\tif (Math.abs(x - gesture.x) > DEAD_ZONE || Math.abs(y - gesture.y) > DEAD_ZONE) {\n\t\t\t\t\t\tgesture = { type: 'entity-dragging' };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction onTouchEnd(e: TouchEvent) {\n\t\t\te.preventDefault();\n\t\t\tconst remaining = e.touches.length;\n\t\t\tconst rect = getRect();\n\n\t\t\t// Pinch → transition based on remaining fingers\n\t\t\tif (gesture.type === 'pinching') {\n\t\t\t\tif (remaining === 1) {\n\t\t\t\t\tconst t = e.touches[0];\n\t\t\t\t\tgesture = { type: 'panning', lastX: t.clientX - rect.left, lastY: t.clientY - rect.top };\n\t\t\t\t} else if (remaining === 0) {\n\t\t\t\t\tgesture = { type: 'idle' };\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (remaining > 0) return;\n\n\t\t\t// Tap on empty space → deselect\n\t\t\tif (gesture.type === 'pending-pan') {\n\t\t\t\tengine.handlePointerDown(gesture.x, gesture.y, 0, noMods);\n\t\t\t\tengine.handlePointerUp();\n\t\t\t\tengine.markDirty();\n\t\t\t\tlastTapTime = Date.now();\n\t\t\t\tlastTapX = gesture.x;\n\t\t\t\tlastTapY = gesture.y;\n\t\t\t}\n\n\t\t\t// Tap on entity (no drag) → selection already happened\n\t\t\tif (gesture.type === 'pending-entity') {\n\t\t\t\tengine.handlePointerUp();\n\t\t\t\tengine.markDirty();\n\t\t\t\tlastTapTime = Date.now();\n\t\t\t\tlastTapX = gesture.x;\n\t\t\t\tlastTapY = gesture.y;\n\t\t\t}\n\n\t\t\t// Entity drag end\n\t\t\tif (gesture.type === 'entity-dragging') {\n\t\t\t\tengine.handlePointerUp();\n\t\t\t\tengine.markDirty();\n\t\t\t}\n\n\t\t\tgesture = { type: 'idle' };\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', onTouchStart, { passive: false });\n\t\tcontainer.addEventListener('touchmove', onTouchMove, { passive: false });\n\t\tcontainer.addEventListener('touchend', onTouchEnd, { passive: false });\n\t\tcontainer.addEventListener('touchcancel', onTouchEnd, { passive: false });\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', onTouchStart);\n\t\t\tcontainer.removeEventListener('touchmove', onTouchMove);\n\t\t\tcontainer.removeEventListener('touchend', onTouchEnd);\n\t\t\tcontainer.removeEventListener('touchcancel', onTouchEnd);\n\t\t};\n\t}, [engine]);\n\n\t// Canvas background pointer — empty-space clicks\n\tconst onBackgroundPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\tif (e.target !== e.currentTarget) return; // ignore bubbled events from widgets\n\t\t\tconst rect = containerRef.current?.getBoundingClientRect();\n\t\t\tif (!rect) return;\n\t\t\tengine.handlePointerDown(e.clientX - rect.left, e.clientY - rect.top, e.button, {\n\t\t\t\tshift: e.shiftKey,\n\t\t\t\tctrl: e.ctrlKey,\n\t\t\t\talt: e.altKey,\n\t\t\t\tmeta: e.metaKey,\n\t\t\t});\n\t\t},\n\t\t[engine],\n\t);\n\n\tconst onBackgroundPointerMove = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\tconst rect = containerRef.current?.getBoundingClientRect();\n\t\t\tif (!rect) return;\n\t\t\tengine.handlePointerMove(e.clientX - rect.left, e.clientY - rect.top, {\n\t\t\t\tshift: e.shiftKey,\n\t\t\t\tctrl: e.ctrlKey,\n\t\t\t\talt: e.altKey,\n\t\t\t\tmeta: e.metaKey,\n\t\t\t});\n\t\t},\n\t\t[engine],\n\t);\n\n\tconst onBackgroundPointerUp = useCallback(\n\t\t(_e: React.PointerEvent) => {\n\t\t\tengine.handlePointerUp();\n\t\t},\n\t\t[engine],\n\t);\n\n\t// rAF tick loop — flushes the engine when dirty, then applies updates.\n\t// This is THE render loop. Input handlers set engine dirty; this loop ticks.\n\tuseEffect(() => {\n\t\tlet rafId: number;\n\t\tlet running = true;\n\n\t\tfunction loop() {\n\t\t\tif (!running) return;\n\n\t\t\tconst didTick = engine.flushIfDirty();\n\t\t\tif (didTick) {\n\t\t\t\tconst camera = engine.getCamera();\n\t\t\t\tconst changes = engine.getFrameChanges();\n\n\t\t\t\t// 1. Update camera layer CSS transform (O(1) for pan/zoom)\n\t\t\t\tif (cameraLayerRef.current) {\n\t\t\t\t\tcameraLayerRef.current.style.transform = `scale(${camera.zoom}) translate(${-camera.x}px, ${-camera.y}px)`;\n\t\t\t\t}\n\n\t\t\t\t// 1b. Render WebGL dot grid + selection\n\t\t\t\tif (gridRendererRef.current) {\n\t\t\t\t\tgridRendererRef.current.render(camera.x, camera.y, camera.zoom);\n\t\t\t\t}\n\t\t\t\tif (selectionRendererRef.current && gridRendererRef.current) {\n\t\t\t\t\tconst selected = engine.getSelectedEntities();\n\t\t\t\t\tconst selBounds: SelectionBounds[] = [];\n\t\t\t\t\tfor (const id of selected) {\n\t\t\t\t\t\tconst wb = engine.get(id, WorldBounds);\n\t\t\t\t\t\tif (wb)\n\t\t\t\t\t\t\tselBounds.push({\n\t\t\t\t\t\t\t\tx: wb.worldX,\n\t\t\t\t\t\t\t\ty: wb.worldY,\n\t\t\t\t\t\t\t\twidth: wb.worldWidth,\n\t\t\t\t\t\t\t\theight: wb.worldHeight,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst hovId = engine.getHoveredEntity();\n\t\t\t\t\tlet hovBounds: SelectionBounds | null = null;\n\t\t\t\t\tif (hovId !== null) {\n\t\t\t\t\t\tconst wb = engine.get(hovId, WorldBounds);\n\t\t\t\t\t\tif (wb)\n\t\t\t\t\t\t\thovBounds = {\n\t\t\t\t\t\t\t\tx: wb.worldX,\n\t\t\t\t\t\t\t\ty: wb.worldY,\n\t\t\t\t\t\t\t\twidth: wb.worldWidth,\n\t\t\t\t\t\t\t\theight: wb.worldHeight,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tselectionRendererRef.current.render(\n\t\t\t\t\t\tgridRendererRef.current.getWebGLRenderer(),\n\t\t\t\t\t\tcamera.x,\n\t\t\t\t\t\tcamera.y,\n\t\t\t\t\t\tcamera.zoom,\n\t\t\t\t\t\tselBounds,\n\t\t\t\t\t\thovBounds,\n\t\t\t\t\t\tengine.getSnapGuides(),\n\t\t\t\t\t\tengine.getEqualSpacing(),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// 2. Fix #1: Use WorldBounds (world-space) not Transform2D (local/parent-relative)\n\t\t\t\tfor (const entityId of changes.positionsChanged) {\n\t\t\t\t\tconst el = slotRefs.current.get(entityId);\n\t\t\t\t\tif (!el) continue;\n\t\t\t\t\tconst wb = engine.get(entityId, WorldBounds);\n\t\t\t\t\tif (!wb) continue;\n\t\t\t\t\tel.style.transform = `translate(${wb.worldX}px, ${wb.worldY}px)`;\n\t\t\t\t\tel.style.width = `${wb.worldWidth}px`;\n\t\t\t\t\tel.style.height = `${wb.worldHeight}px`;\n\t\t\t\t}\n\n\t\t\t\t// 3. Update visible entity list if entities entered/exited\n\t\t\t\tif (changes.entered.length > 0 || changes.exited.length > 0) {\n\t\t\t\t\tconst visible = engine.getVisibleEntities();\n\t\t\t\t\tsetVisibleEntities(visible.map((v) => v.entityId));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trafId = requestAnimationFrame(loop);\n\t\t}\n\n\t\t// Initial tick on mount\n\t\tengine.tick();\n\t\tconst visible = engine.getVisibleEntities();\n\t\tsetVisibleEntities(visible.map((v) => v.entityId));\n\n\t\t// Set initial camera transform + grid\n\t\tconst camera = engine.getCamera();\n\t\tif (cameraLayerRef.current) {\n\t\t\tcameraLayerRef.current.style.transform = `scale(${camera.zoom}) translate(${-camera.x}px, ${-camera.y}px)`;\n\t\t}\n\t\t// Initial WebGL grid render\n\t\tif (gridRendererRef.current) {\n\t\t\tgridRendererRef.current.render(camera.x, camera.y, camera.zoom);\n\t\t}\n\n\t\t// Set initial slot positions\n\t\tfor (const v of visible) {\n\t\t\tconst el = slotRefs.current.get(v.entityId);\n\t\t\tif (!el) continue;\n\t\t\tel.style.transform = `translate(${v.worldX}px, ${v.worldY}px)`;\n\t\t\tel.style.width = `${v.worldWidth}px`;\n\t\t\tel.style.height = `${v.worldHeight}px`;\n\t\t}\n\n\t\t// Start the loop\n\t\trafId = requestAnimationFrame(loop);\n\n\t\treturn () => {\n\t\t\trunning = false;\n\t\t\tcancelAnimationFrame(rafId);\n\t\t};\n\t}, [engine]);\n\n\t// Fix #4: useLayoutEffect to set initial positions BEFORE browser paint\n\t// Prevents one-frame flash at (0,0) when new widgets enter the viewport\n\tuseLayoutEffect(() => {\n\t\tfor (const entityId of visibleEntities) {\n\t\t\tconst el = slotRefs.current.get(entityId);\n\t\t\tif (!el) continue;\n\t\t\tconst wb = engine.get(entityId, WorldBounds);\n\t\t\tif (!wb) continue;\n\t\t\tel.style.transform = `translate(${wb.worldX}px, ${wb.worldY}px)`;\n\t\t\tel.style.width = `${wb.worldWidth}px`;\n\t\t\tel.style.height = `${wb.worldHeight}px`;\n\t\t}\n\t}, [visibleEntities, engine]);\n\n\t// Split visible entities by surface\n\tconst { domEntities, webglEntities } = useMemo(() => {\n\t\tconst dom: EntityId[] = [];\n\t\tconst webgl: EntityId[] = [];\n\t\tfor (const id of visibleEntities) {\n\t\t\tconst w = engine.get(id, Widget);\n\t\t\tif (w?.surface === 'webgl') {\n\t\t\t\twebgl.push(id);\n\t\t\t} else {\n\t\t\t\tdom.push(id);\n\t\t\t}\n\t\t}\n\t\treturn { domEntities: dom, webglEntities: webgl };\n\t}, [visibleEntities, engine]);\n\n\tconst canvasContent = (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName={`relative overflow-hidden ${className ?? ''}`}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\ttouchAction: 'none',\n\t\t\t\tbackgroundColor: 'var(--canvas-bg, #fafafa)',\n\t\t\t}}\n\t\t>\n\t\t\t{/* WebGL layer — dot grid, selection overlays, connections */}\n\t\t\t<canvas ref={webglCanvasRef} className=\"absolute inset-0 pointer-events-none\" />\n\n\t\t\t{/* R3F layer — WebGL widgets (lazy, only when webgl entities exist) */}\n\t\t\t{webglEntities.length > 0 && <WebGLWidgetBridge engine={engine} entities={webglEntities} />}\n\n\t\t\t{/* Background — handles empty-space pointer events (deselect, marquee) */}\n\t\t\t<div\n\t\t\t\tclassName=\"absolute inset-0\"\n\t\t\t\tonPointerDown={onBackgroundPointerDown}\n\t\t\t\tonPointerMove={onBackgroundPointerMove}\n\t\t\t\tonPointerUp={onBackgroundPointerUp}\n\t\t\t/>\n\n\t\t\t{/* Camera transform layer — DOM widgets + selection overlays for WebGL widgets */}\n\t\t\t<div\n\t\t\t\tref={cameraLayerRef}\n\t\t\t\tclassName=\"absolute left-0 top-0 origin-top-left will-change-transform\"\n\t\t\t>\n\t\t\t\t{domEntities.map((entityId) => (\n\t\t\t\t\t<WidgetSlot key={entityId} entityId={entityId} slotRef={registerSlotRef} />\n\t\t\t\t))}\n\t\t\t\t{webglEntities.map((entityId) => (\n\t\t\t\t\t<SelectionOverlaySlot key={entityId} entityId={entityId} slotRef={registerSlotRef} />\n\t\t\t\t))}\n\t\t\t</div>\n\n\t\t\t{/* Children: toolbars, panels, etc. */}\n\t\t\t{children}\n\t\t</div>\n\t);\n\n\treturn (\n\t\t<EngineProvider value={engine}>\n\t\t\t<ContainerRefProvider value={containerRef}>\n\t\t\t\t{internalRegistry ? (\n\t\t\t\t\t<WidgetProvider registry={internalRegistry}>{canvasContent}</WidgetProvider>\n\t\t\t\t) : (\n\t\t\t\t\tcanvasContent\n\t\t\t\t)}\n\t\t\t</ContainerRefProvider>\n\t\t</EngineProvider>\n\t);\n}\n\n/** Bridge component — reads widget resolver from context and passes to WebGLWidgetLayer */\nfunction WebGLWidgetBridge({ engine, entities }: { engine: LayoutEngine; entities: EntityId[] }) {\n\tconst resolver = useWidgetResolver();\n\tconst resolve = useCallback(\n\t\t(entityId: EntityId) => {\n\t\t\tif (!resolver) return null;\n\t\t\tconst w = engine.get(entityId, Widget);\n\t\t\treturn resolver(entityId, w?.type ?? '');\n\t\t},\n\t\t[resolver, engine],\n\t);\n\n\tif (!resolver) return null;\n\n\treturn <WebGLWidgetLayer engine={engine} entities={entities} resolve={resolve} />;\n}\n","import { memo, useCallback, useEffect, useRef } from 'react';\nimport { WorldBounds } from '../components.js';\nimport type { EntityId } from '../ecs/types.js';\nimport type { Modifiers } from '../engine.js';\nimport { useContainerRef, useLayoutEngine } from './context.js';\n\ninterface SelectionOverlaySlotProps {\n\tentityId: EntityId;\n\tslotRef: (entityId: EntityId, el: HTMLDivElement | null) => void;\n}\n\nfunction getMods(e: React.PointerEvent): Modifiers {\n\treturn { shift: e.shiftKey, ctrl: e.ctrlKey, alt: e.altKey, meta: e.metaKey };\n}\n\n/**\n * DOM overlay for WebGL widgets — provides selection frame and pointer\n * interaction (select, drag, resize) without rendering widget content.\n */\nexport const SelectionOverlaySlot = memo(function SelectionOverlaySlot({\n\tentityId,\n\tslotRef,\n}: SelectionOverlaySlotProps) {\n\tconst wrapperRef = useRef<HTMLDivElement>(null);\n\tconst engine = useLayoutEngine();\n\tconst containerRefObj = useContainerRef();\n\n\tuseEffect(() => {\n\t\tslotRef(entityId, wrapperRef.current);\n\t\treturn () => slotRef(entityId, null);\n\t}, [entityId, slotRef]);\n\n\tconst toLocal = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\tconst rect = containerRefObj?.current?.getBoundingClientRect();\n\t\t\tif (!rect) return { x: e.clientX, y: e.clientY };\n\t\t\treturn { x: e.clientX - rect.left, y: e.clientY - rect.top };\n\t\t},\n\t\t[containerRefObj],\n\t);\n\n\tconst capturedRef = useRef(false);\n\n\tconst onPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\te.stopPropagation();\n\t\t\tconst { x, y } = toLocal(e);\n\t\t\tconst directive = engine.handlePointerDown(x, y, e.button, getMods(e));\n\t\t\tif (directive.action === 'capture-resize' || directive.action === 'passthrough-track-drag') {\n\t\t\t\twrapperRef.current?.setPointerCapture(e.pointerId);\n\t\t\t}\n\t\t\tif (directive.action === 'capture-resize') {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\t\t},\n\t\t[engine, toLocal],\n\t);\n\n\tconst onPointerMove = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\tconst { x, y } = toLocal(e);\n\t\t\tconst directive = engine.handlePointerMove(x, y, getMods(e));\n\t\t\tif (directive.action === 'capture-drag' && !capturedRef.current) {\n\t\t\t\tcapturedRef.current = true;\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t},\n\t\t[engine, toLocal],\n\t);\n\n\tconst onPointerUp = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\te.stopPropagation();\n\t\t\tcapturedRef.current = false;\n\t\t\tif (wrapperRef.current?.hasPointerCapture(e.pointerId)) {\n\t\t\t\twrapperRef.current.releasePointerCapture(e.pointerId);\n\t\t\t}\n\t\t\tengine.handlePointerUp();\n\t\t},\n\t\t[engine],\n\t);\n\n\tconst onDoubleClick = useCallback(\n\t\t(e: React.MouseEvent) => {\n\t\t\te.stopPropagation();\n\t\t\tengine.enterContainer(entityId);\n\t\t},\n\t\t[engine, entityId],\n\t);\n\n\tconst wb = engine.get(entityId, WorldBounds);\n\tconst initialStyle: React.CSSProperties = wb\n\t\t? {\n\t\t\t\ttransform: `translate(${wb.worldX}px, ${wb.worldY}px)`,\n\t\t\t\twidth: `${wb.worldWidth}px`,\n\t\t\t\theight: `${wb.worldHeight}px`,\n\t\t\t}\n\t\t: {};\n\n\treturn (\n\t\t<div\n\t\t\tref={wrapperRef}\n\t\t\tclassName=\"absolute left-0 top-0 origin-top-left will-change-transform\"\n\t\t\tstyle={initialStyle}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonPointerMove={onPointerMove}\n\t\t\tonPointerUp={onPointerUp}\n\t\t\tonDoubleClick={onDoubleClick}\n\t\t/>\n\t);\n});\n","import { createContext, useContext } from 'react';\nimport type { EntityId } from '../ecs/types.js';\nimport type { LayoutEngine } from '../engine.js';\n\n// === Engine Context ===\n\nconst EngineContext = createContext<LayoutEngine | null>(null);\n\nexport const EngineProvider = EngineContext.Provider;\n\n// === Container Ref Context ===\n// Shared so WidgetSlot can compute container-relative pointer coordinates.\n\nconst ContainerRefContext = createContext<React.RefObject<HTMLDivElement | null> | null>(null);\n\nexport const ContainerRefProvider = ContainerRefContext.Provider;\n\nexport function useContainerRef(): React.RefObject<HTMLDivElement | null> | null {\n\treturn useContext(ContainerRefContext);\n}\n\nexport function useLayoutEngine(): LayoutEngine {\n\tconst engine = useContext(EngineContext);\n\tif (!engine) {\n\t\tthrow new Error('useLayoutEngine must be used within an <InfiniteCanvas>');\n\t}\n\treturn engine;\n}\n\n/** @deprecated Use useLayoutEngine instead */\nexport const useEngine = useLayoutEngine;\n\n// === Widget Resolver Context ===\n\nexport type WidgetSurface = 'dom' | 'webgl';\n\nexport interface ResolvedWidget {\n\tcomponent: React.ComponentType<{ entityId: EntityId }>;\n\tsurface: WidgetSurface;\n}\n\nexport type WidgetResolver = (entityId: EntityId, widgetType: string) => ResolvedWidget | null;\n\nconst WidgetResolverContext = createContext<WidgetResolver | null>(null);\n\nexport const WidgetResolverProvider = WidgetResolverContext.Provider;\n\nexport function useWidgetResolver(): WidgetResolver | null {\n\treturn useContext(WidgetResolverContext);\n}\n","import { useCallback } from 'react';\nimport type { ReactNode } from 'react';\nimport { WidgetResolverProvider } from './context.js';\nimport type { WidgetRegistry } from './registry.js';\n\ninterface WidgetProviderProps {\n\tregistry: WidgetRegistry;\n\tchildren?: ReactNode;\n}\n\n/**\n * Connects a WidgetRegistry to the InfiniteCanvas.\n * Fix #9: Memoize the resolver so context consumers don't re-render on every parent render.\n */\nexport function WidgetProvider({ registry, children }: WidgetProviderProps) {\n\tconst resolver = useCallback(\n\t\t(_entityId: number, widgetType: string) => {\n\t\t\tconst def = registry.get(widgetType);\n\t\t\tif (!def) return null;\n\t\t\treturn { component: def.component, surface: def.surface ?? ('dom' as const) };\n\t\t},\n\t\t[registry],\n\t);\n\n\treturn <WidgetResolverProvider value={resolver}>{children}</WidgetResolverProvider>;\n}\n","import { memo, useCallback, useEffect, useRef } from 'react';\nimport { Widget, WorldBounds } from '../components.js';\nimport type { EntityId } from '../ecs/types.js';\nimport type { Modifiers } from '../engine.js';\nimport { useContainerRef, useLayoutEngine, useWidgetResolver } from './context.js';\nimport { useComponent } from './hooks.js';\n\ninterface WidgetSlotProps {\n\tentityId: EntityId;\n\tslotRef: (entityId: EntityId, el: HTMLDivElement | null) => void;\n}\n\nfunction getMods(e: React.PointerEvent): Modifiers {\n\treturn { shift: e.shiftKey, ctrl: e.ctrlKey, alt: e.altKey, meta: e.metaKey };\n}\n\nexport const WidgetSlot = memo(function WidgetSlot({ entityId, slotRef }: WidgetSlotProps) {\n\tconst wrapperRef = useRef<HTMLDivElement>(null);\n\tconst engine = useLayoutEngine();\n\tconst containerRefObj = useContainerRef();\n\tconst resolve = useWidgetResolver();\n\n\tconst widgetComp = useComponent(entityId, Widget);\n\n\tconst resolved = resolve?.(entityId, widgetComp?.type ?? '');\n\tconst WidgetComponent = resolved?.component ?? null;\n\n\t// Register wrapper ref with the batch updater\n\tuseEffect(() => {\n\t\tslotRef(entityId, wrapperRef.current);\n\t\treturn () => slotRef(entityId, null);\n\t}, [entityId, slotRef]);\n\n\t// Convert clientX/Y to container-relative coords\n\tconst toLocal = useCallback(\n\t\t(e: React.PointerEvent): { x: number; y: number } => {\n\t\t\tconst rect = containerRefObj?.current?.getBoundingClientRect();\n\t\t\tif (!rect) return { x: e.clientX, y: e.clientY };\n\t\t\treturn { x: e.clientX - rect.left, y: e.clientY - rect.top };\n\t\t},\n\t\t[containerRefObj],\n\t);\n\n\t// Fix #3: Capture pointer immediately on pointerdown for any widget interaction.\n\t// This ensures we always get pointerup even if the cursor leaves the window.\n\tconst onPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\t// Don't intercept clicks on interactive elements inside widgets\n\t\t\tconst target = e.target as HTMLElement;\n\t\t\tif (target.closest('button, input, textarea, select, [contenteditable]')) {\n\t\t\t\te.stopPropagation(); // still prevent background handler\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { x, y } = toLocal(e);\n\t\t\tconst directive = engine.handlePointerDown(x, y, e.button, getMods(e));\n\n\t\t\t// Always stop propagation — prevent background handler from double-processing\n\t\t\te.stopPropagation();\n\n\t\t\tif (directive.action === 'capture-resize' || directive.action === 'passthrough-track-drag') {\n\t\t\t\t// Capture pointer for both resize AND tracking (so we get pointerup reliably)\n\t\t\t\twrapperRef.current?.setPointerCapture(e.pointerId);\n\t\t\t}\n\t\t\tif (directive.action === 'capture-resize') {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\t\t},\n\t\t[engine, toLocal],\n\t);\n\n\tconst capturedRef = useRef(false);\n\n\tconst onPointerMove = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\tconst { x, y } = toLocal(e);\n\t\t\tconst directive = engine.handlePointerMove(x, y, getMods(e));\n\n\t\t\t// Fix #3: Only call setPointerCapture once when drag starts (not every move)\n\t\t\tif (directive.action === 'capture-drag' && !capturedRef.current) {\n\t\t\t\tcapturedRef.current = true;\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t},\n\t\t[engine, toLocal],\n\t);\n\n\tconst onPointerUp = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\te.stopPropagation();\n\t\t\tcapturedRef.current = false;\n\t\t\t// Release pointer capture (browser does this automatically, but be explicit)\n\t\t\tif (wrapperRef.current?.hasPointerCapture(e.pointerId)) {\n\t\t\t\twrapperRef.current.releasePointerCapture(e.pointerId);\n\t\t\t}\n\t\t\tengine.handlePointerUp();\n\t\t},\n\t\t[engine],\n\t);\n\n\tconst onDoubleClick = useCallback(\n\t\t(e: React.MouseEvent) => {\n\t\t\te.stopPropagation();\n\t\t\tengine.enterContainer(entityId);\n\t\t},\n\t\t[engine, entityId],\n\t);\n\n\t// Read WorldBounds at render time for initial inline position.\n\t// This ensures the div has the correct position on its very first paint —\n\t// no flash at (0,0). Subsequent updates come from the batch updater (rAF).\n\tconst wb = engine.get(entityId, WorldBounds);\n\tconst initialStyle: React.CSSProperties = wb\n\t\t? {\n\t\t\t\ttransform: `translate(${wb.worldX}px, ${wb.worldY}px)`,\n\t\t\t\twidth: `${wb.worldWidth}px`,\n\t\t\t\theight: `${wb.worldHeight}px`,\n\t\t\t}\n\t\t: {};\n\n\tconst content = WidgetComponent ? (\n\t\t<WidgetComponent entityId={entityId} />\n\t) : (\n\t\t<div className=\"h-full w-full rounded border border-dashed border-gray-300 bg-gray-50\" />\n\t);\n\n\treturn (\n\t\t<div\n\t\t\tref={wrapperRef}\n\t\t\tdata-widget-slot=\"\"\n\t\t\tclassName=\"absolute left-0 top-0 origin-top-left will-change-transform\"\n\t\t\tstyle={initialStyle}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonPointerMove={onPointerMove}\n\t\t\tonPointerUp={onPointerUp}\n\t\t\tonDoubleClick={onDoubleClick}\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t);\n});\n","import { useEffect, useRef, useState } from 'react';\nimport type { ComponentType, EntityId, ResourceType, TagType } from '../ecs/types.js';\nimport { useLayoutEngine } from './context.js';\n\n/**\n * Subscribe to a component on a specific entity.\n * Re-renders only when this component on this entity changes.\n */\nexport function useComponent<T>(entity: EntityId, type: ComponentType<T>): T | undefined {\n\tconst engine = useLayoutEngine();\n\tconst [value, setValue] = useState<T | undefined>(() => engine.get(entity, type));\n\n\tuseEffect(() => {\n\t\tsetValue(engine.get(entity, type));\n\n\t\tconst unsub = engine.world.onComponentChanged(\n\t\t\ttype,\n\t\t\t(_id, _prev, next) => {\n\t\t\t\tsetValue({ ...next });\n\t\t\t},\n\t\t\tentity,\n\t\t);\n\n\t\treturn unsub;\n\t}, [engine, entity, type]);\n\n\treturn value;\n}\n\n/**\n * Subscribe to a tag on a specific entity.\n * Re-renders when the tag is added or removed.\n */\nexport function useTag(entity: EntityId, type: TagType): boolean {\n\tconst engine = useLayoutEngine();\n\tconst [has, setHas] = useState(() => engine.world.hasTag(entity, type));\n\n\tuseEffect(() => {\n\t\tsetHas(engine.world.hasTag(entity, type));\n\n\t\tconst unsub1 = engine.world.onTagAdded(type, () => setHas(true), entity);\n\t\tconst unsub2 = engine.world.onTagRemoved(type, () => setHas(false), entity);\n\n\t\treturn () => {\n\t\t\tunsub1();\n\t\t\tunsub2();\n\t\t};\n\t}, [engine, entity, type]);\n\n\treturn has;\n}\n\n/**\n * Subscribe to a resource. Re-renders only when the resource actually changes.\n * Fix #6: Caches previous value and compares before triggering re-render.\n */\nexport function useResource<T>(type: ResourceType<T>): T {\n\tconst engine = useLayoutEngine();\n\tconst [value, setValue] = useState<T>(() => ({ ...engine.world.getResource(type) }));\n\tconst prevRef = useRef<string>('');\n\n\tuseEffect(() => {\n\t\tconst unsub = engine.onFrame(() => {\n\t\t\tconst current = engine.world.getResource(type);\n\t\t\tconst serialized = JSON.stringify(current);\n\t\t\tif (serialized !== prevRef.current) {\n\t\t\t\tprevRef.current = serialized;\n\t\t\t\tsetValue({ ...current });\n\t\t\t}\n\t\t});\n\t\treturn unsub;\n\t}, [engine, type]);\n\n\treturn value;\n}\n\n/**\n * Query entities matching component/tag types.\n * Re-renders when the result set changes.\n * Fix #7: Uses a stable key instead of spreading types into deps array.\n */\nexport function useQuery(...types: (ComponentType | TagType)[]): EntityId[] {\n\tconst engine = useLayoutEngine();\n\t// Create a stable key from type names for the dependency\n\tconst typeKey = types.map((t) => t.name).join(',');\n\tconst [result, setResult] = useState<EntityId[]>(() => engine.world.query(...types));\n\n\tuseEffect(() => {\n\t\tconst unsub = engine.onFrame(() => {\n\t\t\tconst next = engine.world.query(...types);\n\t\t\tsetResult((prev) => {\n\t\t\t\tif (prev.length !== next.length || prev.some((id, i) => id !== next[i])) {\n\t\t\t\t\treturn next;\n\t\t\t\t}\n\t\t\t\treturn prev;\n\t\t\t});\n\t\t});\n\t\treturn unsub;\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [engine, typeKey]);\n\n\treturn result;\n}\n\n/**\n * Get all entities with a specific tag.\n * Re-renders when the set changes.\n */\nexport function useTaggedEntities(type: TagType): EntityId[] {\n\tconst engine = useLayoutEngine();\n\tconst [result, setResult] = useState<EntityId[]>(() => engine.world.queryTagged(type));\n\n\tuseEffect(() => {\n\t\tconst update = () => setResult([...engine.world.queryTagged(type)]);\n\t\tconst unsub1 = engine.world.onTagAdded(type, update);\n\t\tconst unsub2 = engine.world.onTagRemoved(type, update);\n\t\treturn () => {\n\t\t\tunsub1();\n\t\t\tunsub2();\n\t\t};\n\t}, [engine, type]);\n\n\treturn result;\n}\n","import type { EntityId } from '../ecs/types.js';\n\nexport type WidgetSurface = 'dom' | 'webgl';\n\nexport interface WidgetDef {\n\ttype: string;\n\t/** Rendering surface — 'dom' (default) or 'webgl' (R3F). */\n\tsurface?: WidgetSurface;\n\tcomponent: React.ComponentType<{ entityId: EntityId }>;\n\tdefaultSize?: { width: number; height: number };\n\tminSize?: { width: number; height: number };\n}\n\nexport interface WidgetRegistry {\n\tregister(def: WidgetDef): void;\n\tget(type: string): WidgetDef | null;\n\tgetAll(): WidgetDef[];\n}\n\nexport function createWidgetRegistry(defs: WidgetDef[] = []): WidgetRegistry {\n\tconst map = new Map<string, WidgetDef>();\n\n\tfor (const def of defs) {\n\t\tmap.set(def.type, def);\n\t}\n\n\treturn {\n\t\tregister(def: WidgetDef) {\n\t\t\tmap.set(def.type, def);\n\t\t},\n\t\tget(type: string) {\n\t\t\treturn map.get(type) ?? null;\n\t\t},\n\t\tgetAll() {\n\t\t\treturn [...map.values()];\n\t\t},\n\t};\n}\n","import * as THREE from 'three';\n\n// === Public config ===\n\nexport interface GridConfig {\n\t/** World-unit spacings for up to 3 grid levels [fine, medium, coarse]. */\n\tspacings: [number, number, number];\n\t/** Dot RGB color as [r, g, b] in 0–1 range. */\n\tdotColor: [number, number, number];\n\t/** Base dot opacity multiplier (0–1). */\n\tdotAlpha: number;\n\t/** CSS-pixel range where a grid level fades in: [start, end]. */\n\tfadeIn: [number, number];\n\t/** CSS-pixel range where a grid level fades out: [start, end]. */\n\tfadeOut: [number, number];\n\t/** Dot radius range in CSS pixels [min, max]. Scaled by DPR internally. */\n\tdotRadius: [number, number];\n\t/** Per-level opacity weight: level i gets (base + i * step). */\n\tlevelWeight: [number, number];\n}\n\nexport const DEFAULT_GRID_CONFIG: GridConfig = {\n\tspacings: [8, 64, 512],\n\tdotColor: [0, 0, 0],\n\tdotAlpha: 0.18,\n\tfadeIn: [4, 12],\n\tfadeOut: [250, 500],\n\tdotRadius: [0.5, 1.4],\n\tlevelWeight: [1.0, 0.4],\n};\n\n// === Shader source ===\n\nconst vertexShader = /* glsl */ `\nvoid main() {\n\tgl_Position = vec4(position.xy, 0.0, 1.0);\n}\n`;\n\nconst fragmentShader = /* glsl */ `\nprecision highp float;\n\nuniform vec2 u_resolution; // device pixels\nuniform vec2 u_camera; // world-space top-left\nuniform float u_zoom; // CSS zoom\nuniform float u_dpr; // device pixel ratio\nuniform vec3 u_spacings; // world-unit grid spacings\nuniform vec3 u_dotColor; // dot RGB\nuniform float u_dotAlpha; // dot base alpha\nuniform vec2 u_fadeIn; // CSS-px [start, end]\nuniform vec2 u_fadeOut; // CSS-px [start, end]\nuniform vec2 u_dotRadius; // CSS-px [min, max]\nuniform vec2 u_levelWeight; // [base, step]\n\nvoid main() {\n\tvec2 devicePos = gl_FragCoord.xy;\n\tdevicePos.y = u_resolution.y - devicePos.y;\n\n\tfloat effectiveZoom = u_zoom * u_dpr;\n\tvec2 worldPos = devicePos / effectiveZoom + u_camera;\n\n\tfloat totalAlpha = 0.0;\n\n\tfor (int i = 0; i < 3; i++) {\n\t\tfloat spacing;\n\t\tif (i == 0) spacing = u_spacings.x;\n\t\telse if (i == 1) spacing = u_spacings.y;\n\t\telse spacing = u_spacings.z;\n\n\t\t// Screen spacing in CSS pixels (DPR-independent for consistent fading)\n\t\tfloat cssSpacing = spacing * u_zoom;\n\n\t\t// Fade curve\n\t\tfloat opacity = 0.0;\n\t\tif (cssSpacing >= u_fadeIn.x && cssSpacing < u_fadeIn.y) {\n\t\t\topacity = (cssSpacing - u_fadeIn.x) / (u_fadeIn.y - u_fadeIn.x);\n\t\t} else if (cssSpacing >= u_fadeIn.y && cssSpacing < u_fadeOut.x) {\n\t\t\topacity = 1.0;\n\t\t} else if (cssSpacing >= u_fadeOut.x && cssSpacing < u_fadeOut.y) {\n\t\t\topacity = 1.0 - (cssSpacing - u_fadeOut.x) / (u_fadeOut.y - u_fadeOut.x);\n\t\t}\n\t\tif (opacity <= 0.001) continue;\n\n\t\t// Distance to nearest grid intersection in device pixels\n\t\tvec2 f = fract(worldPos / spacing + 0.5) - 0.5;\n\t\tfloat dist = length(f) * spacing * effectiveZoom;\n\n\t\t// Dot radius in device pixels — grows as grid becomes sparser\n\t\tfloat t = clamp((cssSpacing - u_fadeIn.x) / 40.0, 0.0, 1.0);\n\t\tfloat radius = mix(u_dotRadius.x, u_dotRadius.y, t) * u_dpr;\n\n\t\t// Anti-aliased dot (0.5 device pixel smoothstep)\n\t\tfloat dot = 1.0 - smoothstep(radius - 0.5, radius + 0.5, dist);\n\n\t\t// Larger grid levels get progressively stronger dots\n\t\tfloat weight = u_levelWeight.x + float(i) * u_levelWeight.y;\n\t\ttotalAlpha += dot * opacity * weight;\n\t}\n\n\tgl_FragColor = vec4(u_dotColor, clamp(totalAlpha * u_dotAlpha, 0.0, 1.0));\n}\n`;\n\n// === Renderer class ===\n\nexport class GridRenderer {\n\tprivate renderer: THREE.WebGLRenderer;\n\tprivate scene: THREE.Scene;\n\tprivate camera: THREE.OrthographicCamera;\n\tprivate material: THREE.ShaderMaterial;\n\tprivate mesh: THREE.Mesh;\n\n\tconstructor(canvas: HTMLCanvasElement) {\n\t\tthis.renderer = new THREE.WebGLRenderer({\n\t\t\tcanvas,\n\t\t\talpha: true,\n\t\t\tantialias: false,\n\t\t\tpremultipliedAlpha: false,\n\t\t});\n\t\tthis.renderer.setClearColor(0x000000, 0);\n\n\t\tthis.scene = new THREE.Scene();\n\t\tthis.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n\n\t\tthis.material = new THREE.ShaderMaterial({\n\t\t\tvertexShader,\n\t\t\tfragmentShader,\n\t\t\tuniforms: {\n\t\t\t\tu_resolution: { value: new THREE.Vector2(1, 1) },\n\t\t\t\tu_camera: { value: new THREE.Vector2(0, 0) },\n\t\t\t\tu_zoom: { value: 1 },\n\t\t\t\tu_dpr: { value: 1 },\n\t\t\t\tu_spacings: { value: new THREE.Vector3(8, 64, 512) },\n\t\t\t\tu_dotColor: { value: new THREE.Vector3(0, 0, 0) },\n\t\t\t\tu_dotAlpha: { value: 0.18 },\n\t\t\t\tu_fadeIn: { value: new THREE.Vector2(4, 12) },\n\t\t\t\tu_fadeOut: { value: new THREE.Vector2(250, 500) },\n\t\t\t\tu_dotRadius: { value: new THREE.Vector2(0.5, 1.4) },\n\t\t\t\tu_levelWeight: { value: new THREE.Vector2(1.0, 0.4) },\n\t\t\t},\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t});\n\n\t\t// Fullscreen triangle (more efficient than quad — no diagonal seam)\n\t\tconst geometry = new THREE.BufferGeometry();\n\t\tconst vertices = new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]);\n\t\tgeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));\n\n\t\tthis.mesh = new THREE.Mesh(geometry, this.material);\n\t\tthis.scene.add(this.mesh);\n\t}\n\n\t/** Apply a (partial) grid config. Only provided fields are updated. */\n\tsetConfig(config: Partial<GridConfig>) {\n\t\tconst u = this.material.uniforms;\n\t\tif (config.spacings) u.u_spacings.value.set(...config.spacings);\n\t\tif (config.dotColor) u.u_dotColor.value.set(...config.dotColor);\n\t\tif (config.dotAlpha !== undefined) u.u_dotAlpha.value = config.dotAlpha;\n\t\tif (config.fadeIn) u.u_fadeIn.value.set(...config.fadeIn);\n\t\tif (config.fadeOut) u.u_fadeOut.value.set(...config.fadeOut);\n\t\tif (config.dotRadius) u.u_dotRadius.value.set(...config.dotRadius);\n\t\tif (config.levelWeight) u.u_levelWeight.value.set(...config.levelWeight);\n\t}\n\n\tsetSize(width: number, height: number, dpr = 1) {\n\t\tthis.renderer.setSize(width, height, false);\n\t\tthis.renderer.setPixelRatio(dpr);\n\t\tconst u = this.material.uniforms;\n\t\tu.u_resolution.value.set(width * dpr, height * dpr);\n\t\tu.u_dpr.value = dpr;\n\t}\n\n\trender(cameraX: number, cameraY: number, zoom: number) {\n\t\tconst u = this.material.uniforms;\n\t\tu.u_camera.value.set(cameraX, cameraY);\n\t\tu.u_zoom.value = zoom;\n\t\tthis.renderer.render(this.scene, this.camera);\n\t}\n\n\tdispose() {\n\t\tthis.mesh.geometry.dispose();\n\t\tthis.material.dispose();\n\t\tthis.renderer.dispose();\n\t}\n\n\t/** Expose for future WebGL widget rendering */\n\tgetWebGLRenderer(): THREE.WebGLRenderer {\n\t\treturn this.renderer;\n\t}\n}\n","import * as THREE from 'three';\nimport type { EqualSpacingIndicator, SnapGuide } from '../../snap.js';\n\n// === Public config (Figma-style defaults) ===\n\nexport interface SelectionConfig {\n\t/** Selection outline color [r,g,b] 0-1. Default: Figma blue. */\n\toutlineColor: [number, number, number];\n\t/** Selection outline width in screen px. */\n\toutlineWidth: number;\n\t/** Hover outline color [r,g,b] 0-1. */\n\thoverColor: [number, number, number];\n\t/** Hover outline width in screen px. */\n\thoverWidth: number;\n\t/** Handle size in screen px. */\n\thandleSize: number;\n\t/** Handle fill color [r,g,b] 0-1 (white). */\n\thandleFill: [number, number, number];\n\t/** Handle border color [r,g,b] 0-1 (same as outline). */\n\thandleBorder: [number, number, number];\n\t/** Handle border width in screen px. */\n\thandleBorderWidth: number;\n\t/** Group bbox dash length in screen px (0 = solid). */\n\tgroupDash: number;\n}\n\nexport const DEFAULT_SELECTION_CONFIG: SelectionConfig = {\n\toutlineColor: [0.051, 0.6, 1.0], // #0d99ff (Figma blue)\n\toutlineWidth: 1.5,\n\thoverColor: [0.051, 0.6, 1.0],\n\thoverWidth: 1.0,\n\thandleSize: 8,\n\thandleFill: [1, 1, 1],\n\thandleBorder: [0.051, 0.6, 1.0],\n\thandleBorderWidth: 1.5,\n\tgroupDash: 4,\n};\n\n// === Bounds data passed per frame ===\n\nexport interface SelectionBounds {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\n// === Shader ===\n\nconst MAX_ENTITIES = 32;\n\nconst vertexShader = /* glsl */ `\nvoid main() {\n\tgl_Position = vec4(position.xy, 0.0, 1.0);\n}\n`;\n\nconst fragmentShader = /* glsl */ `\nprecision highp float;\n\nuniform vec2 u_resolution;\nuniform vec2 u_camera;\nuniform float u_zoom;\nuniform float u_dpr;\n\n// Selection data\nuniform int u_count;\nuniform vec4 u_bounds[${MAX_ENTITIES}]; // (worldX, worldY, width, height)\nuniform int u_hoverIdx; // -1 = none\nuniform vec4 u_groupBounds; // group bbox (0 if count <= 1)\nuniform int u_hasGroup;\n\n// Snap guides\nuniform int u_guideCount;\nuniform vec4 u_guides[16]; // (axis: 0=x/1=y, position, 0, 0)\nuniform int u_spacingCount;\nuniform vec4 u_spacings[8]; // equal-spacing segments: (axis, from, to, perpPos)\nuniform vec3 u_guideColor;\n\n// Style\nuniform vec3 u_outlineColor;\nuniform float u_outlineWidth;\nuniform vec3 u_hoverColor;\nuniform float u_hoverWidth;\nuniform float u_handleSize;\nuniform vec3 u_handleFill;\nuniform vec3 u_handleBorder;\nuniform float u_handleBorderWidth;\nuniform float u_groupDash;\n\n// SDF for axis-aligned rectangle outline (returns distance to edge)\nfloat sdRectOutline(vec2 p, vec2 center, vec2 halfSize) {\n\tvec2 d = abs(p - center) - halfSize;\n\tfloat outside = length(max(d, 0.0));\n\tfloat inside = min(max(d.x, d.y), 0.0);\n\treturn abs(outside + inside);\n}\n\n// SDF for filled square\nfloat sdSquare(vec2 p, vec2 center, float halfSize) {\n\tvec2 d = abs(p - center) - vec2(halfSize);\n\treturn max(d.x, d.y);\n}\n\nvoid main() {\n\tif (u_count == 0 && u_hoverIdx < 0) discard;\n\n\tvec2 devicePos = gl_FragCoord.xy;\n\tdevicePos.y = u_resolution.y - devicePos.y;\n\n\tfloat effectiveZoom = u_zoom * u_dpr;\n\tvec2 worldPos = devicePos / effectiveZoom + u_camera;\n\n\t// Screen-space conversion factor\n\tfloat pxToWorld = 1.0 / effectiveZoom;\n\n\tvec4 color = vec4(0.0);\n\n\t// --- Hover outline ---\n\tif (u_hoverIdx >= 0 && u_hoverIdx < ${MAX_ENTITIES}) {\n\t\tvec4 b = u_bounds[u_hoverIdx];\n\t\tvec2 center = vec2(b.x + b.z * 0.5, b.y + b.w * 0.5);\n\t\tvec2 halfSize = vec2(b.z, b.w) * 0.5;\n\t\tfloat dist = sdRectOutline(worldPos, center, halfSize);\n\t\tfloat width = u_hoverWidth * pxToWorld;\n\t\tfloat alpha = 1.0 - smoothstep(width - pxToWorld * 0.5, width + pxToWorld * 0.5, dist);\n\t\tcolor = max(color, vec4(u_hoverColor, alpha * 0.6));\n\t}\n\n\t// --- Selection outlines ---\n\tfor (int i = 0; i < ${MAX_ENTITIES}; i++) {\n\t\tif (i >= u_count) break;\n\t\tvec4 b = u_bounds[i];\n\t\tvec2 center = vec2(b.x + b.z * 0.5, b.y + b.w * 0.5);\n\t\tvec2 halfSize = vec2(b.z, b.w) * 0.5;\n\n\t\t// Outline\n\t\tfloat dist = sdRectOutline(worldPos, center, halfSize);\n\t\tfloat width = u_outlineWidth * pxToWorld;\n\t\tfloat outlineAlpha = 1.0 - smoothstep(width - pxToWorld * 0.5, width + pxToWorld * 0.5, dist);\n\t\tcolor = max(color, vec4(u_outlineColor, outlineAlpha));\n\n\t\t// 8 resize handles\n\t\tfloat hs = u_handleSize * 0.5 * pxToWorld;\n\t\tfloat bw = u_handleBorderWidth * pxToWorld;\n\t\tvec2 corners[8];\n\t\tcorners[0] = vec2(b.x, b.y); // nw\n\t\tcorners[1] = vec2(b.x + b.z * 0.5, b.y); // n\n\t\tcorners[2] = vec2(b.x + b.z, b.y); // ne\n\t\tcorners[3] = vec2(b.x + b.z, b.y + b.w * 0.5); // e\n\t\tcorners[4] = vec2(b.x + b.z, b.y + b.w); // se\n\t\tcorners[5] = vec2(b.x + b.z * 0.5, b.y + b.w); // s\n\t\tcorners[6] = vec2(b.x, b.y + b.w); // sw\n\t\tcorners[7] = vec2(b.x, b.y + b.w * 0.5); // w\n\n\t\tfor (int h = 0; h < 8; h++) {\n\t\t\tfloat d = sdSquare(worldPos, corners[h], hs);\n\t\t\t// Fill (white)\n\t\t\tfloat fillAlpha = 1.0 - smoothstep(-pxToWorld * 0.5, pxToWorld * 0.5, d);\n\t\t\t// Border\n\t\t\tfloat borderDist = abs(d + bw * 0.5) - bw * 0.5;\n\t\t\tfloat borderAlpha = 1.0 - smoothstep(-pxToWorld * 0.5, pxToWorld * 0.5, borderDist);\n\n\t\t\tif (fillAlpha > 0.01) {\n\t\t\t\t// Composite: border color on top of fill\n\t\t\t\tvec3 handleColor = mix(u_handleFill, u_handleBorder, borderAlpha);\n\t\t\t\tcolor = vec4(handleColor, max(fillAlpha, color.a));\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Group bounding box (dashed) ---\n\tif (u_hasGroup == 1 && u_count > 1) {\n\t\tvec4 gb = u_groupBounds;\n\t\tvec2 center = vec2(gb.x + gb.z * 0.5, gb.y + gb.w * 0.5);\n\t\tvec2 halfSize = vec2(gb.z, gb.w) * 0.5;\n\t\tfloat dist = sdRectOutline(worldPos, center, halfSize);\n\t\tfloat width = u_outlineWidth * 0.75 * pxToWorld;\n\t\tfloat lineAlpha = 1.0 - smoothstep(width - pxToWorld * 0.5, width + pxToWorld * 0.5, dist);\n\n\t\t// Dash pattern along the rectangle perimeter\n\t\tif (u_groupDash > 0.0 && lineAlpha > 0.01) {\n\t\t\tvec2 rel = worldPos - vec2(gb.x, gb.y);\n\t\t\tfloat perim;\n\t\t\t// Approximate perimeter position for dash\n\t\t\tif (abs(rel.y) < width || abs(rel.y - gb.w) < width) {\n\t\t\t\tperim = rel.x;\n\t\t\t} else {\n\t\t\t\tperim = rel.y;\n\t\t\t}\n\t\t\tfloat dashWorld = u_groupDash * pxToWorld;\n\t\t\tfloat dashPattern = step(0.5, fract(perim / (dashWorld * 2.0)));\n\t\t\tlineAlpha *= dashPattern;\n\t\t}\n\n\t\tcolor = max(color, vec4(u_outlineColor, lineAlpha * 0.5));\n\t}\n\n\t// --- Snap guide lines ---\n\tfor (int i = 0; i < 16; i++) {\n\t\tif (i >= u_guideCount) break;\n\t\tvec4 g = u_guides[i];\n\t\tfloat guideWidth = 0.5 * pxToWorld;\n\t\tfloat dist;\n\t\tif (g.x < 0.5) {\n\t\t\t// Vertical line (x-axis alignment)\n\t\t\tdist = abs(worldPos.x - g.y);\n\t\t} else {\n\t\t\t// Horizontal line (y-axis alignment)\n\t\t\tdist = abs(worldPos.y - g.y);\n\t\t}\n\t\tfloat guideAlpha = 1.0 - smoothstep(guideWidth - pxToWorld * 0.3, guideWidth + pxToWorld * 0.3, dist);\n\t\tcolor = max(color, vec4(u_guideColor, guideAlpha * 0.8));\n\t}\n\n\t// --- Equal spacing indicators ---\n\tfor (int i = 0; i < 8; i++) {\n\t\tif (i >= u_spacingCount) break;\n\t\tvec4 s = u_spacings[i];\n\t\tfloat lineWidth = 0.5 * pxToWorld;\n\t\tfloat segAlpha = 0.0;\n\t\tif (s.x < 0.5) {\n\t\t\t// Horizontal segment (x-axis gap)\n\t\t\tfloat yDist = abs(worldPos.y - s.w);\n\t\t\tfloat xInRange = step(s.y, worldPos.x) * step(worldPos.x, s.z);\n\t\t\t// Center line\n\t\t\tsegAlpha = (1.0 - smoothstep(lineWidth, lineWidth + pxToWorld, yDist)) * xInRange;\n\t\t\t// End bars (perpendicular marks at from and to)\n\t\t\tfloat barHeight = 4.0 * pxToWorld;\n\t\t\tfloat barFromDist = abs(worldPos.x - s.y);\n\t\t\tfloat barFromAlpha = (1.0 - smoothstep(lineWidth, lineWidth + pxToWorld, barFromDist))\n\t\t\t\t* (1.0 - smoothstep(barHeight, barHeight + pxToWorld, abs(worldPos.y - s.w)));\n\t\t\tfloat barToDist = abs(worldPos.x - s.z);\n\t\t\tfloat barToAlpha = (1.0 - smoothstep(lineWidth, lineWidth + pxToWorld, barToDist))\n\t\t\t\t* (1.0 - smoothstep(barHeight, barHeight + pxToWorld, abs(worldPos.y - s.w)));\n\t\t\tsegAlpha = max(segAlpha, max(barFromAlpha, barToAlpha));\n\t\t} else {\n\t\t\t// Vertical segment (y-axis gap)\n\t\t\tfloat xDist = abs(worldPos.x - s.w);\n\t\t\tfloat yInRange = step(s.y, worldPos.y) * step(worldPos.y, s.z);\n\t\t\tsegAlpha = (1.0 - smoothstep(lineWidth, lineWidth + pxToWorld, xDist)) * yInRange;\n\t\t\tfloat barWidth = 4.0 * pxToWorld;\n\t\t\tfloat barFromAlpha = (1.0 - smoothstep(lineWidth, lineWidth + pxToWorld, abs(worldPos.y - s.y)))\n\t\t\t\t* (1.0 - smoothstep(barWidth, barWidth + pxToWorld, abs(worldPos.x - s.w)));\n\t\t\tfloat barToAlpha = (1.0 - smoothstep(lineWidth, lineWidth + pxToWorld, abs(worldPos.y - s.z)))\n\t\t\t\t* (1.0 - smoothstep(barWidth, barWidth + pxToWorld, abs(worldPos.x - s.w)));\n\t\t\tsegAlpha = max(segAlpha, max(barFromAlpha, barToAlpha));\n\t\t}\n\t\tcolor = max(color, vec4(u_guideColor, segAlpha * 0.7));\n\t}\n\n\tif (color.a < 0.01) discard;\n\tgl_FragColor = color;\n}\n`;\n\n// === Renderer class ===\n\nexport class SelectionRenderer {\n\tprivate material: THREE.ShaderMaterial;\n\tprivate mesh: THREE.Mesh;\n\tprivate scene: THREE.Scene;\n\tprivate camera: THREE.OrthographicCamera;\n\n\tconstructor() {\n\t\tthis.scene = new THREE.Scene();\n\t\tthis.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n\n\t\tconst boundsDefault = [];\n\t\tfor (let i = 0; i < MAX_ENTITIES; i++) {\n\t\t\tboundsDefault.push(new THREE.Vector4(0, 0, 0, 0));\n\t\t}\n\n\t\tthis.material = new THREE.ShaderMaterial({\n\t\t\tvertexShader,\n\t\t\tfragmentShader,\n\t\t\tuniforms: {\n\t\t\t\tu_resolution: { value: new THREE.Vector2(1, 1) },\n\t\t\t\tu_camera: { value: new THREE.Vector2(0, 0) },\n\t\t\t\tu_zoom: { value: 1 },\n\t\t\t\tu_dpr: { value: 1 },\n\t\t\t\tu_count: { value: 0 },\n\t\t\t\tu_bounds: { value: boundsDefault },\n\t\t\t\tu_hoverIdx: { value: -1 },\n\t\t\t\tu_groupBounds: { value: new THREE.Vector4(0, 0, 0, 0) },\n\t\t\t\tu_hasGroup: { value: 0 },\n\t\t\t\t// Style (Figma defaults)\n\t\t\t\tu_outlineColor: { value: new THREE.Vector3(...DEFAULT_SELECTION_CONFIG.outlineColor) },\n\t\t\t\tu_outlineWidth: { value: DEFAULT_SELECTION_CONFIG.outlineWidth },\n\t\t\t\tu_hoverColor: { value: new THREE.Vector3(...DEFAULT_SELECTION_CONFIG.hoverColor) },\n\t\t\t\tu_hoverWidth: { value: DEFAULT_SELECTION_CONFIG.hoverWidth },\n\t\t\t\tu_handleSize: { value: DEFAULT_SELECTION_CONFIG.handleSize },\n\t\t\t\tu_handleFill: { value: new THREE.Vector3(...DEFAULT_SELECTION_CONFIG.handleFill) },\n\t\t\t\tu_handleBorder: { value: new THREE.Vector3(...DEFAULT_SELECTION_CONFIG.handleBorder) },\n\t\t\t\tu_handleBorderWidth: { value: DEFAULT_SELECTION_CONFIG.handleBorderWidth },\n\t\t\t\tu_groupDash: { value: DEFAULT_SELECTION_CONFIG.groupDash },\n\t\t\t\t// Snap guides\n\t\t\t\tu_guideCount: { value: 0 },\n\t\t\t\tu_guides: { value: Array.from({ length: 16 }, () => new THREE.Vector4(0, 0, 0, 0)) },\n\t\t\t\tu_spacingCount: { value: 0 },\n\t\t\t\tu_spacings: { value: Array.from({ length: 8 }, () => new THREE.Vector4(0, 0, 0, 0)) },\n\t\t\t\tu_guideColor: { value: new THREE.Vector3(1.0, 0.0, 0.55) }, // magenta/pink\n\t\t\t},\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t});\n\n\t\tconst geometry = new THREE.BufferGeometry();\n\t\tconst vertices = new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]);\n\t\tgeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));\n\n\t\tthis.mesh = new THREE.Mesh(geometry, this.material);\n\t\tthis.scene.add(this.mesh);\n\t}\n\n\tsetConfig(config: Partial<SelectionConfig>) {\n\t\tconst u = this.material.uniforms;\n\t\tif (config.outlineColor) u.u_outlineColor.value.set(...config.outlineColor);\n\t\tif (config.outlineWidth !== undefined) u.u_outlineWidth.value = config.outlineWidth;\n\t\tif (config.hoverColor) u.u_hoverColor.value.set(...config.hoverColor);\n\t\tif (config.hoverWidth !== undefined) u.u_hoverWidth.value = config.hoverWidth;\n\t\tif (config.handleSize !== undefined) u.u_handleSize.value = config.handleSize;\n\t\tif (config.handleFill) u.u_handleFill.value.set(...config.handleFill);\n\t\tif (config.handleBorder) u.u_handleBorder.value.set(...config.handleBorder);\n\t\tif (config.handleBorderWidth !== undefined)\n\t\t\tu.u_handleBorderWidth.value = config.handleBorderWidth;\n\t\tif (config.groupDash !== undefined) u.u_groupDash.value = config.groupDash;\n\t}\n\n\tsetSize(resolution: THREE.Vector2, dpr: number) {\n\t\tthis.material.uniforms.u_resolution.value.copy(resolution);\n\t\tthis.material.uniforms.u_dpr.value = dpr;\n\t}\n\n\trender(\n\t\trenderer: THREE.WebGLRenderer,\n\t\tcameraX: number,\n\t\tcameraY: number,\n\t\tzoom: number,\n\t\tselected: SelectionBounds[],\n\t\thovered: SelectionBounds | null,\n\t\tguides: SnapGuide[] = [],\n\t\tspacings: EqualSpacingIndicator[] = [],\n\t) {\n\t\tconst u = this.material.uniforms;\n\t\tu.u_camera.value.set(cameraX, cameraY);\n\t\tu.u_zoom.value = zoom;\n\n\t\t// Upload selected bounds\n\t\tconst count = Math.min(selected.length, MAX_ENTITIES);\n\t\tu.u_count.value = count;\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst b = selected[i];\n\t\t\tu.u_bounds.value[i].set(b.x, b.y, b.width, b.height);\n\t\t}\n\n\t\t// Upload hover\n\t\tif (hovered && count < MAX_ENTITIES) {\n\t\t\t// Find if hovered is in the selected list\n\t\t\tlet hoverIdx = -1;\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tconst b = selected[i];\n\t\t\t\tif (b.x === hovered.x && b.y === hovered.y) {\n\t\t\t\t\thoverIdx = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hoverIdx < 0) {\n\t\t\t\t// Hovered but not selected — add to bounds array\n\t\t\t\tu.u_bounds.value[count].set(hovered.x, hovered.y, hovered.width, hovered.height);\n\t\t\t\tu.u_hoverIdx.value = count;\n\t\t\t} else {\n\t\t\t\tu.u_hoverIdx.value = -1; // already selected, no separate hover\n\t\t\t}\n\t\t} else {\n\t\t\tu.u_hoverIdx.value = -1;\n\t\t}\n\n\t\t// Group bounding box\n\t\tif (count > 1) {\n\t\t\tlet minX = Number.POSITIVE_INFINITY,\n\t\t\t\tminY = Number.POSITIVE_INFINITY,\n\t\t\t\tmaxX = Number.NEGATIVE_INFINITY,\n\t\t\t\tmaxY = Number.NEGATIVE_INFINITY;\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tconst b = selected[i];\n\t\t\t\tminX = Math.min(minX, b.x);\n\t\t\t\tminY = Math.min(minY, b.y);\n\t\t\t\tmaxX = Math.max(maxX, b.x + b.width);\n\t\t\t\tmaxY = Math.max(maxY, b.y + b.height);\n\t\t\t}\n\t\t\tu.u_groupBounds.value.set(minX, minY, maxX - minX, maxY - minY);\n\t\t\tu.u_hasGroup.value = 1;\n\t\t} else {\n\t\t\tu.u_hasGroup.value = 0;\n\t\t}\n\n\t\t// Upload snap guides\n\t\tconst gCount = Math.min(guides.length, 16);\n\t\tu.u_guideCount.value = gCount;\n\t\tfor (let i = 0; i < gCount; i++) {\n\t\t\tconst g = guides[i];\n\t\t\tu.u_guides.value[i].set(g.axis === 'x' ? 0 : 1, g.position, 0, 0);\n\t\t}\n\n\t\t// Upload equal spacing segments\n\t\tlet sIdx = 0;\n\t\tfor (const sp of spacings) {\n\t\t\tfor (const seg of sp.segments) {\n\t\t\t\tif (sIdx >= 8) break;\n\t\t\t\tu.u_spacings.value[sIdx].set(sp.axis === 'x' ? 0 : 1, seg.from, seg.to, sp.perpPosition);\n\t\t\t\tsIdx++;\n\t\t\t}\n\t\t}\n\t\tu.u_spacingCount.value = sIdx;\n\n\t\t// Render without clearing (composites on top of grid)\n\t\tconst prevAutoClear = renderer.autoClear;\n\t\trenderer.autoClear = false;\n\t\trenderer.render(this.scene, this.camera);\n\t\trenderer.autoClear = prevAutoClear;\n\t}\n\n\tdispose() {\n\t\tthis.mesh.geometry.dispose();\n\t\tthis.material.dispose();\n\t}\n}\n","import { Canvas, useFrame, useThree } from '@react-three/fiber';\nimport { useMemo, useRef } from 'react';\nimport * as THREE from 'three';\nimport type { EntityId } from '../../ecs/types.js';\nimport type { LayoutEngine } from '../../engine.js';\nimport type { ResolvedWidget } from '../context.js';\nimport { EngineProvider } from '../context.js';\nimport { WebGLWidgetSlot } from './WebGLWidgetSlot.js';\n\n// === Camera sync component (runs inside R3F) ===\n\nfunction CameraSync({ engine }: { engine: LayoutEngine }) {\n\tconst { camera, size } = useThree();\n\n\tuseFrame(() => {\n\t\tconst cam = engine.getCamera();\n\t\tconst ortho = camera as THREE.OrthographicCamera;\n\n\t\t// Frustum in world units — matches our engine coordinate system\n\t\tortho.left = 0;\n\t\tortho.right = size.width / cam.zoom;\n\t\tortho.top = 0;\n\t\tortho.bottom = -(size.height / cam.zoom);\n\t\tortho.near = 0.1;\n\t\tortho.far = 10000;\n\n\t\t// Position camera at engine camera origin; flip Y for Three.js\n\t\tortho.position.set(cam.x, -cam.y, 1000);\n\t\tortho.updateProjectionMatrix();\n\t});\n\n\treturn null;\n}\n\n// === Main layer component ===\n\ninterface WebGLWidgetLayerProps {\n\tengine: LayoutEngine;\n\tentities: EntityId[];\n\tresolve: (entityId: EntityId) => ResolvedWidget | null;\n}\n\nexport function WebGLWidgetLayer({ engine, entities, resolve }: WebGLWidgetLayerProps) {\n\tconst canvasRef = useRef<HTMLCanvasElement>(null);\n\n\t// Create a stable orthographic camera (R3F needs one at init)\n\tconst initialCamera = useMemo(() => {\n\t\tconst cam = new THREE.OrthographicCamera(0, 1, 0, -1, 0.1, 10000);\n\t\tcam.position.set(0, 0, 1000);\n\t\treturn cam;\n\t}, []);\n\n\t// Build a map of entityId → component for rendering\n\tconst widgetEntries = useMemo(() => {\n\t\tconst result: {\n\t\t\tentityId: EntityId;\n\t\t\tcomponent: React.ComponentType<{ entityId: EntityId; width: number; height: number }>;\n\t\t}[] = [];\n\t\tfor (const id of entities) {\n\t\t\tconst resolved = resolve(id);\n\t\t\tif (resolved && resolved.surface === 'webgl') {\n\t\t\t\tresult.push({\n\t\t\t\t\tentityId: id,\n\t\t\t\t\tcomponent: resolved.component as React.ComponentType<{\n\t\t\t\t\t\tentityId: EntityId;\n\t\t\t\t\t\twidth: number;\n\t\t\t\t\t\theight: number;\n\t\t\t\t\t}>,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}, [entities, resolve]);\n\n\tif (widgetEntries.length === 0) return null;\n\n\treturn (\n\t\t<Canvas\n\t\t\tref={canvasRef}\n\t\t\tcamera={initialCamera}\n\t\t\tframeloop=\"always\"\n\t\t\tgl={{ alpha: true, antialias: true }}\n\t\t\tstyle={{\n\t\t\t\tposition: 'absolute',\n\t\t\t\tinset: 0,\n\t\t\t\tpointerEvents: 'none',\n\t\t\t\tzIndex: 1,\n\t\t\t}}\n\t\t>\n\t\t\t<EngineProvider value={engine}>\n\t\t\t\t<CameraSync engine={engine} />\n\t\t\t\t{widgetEntries.map(({ entityId, component }) => (\n\t\t\t\t\t<WebGLWidgetSlot key={entityId} entityId={entityId} component={component} />\n\t\t\t\t))}\n\t\t\t</EngineProvider>\n\t\t</Canvas>\n\t);\n}\n","import { useFrame } from '@react-three/fiber';\nimport { useRef } from 'react';\nimport type { Group } from 'three';\nimport { WorldBounds } from '../../components.js';\nimport type { EntityId } from '../../ecs/types.js';\nimport { useLayoutEngine } from '../context.js';\nimport { useComponent } from '../hooks.js';\n\ninterface WebGLWidgetSlotProps {\n\tentityId: EntityId;\n\tcomponent: React.ComponentType<{ entityId: EntityId; width: number; height: number }>;\n}\n\n/**\n * Positions a Three.js Group at the entity's world-space center.\n * The widget component renders in local space: origin at center,\n * X right, Y up, dimensions = (width, height) in world units.\n */\nexport function WebGLWidgetSlot({ entityId, component: WidgetComponent }: WebGLWidgetSlotProps) {\n\tconst groupRef = useRef<Group>(null);\n\tconst engine = useLayoutEngine();\n\n\t// Read WorldBounds reactively for initial render\n\tconst wb = useComponent(entityId, WorldBounds);\n\n\t// Update position every frame (camera may have moved)\n\tuseFrame(() => {\n\t\tif (!groupRef.current) return;\n\t\tconst bounds = engine.get(entityId, WorldBounds);\n\t\tif (!bounds) return;\n\t\t// Position at center of bounding box; flip Y for Three.js\n\t\tgroupRef.current.position.set(\n\t\t\tbounds.worldX + bounds.worldWidth / 2,\n\t\t\t-(bounds.worldY + bounds.worldHeight / 2),\n\t\t\t0,\n\t\t);\n\t});\n\n\tif (!wb) return null;\n\n\treturn (\n\t\t<group ref={groupRef}>\n\t\t\t<WidgetComponent entityId={entityId} width={wb.worldWidth} height={wb.worldHeight} />\n\t\t</group>\n\t);\n}\n","import { useCallback } from 'react';\nimport { Children, Selected, WidgetBreakpoint, WidgetData } from '../components.js';\nimport type { EntityId } from '../ecs/types.js';\nimport type { Breakpoint } from '../resources.js';\nimport { useLayoutEngine } from './context.js';\nimport { useComponent, useTag } from './hooks.js';\n\n/**\n * Read widget data for an entity. Re-renders when data changes.\n */\nexport function useWidgetData(entityId: EntityId): Record<string, any> {\n\tconst comp = useComponent(entityId, WidgetData);\n\treturn comp?.data ?? {};\n}\n\n/**\n * Read the current breakpoint for an entity. Re-renders when breakpoint changes.\n */\nexport function useBreakpoint(entityId: EntityId): Breakpoint {\n\tconst comp = useComponent(entityId, WidgetBreakpoint);\n\treturn comp?.current ?? 'normal';\n}\n\n/**\n * Read child entity IDs. Re-renders when children change.\n */\nexport function useChildren(entityId: EntityId): EntityId[] {\n\tconst comp = useComponent(entityId, Children);\n\treturn comp?.ids ?? [];\n}\n\n/** @deprecated Use useChildren instead */\nexport const useWidgetChildren = useChildren;\n\n/**\n * Check if this entity is selected. Re-renders when selection changes.\n */\nexport function useIsSelected(entityId: EntityId): boolean {\n\treturn useTag(entityId, Selected);\n}\n\n/**\n * Returns a function to update widget data via the engine.\n */\nexport function useUpdateWidget(entityId: EntityId): (patch: Record<string, any>) => void {\n\tconst engine = useLayoutEngine();\n\treturn useCallback(\n\t\t(patch: Record<string, any>) => {\n\t\t\tconst existing = engine.get(entityId, WidgetData);\n\t\t\tif (existing) {\n\t\t\t\tengine.set(entityId, WidgetData, {\n\t\t\t\t\tdata: { ...existing.data, ...patch },\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[engine, entityId],\n\t);\n}\n\n/** @deprecated Use useUpdateWidget instead */\nexport const useUpdateData = useUpdateWidget;\n"],"mappings":"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","names":["RBushImport","import_react","import_react","SelectionOverlaySlot","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","getMods","WidgetSlot","THREE","vertexShader","fragmentShader","import_fiber","import_react","THREE","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","camera","visible","import_react"]}