@woven-canvas/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +34 -0
- package/build/_tsup-dts-rollup.d.cts +1509 -0
- package/build/_tsup-dts-rollup.d.ts +1509 -0
- package/build/index.cjs +4109 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.cts +133 -0
- package/build/index.d.ts +133 -0
- package/build/index.js +4036 -0
- package/build/index.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/CorePlugin.ts","../src/components/index.ts","../src/components/Aabb.ts","../src/components/Block.ts","../src/components/Asset.ts","../src/components/Color.ts","../src/components/Connector.ts","../src/components/Edited.ts","../src/components/Held.ts","../src/components/HitGeometry.ts","../src/components/Hovered.ts","../src/components/Image.ts","../src/components/Opacity.ts","../src/components/Pointer.ts","../src/components/ScaleWithZoom.ts","../src/components/Shape.ts","../src/components/Text.ts","../src/types.ts","../src/components/User.ts","../src/components/VerticalAlign.ts","../src/constants.ts","../src/singletons/index.ts","../src/singletons/Camera.ts","../src/singletons/Screen.ts","../src/singletons/Controls.ts","../src/singletons/Cursor.ts","../src/singletons/Frame.ts","../src/singletons/Grid.ts","../src/singletons/Intersect.ts","../src/singletons/Keyboard.ts","../src/singletons/Mouse.ts","../src/singletons/RankBounds.ts","../src/singletons/ScaleWithZoomState.ts","../src/systems/capture/keybindSystem.ts","../src/command.ts","../src/EditorSystem.ts","../src/systems/input/frameSystem.ts","../src/systems/input/keyboardSystem.ts","../src/systems/input/mouseSystem.ts","../src/systems/input/pointerSystem.ts","../src/systems/input/screenSystem.ts","../src/systems/postRender/cursorSystem.ts","../src/systems/postRender/presenceSystem.ts","../src/helpers/blockDefs.ts","../src/helpers/computeAabb.ts","../src/helpers/held.ts","../src/helpers/intersect.ts","../src/helpers/intersectCapsule.ts","../src/helpers/user.ts","../src/systems/preCapture/intersectSystem.ts","../src/systems/preInput/rankBoundsSystem.ts","../src/systems/preRender/canSeeBlocksSystem.ts","../src/systems/preRender/scaleWithZoomSystem.ts","../src/Editor.ts","../src/FontLoader.ts","../src/plugin.ts","../src/EditorStateDef.ts","../src/machine.ts","../src/events/frameInputEvents.ts","../src/events/keyboardInputEvents.ts","../src/events/mouseInputEvents.ts","../src/events/pointerInputEvents.ts"],"sourcesContent":["// Re-export math types\nexport type { Vec2 } from '@woven-canvas/math'\nexport type {\n AnyCanvasComponentDef,\n AnyCanvasSingletonDef,\n InferCanvasComponentType,\n SingletonSyncBehavior,\n SyncBehavior,\n} from '@woven-ecs/canvas-store'\n// Re-export from ecs-sync\nexport {\n CanvasComponentDef,\n CanvasSingletonDef,\n defineCanvasComponent,\n defineCanvasSingleton,\n Synced,\n} from '@woven-ecs/canvas-store'\n// Re-export useful ECS utilities\nexport {\n addComponent,\n ComponentDef,\n type ComponentSchema,\n type Context,\n createEntity,\n defineQuery,\n defineSystem,\n type EntityId,\n EventType,\n field,\n getBackrefs,\n getResources,\n hasComponent,\n isAlive,\n MainThreadSystem,\n type QueryDef,\n removeComponent,\n removeEntity,\n SINGLETON_ENTITY_ID,\n type System,\n} from '@woven-ecs/core'\n// Plugin\nexport { CorePlugin } from './CorePlugin'\n// Command system\nexport {\n type CommandDef,\n CommandMarker,\n defineCommand,\n on,\n Redo,\n Undo,\n} from './command'\n// Components\nexport {\n Aabb,\n Asset,\n Block,\n Color,\n Connector,\n Edited,\n Held,\n HitGeometry,\n Hovered,\n Image,\n MAX_HIT_ARCS,\n MAX_HIT_CAPSULES,\n Opacity,\n Pointer,\n PointerButton,\n PointerType,\n ScaleWithZoom,\n Shape,\n StrokeKind,\n Text,\n UploadState,\n User,\n VerticalAlign,\n} from './components'\n// Constants\nexport { STRATUM_ORDER } from './constants'\n// Editor class\nexport { Editor, type QueryCallback } from './Editor'\n// State machine singleton\nexport {\n defineEditorState,\n EditorStateDef,\n type InferStateContext,\n type StateSchema,\n} from './EditorStateDef'\n// Editor system\nexport {\n defineEditorSystem,\n type EditorSystem,\n type EditorSystemFunction,\n type EditorSystemOptions,\n} from './EditorSystem'\n// Events\nexport {\n clearPointerTrackingState,\n type FrameInput,\n getFrameInput,\n getKeyboardInput,\n getMouseInput,\n getPointerInput,\n type KeyboardInput,\n type KeyboardInputType,\n type MouseInput,\n type MouseInputType,\n // Types\n type PointerInput,\n type PointerInputOptions,\n type PointerInputType,\n} from './events'\nexport type { FontFamily as FontFamilyType } from './FontLoader'\n// Font loading\nexport { FontFamily, type FontFamilyInput, FontLoader } from './FontLoader'\n// Helpers\nexport {\n canBlockEdit,\n getBlockDef,\n getTopmostBlockAtPoint,\n intersectAabb,\n intersectCapsule,\n intersectPoint,\n isHeldByRemote,\n} from './helpers'\n// State machine utilities\nexport { type MachineResult, runMachine } from './machine'\n// Plugin system\nexport {\n type EditorPlugin,\n type EditorPluginFactory,\n type EditorPluginInput,\n parsePlugin,\n} from './plugin'\n// Singletons\nexport {\n Camera,\n Controls,\n Cursor,\n Frame,\n Grid,\n Intersect,\n Key,\n Keyboard,\n Mouse,\n RankBounds,\n ScaleWithZoomState,\n Screen,\n} from './singletons'\n// types\nexport type {\n BlockDefInput,\n ControlsOptionsInput,\n CursorDefMap,\n EditorOptionsInput,\n EditorResources,\n GridOptionsInput,\n KeybindInput,\n ResizeMode,\n UserDataInput,\n} from './types'\nexport {\n BlockDef,\n ControlsOptions,\n CursorDef,\n GridOptions,\n getPluginResources,\n Keybind,\n Stratum,\n TextAlignment,\n UserData,\n VerticalAlignment,\n} from './types'\n","import {\n type AnyCanvasComponentDef,\n type AnyCanvasSingletonDef,\n CanvasComponentDef,\n CanvasSingletonDef,\n} from '@woven-ecs/canvas-store'\nimport { getResources } from '@woven-ecs/core'\nimport * as components from './components'\nimport { Asset, Color, Image, Shape, Text, VerticalAlign } from './components'\nimport { PLUGIN_NAME } from './constants'\nimport type { EditorPlugin } from './plugin'\nimport * as singletons from './singletons'\nimport { keybindSystem } from './systems/capture'\nimport {\n attachKeyboardListeners,\n attachMouseListeners,\n attachPointerListeners,\n attachScreenObserver,\n detachKeyboardListeners,\n detachMouseListeners,\n detachPointerListeners,\n detachScreenObserver,\n frameSystem,\n keyboardSystem,\n mouseSystem,\n pointerSystem,\n screenSystem,\n} from './systems/input'\nimport { cursorSystem, presenceSystem } from './systems/postRender'\nimport { intersectSystem } from './systems/preCapture'\nimport { rankBoundsSystem } from './systems/preInput'\nimport { canSeeBlocksSystem, scaleWithZoomSystem } from './systems/preRender'\nimport type { EditorResources } from './types'\n\n/**\n * Core plugin - handles input, camera, and basic block types.\n */\nexport const CorePlugin: EditorPlugin = {\n name: PLUGIN_NAME,\n\n singletons: Object.values(singletons).filter((v) => v instanceof CanvasSingletonDef) as AnyCanvasSingletonDef[],\n\n components: Object.values(components).filter((v) => v instanceof CanvasComponentDef) as AnyCanvasComponentDef[],\n\n blockDefs: [\n {\n tag: 'sticky-note',\n components: [Color, Text, VerticalAlign],\n editOptions: {\n canEdit: true,\n },\n },\n {\n tag: 'text',\n components: [Text],\n resizeMode: 'text',\n editOptions: {\n canEdit: true,\n removeWhenTextEmpty: true,\n },\n },\n {\n tag: 'image',\n components: [Image, Asset],\n resizeMode: 'scale',\n },\n {\n tag: 'shape',\n components: [Shape, Text, VerticalAlign],\n resizeMode: 'free',\n editOptions: {\n canEdit: true,\n },\n },\n ],\n\n systems: [\n // Input phase\n frameSystem, // priority: 100\n rankBoundsSystem, // priority: 100\n keyboardSystem,\n mouseSystem,\n screenSystem,\n pointerSystem,\n\n // Capture phase\n intersectSystem, // priority: 100\n keybindSystem,\n\n // Render phase\n scaleWithZoomSystem, // priority: 100\n canSeeBlocksSystem, // priority: 90\n cursorSystem, // priority: -100\n presenceSystem, // priority: -100\n ],\n\n setup(ctx) {\n const { domElement } = getResources<EditorResources>(ctx)\n\n // Attach all event listeners\n attachKeyboardListeners(domElement)\n attachMouseListeners(domElement)\n attachScreenObserver(domElement)\n attachPointerListeners(domElement)\n },\n\n teardown(ctx) {\n const { domElement } = getResources<EditorResources>(ctx)\n\n // Detach all event listeners\n detachKeyboardListeners(domElement)\n detachMouseListeners(domElement)\n detachScreenObserver(domElement)\n detachPointerListeners(domElement)\n },\n}\n","export { Aabb } from './Aabb'\nexport { Asset, UploadState } from './Asset'\n// Core spatial components\nexport { Block } from './Block'\nexport { Color } from './Color'\nexport { Connector } from './Connector'\nexport { Edited } from './Edited'\nexport { Held } from './Held'\n// Hit geometry for collision detection\nexport { HitGeometry, MAX_HIT_ARCS, MAX_HIT_CAPSULES } from './HitGeometry'\n// State components\nexport { Hovered } from './Hovered'\n// Image/Asset components\nexport { Image } from './Image'\nexport { Opacity } from './Opacity'\nexport {\n addPointerSample,\n Pointer,\n PointerButton,\n PointerType,\n} from './Pointer'\n// Transform components\nexport { ScaleWithZoom } from './ScaleWithZoom'\n// Shape\nexport { Shape, StrokeKind } from './Shape'\n// Content components\nexport { Text } from './Text'\n// User presence\nexport { User } from './User'\nexport { VerticalAlign } from './VerticalAlign'\n","import { Aabb as AabbMath, type Vec2 } from '@woven-canvas/math'\nimport { CanvasComponentDef } from '@woven-ecs/canvas-store'\nimport { type Context, type EntityId, field } from '@woven-ecs/core'\nimport { Block } from './Block'\n\n// Tuple indices for AABB\nconst LEFT = 0\nconst TOP = 1\nconst RIGHT = 2\nconst BOTTOM = 3\n\nconst AabbSchema = {\n /** Bounds as [left, top, right, bottom] */\n value: field.tuple(field.float32(), 4).default([0, 0, 0, 0]),\n}\n\n/**\n * Axis-aligned bounding box component.\n *\n * Stored as a tuple [left, top, right, bottom] for memory efficiency.\n * Used for fast intersection tests and spatial queries.\n * Updated automatically when Block transforms change.\n */\nclass AabbDef extends CanvasComponentDef<typeof AabbSchema> {\n constructor() {\n super({ name: 'aabb' }, AabbSchema)\n }\n\n /**\n * Check if a point is contained within an entity's AABB.\n */\n containsPoint(ctx: Context, entityId: EntityId, point: Vec2, inclusive = true): boolean {\n const { value } = this.read(ctx, entityId)\n\n return AabbMath.containsPoint(value, point, inclusive)\n }\n\n /**\n * Expand AABB to include a point.\n */\n expandByPoint(ctx: Context, entityId: EntityId, point: Vec2): void {\n const { value } = this.write(ctx, entityId)\n AabbMath.expand(value, point)\n }\n\n /**\n * Expand AABB to include another entity's block.\n */\n expandByBlock(ctx: Context, entityId: EntityId, blockEntityId: EntityId): void {\n const corners = Block.getCorners(ctx, blockEntityId)\n const { value } = this.write(ctx, entityId)\n for (const corner of corners) {\n AabbMath.expand(value, corner)\n }\n }\n\n /**\n * Expand AABB to include another AABB.\n */\n expandByAabb(ctx: Context, entityId: EntityId, other: AabbMath): void {\n const { value } = this.write(ctx, entityId)\n AabbMath.union(value, other)\n }\n\n /**\n * Copy bounds from another entity's AABB.\n */\n copyFrom(ctx: Context, entityId: EntityId, otherEntityId: EntityId): void {\n const { value: src } = this.read(ctx, otherEntityId)\n const { value: dst } = this.write(ctx, entityId)\n AabbMath.copy(dst, src)\n }\n\n /**\n * Set AABB from an array of points.\n */\n setByPoints(ctx: Context, entityId: EntityId, points: Vec2[]): void {\n if (points.length === 0) return\n const { value } = this.write(ctx, entityId)\n AabbMath.setFromPoints(value, points)\n }\n\n /**\n * Get the center point of an entity's AABB.\n */\n getCenter(ctx: Context, entityId: EntityId): Vec2 {\n const { value } = this.read(ctx, entityId)\n return AabbMath.center(value)\n }\n\n /**\n * Get the width of an entity's AABB.\n */\n getWidth(ctx: Context, entityId: EntityId): number {\n const { value } = this.read(ctx, entityId)\n return AabbMath.width(value)\n }\n\n /**\n * Get the height of an entity's AABB.\n */\n getHeight(ctx: Context, entityId: EntityId): number {\n const { value } = this.read(ctx, entityId)\n return AabbMath.height(value)\n }\n\n /**\n * Get the distance from AABB to a point.\n */\n distanceToPoint(ctx: Context, entityId: EntityId, point: Vec2): number {\n const { value } = this.read(ctx, entityId)\n return AabbMath.distanceToPoint(value, point)\n }\n\n /**\n * Check if two entity AABBs intersect.\n */\n intersectsEntity(ctx: Context, entityIdA: EntityId, entityIdB: EntityId): boolean {\n const { value: a } = this.read(ctx, entityIdA)\n const { value: b } = this.read(ctx, entityIdB)\n return AabbMath.intersects(a, b)\n }\n\n /**\n * Check if entity A's AABB completely surrounds entity B's AABB.\n */\n surroundsEntity(ctx: Context, entityIdA: EntityId, entityIdB: EntityId): boolean {\n const { value: a } = this.read(ctx, entityIdA)\n const { value: b } = this.read(ctx, entityIdB)\n return AabbMath.contains(a, b)\n }\n\n /**\n * Get the four corner points of an entity's AABB.\n * Returns corners in order: top-left, top-right, bottom-right, bottom-left.\n * @param out - Optional output array to write to (avoids allocation)\n */\n getCorners(ctx: Context, entityId: EntityId, out?: [Vec2, Vec2, Vec2, Vec2]): [Vec2, Vec2, Vec2, Vec2] {\n const { value } = this.read(ctx, entityId)\n const result: [Vec2, Vec2, Vec2, Vec2] = out ?? [\n [0, 0],\n [0, 0],\n [0, 0],\n [0, 0],\n ]\n // TL\n result[0][0] = value[LEFT]\n result[0][1] = value[TOP]\n // TR\n result[1][0] = value[RIGHT]\n result[1][1] = value[TOP]\n // BR\n result[2][0] = value[RIGHT]\n result[2][1] = value[BOTTOM]\n // BL\n result[3][0] = value[LEFT]\n result[3][1] = value[BOTTOM]\n return result\n }\n\n /**\n * Apply padding to all sides of the AABB.\n */\n applyPadding(ctx: Context, entityId: EntityId, padding: number): void {\n const { value } = this.write(ctx, entityId)\n AabbMath.pad(value, padding)\n }\n}\n\nexport const Aabb = new AabbDef()\n","import { type Aabb, type Mat2, Rect, Vec2 } from '@woven-canvas/math'\nimport { CanvasComponentDef } from '@woven-ecs/canvas-store'\nimport { type Context, type EntityId, field } from '@woven-ecs/core'\n\n// Pre-allocated arrays for SAT intersection to avoid allocations\nconst _aabbCorners: [Vec2, Vec2, Vec2, Vec2] = [\n [0, 0],\n [0, 0],\n [0, 0],\n [0, 0],\n]\nconst _blockCorners: [Vec2, Vec2, Vec2, Vec2] = [\n [0, 0],\n [0, 0],\n [0, 0],\n [0, 0],\n]\nconst _blockAxes: [Vec2, Vec2] = [\n [0, 0],\n [0, 0],\n]\n\nconst BlockSchema = {\n /** Element tag name (e.g., \"div\", \"img\") */\n tag: field.string().max(36).default('div'),\n /** Position as [left, top] */\n position: field.tuple(field.float64(), 2).default([0, 0]),\n /** Size as [width, height] */\n size: field.tuple(field.float64(), 2).default([100, 100]),\n /** Rotation around center in radians */\n rotateZ: field.float64().default(0),\n /** Flip state as [flipX, flipY] */\n flip: field.tuple(field.boolean(), 2).default([false, false]),\n /** Z-order rank (LexoRank string) */\n rank: field.string().max(36).default(''),\n}\n\n/**\n * Block component - core spatial data for canvas entities.\n *\n * Contains position (left, top), size (width, height), rotation (rotateZ),\n * z-order (rank), and element tag.\n */\nclass BlockDef extends CanvasComponentDef<typeof BlockSchema> {\n constructor() {\n super({ name: 'block', sync: 'document' }, BlockSchema)\n }\n\n /**\n * Get the center point of a block.\n * @param out - Optional output vector to write to (avoids allocation)\n */\n getCenter(ctx: Context, entityId: EntityId, out?: Vec2): Vec2 {\n const { position, size } = this.read(ctx, entityId)\n const result: Vec2 = out ?? [0, 0]\n Rect.getCenter(position, size, result)\n return result\n }\n\n /**\n * Set the center point of a block (adjusts position accordingly).\n */\n setCenter(ctx: Context, entityId: EntityId, center: Vec2): void {\n const block = this.write(ctx, entityId)\n Rect.setCenter(block.position, block.size, center)\n }\n\n /**\n * Get the four corner points of a block (accounting for rotation).\n * Returns corners in order: top-left, top-right, bottom-right, bottom-left.\n * @param out - Optional output array to write to (avoids allocation)\n */\n getCorners(ctx: Context, entityId: EntityId, out?: [Vec2, Vec2, Vec2, Vec2]): [Vec2, Vec2, Vec2, Vec2] {\n const { position, size, rotateZ } = this.read(ctx, entityId)\n const result: [Vec2, Vec2, Vec2, Vec2] = out ?? [\n [0, 0],\n [0, 0],\n [0, 0],\n [0, 0],\n ]\n Rect.getCorners(position, size, rotateZ, result)\n return result\n }\n\n /**\n * Check if a point intersects a block (accounting for rotation).\n */\n containsPoint(ctx: Context, entityId: EntityId, point: Vec2): boolean {\n const { position, size, rotateZ } = this.read(ctx, entityId)\n return Rect.containsPoint(position, size, rotateZ, point)\n }\n\n /**\n * Move a block by a delta offset.\n */\n translate(ctx: Context, entityId: EntityId, delta: Vec2): void {\n const block = this.write(ctx, entityId)\n Rect.translate(block.position, delta)\n }\n\n /**\n * Set the position of a block.\n */\n setPosition(ctx: Context, entityId: EntityId, position: Vec2): void {\n const block = this.write(ctx, entityId)\n Vec2.copy(block.position, position)\n }\n\n /**\n * Set the size of a block.\n */\n setSize(ctx: Context, entityId: EntityId, size: Vec2): void {\n const block = this.write(ctx, entityId)\n Vec2.copy(block.size, size)\n }\n\n /**\n * Rotate a block by a delta angle (in radians).\n */\n rotateBy(ctx: Context, entityId: EntityId, deltaAngle: number): void {\n const block = this.write(ctx, entityId)\n block.rotateZ += deltaAngle\n }\n\n /**\n * Rotate a block around a pivot point.\n */\n rotateAround(ctx: Context, entityId: EntityId, pivot: Vec2, angle: number): void {\n const block = this.write(ctx, entityId)\n block.rotateZ = Rect.rotateAround(block.position, block.size, block.rotateZ, pivot, angle)\n }\n\n /**\n * Scale a block uniformly around its center.\n */\n scaleBy(ctx: Context, entityId: EntityId, scaleFactor: number): void {\n const block = this.write(ctx, entityId)\n Rect.scaleBy(block.position, block.size, scaleFactor)\n }\n\n /**\n * Scale a block around a pivot point.\n */\n scaleAround(ctx: Context, entityId: EntityId, pivot: Vec2, scaleFactor: number): void {\n const block = this.write(ctx, entityId)\n Rect.scaleAround(block.position, block.size, pivot, scaleFactor)\n }\n\n /**\n * Check if an AABB intersects with this block using Separating Axis Theorem.\n * This handles all intersection cases including narrow AABBs that pass through\n * the middle of a rotated block without touching any corners.\n * Optimized to avoid allocations for hot path usage.\n */\n intersectsAabb(ctx: Context, entityId: EntityId, aabb: Aabb): boolean {\n const { position, size, rotateZ } = this.read(ctx, entityId)\n return Rect.intersectsAabb(position, size, rotateZ, aabb, _blockCorners, _aabbCorners, _blockAxes)\n }\n\n worldToUv(ctx: Context, entityId: EntityId, worldPos: Vec2): Vec2 {\n const { position, size, rotateZ, flip } = this.read(ctx, entityId)\n const uv = Rect.worldToUv(position, size, rotateZ, worldPos)\n // Apply flip to UV coordinates\n if (flip[0]) uv[0] = 1 - uv[0]\n if (flip[1]) uv[1] = 1 - uv[1]\n return uv\n }\n\n uvToWorld(ctx: Context, entityId: EntityId, uv: Vec2): Vec2 {\n const { position, size, rotateZ, flip } = this.read(ctx, entityId)\n // Apply flip to UV coordinates before converting to world\n const flippedUv: Vec2 = [flip[0] ? 1 - uv[0] : uv[0], flip[1] ? 1 - uv[1] : uv[1]]\n return Rect.uvToWorld(position, size, rotateZ, flippedUv)\n }\n\n /**\n * Get the UV-to-world transformation matrix for a block.\n * More efficient than multiple uvToWorld() calls since sin/cos is computed once.\n * Use with Mat2.transformPoint() to transform UV coordinates to world.\n * Note: This matrix does NOT account for flip - use uvToWorld() for flipped blocks.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param out - Output matrix to write to [a, b, c, d, tx, ty]\n */\n getUvToWorldMatrix(ctx: Context, entityId: EntityId, out: Mat2): void {\n const { position, size, rotateZ, flip } = this.read(ctx, entityId)\n Rect.getUvToWorldMatrix(position, size, rotateZ, out)\n // Apply flip by negating scale and adjusting translation\n if (flip[0]) {\n out[0] = -out[0] // Negate scaleX\n out[2] = -out[2] // Negate shearX\n out[4] += size[0] * Math.cos(rotateZ) // Adjust tx\n out[5] += size[0] * Math.sin(rotateZ) // Adjust ty\n }\n if (flip[1]) {\n out[1] = -out[1] // Negate shearY\n out[3] = -out[3] // Negate scaleY\n out[4] -= size[1] * Math.sin(rotateZ) // Adjust tx\n out[5] += size[1] * Math.cos(rotateZ) // Adjust ty\n }\n }\n}\n\nexport const Block = new BlockDef()\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Upload state for assets.\n */\nexport const UploadState = {\n /** Asset queued for upload, not yet started */\n Pending: 'pending',\n /** Upload in progress */\n Uploading: 'uploading',\n /** Upload completed successfully */\n Complete: 'complete',\n /** Upload failed */\n Failed: 'failed',\n} as const\n\n/**\n * Asset component - tracks upload state and identifier for binary assets.\n *\n * The identifier is empty until upload completes, at which point it contains\n * the permanent identifier returned by the AssetProvider.\n */\nexport const Asset = defineCanvasComponent(\n { name: 'asset', sync: 'document', excludeFromHistory: ['uploadState'] },\n {\n /** Permanent identifier from AssetProvider (empty until upload complete) */\n identifier: field.string().max(512).default(''),\n /** Current upload state */\n uploadState: field.enum(UploadState).default(UploadState.Pending),\n },\n)\n","import { CanvasComponentDef } from '@woven-ecs/canvas-store'\nimport { type Context, type EntityId, field } from '@woven-ecs/core'\n\nconst ColorSchema = {\n red: field.uint8().default(0),\n green: field.uint8().default(0),\n blue: field.uint8().default(0),\n alpha: field.uint8().default(255),\n}\n\n/**\n * Color component - stores RGBA color values.\n *\n * Each channel is 0-255. Alpha defaults to 255 (fully opaque).\n */\nclass ColorDef extends CanvasComponentDef<typeof ColorSchema> {\n constructor() {\n super({ name: 'color', sync: 'document' }, ColorSchema)\n }\n\n /**\n * Convert a color to a hex string.\n */\n toHex(ctx: Context, entityId: EntityId): string {\n const { red, green, blue, alpha } = this.read(ctx, entityId)\n const rHex = red.toString(16).padStart(2, '0')\n const gHex = green.toString(16).padStart(2, '0')\n const bHex = blue.toString(16).padStart(2, '0')\n const aHex = alpha.toString(16).padStart(2, '0')\n return `#${rHex}${gHex}${bHex}${aHex}`\n }\n\n /**\n * Set color from a hex string.\n */\n fromHex(ctx: Context, entityId: EntityId, hex: string): void {\n const color = this.write(ctx, entityId)\n color.red = Number.parseInt(hex.slice(1, 3), 16)\n color.green = Number.parseInt(hex.slice(3, 5), 16)\n color.blue = Number.parseInt(hex.slice(5, 7), 16)\n color.alpha = hex.length > 7 ? Number.parseInt(hex.slice(7, 9), 16) : 255\n }\n}\n\nexport const Color = new ColorDef()\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Connector component - defines a line/arrow between two blocks.\n *\n * Connectors link two blocks together with optional anchor points.\n * When connected blocks move, the connector endpoints update automatically.\n *\n * - `startBlock`/`endBlock`: Ref to connected blocks (null = free endpoint)\n * - `startBlockUv`/`endBlockUv`: Anchor point on block in UV coords (0-1)\n * - `startUv`/`endUv`: Actual endpoint position as UV coords on this connector's block\n * - `startNeedsUpdate`/`endNeedsUpdate`: Flags to trigger recalculation\n */\nexport const Connector = defineCanvasComponent(\n { name: 'connector', sync: 'document' },\n {\n startBlock: field.ref(),\n startBlockUv: field.tuple(field.float64(), 2).default([0, 0]),\n startUv: field.tuple(field.float64(), 2).default([0, 0]),\n\n endBlock: field.ref(),\n endBlockUv: field.tuple(field.float64(), 2).default([0, 0]),\n endUv: field.tuple(field.float64(), 2).default([1, 1]),\n },\n)\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\n\n/**\n * Edited component - marks an entity as currently being edited.\n *\n * When present, the block is in edit mode (e.g., text editing).\n * The transform box is hidden and click-through is disabled.\n */\nexport const Edited = defineCanvasComponent({ name: 'edited' }, {})\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Held component - marks an entity as being actively held by a user.\n *\n * When a block is selected or being dragged, the Held component is added\n * to indicate that another user should not interact with it. This prevents\n * conflicts when multiple users try to manipulate the same block.\n *\n * The `sessionId` field stores which user is holding this entity.\n * This syncs ephemerally so remote users can see what's being held.\n */\nexport const Held = defineCanvasComponent(\n { name: 'held', sync: 'ephemeral' },\n {\n sessionId: field.string().max(36).default(''),\n },\n)\n","import { type Aabb, Arc, Capsule, Mat2, type Vec2 } from '@woven-canvas/math'\nimport { CanvasComponentDef } from '@woven-ecs/canvas-store'\nimport { type Context, type EntityId, field } from '@woven-ecs/core'\nimport { Block } from './Block'\n\n// Pre-allocated matrix for UV-to-world transforms (avoids allocation in hot paths)\nconst _uvToWorldMatrix: Mat2 = [1, 0, 0, 1, 0, 0]\n\n/**\n * Maximum number of capsules that can be stored in the hitCapsules array.\n * Each capsule takes 5 floats: ax, ay, bx, by, radius\n */\nexport const MAX_HIT_CAPSULES = 64\n\n/**\n * Number of floats per capsule in the hitCapsules array.\n */\nconst FLOATS_PER_CAPSULE = 5\n\n/**\n * Maximum number of arcs that can be stored in the hitArcs array.\n * Each arc takes 7 floats: ax, ay, bx, by, cx, cy, thickness\n */\nexport const MAX_HIT_ARCS = 2\n\n/**\n * Number of floats per arc in the hitArcs array.\n */\nconst FLOATS_PER_ARC = 7\n\nconst HitGeometrySchema = {\n hitCapsules: field.buffer(field.float32()).size(MAX_HIT_CAPSULES * FLOATS_PER_CAPSULE),\n capsuleCount: field.uint16().default(0),\n hitArcs: field.buffer(field.float32()).size(MAX_HIT_ARCS * FLOATS_PER_ARC),\n arcCount: field.uint16().default(0),\n}\n\n/**\n * HitGeometry component - stores collision geometry for an entity in UV coordinates.\n *\n * Geometry positions are stored in UV coordinates (0-1) relative to the entity's Block.\n * UV (0,0) is top-left, (1,1) is bottom-right of the block. This means:\n * - Translating or scaling the block does NOT require updating hit geometry\n * - Rotating the block automatically rotates the hit geometry\n * - Thickness/radius values are in world units (not UV) for visual consistency\n *\n * The hitCapsules buffer stores capsule data as a flat array of floats:\n * [ax0, ay0, bx0, by0, r0, ax1, ay1, bx1, by1, r1, ...]\n *\n * Each capsule is defined by:\n * - ax, ay: First endpoint in UV coordinates (0-1)\n * - bx, by: Second endpoint in UV coordinates (0-1)\n * - radius: The radius in world units\n *\n * Uses field.buffer for zero-allocation subarray views.\n * Used for collision detection with eraser strokes and other tools.\n */\nclass HitGeometryDef extends CanvasComponentDef<typeof HitGeometrySchema> {\n constructor() {\n super({ name: 'hitHeometry' }, HitGeometrySchema)\n }\n\n /**\n * Get a capsule at a specific index from the hitCapsules buffer.\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param index - Index of the capsule (0-based)\n * @returns Capsule tuple [ax, ay, bx, by, radius]\n */\n getCapsuleAt(ctx: Context, entityId: EntityId, index: number): Capsule {\n const hitGeometry = this.read(ctx, entityId)\n const offset = index * FLOATS_PER_CAPSULE\n return [\n hitGeometry.hitCapsules[offset],\n hitGeometry.hitCapsules[offset + 1],\n hitGeometry.hitCapsules[offset + 2],\n hitGeometry.hitCapsules[offset + 3],\n hitGeometry.hitCapsules[offset + 4],\n ]\n }\n\n /**\n * Set a capsule at a specific index in the hitCapsules buffer.\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param index - Index of the capsule (0-based)\n * @param capsule - Capsule tuple [ax, ay, bx, by, radius]\n */\n setCapsuleAt(ctx: Context, entityId: EntityId, index: number, capsule: Capsule): void {\n const hitGeometry = this.write(ctx, entityId)\n const offset = index * FLOATS_PER_CAPSULE\n for (let i = 0; i < FLOATS_PER_CAPSULE; i++) {\n hitGeometry.hitCapsules[offset + i] = capsule[i]\n }\n }\n\n /**\n * Get an arc at a specific index from the hitArcs buffer.\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param index - Index of the arc (0-based)\n * @returns Arc tuple [ax, ay, bx, by, cx, cy, thickness]\n */\n getArcAt(ctx: Context, entityId: EntityId, index: number): Arc {\n const hitGeometry = this.read(ctx, entityId)\n const offset = index * FLOATS_PER_ARC\n return [\n hitGeometry.hitArcs[offset],\n hitGeometry.hitArcs[offset + 1],\n hitGeometry.hitArcs[offset + 2],\n hitGeometry.hitArcs[offset + 3],\n hitGeometry.hitArcs[offset + 4],\n hitGeometry.hitArcs[offset + 5],\n hitGeometry.hitArcs[offset + 6],\n ]\n }\n\n /**\n * Set an arc at a specific index in the hitArcs buffer.\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param index - Index of the arc (0-based)\n * @param arc - Arc tuple [ax, ay, bx, by, cx, cy, thickness]\n */\n setArcAt(ctx: Context, entityId: EntityId, index: number, arc: Arc): void {\n const hitGeometry = this.write(ctx, entityId)\n const offset = index * FLOATS_PER_ARC\n for (let i = 0; i < FLOATS_PER_ARC; i++) {\n hitGeometry.hitArcs[offset + i] = arc[i]\n }\n }\n\n /**\n * Check if a point is inside the entity's hit geometry.\n * Hit geometry is stored in UV coordinates (0-1) relative to the block.\n * This method transforms UV geometry to world space for intersection testing.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param point - Point to test in world coordinates [x, y]\n * @returns True if the point is inside any of the entity's hit capsules or arc\n */\n containsPointWorld(ctx: Context, entityId: EntityId, point: Vec2): boolean {\n const hitGeometry = this.read(ctx, entityId)\n\n // Build UV-to-world matrix once (computes sin/cos once)\n Block.getUvToWorldMatrix(ctx, entityId, _uvToWorldMatrix)\n\n // Check arc intersections (transform UV arcs to world)\n for (let i = 0; i < hitGeometry.arcCount; i++) {\n const uvArc = this.getArcAt(ctx, entityId, i)\n\n // Transform 3 UV points to world using matrix\n const worldA: Vec2 = [uvArc[0], uvArc[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvArc[2], uvArc[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n const worldC: Vec2 = [uvArc[4], uvArc[5]]\n Mat2.transformPoint(_uvToWorldMatrix, worldC)\n\n const thickness = uvArc[6] // Already in world units\n\n const worldArc = Arc.create(worldA[0], worldA[1], worldB[0], worldB[1], worldC[0], worldC[1], thickness)\n\n if (Arc.containsPoint(worldArc, point)) {\n return true\n }\n }\n\n // Check capsule intersections (transform UV capsules to world)\n for (let i = 0; i < hitGeometry.capsuleCount; i++) {\n const uvCapsule = this.getCapsuleAt(ctx, entityId, i)\n\n // Transform 2 UV points to world using matrix\n const worldA: Vec2 = [uvCapsule[0], uvCapsule[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvCapsule[2], uvCapsule[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n\n const radius = uvCapsule[4] // Already in world units\n\n const worldCapsule = Capsule.create(worldA[0], worldA[1], worldB[0], worldB[1], radius)\n\n if (Capsule.containsPoint(worldCapsule, point)) {\n return true\n }\n }\n\n return false\n }\n\n /**\n * Check if an AABB intersects with the entity's hit geometry.\n * Hit geometry is stored in UV coordinates (0-1) relative to the block.\n * This method transforms UV geometry to world space for intersection testing.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param aabb - AABB to test in world coordinates [left, top, right, bottom]\n * @returns True if the AABB intersects any of the entity's hit capsules or arc\n */\n intersectsAabbWorld(ctx: Context, entityId: EntityId, aabb: Aabb): boolean {\n const hitGeometry = this.read(ctx, entityId)\n\n // Build UV-to-world matrix once (computes sin/cos once)\n Block.getUvToWorldMatrix(ctx, entityId, _uvToWorldMatrix)\n\n // Check arc intersections (transform UV arcs to world)\n for (let i = 0; i < hitGeometry.arcCount; i++) {\n const uvArc = this.getArcAt(ctx, entityId, i)\n\n // Transform 3 UV points to world using matrix\n const worldA: Vec2 = [uvArc[0], uvArc[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvArc[2], uvArc[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n const worldC: Vec2 = [uvArc[4], uvArc[5]]\n Mat2.transformPoint(_uvToWorldMatrix, worldC)\n\n const thickness = uvArc[6] // Already in world units\n\n const worldArc = Arc.create(worldA[0], worldA[1], worldB[0], worldB[1], worldC[0], worldC[1], thickness)\n\n if (Arc.intersectsAabb(worldArc, aabb)) {\n return true\n }\n }\n\n // Check capsule intersections (transform UV capsules to world)\n for (let i = 0; i < hitGeometry.capsuleCount; i++) {\n const uvCapsule = this.getCapsuleAt(ctx, entityId, i)\n\n // Transform 2 UV points to world using matrix\n const worldA: Vec2 = [uvCapsule[0], uvCapsule[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvCapsule[2], uvCapsule[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n\n const radius = uvCapsule[4] // Already in world units\n\n const worldCapsule = Capsule.create(worldA[0], worldA[1], worldB[0], worldB[1], radius)\n\n if (Capsule.intersectsAabb(worldCapsule, aabb)) {\n return true\n }\n }\n\n return false\n }\n\n /**\n * Get all extrema points of the hit geometry in world coordinates for AABB computation.\n * Hit geometry is stored in UV coordinates; this transforms them to world space.\n * Returns corner points expanded by radius/thickness for each capsule and arc.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @returns Array of extrema points in world coordinates\n */\n getExtremaWorld(ctx: Context, entityId: EntityId): Vec2[] {\n const hitGeometry = this.read(ctx, entityId)\n const pts: Vec2[] = []\n\n // Build UV-to-world matrix once (computes sin/cos once)\n Block.getUvToWorldMatrix(ctx, entityId, _uvToWorldMatrix)\n\n // Add extrema from capsules (transform UV to world, then compute extrema)\n for (let i = 0; i < hitGeometry.capsuleCount; i++) {\n const uvCapsule = this.getCapsuleAt(ctx, entityId, i)\n\n // Transform 2 UV points to world using matrix\n const worldA: Vec2 = [uvCapsule[0], uvCapsule[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvCapsule[2], uvCapsule[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n\n const radius = uvCapsule[4] // Already in world units\n\n const worldCapsule = Capsule.create(worldA[0], worldA[1], worldB[0], worldB[1], radius)\n pts.push(...Capsule.getExtrema(worldCapsule))\n }\n\n // Add extrema from arcs (transform UV to world, then compute extrema)\n for (let i = 0; i < hitGeometry.arcCount; i++) {\n const uvArc = this.getArcAt(ctx, entityId, i)\n\n // Transform 3 UV points to world using matrix\n const worldA: Vec2 = [uvArc[0], uvArc[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvArc[2], uvArc[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n const worldC: Vec2 = [uvArc[4], uvArc[5]]\n Mat2.transformPoint(_uvToWorldMatrix, worldC)\n\n const thickness = uvArc[6] // Already in world units\n\n const worldArc = Arc.create(worldA[0], worldA[1], worldB[0], worldB[1], worldC[0], worldC[1], thickness)\n pts.push(...Arc.getExtrema(worldArc))\n }\n\n return pts\n }\n\n // ============================================\n // User-facing helper methods for adding hit geometry\n // ============================================\n\n /**\n * Add a capsule from a capsule tuple [ax, ay, bx, by, radius].\n * Positions are in UV coordinates (0-1), radius is in world units.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param capsule - Capsule tuple [ax, ay, bx, by, radius]\n */\n addCapsule(ctx: Context, entityId: EntityId, capsule: Capsule): void {\n const hitGeometry = this.write(ctx, entityId)\n const index = hitGeometry.capsuleCount\n\n if (index >= MAX_HIT_CAPSULES) {\n console.warn(`HitGeometry: Max capsules (${MAX_HIT_CAPSULES}) reached`)\n return\n }\n\n this.setCapsuleAt(ctx, entityId, index, capsule)\n hitGeometry.capsuleCount = index + 1\n }\n\n /**\n * Add a capsule using UV coordinates.\n * UV (0,0) is top-left, (1,1) is bottom-right of the block.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param uvA - First endpoint in UV coordinates [0-1, 0-1]\n * @param uvB - Second endpoint in UV coordinates [0-1, 0-1]\n * @param worldRadius - Radius in world units (pixels)\n */\n addCapsuleUv(ctx: Context, entityId: EntityId, uvA: Vec2, uvB: Vec2, worldRadius: number): void {\n const capsule: Capsule = [uvA[0], uvA[1], uvB[0], uvB[1], worldRadius]\n this.addCapsule(ctx, entityId, capsule)\n }\n\n /**\n * Add a capsule using world coordinates.\n * Automatically converts to UV coordinates relative to the block.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param worldA - First endpoint in world coordinates\n * @param worldB - Second endpoint in world coordinates\n * @param worldRadius - Radius in world units (pixels)\n */\n addCapsuleWorld(ctx: Context, entityId: EntityId, worldA: Vec2, worldB: Vec2, worldRadius: number): void {\n const uvA = Block.worldToUv(ctx, entityId, worldA)\n const uvB = Block.worldToUv(ctx, entityId, worldB)\n this.addCapsuleUv(ctx, entityId, uvA, uvB, worldRadius)\n }\n\n /**\n * Add an arc from an arc tuple [aX, aY, bX, bY, cX, cY, thickness].\n * Positions are in UV coordinates (0-1), thickness is in world units.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param arc - Arc tuple [aX, aY, bX, bY, cX, cY, thickness]\n */\n addArc(ctx: Context, entityId: EntityId, arc: Arc): void {\n const hitGeometry = this.write(ctx, entityId)\n const index = hitGeometry.arcCount\n\n if (index >= MAX_HIT_ARCS) {\n console.warn(`HitGeometry: Max arcs (${MAX_HIT_ARCS}) reached`)\n return\n }\n\n this.setArcAt(ctx, entityId, index, arc)\n hitGeometry.arcCount = index + 1\n }\n\n /**\n * Add an arc using UV coordinates.\n * UV (0,0) is top-left, (1,1) is bottom-right of the block.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param uvA - Start point in UV coordinates\n * @param uvB - Control point in UV coordinates\n * @param uvC - End point in UV coordinates\n * @param worldThickness - Thickness in world units (pixels)\n */\n addArcUv(ctx: Context, entityId: EntityId, uvA: Vec2, uvB: Vec2, uvC: Vec2, worldThickness: number): void {\n const arc: Arc = [uvA[0], uvA[1], uvB[0], uvB[1], uvC[0], uvC[1], worldThickness]\n this.addArc(ctx, entityId, arc)\n }\n\n /**\n * Add an arc using world coordinates.\n * Automatically converts to UV coordinates relative to the block.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n * @param worldA - Start point in world coordinates\n * @param worldB - Control point in world coordinates\n * @param worldC - End point in world coordinates\n * @param worldThickness - Thickness in world units (pixels)\n */\n addArcWorld(\n ctx: Context,\n entityId: EntityId,\n worldA: Vec2,\n worldB: Vec2,\n worldC: Vec2,\n worldThickness: number,\n ): void {\n const uvA = Block.worldToUv(ctx, entityId, worldA)\n const uvB = Block.worldToUv(ctx, entityId, worldB)\n const uvC = Block.worldToUv(ctx, entityId, worldC)\n this.addArcUv(ctx, entityId, uvA, uvB, uvC, worldThickness)\n }\n\n /**\n * Clear all hit geometry from an entity.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID\n */\n clear(ctx: Context, entityId: EntityId): void {\n const hitGeometry = this.write(ctx, entityId)\n hitGeometry.capsuleCount = 0\n hitGeometry.arcCount = 0\n }\n}\n\nexport const HitGeometry = new HitGeometryDef()\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\n\n/**\n * Hovered component - marks an entity as being hovered by the mouse.\n */\nexport const Hovered = defineCanvasComponent({ name: 'hovered' }, {})\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Image component - stores image-specific metadata.\n *\n * Used alongside the Asset component for image blocks.\n * The actual image binary is managed by AssetManager, not stored in ECS.\n */\nexport const Image = defineCanvasComponent(\n { name: 'image', sync: 'document' },\n {\n /** Image width in pixels */\n width: field.uint16().default(0),\n /** Image height in pixels */\n height: field.uint16().default(0),\n /** Alt text for accessibility */\n alt: field.string().max(256).default(''),\n },\n)\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Opacity component - controls visibility of an entity.\n *\n * Value is 0-255 where 0 is fully transparent and 255 is fully opaque.\n * Used to temporarily hide transform boxes and handles during drag operations.\n */\nexport const Opacity = defineCanvasComponent(\n { name: 'opacity' },\n {\n value: field.uint8().default(255),\n },\n)\n","import type { Vec2 } from '@woven-canvas/math'\nimport { CanvasComponentDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\n\n/**\n * Pointer button types\n */\nexport const PointerButton = {\n None: 'none',\n Left: 'left',\n Middle: 'middle',\n Right: 'right',\n Back: 'back',\n Forward: 'forward',\n} as const\n\nexport type PointerButton = (typeof PointerButton)[keyof typeof PointerButton]\n\n/**\n * Pointer type (input device)\n */\nexport const PointerType = {\n Mouse: 'mouse',\n Pen: 'pen',\n Touch: 'touch',\n} as const\n\nexport type PointerType = (typeof PointerType)[keyof typeof PointerType]\n\n/**\n * Number of position samples to keep for velocity calculation\n */\nconst SAMPLE_COUNT = 6\n\nconst PointerSchema = {\n /** Unique pointer ID (from PointerEvent.pointerId) */\n pointerId: field.uint16().default(0),\n /** Current position relative to the editor element [x, y] */\n position: field.tuple(field.float32(), 2).default([0, 0]),\n /** Position where the pointer went down [x, y] */\n downPosition: field.tuple(field.float32(), 2).default([0, 0]),\n /** Frame number when the pointer went down (for click detection) */\n downFrame: field.uint32().default(0),\n /** Which button is pressed */\n button: field.enum(PointerButton).default(PointerButton.None),\n /** Type of pointer device */\n pointerType: field.enum(PointerType).default(PointerType.Mouse),\n /** Pressure from 0 to 1 (for pen/touch) */\n pressure: field.float32().default(0),\n /** Whether the pointer event target was not the editor element */\n obscured: field.boolean().default(false),\n // Velocity tracking (ring buffer for position samples)\n /** Ring buffer of previous positions [x0, y0, x1, y1, ...] @internal */\n _prevPositions: field.array(field.float32(), SAMPLE_COUNT * 2),\n /** Ring buffer of timestamps for each position sample @internal */\n _prevTimes: field.array(field.float32(), SAMPLE_COUNT),\n /** Total number of samples added (used for ring buffer indexing) @internal */\n _sampleCount: field.int32().default(0),\n /** Computed velocity [vx, vy] in pixels per second @internal */\n _velocity: field.tuple(field.float32(), 2).default([0, 0]),\n}\n\n/**\n * Pointer component - represents an active pointer (mouse, touch, or pen).\n *\n * Unlike Mouse (singleton), Pointer is a regular component because touch\n * can have multiple simultaneous pointers. Each pointer entity is created\n * on pointerdown and deleted on pointerup.\n *\n * This component stores position history for smooth velocity calculation\n * using exponentially time-decayed weighted least-squares fitting.\n *\n * Note: This is an internal runtime component using base ComponentDef,\n * not CanvasComponentDef, since it doesn't need sync or a string id.\n */\nclass PointerDef extends CanvasComponentDef<typeof PointerSchema> {\n constructor() {\n super({ name: 'pointer' }, PointerSchema)\n }\n\n /** Get the computed velocity of a pointer */\n getVelocity(ctx: Context, entityId: number): Vec2 {\n const p = this.read(ctx, entityId)\n return [p._velocity[0], p._velocity[1]]\n }\n\n /**\n * Get the pointer button from a PointerEvent button number.\n * @param button - PointerEvent.button value\n * @returns PointerButton enum value\n */\n getButton(button: number): PointerButton {\n switch (button) {\n case 0:\n return PointerButton.Left\n case 1:\n return PointerButton.Middle\n case 2:\n return PointerButton.Right\n case 3:\n return PointerButton.Back\n case 4:\n return PointerButton.Forward\n default:\n return PointerButton.None\n }\n }\n\n /**\n * Get the pointer type from a PointerEvent pointerType string.\n * @param pointerType - PointerEvent.pointerType value\n * @returns PointerType enum value\n */\n getType(pointerType: string): PointerType {\n switch (pointerType) {\n case 'pen':\n return PointerType.Pen\n case 'touch':\n return PointerType.Touch\n default:\n return PointerType.Mouse\n }\n }\n}\n\nexport const Pointer = new PointerDef()\n\n/**\n * Add a position sample and update velocity calculation.\n * Uses exponentially time-decayed weighted least-squares fitting.\n *\n * @param pointer - The writable pointer component\n * @param position - Current position [x, y]\n * @param time - Current time in seconds\n */\nexport function addPointerSample(pointer: ReturnType<typeof Pointer.write>, position: Vec2, time: number): void {\n // Avoid duplicate samples at same time\n const currentIndex = pointer._sampleCount % SAMPLE_COUNT\n const mostRecentTime = pointer._prevTimes[currentIndex] || 0\n if (Math.abs(mostRecentTime - time) < 0.001) return\n\n // Update current position\n pointer.position = position\n\n // Push to ring buffer\n pointer._sampleCount++\n const writeIndex = pointer._sampleCount % SAMPLE_COUNT\n pointer._prevPositions[writeIndex * 2] = position[0]\n pointer._prevPositions[writeIndex * 2 + 1] = position[1]\n pointer._prevTimes[writeIndex] = time\n\n // Calculate velocity using weighted least-squares\n const pointCount = Math.min(pointer._sampleCount, SAMPLE_COUNT)\n if (pointCount <= 1) {\n pointer._velocity = [0, 0]\n return\n }\n\n const mod = (n: number) => ((n % SAMPLE_COUNT) + SAMPLE_COUNT) % SAMPLE_COUNT\n\n // Exponentially time-decayed weighted least-squares fit\n const TAU = 0.04 // seconds, adjust to tune responsiveness vs smoothness\n const EPS = 1e-6\n\n let W = 0\n let WU = 0\n let WUU = 0\n let WX = 0\n let WY = 0\n let WU_X = 0\n let WU_Y = 0\n\n for (let j = 0; j < pointCount; j++) {\n const idx = mod(pointer._sampleCount - pointCount + 1 + j)\n\n const t = pointer._prevTimes[idx] || 0\n const u = t - time\n const recency = -u\n\n if (recency > 5 * TAU) continue\n\n const w = Math.exp(-recency / TAU)\n\n const x = pointer._prevPositions[idx * 2] || 0\n const y = pointer._prevPositions[idx * 2 + 1] || 0\n\n W += w\n WU += w * u\n WUU += w * u * u\n\n WX += w * x\n WY += w * y\n\n WU_X += w * u * x\n WU_Y += w * u * y\n }\n\n const denom = W * WUU - WU * WU\n if (Math.abs(denom) <= EPS) {\n // Fallback: last-segment velocity\n const iCurr = pointer._sampleCount % SAMPLE_COUNT\n const iPrev = mod(pointer._sampleCount - 1)\n const dt = (pointer._prevTimes[iCurr] || 0) - (pointer._prevTimes[iPrev] || 0)\n if (dt > EPS) {\n const dx = (pointer._prevPositions[iCurr * 2] || 0) - (pointer._prevPositions[iPrev * 2] || 0)\n const dy = (pointer._prevPositions[iCurr * 2 + 1] || 0) - (pointer._prevPositions[iPrev * 2 + 1] || 0)\n pointer._velocity = [dx / dt, dy / dt]\n } else {\n pointer._velocity = [0, 0]\n }\n return\n }\n\n const vx = (W * WU_X - WU * WX) / denom\n const vy = (W * WU_Y - WU * WY) / denom\n\n pointer._velocity = [vx, vy]\n}\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * ScaleWithZoom component - marks an entity that should maintain\n * screen-space size when the camera zooms.\n *\n * Used for transform handles so they remain a consistent size\n * regardless of zoom level.\n */\nexport const ScaleWithZoom = defineCanvasComponent(\n { name: 'scaleWithZoom' },\n {\n /** Pivot point for scaling as [x, y] (0-1, default 0.5,0.5 = center) */\n anchor: field.tuple(field.float64(), 2).default([0.5, 0.5]),\n /** Initial position as [left, top] at zoom=1 */\n startPosition: field.tuple(field.float64(), 2).default([0, 0]),\n /** Initial size as [width, height] at zoom=1 */\n startSize: field.tuple(field.float64(), 2).default([0, 0]),\n /** Scale multiplier per dimension: [x, y] (0 = no zoom effect, 1 = full zoom effect, 0.5 = half effect) */\n scaleMultiplier: field.tuple(field.float64(), 2).default([1, 1]),\n },\n)\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Stroke style for shapes.\n */\nexport const StrokeKind = {\n Solid: 'solid',\n Dashed: 'dashed',\n None: 'none',\n} as const\n\nexport type StrokeKind = (typeof StrokeKind)[keyof typeof StrokeKind]\n\n/**\n * Shape component - defines the visual properties of a shape block.\n *\n * Includes shape type, stroke style/color/width, and fill color.\n */\nexport const Shape = defineCanvasComponent(\n { name: 'shape', sync: 'document' },\n {\n /** The kind of shape to render (e.g. 'rectangle', 'ellipse', or custom shape key) */\n kind: field.string().default('rectangle'),\n\n /** Stroke style */\n strokeKind: field.enum(StrokeKind).default(StrokeKind.Solid),\n\n /** Stroke width in pixels */\n strokeWidth: field.uint16().default(2),\n\n /** Stroke color - red component (0-255) */\n strokeRed: field.uint8().default(0),\n\n /** Stroke color - green component (0-255) */\n strokeGreen: field.uint8().default(0),\n\n /** Stroke color - blue component (0-255) */\n strokeBlue: field.uint8().default(0),\n\n /** Stroke color - alpha component (0-255) */\n strokeAlpha: field.uint8().default(255),\n\n /** Fill color - red component (0-255) */\n fillRed: field.uint8().default(255),\n\n /** Fill color - green component (0-255) */\n fillGreen: field.uint8().default(255),\n\n /** Fill color - blue component (0-255) */\n fillBlue: field.uint8().default(255),\n\n /** Fill color - alpha component (0-255) */\n fillAlpha: field.uint8().default(0),\n },\n)\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\nimport { TextAlignment } from '../types'\n\n/**\n * Text component - stores text content and styling for text blocks.\n */\nexport const Text = defineCanvasComponent(\n { name: 'text', sync: 'document' },\n {\n /** HTML content (supports rich text formatting) */\n content: field.string().max(10000).default(''),\n /** Font size in pixels */\n fontSizePx: field.float64().default(24),\n /** Font family name */\n fontFamily: field.string().max(64).default('Figtree'),\n /** Line height multiplier */\n lineHeight: field.float64().default(1.2),\n /** Letter spacing in em units */\n letterSpacingEm: field.float64().default(0),\n /** Whether width is constrained (text wraps) */\n constrainWidth: field.boolean().default(true),\n /** Default text alignment for new paragraphs */\n defaultAlignment: field.enum(TextAlignment).default(TextAlignment.Left),\n },\n)\n","import type { Context, EntityId } from '@woven-ecs/core'\nexport type { Context }\n\nimport type { AnyCanvasComponentDef, AnyCanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { z } from 'zod'\n\nimport type { Editor } from './Editor'\nimport type { EditorSystem } from './EditorSystem'\nimport type { FontFamilyInput } from './FontLoader'\nimport type { EditorPluginInput } from './plugin'\n\n// Re-export EntityId for convenience\nexport type { EntityId }\n\n/**\n * Base resources required by the Editor.\n * Plugins can extend this interface for additional resources.\n *\n * @example\n * ```typescript\n * interface MyPluginResources extends EditorResources {\n * apiClient: ApiClient;\n * }\n * ```\n */\n/**\n * Generate a random user color from a predefined palette.\n */\nfunction generateUserColor(): string {\n const colors = [\n '#f43f5e', // rose\n '#ec4899', // pink\n '#a855f7', // purple\n '#6366f1', // indigo\n '#3b82f6', // blue\n '#0ea5e9', // sky\n '#14b8a6', // teal\n '#22c55e', // green\n '#eab308', // yellow\n '#f97316', // orange\n ]\n return colors[Math.floor(Math.random() * colors.length)]\n}\n\n/**\n * User data for presence tracking.\n */\nexport const UserData = z.object({\n userId: z\n .string()\n .max(36)\n .default(() => crypto.randomUUID()),\n sessionId: z\n .string()\n .max(36)\n .default(() => crypto.randomUUID()),\n color: z.string().max(7).default(generateUserColor),\n name: z.string().max(100).default('Anonymous'),\n avatar: z.string().max(500).default(''),\n})\n\nexport type UserData = z.infer<typeof UserData>\n\nexport type UserDataInput = z.input<typeof UserData>\n\nexport interface EditorResources {\n /**\n * The DOM element to attach input listeners and render output to.\n * This should be the editor's main container or canvas element.\n */\n domElement: HTMLElement\n\n /**\n * Reference to the Editor instance.\n * Use this to spawn commands, subscribe to queries, etc.\n */\n editor: Editor\n\n /**\n * User identity for the current session.\n * Only stores userId and sessionId - other user data (color, name, avatar)\n * should be read from the ECS User component.\n */\n userId: string\n sessionId: string\n\n /**\n * Plugin-specific resources keyed by plugin name.\n * Access via getPluginResources<T>(ctx, pluginName).\n * @internal Populated automatically from plugin.resources\n */\n pluginResources: Record<string, unknown>\n\n /**\n * All registered components keyed by name.\n * Use this for fast component lookup by name (e.g., from snapshots).\n */\n componentsByName: Map<string, AnyCanvasComponentDef>\n\n /**\n * All registered singletons keyed by name.\n * Use this for fast singleton lookup by name.\n */\n singletonsByName: Map<string, AnyCanvasSingletonDef>\n\n /**\n * All registered components keyed by componentId.\n * Use this for component lookup by runtime id (e.g., from events).\n */\n componentsById: Map<number, AnyCanvasComponentDef>\n\n /**\n * All registered singletons keyed by componentId.\n * Use this for singleton lookup by runtime id (e.g., from events).\n */\n singletonsById: Map<number, AnyCanvasSingletonDef>\n}\n\n/**\n * System execution phases.\n *\n * Systems are grouped into 4 phases that execute in order each frame:\n * 1. **input** - Convert raw DOM events to ECS state (keyboard, mouse, pointer, screen)\n * 2. **capture** - Detect targets, compute intersections, process keybinds\n * 3. **update** - Modify document state, process commands\n * 4. **render** - Sync ECS state to output (DOM, canvas)\n *\n * Within each phase, systems are sorted by priority (higher = runs first).\n * Ties are broken by registration order.\n */\nexport type SystemPhase = 'input' | 'capture' | 'update' | 'render'\n\n/**\n * Get plugin-specific resources from the context.\n *\n * @typeParam T - The expected plugin resources type\n * @param ctx - The ECS context\n * @param pluginName - The plugin name to get resources for\n * @returns The plugin resources cast to type T\n *\n * @example\n * ```typescript\n * interface ControlsOptions {\n * zoomSpeed: number;\n * panSpeed: number;\n * }\n *\n * const CanvasControlsPlugin: EditorPlugin<ControlsOptions> = {\n * name: \"controls\",\n * resources: { zoomSpeed: 1.0, panSpeed: 1.0 },\n * // ...\n * };\n *\n * // In a system:\n * function mySystem(ctx: Context) {\n * const opts = getPluginResources<ControlsOptions>(ctx, \"controls\");\n * console.log(opts.zoomSpeed);\n * }\n * ```\n */\nexport function getPluginResources<T>(ctx: Context, pluginName: string): T {\n const resources = ctx.resources as EditorResources\n return resources.pluginResources[pluginName] as T\n}\n\n/**\n * Grid configuration options schema.\n */\nexport const GridOptions = z.object({\n /**\n * Whether grid snapping is enabled.\n * @default true\n */\n enabled: z.boolean().default(true),\n\n /**\n * Whether resized/rotated objects must stay aligned to the grid.\n * If true, objects snap to grid during resize/rotate.\n * If false, objects scale proportionally to the transform box, which may\n * cause them to be unaligned with the grid.\n * @default false\n */\n strict: z.boolean().default(false),\n\n /**\n * Width of each grid column in world units.\n * @default 20\n */\n colWidth: z.number().nonnegative().default(20),\n\n /**\n * Height of each grid row in world units.\n * @default 20\n */\n rowHeight: z.number().nonnegative().default(20),\n\n /**\n * Angular snap increment in radians when grid is enabled.\n * @default Math.PI / 36 (5 degrees)\n */\n snapAngleRad: z\n .number()\n .nonnegative()\n .default(Math.PI / 36),\n\n /**\n * Angular snap increment in radians when shift key is held.\n * @default Math.PI / 12 (15 degrees)\n */\n shiftSnapAngleRad: z\n .number()\n .nonnegative()\n .default(Math.PI / 12),\n})\n\nexport type GridOptions = z.infer<typeof GridOptions>\nexport type GridOptionsInput = z.input<typeof GridOptions>\n\n/**\n * Controls configuration options schema.\n * Maps input methods (mouse buttons, wheel) to tools.\n */\nexport const ControlsOptions = z.object({\n /**\n * Tool activated by left mouse button.\n * @default 'select'\n */\n leftMouseTool: z.string().max(32).default('select'),\n\n /**\n * Tool activated by middle mouse button.\n * @default 'hand'\n */\n middleMouseTool: z.string().max(32).default('hand'),\n\n /**\n * Tool activated by right mouse button.\n * @default 'menu'\n */\n rightMouseTool: z.string().max(32).default('menu'),\n\n /**\n * Tool activated by mouse wheel.\n * @default 'scroll'\n */\n wheelTool: z.string().max(32).default('scroll'),\n\n /**\n * Tool activated by mouse wheel with modifier key held.\n * @default 'zoom'\n */\n modWheelTool: z.string().max(32).default('zoom'),\n})\n\nexport type ControlsOptions = z.infer<typeof ControlsOptions>\nexport type ControlsOptionsInput = z.input<typeof ControlsOptions>\n\n/**\n * Editor configuration options schema.\n */\nexport const EditorOptionsSchema = z.object({\n /**\n * Plugins to load.\n * Plugins are sorted by dependencies automatically.\n */\n plugins: z.array(z.custom<EditorPluginInput>()).default([]),\n\n /**\n * Maximum number of entities.\n * @default 5_000\n */\n maxEntities: z.number().default(5_000),\n\n /**\n * User data for presence tracking.\n * All fields are optional - defaults will be applied.\n */\n user: z.custom<UserDataInput>().default({}),\n\n /**\n * Grid configuration for snap-to-grid behavior.\n * All fields are optional - defaults will be applied.\n */\n grid: z.custom<GridOptionsInput>().default({}),\n\n /**\n * Custom block definitions.\n * Accepts partial block definitions - defaults will be applied automatically.\n */\n blockDefs: z.array(z.custom<BlockDefInput>()).default([]),\n\n /**\n * Keybind definitions for keyboard shortcuts.\n * These map key combinations to plugin commands.\n */\n keybinds: z.array(z.custom<Keybind>()).default([]),\n\n /**\n * Custom cursor definitions.\n * Override default cursors or define new ones for transform operations.\n */\n cursors: z.record(z.string(), z.custom<CursorDef>()).default({}),\n\n /**\n * Custom components to register without creating a plugin.\n */\n components: z.array(z.custom<AnyCanvasComponentDef>()).default([]),\n\n /**\n * Custom singletons to register without creating a plugin.\n */\n singletons: z.array(z.custom<AnyCanvasSingletonDef>()).default([]),\n\n /**\n * Custom systems to register without creating a plugin.\n * Each system specifies its phase and priority.\n */\n systems: z.array(z.custom<EditorSystem>()).default([]),\n\n /**\n * Custom font families to load and make available in the font selector.\n * Fonts will be loaded automatically during editor initialization.\n */\n fonts: z.array(z.custom<FontFamilyInput>()).default([]),\n\n /**\n * If true, keybinds from plugins will be ignored.\n * Use this when you want full control over keybinds.\n */\n omitPluginKeybinds: z.boolean().default(false),\n\n /**\n * If true, cursors from plugins will be ignored.\n * Use this when you want full control over cursors.\n */\n omitPluginCursors: z.boolean().default(false),\n\n /**\n * If true, fonts from plugins will be ignored.\n * Use this when you want full control over fonts.\n */\n omitPluginFonts: z.boolean().default(false),\n\n /**\n * Initial controls configuration.\n * Override default tool mappings for mouse buttons, wheel, etc.\n *\n * @example\n * ```typescript\n * controls: {\n * leftMouseTool: 'pen', // Start with pen tool active\n * middleMouseTool: 'hand', // Middle mouse pans\n * }\n * ```\n */\n controls: z.custom<ControlsOptionsInput>().optional(),\n})\n\nexport type EditorOptionsInput = z.input<typeof EditorOptionsSchema>\n\nexport type EditorOptions = z.infer<typeof EditorOptionsSchema>\n\n/**\n * Keybind definition schema.\n * Maps a key combination to a command.\n */\nexport const Keybind = z.object({\n /** The command to execute when this keybind is triggered */\n command: z.string(),\n /** The key index from the Key constants (e.g., Key.A, Key.Delete) */\n key: z.number(),\n /** Whether the modifier key (Cmd on Mac, Ctrl on Windows) must be held */\n mod: z.boolean().optional(),\n /** Whether the Shift key must be held */\n shift: z.boolean().optional(),\n})\n\nexport type Keybind = z.infer<typeof Keybind>\nexport type KeybindInput = z.input<typeof Keybind>\n\n/**\n * Cursor definition schema.\n * Defines how to generate the cursor SVG at a given rotation.\n */\nexport const CursorDef = z.object({\n /** Function that generates the SVG string for a given rotation angle (in radians) */\n makeSvg: z.function({ input: z.tuple([z.number()]), output: z.string() }),\n /** Hotspot coordinates [x, y] for the cursor */\n hotspot: z.tuple([z.number(), z.number()]),\n /** Base rotation offset applied before the dynamic rotation */\n rotationOffset: z.number(),\n})\n\nexport type CursorDef = z.infer<typeof CursorDef>\n\n/**\n * Map of cursor kind to cursor definition.\n */\nexport type CursorDefMap = Partial<Record<string, CursorDef>>\n\n/**\n * Block resize modes.\n */\nexport type ResizeMode = 'scale' | 'text' | 'free' | 'groupOnly'\n\nexport const VerticalAlignment = {\n Top: 'top',\n Center: 'center',\n Bottom: 'bottom',\n} as const\n\nexport const TextAlignment = {\n Left: 'left',\n Center: 'center',\n Right: 'right',\n Justify: 'justify',\n} as const\n\nexport type TextAlignment = (typeof TextAlignment)[keyof typeof TextAlignment]\n\n/**\n * Block definition edit options schema.\n */\nconst BlockDefEditOptions = z.object({\n canEdit: z.boolean().default(false),\n removeWhenTextEmpty: z.boolean().default(false),\n})\n\n/**\n * Block definition connectors schema.\n * Defines connector terminals for arrows/links.\n */\nconst BlockDefConnectors = z.object({\n /** Whether connectors are enabled for this block type */\n enabled: z.boolean().default(true),\n /** UV coordinates of terminal positions (0-1 range, where [0,0] is top-left) */\n terminals: z.array(z.tuple([z.number(), z.number()])).default([\n [0.5, 0], // top\n [0.5, 1], // bottom\n [0.5, 0.5], // center\n [0, 0.5], // left\n [1, 0.5], // right\n ]),\n})\n\n/**\n * Block definition schema with validation and defaults.\n * Defines how different block types behave (editing, resizing, rotation, etc.)\n */\nexport const Stratum = z.enum(['background', 'content', 'overlay'])\nexport type Stratum = z.infer<typeof Stratum>\n\nexport const BlockDef = z.object({\n tag: z.string(),\n stratum: Stratum.default('content'),\n editOptions: BlockDefEditOptions.default(BlockDefEditOptions.parse({})),\n components: z.array(z.custom<AnyCanvasComponentDef>()).default([]),\n resizeMode: z.enum(['scale', 'text', 'free', 'groupOnly']).default('scale'),\n canRotate: z.boolean().default(true),\n canScale: z.boolean().default(true),\n connectors: BlockDefConnectors.default(BlockDefConnectors.parse({})),\n})\n\n/**\n * Input type for block definitions (what users provide).\n * All fields except `tag` are optional.\n */\nexport type BlockDefInput = z.input<typeof BlockDef>\n\n/**\n * Normalized block definition type (after parsing with defaults applied).\n */\nexport type BlockDef = z.infer<typeof BlockDef>\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * User component - tracks user presence on the canvas.\n *\n * Used to identify who is currently viewing the document.\n */\nexport const User = defineCanvasComponent(\n { name: 'user', sync: 'ephemeral' },\n {\n userId: field.string().max(36),\n sessionId: field.string().max(36),\n color: field.string().max(7),\n name: field.string().max(100),\n avatar: field.string().max(500),\n position: field.tuple(field.float32(), 2).default([0, 0]),\n },\n)\n","import { defineCanvasComponent } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\nimport { VerticalAlignment } from '../types'\n\n/**\n * VerticalAlign component - controls vertical text alignment within a block.\n *\n * Values: \"top\", \"center\", \"bottom\"\n */\nexport const VerticalAlign = defineCanvasComponent(\n { name: 'verticalAlign', sync: 'document' },\n {\n value: field.enum(VerticalAlignment).default(VerticalAlignment.Top),\n },\n)\n","export const PLUGIN_NAME = 'core'\n\nexport const STRATUM_ORDER = {\n background: 0,\n content: 1,\n overlay: 2,\n} as const\n","export { Camera } from './Camera'\n\nexport { Controls } from './Controls'\nexport { Cursor } from './Cursor'\nexport { Frame } from './Frame'\nexport { Grid } from './Grid'\nexport { Intersect } from './Intersect'\nexport { clearBits, codeToIndex, Key, Keyboard, setBit } from './Keyboard'\nexport { Mouse } from './Mouse'\nexport { RankBounds } from './RankBounds'\nexport { ScaleWithZoomState } from './ScaleWithZoomState'\nexport { Screen } from './Screen'\n","import type { Aabb as AabbType, Vec2 } from '@woven-canvas/math'\nimport { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\nimport { Screen } from './Screen'\n\nconst CameraSchema = {\n /** Top position of the camera in world coordinates */\n top: field.float64().default(0),\n /** Left position of the camera in world coordinates */\n left: field.float64().default(0),\n /** Zoom level (1 = 100%, 2 = 200%, 0.5 = 50%) */\n zoom: field.float64().default(1),\n /** Whether the camera viewport intersects any blocks */\n canSeeBlocks: field.boolean().default(true),\n /** Reference to a block that the camera can currently see (for optimization) */\n lastSeenBlock: field.ref(),\n}\n\n/**\n * Camera singleton - tracks the viewport position and zoom in the infinite canvas.\n *\n * The camera defines the visible region of the world:\n * - `left` and `top` define the world coordinates of the top-left corner\n * - `zoom` scales the view (higher = zoomed in, lower = zoomed out)\n *\n * Screen coordinates can be converted to world coordinates using `toWorld()`.\n */\nclass CameraDef extends CanvasSingletonDef<typeof CameraSchema> {\n constructor() {\n super({ name: 'camera', sync: 'local' }, CameraSchema)\n }\n\n /**\n * Convert screen coordinates to world coordinates.\n * @param ctx - ECS context\n * @param screenPos - Position in screen pixels [x, y]\n * @returns Position in world coordinates [x, y]\n */\n toWorld(ctx: Context, screenPos: Vec2): Vec2 {\n const camera = this.read(ctx)\n const worldX = camera.left + screenPos[0] / camera.zoom\n const worldY = camera.top + screenPos[1] / camera.zoom\n return [worldX, worldY]\n }\n\n /**\n * Convert world coordinates to screen coordinates.\n * @param ctx - ECS context\n * @param worldPos - Position in world coordinates [x, y]\n * @returns Position in screen pixels [x, y]\n */\n toScreen(ctx: Context, worldPos: Vec2): Vec2 {\n const camera = this.read(ctx)\n const screenX = (worldPos[0] - camera.left) * camera.zoom\n const screenY = (worldPos[1] - camera.top) * camera.zoom\n return [screenX, screenY]\n }\n\n /**\n * Get the world coordinates of the viewport center.\n * @param ctx - ECS context\n * @returns Center position in world coordinates [x, y]\n */\n getWorldCenter(ctx: Context): Vec2 {\n const camera = this.read(ctx)\n const screen = Screen.read(ctx)\n return [camera.left + screen.width / camera.zoom / 2, camera.top + screen.height / camera.zoom / 2]\n }\n\n /**\n * Get the world-space bounds of the visible viewport.\n * @param ctx - ECS context\n * @returns Bounds as { left, top, right, bottom } in world coordinates\n */\n getWorldBounds(ctx: Context): {\n left: number\n top: number\n right: number\n bottom: number\n } {\n const camera = this.read(ctx)\n const screen = Screen.read(ctx)\n return {\n left: camera.left,\n top: camera.top,\n right: camera.left + screen.width / camera.zoom,\n bottom: camera.top + screen.height / camera.zoom,\n }\n }\n\n /**\n * Get the camera viewport as an AABB tuple [left, top, right, bottom].\n * @param ctx - ECS context\n * @param out - Optional output array to write to (avoids allocation)\n * @returns AABB tuple in world coordinates\n */\n getAabb(ctx: Context, out?: AabbType): AabbType {\n const camera = this.read(ctx)\n const screen = Screen.read(ctx)\n const result: AabbType = out ?? [0, 0, 0, 0]\n result[0] = camera.left\n result[1] = camera.top\n result[2] = camera.left + screen.width / camera.zoom\n result[3] = camera.top + screen.height / camera.zoom\n return result\n }\n}\n\nexport const Camera = new CameraDef()\n","import type { Vec2 } from '@woven-canvas/math'\nimport { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\n\nconst ScreenSchema = {\n /** Width of the editor element in pixels */\n width: field.float64().default(0),\n /** Height of the editor element in pixels */\n height: field.float64().default(0),\n /** Left offset of the editor element relative to the viewport */\n left: field.float64().default(0),\n /** Top offset of the editor element relative to the viewport */\n top: field.float64().default(0),\n}\n\n/**\n * Screen singleton - tracks the editor element's dimensions and position.\n *\n * Updated automatically via ResizeObserver when the element resizes.\n */\nclass ScreenDef extends CanvasSingletonDef<typeof ScreenSchema> {\n constructor() {\n super({ name: 'screen' }, ScreenSchema)\n }\n\n /** Get screen dimensions as [width, height] */\n getSize(ctx: Context): Vec2 {\n const s = this.read(ctx)\n return [s.width, s.height]\n }\n\n /** Get screen position as [left, top] */\n getPosition(ctx: Context): Vec2 {\n const s = this.read(ctx)\n return [s.left, s.top]\n }\n\n /** Get the center point of the screen */\n getCenter(ctx: Context): Vec2 {\n const s = this.read(ctx)\n return [s.left + s.width / 2, s.top + s.height / 2]\n }\n}\n\nexport const Screen = new ScreenDef()\n","import { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\nimport { PointerButton } from '../components'\n\nconst ControlsSchema = {\n /** Tool activated by left mouse button */\n leftMouseTool: field.string().max(32).default('select'),\n /** Tool activated by middle mouse button */\n middleMouseTool: field.string().max(32).default('hand'),\n /** Tool activated by right mouse button */\n rightMouseTool: field.string().max(32).default('menu'),\n /** Tool activated by mouse wheel */\n wheelTool: field.string().max(32).default('scroll'),\n /** Tool activated by mouse wheel with modifier key held */\n modWheelTool: field.string().max(32).default('zoom'),\n /** JSON snapshot of block to place on next click (empty string = no placement active) */\n heldSnapshot: field.string().max(4096).default(''),\n}\n\n/**\n * Controls singleton - maps input methods to tools.\n *\n * This allows applications to define their own tools (select, brush, hand, etc.)\n * and configure which mouse buttons or wheel actions activate them.\n */\nclass ControlsDef extends CanvasSingletonDef<typeof ControlsSchema> {\n constructor() {\n super({ name: 'controls' }, ControlsSchema)\n }\n\n /**\n * Get the pointer buttons that are mapped to the given tools.\n * @param ctx - ECS context\n * @param tools - Tool names to check\n * @returns Array of PointerButton values that activate any of the given tools\n */\n getButtons(ctx: Context, ...tools: string[]): PointerButton[] {\n const controls = this.read(ctx)\n const buttons: PointerButton[] = []\n\n if (tools.includes(controls.leftMouseTool)) {\n buttons.push(PointerButton.Left)\n }\n if (tools.includes(controls.middleMouseTool)) {\n buttons.push(PointerButton.Middle)\n }\n if (tools.includes(controls.rightMouseTool)) {\n buttons.push(PointerButton.Right)\n }\n\n return buttons\n }\n\n /**\n * Check if a wheel tool is active based on modifier key state.\n * @param ctx - ECS context\n * @param tool - Tool name to check\n * @param modDown - Whether the modifier key is held\n * @returns True if the given tool is active for wheel input\n */\n wheelActive(ctx: Context, tool: string, modDown: boolean): boolean {\n const controls = this.read(ctx)\n return (controls.wheelTool === tool && !modDown) || (controls.modWheelTool === tool && modDown)\n }\n}\n\nexport const Controls = new ControlsDef()\n","import { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\n\nconst CursorSchema = {\n /** Base cursor kind (from current tool) */\n cursorKind: field.string().max(64).default('select'),\n /** Base cursor rotation in radians */\n rotation: field.float64().default(0),\n /** Context-specific cursor kind (overrides cursorKind when set, e.g., during drag/hover) */\n contextCursorKind: field.string().max(64).default(''),\n /** Context cursor rotation in radians */\n contextRotation: field.float64().default(0),\n}\n\n/**\n * Cursor singleton - manages the current cursor appearance.\n *\n * Stores cursor kind and rotation, which are resolved to SVG at render time.\n * This allows cursor definitions to be changed dynamically.\n *\n * - `cursorKind`/`rotation`: The default cursor from the active tool\n * - `contextCursorKind`/`contextRotation`: Temporary override cursor (e.g., during drag operations)\n *\n * When contextCursorKind is set, it takes precedence over cursorKind.\n */\nclass CursorDef extends CanvasSingletonDef<typeof CursorSchema> {\n constructor() {\n super({ name: 'cursor' }, CursorSchema)\n }\n\n /**\n * Get the effective cursor kind and rotation (context if set, otherwise base).\n */\n getEffective(ctx: Context): { cursorKind: string; rotation: number } {\n const cursor = this.read(ctx)\n if (cursor.contextCursorKind) {\n return {\n cursorKind: cursor.contextCursorKind,\n rotation: cursor.contextRotation,\n }\n }\n return { cursorKind: cursor.cursorKind, rotation: cursor.rotation }\n }\n\n /**\n * Set the base cursor kind and rotation.\n */\n setCursor(ctx: Context, cursorKind: string, rotation: number = 0): void {\n const cursor = this.write(ctx)\n cursor.cursorKind = cursorKind\n cursor.rotation = rotation\n }\n\n /**\n * Set the context cursor kind and rotation (temporary override).\n */\n setContextCursor(ctx: Context, cursorKind: string, rotation: number = 0): void {\n const cursor = this.write(ctx)\n cursor.contextCursorKind = cursorKind\n cursor.contextRotation = rotation\n }\n\n /**\n * Clear the context cursor.\n */\n clearContextCursor(ctx: Context): void {\n const cursor = this.write(ctx)\n cursor.contextCursorKind = ''\n cursor.contextRotation = 0\n }\n}\n\nexport const Cursor = new CursorDef()\n","import { defineCanvasSingleton } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * Frame singleton - tracks frame timing information.\n *\n * Updated automatically at the start of each tick by the Editor.\n * Use this to access delta time for animations and physics calculations.\n *\n * @example\n * ```typescript\n * const mySystem = defineSystem((ctx) => {\n * const frame = Frame.read(ctx);\n * // Use frame.delta for time-based calculations\n * position += velocity * frame.delta;\n * });\n * ```\n */\nexport const Frame = defineCanvasSingleton(\n { name: 'frame' },\n {\n /** Current frame number (increments each tick) */\n number: field.uint32().default(0),\n /** Time since last frame in seconds */\n delta: field.float64().default(0),\n /** Timestamp of current frame in milliseconds (from performance.now()) */\n time: field.float64().default(0),\n /** Timestamp of previous frame in milliseconds (0 if first frame) */\n lastTime: field.float64().default(0),\n },\n)\n","import type { Vec2 } from '@woven-canvas/math'\nimport { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\n\nconst GridSchema = {\n /** Whether grid snapping is enabled */\n enabled: field.boolean().default(false),\n /** Whether resized/rotated objects must stay aligned to the grid */\n strict: field.boolean().default(false),\n /** Width of each grid column in world units */\n colWidth: field.float64().default(20),\n /** Height of each grid row in world units */\n rowHeight: field.float64().default(20),\n /** Angular snap increment in radians when grid is enabled */\n snapAngleRad: field.float64().default(Math.PI / 36),\n /** Angular snap increment in radians when shift key is held */\n shiftSnapAngleRad: field.float64().default(Math.PI / 12),\n}\n\n/**\n * Grid singleton - controls snap-to-grid behavior for block positioning and resizing.\n *\n * When enabled, blocks will snap to grid positions during:\n * - Dragging/moving blocks\n * - Resizing blocks\n *\n * The grid size is defined by `colWidth` and `rowHeight`.\n */\nclass GridDef extends CanvasSingletonDef<typeof GridSchema> {\n constructor() {\n super({ name: 'grid' }, GridSchema)\n }\n\n /**\n * Snap a position to the grid.\n * @param ctx - ECS context\n * @param position - Position to snap [x, y] (mutated in place)\n */\n snapPosition(ctx: Context, position: Vec2): void {\n const grid = this.read(ctx)\n if (!grid.enabled) return\n\n if (grid.colWidth !== 0) {\n position[0] = Math.round(position[0] / grid.colWidth) * grid.colWidth\n }\n if (grid.rowHeight !== 0) {\n position[1] = Math.round(position[1] / grid.rowHeight) * grid.rowHeight\n }\n }\n\n /**\n * Snap a size to the grid (minimum one grid cell).\n * @param ctx - ECS context\n * @param size - Size to snap [width, height] (mutated in place)\n */\n snapSize(ctx: Context, size: Vec2): void {\n const grid = this.read(ctx)\n if (!grid.enabled) return\n\n if (grid.colWidth !== 0) {\n size[0] = Math.max(grid.colWidth, Math.round(size[0] / grid.colWidth) * grid.colWidth)\n }\n if (grid.rowHeight !== 0) {\n size[1] = Math.max(grid.rowHeight, Math.round(size[1] / grid.rowHeight) * grid.rowHeight)\n }\n }\n\n /**\n * Snap a value to the grid column width.\n * @param ctx - ECS context\n * @param value - Value to snap\n * @returns Snapped value, or original if grid disabled\n */\n snapX(ctx: Context, value: number): number {\n const grid = this.read(ctx)\n if (!grid.enabled || grid.colWidth === 0) return value\n\n return Math.round(value / grid.colWidth) * grid.colWidth\n }\n\n /**\n * Snap a value to the grid row height.\n * @param ctx - ECS context\n * @param value - Value to snap\n * @returns Snapped value, or original if grid disabled\n */\n snapY(ctx: Context, value: number): number {\n const grid = this.read(ctx)\n if (!grid.enabled || grid.rowHeight === 0) return value\n\n return Math.round(value / grid.rowHeight) * grid.rowHeight\n }\n}\n\nexport const Grid = new GridDef()\n","import { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, type EntityId, field } from '@woven-ecs/core'\n\nconst IntersectSchema = {\n // Store up to 5 intersected entity IDs\n entity1: field.ref(),\n entity2: field.ref(),\n entity3: field.ref(),\n entity4: field.ref(),\n entity5: field.ref(),\n}\n\n/**\n * Intersect singleton - stores the entities currently under the mouse cursor.\n *\n * Updated by the intersect system when the mouse moves.\n * Entities are stored in z-order (top to bottom).\n */\nclass IntersectDef extends CanvasSingletonDef<typeof IntersectSchema> {\n constructor() {\n super({ name: 'intersect' }, IntersectSchema)\n }\n\n /**\n * Get the topmost intersected entity.\n */\n getTop(ctx: Context): EntityId | null {\n return this.read(ctx).entity1\n }\n\n /**\n * Get all intersected entities as an array.\n */\n getAll(ctx: Context): EntityId[] {\n const intersect = this.read(ctx)\n const result: EntityId[] = []\n\n if (intersect.entity1 !== null) result.push(intersect.entity1)\n if (intersect.entity2 !== null) result.push(intersect.entity2)\n if (intersect.entity3 !== null) result.push(intersect.entity3)\n if (intersect.entity4 !== null) result.push(intersect.entity4)\n if (intersect.entity5 !== null) result.push(intersect.entity5)\n\n return result\n }\n\n /**\n * Set intersected entities from an array.\n */\n setAll(ctx: Context, entities: EntityId[]): void {\n const intersect = this.write(ctx)\n intersect.entity1 = entities[0] ?? null\n intersect.entity2 = entities[1] ?? null\n intersect.entity3 = entities[2] ?? null\n intersect.entity4 = entities[3] ?? null\n intersect.entity5 = entities[4] ?? null\n }\n\n /**\n * Clear all intersections.\n */\n clear(ctx: Context): void {\n const intersect = this.write(ctx)\n intersect.entity1 = null\n intersect.entity2 = null\n intersect.entity3 = null\n intersect.entity4 = null\n intersect.entity5 = null\n }\n}\n\nexport const Intersect = new IntersectDef()\n","import { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\n\n/** Buffer size for key states (32 bytes = 256 bits = covers all keycodes) */\nconst KEY_BUFFER_SIZE = 32\n\nconst KeyboardSchema = {\n /**\n * Buffer where each bit represents whether a key is currently pressed.\n * Uses field.buffer for zero-allocation subarray views.\n */\n keysDown: field.buffer(field.uint8()).size(KEY_BUFFER_SIZE),\n /**\n * Buffer for key-down triggers (true for exactly 1 frame when key is pressed).\n * Uses field.buffer for zero-allocation subarray views.\n */\n keysDownTrigger: field.buffer(field.uint8()).size(KEY_BUFFER_SIZE),\n /**\n * Buffer for key-up triggers (true for exactly 1 frame when key is released).\n * Uses field.buffer for zero-allocation subarray views.\n */\n keysUpTrigger: field.buffer(field.uint8()).size(KEY_BUFFER_SIZE),\n /** Common modifier - Shift key is down */\n shiftDown: field.boolean().default(false),\n /** Common modifier - Alt/Option key is down */\n altDown: field.boolean().default(false),\n /** Common modifier - Ctrl (Windows/Linux) or Cmd (Mac) is down */\n modDown: field.boolean().default(false),\n}\n\n/**\n * Get a bit from a buffer field.\n * @internal\n */\nfunction getBit(buffer: ArrayLike<number>, bitIndex: number): boolean {\n if (bitIndex < 0 || bitIndex >= buffer.length * 8) return false\n const byteIndex = Math.floor(bitIndex / 8)\n const bitOffset = bitIndex % 8\n return (buffer[byteIndex] & (1 << bitOffset)) !== 0\n}\n\n/**\n * Keyboard singleton - tracks keyboard state using binary fields for efficiency.\n *\n * Instead of having a separate boolean field for each key, we use binary fields\n * where each bit represents a key state. This is more memory-efficient and\n * allows tracking all possible keys.\n */\nclass KeyboardDef extends CanvasSingletonDef<typeof KeyboardSchema> {\n constructor() {\n super({ name: 'keyboard' }, KeyboardSchema)\n }\n\n /**\n * Check if a key is currently pressed.\n * @param ctx - Editor context\n * @param key - The key index to check (use Key.A, Key.Space, etc.)\n */\n isKeyDown(ctx: Context, key: number): boolean {\n return getBit(this.read(ctx).keysDown, key)\n }\n\n /**\n * Check if a key was just pressed this frame.\n * @param ctx - Editor context\n * @param key - The key index to check (use Key.A, Key.Space, etc.)\n */\n isKeyDownTrigger(ctx: Context, key: number): boolean {\n return getBit(this.read(ctx).keysDownTrigger, key)\n }\n\n /**\n * Check if a key was just released this frame.\n * @param ctx - Editor context\n * @param key - The key index to check (use Key.A, Key.Space, etc.)\n */\n isKeyUpTrigger(ctx: Context, key: number): boolean {\n return getBit(this.read(ctx).keysUpTrigger, key)\n }\n}\n\nexport const Keyboard = new KeyboardDef()\n\n/**\n * Set a bit in a buffer field.\n * @internal\n */\nexport function setBit(buffer: { [index: number]: number; length: number }, bitIndex: number, value: boolean): void {\n if (bitIndex < 0 || bitIndex >= buffer.length * 8) return\n const byteIndex = Math.floor(bitIndex / 8)\n const bitOffset = bitIndex % 8\n if (value) {\n buffer[byteIndex] |= 1 << bitOffset\n } else {\n buffer[byteIndex] &= ~(1 << bitOffset)\n }\n}\n\n/**\n * Clear all bits in a buffer field.\n * @internal\n */\nexport function clearBits(buffer: { [index: number]: number; length: number }): void {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = 0\n }\n}\n\n/**\n * Mapping from event.code strings to bit indices.\n * Using event.code instead of event.keyCode for layout-independent key detection.\n * @internal\n */\nexport const codeToIndex: Record<string, number> = {\n // Letters (0-25)\n KeyA: 0,\n KeyB: 1,\n KeyC: 2,\n KeyD: 3,\n KeyE: 4,\n KeyF: 5,\n KeyG: 6,\n KeyH: 7,\n KeyI: 8,\n KeyJ: 9,\n KeyK: 10,\n KeyL: 11,\n KeyM: 12,\n KeyN: 13,\n KeyO: 14,\n KeyP: 15,\n KeyQ: 16,\n KeyR: 17,\n KeyS: 18,\n KeyT: 19,\n KeyU: 20,\n KeyV: 21,\n KeyW: 22,\n KeyX: 23,\n KeyY: 24,\n KeyZ: 25,\n\n // Numbers (26-35)\n Digit0: 26,\n Digit1: 27,\n Digit2: 28,\n Digit3: 29,\n Digit4: 30,\n Digit5: 31,\n Digit6: 32,\n Digit7: 33,\n Digit8: 34,\n Digit9: 35,\n\n // Function keys (36-47)\n F1: 36,\n F2: 37,\n F3: 38,\n F4: 39,\n F5: 40,\n F6: 41,\n F7: 42,\n F8: 43,\n F9: 44,\n F10: 45,\n F11: 46,\n F12: 47,\n\n // Modifiers (48-51)\n ShiftLeft: 48,\n ShiftRight: 49,\n ControlLeft: 50,\n ControlRight: 51,\n AltLeft: 52,\n AltRight: 53,\n MetaLeft: 54,\n MetaRight: 55,\n\n // Navigation (56-71)\n Escape: 56,\n Space: 57,\n Enter: 58,\n Tab: 59,\n Backspace: 60,\n Delete: 61,\n ArrowLeft: 62,\n ArrowUp: 63,\n ArrowRight: 64,\n ArrowDown: 65,\n Home: 66,\n End: 67,\n PageUp: 68,\n PageDown: 69,\n Insert: 70,\n\n // Punctuation (72-83)\n Semicolon: 72,\n Equal: 73,\n Comma: 74,\n Minus: 75,\n Period: 76,\n Slash: 77,\n Backquote: 78,\n BracketLeft: 79,\n Backslash: 80,\n BracketRight: 81,\n Quote: 82,\n\n // Numpad (84-99)\n Numpad0: 84,\n Numpad1: 85,\n Numpad2: 86,\n Numpad3: 87,\n Numpad4: 88,\n Numpad5: 89,\n Numpad6: 90,\n Numpad7: 91,\n Numpad8: 92,\n Numpad9: 93,\n NumpadAdd: 94,\n NumpadSubtract: 95,\n NumpadMultiply: 96,\n NumpadDivide: 97,\n NumpadDecimal: 98,\n NumpadEnter: 99,\n}\n\n/**\n * Key codes for use with Keyboard.isKeyDown(), isKeyDownTrigger(), isKeyUpTrigger().\n * These are numeric indices into the bit array, mapped from physical key positions (event.code).\n */\nexport const Key = {\n // Letters\n A: codeToIndex.KeyA,\n B: codeToIndex.KeyB,\n C: codeToIndex.KeyC,\n D: codeToIndex.KeyD,\n E: codeToIndex.KeyE,\n F: codeToIndex.KeyF,\n G: codeToIndex.KeyG,\n H: codeToIndex.KeyH,\n I: codeToIndex.KeyI,\n J: codeToIndex.KeyJ,\n K: codeToIndex.KeyK,\n L: codeToIndex.KeyL,\n M: codeToIndex.KeyM,\n N: codeToIndex.KeyN,\n O: codeToIndex.KeyO,\n P: codeToIndex.KeyP,\n Q: codeToIndex.KeyQ,\n R: codeToIndex.KeyR,\n S: codeToIndex.KeyS,\n T: codeToIndex.KeyT,\n U: codeToIndex.KeyU,\n V: codeToIndex.KeyV,\n W: codeToIndex.KeyW,\n X: codeToIndex.KeyX,\n Y: codeToIndex.KeyY,\n Z: codeToIndex.KeyZ,\n\n // Numbers\n Digit0: codeToIndex.Digit0,\n Digit1: codeToIndex.Digit1,\n Digit2: codeToIndex.Digit2,\n Digit3: codeToIndex.Digit3,\n Digit4: codeToIndex.Digit4,\n Digit5: codeToIndex.Digit5,\n Digit6: codeToIndex.Digit6,\n Digit7: codeToIndex.Digit7,\n Digit8: codeToIndex.Digit8,\n Digit9: codeToIndex.Digit9,\n\n // Function keys\n F1: codeToIndex.F1,\n F2: codeToIndex.F2,\n F3: codeToIndex.F3,\n F4: codeToIndex.F4,\n F5: codeToIndex.F5,\n F6: codeToIndex.F6,\n F7: codeToIndex.F7,\n F8: codeToIndex.F8,\n F9: codeToIndex.F9,\n F10: codeToIndex.F10,\n F11: codeToIndex.F11,\n F12: codeToIndex.F12,\n\n // Modifiers\n ShiftLeft: codeToIndex.ShiftLeft,\n ShiftRight: codeToIndex.ShiftRight,\n ControlLeft: codeToIndex.ControlLeft,\n ControlRight: codeToIndex.ControlRight,\n AltLeft: codeToIndex.AltLeft,\n AltRight: codeToIndex.AltRight,\n MetaLeft: codeToIndex.MetaLeft,\n MetaRight: codeToIndex.MetaRight,\n\n // Navigation\n Escape: codeToIndex.Escape,\n Space: codeToIndex.Space,\n Enter: codeToIndex.Enter,\n Tab: codeToIndex.Tab,\n Backspace: codeToIndex.Backspace,\n Delete: codeToIndex.Delete,\n ArrowLeft: codeToIndex.ArrowLeft,\n ArrowUp: codeToIndex.ArrowUp,\n ArrowRight: codeToIndex.ArrowRight,\n ArrowDown: codeToIndex.ArrowDown,\n Home: codeToIndex.Home,\n End: codeToIndex.End,\n PageUp: codeToIndex.PageUp,\n PageDown: codeToIndex.PageDown,\n Insert: codeToIndex.Insert,\n\n // Punctuation\n Semicolon: codeToIndex.Semicolon,\n Equal: codeToIndex.Equal,\n Comma: codeToIndex.Comma,\n Minus: codeToIndex.Minus,\n Period: codeToIndex.Period,\n Slash: codeToIndex.Slash,\n Backquote: codeToIndex.Backquote,\n BracketLeft: codeToIndex.BracketLeft,\n Backslash: codeToIndex.Backslash,\n BracketRight: codeToIndex.BracketRight,\n Quote: codeToIndex.Quote,\n\n // Numpad\n Numpad0: codeToIndex.Numpad0,\n Numpad1: codeToIndex.Numpad1,\n Numpad2: codeToIndex.Numpad2,\n Numpad3: codeToIndex.Numpad3,\n Numpad4: codeToIndex.Numpad4,\n Numpad5: codeToIndex.Numpad5,\n Numpad6: codeToIndex.Numpad6,\n Numpad7: codeToIndex.Numpad7,\n Numpad8: codeToIndex.Numpad8,\n Numpad9: codeToIndex.Numpad9,\n NumpadAdd: codeToIndex.NumpadAdd,\n NumpadSubtract: codeToIndex.NumpadSubtract,\n NumpadMultiply: codeToIndex.NumpadMultiply,\n NumpadDivide: codeToIndex.NumpadDivide,\n NumpadDecimal: codeToIndex.NumpadDecimal,\n NumpadEnter: codeToIndex.NumpadEnter,\n} as const\n\nexport type Key = (typeof Key)[keyof typeof Key]\n","import type { Vec2 } from '@woven-canvas/math'\nimport { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\n\nconst MouseSchema = {\n /** Current mouse position relative to the editor element [x, y] */\n position: field.tuple(field.float32(), 2).default([0, 0]),\n /** Horizontal wheel delta (positive = scroll right) */\n wheelDeltaX: field.float32().default(0),\n /** Vertical wheel delta (positive = scroll down), normalized across browsers */\n wheelDeltaY: field.float32().default(0),\n /** True for 1 frame when mouse moves */\n moveTrigger: field.boolean().default(false),\n /** True for 1 frame when wheel is scrolled */\n wheelTrigger: field.boolean().default(false),\n /** True for 1 frame when mouse enters the editor element */\n enterTrigger: field.boolean().default(false),\n /** True for 1 frame when mouse leaves the editor element */\n leaveTrigger: field.boolean().default(false),\n}\n\n/**\n * Mouse singleton - tracks mouse position and wheel events.\n *\n * Position is relative to the editor's DOM element (not the viewport).\n * Triggers are true for exactly 1 frame after the event occurs.\n */\nclass MouseDef extends CanvasSingletonDef<typeof MouseSchema> {\n constructor() {\n super({ name: 'mouse' }, MouseSchema)\n }\n\n /** Check if mouse moved this frame */\n didMove(ctx: Context): boolean {\n return this.read(ctx).moveTrigger\n }\n\n /** Check if wheel was scrolled this frame */\n didScroll(ctx: Context): boolean {\n return this.read(ctx).wheelTrigger\n }\n\n /** Check if mouse entered the editor element this frame */\n didEnter(ctx: Context): boolean {\n return this.read(ctx).enterTrigger\n }\n\n /** Check if mouse left the editor element this frame */\n didLeave(ctx: Context): boolean {\n return this.read(ctx).leaveTrigger\n }\n\n /** Get current mouse position as [x, y] */\n getPosition(ctx: Context): Vec2 {\n const m = this.read(ctx)\n return [m.position[0], m.position[1]]\n }\n\n /** Get wheel delta as [dx, dy] */\n getWheelDelta(ctx: Context): Vec2 {\n const m = this.read(ctx)\n return [m.wheelDeltaX, m.wheelDeltaY]\n }\n}\n\nexport const Mouse = new MouseDef()\n","import { CanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport { type Context, field } from '@woven-ecs/core'\nimport { generateJitteredKeyBetween } from 'fractional-indexing-jittered'\n\nconst RankBoundsSchema = {\n minRank: field.string().max(36).default(''),\n maxRank: field.string().max(36).default(''),\n}\n\n/**\n * RankBounds singleton - tracks the min and max z-order ranks in the document.\n *\n * Used to generate new ranks when creating blocks that should be\n * at the top or bottom of the z-order.\n */\nclass RankBoundsDef extends CanvasSingletonDef<typeof RankBoundsSchema> {\n constructor() {\n super({ name: 'rankBounds' }, RankBoundsSchema)\n }\n\n /**\n * Generate the next rank (higher z-order than all existing).\n * @returns A new rank string that sorts after maxRank\n */\n genNext(ctx: Context): string {\n const bounds = this.write(ctx)\n\n // Generate key after current max (or first key if empty)\n const next = generateJitteredKeyBetween(bounds.maxRank || null, null)\n bounds.maxRank = next\n\n // If this is the first key, also set minRank\n if (!bounds.minRank) {\n bounds.minRank = next\n }\n\n return next\n }\n\n /**\n * Generate the previous rank (lower z-order than all existing).\n * @returns A new rank string that sorts before minRank\n */\n genPrev(ctx: Context): string {\n const bounds = this.write(ctx)\n\n // Generate key before current min (or first key if empty)\n const prev = generateJitteredKeyBetween(null, bounds.minRank || null)\n bounds.minRank = prev\n\n // If this is the first key, also set maxRank\n if (!bounds.maxRank) {\n bounds.maxRank = prev\n }\n\n return prev\n }\n\n /**\n * Generate a rank between two existing ranks.\n * @param before - Rank to come after (or null for start)\n * @param after - Rank to come before (or null for end)\n * @returns A new rank string that sorts between the two\n */\n genBetween(before: string | null, after: string | null): string {\n return generateJitteredKeyBetween(before, after)\n }\n\n /**\n * Add a rank to tracking (expands bounds if needed).\n */\n add(ctx: Context, rank: string): void {\n if (!rank) return\n\n const bounds = this.write(ctx)\n\n if (!bounds.minRank || rank < bounds.minRank) {\n bounds.minRank = rank\n }\n\n if (!bounds.maxRank || rank > bounds.maxRank) {\n bounds.maxRank = rank\n }\n }\n}\n\nexport const RankBounds = new RankBoundsDef()\n","import { defineCanvasSingleton } from '@woven-ecs/canvas-store'\nimport { field } from '@woven-ecs/core'\n\n/**\n * ScaleWithZoomState singleton - tracks state for the ScaleWithZoom system.\n *\n * Stores the last zoom level so the system can detect when zoom changes\n * and update all ScaleWithZoom entities accordingly.\n */\nexport const ScaleWithZoomState = defineCanvasSingleton(\n { name: 'scaleWithZoomState' },\n {\n /** Last processed zoom level */\n lastZoom: field.float64().default(1),\n },\n)\n","import { addComponent, type Context, createEntity, getResources } from '@woven-ecs/core'\nimport { CommandMarker } from '../../command'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Keyboard } from '../../singletons'\nimport type { EditorResources } from '../../types'\n\n/**\n * Keybind capture system - handles keybind-to-command mapping.\n *\n * Listens for keyboard input and spawns commands based on\n * the plugin's keybind configuration.\n */\nexport const keybindSystem = defineEditorSystem({ phase: 'capture' }, (ctx: Context) => {\n const keyboard = Keyboard.read(ctx)\n const { editor } = getResources<EditorResources>(ctx)\n\n for (const keybind of editor.keybinds) {\n // Check if key was just pressed\n let triggered = Keyboard.isKeyDownTrigger(ctx, keybind.key)\n\n // Check modifier keys\n triggered &&= !!keybind.mod === keyboard.modDown\n triggered &&= !!keybind.shift === keyboard.shiftDown\n\n if (triggered) {\n // Spawn the command by name\n const eid = createEntity(ctx)\n addComponent(ctx, eid, CommandMarker, { name: keybind.command })\n\n break\n }\n }\n})\n","import {\n addComponent,\n type Context,\n createEntity,\n defineComponent,\n defineQuery,\n type EntityId,\n field,\n getResources,\n removeEntity,\n} from '@woven-ecs/core'\nimport type { Editor } from './Editor'\nimport type { EditorResources } from './types'\n\n/**\n * Marker component for all command entities.\n * Commands are ephemeral entities that exist for exactly one frame.\n */\nexport const CommandMarker = defineComponent({\n name: field.string().max(128),\n})\n\n/**\n * Per-editor command payload storage.\n * Uses WeakMap keyed by Editor instance for world isolation and automatic cleanup.\n */\nconst editorPayloads = new WeakMap<Editor, Map<EntityId, unknown>>()\n\n/** Get or create the payload map for an editor */\nfunction getPayloadMap(ctx: Context): Map<EntityId, unknown> {\n const { editor } = getResources<EditorResources>(ctx)\n let map = editorPayloads.get(editor)\n if (!map) {\n map = new Map()\n editorPayloads.set(editor, map)\n }\n return map\n}\n\n// Query for commands - we filter by name in iter()\nconst commands = defineQuery((q) => q.with(CommandMarker))\n\n/**\n * Command definition - provides typed spawn() and iteration.\n *\n * @typeParam T - The payload type for this command\n */\nexport interface CommandDef<T> {\n /** Unique command name */\n readonly name: string\n\n /**\n * Spawn a command entity with the given payload.\n * The command will be available to systems this frame and cleaned up at frame end.\n *\n * @param ctx - Editor context\n * @param payload - Command payload data\n * @returns Entity ID of the spawned command\n */\n spawn(ctx: Context, payload: T): EntityId\n\n /**\n * Iterate over commands of this type spawned this frame.\n * Use this in systems to react to commands.\n *\n * @param ctx - Editor context\n * @returns Iterable of command entities with their payloads\n */\n iter(ctx: Context): IterableIterator<{ eid: EntityId; payload: T }>\n\n /**\n * Check if this command was spawned in the previous frame.\n * Useful for testing - checks the removed query for commands cleaned up last frame.\n *\n * @param ctx - Editor context\n * @returns True if at least one command of this type was spawned last frame\n */\n didSpawnLastFrame(ctx: Context): boolean\n}\n\n/**\n * Define a command type with a typed payload.\n *\n * Commands are ephemeral entities that exist for exactly one frame.\n * External code spawns commands via `editor.command()`, and systems\n * react to them by iterating with `CommandDef.iter()`.\n *\n * @typeParam T - The payload type (use `void` for commands with no data)\n * @param name - Human-readable command name for debugging\n * @returns A CommandDef for spawning and iterating commands\n *\n * @example\n * ```typescript\n * // Define commands with typed payloads\n * const SelectAll = defineCommand<{ filter?: string }>(\"select-all\");\n * const Undo = defineCommand<void>(\"undo\");\n *\n * // Spawn from external code\n * editor.command(SelectAll, { filter: \"blocks\" });\n * editor.command(Undo);\n *\n * // React in a system\n * defineSystem(\"update\", (ctx) => {\n * for (const { payload } of SelectAll.iter(ctx)) {\n * selectAllBlocks(ctx, payload.filter);\n * }\n *\n * for (const _ of Undo.iter(ctx)) {\n * performUndo(ctx);\n * }\n * });\n * ```\n */\nexport function defineCommand<T = void>(name: string): CommandDef<T> {\n return {\n name,\n\n spawn(ctx: Context, payload: T): EntityId {\n const eid = createEntity(ctx)\n addComponent(ctx, eid, CommandMarker, { name })\n getPayloadMap(ctx).set(eid, payload)\n\n // console.log(\n // `Spawned command \"${name}\" with eid ${eid} and payload:`,\n // payload,\n // );\n return eid\n },\n\n *iter(ctx: Context): IterableIterator<{ eid: EntityId; payload: T }> {\n const payloads = getPayloadMap(ctx)\n for (const eid of commands.current(ctx)) {\n const marker = CommandMarker.read(ctx, eid)\n if (marker.name === name) {\n const payload = payloads.get(eid) as T\n yield { eid, payload }\n }\n }\n },\n\n didSpawnLastFrame(ctx: Context): boolean {\n for (const eid of commands.removed(ctx)) {\n const marker = CommandMarker.read(ctx, eid)\n if (marker.name === name) {\n return true\n }\n }\n return false\n },\n }\n}\n\n/**\n * Clean up all command entities and their payloads.\n * Called automatically at the end of each frame.\n *\n * @internal\n */\nexport function cleanupCommands(ctx: Context): void {\n const payloads = getPayloadMap(ctx)\n for (const eid of commands.current(ctx)) {\n payloads.delete(eid)\n removeEntity(ctx, eid)\n }\n}\n\n/**\n * Execute a handler for each command of a given type spawned this frame.\n *\n * This is a convenience helper that iterates over commands and calls\n * the handler for each one. Use this to reduce boilerplate in systems.\n *\n * @param ctx - Editor context\n * @param def - The command definition to listen for\n * @param handler - Function to call for each command\n *\n * @example\n * ```typescript\n * defineSystem((ctx) => {\n * on(ctx, SelectAll, (ctx, payload) => {\n * selectAllBlocks(ctx, payload.filter);\n * });\n *\n * on(ctx, Undo, (ctx) => {\n * performUndo(ctx);\n * });\n * });\n * ```\n */\nexport function on<T>(ctx: Context, def: CommandDef<T>, handler: (ctx: Context, payload: T) => void): void {\n for (const { payload } of def.iter(ctx)) {\n handler(ctx, payload)\n }\n}\n\n/**\n * Undo command - triggers an undo operation on the store.\n * Only executes if the store supports undo and canUndo() returns true.\n */\nexport const Undo = defineCommand<void>('undo')\n\n/**\n * Redo command - triggers a redo operation on the store.\n * Only executes if the store supports redo and canRedo() returns true.\n */\nexport const Redo = defineCommand<void>('redo')\n","import type { Context } from '@woven-ecs/core'\nimport { MainThreadSystem } from '@woven-ecs/core'\n\nimport type { SystemPhase } from './types'\n\n/**\n * Editor system execution function.\n */\nexport type EditorSystemFunction = (ctx: Context) => void\n\n/**\n * Default priority for systems.\n * Systems with higher priority run first within a phase.\n */\nexport const DEFAULT_PRIORITY = 0\n\n/**\n * Editor system with phase and priority.\n *\n * Systems are grouped by phase and sorted by priority within each phase.\n * Higher priority means the system runs earlier in the phase.\n * Ties are broken by registration order (plugin order, then system order within plugin)\n * using JavaScript's stable sort.\n */\nexport interface EditorSystem {\n /** Wrapped ECS system for world.execute() compatibility */\n readonly _system: MainThreadSystem\n /** Execution phase */\n readonly phase: SystemPhase\n /** Priority within phase (higher = runs first). Default: 0 */\n readonly priority: number\n}\n\n/**\n * Options for defining an editor system.\n */\nexport interface EditorSystemOptions {\n /** Execution phase */\n phase: SystemPhase\n /** Priority within phase (higher = runs first). Default: 0 */\n priority?: number\n}\n\n/**\n * Define an editor system with phase and priority.\n *\n * Systems are grouped by phase and sorted by priority within each phase.\n * Higher priority means the system runs earlier in the phase.\n *\n * @param options - System options including phase and optional priority\n * @param execute - System execution function\n * @returns EditorSystem instance\n *\n * @example\n * ```typescript\n * // Basic system in update phase\n * const mySystem = defineEditorSystem(\n * { phase: \"update\" },\n * (ctx) => {\n * // System logic here\n * }\n * );\n *\n * // High priority system that runs early in render phase\n * const earlyRenderSystem = defineEditorSystem(\n * { phase: \"render\", priority: 100 },\n * (ctx) => {\n * // Runs before other render systems\n * }\n * );\n *\n * // Low priority system that runs late in render phase\n * const lateRenderSystem = defineEditorSystem(\n * { phase: \"render\", priority: -100 },\n * (ctx) => {\n * // Runs after other render systems\n * }\n * );\n * ```\n */\nexport function defineEditorSystem(options: EditorSystemOptions, execute: EditorSystemFunction): EditorSystem {\n return {\n _system: new MainThreadSystem(execute),\n phase: options.phase,\n priority: options.priority ?? DEFAULT_PRIORITY,\n }\n}\n","import { defineEditorSystem } from '../../EditorSystem'\nimport { Frame } from '../../singletons'\n\n/**\n * Frame system - updates frame timing at the start of each tick.\n *\n * This system runs first in the input phase (priority: 100) to ensure\n * frame.delta is available to all other systems.\n */\nexport const frameSystem = defineEditorSystem({ phase: 'input', priority: 100 }, (ctx) => {\n const now = performance.now()\n const buffer = Frame._getInstance(ctx).buffer\n const last = buffer.lastTime[0]\n\n buffer.number[0]++\n buffer.lastTime[0] = now\n buffer.time[0] = now\n\n if (last === 0) {\n // First frame, assume 16ms (60fps)\n buffer.delta[0] = 0.016\n } else {\n // Convert to seconds, clamp to reasonable range (max 100ms)\n buffer.delta[0] = Math.min((now - last) / 1000, 0.1)\n }\n})\n","import { type Context, getResources } from '@woven-ecs/core'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { codeToIndex, Keyboard, setBit } from '../../singletons/Keyboard'\nimport type { EditorResources } from '../../types'\n\n/**\n * Per-instance state for keyboard input\n */\ninterface KeyboardState {\n eventsBuffer: KeyboardEvent[]\n onKeyDown: (e: KeyboardEvent) => void\n onKeyUp: (e: KeyboardEvent) => void\n onBlur: () => void\n // Reusable buffers to avoid allocation each frame\n keysDown: Uint8Array\n keysDownTrigger: Uint8Array\n keysUpTrigger: Uint8Array\n}\n\n/**\n * Per-instance state keyed by DOM element\n */\nconst instanceState = new WeakMap<HTMLElement, KeyboardState>()\n\n/**\n * Attach keyboard event listeners.\n * Called from plugin setup.\n */\nexport function attachKeyboardListeners(domElement: HTMLElement): void {\n if (instanceState.has(domElement)) return\n\n // Make element focusable if not already\n if (!domElement.hasAttribute('tabindex')) {\n domElement.setAttribute('tabindex', '0')\n }\n\n const state: KeyboardState = {\n eventsBuffer: [],\n onKeyDown: (e: KeyboardEvent) => {\n // Prevent default for certain keys that interfere with canvas interaction\n if (e.key === 'Tab' || e.key === 'Alt' || e.key === ' ') {\n e.preventDefault()\n }\n state.eventsBuffer.push(e)\n },\n onKeyUp: (e: KeyboardEvent) => {\n state.eventsBuffer.push(e)\n },\n onBlur: () => {\n // Create a synthetic event to signal blur\n state.eventsBuffer.push({ type: 'blur' } as unknown as KeyboardEvent)\n },\n // Reusable buffers - allocated once per instance\n keysDown: new Uint8Array(32),\n keysDownTrigger: new Uint8Array(32),\n keysUpTrigger: new Uint8Array(32),\n }\n\n instanceState.set(domElement, state)\n\n domElement.addEventListener('keydown', state.onKeyDown)\n domElement.addEventListener('keyup', state.onKeyUp)\n domElement.addEventListener('blur', state.onBlur)\n}\n\n/**\n * Detach keyboard event listeners.\n * Called from plugin teardown.\n */\nexport function detachKeyboardListeners(domElement: HTMLElement): void {\n const state = instanceState.get(domElement)\n\n if (!state) return\n\n domElement.removeEventListener('keydown', state.onKeyDown)\n domElement.removeEventListener('keyup', state.onKeyUp)\n domElement.removeEventListener('blur', state.onBlur)\n\n instanceState.delete(domElement)\n}\n\n/**\n * Keyboard system - converts keyboard events to ECS state.\n *\n * Processes buffered keyboard events and updates the Keyboard singleton:\n * - Sets bits in keysDown for pressed keys\n * - Sets bits in keysDownTrigger for newly pressed keys (1 frame)\n * - Sets bits in keysUpTrigger for released keys (1 frame)\n * - Updates modifier booleans (shiftDown, altDown, modDown)\n */\nexport const keyboardSystem = defineEditorSystem({ phase: 'input' }, (ctx: Context) => {\n const resources = getResources<EditorResources>(ctx)\n const state = instanceState.get(resources.domElement)\n if (!state) return\n\n const hasEvents = state.eventsBuffer.length > 0\n\n // Check if triggers need to be cleared from previous frame\n const triggersNeedClearing = !isZeroed(state.keysDownTrigger) || !isZeroed(state.keysUpTrigger)\n\n // Only write if there are events or triggers need clearing\n if (!hasEvents && !triggersNeedClearing) return\n\n const keyboard = Keyboard.write(ctx)\n\n const keysDown = state.keysDown\n const keysDownTrigger = state.keysDownTrigger\n const keysUpTrigger = state.keysUpTrigger\n\n keysDownTrigger.fill(0)\n keysUpTrigger.fill(0)\n keysDown.set(keyboard.keysDown)\n\n // Process buffered events\n for (const event of state.eventsBuffer) {\n if (event.type === 'blur') {\n // Reset all keys on blur\n keysDown.fill(0)\n keyboard.shiftDown = false\n keyboard.altDown = false\n keyboard.modDown = false\n continue\n }\n\n const keyIndex = codeToIndex[event.code]\n if (keyIndex === undefined) continue // Unknown key, skip\n\n if (event.type === 'keydown') {\n // Check if this is a new press (wasn't down before)\n const wasDown = getBit(keysDown, keyIndex)\n if (!wasDown) {\n setBit(keysDownTrigger, keyIndex, true)\n }\n\n setBit(keysDown, keyIndex, true)\n } else if (event.type === 'keyup') {\n setBit(keysDown, keyIndex, false)\n setBit(keysUpTrigger, keyIndex, true)\n }\n\n // Update modifier state from the event\n keyboard.shiftDown = event.shiftKey\n keyboard.altDown = event.altKey\n keyboard.modDown = event.ctrlKey || event.metaKey\n }\n\n // Write back the modified buffers\n keyboard.keysDown = keysDown\n keyboard.keysDownTrigger = keysDownTrigger\n keyboard.keysUpTrigger = keysUpTrigger\n\n // Clear buffer\n state.eventsBuffer.length = 0\n})\n\n/**\n * Get a bit from a binary field.\n * @internal\n */\nfunction getBit(buffer: Uint8Array, bitIndex: number): boolean {\n if (bitIndex < 0 || bitIndex >= buffer.length * 8) return false\n const byteIndex = Math.floor(bitIndex / 8)\n const bitOffset = bitIndex % 8\n return (buffer[byteIndex] & (1 << bitOffset)) !== 0\n}\n\n/**\n * Check if a buffer is all zeros.\n * @internal\n */\nfunction isZeroed(buffer: Uint8Array): boolean {\n for (let i = 0; i < buffer.length; i++) {\n if (buffer[i] !== 0) return false\n }\n return true\n}\n","import { type Context, getResources } from '@woven-ecs/core'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Mouse } from '../../singletons/Mouse'\nimport { Screen } from '../../singletons/Screen'\nimport type { EditorResources } from '../../types'\n\n/**\n * Event types we track\n */\ntype MouseEventType = 'mousemove' | 'wheel' | 'mouseenter' | 'mouseleave'\n\ninterface BufferedMouseEvent {\n type: MouseEventType\n clientX?: number\n clientY?: number\n deltaX?: number\n deltaY?: number\n deltaMode?: number\n}\n\n/**\n * Per-instance state for mouse input\n */\ninterface MouseState {\n eventsBuffer: BufferedMouseEvent[]\n onMouseMove: (e: MouseEvent) => void\n onWheel: (e: WheelEvent) => void\n onMouseEnter: () => void\n onMouseLeave: () => void\n}\n\n/**\n * Per-instance state keyed by DOM element\n */\nconst instanceState = new WeakMap<HTMLElement, MouseState>()\n\n/**\n * Attach mouse event listeners.\n * Called from plugin setup.\n */\nexport function attachMouseListeners(domElement: HTMLElement): void {\n if (instanceState.has(domElement)) return\n\n const state: MouseState = {\n eventsBuffer: [],\n onMouseMove: (e: MouseEvent) => {\n state.eventsBuffer.push({\n type: 'mousemove',\n clientX: e.clientX,\n clientY: e.clientY,\n })\n },\n onWheel: (e: WheelEvent) => {\n e.preventDefault()\n state.eventsBuffer.push({\n type: 'wheel',\n clientX: e.clientX,\n clientY: e.clientY,\n deltaX: e.deltaX,\n deltaY: e.deltaY,\n deltaMode: e.deltaMode,\n })\n },\n onMouseEnter: () => {\n state.eventsBuffer.push({ type: 'mouseenter' })\n },\n onMouseLeave: () => {\n state.eventsBuffer.push({ type: 'mouseleave' })\n },\n }\n\n instanceState.set(domElement, state)\n\n // Attach listeners - mousemove on window to track even outside element\n window.addEventListener('mousemove', state.onMouseMove)\n domElement.addEventListener('wheel', state.onWheel, { passive: false })\n domElement.addEventListener('mouseenter', state.onMouseEnter)\n domElement.addEventListener('mouseleave', state.onMouseLeave)\n}\n\n/**\n * Detach mouse event listeners.\n * Called from plugin teardown.\n */\nexport function detachMouseListeners(domElement: HTMLElement): void {\n const state = instanceState.get(domElement)\n\n if (!state) return\n\n window.removeEventListener('mousemove', state.onMouseMove)\n domElement.removeEventListener('wheel', state.onWheel)\n domElement.removeEventListener('mouseenter', state.onMouseEnter)\n domElement.removeEventListener('mouseleave', state.onMouseLeave)\n\n instanceState.delete(domElement)\n}\n\n/**\n * Mouse system - converts mouse events to ECS state.\n *\n * Updates the Mouse singleton with:\n * - Current position (relative to editor element)\n * - Wheel deltas (normalized across browsers)\n * - Triggers for move, wheel, enter, leave events\n */\nexport const mouseSystem = defineEditorSystem({ phase: 'input' }, (ctx: Context) => {\n const resources = getResources<EditorResources>(ctx)\n const state = instanceState.get(resources.domElement)\n if (!state) return\n\n const currentMouse = Mouse.read(ctx)\n const hadTriggers =\n currentMouse.moveTrigger || currentMouse.wheelTrigger || currentMouse.enterTrigger || currentMouse.leaveTrigger\n const hasEvents = state.eventsBuffer.length > 0\n\n // Only write if we need to clear previous triggers or process new events\n if (!hadTriggers && !hasEvents) return\n\n const mouse = Mouse.write(ctx)\n const screen = Screen.read(ctx)\n\n // Clear triggers from previous frame\n mouse.moveTrigger = false\n mouse.wheelTrigger = false\n mouse.enterTrigger = false\n mouse.leaveTrigger = false\n mouse.wheelDeltaX = 0\n mouse.wheelDeltaY = 0\n\n // Process buffered events\n for (const event of state.eventsBuffer) {\n switch (event.type) {\n case 'mousemove':\n // Convert to element-relative coordinates\n mouse.position = [event.clientX! - screen.left, event.clientY! - screen.top]\n mouse.moveTrigger = true\n break\n\n case 'wheel':\n mouse.wheelDeltaX = event.deltaX!\n mouse.wheelDeltaY = normalizeWheelDelta(event.deltaY!, event.deltaMode!)\n mouse.wheelTrigger = true\n\n break\n\n case 'mouseenter':\n mouse.enterTrigger = true\n break\n\n case 'mouseleave':\n mouse.leaveTrigger = true\n break\n }\n }\n\n // Clear buffer\n state.eventsBuffer.length = 0\n})\n\n/**\n * Normalize wheel deltaY across browsers and delta modes.\n * @param deltaY - Raw deltaY from WheelEvent\n * @param deltaMode - WheelEvent.deltaMode (0=pixel, 1=line, 2=page)\n * @returns Normalized delta in pixels\n */\nfunction normalizeWheelDelta(deltaY: number, deltaMode: number): number {\n const LINE_HEIGHT = 16\n const PAGE_HEIGHT = typeof window !== 'undefined' ? window.innerHeight : 800\n\n let normalized = deltaY\n\n // Convert based on deltaMode\n if (deltaMode === 1) {\n // Line mode\n normalized *= LINE_HEIGHT\n } else if (deltaMode === 2) {\n // Page mode\n normalized *= PAGE_HEIGHT\n }\n\n // Firefox adjustment\n if (typeof navigator !== 'undefined' && navigator.userAgent.includes('Firefox')) {\n normalized *= 4\n }\n\n // macOS adjustment\n if (\n typeof navigator !== 'undefined' &&\n (navigator.userAgent.includes('Mac') || navigator.userAgent.includes('Macintosh'))\n ) {\n normalized *= 1.5\n }\n\n // Clamp to reasonable range\n return Math.min(Math.max(normalized, -100), 100)\n}\n","import type { Vec2 } from '@woven-canvas/math'\nimport { addComponent, type Context, createEntity, getResources, removeEntity } from '@woven-ecs/core'\nimport { addPointerSample, Pointer } from '../../components/Pointer'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Screen } from '../../singletons/Screen'\nimport type { EditorResources } from '../../types'\n\n/**\n * Buffered pointer event\n */\ninterface BufferedPointerEvent {\n type: 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel'\n pointerId: number\n clientX: number\n clientY: number\n button: number\n pointerType: string\n pressure: number\n target: EventTarget | null\n}\n\n/**\n * Per-instance state for pointer input\n */\ninterface PointerState {\n eventsBuffer: BufferedPointerEvent[]\n frameCount: number\n /** Maps pointerId -> entityId for this instance */\n pointerEntityMap: Map<number, number>\n onPointerDown: (e: PointerEvent) => void\n onContextMenu: (e: MouseEvent) => void\n onPointerMove: (e: PointerEvent) => void\n onPointerUp: (e: PointerEvent) => void\n onPointerCancel: (e: PointerEvent) => void\n}\n\n/**\n * Per-instance state keyed by DOM element\n */\nconst instanceState = new WeakMap<HTMLElement, PointerState>()\n\n/**\n * Attach pointer event listeners.\n * Called from plugin setup.\n */\nexport function attachPointerListeners(domElement: HTMLElement): void {\n if (instanceState.has(domElement)) return\n\n const state: PointerState = {\n eventsBuffer: [],\n frameCount: 0,\n pointerEntityMap: new Map(),\n onPointerDown: (e: PointerEvent) => {\n state.eventsBuffer.push({\n type: 'pointerdown',\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n button: e.button,\n pointerType: e.pointerType,\n pressure: e.pressure,\n target: e.target,\n })\n },\n onContextMenu: (e: MouseEvent) => {\n e.preventDefault()\n\n // Check if there's already a pointerdown in the buffer for this frame\n const hasPointerDown = state.eventsBuffer.some((evt) => evt.type === 'pointerdown')\n if (hasPointerDown) return\n\n // Create a synthetic pointer event for right-click\n state.eventsBuffer.push({\n type: 'pointerdown',\n pointerId: 0,\n clientX: e.clientX,\n clientY: e.clientY,\n button: 2, // Right button\n pointerType: 'mouse',\n pressure: 0.5,\n target: e.target,\n })\n },\n onPointerMove: (e: PointerEvent) => {\n state.eventsBuffer.push({\n type: 'pointermove',\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n button: e.button,\n pointerType: e.pointerType,\n pressure: e.pressure,\n target: e.target,\n })\n },\n onPointerUp: (e: PointerEvent) => {\n state.eventsBuffer.push({\n type: 'pointerup',\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n button: e.button,\n pointerType: e.pointerType,\n pressure: e.pressure,\n target: e.target,\n })\n },\n onPointerCancel: (e: PointerEvent) => {\n state.eventsBuffer.push({\n type: 'pointercancel',\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n button: e.button,\n pointerType: e.pointerType,\n pressure: e.pressure,\n target: e.target,\n })\n },\n }\n\n instanceState.set(domElement, state)\n\n // Pointer down and context menu on element only\n domElement.addEventListener('pointerdown', state.onPointerDown)\n domElement.addEventListener('contextmenu', state.onContextMenu)\n\n // Move, up, cancel on window to capture outside movement\n window.addEventListener('pointermove', state.onPointerMove)\n window.addEventListener('pointerup', state.onPointerUp)\n window.addEventListener('pointercancel', state.onPointerCancel)\n}\n\n/**\n * Detach pointer event listeners.\n * Called from plugin teardown.\n */\nexport function detachPointerListeners(domElement: HTMLElement): void {\n const state = instanceState.get(domElement)\n\n if (!state) return\n\n domElement.removeEventListener('pointerdown', state.onPointerDown)\n domElement.removeEventListener('contextmenu', state.onContextMenu)\n window.removeEventListener('pointermove', state.onPointerMove)\n window.removeEventListener('pointerup', state.onPointerUp)\n window.removeEventListener('pointercancel', state.onPointerCancel)\n\n instanceState.delete(domElement)\n}\n\n/**\n * Pointer system - manages pointer entities for touch/pen/mouse.\n *\n * Creates a Pointer entity on pointerdown and deletes it on pointerup.\n * This allows multiple simultaneous pointers (for touch).\n */\nexport const pointerSystem = defineEditorSystem({ phase: 'input' }, (ctx: Context) => {\n const resources = getResources<EditorResources>(ctx)\n const { domElement } = resources\n const state = instanceState.get(domElement)\n if (!state) return\n\n state.frameCount++\n const screen = Screen.read(ctx)\n const time = state.frameCount / 60 // Approximate time in seconds\n\n // Process buffered events\n for (const event of state.eventsBuffer) {\n switch (event.type) {\n case 'pointerdown': {\n const position: Vec2 = [event.clientX - screen.left, event.clientY - screen.top]\n\n // Create pointer entity\n const entityId = createEntity(ctx)\n addComponent(ctx, entityId, Pointer, {\n pointerId: event.pointerId,\n position: position,\n downPosition: position,\n downFrame: state.frameCount,\n button: Pointer.getButton(event.button),\n pointerType: Pointer.getType(event.pointerType),\n pressure: event.pressure,\n obscured: event.target !== domElement,\n })\n\n // Add initial position sample\n const pointer = Pointer.write(ctx, entityId)\n addPointerSample(pointer, position, time)\n\n // Track in map\n state.pointerEntityMap.set(event.pointerId, entityId)\n break\n }\n\n case 'pointermove': {\n const entityId = state.pointerEntityMap.get(event.pointerId)\n if (entityId === undefined) break\n\n const position: Vec2 = [event.clientX - screen.left, event.clientY - screen.top]\n\n const pointer = Pointer.write(ctx, entityId)\n addPointerSample(pointer, position, time)\n pointer.pressure = event.pressure\n pointer.obscured = event.target !== domElement\n break\n }\n\n case 'pointerup':\n case 'pointercancel': {\n const entityId = state.pointerEntityMap.get(event.pointerId)\n if (entityId === undefined) break\n\n // Update final position before removal\n const position: Vec2 = [event.clientX - screen.left, event.clientY - screen.top]\n\n const pointer = Pointer.write(ctx, entityId)\n addPointerSample(pointer, position, time)\n\n // Remove entity\n removeEntity(ctx, entityId)\n state.pointerEntityMap.delete(event.pointerId)\n\n break\n }\n }\n }\n\n // Clear buffer\n state.eventsBuffer.length = 0\n})\n","import { getResources } from '@woven-ecs/core'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Frame, Screen } from '../../singletons'\nimport type { EditorResources } from '../../types'\n\n/**\n * Per-instance state for screen input\n */\ninterface ScreenState {\n needsUpdate: boolean\n resizeObserver: ResizeObserver\n onScroll: () => void\n}\n\n/**\n * Per-instance state keyed by DOM element\n */\nconst instanceState = new WeakMap<HTMLElement, ScreenState>()\n\n/**\n * Attach screen resize observer.\n * Called from plugin setup.\n */\nexport function attachScreenObserver(domElement: HTMLElement): void {\n if (instanceState.has(domElement)) return\n\n const state: ScreenState = {\n needsUpdate: false,\n resizeObserver: new ResizeObserver(() => {\n state.needsUpdate = true\n }),\n onScroll: () => {\n state.needsUpdate = true\n },\n }\n\n instanceState.set(domElement, state)\n state.resizeObserver.observe(domElement)\n window.addEventListener('scroll', state.onScroll, true)\n}\n\n/**\n * Detach screen resize observer.\n * Called from plugin teardown.\n */\nexport function detachScreenObserver(domElement: HTMLElement): void {\n const state = instanceState.get(domElement)\n\n if (!state) return\n\n state.resizeObserver.disconnect()\n window.removeEventListener('scroll', state.onScroll, true)\n instanceState.delete(domElement)\n}\n\n/**\n * Screen system - tracks editor element dimensions.\n *\n * Uses ResizeObserver to detect size changes and updates the Screen singleton.\n * Also handles initial sizing on the first frame.\n */\nexport const screenSystem = defineEditorSystem({ phase: 'input' }, (ctx) => {\n const resources = getResources<EditorResources>(ctx)\n const { domElement } = resources\n const state = instanceState.get(domElement)\n if (!state) return\n\n const frame = Frame.read(ctx)\n\n // Handle initial sizing on first frame\n if (frame.number === 1) {\n state.needsUpdate = true\n }\n\n if (!state.needsUpdate) return\n\n const screen = Screen.write(ctx)\n const rect = domElement.getBoundingClientRect()\n\n screen.left = rect.left\n screen.top = rect.top\n screen.width = rect.width\n screen.height = rect.height\n\n state.needsUpdate = false\n})\n","import { type Context, defineQuery, getResources } from '@woven-ecs/core'\n\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Cursor, Frame } from '../../singletons'\nimport type { CursorDef, EditorResources } from '../../types'\n\nconst cursorQuery = defineQuery((q) => q.tracking(Cursor))\n\n/**\n * Get a cursor CSS value for a given cursor kind and rotation.\n * @param cursors - The cursor definitions map (from resources)\n * @param kind - The cursor kind\n * @param rotateZ - The rotation angle in radians\n * @returns CSS cursor value string\n */\nexport function getCursorSvg(cursors: Record<string, CursorDef>, kind: string, rotateZ: number): string {\n const def = cursors[kind]\n if (!def) return 'auto'\n\n const svg = def.makeSvg(rotateZ + def.rotationOffset)\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg.trim())}\") ${def.hotspot[0]} ${def.hotspot[1]}, auto`\n}\n\n/**\n * Post-render cursor system - applies the current cursor to the DOM.\n *\n * Runs late in the render phase (priority: -100) to update document.body.style.cursor based on:\n * 1. contextCursorKind (hover/drag cursor) - highest priority\n * 2. cursorKind (tool cursor) - medium priority\n * 3. Default cursor - fallback\n *\n * Resolves cursor kind + rotation to SVG using getCursorSvg at render time,\n * allowing cursor definitions to be changed dynamically.\n */\nexport const cursorSystem = defineEditorSystem({ phase: 'render', priority: -100 }, (ctx: Context) => {\n const changedCursors = cursorQuery.changed(ctx)\n\n const frame = Frame.read(ctx)\n\n // If no cursor changes, skip updating DOM\n if (changedCursors.length === 0 && frame.number !== 1) {\n return\n }\n\n const { cursorKind, rotation } = Cursor.getEffective(ctx)\n\n // If no cursor kind set, use default\n if (!cursorKind) {\n document.body.style.cursor = 'default'\n return\n }\n\n // Get cursors from resources and resolve to SVG\n const { editor } = getResources<EditorResources>(ctx)\n const cursorValue = getCursorSvg(editor.cursors, cursorKind, rotation)\n\n // Apply to DOM\n document.body.style.cursor = cursorValue\n})\n","import { type Context, defineQuery } from '@woven-ecs/core'\nimport { Pointer, User } from '../../components'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { getMyUserEntityId } from '../../helpers'\nimport { Camera, Mouse } from '../../singletons'\n\nconst pointerQuery = defineQuery((q) => q.tracking(Pointer))\n\nexport const presenceSystem = defineEditorSystem({ phase: 'render', priority: -100 }, (ctx: Context) => {\n // Update user position based on mouse input\n if (Mouse.didMove(ctx)) {\n const mouse = Mouse.read(ctx)\n updateUserPosition(ctx, mouse.position)\n return\n }\n\n // for mobile we use pointer input to update user position\n const changedPointers = pointerQuery.changed(ctx)\n if (changedPointers.length === 0) return\n\n const pointers = pointerQuery.current(ctx)\n\n let mainPointerEid: number | null = null\n let lowestId = Number.MAX_SAFE_INTEGER\n\n for (const eid of pointers) {\n const pointer = Pointer.read(ctx, eid)\n if (pointer.pointerId < lowestId) {\n lowestId = pointer.pointerId\n mainPointerEid = eid\n }\n }\n\n const pointer = Pointer.read(ctx, mainPointerEid!)\n updateUserPosition(ctx, pointer.position)\n})\n\nfunction updateUserPosition(ctx: Context, position: [number, number]): void {\n const myUserEid = getMyUserEntityId(ctx)\n if (myUserEid === null) return\n\n const user = User.write(ctx, myUserEid)\n user.position = Camera.toWorld(ctx, position)\n}\n","import { type Context, getResources } from '@woven-ecs/core'\n\nimport { BlockDef, type EditorResources } from '../types'\n\n/**\n * Get all block definitions from the editor resources.\n *\n * @param ctx - The ECS context\n * @returns Map of block tag to normalized block definition\n */\nexport function getBlockDefs(ctx: Context): Record<string, BlockDef> {\n const { editor } = getResources<EditorResources>(ctx)\n return editor.blockDefs\n}\n\n/**\n * Get a block definition by tag.\n * Returns a default definition if the tag is not registered.\n *\n * @param ctx - The ECS context\n * @param tag - The block tag to look up\n * @returns Normalized block definition\n */\nexport function getBlockDef(ctx: Context, tag: string): BlockDef {\n const blockDefs = getBlockDefs(ctx)\n return blockDefs[tag] ?? BlockDef.parse({ tag })\n}\n\n/**\n * Check if a block definition allows editing.\n *\n * @param ctx - The ECS context\n * @param tag - The block tag to check\n * @returns True if the block can be edited\n */\nexport function canBlockEdit(ctx: Context, tag: string): boolean {\n return getBlockDef(ctx, tag).editOptions.canEdit\n}\n\n/**\n * Check if a block definition allows rotation.\n *\n * @param ctx - The ECS context\n * @param tag - The block tag to check\n * @returns True if the block can be rotated\n */\nexport function canBlockRotate(ctx: Context, tag: string): boolean {\n return getBlockDef(ctx, tag).canRotate\n}\n\n/**\n * Check if a block definition allows scaling.\n *\n * @param ctx - The ECS context\n * @param tag - The block tag to check\n * @returns True if the block can be scaled\n */\nexport function canBlockScale(ctx: Context, tag: string): boolean {\n return getBlockDef(ctx, tag).canScale\n}\n","import { Aabb } from '@woven-canvas/math'\nimport { type Context, type EntityId, hasComponent } from '@woven-ecs/core'\nimport { Block } from '../components/Block'\nimport { HitGeometry } from '../components/HitGeometry'\n\n/**\n * Compute AABB from block or hit geometry.\n * If the entity has HitGeometry, computes AABB spanning all hit geometries.\n * Otherwise, computes AABB from block corners.\n *\n * @param ctx - ECS context\n * @param entityId - Entity ID with Block component\n * @param out - Output AABB tuple to write to\n */\nexport function computeAabb(ctx: Context, entityId: EntityId, out: Aabb): void {\n if (hasComponent(ctx, entityId, HitGeometry)) {\n const pts = HitGeometry.getExtremaWorld(ctx, entityId)\n Aabb.setFromPoints(out, pts)\n } else {\n const corners = Block.getCorners(ctx, entityId)\n Aabb.setFromPoints(out, corners)\n }\n}\n","import { type Context, type EntityId, getResources, hasComponent } from '@woven-ecs/core'\nimport { Held } from '../components/Held'\nimport type { EditorResources } from '../types'\n\n/**\n * Check if a block is held by a remote user (not the current session).\n *\n * @param ctx - The ECS context\n * @param entityId - The entity to check\n * @returns True if the block is held by another user\n */\nexport function isHeldByRemote(ctx: Context, entityId: EntityId): boolean {\n if (!hasComponent(ctx, entityId, Held)) return false\n\n const { sessionId } = getResources<EditorResources>(ctx)\n const held = Held.read(ctx, entityId)\n return held.sessionId !== '' && held.sessionId !== sessionId\n}\n","import { Aabb, type Vec2 } from '@woven-canvas/math'\nimport { type Context, defineQuery, type EntityId, hasComponent } from '@woven-ecs/core'\nimport { Aabb as AabbComp } from '../components/Aabb'\nimport { Block } from '../components/Block'\nimport { HitGeometry } from '../components/HitGeometry'\nimport { STRATUM_ORDER } from '../constants'\nimport { getBlockDef } from './blockDefs'\n\n// Query for all blocks with Aabb\nconst blocksWithAabb = defineQuery((q) => q.with(Block, AabbComp))\n\n/**\n * Find all blocks that contain a point, sorted by z-order (topmost first).\n *\n * Uses AABB for fast rejection, then precise rotated block intersection.\n *\n * @param ctx - ECS context\n * @param point - Point to test in world coordinates [x, y]\n * @param entityIds - Optional specific entities to test (defaults to all blocks)\n * @returns Array of entity IDs sorted by rank (topmost first)\n */\nexport function intersectPoint(ctx: Context, point: Vec2, entityIds?: Iterable<EntityId>): EntityId[] {\n const intersects: EntityId[] = []\n const entities = entityIds ?? blocksWithAabb.current(ctx)\n\n for (const entityId of entities) {\n // Fast AABB rejection\n if (!AabbComp.containsPoint(ctx, entityId, point)) {\n continue\n }\n\n // Check HitGeometry if present, otherwise use block intersection\n if (hasComponent(ctx, entityId, HitGeometry)) {\n if (!HitGeometry.containsPointWorld(ctx, entityId, point)) {\n continue\n }\n } else {\n // Precise rotated block intersection\n if (!Block.containsPoint(ctx, entityId, point)) {\n continue\n }\n }\n\n intersects.push(entityId)\n }\n\n // Sort by rank (highest/topmost first)\n return sortByRankDescending(ctx, intersects)\n}\n\n/**\n * Find all blocks that intersect with an AABB (selection box).\n *\n * Uses AABB-AABB for fast rejection, then uses Separating Axis Theorem (SAT)\n * for precise AABB-to-oriented-block intersection. This correctly handles\n * all cases including narrow AABBs that pass through the middle of a block\n * without touching any corners.\n *\n * @param ctx - ECS context\n * @param bounds - Selection box bounds [left, top, right, bottom]\n * @param entityIds - Optional specific entities to test (defaults to all blocks)\n * @returns Array of entity IDs that intersect (unsorted)\n */\nexport function intersectAabb(ctx: Context, bounds: Aabb, entityIds?: Iterable<EntityId>): EntityId[] {\n const intersecting: EntityId[] = []\n const entities = entityIds ?? blocksWithAabb.current(ctx)\n\n for (const entityId of entities) {\n const { value: entityAabb } = AabbComp.read(ctx, entityId)\n\n // Fast AABB-AABB rejection\n if (!Aabb.intersects(bounds, entityAabb)) {\n continue\n }\n\n // If selection box fully contains block AABB, it's definitely intersecting\n if (Aabb.contains(bounds, entityAabb)) {\n intersecting.push(entityId)\n continue\n }\n\n // Check HitGeometry if present, otherwise use block intersection\n if (hasComponent(ctx, entityId, HitGeometry)) {\n if (HitGeometry.intersectsAabbWorld(ctx, entityId, bounds)) {\n intersecting.push(entityId)\n }\n } else {\n // Use SAT for precise AABB-to-oriented-block intersection\n if (Block.intersectsAabb(ctx, entityId, bounds)) {\n intersecting.push(entityId)\n }\n }\n }\n\n return intersecting\n}\n\n/**\n * Sort entity IDs by stratum then rank in descending order (topmost first).\n * Overlay blocks are always on top of content, which are on top of background.\n * Within each stratum, blocks are sorted by rank (higher = on top).\n */\nfunction sortByRankDescending(ctx: Context, entityIds: EntityId[]): EntityId[] {\n return entityIds.sort((a, b) => {\n const blockA = Block.read(ctx, a)\n const blockB = Block.read(ctx, b)\n\n // Get stratum for each block\n const stratumA = getBlockDef(ctx, blockA.tag).stratum\n const stratumB = getBlockDef(ctx, blockB.tag).stratum\n\n // Sort by stratum first (overlay > content > background)\n const stratumOrderA = STRATUM_ORDER[stratumA]\n const stratumOrderB = STRATUM_ORDER[stratumB]\n if (stratumOrderB !== stratumOrderA) {\n return stratumOrderB - stratumOrderA\n }\n\n // Within same stratum, sort by rank\n const rankA = blockA.rank\n const rankB = blockB.rank\n\n // Handle empty ranks (put at bottom)\n if (!rankA && !rankB) return 0\n if (!rankA) return 1\n if (!rankB) return -1\n\n // Descending order: higher rank first\n if (rankB > rankA) return 1\n if (rankB < rankA) return -1\n return 0\n })\n}\n\n/**\n * Get the topmost block at a point.\n *\n * @param ctx - ECS context\n * @param point - Point to test in world coordinates [x, y]\n * @returns Entity ID of topmost block, or undefined if none\n */\nexport function getTopmostBlockAtPoint(ctx: Context, point: Vec2): EntityId | undefined {\n const intersects = intersectPoint(ctx, point)\n return intersects[0]\n}\n","import { Aabb as AabbNs, Arc, Capsule, Mat2, type Vec2 } from '@woven-canvas/math'\nimport { type Context, type EntityId, hasComponent } from '@woven-ecs/core'\n\nimport { Aabb as AabbComponent } from '../components/Aabb'\nimport { Block } from '../components/Block'\nimport { HitGeometry } from '../components/HitGeometry'\n\n// Pre-allocated matrix for UV-to-world transforms (avoids allocation in hot paths)\nconst _uvToWorldMatrix: Mat2 = [1, 0, 0, 1, 0, 0]\n\n/**\n * Find all blocks that intersect with a capsule.\n *\n * Uses a two-phase approach:\n * 1. Broad phase: AABB intersection for fast rejection\n * 2. Narrow phase: Precise capsule intersection with HitGeometry (if available)\n * or AABB fallback\n *\n * @param ctx - ECS context\n * @param capsule - Capsule to test [ax, ay, bx, by, radius]\n * @param entityIds - Entities to test (required - typically from a query)\n * @returns Array of entity IDs that intersect with the capsule\n *\n * @example\n * ```typescript\n * const syncedBlocksQuery = defineQuery((q) => q.with(Block, Synced, Aabb));\n *\n * // In a system:\n * const capsule = Capsule.create(x1, y1, x2, y2, radius);\n * const hits = intersectCapsule(ctx, capsule, syncedBlocksQuery.current(ctx));\n * ```\n */\nexport function intersectCapsule(ctx: Context, capsule: Capsule, entityIds: Iterable<EntityId>): EntityId[] {\n const intersects: EntityId[] = []\n\n // Get capsule bounds for broad phase\n const capsuleBounds = Capsule.bounds(capsule)\n\n for (const entityId of entityIds) {\n // Broad phase: AABB intersection test\n const aabb = AabbComponent.read(ctx, entityId)\n if (!AabbNs.intersects(capsuleBounds, aabb.value)) {\n continue\n }\n\n // Narrow phase: Check against HitGeometry if available\n if (hasComponent(ctx, entityId, HitGeometry)) {\n if (intersectsCapsuleHitGeometry(ctx, entityId, capsule)) {\n intersects.push(entityId)\n }\n } else {\n // Fall back to AABB intersection for entities without HitGeometry\n if (Capsule.intersectsAabb(capsule, aabb.value)) {\n intersects.push(entityId)\n }\n }\n }\n\n return intersects\n}\n\n/**\n * Check if a capsule intersects with an entity's hit geometry.\n * Hit geometry is stored in UV coordinates; this transforms to world for testing.\n *\n * @param ctx - ECS context\n * @param entityId - Entity with HitGeometry component\n * @param capsule - Capsule to test in world coordinates\n * @returns True if the capsule intersects any of the entity's hit capsules or arc\n */\nfunction intersectsCapsuleHitGeometry(ctx: Context, entityId: EntityId, capsule: Capsule): boolean {\n const hitGeometry = HitGeometry.read(ctx, entityId)\n\n // Build UV-to-world matrix once (computes sin/cos once)\n Block.getUvToWorldMatrix(ctx, entityId, _uvToWorldMatrix)\n\n // Check arc intersections (transform UV arcs to world)\n for (let i = 0; i < hitGeometry.arcCount; i++) {\n const uvArc = HitGeometry.getArcAt(ctx, entityId, i)\n\n // Transform 3 UV points to world using matrix\n const worldA: Vec2 = [uvArc[0], uvArc[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvArc[2], uvArc[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n const worldC: Vec2 = [uvArc[4], uvArc[5]]\n Mat2.transformPoint(_uvToWorldMatrix, worldC)\n\n const thickness = uvArc[6] // Already in world units\n\n const worldArc = Arc.create(worldA[0], worldA[1], worldB[0], worldB[1], worldC[0], worldC[1], thickness)\n\n const capsuleA = Capsule.pointA(capsule)\n const capsuleB = Capsule.pointB(capsule)\n if (Arc.intersectsCapsule(worldArc, capsuleA, capsuleB, Capsule.radius(capsule))) {\n return true\n }\n }\n\n // Check capsule intersections (transform UV capsules to world)\n for (let i = 0; i < hitGeometry.capsuleCount; i++) {\n const uvCapsule = HitGeometry.getCapsuleAt(ctx, entityId, i)\n\n // Transform 2 UV points to world using matrix\n const worldA: Vec2 = [uvCapsule[0], uvCapsule[1]]\n Mat2.transformPoint(_uvToWorldMatrix, worldA)\n const worldB: Vec2 = [uvCapsule[2], uvCapsule[3]]\n Mat2.transformPoint(_uvToWorldMatrix, worldB)\n\n const radius = uvCapsule[4] // Already in world units\n\n const worldCapsule = Capsule.create(worldA[0], worldA[1], worldB[0], worldB[1], radius)\n\n if (Capsule.intersectsCapsule(capsule, worldCapsule)) {\n return true\n }\n }\n\n return false\n}\n","import { type Context, defineQuery, type EntityId, getResources } from '@woven-ecs/core'\nimport { User } from '../components/User'\nimport type { EditorResources } from '../types'\n\nconst userQuery = defineQuery((q) => q.with(User))\n\nexport function getMyUserEntityId(ctx: Context): EntityId | null {\n const mySessionId = getResources<EditorResources>(ctx).sessionId\n\n for (const eid of userQuery.current(ctx)) {\n const user = User.read(ctx, eid)\n if (user.sessionId === mySessionId) {\n return eid\n }\n }\n\n return null\n}\n","import { addComponent, type Context, defineQuery, hasComponent, removeComponent } from '@woven-ecs/core'\nimport { Aabb, Block, Held, HitGeometry, Hovered, Pointer } from '../../components'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { computeAabb, intersectPoint, isHeldByRemote } from '../../helpers'\nimport { Camera, Controls, Intersect, Mouse } from '../../singletons'\n\n// Query for blocks that have changed (need AABB recalculation)\nconst blocksChanged = defineQuery((q) => q.tracking(Block))\n\nconst hitGeometryChanged = defineQuery((q) => q.tracking(HitGeometry))\n\n// Query for held entities - track to re-evaluate hover when Held changes\nconst heldQuery = defineQuery((q) => q.with(Held).tracking(Held))\n\n// Query for currently hovered entities\nconst hoveredQuery = defineQuery((q) => q.with(Hovered))\n\n// Query for active pointers\nconst pointerQuery = defineQuery((q) => q.with(Pointer))\n\n/**\n * Clear all Hovered components.\n */\nfunction clearHovered(ctx: Context): void {\n for (const entityId of hoveredQuery.current(ctx)) {\n if (hasComponent(ctx, entityId, Hovered)) {\n removeComponent(ctx, entityId, Hovered)\n }\n }\n}\n\n/**\n * Find the first valid entity to hover from the intersect list.\n * Returns undefined if the topmost synced entity is held by a remote user,\n * to prevent accidentally grabbing blocks underneath.\n */\nfunction findValidHoverTarget(ctx: Context, intersected: number[]): number | undefined {\n for (const entityId of intersected) {\n // If the topmost synced entity is held by remote, don't hover anything\n // This prevents accidentally grabbing blocks underneath held blocks\n if (isHeldByRemote(ctx, entityId)) return undefined\n\n return entityId\n }\n\n return undefined\n}\n\n/**\n * Update which entity has the Hovered component.\n */\nfunction updateHovered(ctx: Context, intersected: number[]): void {\n // Only show hover when select tool is active\n const controls = Controls.read(ctx)\n const selectToolActive = controls.leftMouseTool === 'select'\n\n // Clear existing hovered entities\n clearHovered(ctx)\n\n if (!selectToolActive) return\n\n // Find first valid hover target (not held by remote)\n const newHoveredId = findValidHoverTarget(ctx, intersected)\n\n // Add hovered to new entity\n if (newHoveredId !== undefined) {\n addComponent(ctx, newHoveredId, Hovered, {})\n }\n}\n\n/**\n * Check if two arrays are equal.\n */\nfunction arraysEqual(a: number[], b: number[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\nconst added = new Set<number>()\nconst changed = new Set<number>()\n\n/**\n * Pre-capture intersect system - computes AABBs and detects mouse-block intersections.\n *\n * Runs early in the capture phase (priority: 100) to:\n * 1. Update AABB for blocks that have changed\n * 2. Find blocks under the mouse cursor\n * 3. Update the Intersect singleton\n * 4. Manage Hovered component on blocks\n *\n * Note: For test isolation, use createIntersectSystem() instead to get a fresh instance.\n */\nexport const intersectSystem = defineEditorSystem({ phase: 'capture', priority: 100 }, (ctx: Context) => {\n // Update AABBs for changed blocks\n added.clear()\n for (const entityId of blocksChanged.added(ctx)) {\n added.add(entityId)\n }\n for (const entityId of hitGeometryChanged.added(ctx)) {\n added.add(entityId)\n }\n\n changed.clear()\n for (const entityId of blocksChanged.changed(ctx)) {\n changed.add(entityId)\n }\n for (const entityId of hitGeometryChanged.changed(ctx)) {\n changed.add(entityId)\n }\n\n for (const entityId of added) {\n // Ensure block has Aabb component\n if (!hasComponent(ctx, entityId, Aabb)) {\n addComponent(ctx, entityId, Aabb, { value: [0, 0, 0, 0] })\n }\n\n const aabb = Aabb.write(ctx, entityId)\n computeAabb(ctx, entityId, aabb.value)\n }\n\n for (const entityId of changed) {\n const aabb = Aabb.write(ctx, entityId)\n computeAabb(ctx, entityId, aabb.value)\n }\n\n // Check if we need to update intersections\n const mouseDidMove = Mouse.didMove(ctx)\n const mouseDidLeave = Mouse.didLeave(ctx)\n const mouseDidScroll = Mouse.didScroll(ctx)\n const blocksHaveChanged = added.size > 0 || changed.size > 0\n\n // Check if Held changed (need to re-evaluate hover when blocks are released)\n const heldAdded = heldQuery.added(ctx)\n const heldRemoved = heldQuery.removed(ctx)\n const heldChanged = heldAdded.length > 0 || heldRemoved.length > 0\n\n // Only update if mouse moved, left, scrolled, blocks changed, or held state changed\n if (!mouseDidMove && !mouseDidLeave && !mouseDidScroll && !blocksHaveChanged && !heldChanged) {\n return\n }\n\n // Handle mouse leave - clear all intersections and hover\n if (mouseDidLeave) {\n Intersect.clear(ctx)\n clearHovered(ctx)\n return\n }\n\n // Get mouse position in world coordinates\n const mousePos = Mouse.getPosition(ctx)\n const worldPos = Camera.toWorld(ctx, mousePos)\n\n // Find intersected blocks (sorted by z-order, topmost first)\n const intersected = intersectPoint(ctx, worldPos)\n\n // Check if intersections changed\n const prevIntersected = Intersect.getAll(ctx)\n const intersectsChanged = !arraysEqual(intersected, prevIntersected)\n\n if (intersectsChanged) {\n // Update Intersect singleton\n Intersect.setAll(ctx, intersected)\n }\n\n // Don't change hover state while pointer is down\n // This prevents flickering when dragging objects\n const pointers = pointerQuery.current(ctx)\n if (pointers.length > 0) {\n return\n }\n\n // Update hovered entity if intersections or held state changed\n if (intersectsChanged || heldChanged) {\n updateHovered(ctx, intersected)\n }\n})\n","import { Synced } from '@woven-ecs/canvas-store'\nimport { type Context, defineQuery } from '@woven-ecs/core'\nimport { Block } from '../../components'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { RankBounds } from '../../singletons'\n\n// Query for blocks - tracks added blocks to sync their ranks\nconst blocksQuery = defineQuery((q) => q.with(Synced, Block))\n\n/**\n * Pre-input system - synchronizes RankBounds singleton with block ranks.\n *\n * Runs early in the input phase (priority: 100) to ensure RankBounds accurately\n * reflects the current min/max ranks across all blocks. This handles:\n * - Blocks added via sync (multiplayer/persistence)\n * - Blocks with ranks that weren't created through RankBounds.genNext/genPrev\n */\nexport const rankBoundsSystem = defineEditorSystem({ phase: 'input', priority: 100 }, (ctx: Context) => {\n const added = blocksQuery.added(ctx)\n\n // Process newly added blocks\n for (const entityId of added) {\n const block = Block.read(ctx, entityId)\n if (block.rank === '') {\n const writableBlock = Block.write(ctx, entityId)\n writableBlock.rank = RankBounds.genNext(ctx)\n } else {\n RankBounds.add(ctx, block.rank)\n }\n }\n})\n","import { Aabb as AabbMath } from '@woven-canvas/math'\nimport { Synced } from '@woven-ecs/canvas-store'\nimport { type Context, defineQuery, type EntityId, hasComponent } from '@woven-ecs/core'\nimport { Aabb, Block } from '../../components'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Camera } from '../../singletons'\n\nconst camerasQuery = defineQuery((q) => q.tracking(Camera))\n\n// Query for synced blocks with Aabb (persistent blocks)\nconst blocksQuery = defineQuery((q) => q.with(Synced, Block, Aabb))\n\nconst syncedBlocksQuery = defineQuery((q) => q.with(Synced, Block, Aabb))\n\n// Re-usable AABB for camera viewport (avoids allocation)\nconst _cameraAabb: AabbMath = [0, 0, 0, 0]\n\n/**\n * PreRender system - updates Camera.canSeeBlocks based on whether any blocks\n * are visible in the current viewport.\n *\n * This is used to show a \"back to content\" button when the user has panned\n * away from all content.\n *\n * Runs early in the render phase (priority: 90) after scaleWithZoom but before\n * other render systems.\n */\nexport const canSeeBlocksSystem = defineEditorSystem({ phase: 'render', priority: 90 }, (ctx: Context) => {\n if (camerasQuery.changed(ctx).length === 0 && syncedBlocksQuery.addedOrRemoved(ctx).length === 0) {\n // No camera or block changes, skip expensive block intersection checks\n return\n }\n\n const camera = Camera.read(ctx)\n\n const cameraAabb = Camera.getAabb(ctx, _cameraAabb)\n\n // Optimization: if we could see blocks before, check if we can still see the same block\n if (camera.canSeeBlocks && camera.lastSeenBlock !== null) {\n // Check if entity still exists with Aabb component before reading\n if (hasComponent(ctx, camera.lastSeenBlock, Aabb)) {\n const aabb = Aabb.read(ctx, camera.lastSeenBlock)\n if (AabbMath.intersects(cameraAabb, aabb.value)) {\n // Still visible, no need to update\n return\n }\n }\n }\n\n // Check if any block intersects with the camera viewport\n let seenBlock: EntityId | null = null\n for (const entityId of blocksQuery.current(ctx)) {\n const aabb = Aabb.read(ctx, entityId)\n if (AabbMath.intersects(cameraAabb, aabb.value)) {\n seenBlock = entityId\n break\n }\n }\n\n const canSeeBlocks = seenBlock !== null\n\n // Early exit if state hasn't changed\n if (canSeeBlocks === camera.canSeeBlocks) {\n if (seenBlock !== camera.lastSeenBlock) {\n Camera.write(ctx).lastSeenBlock = seenBlock\n }\n return\n }\n\n // Update camera state\n const writableCamera = Camera.write(ctx)\n writableCamera.canSeeBlocks = canSeeBlocks\n writableCamera.lastSeenBlock = seenBlock\n})\n","import { Scalar, Vec2 } from '@woven-canvas/math'\nimport { type Context, defineQuery, type EntityId } from '@woven-ecs/core'\nimport { Block, ScaleWithZoom } from '../../components'\nimport { defineEditorSystem } from '../../EditorSystem'\nimport { Camera, ScaleWithZoomState } from '../../singletons'\n\n// Query for entities with ScaleWithZoom\nconst scaleWithZoomQuery = defineQuery((q) => q.with(Block).tracking(ScaleWithZoom))\n\n// Pre-allocated vectors to avoid allocations in hot path\nconst _scaledSize: Vec2 = [0, 0]\nconst _anchorOffset: Vec2 = [0, 0]\n\n/**\n * PreRenderScaleWithZoom system - maintains screen-space size for entities\n * with the ScaleWithZoom component.\n *\n * When the camera zoom changes, this system scales entities inversely so they\n * appear the same size on screen regardless of zoom level. This is used for\n * transform handles, UI elements, etc.\n *\n * The scaling pivots around the anchor point specified in the ScaleWithZoom\n * component (default center [0.5, 0.5]).\n *\n * Runs early in the render phase (priority: 100) so other render systems\n * see the correctly scaled entities.\n */\nexport const scaleWithZoomSystem = defineEditorSystem({ phase: 'render', priority: 100 }, (ctx: Context) => {\n const camera = Camera.read(ctx)\n const state = ScaleWithZoomState.read(ctx)\n\n // Check if zoom changed\n const zoomChanged = !Scalar.approxEqual(camera.zoom, state.lastZoom)\n\n if (zoomChanged) {\n // Zoom changed - update all ScaleWithZoom entities\n for (const entityId of scaleWithZoomQuery.current(ctx)) {\n scaleBlock(ctx, entityId, camera.zoom)\n }\n ScaleWithZoomState.write(ctx).lastZoom = camera.zoom\n }\n\n // Always process newly added entities - they need to be scaled\n // even if zoom hasn't changed\n for (const entityId of scaleWithZoomQuery.addedOrChanged(ctx)) {\n scaleBlock(ctx, entityId, camera.zoom)\n }\n})\n\n/**\n * Scale a block based on the current zoom level.\n * The block maintains its screen-space size by scaling inversely with zoom.\n * Uses scaleMultiplier to control how much zoom affects each dimension.\n */\nfunction scaleBlock(ctx: Context, entityId: EntityId, zoom: number): void {\n const block = Block.write(ctx, entityId)\n const swz = ScaleWithZoom.read(ctx, entityId)\n\n const baseScale = 1 / zoom\n\n // Calculate scaled size per dimension based on scaleMultiplier\n // multiplier: 0 = no zoom effect (keeps startSize), 1 = full zoom effect, 0.5 = half effect\n // Interpolate between startSize and fully scaled size based on multiplier\n const scaleX = 1 + (baseScale - 1) * swz.scaleMultiplier[0]\n const scaleY = 1 + (baseScale - 1) * swz.scaleMultiplier[1]\n _scaledSize[0] = swz.startSize[0] * scaleX\n _scaledSize[1] = swz.startSize[1] * scaleY\n\n // Calculate anchor offset: (startSize - scaledSize) * anchor\n Vec2.copy(_anchorOffset, swz.startSize)\n Vec2.sub(_anchorOffset, _scaledSize)\n Vec2.multiply(_anchorOffset, swz.anchor)\n\n // Apply position with anchor offset\n Vec2.copy(block.position, swz.startPosition)\n Vec2.add(block.position, _anchorOffset)\n\n Vec2.copy(block.size, _scaledSize)\n}\n","import { type AnyCanvasComponentDef, type AnyCanvasSingletonDef, Synced } from '@woven-ecs/canvas-store'\nimport {\n addComponent,\n type ComponentDef,\n type Context,\n createEntity,\n type QueryDef,\n type SingletonDef,\n World,\n} from '@woven-ecs/core'\nimport { CorePlugin } from './CorePlugin'\nimport { type CommandDef, CommandMarker, cleanupCommands } from './command'\nimport { User } from './components'\nimport type { EditorSystem } from './EditorSystem'\nimport { FontFamily, FontLoader } from './FontLoader'\nimport { type EditorPlugin, parsePlugin, sortPluginsByDependencies } from './plugin'\nimport { Controls, Grid } from './singletons'\nimport {\n BlockDef,\n ControlsOptions,\n type CursorDef,\n type EditorOptionsInput,\n EditorOptionsSchema,\n type EditorResources,\n GridOptions,\n type Keybind,\n type SystemPhase,\n UserData,\n} from './types'\n\n/**\n * Query subscription callback\n */\nexport type QueryCallback = (\n ctx: Context,\n result: {\n added: number[]\n changed: number[]\n removed: number[]\n },\n) => void\n\n/**\n * Order of system execution phases\n */\nconst PHASE_ORDER: SystemPhase[] = ['input', 'capture', 'update', 'render']\n\n/**\n * Batch systems by phase and priority.\n *\n * Returns an array of system batches, sorted by phase order then priority (descending).\n * Systems at the same phase and priority are kept in registration order within their batch.\n *\n * This batching allows systems with lower priority to see `.changed()` and `.added()`\n * query results from systems that ran earlier in the same phase.\n */\nfunction batchSystems(systems: EditorSystem[]): EditorSystem[][] {\n // Group by phase first\n const byPhase = new Map<SystemPhase, EditorSystem[]>()\n for (const phase of PHASE_ORDER) {\n byPhase.set(phase, [])\n }\n for (const system of systems) {\n byPhase.get(system.phase)!.push(system)\n }\n\n // Then batch each phase by priority and flatten\n const result: EditorSystem[][] = []\n for (const phase of PHASE_ORDER) {\n const phaseSystems = byPhase.get(phase)!\n const byPriority = new Map<number, EditorSystem[]>()\n for (const system of phaseSystems) {\n const group = byPriority.get(system.priority) ?? []\n group.push(system)\n byPriority.set(system.priority, group)\n }\n\n // Sort priorities descending (higher runs first)\n const priorities = [...byPriority.keys()].sort((a, b) => b - a)\n for (const p of priorities) {\n result.push(byPriority.get(p)!)\n }\n }\n\n return result\n}\n\n/**\n * Editor is the main entry point for building editor applications.\n *\n * It manages:\n * - ECS World lifecycle\n * - Plugin registration\n * - System phase execution\n * - Command dispatch\n *\n * @example\n * ```typescript\n * import { Editor } from '@woven-canvas/core';\n * import { SelectionPlugin, TransformPlugin } from './plugins';\n *\n * const editor = new Editor(document.getElementById('canvas')!, {\n * plugins: [SelectionPlugin, TransformPlugin],\n * });\n *\n * // Run the editor loop\n * function loop() {\n * editor.tick();\n * requestAnimationFrame(loop);\n * }\n * loop();\n *\n * // Emit commands from UI\n * editor.emit('selection:select-all', {});\n *\n * // Clean up\n * editor.dispose();\n * ```\n */\nexport class Editor {\n public cursors: Record<string, CursorDef> = {}\n public keybinds: Keybind[]\n public blockDefs: Record<string, BlockDef> = {}\n public fonts: FontFamily[] = []\n public components: AnyCanvasComponentDef[] = []\n public singletons: AnyCanvasSingletonDef[] = []\n\n private world: World\n private systemBatches: EditorSystem[][]\n private plugins: Map<string, EditorPlugin>\n private fontLoader: FontLoader\n private userData: UserData\n private gridOptions: GridOptions\n private controlsOptions: ControlsOptions\n\n constructor(domElement: HTMLElement, optionsInput?: EditorOptionsInput) {\n const options = EditorOptionsSchema.parse(optionsInput ?? {})\n const { plugins: pluginInputs, maxEntities } = options\n\n // Parse user data with defaults\n const user = UserData.parse(options.user ?? {})\n this.userData = user\n\n // Parse grid options with defaults\n this.gridOptions = GridOptions.parse(options.grid ?? {})\n\n // Parse controls options with defaults\n this.controlsOptions = ControlsOptions.parse(options.controls ?? {})\n\n // Parse plugin inputs (handle both direct plugins and factory functions)\n const plugins = pluginInputs.map(parsePlugin)\n\n // Sort plugins by dependencies, always including CorePlugin first\n const sortedPlugins = sortPluginsByDependencies([CorePlugin, ...plugins])\n\n // Collect all components and singletons from plugins and custom options\n // Always include CommandMarker for the command system\n const allDefs: (ComponentDef<any> | SingletonDef<any>)[] = [CommandMarker, Synced]\n for (const plugin of sortedPlugins) {\n if (plugin.components) {\n allDefs.push(...plugin.components)\n }\n if (plugin.singletons) {\n allDefs.push(...plugin.singletons)\n }\n }\n // Add custom components and singletons\n allDefs.push(...options.components)\n allDefs.push(...options.singletons)\n\n // Setup keybinds\n const keybinds = options.keybinds\n if (!options.omitPluginKeybinds) {\n for (const plugin of sortedPlugins) {\n if (plugin.keybinds) {\n keybinds.push(...plugin.keybinds)\n }\n }\n }\n this.keybinds = keybinds\n\n // Setup block defs (parse inputs to apply defaults)\n const blockDefs: Record<string, BlockDef> = {}\n for (const input of options.blockDefs) {\n const parsed = BlockDef.parse(input)\n blockDefs[parsed.tag] = parsed\n }\n for (const plugin of sortedPlugins) {\n if (plugin.blockDefs) {\n for (const input of plugin.blockDefs) {\n const parsed = BlockDef.parse(input)\n blockDefs[parsed.tag] = parsed\n }\n }\n }\n this.blockDefs = blockDefs\n\n // Setup cursors\n const cursors: Record<string, CursorDef> = {}\n Object.assign(cursors, options.cursors)\n if (!options.omitPluginCursors) {\n for (const plugin of sortedPlugins) {\n if (plugin.cursors) {\n Object.assign(cursors, plugin.cursors)\n }\n }\n }\n this.cursors = cursors\n\n // Setup fonts (parse inputs to apply defaults, merge from plugins)\n this.fontLoader = new FontLoader()\n const fontInputs = [...options.fonts]\n if (!options.omitPluginFonts) {\n for (const plugin of sortedPlugins) {\n if (plugin.fonts) {\n fontInputs.push(...plugin.fonts)\n }\n }\n }\n this.fonts = fontInputs.map((input) => FontFamily.parse(input))\n\n // Collect plugin resources\n const pluginResources: Record<string, unknown> = {}\n for (const plugin of sortedPlugins) {\n if (plugin.resources !== undefined) {\n pluginResources[plugin.name] = plugin.resources\n }\n }\n\n // Build component/singleton maps for resources\n const componentsByName = new Map<string, AnyCanvasComponentDef>()\n const singletonsByName = new Map<string, AnyCanvasSingletonDef>()\n const componentsById = new Map<number, AnyCanvasComponentDef>()\n const singletonsById = new Map<number, AnyCanvasSingletonDef>()\n\n // Create ECS World with editor resources\n const allResources: EditorResources = {\n domElement,\n editor: this,\n userId: user.userId,\n sessionId: user.sessionId,\n pluginResources,\n componentsByName,\n singletonsByName,\n componentsById,\n singletonsById,\n }\n\n this.world = new World(allDefs, {\n maxEntities,\n resources: allResources,\n })\n\n // Collect all systems\n const allSystems: EditorSystem[] = []\n\n // Register systems from plugins (order matters for stable tie-breaking)\n for (const plugin of sortedPlugins) {\n if (plugin.systems) {\n allSystems.push(...plugin.systems)\n }\n }\n\n // Register custom systems\n allSystems.push(...options.systems)\n\n // Batch systems by phase and priority\n this.systemBatches = batchSystems(allSystems)\n\n // Build map of plugins\n this.plugins = new Map(sortedPlugins.map((p) => [p.name, p]))\n\n // Build maps of all components/singletons (by id and by name)\n for (const plugin of sortedPlugins) {\n if (plugin.components) {\n for (const comp of plugin.components) {\n const componentId = comp._getComponentId(this.ctx)\n componentsById.set(componentId, comp)\n componentsByName.set(comp.name, comp)\n }\n }\n if (plugin.singletons) {\n for (const singleton of plugin.singletons) {\n const componentId = singleton._getComponentId(this.ctx)\n singletonsById.set(componentId, singleton)\n singletonsByName.set(singleton.name, singleton)\n }\n }\n }\n // Add custom components and singletons to maps\n for (const comp of options.components) {\n const componentId = comp._getComponentId(this.ctx)\n componentsById.set(componentId, comp)\n componentsByName.set(comp.name, comp)\n }\n for (const singleton of options.singletons) {\n const componentId = singleton._getComponentId(this.ctx)\n singletonsById.set(componentId, singleton)\n singletonsByName.set(singleton.name, singleton)\n }\n\n // Expose collected components/singletons\n this.components = [...componentsByName.values()]\n this.singletons = [...singletonsByName.values()]\n }\n\n /**\n * Get the ECS context.\n * Use this to access ECS functions and resources.\n */\n private get ctx(): Context {\n return this.world._getContext()\n }\n\n /**\n * Initialize the editor.\n * Call this after construction to run async setup.\n */\n async initialize(): Promise<void> {\n // Load custom fonts\n if (this.fonts.length > 0) {\n await this.fontLoader.loadFonts(this.fonts)\n }\n\n Grid.copy(this.ctx, this.gridOptions)\n Controls.copy(this.ctx, this.controlsOptions)\n\n // Create the user entity for presence tracking\n this.nextTick((ctx) => {\n const userEntity = createEntity(ctx)\n addComponent(ctx, userEntity, Synced, {\n id: crypto.randomUUID(),\n })\n addComponent(ctx, userEntity, User, {\n userId: this.userData.userId,\n sessionId: this.userData.sessionId,\n color: this.userData.color,\n name: this.userData.name,\n avatar: this.userData.avatar,\n })\n })\n\n // Run plugin setup\n for (const plugin of this.plugins.values()) {\n if (plugin.setup) {\n await plugin.setup(this.ctx)\n }\n }\n }\n\n /**\n * Run one frame of the editor loop.\n *\n * Executes systems in phase order:\n * 1. Input - convert raw events to ECS state\n * 2. Capture - detect targets, compute intersections\n * 3. Update - modify document state, process commands\n * 4. Render - sync ECS state to output\n *\n * Commands spawned via `command()` are available during this frame\n * and automatically cleaned up at the end.\n */\n async tick(): Promise<void> {\n // Process scheduled callbacks (including command spawns)\n this.world.sync()\n\n // Execute system batches in order (already sorted by phase then priority)\n for (const batch of this.systemBatches) {\n const systems = batch.map((s) => s._system)\n await this.world.execute(...systems)\n }\n\n const currentEventIndex = this.ctx.eventBuffer.getWriteIndex()\n this.ctx.prevEventIndex = currentEventIndex\n this.ctx.currEventIndex = currentEventIndex\n\n // Clean up command entities at end of frame\n cleanupCommands(this.ctx)\n }\n\n /**\n * Schedule work for the next tick.\n * Use this from event handlers to safely modify ECS state.\n *\n * @param callback - Function to execute at next tick\n *\n * @example\n * ```typescript\n * element.addEventListener('click', () => {\n * editor.nextTick((ctx) => {\n * const block = Block.write(ctx, entityId);\n * block.selected = true;\n * });\n * });\n * ```\n */\n nextTick(callback: (ctx: Context) => void): () => void {\n return this.world.nextSync((ctx) => {\n callback(ctx)\n })\n }\n\n /**\n * Spawn a command to be processed this frame.\n * Commands are ephemeral entities that systems can react to via `CommandDef.iter()`.\n *\n * @param def - The command definition created with `defineCommand()`\n * @param payload - Command payload data\n *\n * @example\n * ```typescript\n * const SelectAll = defineCommand<{ filter?: string }>(\"select-all\");\n *\n * // From UI event handler\n * editor.command(SelectAll, { filter: \"blocks\" });\n * ```\n */\n command<T>(def: CommandDef<T>, ...args: T extends void ? [] : [T]): void {\n const payload = args[0] as T\n this.nextTick((ctx) => {\n def.spawn(ctx, payload)\n })\n }\n\n /**\n * Subscribe to query changes.\n *\n * @param query - Query definition\n * @param callback - Called when query results change\n * @returns Unsubscribe function\n *\n * @example\n * ```typescript\n * const unsubscribe = editor.subscribe(selectedBlocks, (ctx, { added, removed }) => {\n * console.log('Selection changed:', added, removed);\n * });\n *\n * // Later:\n * unsubscribe();\n * ```\n */\n subscribe(query: QueryDef, callback: QueryCallback): () => void {\n return this.world.subscribe(query, (ctx, result) => {\n callback(ctx, result)\n })\n }\n\n /**\n * Get the ECS context.\n * Only for testing and advanced use cases.\n * @internal\n */\n _getContext(): Context {\n return this.ctx\n }\n\n /**\n * Clean up the editor.\n * Call this when done to release resources.\n */\n dispose(): void {\n // Run plugin teardown in reverse order\n const plugins = Array.from(this.plugins.values()).reverse()\n for (const plugin of plugins) {\n if (plugin.teardown) {\n plugin.teardown(this.ctx)\n }\n }\n\n // Dispose ECS World\n this.world.dispose()\n\n // Clear state\n this.plugins.clear()\n this.systemBatches = []\n }\n}\n","import { z } from 'zod'\n\n/**\n * Font family definition schema.\n * Defines a custom font that can be loaded and used in text blocks.\n */\nexport const FontFamily = z.object({\n /** The CSS font-family name */\n name: z.string(),\n /** Display name shown in the font selector UI */\n displayName: z.string(),\n /** URL to the font stylesheet (e.g., Google Fonts URL) */\n url: z.string(),\n /** Optional preview image URL for the font selector */\n previewImage: z.string().optional(),\n /** Whether this font appears in the font selector (default: true) */\n selectable: z.boolean().default(true),\n /**\n * Font weights to load (e.g., [400, 700] for regular and bold).\n * Only applies to Google Fonts URLs - will auto-construct the variant URL.\n * Default: [400, 700]\n */\n weights: z.array(z.number()).default([400, 700]),\n /**\n * Whether to also load italic variants for each weight.\n * Only applies to Google Fonts URLs.\n * Default: true\n */\n italics: z.boolean().default(true),\n})\n\nexport type FontFamily = z.infer<typeof FontFamily>\nexport type FontFamilyInput = z.input<typeof FontFamily>\n\n/**\n * FontLoader handles loading custom fonts from URLs.\n * It tracks which fonts have been loaded to avoid duplicate loading.\n */\nexport class FontLoader {\n private loadedFonts: Set<string> = new Set()\n\n /**\n * Load multiple font families.\n * Fonts that have already been loaded will be skipped.\n *\n * @param families - Array of font families to load\n */\n async loadFonts(families: FontFamily[]): Promise<void> {\n const unloadedFamilies = families.filter((family) => !this.loadedFonts.has(family.name))\n\n if (unloadedFamilies.length === 0) {\n return\n }\n\n const fontPromises = unloadedFamilies.map((family) => this.loadSingleFont(family))\n await Promise.all(fontPromises)\n }\n\n /**\n * Build a Google Fonts URL with weight and italic variants.\n * Format: https://fonts.googleapis.com/css2?family=FontName:ital,wght@0,400;0,700;1,400;1,700\n *\n * @param family - Font family configuration\n * @returns The constructed URL with variants\n */\n private buildGoogleFontsUrl(family: FontFamily): string {\n const baseUrl = family.url\n\n // Check if this is a Google Fonts URL\n if (!baseUrl.includes('fonts.googleapis.com')) {\n return baseUrl\n }\n\n // Extract the font family name from the URL\n const urlObj = new URL(baseUrl)\n const familyParam = urlObj.searchParams.get('family')\n if (!familyParam) {\n return baseUrl\n }\n\n // Get the base family name (remove any existing weight/style specifiers)\n const baseFamilyName = familyParam.split(':')[0]\n\n // Build the variant specifier\n const weights = family.weights\n const variants: string[] = []\n\n if (family.italics) {\n // Format: ital,wght@0,400;0,700;1,400;1,700\n for (const weight of weights) {\n variants.push(`0,${weight}`) // Normal\n }\n for (const weight of weights) {\n variants.push(`1,${weight}`) // Italic\n }\n urlObj.searchParams.set('family', `${baseFamilyName}:ital,wght@${variants.join(';')}`)\n } else {\n // Format: wght@400;700\n urlObj.searchParams.set('family', `${baseFamilyName}:wght@${weights.join(';')}`)\n }\n\n return urlObj.toString()\n }\n\n /**\n * Load a single font family.\n * Adds a link element to the document head and waits for the font to be ready.\n *\n * @param family - Font family to load\n */\n private loadSingleFont(family: FontFamily): Promise<void> {\n this.loadedFonts.add(family.name)\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = this.buildGoogleFontsUrl(family)\n link.onload = async () => {\n try {\n // Wait for all font variants to be loaded\n const loadPromises = this.getFontLoadPromises(family)\n await Promise.all(loadPromises)\n // Ensure all fonts are ready\n await document.fonts.ready\n resolve()\n } catch (error) {\n reject(new Error(`Failed to load font face for: ${family.name}. ${error}`))\n }\n }\n link.onerror = () => {\n reject(new Error(`Failed to load font stylesheet: ${family.name}`))\n }\n document.head.appendChild(link)\n })\n }\n\n /**\n * Get promises for loading all font variants (weights and italics).\n *\n * @param family - Font family configuration\n * @returns Array of promises for loading each font variant\n */\n private getFontLoadPromises(family: FontFamily): Promise<FontFace[]>[] {\n const promises: Promise<FontFace[]>[] = []\n const fontName = family.name\n\n for (const weight of family.weights) {\n // Load normal variant\n promises.push(document.fonts.load(`${weight} 12px \"${fontName}\"`))\n\n // Load italic variant if enabled\n if (family.italics) {\n promises.push(document.fonts.load(`italic ${weight} 12px \"${fontName}\"`))\n }\n }\n\n return promises\n }\n\n /**\n * Check if a font has been loaded.\n *\n * @param fontName - The font-family name to check\n * @returns True if the font has been loaded\n */\n isLoaded(fontName: string): boolean {\n return this.loadedFonts.has(fontName)\n }\n\n /**\n * Get the set of loaded font names.\n */\n getLoadedFonts(): ReadonlySet<string> {\n return this.loadedFonts\n }\n}\n","import type { AnyCanvasComponentDef, AnyCanvasSingletonDef } from '@woven-ecs/canvas-store'\nimport type { Context } from '@woven-ecs/core'\nimport type { EditorSystem } from './EditorSystem'\nimport type { FontFamilyInput } from './FontLoader'\nimport type { BlockDefInput, CursorDef, Keybind } from './types'\n\n/**\n * Editor plugin interface.\n *\n * Plugins extend the editor with:\n * - Components (CanvasComponentDef instances)\n * - Singletons (CanvasSingletonDef instances)\n * - Systems (behavior in specific phases with priority)\n * - Commands (user actions)\n *\n * @example\n * ```typescript\n * import {\n * EditorPlugin,\n * defineCanvasComponent,\n * defineCanvasSingleton,\n * defineEditorSystem,\n * field,\n * } from '@woven-canvas/core';\n *\n * const Selected = defineCanvasComponent('selected', {}, { sync: 'ephemeral' });\n * const Hovered = defineCanvasComponent('hovered', {}, { sync: 'none' });\n *\n * const CameraState = defineCanvasSingleton('camera', {\n * x: field.float64().default(0),\n * y: field.float64().default(0),\n * zoom: field.float64().default(1),\n * }, { sync: 'ephemeral' });\n *\n * const hoverSystem = defineEditorSystem(\n * { phase: 'capture' },\n * (ctx) => {\n * // Detect hover state\n * }\n * );\n *\n * const selectionSystem = defineEditorSystem(\n * { phase: 'capture', priority: -10 }, // Runs after hoverSystem\n * (ctx) => {\n * // Handle selection logic\n * }\n * );\n *\n * const SelectionPlugin: EditorPlugin = {\n * name: 'selection',\n * components: [Selected, Hovered],\n * singletons: [CameraState],\n * systems: [hoverSystem, selectionSystem],\n *\n * setup(ctx) {\n * console.log('Selection plugin initialized');\n * },\n *\n * teardown(ctx) {\n * console.log('Selection plugin destroyed');\n * }\n * };\n * ```\n */\nexport interface EditorPlugin<TResources = unknown> {\n /** Unique plugin identifier */\n name: string\n\n /** Keybindings provided by the plugin */\n keybinds?: Keybind[]\n\n /** Block definitions provided by the plugin (keyed by tag) */\n blockDefs?: BlockDefInput[]\n\n cursors?: Record<string, CursorDef>\n\n /**\n * Font families provided by the plugin.\n * Fonts will be loaded automatically during editor initialization.\n */\n fonts?: FontFamilyInput[]\n\n /**\n * Plugin-specific resources/options.\n * Access in systems via getPluginResources<T>(ctx, pluginName).\n */\n resources?: TResources\n\n /**\n * Names of plugins this one depends on.\n * Dependencies are loaded before this plugin.\n */\n dependencies?: string[]\n\n /**\n * Components to register.\n * User-defined components should use defineCanvasComponent() with an `id` field.\n * Internal components may use base ComponentDef.\n */\n components?: AnyCanvasComponentDef[]\n\n /**\n * Singletons to register.\n * Create with new CanvasSingletonDef(schema, options).\n */\n singletons?: AnyCanvasSingletonDef[]\n\n /**\n * Systems to register.\n * Each system specifies its phase and priority.\n * Use defineEditorSystem() to create systems.\n */\n systems?: EditorSystem[]\n\n /**\n * Called when the plugin is initialized.\n * Use this for one-time setup like adding event listeners.\n */\n setup?: (ctx: Context) => void | Promise<void>\n\n /**\n * Called when the editor is destroyed.\n * Use this to clean up resources.\n */\n teardown?: (ctx: Context) => void\n}\n\n/**\n * A plugin factory function that returns a plugin when called.\n * Allows passing configuration options to plugins.\n *\n * @example\n * ```typescript\n * // Define a plugin factory\n * export const CanvasControlsPlugin = (options: ControlsOptions = {}) => ({\n * name: \"controls\",\n * resources: { zoomSpeed: options.zoomSpeed ?? 1.0 },\n * // ... systems, components, etc.\n * });\n *\n * // Use with default options\n * const editor = new Editor(el, { plugins: [CanvasControlsPlugin] });\n *\n * // Or with custom options\n * const editor = new Editor(el, { plugins: [CanvasControlsPlugin({ zoomSpeed: 2.0 })] });\n * ```\n */\nexport type EditorPluginFactory<TOptions = unknown, TResources = unknown> = (\n options: TOptions,\n) => EditorPlugin<TResources>\n\n/**\n * Input type for plugin configuration.\n * Accepts either a plugin object directly or a factory function.\n */\nexport type EditorPluginInput = EditorPlugin | EditorPluginFactory<any, any>\n\n/**\n * Parse a plugin input into a plugin object.\n * If the input is a factory function, it's called with empty options.\n *\n * @param input - Either a plugin object or factory function\n * @returns The resolved plugin object\n */\nexport function parsePlugin(input: EditorPluginInput): EditorPlugin {\n if (typeof input === 'function') {\n return input({})\n }\n return input\n}\n\n/**\n * Sort plugins by dependencies (topological sort)\n * @internal\n */\nexport function sortPluginsByDependencies(plugins: EditorPlugin[]): EditorPlugin[] {\n const sorted: EditorPlugin[] = []\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const pluginMap = new Map(plugins.map((p) => [p.name, p]))\n\n function visit(plugin: EditorPlugin): void {\n if (visited.has(plugin.name)) return\n if (visiting.has(plugin.name)) {\n throw new Error(`Circular plugin dependency detected: ${plugin.name}`)\n }\n\n visiting.add(plugin.name)\n\n for (const depName of plugin.dependencies ?? []) {\n const dep = pluginMap.get(depName)\n if (!dep) {\n throw new Error(`Plugin \"${plugin.name}\" depends on \"${depName}\" which is not registered`)\n }\n visit(dep)\n }\n\n visiting.delete(plugin.name)\n visited.add(plugin.name)\n sorted.push(plugin)\n }\n\n for (const plugin of plugins) {\n visit(plugin)\n }\n\n return sorted\n}\n","import { CanvasSingletonDef, type InferCanvasComponentType } from '@woven-ecs/canvas-store'\nimport type { ComponentSchema, Context, EnumFieldDef, StringFieldDef } from '@woven-ecs/core'\nimport type { AnyStateMachine } from 'xstate'\nimport { runMachine } from './machine'\n\n/**\n * Schema type for state machine singletons.\n * Must include a 'state' field that stores the current state value.\n */\nexport interface StateSchema extends ComponentSchema {\n /** The current state machine state value (can be string or enum) */\n state: { def: StringFieldDef | EnumFieldDef<any> }\n}\n\n/**\n * Internal type: infer machine context from schema (excludes 'state' field).\n */\ntype InferMachineContext<T extends StateSchema> = Omit<InferCanvasComponentType<T>, 'state'>\n\n/**\n * Extract the machine context type from an EditorStateDef instance.\n * Returns all fields except 'state', properly typed.\n *\n * @example\n * ```typescript\n * const DragState = defineEditorState(\"dragState\", {\n * state: field.string().max(16).default(\"idle\"),\n * startX: field.float64().default(0),\n * startY: field.float64().default(0),\n * });\n *\n * type DragContext = InferStateContext<typeof DragState>;\n * // { startX: number; startY: number }\n * ```\n */\nexport type InferStateContext<T> =\n T extends EditorStateDef<infer S> ? Omit<InferMachineContext<S>, '_exists' | '_version'> : never\n\n/**\n * Editor singleton definition for XState state machine state storage.\n *\n * This class extends CanvasSingletonDef to provide convenient methods\n * for working with XState machines in ECS systems.\n *\n * The schema must include a 'state' field for the current state value,\n * plus any additional fields for the machine context.\n *\n * @example\n * ```typescript\n * export const PanState = defineEditorState(\"panState\", {\n * state: field.string().max(16).default(\"idle\"),\n * panStartX: field.float64().default(0),\n * panStartY: field.float64().default(0),\n * });\n *\n * // In a system:\n * const events = getPointerInput(ctx, [\"middle\"]);\n * if (events.length > 0) {\n * PanState.run(ctx, createPanMachine(ctx), events);\n * }\n * ```\n */\nexport class EditorStateDef<T extends StateSchema> extends CanvasSingletonDef<T> {\n constructor(name: string, schema: T) {\n // State machine state is never synced - it's ephemeral runtime state\n super({ name, sync: 'none' }, schema)\n }\n\n /**\n * Get the current state value.\n *\n * @param ctx - The ECS context\n * @returns The current state machine state value\n */\n getState(ctx: Context): string {\n return this.read(ctx).state as string\n }\n\n /**\n * Get the machine context (all fields except 'state').\n *\n * @param ctx - The ECS context\n * @returns Plain object with context field values\n */\n getContext<TContext extends object = InferMachineContext<T>>(ctx: Context): TContext {\n const snapshot = this.snapshot(ctx)\n const result: Record<string, unknown> = {}\n\n for (const key of Object.keys(snapshot)) {\n if (key !== 'state') {\n result[key] = snapshot[key as keyof typeof snapshot]\n }\n }\n\n return result as TContext\n }\n\n /**\n * Run an XState machine through events and update the singleton state.\n *\n * This method encapsulates the common pattern of:\n * 1. Reading the current state and context\n * 2. Running the machine through events\n * 3. Writing the updated state and context back\n *\n * @param ctx - The ECS context\n * @param machine - The XState machine definition\n * @param events - Array of events to process (must have a 'type' property)\n * @returns The resulting state value and context\n *\n * @example\n * ```typescript\n * const capturePanSystem = defineSystem((ctx) => {\n * const events = getPointerInput(ctx, [\"middle\"]);\n * if (events.length === 0) return;\n *\n * PanState.run(ctx, createPanMachine(ctx), events);\n * });\n * ```\n */\n run<\n TState extends string,\n TContext extends object = InferMachineContext<T>,\n TEvent extends { type: string } = { type: string },\n >(ctx: Context, machine: AnyStateMachine, events: TEvent[]): { value: TState; context: TContext } {\n // Read current state\n const currentState = this.getState(ctx) as TState\n const currentContext = this.getContext<TContext>(ctx)\n\n // Run machine through events\n const result = runMachine<TState, TContext>(\n machine,\n currentState,\n currentContext,\n events as unknown as Array<{ type: string; [key: string]: unknown }>,\n )\n\n // Write updated state and context\n const writable = this.write(ctx)\n ;(writable as { state: string }).state = result.value\n\n // Copy context fields back\n for (const [key, value] of Object.entries(result.context)) {\n ;(writable as Record<string, unknown>)[key] = value\n }\n\n return result\n }\n}\n\n/**\n * Define an editor state singleton for XState machine state storage.\n *\n * State machine state is ephemeral runtime state that is never persisted or synced.\n * Use this for UI state machines like pan, drag, selection, etc.\n *\n * @param name - Stable identifier for the state (e.g., \"panState\", \"dragState\")\n * @param schema - The singleton schema (must include 'state' field)\n * @returns EditorStateDef instance\n *\n * @example\n * ```typescript\n * export const DragState = defineEditorState(\"dragState\", {\n * state: field.string().max(16).default(\"idle\"),\n * startX: field.float64().default(0),\n * startY: field.float64().default(0),\n * });\n * ```\n */\nexport function defineEditorState<T extends StateSchema>(name: string, schema: T): EditorStateDef<T> {\n return new EditorStateDef(name, schema)\n}\n","import { type AnyStateMachine, transition } from 'xstate'\n\n/**\n * Result of running a state machine through events.\n */\nexport interface MachineResult<TState, TContext> {\n /** The resulting state value */\n value: TState\n /** The resulting context */\n context: TContext\n}\n\n/**\n * Run an XState machine synchronously through a batch of events.\n *\n * This is a stateless, functional approach to state machines that works well\n * with ECS systems. Instead of creating long-running actor instances, the\n * machine processes events in a single frame and returns the new state.\n *\n * @param machine - The XState machine definition\n * @param currentState - The current state value (e.g., 'idle', 'dragging')\n * @param context - The current machine context\n * @param events - Array of events to process\n * @returns The resulting state value and context\n *\n * @example\n * ```typescript\n * const panMachine = setup({\n * types: {\n * context: {} as { panStart: Vec2 },\n * events: {} as PointerEvent,\n * },\n * actions: {\n * setDragStart: assign({\n * panStart: ({ event }) => event.worldPosition,\n * }),\n * },\n * }).createMachine({\n * initial: 'idle',\n * states: {\n * idle: {\n * on: { pointerDown: { actions: 'setDragStart', target: 'panning' } },\n * },\n * panning: {\n * on: { pointerUp: 'idle' },\n * },\n * },\n * });\n *\n * // In a system:\n * const events = getPointerEvents(ctx, ['left']);\n * const { value, context } = runMachine(\n * panMachine,\n * state.currentState,\n * state.toContext(),\n * events,\n * );\n * ```\n */\nexport function runMachine<TState extends string, TContext extends object>(\n machine: AnyStateMachine,\n currentState: TState,\n context: TContext,\n events: Array<{ type: string; [key: string]: unknown }>,\n): MachineResult<TState, TContext> {\n if (events.length === 0) {\n return { value: currentState, context }\n }\n\n let state = machine.resolveState({\n value: String(currentState),\n context,\n })\n\n for (const event of events) {\n const [nextState, actions] = transition(machine, state, event)\n state = nextState\n\n // Execute actions synchronously\n for (const action of actions) {\n if (typeof action.exec === 'function') {\n action.exec(action.info, action.params)\n }\n }\n }\n\n return {\n value: state.value as TState,\n context: state.context as TContext,\n }\n}\n","import type { Context } from '@woven-ecs/core'\nimport { Frame } from '../singletons'\nimport type { FrameInput } from './types'\n\n/**\n * Generate a frame input event from ECS state for state machine consumption.\n *\n * This function provides frame timing information as a standardized event\n * suitable for XState machines. Useful for driving animations and\n * time-based state transitions (e.g., camera glide, tweens).\n *\n * @param ctx - ECS context\n * @returns A frame input event\n *\n * @example\n * ```typescript\n * import { getFrameInput } from '@woven-canvas/core';\n *\n * const glideSystem = defineSystem((ctx) => {\n * const state = GlideState.read(ctx);\n * if (state.state !== 'gliding') return;\n *\n * const frameEvent = getFrameInput(ctx);\n * GlideState.run(ctx, glideMachine, [frameEvent]);\n * });\n * ```\n */\nexport function getFrameInput(ctx: Context): FrameInput {\n const frame = Frame.read(ctx)\n\n return {\n type: 'frame',\n ctx,\n delta: frame.delta,\n frameNumber: frame.number,\n time: frame.time,\n }\n}\n","import type { Context } from '@woven-ecs/core'\nimport { Keyboard } from '../singletons'\nimport type { KeyboardInput } from './types'\n\n/**\n * Get keyboard input events for specific keys.\n *\n * Checks the specified keys for press/release triggers and returns\n * corresponding events for state machine consumption.\n *\n * @param ctx - ECS context\n * @param keys - Array of key indices to check (use Key.A, Key.Escape, etc.)\n * @returns Array of keyboard input events that occurred this frame\n *\n * @example\n * ```ts\n * const events = getKeyboardInput(ctx, [Key.Escape, Key.Space]);\n * for (const event of events) {\n * if (event.type === \"keyDown\" && event.key === Key.Escape) {\n * // Handle escape pressed\n * }\n * }\n * ```\n */\nexport function getKeyboardInput(ctx: Context, keys: number[]): KeyboardInput[] {\n const events: KeyboardInput[] = []\n\n for (const key of keys) {\n if (Keyboard.isKeyDownTrigger(ctx, key)) {\n events.push({ type: 'keyDown', key, ctx })\n }\n if (Keyboard.isKeyUpTrigger(ctx, key)) {\n events.push({ type: 'keyUp', key, ctx })\n }\n }\n\n return events\n}\n","import type { Vec2 } from '@woven-canvas/math'\nimport type { Context } from '@woven-ecs/core'\nimport { Camera, Mouse } from '../singletons'\nimport type { MouseInput } from './types'\n\n/**\n * Generate high-level mouse input events from ECS state for state machine consumption.\n *\n * This function transforms raw Mouse singleton data into semantic events\n * suitable for XState machines. It handles:\n *\n * - **wheel** - Mouse wheel was scrolled (includes deltaX and deltaY)\n * - **mouseMove** - Mouse moved (without button pressed)\n *\n * Note: For pointer-based events (click, drag), use `getPointerInput` instead.\n * This function is specifically for wheel events and hover movement.\n *\n * @param ctx - ECS context\n * @returns Array of mouse input events to process\n *\n * @example\n * ```typescript\n * import { getMouseInput, runMachine } from '@woven-canvas/plugin-xstate';\n *\n * const zoomSystem = defineSystem((ctx) => {\n * const events = getMouseInput(ctx);\n * if (events.length === 0) return;\n *\n * const wheelEvents = events.filter(e => e.type === 'wheel');\n * // Handle zoom...\n * });\n * ```\n */\nexport function getMouseInput(ctx: Context): MouseInput[] {\n const events: MouseInput[] = []\n const mouse = Mouse.read(ctx)\n\n // Get screen position\n const screenPos: Vec2 = [mouse.position[0], mouse.position[1]]\n\n // Get world position using Camera component\n const worldPos = Camera.toWorld(ctx, screenPos)\n\n // Handle wheel event\n if (mouse.wheelTrigger) {\n events.push({\n type: 'wheel',\n ctx,\n screenPosition: screenPos,\n worldPosition: worldPos,\n wheelDeltaX: mouse.wheelDeltaX,\n wheelDeltaY: mouse.wheelDeltaY,\n })\n }\n\n // Handle move event\n if (mouse.moveTrigger) {\n events.push({\n type: 'mouseMove',\n ctx,\n screenPosition: screenPos,\n worldPosition: worldPos,\n wheelDeltaX: 0,\n wheelDeltaY: 0,\n })\n }\n\n return events\n}\n","import { Vec2 } from '@woven-canvas/math'\nimport { type Context, defineQuery, type EntityId } from '@woven-ecs/core'\n\nimport { Pointer, type PointerButton } from '../components'\nimport { Camera, Frame, Intersect, Key, Keyboard } from '../singletons'\nimport type { PointerInput, PointerInputOptions } from './types'\n\n// Default thresholds for click detection\nconst DEFAULT_CLICK_MOVE_THRESHOLD = 3\nconst DEFAULT_CLICK_FRAME_THRESHOLD = 30\n\n// Query for pointer entities with change tracking\nconst pointerQuery = defineQuery((q) => q.tracking(Pointer))\n\n/**\n * Per-context state for tracking pointer events across frames.\n * Keyed by context readerId to support multiple editor instances.\n */\ninterface PointerTrackingState {\n /** Previous frame's pointer positions for movement detection */\n prevPositions: Map<number, Vec2>\n /** Previous modifier key state */\n prevModifiers: {\n shiftDown: boolean\n altDown: boolean\n modDown: boolean\n }\n /** Previous camera state for detecting camera movement during drag */\n prevCamera: {\n left: number\n top: number\n zoom: number\n }\n}\n\nconst trackingState = new Map<string, PointerTrackingState>()\n\nfunction getTrackingState(ctx: Context): PointerTrackingState {\n const key = ctx.readerId\n let state = trackingState.get(key)\n if (!state) {\n state = {\n prevPositions: new Map(),\n prevModifiers: {\n shiftDown: false,\n altDown: false,\n modDown: false,\n },\n prevCamera: {\n left: 0,\n top: 0,\n zoom: 1,\n },\n }\n trackingState.set(key, state)\n }\n return state\n}\n\n/**\n * Generate high-level pointer input events from ECS state for state machine consumption.\n *\n * This function transforms raw Pointer component data into semantic events\n * suitable for XState machines. It handles:\n *\n * - **pointerDown** - When a new pointer matching the specified buttons is added\n * - **pointerUp** - When a matching pointer is removed\n * - **pointerMove** - When a matching pointer's position changes, modifier keys change, or camera moves\n * - **click** - After pointerUp, if the pointer didn't move much and wasn't held long\n * - **cancel** - When Escape is pressed or multi-touch is detected\n * - **frame** - Optional continuous event while pointer is active\n *\n * @param ctx - ECS context\n * @param buttons - Array of pointer buttons to filter for (e.g., ['left', 'middle'])\n * @param options - Optional configuration\n * @returns Array of pointer input events to process\n *\n * @example\n * ```typescript\n * import { getPointerInput, runMachine } from '@woven-canvas/plugin-xstate';\n *\n * const panSystem = defineSystem((ctx) => {\n * const events = getPointerInput(ctx, ['middle']);\n * if (events.length === 0) return;\n *\n * const { value, context } = runMachine(panMachine, state.state, state.context, events);\n * // Update state...\n * });\n * ```\n */\nexport function getPointerInput(\n ctx: Context,\n buttons: PointerButton[],\n options: PointerInputOptions = {},\n): PointerInput[] {\n if (buttons.length === 0) return []\n\n const {\n includeFrameEvent = false,\n clickMoveThreshold = DEFAULT_CLICK_MOVE_THRESHOLD,\n clickFrameThreshold = DEFAULT_CLICK_FRAME_THRESHOLD,\n } = options\n\n const state = getTrackingState(ctx)\n const frameNumber = Frame.read(ctx).number\n\n const events: PointerInput[] = []\n\n // Get keyboard state for modifiers\n const keyboard = Keyboard.read(ctx)\n const modifiers = {\n shiftDown: keyboard.shiftDown,\n altDown: keyboard.altDown,\n modDown: keyboard.modDown,\n }\n\n // Get camera state\n const camera = Camera.read(ctx)\n\n // Helper to check if pointer button matches filter\n const matchesButtons = (entityId: EntityId) => {\n const pointer = Pointer.read(ctx, entityId)\n return buttons.includes(pointer.button)\n }\n\n // Get current intersects\n const intersects = Intersect.getAll(ctx)\n\n // Helper to create event from pointer\n const createEvent = (type: PointerInput['type'], entityId: EntityId): PointerInput => {\n const pointer = Pointer.read(ctx, entityId)\n const screenPos: Vec2 = [pointer.position[0], pointer.position[1]]\n const worldPos = Camera.toWorld(ctx, screenPos)\n\n return {\n type,\n ctx,\n screenPosition: screenPos,\n worldPosition: worldPos,\n velocity: [pointer._velocity[0], pointer._velocity[1]],\n pressure: pointer.pressure,\n button: pointer.button,\n pointerType: pointer.pointerType,\n obscured: pointer.obscured,\n shiftDown: modifiers.shiftDown,\n altDown: modifiers.altDown,\n modDown: modifiers.modDown,\n cameraLeft: camera.left,\n cameraTop: camera.top,\n cameraZoom: camera.zoom,\n pointerId: entityId,\n intersects,\n }\n }\n\n // Get query results\n const addedPointers = pointerQuery.added(ctx)\n const removedPointers = pointerQuery.removed(ctx)\n const changedPointers = pointerQuery.changed(ctx)\n const currentPointers = pointerQuery.current(ctx)\n\n // Filter by button\n const matchingAdded = addedPointers.filter(matchesButtons)\n const matchingRemoved = removedPointers.filter(matchesButtons)\n const matchingChanged = changedPointers.filter(matchesButtons)\n const matchingCurrent = Array.from(currentPointers).filter(matchesButtons)\n\n // Check for cancel conditions\n const escapePressed = Keyboard.isKeyDownTrigger(ctx, Key.Escape)\n const multiTouch = matchingCurrent.length > 1 && matchingAdded.length > 0\n\n if ((escapePressed || multiTouch) && matchingCurrent.length > 0) {\n // Generate cancel event using the first current pointer\n events.push(createEvent('cancel', matchingCurrent[0]))\n return events\n }\n\n // Handle pointer down (new pointer added, and we now have exactly 1 matching)\n if (matchingAdded.length > 0 && matchingCurrent.length === 1) {\n const entityId = matchingCurrent[0]\n const pointer = Pointer.read(ctx, entityId)\n\n // Only generate pointerDown if not obscured\n if (!pointer.obscured) {\n events.push(createEvent('pointerDown', entityId))\n\n // Store initial position for click detection\n state.prevPositions.set(entityId, [pointer.position[0], pointer.position[1]])\n }\n }\n\n // Handle pointer up (pointer removed, we now have 0 matching)\n if (matchingRemoved.length > 0 && matchingCurrent.length === 0) {\n const entityId = matchingRemoved[0]\n const pointer = Pointer.read(ctx, entityId)\n\n events.push(createEvent('pointerUp', entityId))\n\n // Check for click\n const downPos = state.prevPositions.get(entityId)\n if (downPos) {\n const currentPos: Vec2 = [pointer.position[0], pointer.position[1]]\n const dist = Vec2.distance(downPos, currentPos)\n const deltaFrame = frameNumber - pointer.downFrame\n\n if (dist < clickMoveThreshold && deltaFrame < clickFrameThreshold) {\n events.push(createEvent('click', entityId))\n }\n\n state.prevPositions.delete(entityId)\n }\n }\n\n // Handle pointer move (position changed, modifier keys changed, or camera moved)\n const modifiersChanged =\n modifiers.shiftDown !== state.prevModifiers.shiftDown ||\n modifiers.altDown !== state.prevModifiers.altDown ||\n modifiers.modDown !== state.prevModifiers.modDown\n\n const cameraChanged =\n camera.left !== state.prevCamera.left ||\n camera.top !== state.prevCamera.top ||\n camera.zoom !== state.prevCamera.zoom\n\n if ((matchingChanged.length > 0 || modifiersChanged || cameraChanged) && matchingCurrent.length === 1) {\n events.push(createEvent('pointerMove', matchingCurrent[0]))\n }\n\n // Handle frame event\n if (includeFrameEvent && matchingCurrent.length === 1) {\n events.push(createEvent('frame', matchingCurrent[0]))\n }\n\n // Update previous modifier and camera state\n state.prevModifiers = { ...modifiers }\n state.prevCamera = { left: camera.left, top: camera.top, zoom: camera.zoom }\n\n return events\n}\n\n/**\n * Clear tracking state for a context.\n * Call this when the editor is destroyed.\n *\n * @param ctx - ECS context\n */\nexport function clearPointerTrackingState(ctx: Context): void {\n trackingState.delete(ctx.readerId)\n}\n"],"mappings":"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","names":["BlockDef","import_canvas_store","import_core","import_canvas_store","import_core","import_math","import_canvas_store","import_core","AabbMath","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_canvas_store","import_core","import_math","import_canvas_store","import_core","import_canvas_store","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","BlockDef","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","CursorDef","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_canvas_store","import_core","import_core","import_core","import_core","import_core","getBit","import_core","instanceState","import_core","instanceState","import_core","instanceState","import_core","import_core","import_core","BlockDef","import_math","import_core","import_core","import_math","import_core","import_math","import_core","_uvToWorldMatrix","AabbNs","import_core","pointer","import_core","pointerQuery","import_canvas_store","import_core","added","import_math","import_canvas_store","import_core","blocksQuery","AabbMath","import_math","import_core","import_canvas_store","import_core","import_zod","BlockDef","import_canvas_store","import_math","import_core","pointerQuery"]}
|