@weasel-js/routing 1.9.2 → 1.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RTCD26NN.js → chunk-LOP2JTTA.js} +32 -3
- package/dist/chunk-LOP2JTTA.js.map +1 -0
- package/dist/{index-X6vX2tYX.d.ts → index-CrbDNXT_.d.ts} +11 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/{internal-DTWYD6-s.d.ts → internal-B1B6gfOS.d.ts} +1 -1
- package/dist/internal.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/react.js.map +1 -1
- package/package.json +7 -7
- package/dist/chunk-RTCD26NN.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interactions/actions/binding.ts","../src/interactions/actions/buildDeps.ts","../src/interactions/actions/scopeNode.ts","../src/interactions/actions/depNode.ts","../src/interactions/actions/registry.ts","../src/interactions/actions/invoker.ts","../src/interactions/actions/toolOffhand.ts","../src/contributions/eligibility.ts","../src/contributions/assemble.ts","../src/devFlag.ts","../src/interactions/dispatcher/matcher.ts","../src/tools/routing/reflection/registry.ts","../src/eligibility/deviceProfile.ts","../src/eligibility/rule.ts","../src/eligibility/exclusive.ts","../src/eligibility/ruleCtx.ts","../src/interactions/dispatcher/dispatcher.ts","../src/interactions/dispatcher/longPressState.ts","../src/interactions/pointerSession/pointerSession.ts","../src/tools/types.ts","../src/tools/routing/reflection/conflicts.ts","../src/interactions/keyHelpers.ts","../src/ingestion/ingestItems.ts","../src/viewport/clientToCanvas.ts","../src/dlog.ts"],"names":["DEV","EMPTY_ENGAGED","activeModeOf"],"mappings":"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","file":"chunk-RTCD26NN.js","sourcesContent":["/**\n * GestureBinding — connects a GestureSpec to an Action id (with per-binding\n * options). Tools own arrays of these on their `bindings` field; ambient\n * gesture-bindings are registered globally.\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md`.\n */\n\nimport type { GestureSpec } from '@weasel-js/gestures';\nimport type { BindingOpts } from './invoker';\n\n/** An interaction: a gesture spec composed with the id of the action it\n * invokes. Tools declare arrays of these; the dispatcher matches an incoming\n * input event against them and runs the winner's action. */\nexport interface GestureBinding {\n spec: GestureSpec;\n actionId: string;\n opts?: BindingOpts;\n}\n\n/**\n * @experimental\n * A single entry in `Action.defaultBinding[]`. Either a bare `GestureSpec`\n * (no per-binding opts) or an object form that pairs a spec with\n * `BindingOpts` for parametric actions (e.g. `{ params: { axis: 'x' } }`).\n * Use the object form when two bindings for the same action differ only in\n * a runtime parameter — the dispatcher extracts `opts.params` and passes\n * them to `ImmediateInvoker.run` as its second argument.\n */\nexport type BoundGesture = GestureSpec | { spec: GestureSpec; opts: BindingOpts };\n\n/**\n * @experimental\n * The whole of an action `actionBindings` reads. Routing needs this much and\n * none of `Action`'s palette fields, so it is the narrowest type the\n * dispatcher's binding walk can be written against.\n */\nexport interface BindingSource {\n id: string;\n /** The gesture-spec form of the binding, read by the gesture dispatcher.\n * May be a single `GestureSpec`, a bare `GestureSpec[]` (any-of semantics),\n * or a `BoundGesture[]` where each entry is either a bare `GestureSpec` or\n * `{ spec, opts }` — use the object form for parametric actions where two\n * bindings for the same action differ only by `opts.params` (e.g. `flip`\n * with `axis: 'x'` vs `'y'`). The dispatcher extracts `opts.params` and\n * passes them to `ImmediateInvoker.run` as its second argument. */\n defaultBinding?: GestureSpec | BoundGesture[];\n}\n\n/**\n * @experimental\n * Flatten an action's `defaultBinding` into `GestureBinding`s. A bare\n * `GestureSpec` has `kind` at top level; the object form has `spec`.\n */\nexport function actionBindings(action: BindingSource): GestureBinding[] {\n const gs = action.defaultBinding;\n if (!gs) return [];\n const raw: BoundGesture[] = Array.isArray(gs) ? gs : [gs as BoundGesture];\n return raw.map((entry) => {\n const isBoundObj = !('kind' in entry);\n const spec = isBoundObj ? (entry as { spec: GestureSpec }).spec : (entry as GestureSpec);\n const opts = isBoundObj ? (entry as { opts: BindingOpts }).opts : undefined;\n return { spec, actionId: action.id, ...(opts !== undefined ? { opts } : {}) };\n });\n}\n","/**\n * Shared dep-bag builder — the single implementation behind both the gesture\n * dispatcher's per-invocation `buildDeps` and `ActionsRegistry.trigger`'s\n * `requires` branch. Reads the action's declared `requires`, resolves each\n * name against the `DepRegistry`, and (dev builds only) wraps the bag in a\n * Proxy that warns on undeclared reads.\n */\nimport type { Action } from './action';\nimport type { DepRegistry } from './depNode';\nimport type { ActionDeps } from './invoker';\n\n/** True in dev builds; false in production. Tree-shakes the Proxy out of\n * prod entirely. (Mirrors the dispatcher's own `DEV` const.) */\nconst DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\n/** Build the deps bag for an action from its declared `requires`. */\nexport function buildDepsFromRequires(action: Action, depRegistry: DepRegistry): ActionDeps {\n const requires = action.requires ?? [];\n const entries = requires.map((name) => [name, depRegistry.get(name)]);\n const deps = Object.fromEntries(entries) as ActionDeps;\n\n // Dev-only: wrap deps in a Proxy that warns when the invoker reads a\n // key not declared in `requires`. Catches silent-failure-by-typo or\n // forgotten-requires (the #1 bug class in this codebase pre-Phase-14e).\n // Production builds: bypass the Proxy entirely (zero overhead).\n if (DEV) {\n const declared = new Set<string>(requires);\n return new Proxy(deps as Record<string, unknown>, {\n get(target, prop, receiver) {\n if (typeof prop === 'string' && !declared.has(prop) && prop !== 'then') {\n const message =\n `[weasel:dispatcher] action \"${action.id}\" read deps.${prop} but did not declare it in \\`requires\\`. ` +\n `Add \\`requires: [...'${prop}']\\` to the descriptor or the dep will be undefined at runtime.`;\n // Warn first so the console trail survives even when the throw is\n // swallowed by a caller, then throw so the gesture fails visibly\n // instead of silently running without the dep.\n console.warn(message);\n throw new Error(message);\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as ActionDeps;\n }\n return deps;\n}\n","/**\n * The tree both input registries hang on. A provider is a root; every canvas\n * mounts a scope under the registry in scope; a yoke sits between the two. A\n * registration lives in the node it was made in, and a lookup starts at a leaf\n * and walks up, so one canvas never answers for another.\n *\n * Design: docs/proposals/2026-09-27-input-scopes.md.\n */\n\n/** What every node of one tree shares: a version and the listeners to it. */\nexport interface ScopeTree {\n version: number;\n readonly listeners: Set<() => void>;\n}\n\nexport class ScopeNode<N extends ScopeNode<N>> {\n readonly tree: ScopeTree;\n private readonly children: N[] = [];\n private activeChild: N | null = null;\n\n /** `descends`: whether reads made here answer from the active child down —\n * true for a root or a yoke, which chrome reads through; false for a scope,\n * which answers for itself even with a scope nested inside it. */\n constructor(readonly parent: N | null, readonly descends: boolean) {\n this.tree = parent ? parent.tree : { version: 0, listeners: new Set() };\n }\n\n /** Bump the tree's version and tell every listener in it. */\n changed(): void {\n this.tree.version++;\n for (const listener of this.tree.listeners) {\n try {\n listener();\n } catch (err) {\n console.error('weasel input scope: subscriber threw', err);\n }\n }\n }\n\n /** Join the parent's children, newest last; returns the leave. */\n mount(): () => void {\n const parent = this.parent;\n if (!parent) return () => {};\n parent.children.push(this as unknown as N);\n this.changed();\n let left = false;\n return () => {\n if (left) return;\n left = true;\n const i = parent.children.lastIndexOf(this as unknown as N);\n if (i !== -1) parent.children.splice(i, 1);\n if (parent.activeChild === (this as unknown as N)) parent.activeChild = null;\n this.changed();\n };\n }\n\n /** Make this node the one its ancestors resolve through. */\n activate(): void {\n let moved = false;\n for (let n = this as unknown as N; n.parent; n = n.parent) {\n if (n.parent.activeChild !== n) {\n n.parent.activeChild = n;\n moved = true;\n }\n }\n if (moved) this.changed();\n }\n\n /** The node a lookup made here starts from: down the active children, or the\n * newest where nothing has been activated yet. A yoke with no members yet\n * is passed over — there is no canvas behind it to answer. */\n leaf(): N {\n let n = this as unknown as N;\n for (;;) {\n const next: N | null = n.activeChild ?? n.newestMember();\n if (!next) return n;\n n = next;\n }\n }\n\n private newestMember(): N | null {\n for (let i = this.children.length - 1; i >= 0; i--) {\n const c = this.children[i]!;\n if (!(c.descends && c.children.length === 0)) return c;\n }\n return null;\n }\n\n /** Where a read made through this node starts. */\n start(): N {\n return this.descends ? this.leaf() : (this as unknown as N);\n }\n\n /** Whether this node is on the path a read from the root takes. */\n isActive(): boolean {\n let root = this as unknown as N;\n while (root.parent) root = root.parent;\n for (const n of root.leaf().chain()) if (n === (this as unknown as N)) return true;\n return false;\n }\n\n /** This node, then each ancestor up to the root. */\n *chain(): Generator<N> {\n for (let n: N | null = this as unknown as N; n; n = n.parent) yield n;\n }\n}\n\n/**\n * Push `value` onto an owner stack and hand back its release.\n *\n * Newest wins, but the release takes out *its own* entry wherever it now sits,\n * so a displaced owner leaving cannot disturb the one above it. A `null` value\n * registers nothing and releases to a no-op. Double-release safe.\n */\nexport function pushOwner<T>(stack: T[], value: T | null): () => void {\n if (value === null) return () => {};\n stack.push(value);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const i = stack.lastIndexOf(value);\n if (i !== -1) stack.splice(i, 1);\n };\n}\n","/**\n * Dep registry for registry unification.\n *\n * Holds named \"live source\" thunks. Actions declare `requires: ['selection']`;\n * the dispatcher calls `registry.get('selection')` at invocation time to\n * build a typed Deps bag.\n *\n * `DepSchema` — the map of dep name → value type — is the single source of\n * truth for what `requires`/`register`/`get` accept. Its concrete fields live\n * in `./depSchema` (co-located with the dep value types). It is declared there\n * as a plain `export interface` rather than via a cross-module\n * `declare module './depRegistry'` augmentation: that augmentation does NOT\n * merge once rollup-plugin-dts flattens both files into one `.d.ts` chunk,\n * which silently emptied `DepSchema` for consumers. Consumers still extend it\n * via `declare module '@weasel-js/core'` augmentation.\n */\nimport type { DepSchema, DepName } from '../../index';\nimport { ScopeNode } from './scopeNode';\n\n/** Holds the live sources an action's declared dependencies resolve to.\n * Sources are thunks, read at invocation time, so an action never captures\n * stale state. */\nexport interface DepRegistry {\n register<K extends DepName>(name: K, source: () => DepSchema[K]): () => void;\n get<K extends DepName>(name: K): DepSchema[K] | undefined;\n}\n\n/** One node of the dep tree: the sources registered at it, over its parent's.\n * Each name holds a stack of sources, newest live, so a displaced source is\n * restored when the one above it leaves. */\nexport class DepNode extends ScopeNode<DepNode> {\n private readonly sources = new Map<string, (() => unknown)[]>();\n\n readonly registry: DepRegistry = {\n register: <K extends DepName>(name: K, source: () => DepSchema[K]) => {\n const key = name as string;\n const entry = source as () => unknown;\n const stack = this.sources.get(key);\n if (stack) stack.push(entry);\n else this.sources.set(key, [entry]);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = this.sources.get(key);\n if (!cur) return;\n // Our own entry, wherever it now sits: a source already displaced must\n // take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(entry);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) this.sources.delete(key);\n };\n },\n get: <K extends DepName>(name: K) => {\n for (const n of this.start().chain()) {\n const source = n.sources.get(name as string)?.at(-1);\n if (source) return source() as DepSchema[K];\n }\n return undefined;\n },\n };\n\n constructor(parent: DepNode | null, descends: boolean) {\n super(parent, descends);\n NODES.set(this.registry, this);\n }\n}\n\nconst NODES = new WeakMap<DepRegistry, DepNode>();\n\n/** The tree node behind `registry`, when it is one of ours. */\nexport function depNodeOf(registry: DepRegistry | null): DepNode | null {\n return registry ? (NODES.get(registry) ?? null) : null;\n}\n\n/**\n * A stock dep registry with no parent: what `<DepRegistryProvider>` mounts,\n * for a dispatcher driven without React. Sources registered under one name\n * stack, newest live, and releasing one restores the one beneath it.\n */\nexport function createDepRegistry(): DepRegistry {\n return new DepNode(null, true).registry;\n}\n","/**\n * @experimental\n * The actions store contract and the `actions` prop that seeds it. The\n * provider that implements this lives in `ActionsProvider.tsx`; nothing here\n * touches React.\n * Spec: docs/superpowers/specs/2026-05-09-actions-registry-design.md\n */\nimport type { GestureSpec, PhaseSpec } from '@weasel-js/gestures';\nimport type { BoundGesture } from './binding';\nimport type { Action } from './action';\nimport { RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, type PhaseAtom } from '../../tools/routing/routeGrammar';\nimport type { Dispatcher, UiOngoingControl } from '../dispatcher/dispatcher';\nexport type { UiOngoingControl } from '../dispatcher/dispatcher';\n\n\n\n\n\n/**\n * @experimental\n * Partial override or full descriptor passed via `<SceneCanvas actions={...}>`.\n * `null` disables a default at this id.\n */\nexport type ActionEntry = null | Partial<Action> | Action;\n\n/**\n * @experimental\n * Shape of the `actions` prop on `<SceneCanvas>`. `null` disables all defaults.\n */\nexport type ActionsProp = null | Record<string, ActionEntry>;\n\n/**\n * @experimental\n * Imperative API exposed by `useActionsRegistry()`.\n */\nexport interface ActionsRegistry {\n /** Add an action and return its release. Registrants for one id stack,\n * newest live, so releasing yours uncovers whoever you displaced. Call it\n * from an effect and release it in that effect's cleanup — registering from\n * a render body pushes an entry per render and releases none. */\n register(action: Action): () => void;\n /** Drop every registrant of `id`. This is the \"this action should not exist\"\n * door, not a release — for that, call what `register` returned. */\n unregister(id: string): void;\n /** Declare `id` not for this scope: it stays registered wherever it was,\n * but here — and in scopes below — it lists as absent and neither\n * `trigger` nor `begin` will fire it. Returns a release. This is the\n * \"not for me\" door — `unregister` is the \"should not exist\" one. */\n mute(id: string): () => void;\n list(): readonly Action[];\n /** Fire an immediate-invoker action by id. The optional `params` arg is\n * forwarded to `ImmediateInvoker.run` as its second argument — use it for\n * parametric actions (e.g. `trigger('tool.activate', { toolId: 'rect' })`).\n * Ongoing-invoker actions are not reachable from `trigger`. */\n trigger(id: string, params?: Record<string, unknown>): boolean;\n /**\n * Subscribe to registry mutations. The callback fires after any\n * `register`/`unregister` that changes the version. Returns an\n * unsubscribe function. Designed for `useSyncExternalStore`-driven\n * surfaces (e.g. `<ActionBar>` in `@weasel-js/ui`) that need to\n * re-render when the action set changes.\n */\n subscribe(listener: () => void): () => void;\n\n /**\n * Start an ongoing action driven by UI (color picker, opacity slider).\n * Returns a control object with `update(params)` and `end(reason)`.\n *\n * Returns `null` if no dispatcher is wired into this registry, the\n * action is unknown, or its invoker is not ongoing.\n *\n * See `Dispatcher.beginUiOngoing` for full semantics including\n * auto-commit when a prior UI handle for the same action is in flight.\n */\n begin(id: string, params?: Record<string, unknown>): UiOngoingControl | null;\n\n /** Wire a dispatcher into the registry so `begin()` can delegate to it.\n * Returns a release that takes out only this dispatcher; a `null` wires\n * nothing. */\n setDispatcher(d: Dispatcher | null): () => void;\n\n /** Make this registry's scope the one chrome above it reaches: `trigger`,\n * `begin` and `list` on any ancestor then answer from here. A dispatcher\n * calls it on the pointerdown and focus that land in its scope. */\n activate(): void;\n\n /** Whether a lookup made from the root of this registry's tree starts here —\n * the question a dispatcher asks before handling a keystroke. */\n isActive(): boolean;\n}\n\n// ─── Registration-time validation ─────────────────────────────────────────\n\n/** Validate that `id` is usable as an action id in the route grammar.\n * Rejects ids that start with a reserved sigil (would shadow future\n * grammar extensions) and ids that collide with phase keywords (would\n * parse as the bare-phase shorthand). Mirrors `defineTool`'s tool-id\n * validation. */\nexport function validateActionId(id: string): void {\n if (id.length === 0) {\n throw new Error(`weasel: action id may not be empty`);\n }\n if (RESERVED_ID_PREFIXES.has(id[0]!)) {\n throw new Error(\n `weasel: action id \"${id}\" starts with reserved sigil \"${id[0]}\" ` +\n `(reserved set: ${[...RESERVED_ID_PREFIXES].join(' ')})`,\n );\n }\n if (RESERVED_ID_NAMES.has(id)) {\n throw new Error(\n `weasel: action id \"${id}\" collides with a reserved phase keyword ` +\n `(reserved: ${[...RESERVED_ID_NAMES].join(', ')})`,\n );\n }\n}\n\n/** Reject any '&'-channel phase atom in an Action's defaultBinding —\n * actions have no owning tool, so '&' can't resolve. Tool-side bindings\n * (Tool.bindings) are the right place for '&' atoms. */\nexport function validateActionDefaultBinding(action: Action): void {\n const gs = action.defaultBinding;\n if (!gs) return;\n const entries: BoundGesture[] = Array.isArray(gs) ? gs : [gs as BoundGesture];\n for (const entry of entries) {\n const spec = ('kind' in entry ? entry : entry.spec) as GestureSpec;\n const phase: PhaseSpec | undefined = spec.phase;\n if (phase === undefined) continue;\n const atoms: readonly PhaseAtom[] = Array.isArray(phase)\n ? phase\n : [{ channel: '&', phase: phase }];\n for (const atom of atoms) {\n if (atom.channel === '&') {\n throw new Error(\n `weasel: action \"${action.id}\" defaultBinding uses '&' channel ` +\n `which has no owning tool to resolve to. Use a named tool channel ` +\n `(e.g. '[rect:engaged]') or '*' instead, or move this binding to ` +\n `the tool's own Tool.bindings.`,\n );\n }\n }\n }\n}\n\n","/**\n * Invoker — pluggable invocation strategy for an Action.\n *\n * An Action's `invoker` field describes how it's run. `immediate` invokers\n * fire once (delete, align, undo). `ongoing` invokers open a phase machine\n * driven by the dispatcher (move, resize, pinch-zoom).\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md`\n * § \"Types\" for the full design.\n */\n\nimport type { ModifierState, ResizeAnchor } from '../../vocabulary';\nimport type { ClaimableGesture } from '@weasel-js/gestures';\n\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { DepSchema } from '../../index';\n\nexport type { ModifierState } from '../../vocabulary';\n\n/** A 2D point in either world or screen coordinates. */\nexport interface Point2 {\n x: number;\n y: number;\n}\n\n/**\n * Information about which UI affordance was hit at pointerdown.\n *\n * Populated by the dispatcher when the `affordanceAt` thunk is provided to\n * `useGestureDispatcher`. Tools / action invokers that only fire on a specific\n * affordance (e.g. a resize handle) use this field as a guard — if the\n * affordance is absent or is the wrong kind, they return `{}` and let other\n * bindings handle the drag.\n *\n * `kind` is a discriminator string:\n * - `'handle:top-left'` / `'handle:top-right'` / `'handle:bottom-left'` /\n * `'handle:bottom-right'` — corner resize handles.\n * - `'rotate-handle'` — the rotation affordance.\n * - `'anchor:N'` — a path anchor at index N.\n *\n * `fixedPoint` is the world-space point that should remain stationary during\n * the gesture. For resize handles this is the opposite (diagonally fixed)\n * corner; for rotate it is the pivot.\n *\n * `targetIds` are the node ids this affordance belongs to.\n */\nexport interface AffordanceHit {\n /** Discriminator string, e.g. `'handle:bottom-right'`. */\n kind: string;\n /** Id of whatever produced this hit — a kit affordance's `id`, or the\n * registered layer's id. Read only by the dispatcher's dead-claim warning today. */\n owner?: string;\n /** `'exclusive'` means no binding may act on this point unless its target\n * consults the affordance. `'shared'` (the default) competes on scope and\n * specificity as bindings always have. */\n strength?: 'exclusive' | 'shared';\n /** Which gestures an exclusive claim bars. Omitted bars all of them. */\n claimedKinds?: readonly ClaimableGesture[];\n /** World-space fixed/pivot point. For resize: opposite corner. For rotate: pivot. */\n fixedPoint?: { x: number; y: number };\n /** Which nodes this affordance belongs to. */\n targetIds?: string[];\n /** Set when `kind` matches `'handle:*'`. Identifies which corner stays\n * fixed during a resize so consumers (resizeAction) don't re-parse `kind`.\n * Other affordance kinds (rotate-handle, anchor:N, controlIn:N, controlOut:N)\n * leave this undefined. */\n anchor?: ResizeAnchor;\n /** Cursor to show while the pointer hovers this affordance (no\n * gesture in flight). Consumed by the hover-cursor pump in\n * `useGestureDispatcher`; unset = the pump falls through to\n * action-cursor prediction, then to the active tool's cursor. */\n cursor?: CursorSpec;\n /**\n * Free-form payload from whatever produced the hit, carried through to the\n * matching action untouched.\n *\n * Kit affordances describe themselves fully in the fields above and leave\n * this unset. It exists for affordances the kit doesn't know the shape of —\n * a registered layer's own chrome, where the hit-test already resolved\n * *which* of its pieces was hit and the action would otherwise have to\n * redo that work. `@weasel-js/hud` passes the hit widget here.\n */\n payload?: unknown;\n}\n\n/**\n * One accumulated point on a drag trail: world-space position plus whatever\n * stylus state the originating `PointerEvent` carried.\n *\n * The stylus fields are absent for mouse/touch on browsers that don't report\n * them, and for synthetic events. Consumers that want pressure-driven output\n * (e.g. `Stroke.vertexWidths` from a pencil stroke) read them off the samples\n * their `insert` dep receives — see `apps/site/demos/StrokeAndFillDemo.tsx`.\n */\nexport interface DragSample extends Point2 {\n /** 0..1. Mouse/touch report 0.5 while a button is held, per the spec. */\n pressure?: number;\n /** Degrees, ±90. Zero for mouse/touch. */\n tiltX?: number;\n /** Degrees, ±90. Zero for mouse/touch. */\n tiltY?: number;\n}\n\n/** Per-invocation runtime context the dispatcher hands to an Invoker.\n * Gesture-kind-specific fields (`drag`, `wheel`, `multiTouch`, `key`) are\n * populated only for matching gesture kinds. */\nexport interface InvocationCtx {\n world: Point2;\n /**\n * The pointer in client/screen pixels, for an action that has to place DOM\n * at the pointer. Absent on every invocation whose event carries no client\n * coordinates — a keystroke, a UI-driven trigger, a synthetic probe — so\n * read it with a fallback rather than assuming a point.\n *\n * A view-mutating drag wants `drag.screenDelta`, not the difference of two\n * of these: world deltas are self-referential mid-pan, and so is any delta\n * taken across a view change.\n */\n screen?: Point2;\n modifiers: ModifierState;\n deps: ActionDeps;\n drag?: {\n start: Point2;\n current: Point2;\n delta: Point2;\n /**\n * Drag delta in client/screen coordinates (CSS pixels from the drag\n * origin). Use this — never `delta` — for any action whose effect\n * mutates the viewport itself (pan, view-zoom), because world-space\n * deltas become self-referential as the view shifts mid-drag.\n *\n * Populated when the dispatcher received `clientX`/`clientY` on the\n * underlying pointer events. Absent for legacy callers that don't\n * provide them.\n */\n screenDelta?: Point2;\n affordance?: AffordanceHit;\n /**\n * Full pointermove history for the current drag, in world space, with\n * per-sample stylus state when the browser reported it.\n * Accumulated by the dispatcher on every `pointermove` pump event.\n * Available only during `onMove` and `onEnd` calls (not on `start`).\n *\n * During `onMove` this is the dispatcher's live accumulator, and it grows\n * under you — read it, don't retain it. On `onEnd` it is a snapshot, so\n * that is where an action that keeps the trail should take it.\n * Used by `lassoSelectAction` to build its polygon vertex list and by\n * `insertAction`'s pencil kind to carry the freehand stroke.\n */\n points?: DragSample[];\n };\n wheel?: { deltaX: number; deltaY: number; deltaZ: number };\n /** One `pinch` sample: `scale` is a multiplier since the previous sample,\n * `rotation` degrees since it. See `PinchEvent`. */\n pinch?: { scale: number; rotation: number };\n multiTouch?: {\n /** Canvas-local CSS pixels — see `MultiTouchEvent.centroid`. Neither\n * `world` nor `screen`: it is the space `zoomAt` anchors in, so passing\n * it through `clientToWorld` removes the canvas origin twice. */\n centroid: Point2;\n /** Distance between the two primary pointers, in CSS pixels. */\n spread: number;\n rotation: number;\n /**\n * Pinch-zoom geometry. Populated by the dispatcher when a multitouch\n * handle is in flight and a pointermove-pump fires.\n * `startSpread` is the spread at the moment the gesture began.\n * `currentSpread` is the spread at the current frame.\n */\n pinch?: {\n startSpread: number;\n currentSpread: number;\n /** Canvas-local, same as the enclosing `centroid`. */\n centroid: Point2;\n };\n };\n key?: { key: string; repeat: boolean };\n /**\n * The view the input landed in, as the surface's view resolver assigned it:\n * a view id, or `null` for the surface's own camera. Absent where no\n * surface routed the input — a UI-driven trigger, a bare dispatcher.\n */\n viewId?: string | null;\n /**\n * Per-invocation parameters. Populated by `ActionsRegistry.begin()` for\n * UI-driven ongoing actions (color picker, opacity slider) so handles can\n * read the current value on `start` and updated values on `onMove`. The\n * gesture dispatcher does not populate this field; gesture-driven actions\n * receive params via `BindingOpts.params` on `start` (the `opts` arg).\n */\n params?: Record<string, unknown>;\n}\n\n/** Per-invocation options the dispatcher reads from a `GestureBinding`'s\n * `opts` field and passes to `OngoingInvoker.start`. Today carries\n * behaviors; extensible. */\nexport interface BindingOpts {\n /** Gesture behaviors the action's own invoker runs. Routing carries the\n * array to the action and never reads an element, so the element type is\n * open here; `@weasel-js/core` narrows it to `ActionBehavior<unknown,\n * unknown, unknown>[]`, which is what a behavior is authored against. */\n behaviors?: unknown[];\n /** Per-binding action parameters. The action's invoker reads\n * these via the second arg to `run` (or via InvocationCtx for ongoing\n * invokers, when needed). Loose typing (Record<string, unknown>) for\n * now; consider per-action typing later via BindingOpts<A>.\n *\n * params may also be a thunk evaluated each time the\n * dispatcher (or invoker) needs the value. Thunks let tools close over\n * refs that mutate during a gesture (e.g. polygon `sides` adjusted\n * mid-drag via ArrowUp). For ongoing invokers that want the latest\n * values at commit, the invoker can re-call the thunk inside `onEnd`\n * via `resolveParams(opts?.params)`. */\n params?: Record<string, unknown> | (() => Record<string, unknown>);\n /**\n * The views this binding is live in, by id, where `null` is the surface's\n * own camera. Omitted means every view.\n *\n * A binding that names the view an input landed in outranks every binding\n * that does not, whatever their scope tiers: naming a view is the most\n * specific thing a binding can say about where it applies. Without that, a\n * drag bound inside a minimap view loses to the active tool's marquee.\n */\n views?: readonly (string | null)[];\n}\n\n/** Resolve `BindingOpts.params` to a concrete record (calling the thunk if\n * needed). Returns `undefined` for absent params. */\nexport function resolveParams(\n params: BindingOpts['params'],\n): Record<string, unknown> | undefined {\n if (params === undefined) return undefined;\n return typeof params === 'function' ? params() : params;\n}\n\n/** The deps an action receives, composed per call from what it `requires`.\n * Each name resolves to its {@link DepSchema} entry, and is absent when no\n * source registered it; a name nothing has declared passes through as\n * `unknown`. */\nexport interface ActionDeps extends Partial<DepSchema> {\n [k: string]: unknown;\n}\n\n/**\n * What a `polyline` overlay is, in a word — the narrowest thing an action can\n * say about how its run should look without naming a paint.\n *\n * The named roles are the kit's; a painter maps each to a style and falls back\n * to plain chrome for one it does not know, so a package outside core can coin\n * its own and still be drawn.\n */\nexport type OverlayRole =\n /** Generic in-flight chrome — the marquee/lasso paint. */\n | 'chrome'\n /** A cut the gesture would make. */\n | 'cut'\n /** An edge the gesture would author between two points. */\n | 'connector'\n | (string & {});\n\n/**\n * What an in-flight gesture proposes to paint *beside* the scene, returned by\n * `OngoingHandle.overlay()` — a marquee rect, a lasso trail, the outline of a\n * shape being dragged out, the line a slice would cut along.\n *\n * Every variant is world geometry and nothing else. No `DrawCommand`, no\n * color, no coordinate space to choose: an action that reached for any of\n * those would be publishing core's own 2D vocabulary, and a surface rendering\n * the same gesture some other way could not read it. `resolveOverlays`\n * normalizes this into `ResolvedOverlay`, which is what a painter consumes —\n * `useDispatcherOverlayLayer` is core's, and it owns every style decision.\n */\nexport type OngoingOverlay =\n | {\n kind: 'marquee';\n start: { x: number; y: number };\n current: { x: number; y: number };\n shiftHeld: boolean;\n }\n | {\n kind: 'lasso';\n vertices: ReadonlyArray<{ x: number; y: number }>;\n current: { x: number; y: number };\n shiftHeld: boolean;\n }\n | {\n /**\n * An open run of world points the gesture is proposing — the slice\n * action's cut line, `@weasel-js/diagram`'s routed connector.\n *\n * Geometry only, like every other variant: `role` is the whole of what\n * an action says about appearance, and the painting surface is what\n * turns it into a stroke. An action that picked its own color would be\n * unpaintable by any renderer but the one it had in mind.\n */\n kind: 'polyline';\n /** At least two points. Anything shorter is dropped in resolution. */\n points: ReadonlyArray<{ x: number; y: number }>;\n /** What the run means. Omitted reads as {@link OverlayRole} `'chrome'`. */\n role?: OverlayRole;\n }\n | {\n /**\n * Live insert-drag preview — dispatched by `insertAction` while the\n * user is dragging out a new shape. Pre-commit there is no scene node\n * to ghost via `previewIds()`/`previewPose()`, so insert paints its\n * preview through the dispatcher overlay layer instead.\n *\n * `shape` is the kit's built-in insert kind. `bounds` is the AABB of\n * the current drag (start/current normalized). `extras` is the\n * per-kind extras the action already collected — the overlay\n * renderer rebuilds the shape using the same path builders the\n * commit factory uses, so the preview matches the eventual node.\n *\n * `extras` is opaque (`unknown`) at the union level; the overlay\n * renderer narrows on `shape` and casts the field shape it expects.\n */\n kind: 'insertPreview';\n /** Which preview the dispatcher's overlay draws. The kit's own shape\n * kinds are the ones it knows how to render; a consumer-defined kind\n * is legal and simply gets no live preview. */\n shape: string;\n bounds: { x: number; y: number; width: number; height: number };\n extras: unknown;\n /** World-space point to paint a small \"anchor\" dot at. Sells the\n * click point as the drag's anchor — particularly useful for\n * radial shapes (polygon/star) where no vertex sits on the\n * click point, and for any shape in center mode where the dot\n * marks the center the shape grows around. */\n anchorPoint?: { x: number; y: number };\n };\n\n/** Handle returned from an `OngoingInvoker.start`. The dispatcher pumps\n * `onMove` on subsequent input events of the same gesture and calls\n * `onEnd` exactly once (with `'commit'` on natural completion or `'cancel'`\n * on pointercancel / blur / escape). */\nexport interface OngoingHandle {\n /**\n * Optional logical action kind — a stable, human-readable tag the\n * dispatcher exposes via `getActiveAction()` for chrome-visibility\n * rules and any other surface that wants to react to \"what action\n * is currently in flight\" without inspecting handles directly.\n *\n * Examples: `'marquee'`, `'lasso'`, `'move'`, `'resize'`, `'rotate'`,\n * `'pan'`, `'pinch'`.\n *\n * Distinct from the dispatcher's internal `gestureId` (`pointer-mouse`,\n * `key-held-Space`, etc.) which keys per-pointer state and is not\n * meaningful to consumers.\n *\n * When omitted, the action is \"anonymous\" — `getActiveAction().kind`\n * reports `null` even though a handle is in flight. This is fine for\n * actions that don't have visible chrome of their own.\n */\n kind?: string;\n\n onMove?(ctx: InvocationCtx): void;\n onEnd?(ctx: InvocationCtx, reason: 'commit' | 'cancel'): void;\n\n /**\n * Optional preview surface — dispatcher-side ghost overlay.\n *\n * An ongoing-action implementation may populate `previewIds()` +\n * `previewPose(id)` to expose its in-flight preview state for the\n * canvas's preview-ghost layer (`usePreviewGhostLayer`) to render on\n * top of the committed scene during the gesture.\n *\n * Returning `null` (or omitting the method entirely) means \"no preview\n * this gesture\" — the canvas will skip this handle as a source.\n *\n * Semantics mirror the tool-side `Tool.previewIds` / `Tool.previewPose`\n * pair: `previewIds()` enumerates the displaced node ids; `previewPose(id)`\n * returns the interim pose for one of those ids (shape opaque — the\n * canvas casts to its `TPose` parameter). The preview-ghost layer\n * merges all sources via first-non-null semantics, with tool-side\n * previews taking precedence over dispatcher-side (preserves\n * backwards-compat during the registry-unification migration).\n */\n previewIds?(): Iterable<string> | null;\n previewPose?(id: string): unknown | null;\n\n /**\n * Subset of `previewIds()` the ghost layer paints at full opacity. The\n * ghost alpha says \"this is in flight under the pointer\"; a node the\n * gesture merely displaces — a layout sibling reflowing into its\n * destination slot — is not, and reads better settled. Honored at\n * subtree-root granularity.\n */\n previewOpaqueIds?(): Iterable<string> | null;\n\n /**\n * When `false`, the preview-ghost layer paints the ghost AND the\n * source node stays visible at its committed pose. Defaults to\n * `true` (move/resize/rotate semantics: ghost replaces the source\n * during the gesture). Clone overrides to `false` so the original\n * stays put and the ghost appears at the drag target.\n */\n previewHidesSource?: boolean;\n\n /**\n * Optional per-id preview *data*. Falls back to the committed\n * `node.data` when null/absent. Use when the gesture mutates\n * `node.data` (e.g. anchor-edit on nodes that store the polygon on\n * `data.path`) rather than (or in addition to) the pose. The preview-\n * ghost layer assembles a synthetic node from `{ ...node, pose:\n * previewPose ?? node.pose, data: previewData ?? node.data }` before\n * calling the scene slot's `drawOne`.\n *\n * Sources compose first-non-null per axis: an action can emit only\n * `previewPose` (translation), only `previewData` (data-only edit),\n * or both (pose + data both change, e.g. anchor drag on a data.path\n * node where the bounds shift).\n */\n previewData?(id: string): unknown | null;\n\n /**\n * Optional chrome surface — dispatcher-side overlay layer.\n *\n * An ongoing-action implementation may populate `overlay()` to expose a\n * non-ghost visual (marquee rectangle, lasso polyline) for the canvas's\n * `useDispatcherOverlayLayer` to paint while the gesture is in flight.\n * Returning `null` (or omitting the method) means \"no overlay this\n * gesture\" — the canvas will skip this handle as a chrome source.\n *\n * Distinct from the `previewIds()`/`previewPose(id)` ghost surface,\n * which paints displaced scene-node silhouettes. Marquee and lasso\n * gestures don't displace any node, but still need on-screen feedback.\n */\n overlay?(): OngoingOverlay | null;\n}\n\n/** Fire-once invocation. Runs to completion synchronously (or fires off an\n * async side-effect; the registry doesn't wait). */\nexport interface ImmediateInvoker {\n timing: 'immediate';\n /** `params` carries the matched binding's opts.params. Invoked from the\n * command palette, or anywhere else with no per-binding context, `params`\n * is undefined; descriptors should default to a sensible variant. */\n run(deps: ActionDeps, params?: Record<string, unknown>): void;\n}\n\n/** Phase-machine invocation. `start` opens the phase and returns the handle\n * the dispatcher pumps. */\nexport interface OngoingInvoker {\n timing: 'ongoing';\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle;\n}\n\n/** Pluggable invocation strategy for an Action. Future variants\n * (`longPress`, `twoStage`, `modal`) extend this union without touching\n * the `Action` type. */\nexport type Invoker = ImmediateInvoker | OngoingInvoker;\n","import type { Action } from './action';\nimport type { BoundGesture } from './binding';\nimport { resolveParams, type InvocationCtx, type BindingOpts } from './invoker';\nimport type { ActiveToolContextValue } from './activeToolContext';\nimport type { HotkeyTrigger } from '../../contributions/types';\n\n/** Canonical id of the consolidated tool-offhand action. One descriptor\n * serves every tool; the matched binding supplies `params.toolId` to select\n * which tool to engage while the key is held. */\nexport const TOOL_OFFHAND_ID = 'tool.offhand';\n\n/** Per-tool spec consumed by `buildToolOffhandBindings`. The key is the\n * held-key trigger (e.g. ' ' for Space-for-hand). */\nexport interface ToolOffhandBindingSpec {\n toolId: string;\n key: string | string[];\n}\n\n/** `KeyboardEvent.key` for a declared `Eligibility.offhand` trigger. The\n * named keys become their DOM names; any other trigger already is one. */\nexport function offhandKeyFor(trigger: HotkeyTrigger): string {\n switch (trigger) {\n case 'space': return ' ';\n case 'alt': return 'Alt';\n case 'ctrl': return 'Control';\n case 'meta': return 'Meta';\n case 'shift': return 'Shift';\n default: return trigger;\n }\n}\n\n/** Build the per-tool `BoundGesture` list for the consolidated action's\n * `defaultBinding`. Each entry pairs a `key-held` spec with\n * `opts.params.toolId` so the invoker's `start` can pick out which tool\n * to engage. */\nexport function buildToolOffhandBindings(\n specs: readonly ToolOffhandBindingSpec[],\n): BoundGesture[] {\n return specs.map(({ toolId, key }) => ({\n spec: { kind: 'key-held', key } as never,\n opts: { params: { toolId } },\n }));\n}\n\n/** Build the consolidated `tool.offhand` action — \"hold a key to engage a\n * secondary tool\" (e.g. Space-for-hand). `bindings` enumerates one\n * `{ spec: keyHeld, opts: { params: { toolId } } }` per tool; the invoker\n * reads `params.toolId` from the matched binding, pushes the tool id onto\n * the active-tool context's hotkey stack on `start`, and pops it on `onEnd`.\n * Mirrors the parametric shape of `tool.activate`. */\nexport function makeToolOffhandAction(bindings: BoundGesture[]): Action {\n return {\n id: TOOL_OFFHAND_ID,\n label: 'Engage tool (offhand)',\n defaultBinding: bindings,\n scope: 'hotkey',\n invoker: {\n timing: 'ongoing',\n start: (ctx: InvocationCtx, opts?: BindingOpts) => {\n const activeTool = ctx.deps.activeTool as ActiveToolContextValue | undefined;\n const toolId = resolveParams(opts?.params)?.toolId as string | undefined;\n if (!activeTool || !toolId) return {};\n activeTool.pushHotkey(toolId);\n return {\n onEnd: () => { activeTool.popHotkey(toolId); },\n };\n },\n },\n requires: ['activeTool'],\n } as Action & { requires: string[] };\n}\n","import type { BindingScope } from '../interactions/dispatcher/matcher';\nimport type { CapabilityTag } from '@weasel-js/modes';\nimport type { Eligibility } from './types';\n\n/** What the registry knows at dispatch time. */\nexport interface EligibilityState {\n focusedId: string | null;\n /** Ids the host reports as hotkey-engaged. A held `offhand` trigger reaches\n * here the same way a palette pick does: the `tool.offhand` action pushes\n * the tool's id onto the active-tool context's hotkey stack. */\n engagedIds?: ReadonlySet<string>;\n /** Whether the active mode allows these capability tags. Omitted → allow. */\n allows?: (tags: readonly CapabilityTag[]) => boolean;\n}\n\n/**\n * The scope tier an entry's bindings are live at, or null when none are.\n * Ordered hotkey > active > ambient to match the dispatcher's own walk.\n */\nexport function liveScope(\n id: string,\n eligibility: Eligibility,\n state: EligibilityState,\n): BindingScope | null {\n const tags = eligibility.capabilities;\n if (tags && tags.length > 0 && state.allows && !state.allows(tags)) return null;\n if (state.engagedIds?.has(id)) return 'hotkey';\n if (eligibility.focus && state.focusedId === id) return 'active';\n if (eligibility.always || eligibility.claimed) return 'ambient';\n return null;\n}\n","import type { ScopedBinding } from '../interactions/dispatcher/matcher';\nimport { liveScope, type EligibilityState } from './eligibility';\nimport type { Contribution } from './types';\n\n/**\n * Every binding the entry set contributes right now, each tiered by the\n * entry's own declared eligibility. Entries with no live tier are omitted.\n *\n * Order is preserved: `matchSorted` sorts by specificity within a scope and\n * breaks ties by declaration order, so the caller's entry order decides which\n * of two same-specificity bindings in one tier wins.\n */\nexport function scopeBindings(\n entries: Iterable<Contribution<unknown>>,\n state: EligibilityState,\n): ScopedBinding[] {\n const out: ScopedBinding[] = [];\n for (const entry of entries) {\n const scope = liveScope(entry.id, entry.eligibility ?? {}, state);\n if (scope === null) continue;\n for (const binding of entry.bindings ?? []) {\n out.push({ binding, scope, ownerId: entry.id });\n }\n }\n return out;\n}\n","/**\n * Whether to emit development diagnostics.\n *\n * Read through a function rather than a module-level constant so a test can\n * observe a runtime with no `process` — and so the read cannot be evaluated at\n * import time in an environment where it would throw.\n *\n * `process` is absent in a browser loading the published ESM directly: a\n * `<script type=\"module\">` from a CDN, or a bundler run with no `--define` for\n * it. A bare `process.env.NODE_ENV` read there is a ReferenceError, not a\n * falsy value, and it escapes through whatever called it — in the dispatcher's\n * case out of the pointerdown listener, losing the press and every subsequent\n * hover. Dev is the default when nothing says otherwise, matching the guarded\n * form the rest of the kit already uses.\n */\nexport function isDev(): boolean {\n return typeof process !== 'undefined'\n ? process.env?.NODE_ENV !== 'production'\n : true;\n}\n","/**\n * Pure matcher primitives live in `@weasel-js/gestures`. This file\n * re-exports them for kit-internal consumers and layers the actions-layer\n * binding-scope / matchBest logic on top.\n */\n\nimport { matchSpec, matchModifiers, matchKey, matchTarget, matchPhase, parseTargetSpec, specificity } from '@weasel-js/gestures';\nimport type {\n GestureSpec, InputEvent, PhaseContext, TargetSpec,\n} from '@weasel-js/gestures';\nimport type { GestureBinding } from '../actions/binding';\nimport type { ClaimableGesture } from '@weasel-js/gestures';\nimport { isDev } from '../../devFlag';\n\nexport { matchSpec, matchModifiers, matchKey, matchTarget, matchPhase, specificity };\nexport type { InputEvent, PhaseContext };\n\n// ---------------------------------------------------------------------------\n// BindingScope / ScopedBinding / MatchResult\n// ---------------------------------------------------------------------------\n\n/** Where a binding came from, which is also its priority: a held hotkey beats\n * the active tool, which beats bindings that are always in scope. */\nexport type BindingScope = 'ambient' | 'active' | 'hotkey';\n\n/** A binding paired with where it came from, ready to be matched against an\n * event. */\nexport interface ScopedBinding {\n binding: GestureBinding;\n scope: BindingScope;\n /** Id of the tool or contribution that declared this binding —\n * `'&'`-channel phase atoms resolve to it. `null` for a registered\n * action's own binding. */\n ownerId: string | null;\n}\n\n/** The binding that won a match. */\nexport interface MatchResult {\n binding: GestureBinding;\n scope: BindingScope;\n /** Id of the entry that declared the binding — propagated from\n * `ScopedBinding` so the dispatcher can record it as the handle owner. */\n ownerId: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// matchBest / matchSorted\n// ---------------------------------------------------------------------------\n\nconst SCOPE_PRIORITY: readonly BindingScope[] = ['hotkey', 'active', 'ambient'];\n\n// ---------------------------------------------------------------------------\n// Binding specificity\n// ---------------------------------------------------------------------------\n\n/**\n * True when a spec's target actually consults the affordance hit rather than\n * only the body classification. `kindOf` predicates are handed the hit;\n * `affordance:<k>` matches on its `kind`. The body-class strings (`'empty'`,\n * `'selected-body'`, `'unselected-body'`) and the `kind:` forms resolve from\n * `bodyTarget` / `bodyKind` and never see it — which is why chrome floating\n * over empty canvas used to read as empty canvas.\n *\n * A predicate carrying `readsAffordance: false` says the same about itself;\n * the kit's own body predicates do. Shape stays the fallback for predicates\n * that declare nothing.\n */\nexport function targetConsultsAffordance(specTarget: TargetSpec | undefined): boolean {\n if (specTarget === undefined) return false;\n const form = parseTargetSpec(specTarget);\n if (form === null) return false;\n switch (form.form) {\n case 'predicate': return form.kindOf.readsAffordance !== false;\n case 'affordance': return true;\n case 'body': return false;\n case 'kind': return false;\n default: {\n const _exhaustive: never = form;\n void _exhaustive;\n return false;\n }\n }\n}\n\nfunction specTargetOf(spec: GestureSpec): TargetSpec | undefined {\n return 'target' in spec ? spec.target : undefined;\n}\n\ninterface Claim {\n owner?: string;\n strength?: 'exclusive' | 'shared';\n claimedKinds?: readonly ClaimableGesture[];\n}\n\nfunction claimOf(e: InputEvent): Claim | undefined {\n return ('affordance' in e ? e.affordance : undefined) as Claim | undefined;\n}\n\n/** Event kind → the claim token that covers it. `null` for events a positional\n * claim has no opinion about — keys, drops, pastes, multitouch. */\nfunction claimGestureOf(e: InputEvent): ClaimableGesture | null {\n switch (e.kind) {\n case 'pointerdown':\n case 'click': return 'pointer';\n case 'doubleclick': return 'doubleClick';\n case 'contextmenu': return 'contextMenu';\n case 'longpress': return 'longPress';\n case 'wheel': return 'wheel';\n case 'pinch': return 'pinch';\n default: return null;\n }\n}\n\n/** `'exclusive'` when the event carries a claim that bars unnamed bindings\n * for this event's gesture. */\nfunction isExclusiveClaim(e: InputEvent): boolean {\n const claim = claimOf(e);\n if (claim?.strength !== 'exclusive') return false;\n const gesture = claimGestureOf(e);\n if (gesture === null) return false;\n return claim.claimedKinds === undefined || claim.claimedKinds.includes(gesture);\n}\n\nconst warnedDeadClaims = new Set<string>();\n\n/** Dev-only. An exclusive claim that matches no binding drops the press with\n * no diagnostic, which reads exactly like deliberate blocking. */\nfunction reportDeadClaim(owner: string | undefined, warn: (message: string) => void): void {\n if (!isDev()) return;\n const key = String(owner);\n if (warnedDeadClaims.has(key)) return;\n warnedDeadClaims.add(key);\n warn(\n `[weasel] exclusive claim by \"${key}\" matched no binding: no `\n + '`affordance:` or `kindOf` target resolved against it, so the press was dropped.',\n );\n}\n\n/** Lexicographic compare for use as an Array.prototype.sort callback.\n * Returns negative when `a` is MORE specific than `b` (so `a` sorts first\n * in a descending sort), positive when less, zero when equal. */\nfunction compareSpecificity(a: GestureSpec, b: GestureSpec): number {\n const sa = specificity(a);\n const sb = specificity(b);\n for (let i = 0; i < sa.length; i++) {\n if (sa[i] !== sb[i]) return sb[i] - sa[i];\n }\n return 0;\n}\n\n/**\n * Find the best-matching binding across all scopes.\n *\n * Precedence: hotkey > active > ambient.\n * Within a scope, more-specific bindings win; same-specificity bindings keep\n * registration order (see `matchSorted`).\n * Returns null when nothing matches.\n *\n * Note: this returns only the single best match. The dispatcher uses\n * `matchSorted` so it can fall through to lower-specificity matches when a\n * higher-specificity match's `enabled()` reports disabled.\n */\nexport function matchBest(\n e: InputEvent,\n bindings: readonly ScopedBinding[],\n isMac: boolean,\n engagedChannels?: ReadonlySet<string>,\n): MatchResult | null {\n const sorted = matchSorted(e, bindings, isMac, engagedChannels);\n return sorted.length > 0 ? sorted[0] : null;\n}\n\n/**\n * Find every binding that matches the event, sorted by precedence\n * (best → worst). Ordering rules:\n *\n * - Scopes by priority: hotkey > active > ambient.\n * - Within a scope, more-specific bindings beat less-specific (see\n * `specificity()`).\n * - Among same-specificity bindings, first-declared wins (stable sort\n * preserves registration order — same tiebreaker as pre-specificity).\n *\n * Used by the dispatcher to implement specificity-ordered fall-through:\n * when the top match's `enabled()` returns a disabled reason (or the\n * action's `start()` returns an empty handle), the next match is tried.\n */\nexport function matchSorted(\n e: InputEvent,\n bindings: readonly ScopedBinding[],\n isMac: boolean,\n engagedChannels?: ReadonlySet<string>,\n warn: (message: string) => void = (m) => console.warn(m),\n): MatchResult[] {\n return matchSortedWithBarred(e, bindings, isMac, engagedChannels, { warn }).matches;\n}\n\n/** {@link matchSorted}, plus what an exclusive claim on the event barred. */\nexport interface MatchOutcome {\n matches: MatchResult[];\n /** Bindings whose spec matched the event but which the claim barred, in\n * the same order `matches` uses. Filled only when `collectBarred` is set. */\n barred: MatchResult[];\n /** Owner of the exclusive claim, when one applied. */\n claimOwner?: string;\n}\n\n/**\n * {@link matchSorted} that can also report the bindings an exclusive claim\n * kept out. Collecting them costs a spec match per barred binding, so it is\n * opt-in — the dispatcher asks only when it is recording.\n */\nexport function matchSortedWithBarred(\n e: InputEvent,\n bindings: readonly ScopedBinding[],\n isMac: boolean,\n engagedChannels?: ReadonlySet<string>,\n opts: { collectBarred?: boolean; warn?: (message: string) => void } = {},\n): MatchOutcome {\n const warn = opts.warn ?? ((m: string) => console.warn(m));\n const engaged = engagedChannels ?? EMPTY_ENGAGED;\n // An exclusive claim outranks the scope tier. Scope is the outermost sort\n // key below, so without this a vague active binding beats the claim owner's\n // precise ambient one — the whole reason chrome got swallowed by whichever\n // tool was active.\n const exclusive = isExclusiveClaim(e);\n const admits = (sb: ScopedBinding): boolean =>\n !exclusive || targetConsultsAffordance(specTargetOf(sb.binding.spec));\n const out: MatchResult[] = [];\n const barred: MatchResult[] = [];\n for (const scope of SCOPE_PRIORITY) {\n const scopeMatches: MatchResult[] = [];\n const scopeBarred: MatchResult[] = [];\n for (const sb of bindings) {\n if (sb.scope !== scope) continue;\n const admitted = admits(sb);\n if (!admitted && !opts.collectBarred) continue;\n const phaseCtx: PhaseContext = { selfChannel: sb.ownerId, engagedChannels: engaged };\n if (matchSpec(e, sb.binding.spec, isMac, phaseCtx)) {\n (admitted ? scopeMatches : scopeBarred)\n .push({ binding: sb.binding, scope, ownerId: sb.ownerId });\n }\n }\n // Stable sort by specificity descending. Identical-specificity entries\n // keep their registration order (Array.prototype.sort is stable per ES2019).\n scopeMatches.sort((a, b) => compareSpecificity(a.binding.spec, b.binding.spec));\n scopeBarred.sort((a, b) => compareSpecificity(a.binding.spec, b.binding.spec));\n out.push(...scopeMatches);\n barred.push(...scopeBarred);\n }\n // Checked against the final result, not the pool: a binding can declare a\n // `kindOf`/`affordance:` target and still fail to match this particular\n // claim, which used to read as \"handled\" even though nothing fired.\n if (exclusive && out.length === 0 && bindings.length > 0) {\n reportDeadClaim(claimOf(e)?.owner, warn);\n }\n const owner = exclusive ? claimOf(e)?.owner : undefined;\n return { matches: out, barred, ...(owner !== undefined ? { claimOwner: owner } : {}) };\n}\n\nconst EMPTY_ENGAGED: ReadonlySet<string> = new Set();\n","import type { Contribution } from '../../../contributions/types';\nimport { routeGestureForSpecKind, specKindForRouteGesture } from '@weasel-js/gestures';\nimport type { GestureSpec, ModSpec, TargetSpec, PhaseSpec } from '@weasel-js/gestures';\nimport type { ParsedModifiers, ModifierKey, PhaseAtom } from '../routeGrammar';\nimport { formatRoute } from '../routeGrammar';\nimport { getGestureDescriptor, type GestureName } from '../gestures';\n\n/**\n * One row in the route registry — a single `GestureBinding` on one tool,\n * flattened into the route grammar's vocabulary so the inspector, the\n * conflict checker, and `describeRoute` can all read the same shape.\n *\n * Multiple rows can share (gesture, arg, target, modifiers) if different tools\n * declare them; consumers walk the list and group client-side.\n */\nexport interface RegistryEntry {\n /** The id of the entry that declared the binding: a tool, or a contribution. */\n ownerId: string;\n /** Which phase the binding's `phase` spec restricts it to. `'any'` when it\n * declares none, declares `'*'`, or declares an atom list whose atoms\n * don't agree on one phase — such a binding fires in either phase, and\n * reporting it as `'initial'` made it collide with genuinely-initial\n * bindings in `findConflicts`' bucket key. */\n phase: 'initial' | 'engaged' | 'any';\n /** Structured v3 modifier requirements. Empty object = \"no modifiers\n * held\" (the strict default). */\n modifiers: ParsedModifiers;\n gesture: GestureName;\n /** Resolved arg value for arg-bearing gestures (wheel direction,\n * key name, multiTouchTap fingers). Undefined for gestures whose\n * descriptor has no `arg`. */\n arg: string | undefined;\n /** Every arg value this binding actually answers to, when the spec names\n * more than one — `key: ['Delete','Backspace']` answers to both, and\n * `matchKey` matches any member case-insensitively. `arg` collapses them\n * into one display token, which is right for a route string and wrong for\n * deciding whether two bindings collide. Absent when there is only one. */\n argAlternatives?: readonly string[];\n /** Target class for hit-testing gestures. `undefined` when the descriptor\n * has `hasTarget: false` or the spec declares no target;\n * {@link PREDICATE_TARGET} when the spec uses a `kindOf` predicate, which\n * the route grammar has no notation for. */\n target: string | undefined;\n /** The action this binding fires. */\n actionId: string;\n /** The `GestureSpec` this row was flattened from, by reference. Reflection\n * consumers that need something the grammar doesn't capture — the\n * specificity tuple, a `kindOf` predicate identity — read it here rather\n * than re-walking `Tool.bindings`. */\n spec: GestureSpec;\n /** The binding's `opts.views`: the views it is live in. Absent when it is\n * live in every view. */\n views?: readonly (string | null)[];\n}\n\n/**\n * Stand-in target for a `{ kindOf }` predicate spec.\n *\n * The route grammar can name target *classes* (`empty`, `selected-body`,\n * `kind:rect`) but not arbitrary predicates, so three distinct select-tool\n * bindings all render as this one token. Narrowing it would mean giving the\n * grammar a way to describe a function, which is a real design question and\n * not one this reflection layer should answer by inventing syntax.\n */\nexport const PREDICATE_TARGET = 'predicate';\n\n/**\n * Flatten every tool's `bindings` into route-registry rows.\n *\n * This was `buildActionRegistry`, and it walked `ToolDef.initial` /\n * `.engaged` phase tables — the grammar that no longer exists. It was also\n * blind to `Tool.bindings` the entire time the two lived side by side, which\n * is why the inspector under-reported select by more than half. The rename\n * fixes a second thing: it never had anything to do with the Actions\n * Registry, and reading `buildActionRegistry` next to `ActionsRegistry`\n * suggested otherwise.\n */\nexport function buildRouteRegistry(\n entries: readonly Contribution<unknown>[],\n): RegistryEntry[] {\n const out: RegistryEntry[] = [];\n for (const owner of entries) {\n for (const binding of owner.bindings ?? []) {\n const row = entryFor(owner.id, binding.spec, binding.actionId);\n if (!row) continue;\n const views = binding.opts?.views;\n out.push(views === undefined ? row : { ...row, views });\n }\n }\n return out;\n}\n\n/**\n * Every route string one `GestureSpec` declares, in route-grammar notation.\n *\n * One string per arg alternative — a spec bound to `['ArrowUp','ArrowDown']`\n * yields two routes, because each is separately conflictable and separately\n * readable. Returns `[]` for spec kinds the grammar can't name.\n *\n * This is the display counterpart to {@link buildRouteRegistry}: same\n * projection of a spec onto the grammar, rendered as text instead of as a\n * conflict-checkable row.\n */\nexport function routesForSpec(spec: GestureSpec): readonly string[] {\n const gesture = routeGestureForSpecKind(spec.kind);\n if (!gesture) return [];\n const descriptor = getGestureDescriptor(gesture);\n const modifiers = parseModSpec('mods' in spec ? spec.mods : undefined);\n const phases = phaseAtomsForSpec('phase' in spec ? spec.phase : undefined);\n const target = descriptor.hasTarget\n ? routeTargetForSpec('target' in spec ? spec.target : undefined) ?? '*'\n : undefined;\n const args = descriptor.arg\n ? routeArgsForSpec(spec, descriptor.arg.default)\n : [undefined];\n return args.map((arg) => formatRoute({ phases, gesture, arg, target, modifiers }));\n}\n\nfunction entryFor(\n ownerId: string,\n spec: GestureSpec,\n actionId: string,\n): RegistryEntry | null {\n const gesture = routeGestureForSpecKind(spec.kind);\n if (!gesture) return null;\n const descriptor = getGestureDescriptor(gesture);\n return {\n ownerId,\n actionId,\n gesture,\n phase: phaseOf('phase' in spec ? spec.phase : undefined),\n modifiers: parseModSpec('mods' in spec ? spec.mods : undefined),\n arg: descriptor.arg ? argOf(spec, descriptor.arg.default) : undefined,\n ...(descriptor.arg ? argAlternativesOf(spec, descriptor.arg.default) : {}),\n target: descriptor.hasTarget\n ? routeTargetForSpec('target' in spec ? spec.target : undefined)\n : undefined,\n spec,\n };\n}\n\n/** Collapse a `PhaseSpec` to the single phase a binding is restricted to, or\n * `'any'` when it isn't restricted to one.\n *\n * `PhaseAtom.channel` says which channel's phase state the binding reads,\n * not which phase it fires in, so it plays no part in this collapse — only\n * the set of distinct `atom.phase` values matters. */\nfunction phaseOf(phase: PhaseSpec | undefined): 'initial' | 'engaged' | 'any' {\n if (phase === undefined || phase === '*') return 'any';\n if (phase === 'initial' || phase === 'engaged') return phase;\n const distinct = new Set(phase.map((atom) => atom.phase));\n if (distinct.size !== 1) return 'any';\n const only = [...distinct][0];\n return only === 'initial' || only === 'engaged' ? only : 'any';\n}\n\n/** `ModSpec` (per-key tri-state) → `ParsedModifiers`. `false` and absent both\n * mean \"must not be held\", which the parsed form spells as an absent key. */\nfunction parseModSpec(mods: ModSpec | undefined): ParsedModifiers {\n if (!mods) return {};\n const out: ParsedModifiers = {};\n for (const [name, req] of Object.entries(mods)) {\n if (req === true) out[name as ModifierKey] = 'required';\n else if (req === 'optional') out[name as ModifierKey] = 'optional';\n }\n return out;\n}\n\n/** Expand a `PhaseSpec` to the atoms `formatRoute` renders. A spec with no\n * `phase` matches in either phase, which the grammar spells `[*]`. */\nfunction phaseAtomsForSpec(phase: PhaseSpec | undefined): readonly PhaseAtom[] {\n if (phase === undefined) return [{ channel: '*', phase: '*' }];\n if (phase === 'initial' || phase === 'engaged' || phase === '*') {\n return [{ channel: '&', phase }];\n }\n return phase;\n}\n\nfunction routeTargetForSpec(target: TargetSpec | undefined): string | undefined {\n if (target === undefined) return undefined;\n return typeof target === 'string' ? target : PREDICATE_TARGET;\n}\n\n/** Every arg value a spec's route slot can take, one per alternative. Both\n * the registry row and the route string read the arg here. */\nfunction routeArgsForSpec(\n spec: GestureSpec,\n fallback: string | undefined,\n): readonly (string | undefined)[] {\n if ('key' in spec) return Array.isArray(spec.key) ? spec.key : [spec.key];\n if ('fingers' in spec) return [String(spec.fingers)];\n if ('direction' in spec) return [spec.direction ?? fallback];\n if ('types' in spec) return [spec.types?.length ? spec.types.join('|') : fallback];\n return [fallback];\n}\n\nfunction argOf(spec: GestureSpec, fallback: string | undefined): string | undefined {\n const args = routeArgsForSpec(spec, fallback);\n return args.length > 1 ? args.join('|') : args[0];\n}\n\n/** The alternatives a spec answers to, when there is more than one. A MIME\n * list is one too: `matchIngestTypes` accepts any member, so two `drop` specs\n * whose type sets overlap collide even though neither set contains the other. */\nfunction argAlternativesOf(\n spec: GestureSpec,\n fallback: string | undefined,\n): { argAlternatives?: readonly string[] } {\n const types = 'types' in spec ? spec.types : undefined;\n const alts = types?.length\n ? types\n : routeArgsForSpec(spec, fallback).filter((a): a is string => a !== undefined);\n return alts.length > 1 ? { argAlternatives: alts } : {};\n}\n\n// Re-export for downstream consumers.\nexport { getGestureDescriptor, routeGestureForSpecKind, specKindForRouteGesture };\nexport type { GestureName };\n","import type { DeviceProfile } from '../vocabulary';\n\n/** The detected half of a profile — everything except the derived scale. */\nexport type DetectedDeviceFacts = Omit<DeviceProfile, 'targetScale'>;\n\n/**\n * Handle/hit multiplier applied on a coarse pointer.\n *\n * 8px handle → 14px; 24px rotation distance → 42px. Counting the\n * surrounding grab zone, that lands in the Apple HIG 44pt / Material 48dp\n * minimum-touch-target band. One constant so it is tunable in one place.\n */\nexport const COARSE_TARGET_SCALE = 1.75;\n\n/**\n * Fold consumer overrides over detected facts and derive `targetScale`.\n *\n * `targetScale` is re-derived AFTER the merge, so an override of\n * `coarsePointer` alone scales the chrome as expected. An explicit\n * `targetScale` override wins over the derivation.\n */\nexport function resolveDeviceProfile(\n detected: DetectedDeviceFacts,\n overrides?: Partial<DeviceProfile>,\n): DeviceProfile {\n const coarsePointer = overrides?.coarsePointer ?? detected.coarsePointer;\n const canHover = overrides?.canHover ?? detected.canHover;\n const dpr = overrides?.dpr ?? detected.dpr;\n const targetScale =\n overrides?.targetScale ?? (coarsePointer ? COARSE_TARGET_SCALE : 1);\n return { coarsePointer, canHover, dpr, targetScale };\n}\n\n/**\n * Assumed when `matchMedia` is unavailable (SSR, jsdom) and used as the\n * absent-means value for `RuleCtx.device`.\n *\n * Derived from `resolveDeviceProfile` rather than hand-written, so it can\n * never drift from what the function would compute for the same facts. A\n * mouse-like device is the safe default: it is what the kit has always\n * assumed, so an absent profile changes nothing for existing consumers.\n */\nexport const DEFAULT_DEVICE_PROFILE: DeviceProfile = resolveDeviceProfile({\n coarsePointer: false,\n canHover: true,\n dpr: 1,\n});\n","import type { ModifierState } from '../vocabulary';\nimport type { CapabilityTag } from '@weasel-js/modes';\nimport type { RuleCtx } from './ruleCtx';\nimport { DEFAULT_DEVICE_PROFILE } from './deviceProfile';\n\n/**\n * A selector is a conjunction of key/value tests. Multiple keys at the same\n * level AND together. Each key maps to a selector primitive in the evaluator.\n */\nexport interface Selector {\n selection?: { is?: number; atLeast?: number; empty?: boolean };\n mode?: string | { not: string } | { in: readonly string[] };\n capability?:\n | CapabilityTag\n | readonly CapabilityTag[]\n | { in: readonly CapabilityTag[] }\n | { not: CapabilityTag };\n gesturing?: boolean;\n actionIs?: string;\n modifierHeld?: keyof ModifierState;\n focused?: boolean;\n hovering?: boolean;\n hoveringSelected?: boolean;\n zoomAtLeast?: number;\n /** Matches `ctx.editingAnchors` — true while a path is in anchor-edit\n * mode. Absent flag is treated as `false`. */\n editingAnchors?: boolean;\n /** Matches `ctx.selectionResizable`. Absent flag is treated as `true`\n * (resizable), so `{ resizable: true }` passes for legacy ctx builders\n * that don't compute it. */\n resizable?: boolean;\n /** Matches `ctx.device.coarsePointer` — the primary pointer is imprecise\n * (touch, most styluses). Absent device is treated as `false`. */\n coarsePointer?: boolean;\n /** Matches `ctx.device.canHover` — the primary pointer can hover. Absent\n * device is treated as `true`. */\n canHover?: boolean;\n}\n\n/**\n * Composable visibility/eligibility rule. Trees of `all`/`any`/`not` nodes\n * over `Selector` leaves. `when` is the escape hatch — its closure is\n * opaque to introspection and should be avoided when a declarative form\n * exists. Empty `all` is true; empty `any` is false.\n */\nexport type Rule =\n | Selector\n | { all: readonly Rule[] }\n | { any: readonly Rule[] }\n | { not: Rule }\n | { when: (ctx: RuleCtx) => boolean };\n\n/** Constant rules. Kept here so they have a single source. */\nexport const ALWAYS: Rule = { all: [] };\n/** A rule that never passes. `any` of nothing is false. */\nexport const NEVER: Rule = { any: [] };\n\n// ───────────────────────────────────────────────────────────────────────────\n// Type guards\n// ───────────────────────────────────────────────────────────────────────────\n\nexport function isAllRule(r: Rule): r is { all: readonly Rule[] } {\n return typeof r === 'object' && r !== null && 'all' in r;\n}\nexport function isAnyRule(r: Rule): r is { any: readonly Rule[] } {\n return typeof r === 'object' && r !== null && 'any' in r;\n}\nexport function isNotRule(r: Rule): r is { not: Rule } {\n return typeof r === 'object' && r !== null && 'not' in r;\n}\nexport function isWhenRule(r: Rule): r is { when: (ctx: RuleCtx) => boolean } {\n return typeof r === 'object' && r !== null && 'when' in r;\n}\nexport function isSelector(r: Rule): r is Selector {\n return !isAllRule(r) && !isAnyRule(r) && !isNotRule(r) && !isWhenRule(r);\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Evaluator\n// ───────────────────────────────────────────────────────────────────────────\n\nfunction checkSelection(s: NonNullable<Selector['selection']>, ctx: RuleCtx): boolean {\n if (s.empty !== undefined && (ctx.selection.length === 0) !== s.empty) return false;\n if (s.is !== undefined && ctx.selection.length !== s.is) return false;\n if (s.atLeast !== undefined && ctx.selection.length < s.atLeast) return false;\n return true;\n}\n\nexport function checkMode(m: NonNullable<Selector['mode']>, ctx: Pick<RuleCtx, 'mode'>): boolean {\n if (typeof m === 'string') return ctx.mode === m;\n if ('not' in m) return ctx.mode !== m.not;\n if ('in' in m) return m.in.includes(ctx.mode);\n return false;\n}\n\nexport function checkCapability(c: NonNullable<Selector['capability']>, ctx: Pick<RuleCtx, 'allowedCapabilities'>): boolean {\n if (typeof c === 'string') return ctx.allowedCapabilities.has(c);\n if (Array.isArray(c)) return c.every((tag) => ctx.allowedCapabilities.has(tag));\n if ('in' in c) return c.in.some((tag) => ctx.allowedCapabilities.has(tag));\n if ('not' in c) return !ctx.allowedCapabilities.has(c.not);\n return false;\n}\n\nfunction evaluateSelector(s: Selector, ctx: RuleCtx): boolean {\n if (s.selection !== undefined && !checkSelection(s.selection, ctx)) return false;\n if (s.mode !== undefined && !checkMode(s.mode, ctx)) return false;\n if (s.capability !== undefined && !checkCapability(s.capability, ctx)) return false;\n if (s.gesturing !== undefined && (ctx.action.kind !== null) !== s.gesturing) return false;\n if (s.actionIs !== undefined && ctx.action.kind !== s.actionIs) return false;\n if (s.modifierHeld !== undefined && !ctx.modifiers[s.modifierHeld]) return false;\n if (s.focused !== undefined && ctx.focused !== s.focused) return false;\n if (s.hovering !== undefined && (ctx.hover !== null) !== s.hovering) return false;\n if (s.hoveringSelected !== undefined) {\n const isHovSel = ctx.hover !== null && ctx.selection.includes(ctx.hover);\n if (isHovSel !== s.hoveringSelected) return false;\n }\n if (s.editingAnchors !== undefined && (ctx.editingAnchors ?? false) !== s.editingAnchors) return false;\n if (s.zoomAtLeast !== undefined) {\n // A host that reports no zoom has no threshold to clear.\n if (ctx.zoom === undefined || ctx.zoom < s.zoomAtLeast) return false;\n }\n if (s.resizable !== undefined) {\n // Absent flag === resizable (back-compat for ctx builders that don't\n // compute it). Only an explicit `false` opts a selection out.\n const resizable = ctx.selectionResizable ?? true;\n if (resizable !== s.resizable) return false;\n }\n if (s.coarsePointer !== undefined) {\n const device = ctx.device ?? DEFAULT_DEVICE_PROFILE;\n if (device.coarsePointer !== s.coarsePointer) return false;\n }\n if (s.canHover !== undefined) {\n const device = ctx.device ?? DEFAULT_DEVICE_PROFILE;\n if (device.canHover !== s.canHover) return false;\n }\n return true;\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Rendering\n// ───────────────────────────────────────────────────────────────────────────\n\n/** Deepest nesting `describeRule` will walk before giving up. `Rule` is plain\n * data and can't be cyclic by construction, so this is only a backstop that\n * makes termination unconditional — no rule anyone writes gets near it. */\nconst MAX_RULE_DEPTH = 10;\n\n/**\n * Render a selector's value side. Handles the shapes {@link Selector} allows:\n * primitives, `{ not }` / `{ in }` wrappers, capability arrays (which AND, so\n * they join with `+`), and the multi-field `selection` object.\n */\nfunction describeValue(value: unknown, depth: number): string {\n if (depth > MAX_RULE_DEPTH) return '…';\n if (value === null || typeof value !== 'object') return String(value);\n if (Array.isArray(value)) return value.map((v) => describeValue(v, depth + 1)).join('+');\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj);\n if (keys.length === 1 && keys[0] === 'not') return `not(${describeValue(obj.not, depth + 1)})`;\n if (keys.length === 1 && keys[0] === 'in') return `in(${describeValue(obj.in, depth + 1)})`;\n return keys.map((k) => `${k}=${describeValue(obj[k], depth + 1)}`).join(',');\n}\n\nfunction describeSelector(s: Selector, depth: number): string {\n const keys = Object.keys(s) as Array<keyof Selector>;\n // An empty selector matches every context — `evaluateSelector` has no test\n // to fail. `*` says that the way a CSS reader expects.\n if (keys.length === 0) return '*';\n return keys.map((k) => `${k}:${describeValue(s[k], depth + 1)}`).join(' & ');\n}\n\nfunction describeAt(rule: Rule, depth: number): string {\n if (depth > MAX_RULE_DEPTH) return '…';\n if (isAllRule(rule)) return `all(${rule.all.map((r) => describeAt(r, depth + 1)).join(', ')})`;\n if (isAnyRule(rule)) return `any(${rule.any.map((r) => describeAt(r, depth + 1)).join(', ')})`;\n if (isNotRule(rule)) return `not(${describeAt(rule.not, depth + 1)})`;\n // `when` is the one arm with nothing to introspect — its predicate is a\n // closure. The function's name is all a reader gets, which is itself an\n // argument for reaching for a declarative selector instead.\n if (isWhenRule(rule)) return `when(${rule.when.name || 'ƒ'})`;\n return describeSelector(rule, depth);\n}\n\n/**\n * Render a {@link Rule} as a short human-readable string, for inspectors and\n * diagnostics that need to say WHICH rule decided something.\n *\n * ```\n * { capability: 'edits-page' } → capability:edits-page\n * { all: [{ mode: 'normal' }, { focused: true }] } → all(mode:normal, focused:true)\n * { not: { selection: { empty: true } } } → not(selection:empty=true)\n * { when: function hasPath() { … } } → when(hasPath)\n * ```\n *\n * Never throws and always terminates — unlike `JSON.stringify`, which throws\n * on a cyclic value and renders the `when` arm as a useless `{}`.\n */\nexport function describeRule(rule: Rule): string {\n return describeAt(rule, 0);\n}\n\n/** Evaluate a rule against a context. Pure, and cheap enough to run per\n * frame for every piece of chrome. */\nexport function evaluate(rule: Rule, ctx: RuleCtx): boolean {\n if (isAllRule(rule)) return rule.all.every((r) => evaluate(r, ctx));\n if (isAnyRule(rule)) return rule.any.some((r) => evaluate(r, ctx));\n if (isNotRule(rule)) return !evaluate(rule.not, ctx);\n if (isWhenRule(rule)) return rule.when(ctx);\n return evaluateSelector(rule, ctx);\n}\n\n/**\n * Composable eligibility predicate with a fluent surface. Carries its\n * underlying `Rule` tree at `.rule` so the dispatcher's eligibility filter and\n * the chrome resolver can introspect and share trees.\n *\n * Callable form `cond(ctx)` evaluates the tree against ctx. The fluent methods\n * return new Conditions wrapping new trees.\n *\n * **Chain semantics: strict left-to-right, no precedence.** `a.and(b).or(c)` is\n * `(a && b) || c`; `a.or(b).and(c)` is `(a || b) && c`. Mix `.and` and `.or`\n * only when you mean left-to-right evaluation. For grouped disjunction, name\n * the subexpression or use the top-level `or(...)`.\n */\nexport interface Condition {\n (ctx: RuleCtx): boolean;\n readonly rule: Rule;\n /** `this && other` */\n and(other: Condition | Rule): Condition;\n /** `this || other` */\n or(other: Condition | Rule): Condition;\n /** `this && !other` */\n andNot(other: Condition | Rule): Condition;\n /** `this || !other` */\n orNot(other: Condition | Rule): Condition;\n}\n","import type { ActiveMode, CapabilityTag } from '@weasel-js/modes';\nimport { checkCapability, checkMode, isAllRule, isAnyRule, isNotRule, isWhenRule, type Rule, type Selector } from './rule';\n\n/**\n * Whether two rules can never hold at once — no `RuleCtx` passes both.\n *\n * Conservative: `true` is a proof, `false` means \"may overlap\". It reasons\n * about the selector values themselves (two different `mode`s, an empty\n * selection against a non-empty one, `focused: true` against `false`) and\n * through `all` / `any` / `not`; a `when` closure is opaque, so it overlaps\n * everything. The route-conflict check uses it to stay quiet about bindings\n * that share a tuple but are never eligible together.\n */\nexport function rulesExclusive(a: Rule, b: Rule): boolean {\n if (isAllRule(a)) return a.all.some((r) => rulesExclusive(r, b));\n if (isAllRule(b)) return b.all.some((r) => rulesExclusive(a, r));\n if (isAnyRule(a)) return a.any.every((r) => rulesExclusive(r, b));\n if (isAnyRule(b)) return b.any.every((r) => rulesExclusive(a, r));\n if (isNotRule(a)) return rulesEqual(a.not, b);\n if (isNotRule(b)) return rulesEqual(b.not, a);\n if (isWhenRule(a) || isWhenRule(b)) return false;\n return selectorsExclusive(a, b);\n}\n\n/**\n * Whether `rule` can hold while `mode` is active. Only its `mode` and\n * `capability` tests are settled by the mode; every other test could go either\n * way, so `false` is a proof and `true` means \"may hold\".\n */\nexport function ruleCanHoldIn(rule: Rule, mode: ActiveMode): boolean {\n return decideIn(rule, mode) !== false;\n}\n\n/** Three-valued: `undefined` when the mode alone does not settle the rule. */\nfunction decideIn(rule: Rule, mode: ActiveMode): boolean | undefined {\n if (isAllRule(rule)) return all3(rule.all.map((r) => decideIn(r, mode)));\n if (isAnyRule(rule)) {\n const parts = rule.any.map((r) => decideIn(r, mode));\n if (parts.includes(true)) return true;\n return parts.every((p) => p === false) ? false : undefined;\n }\n if (isNotRule(rule)) {\n const inner = decideIn(rule.not, mode);\n return inner === undefined ? undefined : !inner;\n }\n if (isWhenRule(rule)) return undefined;\n const ctx = { mode: mode.id, allowedCapabilities: mode.allowedCapabilities as ReadonlySet<CapabilityTag> };\n const settled = [\n rule.mode === undefined ? true : checkMode(rule.mode, ctx),\n rule.capability === undefined ? true : checkCapability(rule.capability, ctx),\n ];\n const { mode: _m, capability: _c, ...rest } = rule;\n void _m; void _c;\n return all3([...settled, Object.keys(rest).length > 0 ? undefined : true]);\n}\n\nfunction all3(parts: readonly (boolean | undefined)[]): boolean | undefined {\n if (parts.includes(false)) return false;\n return parts.every((p) => p === true) ? true : undefined;\n}\n\nconst BOOLEAN_KEYS = [\n 'gesturing', 'focused', 'hovering', 'hoveringSelected', 'editingAnchors',\n 'resizable', 'coarsePointer', 'canHover',\n] as const satisfies readonly (keyof Selector)[];\n\nfunction selectorsExclusive(a: Selector, b: Selector): boolean {\n for (const key of BOOLEAN_KEYS) {\n if (a[key] !== undefined && b[key] !== undefined && a[key] !== b[key]) return true;\n }\n if (a.actionIs !== undefined && b.actionIs !== undefined && a.actionIs !== b.actionIs) return true;\n // `actionIs` holds only while some action runs.\n if (a.actionIs !== undefined && b.gesturing === false) return true;\n if (b.actionIs !== undefined && a.gesturing === false) return true;\n if (a.mode !== undefined && b.mode !== undefined && modesExclusive(a.mode, b.mode)) return true;\n if (a.selection && b.selection && selectionsExclusive(a.selection, b.selection)) return true;\n if (a.capability !== undefined && b.capability !== undefined\n && capabilitiesExclusive(a.capability, b.capability)) return true;\n return false;\n}\n\ntype ModeSet = { in: ReadonlySet<string> } | { notIn: ReadonlySet<string> };\n\nfunction modeSet(m: NonNullable<Selector['mode']>): ModeSet {\n if (typeof m === 'string') return { in: new Set([m]) };\n if ('not' in m) return { notIn: new Set([m.not]) };\n return { in: new Set(m.in) };\n}\n\nfunction modesExclusive(a: NonNullable<Selector['mode']>, b: NonNullable<Selector['mode']>): boolean {\n const x = modeSet(a);\n const y = modeSet(b);\n if ('in' in x && 'in' in y) return ![...x.in].some((m) => y.in.has(m));\n if ('in' in x && 'notIn' in y) return [...x.in].every((m) => y.notIn.has(m));\n if ('notIn' in x && 'in' in y) return [...y.in].every((m) => x.notIn.has(m));\n // Two exclusions always leave some mode both allow.\n return false;\n}\n\n/** The selection-length interval a `selection` selector admits. */\nfunction selectionRange(s: NonNullable<Selector['selection']>): [number, number] {\n let lo = 0;\n let hi = Infinity;\n if (s.empty === true) hi = 0;\n if (s.empty === false) lo = 1;\n if (s.is !== undefined) { lo = Math.max(lo, s.is); hi = Math.min(hi, s.is); }\n if (s.atLeast !== undefined) lo = Math.max(lo, s.atLeast);\n return [lo, hi];\n}\n\nfunction selectionsExclusive(\n a: NonNullable<Selector['selection']>,\n b: NonNullable<Selector['selection']>,\n): boolean {\n const [alo, ahi] = selectionRange(a);\n const [blo, bhi] = selectionRange(b);\n return Math.max(alo, blo) > Math.min(ahi, bhi);\n}\n\n/** Tags a capability selector requires, and the one it forbids. */\nfunction capabilityTerms(c: NonNullable<Selector['capability']>): {\n requires: readonly CapabilityTag[];\n forbids?: CapabilityTag;\n} {\n if (typeof c === 'string') return { requires: [c] };\n if (Array.isArray(c)) return { requires: c };\n if ('not' in c) return { requires: [], forbids: c.not };\n // `{ in }` requires any one of its tags, so no single tag is required.\n return { requires: [] };\n}\n\nfunction capabilitiesExclusive(\n a: NonNullable<Selector['capability']>,\n b: NonNullable<Selector['capability']>,\n): boolean {\n const x = capabilityTerms(a);\n const y = capabilityTerms(b);\n return (x.forbids !== undefined && y.requires.includes(x.forbids))\n || (y.forbids !== undefined && x.requires.includes(y.forbids));\n}\n\n/** Structural equality over rule trees; a `when` closure matches only itself. */\nfunction rulesEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n return ka.every((k) => rulesEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]));\n}\n","import type { NodeId, DeviceProfile, ModifierState } from '../vocabulary';\nimport { activeModeOf, NORMAL, type CapabilityTag } from '@weasel-js/modes';\n\n/**\n * Live state read by rule evaluation. Built once per frame on the consuming\n * surface — chrome-caps, the affordance pipeline, the dispatcher's\n * eligibility filter — and discarded.\n *\n * Adding a new field is additive: existing rules don't change, new\n * selector atoms can read it.\n */\nexport interface RuleCtx {\n readonly focused: boolean;\n readonly selection: readonly NodeId[];\n readonly multiActive: boolean;\n readonly modifiers: ModifierState;\n readonly action: { readonly kind: string | null; readonly id: string | null };\n readonly hover: NodeId | null;\n /**\n * How far the viewport is zoomed in, as one number — `1` at native scale.\n *\n * A scalar rather than the `View` this used to carry, because `zoomAtLeast`\n * is the only selector that ever read one and a number is all it needs. A\n * host whose viewport is a camera has no `View` to hand over and would\n * otherwise have to invent one to use eligibility at all; it omits this\n * instead, and `zoomAtLeast` declines rather than matching on a fiction.\n */\n readonly zoom?: number;\n /** Active mode id. `'normal'` when no non-default mode is engaged. */\n readonly mode: string;\n /** Capability tags allowed by the active mode (the union of\n * `ModeDefinition.allows` plus implicit tags). The `capability:`\n * selector reads this to determine whether a tag is permitted. */\n readonly allowedCapabilities: ReadonlySet<CapabilityTag>;\n /** Whether the current selection may be resized. `<SceneCanvas>` folds\n * `selectTool.resize.resizable` over the selection (true only when every\n * selected node is resizable). Read by the `resizable:` selector to gate\n * `selection.resize-handles`. Absent (legacy ctx builders) is treated as\n * resizable — back-compat: handles show unless a consumer opts a node out. */\n readonly selectionResizable?: boolean;\n /** Whether a path is currently in anchor-edit mode. Read by the\n * `editingAnchors:` selector, which gates the path-edit chrome.\n *\n * This is deliberately a fact about state, not about permission: the\n * anchor overlay and the anchor hit-test must agree, and the thing they\n * must agree on is \"is there an edited path right now\", which no\n * capability or mode id answers. A mode that allows `edits-anchors`\n * with nothing being edited should draw no anchors. Absent is treated\n * as false. */\n readonly editingAnchors?: boolean;\n /** Device facts — pointer coarseness, hover capability, density.\n *\n * Absent (legacy ctx builders) is treated as\n * {@link DEFAULT_DEVICE_PROFILE}: a fine pointer that can hover, at\n * density 1. That is what the kit assumed before this field existed, so\n * an absent profile is behavior-preserving by construction. */\n readonly device?: DeviceProfile;\n /** The view the input being dispatched landed in — a view id, or `null`\n * for the surface's own camera. The dispatcher fills it; absent anywhere\n * else a rule is evaluated. */\n readonly viewId?: string | null;\n}\n\n/** The live state a `RuleCtx` is assembled from — the chrome context plus\n * what the active mode allows. */\nexport interface BuildRuleCtxArgs {\n focused: boolean;\n selection: readonly NodeId[];\n multiActive: boolean;\n modifiers: ModifierState;\n action: { kind: string | null; id: string | null };\n hover: NodeId | null;\n /** See {@link RuleCtx.zoom}. */\n zoom?: number;\n mode: string;\n allowedCapabilities: ReadonlySet<CapabilityTag>;\n /** Optional — omitted means \"resizable\" (handles show). See {@link RuleCtx}. */\n selectionResizable?: boolean;\n /** Optional — omitted means \"no path is being anchor-edited\". */\n editingAnchors?: boolean;\n /** Optional — omitted means {@link DEFAULT_DEVICE_PROFILE}. */\n device?: DeviceProfile;\n}\n\n/**\n * Capability set to assume when no mode registry is wired.\n *\n * \"No modes configured\" means *everything the default mode permits*, not\n * *nothing permitted*. The empty set is the wrong default: it makes every\n * `capability:` rule evaluate false, so a kit default written the\n * recommended way (capability rules outlive new modes; mode rules have to\n * be edited) would silently hide its chrome for every consumer that hasn't\n * opted into modality. `NORMAL.allows` plus the implicit tags is what a\n * mode-less canvas actually behaves like.\n */\nexport const DEFAULT_ALLOWED_CAPABILITIES = activeModeOf(NORMAL).allowedCapabilities as ReadonlySet<CapabilityTag>;\n\n/** Gather the current canvas and mode state into the context that action\n * eligibility and chrome-visibility rules are evaluated against. */\nexport function buildRuleCtx(args: BuildRuleCtxArgs): RuleCtx {\n return {\n focused: args.focused,\n selection: args.selection,\n multiActive: args.multiActive,\n modifiers: args.modifiers,\n action: args.action,\n hover: args.hover,\n zoom: args.zoom,\n mode: args.mode,\n allowedCapabilities: args.allowedCapabilities,\n selectionResizable: args.selectionResizable,\n editingAnchors: args.editingAnchors,\n device: args.device,\n };\n}\n","/**\n * Dispatcher orchestrator — pure module, no React, no DOM.\n *\n * Assembles `ScopedBinding[]` from the actions registry, active tool, and\n * hotkey stack; matches input events via `matchSorted`; gates each candidate\n * on `enabled()`; then invokes `immediate` or `ongoing` invokers and tracks\n * in-flight handles.\n *\n * ## Precedence and fall-through\n * An exclusive affordance claim first bars every binding that does not\n * consult the affordance. The rest are ranked, best first, by:\n * 1. bindings naming the routed view ahead of every other\n * (`preferViewScoped`);\n * 2. scope tier: hotkey > active > ambient;\n * 3. specificity within a tier (`specificity()` in `matcher.ts`);\n * 4. an action gated by an `eligible` rule that holds now ahead of one with\n * no rule (`preferContextual`) — Escape while editing a path exits the\n * edit rather than resetting the tool;\n * 5. registration order.\n * Candidates whose `eligible` rule is false are dropped first. The dispatcher\n * walks the rest and fires the first action whose `enabled()` returns\n * `true`. If every candidate's `enabled()` returns a disabled reason, the\n * event is unhandled. This mirrors CSS-style specificity matching with a\n * `:not(:disabled)` filter, and lets a tool declare a high-specificity\n * binding (e.g. drag-on-empty → areaSelect) that gracefully falls through\n * to a lower-specificity ambient binding (e.g. drag → viewport.dragPan)\n * when its required deps aren't wired.\n *\n * ## gestureId scheme\n * - `key-held` ongoing actions: `key-held-<key>` (e.g. `key-held- ` for Space).\n * Chosen because key-held gestures are identified by the held key alone.\n * - `pointerdown` / drag ongoing actions: `pointer-<pointerId>`, taken from\n * the originating DOM `PointerEvent`. Each physical pointer — mouse, each\n * touch, the stylus — gets its own handle slot. Events with no\n * `pointerId` (synthesized probes, programmatic drags, most tests) key to\n * `pointer-mouse`, so a single synthetic pointer behaves as it always has.\n * - `multitouch` ongoing actions: `multitouch-<fingers>`.\n * - Fallback for any other kind that triggers an ongoing invoker: `ongoing-<kind>`.\n *\n * ## Action-lookup miss behavior\n * When `matchBest` resolves a binding whose `actionId` has no entry in\n * `ctx.actions.list()`, the dispatcher emits `console.warn` and returns\n * `'unhandled'`. The user's input gesture falls through as if unmatched.\n * This preserves input flow (nothing is swallowed silently) while flagging\n * the misconfiguration at dev time.\n */\n\n\nimport type { Action, ActionSource } from '../actions/action';\nimport { actionBindings } from '../actions/binding';\nimport type { DepRegistry } from '../actions/depNode';\nimport type { GestureBinding } from '../actions/binding';\nimport type { GestureSpec } from '@weasel-js/gestures';\nimport type { OngoingHandle, InvocationCtx, ActionDeps, AffordanceHit, DragSample, Point2 } from '../actions/invoker';\nimport { resolveParams } from '../actions/invoker';\nimport { buildDepsFromRequires } from '../actions/buildDeps';\nimport type { Contribution } from '../../contributions/types';\nimport { scopeBindings } from '../../contributions/assemble';\nimport type { InputEvent, BindingScope, MatchResult, ScopedBinding } from './matcher';\nimport { matchSortedWithBarred, specificity } from './matcher';\nimport { routesForSpec } from '../../tools/routing/reflection/registry';\nimport type {\n DispatchRecord, DroppedCandidate, PlacedBy, RankedCandidate, RecordCandidate, SpecificityPart,\n WalkStep,\n} from './dispatchRecord';\nimport { evaluate, describeRule, type Rule, type RuleCtx, type Condition } from '../../eligibility';\nimport { resolveCursor } from '@weasel-js/cursor';\nimport type { CapabilityTag } from '@weasel-js/modes';\n\n/**\n * The in-flight handle slot a pointer's gestures key into.\n *\n * Exported because the React seam (`useGestureDispatcher`) has to name the\n * same slot when it asks `dispatcher.inFlight()` whether a given pointer is\n * mid-drag. That used to be the string literal `'pointer-mouse'` on both\n * sides, which was correct only because `gestureIdFor` ignored the pointer id\n * entirely — the two lies cancelled out.\n *\n * @param pointerId - `PointerEvent.pointerId`, or `undefined` for a\n * synthesized event with no originating DOM pointer.\n */\nexport function pointerGestureId(pointerId: number | undefined): string {\n return `pointer-${pointerId ?? 'mouse'}`;\n}\n\n// ---------------------------------------------------------------------------\n// Dev-only instrumentation\n// ---------------------------------------------------------------------------\n\n/** True in dev builds; false in production. Tree-shakes the Proxy + trace\n * log out of prod entirely. */\nconst DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\n/** One entry per \"mode change\" — a kit state transition that isn't a\n * dispatched input event but is load-bearing for understanding why an\n * input was (or wasn't) handled later. Pushed via `recordModeSwitch()`;\n * consumers include the editAnchors dep (editingId changes), and\n * could expand to active-tool / hotkey-stack / focus changes. */\nexport interface ModeSwitchLogEntry {\n kind: 'mode';\n ts: number;\n /** Logical mode name, e.g. `'editAnchors.editingId'`. */\n mode: string;\n from: string | null;\n to: string | null;\n /** Optional free-form context — `'enterPathEdit'`, `'exitPathEdit'`,\n * `'selection-dropped target'`, etc. */\n detail?: string;\n}\n\n/** A trace entry: one {@link DispatchRecord} per resolved input, or a mode switch. */\nexport type TraceLogEntry = DispatchRecord | ModeSwitchLogEntry;\n\nconst TRACE_LIMIT = 200;\n\n// `traceLog` is the rolling buffer; in dev it IS `window.__weaselDispatchLog__`\n// so the ToolkitBuilder widget can poll it. Bind to the existing global if one\n// is already present rather than reassigning a fresh array: an HMR\n// re-evaluation of this module would otherwise create a new array and orphan\n// the long-lived Dispatcher (held in a SceneCanvas `useRef` that survives Fast\n// Refresh) whose `recordTrace` closure still pushes to the previous array — the\n// widget would then read an array nothing writes to. Reuse keeps every module\n// instance and the widget pointed at one shared array.\n//\n// `__weaselDispatchLog__` is the historical global; entries are a union of\n// dispatch + mode-switch records. Filter via `(e) => e.kind === 'dispatch'` if\n// you only want input routing.\nconst traceLog: TraceLogEntry[] =\n DEV && typeof window !== 'undefined'\n ? ((window as unknown as { __weaselDispatchLog__?: TraceLogEntry[] }).__weaselDispatchLog__ ??=\n [])\n : [];\n\nfunction recordTrace(entry: TraceLogEntry): void {\n if (!DEV) return;\n traceLog.push(entry);\n if (traceLog.length > TRACE_LIMIT) traceLog.shift();\n}\n\n/**\n * Dev only: offer the record for what a press at the pointer would do, as a\n * thunk on `window.__weaselDispatchLive__`. The hover pump offers one per move\n * and a reader builds the record only when it looks, so no record is built\n * while nothing is watching. `null` withdraws it when the pointer leaves.\n *\n * @internal\n */\nexport function publishLiveDispatch(explain: (() => DispatchRecord) | null): void {\n if (!DEV || typeof window === 'undefined') return;\n (window as unknown as { __weaselDispatchLive__?: (() => DispatchRecord) | null })\n .__weaselDispatchLive__ = explain;\n}\n\n/** Push a mode-switch record into the trace log. Safe to call from\n * anywhere; no-ops outside DEV. */\nexport function recordModeSwitch(\n mode: string,\n from: string | null,\n to: string | null,\n detail?: string,\n): void {\n recordTrace({\n kind: 'mode',\n ts: Date.now(),\n mode,\n from,\n to,\n ...(detail !== undefined ? { detail } : {}),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Everything the dispatcher must consult to route one input event: the\n * registered actions and their deps, which tool is active, which hotkeys are\n * held, and — optionally — the chrome state that action eligibility rules are\n * evaluated against. Rebuilt per event rather than held, so the dispatcher\n * itself stays stateless apart from in-flight gestures. */\nexport interface DispatcherContext {\n /** All registered actions; the dispatcher walks `.defaultBinding` for ambient bindings. */\n actions: ActionSource;\n /** Dep sources keyed by name. */\n depRegistry: DepRegistry;\n /** Active tool's id (from ActiveToolContext); `null` when none is. */\n activeToolId: string | null;\n /** Held-hotkey stack, top of stack last. */\n hotkeyStack: readonly string[];\n /** Every registered entry, tools and ambient contributions alike, by id. */\n entriesById: ReadonlyMap<string, Contribution<unknown>>;\n /** Platform flag for `mod` shorthand resolution. */\n isMac: boolean;\n /**\n * Thunk returning a fresh `RuleCtx` for the current frame — the routed\n * view's, when the surface hosts several. When it answers, the dispatcher\n * filters matched candidates by their declared `Action.eligible` rule\n * (omitted => always eligible). Absent, or answering `undefined`, applies\n * no eligibility filtering.\n */\n getRuleCtx?: () => RuleCtx | undefined;\n /**\n * The view this input landed in — a view id, or `null` for the surface's\n * own camera. Bindings whose `opts.views` omit it are not live, those naming\n * it outrank the rest, and it reaches the invoker as `InvocationCtx.viewId`\n * and rules as `RuleCtx.viewId`. Absent means the host routes no views, which\n * reads as the root.\n */\n viewId?: string | null;\n}\n\n/** Whether `binding` is live for input routed to `view`. */\nfunction liveInView(binding: GestureBinding, view: string | null): boolean {\n const views = binding.opts?.views;\n return views === undefined || views.includes(view);\n}\n\n/** Stable partition: matches whose binding names `view` first. See\n * `BindingOpts.views` for why naming the view outranks the scope tier. */\nfunction namesView(binding: GestureBinding, view: string | null): boolean {\n return binding.opts?.views?.includes(view) ?? false;\n}\n\nfunction preferViewScoped<M extends { binding: GestureBinding }>(\n matches: readonly M[],\n view: string | null,\n): M[] {\n const named: M[] = [];\n const rest: M[] = [];\n for (const m of matches) {\n (namesView(m.binding, view) ? named : rest).push(m);\n }\n return named.length === 0 ? [...matches] : [...named, ...rest];\n}\n\n/** The routed view's rule context, carrying the view id. */\nfunction ruleCtxOf(ctx: DispatcherContext): RuleCtx | undefined {\n const r = ctx.getRuleCtx?.();\n return r ? { ...r, viewId: ctx.viewId ?? null } : undefined;\n}\n\n/**\n * Normalize an `Action.eligible` value to a raw `Rule`. Conditions are\n * callable functions carrying `.rule`; raw Rules are returned as-is.\n */\nfunction eligibleToRule(eligible: Rule | Condition): Rule {\n return typeof eligible === 'function' ? (eligible as Condition).rule : eligible;\n}\n\n/** Does `action`'s declared eligibility rule pass against `ruleCtx`?\n * An action with no `eligible` rule is always eligible. */\nfunction isEligible(action: Action, ruleCtx: RuleCtx): boolean {\n if (!action.eligible) return true;\n return evaluate(eligibleToRule(action.eligible), ruleCtx);\n}\n\n/** Render an `eligible` rule for display. `evaluate()` returns a bare\n * boolean, so there is no reason string to carry — the rule itself is the\n * most informative thing available. */\nfunction describeEligible(eligible: NonNullable<Action['eligible']>): string {\n return describeRule(eligibleToRule(eligible));\n}\n\n/**\n * Filter `matches` to only those whose backing action has no `eligible`\n * rule, or whose rule evaluates true against `ruleCtx`. Exported for\n * unit testing.\n *\n * @internal\n */\nexport function filterEligible<M extends { binding: { actionId: string } }>(\n matches: readonly M[],\n actionLookup: (id: string) => Action | undefined,\n ruleCtx: RuleCtx,\n): M[] {\n return matches.filter((m) => {\n const action = actionLookup(m.binding.actionId);\n if (!action) return true;\n return isEligible(action, ruleCtx);\n });\n}\n\n/**\n * Among matches tied on scope and specificity, put those whose action is\n * gated by an `eligible` rule that holds now ahead of those with no rule: a\n * binding that applies only in the current context — Escape while editing a\n * path — outranks one that applies everywhere. Otherwise stable.\n *\n * @internal\n */\nexport function preferContextual<M extends { binding: GestureBinding; scope: string }>(\n matches: readonly M[],\n actionLookup: (id: string) => Action | undefined,\n /** Whether a gated action's rule holds; skip re-asking where the matches\n * were already filtered by it. */\n holds: (action: Action) => boolean,\n /** The routed view: a binding naming it is never tied with one that does not. */\n view: string | null,\n): M[] {\n const out: M[] = [];\n let run: M[] = [];\n const flush = (): void => {\n const gated = run.filter((m) => {\n const action = actionLookup(m.binding.actionId);\n return action?.eligible !== undefined && holds(action);\n });\n out.push(...gated, ...run.filter((m) => !gated.includes(m)));\n run = [];\n };\n for (const m of matches) {\n const head = run[0];\n if (\n head\n && (head.scope !== m.scope\n || namesView(head.binding, view) !== namesView(m.binding, view)\n || !sameSpecificity(head.binding.spec, m.binding.spec))\n ) flush();\n run.push(m);\n }\n flush();\n return out;\n}\n\nconst SPECIFICITY_PARTS: readonly SpecificityPart[] = ['target', 'mods', 'phase', 'exact'];\n\n/** The ranking step that put `cur` directly below `prev`. `contextual` says\n * `prev` is gated by a rule that holds and `cur` is not — the only thing the\n * step after specificity looks at. */\nfunction placedBy(\n prev: MatchResult,\n cur: MatchResult,\n view: string | null,\n contextual: boolean,\n): PlacedBy {\n if (namesView(prev.binding, view) !== namesView(cur.binding, view)) return { step: 'view' };\n if (prev.scope !== cur.scope) return { step: 'tier' };\n const sp = specificity(prev.binding.spec);\n const sc = specificity(cur.binding.spec);\n const i = sp.findIndex((v, k) => v !== sc[k]);\n if (i >= 0) return { step: 'specificity', part: SPECIFICITY_PARTS[i]! };\n return contextual ? { step: 'context' } : { step: 'order' };\n}\n\nfunction sameSpecificity(a: GestureSpec, b: GestureSpec): boolean {\n const sa = specificity(a);\n const sb = specificity(b);\n return sa.every((v, i) => v === sb[i]);\n}\n\n/**\n * Handle returned by `Dispatcher.beginUiOngoing()` for driving an\n * ongoing invoker from a UI control (color picker, slider).\n *\n * - `update(params)` rebuilds an `InvocationCtx` with the new params and\n * calls the handle's `onMove`. Safe to call many times.\n * - `end(reason)` calls `onEnd(ctx, reason)` once and removes the handle\n * from the in-flight map. Idempotent — further calls are no-ops.\n */\nexport interface UiOngoingControl {\n readonly gestureId: string;\n update(params?: Record<string, unknown>): void;\n end(reason: 'commit' | 'cancel'): void;\n}\n\n/**\n * Successful `Dispatcher.resolveOnly` prediction: the binding + action that\n * would fire if `event` were dispatched for real. `action` is the resolved\n * descriptor so callers (the hover-cursor pump) can read metadata like\n * `Action.cursor` without a second registry lookup.\n */\nexport interface ResolveOnlyResult {\n actionId: string;\n action: Action;\n scope: BindingScope;\n /** Tool id owning the winning binding; `null` for ambient action bindings. */\n ownerId: string | null;\n}\n\n/**\n * One candidate from `Dispatcher.resolveAll` — a binding that matched the\n * event, with why it did or didn't get to fire.\n *\n * Verdicts:\n * - `would-fire` — eligible, `enabled()` passed, and nothing above it fired.\n * At most one candidate per call carries this.\n * - `ineligible` — the action's `eligible` rule evaluated false against the\n * live `RuleCtx`. `reason` is the rule, serialized.\n * - `disabled` — `enabled()` returned a disabled reason, carried verbatim.\n * - `shadowed` — never asked, for one of two reasons: something above it\n * already fired, or it is a repeat binding of the action that itself won\n * higher in the list (several bindings may point at one action, and the\n * dispatcher runs each action at most once). A repeat of an action that was\n * already judged `ineligible` or `disabled` is NOT shadowed — it inherits\n * that action's verdict, since that is the reason it doesn't fire.\n */\nexport interface ResolvedCandidate {\n actionId: string;\n action: Action;\n binding: GestureBinding;\n scope: BindingScope;\n ownerId: string | null;\n /** The tuple from `specificity(binding.spec)`, surfaced so a reader can see\n * why one candidate outranks another rather than inferring it. */\n specificity: readonly [number, number, number, number];\n verdict:\n | { kind: 'would-fire' }\n | { kind: 'ineligible'; reason: string }\n | { kind: 'disabled'; reason: string }\n | { kind: 'shadowed' };\n}\n\n/** Options for {@link Dispatcher.resolveAll}. */\nexport interface ResolveAllOptions {\n /**\n * Evaluate eligibility and `enabled()` for candidates below the winner\n * instead of short-circuiting them to `shadowed`.\n *\n * Off by default, and deliberately so: the default walk's early exit is what\n * keeps `resolveOnly`'s `enabled()` call count identical to a real dispatch,\n * and `enabled()` predicates are only contractually pure — not free.\n *\n * Turn it on for diagnostics, where \"this one was outranked\" is a less\n * useful answer than \"this one was outranked AND would have been disabled\n * anyway\". With it on, `shadowed` narrows to its precise meaning: this\n * candidate would have fired, but something above it did.\n */\n evaluateShadowed?: boolean;\n}\n\n/**\n * Routes input events to actions.\n *\n * For each event it assembles the bindings in scope (hotkey, then active tool,\n * then ambient), matches them in specificity order, filters by eligibility and\n * each action's `enabled` gate, and invokes the first survivor. Ongoing\n * actions — anything that runs across a drag — are kept in flight here and\n * pumped with subsequent moves until the gesture ends.\n */\nexport interface Dispatcher {\n /**\n * Route an input event through the binding pipeline. Returns `'handled'`\n * when a binding matched and the action invoked successfully (whether it\n * returned ops or not). Returns `'unhandled'` when no binding matched or\n * the matched action's `enabled()` returned a disabled reason.\n */\n handleInput(event: InputEvent, ctx: DispatcherContext): 'handled' | 'unhandled';\n\n /**\n * Predict which action `event` would route to WITHOUT invoking it. Replays\n * the same walk as `handleInput` — scope assembly, specificity-sorted\n * match, eligibility filter, per-candidate `enabled()` gate — and returns\n * the first candidate that would fire, or `null` when the event would go\n * unhandled. Pure query: no invoker runs, no in-flight state changes, no\n * trace-log entry.\n *\n * Known divergence from a real dispatch: an ongoing invoker that matches\n * but returns an empty handle at `start()` (runtime bail) makes the real\n * dispatch fall through to the next candidate; prediction cannot see that\n * and reports the bailing action. Keep `enabled()` accurate on actions\n * that rely on prediction (hover cursors).\n */\n resolveOnly(event: InputEvent, ctx: DispatcherContext): ResolveOnlyResult | null;\n\n /**\n * Every binding that matches `event`, in dispatch precedence order, each\n * with a verdict explaining whether it would fire. Same walk as\n * `resolveOnly` — scope assembly, specificity-sorted match, eligibility\n * check, per-candidate `enabled()` gate — without stopping at the winner\n * and without invoking anything. Nothing is dropped: candidates that\n * `resolveOnly`'s walk would filter out are kept here and labelled\n * `ineligible` instead. Pure query: no invoker runs, no in-flight state\n * changes, no trace-log entry.\n *\n * `resolveOnly` is the first `would-fire` entry of this list.\n *\n * Shares `resolveOnly`'s known divergence from a real dispatch: an ongoing\n * invoker that matches but returns an empty handle at `start()` makes the\n * real dispatch fall through, and this cannot see that.\n *\n * By default everything below the winner is `shadowed` without being asked,\n * which is what keeps this walk as cheap as the dispatch it replays. Pass\n * `{ evaluateShadowed: true }` to keep evaluating past the winner, so a\n * lower candidate that is ALSO ineligible or disabled says so — see\n * {@link ResolveAllOptions.evaluateShadowed}.\n */\n resolveAll(\n event: InputEvent,\n ctx: DispatcherContext,\n opts?: ResolveAllOptions,\n ): ResolvedCandidate[];\n\n /**\n * The full {@link DispatchRecord} for `event` — what matched, what each\n * filter dropped, how the rest ranked and why, and the walk — without\n * invoking anything, so `predicted` is true and the winner is `would-fire`.\n * It is the same computation `handleInput` and `resolveAll` run. Costs more\n * than `resolveOnly`: it renders every candidate's routes and rule.\n */\n explain(event: InputEvent, ctx: DispatcherContext, opts?: ResolveAllOptions): DispatchRecord;\n\n /**\n * Synthesize an end-of-gesture for every in-flight ongoing handle.\n * Used by tool-switch cancellation (Q2 decision).\n */\n cancelAll(reason: 'commit' | 'cancel'): void;\n\n /**\n * Read-only view of currently in-flight ongoing handles, keyed by gestureId.\n * For debug/testing.\n */\n inFlight(): ReadonlyMap<string, OngoingHandle>;\n\n /**\n * CSS cursor for the gesture currently in flight, or `null` when nothing\n * is. Reads `Action.activeCursor` (falling back to `Action.cursor`) off the\n * action whose handle is open — the hover pump applies this instead of its\n * prediction once a gesture starts, which is how `grab` becomes `grabbing`.\n */\n inFlightCursor(): string | null;\n\n /**\n * Read-only iterator over currently in-flight `OngoingHandle` instances.\n *\n * Surface for the canvas's preview-ghost layer (`usePreviewGhostLayer`)\n * to walk each handle's `previewIds()` / `previewPose(id)` and render\n * dispatcher-driven gesture previews. Read-only by design:\n * external consumers must not mutate the in-flight map.\n */\n getInFlightHandles(): Iterable<OngoingHandle>;\n\n /**\n * Subscribe to in-flight state changes. The callback fires after every\n * mutation that affects what the preview-ghost / dispatcher-overlay\n * layers read — handle start, every `onMove` pump, end, cancel,\n * cancel-all. Consumers re-read `getInFlightHandles()` and re-render.\n *\n * Returns an unsubscribe function.\n */\n subscribe(fn: () => void): () => void;\n\n /**\n * Monotonic counter bumped on exactly the events {@link subscribe} fires\n * on. The snapshot half of the `useSyncExternalStore` contract: pair it\n * with `subscribe` to drive a render off in-flight gesture state without\n * a `useReducer` force-rerender.\n *\n * Starts at 0 and only ever increases. Two reads returning the same number\n * mean nothing pumped in between; it does **not** guarantee that a bump\n * changed anything observable (a pump that matched no binding still\n * counts — see `subscribe`).\n */\n getVersion(): number;\n\n /**\n * Snapshot of the currently active action, for surfaces (chrome-caps\n * visibility rules, debug HUDs) that need to react to \"what action\n * is in flight right now.\"\n *\n * - `kind` — the `OngoingHandle.kind` reported by the in-flight\n * handle (e.g. `'marquee'`, `'move'`). `null` when no action is\n * in flight OR the handle didn't declare a kind.\n * - `id` — the dispatcher's internal `gestureId` (`pointer-1`,\n * `key-held-Space`, …) — the pointer/key channel the action rode\n * in on. `null` when no action is in flight.\n *\n * When multiple handles are in flight simultaneously (e.g. a key-held\n * action overlapping a pointer action), the most-recently-started\n * handle wins. This matches user intent: the latest interaction is\n * the one consumers care about.\n *\n * That rule used to be near-vacuous on the pointer side, because every\n * pointer shared one handle slot and two pointer drags could not coexist.\n * With per-pointer keying they can — but only via paths that bypass the\n * multi-pointer policy in `useGestureDispatcher` (which stops a second\n * finger from opening a drag while a pinch is live), such as a mouse and\n * a pen used together. Latest-start remains the right answer there.\n */\n getActiveAction(): { kind: string | null; id: string | null };\n\n /**\n * Start an ongoing action driven by UI (not a gesture). Builds an\n * `InvocationCtx` with the given `deps` and `params`, calls\n * `action.invoker.start(ctx, { params })`, and registers the returned\n * handle in the in-flight map so `getInFlightHandles()` reports it —\n * enabling preview rendering via `SceneCanvas`.\n *\n * Returns `null` if `actionId` is unknown, the action's invoker is not\n * ongoing, or `start` returned an empty handle.\n *\n * If a UI-driven handle for the same `actionId` is already in flight,\n * it is committed (`end('commit')`) before the new one starts.\n */\n beginUiOngoing(\n actionId: string,\n deps: ActionDeps,\n params?: Record<string, unknown>,\n ): UiOngoingControl | null;\n}\n\n// ---------------------------------------------------------------------------\n// createDispatcher\n// ---------------------------------------------------------------------------\n\nconst EMPTY_ENGAGED: ReadonlySet<string> = new Set();\n\n/**\n * Modifier flags as an immediate invoker sees them, in the kit's\n * `ModifierState` spelling rather than the DOM's `*Key` one.\n *\n * Ongoing invokers read modifiers off `InvocationCtx`; immediate ones get only\n * `(deps, params)`, so pointer-driven immediate actions need them merged into\n * params the same way wheel deltas already are. Most actions should still\n * express modifier semantics as separate bindings with `opts.params` — that is\n * what makes them visible to conflict detection and the inspector. This is for\n * the cases where the modifier is data rather than a route, e.g. select\n * forwarding the press's modifiers into `SelectionApi.applyClick`, which\n * resolves them against the host's configured extend key.\n */\nfunction modifiersOf(e: {\n altKey: boolean; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean;\n}): { alt: boolean; ctrl: boolean; meta: boolean; shift: boolean } {\n return { alt: e.altKey, ctrl: e.ctrlKey, meta: e.metaKey, shift: e.shiftKey };\n}\n\n/** The world point an event landed on, for `Action.enabled`'s position\n * argument. Undefined for events with no position (keys, drops, pastes). */\nfunction worldPointOf(event: InputEvent): { x: number; y: number } | undefined {\n switch (event.kind) {\n case 'pointerdown':\n case 'longpress':\n case 'click':\n case 'doubleclick':\n case 'contextmenu':\n return event.x !== undefined && event.y !== undefined ? { x: event.x, y: event.y } : undefined;\n default:\n return undefined;\n }\n}\n\n/** Build a dispatcher. `getAction` overrides how action ids are resolved;\n * by default the `DispatcherContext`'s registry is used. */\nexport function createDispatcher(opts?: {\n getAction?: (id: string) => Action | undefined;\n}): Dispatcher {\n const inFlightHandles = new Map<string, OngoingHandle>();\n /** gestureId → tool id that owns the binding which opened this handle.\n * Used to compute the `engagedChannels` PhaseContext for the matcher.\n * `null` when the opening binding came from an ambient action with no\n * owning tool. */\n const inFlightOwners = new Map<string, string | null>();\n /** Gesture id -> the Action whose handle is in flight, so the hover-cursor\n * pump can ask what the gesture currently IS rather than what a drag from\n * here WOULD be. See `Action.activeCursor`. */\n const inFlightActions = new Map<string, Action>();\n\n // -------------------------------------------------------------------------\n // Helpers\n // -------------------------------------------------------------------------\n\n /**\n * Per-gesture drag origin, keyed by gestureId.\n * Set when an ongoing drag handle is opened; used to compute deltas for\n * `pointermove` pump events.\n *\n * Stores both world (`x`/`y`) and client/screen (`clientX`/`clientY`)\n * coordinates so we can produce both `drag.delta` (world) and\n * `drag.screenDelta` (client). View-mutating drag actions (pan, etc.)\n * must consume `screenDelta` — world deltas are self-referential when\n * the action itself shifts the view.\n */\n const dragOrigins = new Map<string, { x: number; y: number; clientX?: number; clientY?: number }>();\n\n /** Subscribers fired after every state mutation. Layers that read from\n * `getInFlightHandles()` use this to know when to re-render. */\n const subscribers = new Set<() => void>();\n /** Bumped before the callbacks run, so a subscriber that re-reads\n * `getVersion()` synchronously inside its callback already sees the new\n * value (what `useSyncExternalStore` does). */\n let version = 0;\n function notify(): void {\n version++;\n for (const fn of subscribers) fn();\n }\n\n /**\n * Per-gesture pointermove history (world-space points), keyed by gestureId.\n * Accumulated on every `pointermove` pump event. Passed as\n * `InvocationCtx.drag.points` so invokers that need the full path\n * (e.g. `lassoSelectAction`) can consume it.\n *\n * Samples carry the originating event's stylus fields (pressure / tilt)\n * when present, so pressure-aware invokers — `insertAction`'s pencil\n * kind — get per-sample data without their own pointer plumbing.\n */\n const dragPoints = new Map<string, DragSample[]>();\n\n /**\n * Pinch-zoom start spread, keyed by multitouch gestureId.\n * Captured when the multitouch ongoing handle first opens.\n */\n const pinchStartSpreads = new Map<string, number>();\n\n /** Monotonic counter for synthesizing unique gestureIds for UI-driven\n * ongoing handles. Each `beginUiOngoing` call increments this. */\n let uiOngoingSeq = 0;\n\n /** actionId → gestureId of the currently in-flight UI-driven handle for\n * that action, if any. Used to auto-commit a prior handle when a new\n * `beginUiOngoing(sameActionId, …)` arrives. */\n const uiOngoingByAction = new Map<string, string>();\n\n /** Returns true when a handle carries no gesture-processing callbacks or\n * preview data — i.e. the invoker decided at runtime not to engage. */\n function isEmptyOngoingHandle(h: OngoingHandle): boolean {\n return !h.onMove && !h.onEnd && !h.overlay && !h.previewIds && !h.previewPose;\n }\n\n // The view the input being handled landed in. Set per `handleInput`, so a\n // pump of an in-flight gesture reports the view it is pinned to.\n let routedView: string | null | undefined;\n\n /** Build a zero-position InvocationCtx for UI-driven invocations (no\n * pointer event involved — world/screen coords are irrelevant). */\n function buildUiInvocationCtx(deps: ActionDeps, params?: Record<string, unknown>): InvocationCtx {\n return {\n world: { x: 0, y: 0 },\n modifiers: { alt: false, ctrl: false, meta: false, shift: false },\n deps,\n ...(params !== undefined ? { params } : {}),\n };\n }\n\n /** Build a minimal InvocationCtx stub for the given event + deps. */\n function buildInvocationCtx(event: InputEvent, deps: ActionDeps, gestureId?: string): InvocationCtx {\n const modifiers = {\n alt: event.altKey,\n ctrl: event.ctrlKey,\n meta: event.metaKey,\n shift: event.shiftKey,\n };\n const base: InvocationCtx = {\n world: { x: 0, y: 0 },\n modifiers,\n deps,\n ...(routedView !== undefined ? { viewId: routedView } : {}),\n };\n\n // The pointer in client pixels, where the event carries it. Not every kind\n // does, which is why `ctx.screen` is optional — filling it from the world\n // point instead is how it came to be screen-space in name only.\n const clientPoint = (ev: InputEvent): Point2 | undefined => {\n const cx = (ev as { clientX?: number }).clientX;\n const cy = (ev as { clientY?: number }).clientY;\n return cx !== undefined && cy !== undefined ? { x: cx, y: cy } : undefined;\n };\n const screen = clientPoint(event);\n if (screen) base.screen = screen;\n\n // Populate gesture-kind-specific fields.\n if (event.kind === 'key') {\n base.key = { key: event.key, repeat: event.repeat ?? false };\n } else if (event.kind === 'key-held') {\n base.key = { key: event.key, repeat: false };\n } else if (event.kind === 'wheel') {\n base.wheel = { deltaX: event.deltaX, deltaY: event.deltaY, deltaZ: 0 };\n } else if (event.kind === 'pinch') {\n base.pinch = { scale: event.scale, rotation: event.rotation };\n } else if (\n event.kind === 'pointerdown'\n || event.kind === 'click'\n || event.kind === 'doubleclick'\n || event.kind === 'contextmenu'\n ) {\n // A click's own world point is `x`/`y` — the release — with the press\n // as the fallback for a consumer that wired neither.\n const sx = event.x ?? (event.kind === 'click' ? event.pressX : undefined) ?? 0;\n const sy = event.y ?? (event.kind === 'click' ? event.pressY : undefined) ?? 0;\n base.world = { x: sx, y: sy };\n const affordance = event.kind === 'pointerdown' ? (event.affordance as AffordanceHit | undefined) : undefined;\n base.drag = {\n start: { x: sx, y: sy },\n current: { x: sx, y: sy },\n delta: { x: 0, y: 0 },\n ...(affordance !== undefined ? { affordance } : {}),\n };\n } else if (event.kind === 'pointermove' || event.kind === 'pointerup') {\n const cx = event.x;\n const cy = event.y;\n base.world = { x: cx, y: cy };\n // Compute delta relative to drag origin if available.\n const origin = gestureId ? dragOrigins.get(gestureId) : undefined;\n const ox = origin?.x ?? cx;\n const oy = origin?.y ?? cy;\n // Live accumulator during the drag — copying it on every move would be\n // quadratic — but a snapshot on the last event, because `onEnd` is where\n // an action is entitled to keep the trail, and the dispatcher clears the\n // accumulator the moment it returns.\n const live = gestureId ? dragPoints.get(gestureId) : undefined;\n const points = live && event.kind === 'pointerup' ? [...live] : live;\n // Screen-space delta — populated when both the event and origin carry\n // client coords. View-mutating drag actions must read this rather than\n // the world `delta` (world deltas are self-referential mid-pan).\n const eventClientX = event.clientX;\n const eventClientY = event.clientY;\n const hasClient =\n eventClientX !== undefined && eventClientY !== undefined\n && origin?.clientX !== undefined && origin?.clientY !== undefined;\n base.drag = {\n start: { x: ox, y: oy },\n current: { x: cx, y: cy },\n delta: { x: cx - ox, y: cy - oy },\n ...(hasClient\n ? { screenDelta: { x: eventClientX! - origin!.clientX!, y: eventClientY! - origin!.clientY! } }\n : {}),\n ...(points !== undefined ? { points } : {}),\n };\n } else if (event.kind === 'multitouch') {\n const centroid = event.centroid ?? { x: 0, y: 0 };\n const spread = event.spread ?? 1;\n // Populate pinch geometry when this is a move-pump (centroid/spread present).\n const startSpread = gestureId ? pinchStartSpreads.get(gestureId) : undefined;\n base.multiTouch = {\n centroid,\n spread,\n rotation: 0,\n ...(startSpread !== undefined && event.spread !== undefined\n ? { pinch: { startSpread, currentSpread: spread, centroid } }\n : {}),\n };\n }\n\n return base;\n }\n\n /**\n * Derive a gestureId from an event for keying in-flight ongoing handles.\n * See module JSDoc for the full scheme.\n */\n function gestureIdFor(event: InputEvent): string {\n if (event.kind === 'key-held') {\n return `key-held-${event.key}`;\n }\n if (\n event.kind === 'pointerdown' ||\n event.kind === 'pointermove' ||\n event.kind === 'pointerup' ||\n event.kind === 'pointercancel'\n ) {\n return pointerGestureId(event.pointerId);\n }\n if (event.kind === 'multitouch') {\n return `multitouch-${event.fingers}`;\n }\n return `ongoing-${event.kind}`;\n }\n\n /** Assemble the ScopedBinding list: every registered entry, tiered by what\n * it declares about its own eligibility, then the actions registry. */\n function assembleScopedBindings(ctx: DispatcherContext): ScopedBinding[] {\n // Hotkey-engaged entries lead, so stack order breaks ties within that tier\n // — newest hold first. `pushHotkey` appends and every other reader takes\n // the top as the engaged one (`ToolsApi.hotkeyEngaged` is `.at(-1)`), so\n // walking the stack bottom-first handed ties to the oldest hold and routed\n // a drag to a tool the rest of the kit did not consider engaged.\n const ordered: Contribution<unknown>[] = [];\n for (let i = ctx.hotkeyStack.length - 1; i >= 0; i--) {\n const id = ctx.hotkeyStack[i]!;\n const entry = ctx.entriesById.get(id);\n if (entry && !ordered.includes(entry)) ordered.push(entry);\n }\n for (const entry of ctx.entriesById.values()) {\n if (!ordered.includes(entry)) ordered.push(entry);\n }\n // `Eligibility.capabilities` is a tool-level gate over the same tags the\n // `capability:` selector reads. It is the only one that fires for a tool\n // whose action declares no `eligible` rule. A consumer with no mode system\n // supplies no `getRuleCtx`, and then `allows` stays absent and everything\n // is permitted — which is what every such consumer has always seen.\n const capsCtx = ctx.getRuleCtx?.();\n const allows = capsCtx\n ? (tags: readonly CapabilityTag[]) =>\n tags.every((tag) => capsCtx.allowedCapabilities.has(tag))\n : undefined;\n const view = ctx.viewId ?? null;\n const result: ScopedBinding[] = scopeBindings(ordered, {\n focusedId: ctx.activeToolId,\n engagedIds: new Set(ctx.hotkeyStack),\n ...(allows ? { allows } : {}),\n }).filter((sb) => liveInView(sb.binding, view));\n\n // Actions have no owning tool — `'&'`-channel phase atoms on their\n // bindings won't match.\n for (const action of ctx.actions.list()) {\n const targetScope: BindingScope = action.scope === 'hotkey' ? 'hotkey' : 'ambient';\n for (const binding of actionBindings(action)) {\n if (!liveInView(binding, view)) continue;\n result.push({ binding, scope: targetScope, ownerId: null });\n }\n }\n\n return result;\n }\n\n /** Snapshot the set of tool ids currently owning an in-flight handle —\n * fed to `matchSorted` as the `engagedChannels` field of `PhaseContext`. */\n function snapshotEngagedChannels(): ReadonlySet<string> {\n if (inFlightOwners.size === 0) return EMPTY_ENGAGED;\n const out = new Set<string>();\n for (const owner of inFlightOwners.values()) {\n if (owner != null) out.add(owner);\n }\n return out;\n }\n\n /** Build an actionId → Action lookup from the registry. */\n function buildActionMap(registry: ActionSource): Map<string, Action> {\n const map = new Map<string, Action>();\n for (const action of registry.list()) {\n map.set(action.id, action);\n }\n return map;\n }\n\n // -------------------------------------------------------------------------\n // handleInput\n // -------------------------------------------------------------------------\n\n function handleInput(event: InputEvent, ctx: DispatcherContext): 'handled' | 'unhandled' {\n routedView = ctx.viewId;\n // --- Pump: check for key-held up-phase against in-flight handle ---\n if (event.kind === 'key-held' && event.phase === 'up') {\n const gestureId = gestureIdFor(event);\n const handle = inFlightHandles.get(gestureId);\n if (handle) {\n const stubCtx = buildInvocationCtx(event, {}, gestureId);\n handle.onEnd?.(stubCtx, 'commit');\n inFlightHandles.delete(gestureId);\n inFlightOwners.delete(gestureId);\n inFlightActions.delete(gestureId);\n dragOrigins.delete(gestureId);\n }\n // Whether we had a handle or not, this is a follow-up event, not a new match.\n return handle ? 'handled' : 'unhandled';\n }\n\n // --- Pump: key-held DOWN re-dispatch for an already-engaged key is a\n // no-op. This is the dispatcher-side defense against autorepeat\n // keydowns (and any caller that re-dispatches) firing `start()`\n // again — each start pushes a offhand hotkey, only one keyup ever\n // fires onEnd, so the stack would leak. Treat as handled (we ARE\n // holding the key) without re-invoking. ---\n if (event.kind === 'key-held' && event.phase === 'down') {\n const gestureId = gestureIdFor(event);\n if (inFlightHandles.has(gestureId)) {\n return 'handled';\n }\n }\n\n // --- Pump: pointermove → onMove on the in-flight drag handle ---\n if (event.kind === 'pointermove') {\n const gestureId = gestureIdFor(event);\n const handle = inFlightHandles.get(gestureId);\n if (!handle) return 'unhandled';\n // Accumulate the world-space point whether or not this handle previews.\n // `onEnd` is handed the same trail, so an action that only reads the\n // finished path — and therefore declares no `onMove` — must still get\n // every vertex rather than the press point alone.\n const pts = dragPoints.get(gestureId);\n if (pts) {\n pts.push({\n x: event.x,\n y: event.y,\n ...(event.pressure !== undefined ? { pressure: event.pressure } : {}),\n ...(event.tiltX !== undefined ? { tiltX: event.tiltX } : {}),\n ...(event.tiltY !== undefined ? { tiltY: event.tiltY } : {}),\n });\n }\n if (handle.onMove) {\n const moveCtx = buildInvocationCtx(event, {}, gestureId);\n handle.onMove(moveCtx);\n return 'handled';\n }\n return 'unhandled';\n }\n\n // --- Pump: pointerup → onEnd('commit') on the in-flight drag handle ---\n if (event.kind === 'pointerup') {\n const gestureId = gestureIdFor(event);\n const handle = inFlightHandles.get(gestureId);\n if (handle) {\n const endCtx = buildInvocationCtx(event, {}, gestureId);\n handle.onEnd?.(endCtx, 'commit');\n inFlightHandles.delete(gestureId);\n inFlightOwners.delete(gestureId);\n inFlightActions.delete(gestureId);\n dragOrigins.delete(gestureId);\n dragPoints.delete(gestureId);\n }\n return handle ? 'handled' : 'unhandled';\n }\n\n // --- Pump: pointercancel → onEnd('cancel') on the in-flight drag handle ---\n if (event.kind === 'pointercancel') {\n const gestureId = gestureIdFor(event);\n const handle = inFlightHandles.get(gestureId);\n if (handle) {\n const endCtx = buildInvocationCtx(event, {}, gestureId);\n handle.onEnd?.(endCtx, 'cancel');\n inFlightHandles.delete(gestureId);\n inFlightOwners.delete(gestureId);\n inFlightActions.delete(gestureId);\n dragOrigins.delete(gestureId);\n dragPoints.delete(gestureId);\n }\n return handle ? 'handled' : 'unhandled';\n }\n\n // --- Pump: multitouch move → onMove on the in-flight multitouch handle ---\n // When a multitouch event arrives with centroid/spread data AND a handle is\n // already in flight, route it to the handle's onMove. When no handle is in\n // flight, fall through to scope assembly so the event can start a new handle.\n if (event.kind === 'multitouch' && event.centroid !== undefined) {\n const gestureId = gestureIdFor(event);\n const handle = inFlightHandles.get(gestureId);\n if (handle?.onMove) {\n const moveCtx = buildInvocationCtx(event, {}, gestureId);\n handle.onMove(moveCtx);\n return 'handled';\n }\n // A hand is doing one multitouch gesture at a time, but the gesture id\n // carries the finger count — so a finger landing or lifting mid-gesture\n // names a different one. Nothing else ends the handle the hand has left:\n // the seam only ends multitouch when the count drops below two, so a\n // three-to-two transition left the three-finger handle in flight,\n // unpumped, until the final lift committed it alongside the real one.\n for (const [id, other] of [...inFlightHandles]) {\n if (!id.startsWith('multitouch-') || id === gestureId) continue;\n other.onEnd?.(buildInvocationCtx(event, {}, id), 'cancel');\n inFlightHandles.delete(id);\n inFlightOwners.delete(id);\n inFlightActions.delete(id);\n pinchStartSpreads.delete(id);\n }\n // No in-flight handle → fall through to scope assembly + match below.\n // This allows the initial multitouch event (which carries centroid/spread)\n // to start a new ongoing handle on first dispatch.\n }\n\n const r = rank(event, ctx, DEV);\n const walked = walk(r, event, ctx, (match, action, deps) => invoke(event, match, action, deps), false);\n const outcome: 'handled' | 'unhandled' = walked.stop === 'fired' ? 'handled' : 'unhandled';\n if (DEV) recordTrace(buildRecord(r, walked, event, ctx, false, outcome));\n return outcome;\n }\n\n /** Run the winning candidate. `'fired'` ends the walk; `'empty-handle'`\n * falls through to the next candidate; `'misbound'` ends it unhandled. */\n function invoke(\n event: InputEvent,\n match: MatchResult,\n action: Action,\n deps: ActionDeps,\n ): 'fired' | 'empty-handle' | 'misbound' {\n if (action.invoker?.timing === 'immediate') {\n try {\n // For wheel / click / doubleclick bindings, merge event-time\n // delta/position data into params so the immediate invoker\n // sees both binding-declared params (e.g. `kind: 'wheel'`)\n // and runtime event data. Option (a) from the design doc —\n // simpler than extending InvocationCtx for immediate invokers.\n const resolved = resolveParams(match.binding.opts?.params);\n let params: Record<string, unknown> | undefined;\n if (event.kind === 'wheel') {\n params = {\n deltaX: event.deltaX,\n deltaY: event.deltaY,\n clientX: event.clientX,\n clientY: event.clientY,\n affordance: event.affordance,\n ...resolved,\n };\n } else if (event.kind === 'pinch') {\n params = {\n scale: event.scale,\n rotation: event.rotation,\n clientX: event.clientX,\n clientY: event.clientY,\n affordance: event.affordance,\n ...resolved,\n };\n } else if (event.kind === 'click' || event.kind === 'doubleclick') {\n params = {\n worldX: event.x,\n worldY: event.y,\n affordance: event.affordance,\n // Press point as well as release point — an action that places\n // geometry at the click wants the former. See `ClickEvent`.\n ...(event.kind === 'click'\n ? { pressX: event.pressX, pressY: event.pressY }\n : {}),\n mods: modifiersOf(event),\n ...resolved,\n };\n } else if (event.kind === 'contextmenu' || event.kind === 'longpress') {\n params = {\n worldX: event.x,\n worldY: event.y,\n affordance: event.affordance,\n bodyTarget: event.bodyTarget,\n mods: modifiersOf(event),\n ...resolved,\n };\n } else if (event.kind === 'pointerdown') {\n // Only `stage: 'press'` events reach an immediate invoker — the\n // buffered copy matches `drag` specs, which are ongoing.\n params = {\n worldX: event.x,\n worldY: event.y,\n affordance: event.affordance,\n bodyTarget: event.bodyTarget,\n mods: modifiersOf(event),\n ...resolved,\n };\n } else if (event.kind === 'drop' || event.kind === 'paste') {\n // External-content events: forward the materialized items and,\n // for drops, the world-space arrival point.\n params = {\n items: event.items,\n via: event.kind,\n ...(event.kind === 'drop' && event.x !== undefined\n ? { worldX: event.x, worldY: event.y }\n : {}),\n ...resolved,\n };\n } else {\n params = resolved;\n }\n action.invoker.run(deps, params);\n } catch (err) {\n console.error(`weasel dispatcher: action \"${action.id}\" invoker threw`, err);\n }\n return 'fired';\n }\n\n if (action.invoker?.timing === 'ongoing') {\n // A `pointerDown` binding fires at press time, on the same\n // `pointer-<id>` gesture id the drag will use. Letting an ongoing\n // action open its handle here would make the drag's own dispatch find\n // a handle already in flight and silently no-op. `PointerDownSpec`\n // documents itself as immediate-only; enforce it rather than let the\n // collision happen quietly.\n if (event.kind === 'pointerdown' && event.stage === 'press') {\n console.error(\n `weasel dispatcher: action \"${action.id}\" has an ongoing invoker but is bound to a `\n + `pointerDown spec, which fires at press time. Bind it to a drag spec, or give the `\n + `action an immediate invoker.`,\n );\n return 'misbound';\n }\n const gestureId = gestureIdFor(event);\n // Record the drag origin so subsequent pointermove events can compute delta.\n if (event.kind === 'pointerdown') {\n dragOrigins.set(gestureId, {\n x: event.x ?? 0,\n y: event.y ?? 0,\n ...(event.clientX !== undefined ? { clientX: event.clientX } : {}),\n ...(event.clientY !== undefined ? { clientY: event.clientY } : {}),\n });\n // Initialize empty drag-points history for the new gesture.\n dragPoints.set(gestureId, [{\n x: event.x ?? 0,\n y: event.y ?? 0,\n ...(event.pressure !== undefined ? { pressure: event.pressure } : {}),\n ...(event.tiltX !== undefined ? { tiltX: event.tiltX } : {}),\n ...(event.tiltY !== undefined ? { tiltY: event.tiltY } : {}),\n }]);\n }\n // Record start spread for pinch-zoom gestures.\n if (event.kind === 'multitouch' && event.spread !== undefined) {\n pinchStartSpreads.set(gestureId, event.spread);\n }\n const invCtx = buildInvocationCtx(event, deps, gestureId);\n const handle = action.invoker.start(invCtx, match.binding.opts);\n // Empty handle = \"matched at the binding level but decided at runtime\n // not to handle this gesture\" (missing dep, wrong affordance, wrong\n // selection kind, etc.). The widely-used early-return-empty pattern\n // depends on the dispatcher falling through to the next match —\n // otherwise the binding silently swallows the gesture.\n if (isEmptyOngoingHandle(handle)) {\n // Clean up the per-gesture state we set above so a later match\n // (still on the same pointerdown) sees a fresh slate.\n if (event.kind === 'pointerdown') {\n dragOrigins.delete(gestureId);\n dragPoints.delete(gestureId);\n }\n if (event.kind === 'multitouch') {\n pinchStartSpreads.delete(gestureId);\n }\n return 'empty-handle';\n }\n inFlightHandles.set(gestureId, handle);\n inFlightOwners.set(gestureId, match.ownerId);\n inFlightActions.set(gestureId, action);\n return 'fired';\n }\n\n // No invoker — action is registered but has nothing to do for this\n // matched binding. Treat as handled (the binding consumed the gesture\n // and the no-op is intentional) to keep dispatch deterministic.\n return 'fired';\n }\n\n // -------------------------------------------------------------------------\n // The walk — one computation behind dispatch, prediction and the record\n // -------------------------------------------------------------------------\n\n /** One input's candidates, matched, filtered and ranked, before any is asked. */\n interface Ranking {\n /** Every match the claim admitted, best first — ineligible ones\n * included, in the place they would hold. */\n ordered: MatchResult[];\n /** Matches an exclusive claim barred; collected only when recording. */\n barred: MatchResult[];\n claimOwner?: string;\n actionMap: Map<string, Action>;\n ruleCtx: RuleCtx | undefined;\n /** Whether a match survives the eligibility filter. */\n eligible(m: MatchResult): boolean;\n }\n\n function rank(event: InputEvent, ctx: DispatcherContext, collectBarred: boolean): Ranking {\n const view = ctx.viewId ?? null;\n const outcome = matchSortedWithBarred(\n event, assembleScopedBindings(ctx), ctx.isMac, snapshotEngagedChannels(), { collectBarred },\n );\n const sorted = preferViewScoped(outcome.matches, view);\n const actionMap = buildActionMap(ctx.actions);\n const ruleCtx = ruleCtxOf(ctx);\n // Asked from the ranking, the filter and the record; a rule runs once per input.\n const held = new Map<Action, boolean>();\n const holds = (a: Action): boolean => {\n if (ruleCtx === undefined) return true;\n let h = held.get(a);\n if (h === undefined) held.set(a, h = isEligible(a, ruleCtx));\n return h;\n };\n // Ranking the ineligible alongside the rest leaves the survivors in the\n // order ranking them alone would: `preferContextual` only reorders within\n // a run of ties, and every tie's members sit together.\n const ordered = ruleCtx\n ? preferContextual(sorted, (id) => actionMap.get(id), holds, view)\n : sorted;\n return {\n ordered,\n barred: outcome.barred,\n ...(outcome.claimOwner !== undefined ? { claimOwner: outcome.claimOwner } : {}),\n actionMap,\n ruleCtx,\n eligible: (m) => {\n const a = actionMap.get(m.binding.actionId);\n return a === undefined || holds(a);\n },\n };\n }\n\n interface Walked {\n /** Survivors of both filters, best first, each with what the walk did. */\n steps: Array<{ match: MatchResult; step: WalkStep }>;\n /** Why the walk ended: a candidate fired (or would), one was misbound, or\n * every candidate was exhausted. */\n stop: 'fired' | 'misbound' | 'exhausted';\n winner: { match: MatchResult; action: Action } | null;\n }\n\n /**\n * Walk the ranked survivors, asking each action's `enabled()` in turn. With\n * `attempt`, the first that passes is run and the walk ends unless it bails;\n * without, it is the predicted winner. Each action is asked at most once.\n */\n function walk(\n r: Ranking,\n event: InputEvent,\n ctx: DispatcherContext,\n attempt: ((match: MatchResult, action: Action, deps: ActionDeps) => 'fired' | 'empty-handle' | 'misbound') | null,\n evaluateShadowed: boolean,\n ): Walked {\n const steps: Walked['steps'] = [];\n const tried = new Set<string>();\n let stop: Walked['stop'] = 'exhausted';\n let winner: Walked['winner'] = null;\n for (const match of r.ordered) {\n if (!r.eligible(match)) continue;\n const push = (step: WalkStep): void => { steps.push({ match, step }); };\n const actionId = match.binding.actionId;\n if (tried.has(actionId)) { push({ kind: 'duplicate' }); continue; }\n if (stop !== 'exhausted' && !evaluateShadowed) { push({ kind: 'not-asked' }); continue; }\n tried.add(actionId);\n const action = r.actionMap.get(actionId);\n if (!action) {\n if (attempt) {\n console.warn(\n `weasel dispatcher: binding resolved actionId \"${actionId}\" which has `\n + `no registered action. Skipping. (misconfiguration)`,\n );\n }\n push({ kind: 'no-such-action' });\n continue;\n }\n // Deps are built before the gate so predicates can read them; the\n // winner's invoke reuses the same bag. Shared with\n // `ActionsRegistry.trigger`, including the dev undeclared-read guard.\n const deps = buildDepsFromRequires(action, ctx.depRegistry);\n const enabled = action.enabled ? action.enabled(deps, worldPointOf(event)) : true;\n if (enabled !== true) { push({ kind: 'declined', reason: String(enabled) }); continue; }\n if (stop !== 'exhausted') { push({ kind: 'outranked' }); continue; }\n if (!attempt) {\n push({ kind: 'would-fire' });\n stop = 'fired';\n winner = { match, action };\n continue;\n }\n const result = attempt(match, action, deps);\n if (result === 'empty-handle') { push({ kind: 'empty-handle' }); continue; }\n push({ kind: result === 'fired' ? 'fired' : 'misbound' });\n stop = result;\n winner = { match, action };\n }\n return { steps, stop, winner };\n }\n\n /** Project a ranking and its walk into a plain {@link DispatchRecord}. */\n function buildRecord(\n r: Ranking,\n walked: Walked,\n event: InputEvent,\n ctx: DispatcherContext,\n predicted: boolean,\n outcome: 'handled' | 'unhandled',\n ): DispatchRecord {\n const view = ctx.viewId ?? null;\n const candidates = new Map<MatchResult, RecordCandidate>();\n const candidateOf = (m: MatchResult): RecordCandidate => {\n let c = candidates.get(m);\n if (!c) {\n const eligible = r.actionMap.get(m.binding.actionId)?.eligible;\n c = {\n actionId: m.binding.actionId,\n routes: routesForSpec(m.binding.spec),\n scope: m.scope,\n ownerId: m.ownerId,\n namesView: namesView(m.binding, view),\n specificity: specificity(m.binding.spec),\n ...(eligible !== undefined ? { eligible: describeEligible(eligible) } : {}),\n };\n candidates.set(m, c);\n }\n return c;\n };\n const dropped: DroppedCandidate[] = [\n ...r.barred.map((m): DroppedCandidate => ({\n candidate: candidateOf(m),\n filter: 'claim',\n ...(r.claimOwner !== undefined ? { owner: r.claimOwner } : {}),\n })),\n ];\n for (const m of r.ordered) {\n if (r.eligible(m)) continue;\n const c = candidateOf(m);\n dropped.push({ candidate: c, filter: 'ineligible', rule: c.eligible ?? '' });\n }\n const gated = (m: MatchResult): boolean =>\n r.actionMap.get(m.binding.actionId)?.eligible !== undefined;\n const ranked: RankedCandidate[] = walked.steps.map(({ match, step }, i) => {\n const prev = walked.steps[i - 1]?.match;\n return {\n candidate: candidateOf(match),\n placedBy: prev ? placedBy(prev, match, view, r.ruleCtx !== undefined && gated(prev) && !gated(match)) : { step: 'first' },\n walk: step,\n };\n });\n const eventKey = event.kind === 'key' || event.kind === 'key-held' ? event.key : undefined;\n const world = worldPointOf(event);\n return {\n kind: 'dispatch',\n ts: Date.now(),\n input: {\n eventKind: event.kind,\n ...(eventKey !== undefined ? { key: eventKey } : {}),\n modifiers: modifiersOf(event),\n viewId: view,\n ...(world !== undefined ? { world } : {}),\n ...(r.ruleCtx !== undefined ? { mode: r.ruleCtx.mode } : {}),\n },\n matched: [...r.ordered, ...r.barred].map(candidateOf),\n dropped,\n ranked,\n predicted,\n fired: walked.winner?.action.id ?? null,\n outcome,\n };\n }\n\n // -------------------------------------------------------------------------\n // resolveAll / resolveOnly / explain — prediction without invocation\n // -------------------------------------------------------------------------\n\n function resolveAll(\n event: InputEvent,\n ctx: DispatcherContext,\n // Not `opts` — `createDispatcher`'s own `opts` is in scope here.\n resolveOpts?: ResolveAllOptions,\n ): ResolvedCandidate[] {\n const evaluateShadowed = resolveOpts?.evaluateShadowed ?? false;\n const r = rank(event, ctx, false);\n if (r.ordered.length === 0) return [];\n const walked = walk(r, event, ctx, null, evaluateShadowed);\n const stepOf = new Map(walked.steps.map((s) => [s.match, s.step]));\n\n // Verdict per action id, so a second binding for an action already judged\n // higher up inherits that verdict — the walk asks each action once.\n const verdictByAction = new Map<string, ResolvedCandidate['verdict']>();\n let fired = false;\n const out: ResolvedCandidate[] = [];\n for (const match of r.ordered) {\n const actionId = match.binding.actionId;\n const action = r.actionMap.get(actionId);\n // A binding pointing at an unregistered action can never fire.\n if (!action) continue;\n\n let verdict = verdictByAction.get(actionId);\n if (verdict === undefined) {\n if (!r.eligible(match)) {\n verdict = fired && !evaluateShadowed\n ? { kind: 'shadowed' }\n : { kind: 'ineligible', reason: describeEligible(action.eligible!) };\n } else {\n const step = stepOf.get(match);\n if (step?.kind === 'would-fire') {\n verdict = { kind: 'would-fire' };\n fired = true;\n } else if (step?.kind === 'declined') {\n verdict = { kind: 'disabled', reason: step.reason };\n } else {\n verdict = { kind: 'shadowed' };\n }\n }\n verdictByAction.set(actionId, verdict);\n } else if (verdict.kind === 'would-fire') {\n // The action already won on an earlier binding; this one never runs.\n verdict = { kind: 'shadowed' };\n }\n\n out.push({\n actionId,\n action,\n binding: match.binding,\n scope: match.scope,\n ownerId: match.ownerId,\n specificity: specificity(match.binding.spec),\n verdict,\n });\n }\n return out;\n }\n\n function resolveOnly(event: InputEvent, ctx: DispatcherContext): ResolveOnlyResult | null {\n const r = rank(event, ctx, false);\n const { winner } = walk(r, event, ctx, null, false);\n if (!winner) return null;\n return {\n actionId: winner.action.id,\n action: winner.action,\n scope: winner.match.scope,\n ownerId: winner.match.ownerId,\n };\n }\n\n function explain(event: InputEvent, ctx: DispatcherContext, explainOpts?: ResolveAllOptions): DispatchRecord {\n const r = rank(event, ctx, true);\n const walked = walk(r, event, ctx, null, explainOpts?.evaluateShadowed ?? false);\n return buildRecord(r, walked, event, ctx, true, walked.winner ? 'handled' : 'unhandled');\n }\n\n // -------------------------------------------------------------------------\n // cancelAll\n // -------------------------------------------------------------------------\n\n function cancelAll(reason: 'commit' | 'cancel'): void {\n const stubCtx: InvocationCtx = {\n world: { x: 0, y: 0 },\n modifiers: { alt: false, ctrl: false, meta: false, shift: false },\n deps: {},\n };\n for (const handle of inFlightHandles.values()) {\n handle.onEnd?.(stubCtx, reason);\n }\n inFlightHandles.clear();\n inFlightOwners.clear();\n inFlightActions.clear();\n uiOngoingByAction.clear();\n dragOrigins.clear();\n dragPoints.clear();\n pinchStartSpreads.clear();\n }\n\n // -------------------------------------------------------------------------\n // inFlight\n // -------------------------------------------------------------------------\n\n function inFlight(): ReadonlyMap<string, OngoingHandle> {\n return inFlightHandles;\n }\n\n function inFlightCursor(): string | null {\n // Latest start wins, matching `getActiveAction` — with a mouse and a pen\n // in flight together the cursor belongs to the gesture the user just\n // began, not the one they began first. Map iteration is insertion order\n // and each gestureId is set exactly once, so the last entry is the newest.\n let cursor: string | null = null;\n for (const action of inFlightActions.values()) {\n const c = resolveCursor(action.activeCursor ?? action.cursor);\n if (c) cursor = c;\n }\n return cursor;\n }\n\n function getInFlightHandles(): Iterable<OngoingHandle> {\n return inFlightHandles.values();\n }\n\n function subscribe(fn: () => void): () => void {\n subscribers.add(fn);\n return () => { subscribers.delete(fn); };\n }\n\n function getVersion(): number {\n return version;\n }\n\n function getActiveAction(): { kind: string | null; id: string | null } {\n // The most-recently-started in-flight handle wins. `Map` preserves\n // insertion order; each gestureId is set exactly once (any pump\n // events `set` only on the initial `start`, and `delete` on end),\n // so iterating to the last entry gives us the latest start.\n let lastId: string | null = null;\n let lastHandle: OngoingHandle | null = null;\n for (const [id, handle] of inFlightHandles) {\n lastId = id;\n lastHandle = handle;\n }\n if (lastHandle === null) return { kind: null, id: null };\n return { kind: lastHandle.kind ?? null, id: lastId };\n }\n\n // Wrap handleInput + cancelAll to notify after every invocation. Done at\n // the boundary (not inside the match loop) so any mutation — start, pump,\n // end, no-op — fires exactly one notify per pump tick.\n const handleInputWithNotify: typeof handleInput = (event, ctx) => {\n const out = handleInput(event, ctx);\n notify();\n return out;\n };\n const cancelAllWithNotify: typeof cancelAll = (reason) => {\n cancelAll(reason);\n notify();\n };\n\n function beginUiOngoing(\n actionId: string,\n deps: ActionDeps,\n params?: Record<string, unknown>,\n ): UiOngoingControl | null {\n const getAction = opts?.getAction;\n if (!getAction) {\n console.warn('weasel dispatcher: beginUiOngoing called but no getAction was provided to createDispatcher');\n return null;\n }\n const action = getAction(actionId);\n if (!action || !action.invoker || action.invoker.timing !== 'ongoing') {\n return null;\n }\n\n // Auto-commit any prior UI-driven handle for the same action.\n const prevGestureId = uiOngoingByAction.get(actionId);\n if (prevGestureId !== undefined) {\n const prevHandle = inFlightHandles.get(prevGestureId);\n if (prevHandle?.onEnd) {\n try { prevHandle.onEnd(buildUiInvocationCtx(deps), 'commit'); }\n catch (e) { console.error(`weasel dispatcher: prior UI handle for \"${actionId}\" threw on auto-commit`, e); }\n }\n inFlightHandles.delete(prevGestureId);\n inFlightOwners.delete(prevGestureId);\n uiOngoingByAction.delete(actionId);\n }\n\n const gestureId = `ui-${actionId}-${++uiOngoingSeq}`;\n let handle: OngoingHandle;\n try {\n // Pass params via BOTH ctx.params (the UI-driven channel) AND BindingOpts.params\n // (the gesture-driven channel). Color/opacity actions read ctx.params; future\n // ongoing actions migrated to UI-driven invocation can rely on either.\n handle = action.invoker.start(buildUiInvocationCtx(deps, params), { params });\n } catch (e) {\n console.error(`weasel dispatcher: action \"${actionId}\" threw on start`, e);\n return null;\n }\n // Treat empty handles ({} with no onMove or onEnd) as \"did not engage\".\n if (isEmptyOngoingHandle(handle)) {\n return null;\n }\n\n inFlightHandles.set(gestureId, handle);\n inFlightOwners.set(gestureId, null);\n uiOngoingByAction.set(actionId, gestureId);\n notify();\n\n let ended = false;\n // The dispatcher can end this handle without the control knowing —\n // `cancelAll` on tool switch, Escape, or unmount. Absence from\n // `inFlightHandles` is that signal; without it a later `end()` would\n // run `onEnd` a second time and commit over an already-cancelled gesture.\n const live = (): boolean => !ended && inFlightHandles.get(gestureId) === handle;\n return {\n gestureId,\n update(nextParams) {\n if (!live()) return;\n if (!handle.onMove) return;\n try { handle.onMove(buildUiInvocationCtx(deps, nextParams)); }\n catch (e) { console.error(`weasel dispatcher: action \"${actionId}\" threw on onMove`, e); }\n notify();\n },\n end(reason) {\n if (!live()) { ended = true; return; }\n ended = true;\n if (handle.onEnd) {\n try { handle.onEnd(buildUiInvocationCtx(deps), reason); }\n catch (e) { console.error(`weasel dispatcher: action \"${actionId}\" threw on onEnd`, e); }\n }\n inFlightHandles.delete(gestureId);\n inFlightOwners.delete(gestureId);\n inFlightActions.delete(gestureId);\n if (uiOngoingByAction.get(actionId) === gestureId) {\n uiOngoingByAction.delete(actionId);\n }\n notify();\n },\n };\n }\n\n return {\n handleInput: handleInputWithNotify,\n resolveOnly,\n resolveAll,\n explain,\n cancelAll: cancelAllWithNotify,\n inFlight,\n inFlightCursor,\n getInFlightHandles,\n subscribe,\n getVersion,\n getActiveAction,\n beginUiOngoing,\n };\n}\n","/**\n * The long-press the gesture dispatcher is timing, as observable state: where\n * the press landed, when the hold started, how far through it is, and whether\n * any binding would fire on it. Feedback — a filling ring, a haptic — reads\n * this; nothing here decides what the feedback looks like.\n */\n\n/** A press being held toward a long-press. */\nexport interface PendingLongPress {\n pointerId: number;\n /** Long-press is synthesized for these two only; a mouse never arms one. */\n pointerType: 'touch' | 'pen';\n /** Where the press landed, in client coordinates. */\n client: { x: number; y: number };\n /** The same point in CSS pixels from the canvas element's top-left — what a\n * `space: 'screen'` layer draws in. */\n local: { x: number; y: number };\n /** The same point in the routed view's world coordinates. */\n world: { x: number; y: number };\n /** The view the press routed to; `null` is the root view. */\n viewId: string | null;\n /** `performance.now()` when the hold started. */\n startedAt: number;\n /** How long the hold must last before the long-press fires, in ms. */\n duration: number;\n /**\n * Whether holding to the end would fire anything — a `longPress` binding,\n * or a `contextMenu` binding through the fallback. Resolved at press time.\n * Feedback shows only when this is true: a press that will do nothing must\n * not promise that it will.\n */\n armed: boolean;\n}\n\n/** Read side of the pending long-press. Published as the `longPress` dep. */\nexport interface LongPressState {\n /** The press being held, or `null` when none is. Cleared when the\n * long-press fires, and when movement, release, cancel or a second\n * pointer abandons it. */\n get(): PendingLongPress | null;\n /** How far through the hold the pending press is, 0→1, at `now`\n * (`performance.now()` by default). 0 when nothing is pending. */\n progress(now?: number): number;\n /** Called whenever {@link get} changes. Progress is derived from the\n * clock, so it does not notify — a loop drawing it asks for frames. */\n subscribe(fn: () => void): () => void;\n}\n\n/** The dispatcher's writable half of {@link LongPressState}. */\nexport interface LongPressStore extends LongPressState {\n set(next: PendingLongPress | null): void;\n}\n\n/** How long a touch or pen press is held before it fires `longPress`, in ms. */\nexport const LONG_PRESS_MS = 500;\n\n/** How `useGestureDispatcher` times, publishes and signals a long-press. */\nexport interface LongPressOptions {\n /** Hold time in ms. Default {@link LONG_PRESS_MS}. */\n duration?: number;\n /**\n * Where the press being held is published: position, start time, progress,\n * and whether any binding would fire on it. `<SceneCanvas>` passes one and\n * republishes it as the `longPress` dep, which its default press ring\n * reads. Omit it and nothing is published.\n */\n state?: LongPressStore;\n /**\n * Default true. A long-press some binding handled pulses `navigator.vibrate`\n * briefly, for touch and pen pointers, where the API exists.\n */\n haptics?: boolean;\n}\n\nconst nowMs = (): number =>\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n\nexport function createLongPressStore(): LongPressStore {\n let current: PendingLongPress | null = null;\n const listeners = new Set<() => void>();\n return {\n get: () => current,\n progress: (now = nowMs()) => {\n if (!current) return 0;\n if (!(current.duration > 0)) return 1;\n const t = (now - current.startedAt) / current.duration;\n return t <= 0 ? 0 : t >= 1 ? 1 : t;\n },\n subscribe: (fn) => {\n listeners.add(fn);\n return () => { listeners.delete(fn); };\n },\n set: (next) => {\n if (next === current) return;\n current = next;\n for (const fn of [...listeners]) fn();\n },\n };\n}\n","/**\n * The DOM half of a drag: one pointer, held down, from press to release.\n *\n * Every pointerdown-to-pointerup lifecycle in the kit used to answer capture,\n * pointer identity, teardown and lost-pointer recovery for itself, and each\n * answered them differently. This is the one place those are decided; anything\n * above it — thresholds, coordinate spaces, what the drag *means* — belongs to\n * its caller.\n */\n\n/** The DOM event that says capture went away mid-gesture. */\nconst LOST_CAPTURE_EVENT = 'lostpointercapture';\n\n/**\n * Does the press report button state at all?\n *\n * Synthesized events routinely carry `buttons: 0`, or nothing. Reading a\n * missed release out of those would end every such drag on its first move, so\n * a press that reports no buttons disarms {@link isMissedRelease} entirely.\n */\nfunction reportsButtons(down: { buttons?: number }): boolean {\n return !!down.buttons;\n}\n\n/**\n * A move with nothing held is the release the document never saw — the pointer\n * came up over another window, a native drag, or an element that swallowed it.\n * Only ask this when {@link reportsButtons} was true for the press.\n */\nfunction isMissedRelease(move: { buttons?: number }): boolean {\n return move.buttons === 0;\n}\n\n/** Why a session ended without the pointer being released. */\nexport type PointerSessionCancelReason =\n /** The browser cancelled the pointer (touch interrupted, palm rejection). */\n | 'pointercancel'\n /** The origin left the document mid-gesture, taking capture with it. */\n | 'lostcapture'\n /** `cancel()` — an unmount, a window blur, Escape, a consumer's own rule. */\n | 'aborted'\n /** A new press arrived on this pointer, so the tracked one had ended. */\n | 'superseded';\n\n/** What {@link openPointerSession} reports. Exactly one of `onEnd` / `onCancel` fires when the session ends. */\nexport interface PointerSessionCallbacks {\n /** Every move belonging to this pointer, while it is still held. */\n onMove?: (e: PointerEvent) => void;\n /** The pointer was released. Fires once, before teardown completes. */\n onEnd?: (e: PointerEvent) => void;\n /** The session ended without a release. Fires once. */\n onCancel?: (reason: PointerSessionCancelReason) => void;\n}\n\n/** Options for {@link openPointerSession}. */\nexport interface PointerSessionOptions {\n /** Ask the origin element to capture the pointer. Default `true`. Capture\n * keeps hover and click off everything the drag passes over; the session\n * does not depend on it to keep receiving events. */\n capture?: boolean;\n}\n\n/** A live drag opened by {@link openPointerSession}. */\nexport interface PointerSession {\n /** The pointer this session follows, taken from the press. */\n readonly pointerId: number;\n /** False once the session has ended, by any route. */\n readonly active: boolean;\n /** End the session now, reporting `'aborted'`. Idempotent. */\n cancel: () => void;\n}\n\n/**\n * Open a session for the pointer that `down` belongs to.\n *\n * Listens on the origin's document rather than on the element: a captured\n * element that is removed mid-drag stops receiving events, and every listener\n * hung on it goes with it. Three recovery rules close the gaps a plain\n * pointerup/pointercancel pair leaves — losing capture cancels only once the\n * origin has left the document, a move reporting no held button is read as\n * the release that never arrived, and a fresh press on the same pointer says\n * the tracked one had already ended.\n */\nexport function openPointerSession(\n origin: Element,\n down: PointerEvent | React.PointerEvent,\n cb: PointerSessionCallbacks,\n opts: PointerSessionOptions = {},\n): PointerSession {\n const pointerId = down.pointerId;\n const doc = origin.ownerDocument ?? document;\n const buttonsReported = reportsButtons(down);\n let active = true;\n\n const teardown = () => {\n active = false;\n doc.removeEventListener('pointermove', onMove, true);\n doc.removeEventListener('pointerup', onUp, true);\n doc.removeEventListener('pointercancel', onPointerCancel, true);\n doc.removeEventListener('pointerdown', onRepress, true);\n origin.removeEventListener(LOST_CAPTURE_EVENT, onLostCapture);\n if (opts.capture !== false) {\n try { origin.releasePointerCapture?.(pointerId); } catch { /* already gone */ }\n }\n };\n\n const mine = (e: PointerEvent) => e.pointerId === pointerId;\n\n const end = (e: PointerEvent) => {\n if (!active) return;\n teardown();\n cb.onEnd?.(e);\n };\n\n const abort = (reason: PointerSessionCancelReason) => {\n if (!active) return;\n teardown();\n cb.onCancel?.(reason);\n };\n\n function onMove(e: PointerEvent) {\n if (!active || !mine(e)) return;\n if (buttonsReported && isMissedRelease(e)) { end(e); return; }\n cb.onMove?.(e);\n }\n function onUp(e: PointerEvent) {\n if (mine(e)) end(e);\n }\n function onPointerCancel(e: PointerEvent) {\n if (mine(e)) abort('pointercancel');\n }\n // A press on a pointer we still believe is held: the release landed\n // somewhere that never told us, and where it ended is unknown — so this\n // cancels rather than ending at the new press's coordinates.\n function onRepress(e: PointerEvent) {\n if (mine(e)) abort('superseded');\n }\n // Losing capture only ends the gesture when the origin is gone, because\n // then nothing more is coming. While it is still in the document the\n // session keeps tracking: it listens there, not on the origin, so it needs\n // capture for retargeting and not for delivery. Chrome releases capture\n // implicitly a beat *before* it delivers `pointerup`, so cancelling here\n // unconditionally threw away releases that had already been dispatched.\n function onLostCapture(e: Event) {\n if ((e as PointerEvent).pointerId !== pointerId) return;\n if (!origin.isConnected) abort('lostcapture');\n }\n\n if (opts.capture !== false) {\n // Best-effort: a detached element throws, and jsdom's implementation\n // records the call and does nothing. Neither is a reason to fail the drag.\n try { origin.setPointerCapture?.(pointerId); } catch { /* uncaptured is fine */ }\n }\n // Capture phase, so a consumer's own stopPropagation cannot strand a session.\n doc.addEventListener('pointermove', onMove, true);\n doc.addEventListener('pointerup', onUp, true);\n doc.addEventListener('pointercancel', onPointerCancel, true);\n doc.addEventListener('pointerdown', onRepress, true);\n origin.addEventListener(LOST_CAPTURE_EVENT, onLostCapture);\n\n return {\n pointerId,\n get active() { return active; },\n cancel: () => abort('aborted'),\n };\n}\n","// src/tools/types.ts\nimport type { Op } from '@weasel-js/history';\nimport type { SelectionApi, View, Bounds, DebugSink, ModifierState } from '../vocabulary';\nimport type { Contribution } from '../contributions/types';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { KernelOverlay } from '../index';\n\n/**\n * Configurable activation-key descriptor for tools that expose their\n * keybinding to the host (currently Lasso and Eyedropper). Captures\n * only the fields meaningful to a caller-supplied tool-select key —\n * dispatcher-internal fields (`skipInEditable`, `enabled`,\n * `preventDefault`) live on `KeyBinding` in keyHelpers.ts and are\n * not part of the configurable surface.\n */\nexport interface ToolKeybinding {\n /** Key or list of keys to match (case-insensitive against `event.key`). */\n key: string | readonly string[];\n /** Require Cmd (mac) / Ctrl (others). Default `false`. */\n mod?: boolean;\n /** Require Alt. Default `false`. */\n alt?: boolean;\n /**\n * Shift policy. `undefined`/`false` forbids shift, `true` requires\n * shift, `'optional'` allows either.\n */\n shift?: boolean | 'optional';\n}\n\n/** Modifier-key snapshot at event dispatch time. */\nexport type ToolModifiers = ModifierState;\n\n/** Per-event context passed to every channel handler. `scratch` is typed\n * via the tool's `TScratch` parameter; it survives across a single\n * gesture (pointer-down through end/cancel) and is replaced on next\n * gesture start by `initScratch()`. */\nexport interface ToolCtx<TScratch = unknown> {\n worldX: number;\n worldY: number;\n modifiers: ToolModifiers;\n selection: SelectionApi;\n /** Adapter/scene access — opaque at this layer; tools that need it\n * cast to a known shape. This layer doesn't constrain it. */\n adapter: unknown;\n applyOps: (ops: Op[], label: string) => void;\n /** Current viewport. Reflects camera-position semantics — see\n * `View` JSDoc. */\n view: View;\n /** Mutate the viewport. In controlled mode this calls the consumer's\n * `onViewChange`; in uncontrolled mode it updates Canvas's internal\n * state. View changes are not undoable. */\n setView: (next: View) => void;\n /** Bounding rect of the canvas element in viewport coords. Used by\n * zoom/pan tools to convert event clientX/clientY to canvas-relative\n * anchors. */\n canvasRect: DOMRect;\n /** Optional debug sink. When `<Canvas debug={...}>` is enabled, Canvas\n * threads its sink here so tool-internal hit math (handle hitboxes,\n * rotation handle, etc.) lands in the same overlay as Canvas's own\n * bounds/origin records. Tools should call this conditionally with `?.`. */\n debug?: DebugSink;\n scratch: TScratch;\n}\n\n/**\n * What `onActivate` / `onDeactivate` receive: the tool's scratch, from\n * `initScratch()`. A lifecycle moment has no pointer, hit or modifier state to\n * report, so nothing else is populated; a callback needing the selection or\n * the scene closes over it, as the tool's actions do.\n */\nexport interface ToolLifecycleCtx<TScratch = unknown> {\n scratch: TScratch;\n}\n\n/** World-space AABB shape used by `previewBounds`. Alias of the kit-wide\n * `Bounds` type — the optional `rotation` field carries through so a tool\n * can report an oriented preview rect (e.g. mid-rotate). */\nexport type ToolBounds = Bounds;\n\n/**\n * The focus-declaring case of a `Contribution`: a mode the user switches\n * into, plus the hooks that only make sense for one (`initScratch`,\n * activate/deactivate, live preview, `cursor`). Everything else — bindings,\n * actions, overlay, presentation — is inherited.\n */\nexport interface Tool<TScratch = unknown, TOverlay = KernelOverlay> extends Contribution<TOverlay> {\n /** Optional caller-supplied key. Most built-in tools have their activation\n * key declared in `BUILTIN_SELECT_KEYS` in `useKeybindings.ts`; this field\n * is for tools that want their activation key to be configurable by the\n * host (currently Lasso and Eyedropper). The dynamic loop in\n * `useKeybindings.ts` picks this up and appends a binding entry to the\n * consolidated `tool.activate` action (with `opts.params.toolId` set so\n * the invoker knows which tool to switch to). */\n keybinding?: ToolKeybinding;\n initScratch?: () => TScratch;\n cursor?: CursorSpec | ((ctx: ToolCtx<TScratch>) => CursorSpec);\n /** The tool became live: it took the active slot, or its `hotkey` went\n * down, while it held neither. */\n onActivate?: (ctx: ToolLifecycleCtx<TScratch>) => void;\n /** The tool stopped being live in both slots, or its canvas unmounted. */\n onDeactivate?: (ctx: ToolLifecycleCtx<TScratch>) => void;\n /** Returns the in-flight preview pose for `id` if this tool is mid-gesture\n * on it; otherwise `null`. Lets `Canvas.helpersRef.getEffectivePose`\n * reflect live gesture state without reaching into hook internals. The\n * return type is `unknown` here because the Tool interface is pose-agnostic;\n * callers that know the pose shape (e.g. Canvas typed by `TPose`) cast at\n * the use site. */\n previewPose?: (id: string) => unknown;\n /** Returns the in-flight preview bounds for `id` if this tool is mid-gesture\n * on it; otherwise `null`. Optional companion to `previewPose` for tools that\n * can compute bounds without round-tripping through a geometry adapter. */\n previewBounds?: (id: string) => ToolBounds | null;\n /** Returns ids whose committed scene-render should be suppressed while this\n * tool is mid-gesture (e.g. cascade move's dragged + descendant ids whose\n * preview ghosts replace the committed pose). The standard scene slot\n * consults this alongside `previewPose` to avoid double-rendering. Returns\n * `null` when no gesture is in flight. */\n previewIds?: () => Iterable<string> | null;\n}\n\n/** Whether `entry` is a tool: a contribution that can hold focus, chosen from\n * a palette or held on a key. Only a tool's focus hooks (`initScratch`,\n * `cursor`, `onActivate`, the previews) ever run. */\nexport function isTool<TOverlay>(entry: Contribution<TOverlay>): entry is Tool<unknown, TOverlay> {\n return !!(entry.eligibility?.focus || entry.eligibility?.offhand);\n}\n\n/** Internal — which slot a tool occupies in the dispatch order. */\nexport type ToolSlot = 'hotkey' | 'active' | 'ambient';\n\n/** Internal alias for \"a Tool of any scratch type\" — used in registries and\n * dispatchers that hold tools of heterogeneous scratch shapes. `any` is\n * intentional: `Tool<TScratch>` is invariant in TScratch, so `Tool<unknown>`\n * is too strict for containers that accept any concrete `Tool<T>`. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyTool = Tool<any, any>;\n\n/** \"A tool of any scratch type that draws `TOverlay`\" — the container form for\n * registries that hold heterogeneous scratch shapes but one overlay type. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyToolOf<TOverlay> = Tool<any, TOverlay>;\n","import type { Contribution } from '../../../contributions/types';\nimport type { Action } from '../../../interactions/actions/action';\nimport { actionBindings } from '../../../interactions/actions/binding';\nimport type { ParsedModifiers } from '../routeGrammar';\nimport { canonicalModifiers, formatRoute } from '../routeGrammar';\nimport { activeModeOf, DEFAULT_MODES, type ActiveMode } from '@weasel-js/modes';\nimport { ALWAYS, ruleCanHoldIn, rulesExclusive, type Rule } from '../../../eligibility';\nimport { buildRouteRegistry, PREDICATE_TARGET, type RegistryEntry, type GestureName } from './registry';\n\n/** Two or more tools declare the same exact (phase, gesture, arg, target,\n * modifiers) tuple — the dispatcher's slot precedence picks one\n * arbitrarily (well, deterministically by slot order, but the author\n * probably didn't intend the duplication). */\nexport interface Conflict {\n phase: 'initial' | 'engaged' | 'any';\n gesture: GestureName;\n arg: string | undefined;\n target: string | undefined;\n modifiers: ParsedModifiers;\n /** The ids of every entry that declared the same tuple. At least 2 by\n * construction, in input order. */\n ownerIds: string[];\n}\n\n/** Detect exact-tuple overlaps across a tool registration set.\n *\n * Intentionally NOT flagged:\n * - Broad vs. narrow targets (e.g. an untargeted `click` alongside\n * `click` on `empty`) — the dispatcher's specificity ordering resolves\n * those cleanly, and the broad one is usually the intended fallback.\n * - Different modifier requirements on the same target — they fire on\n * different inputs.\n * - A binding whose action declines via `enabled()` so a lower-priority\n * one can take the gesture. Detecting that intent would mean evaluating\n * the action; consumers can suppress known-intentional compositions in\n * their UI layer.\n *\n * - Two `{ kindOf }` predicate targets. The route grammar renders every\n * predicate as the single token {@link PREDICATE_TARGET}, so bucketing on\n * the rendered target alone reported select's `resize` / `rotate` / `move`\n * drags — three genuinely different predicates — as a three-way conflict.\n * Predicate entries bucket by function identity instead, which means two\n * *separately written but equivalent* predicates go unflagged. That's the\n * right way to be wrong here: this check has to be silent when nothing is\n * wrong or nobody will keep it on.\n *\n * - Two actions whose `eligible` rules can never hold together — each\n * mode's own Escape exit, say. See {@link rulesExclusive}.\n *\n * - Two bindings whose `opts.views` keep them from being live and equally\n * ranked in any one view. See {@link viewsTie}.\n *\n * Note that two bindings sharing a tuple on the SAME tool are now possible\n * (bindings are an array, where phase tables were objects with unique\n * keys) — so a conflict may name one tool twice.\n *\n * This is the raw same-tuple detector. Feeding it a whole tool *registry*\n * over-reports, because registry tools take turns in the active slot and\n * can't collide with each other — see {@link findScopedConflicts}.\n */\nexport function findConflicts(entries: readonly Contribution<unknown>[]): Conflict[] {\n return findConflictsKeyed(entries).map((k) => k.conflict);\n}\n\n/**\n * The same detector, keeping each conflict's bucket key.\n *\n * `Conflict.target` renders every predicate as the flat grammar token\n * `'predicate'`, while the buckets key on the predicate's *identity* — so two\n * genuinely distinct predicate collisions are indistinguishable once rendered.\n * `findScopedConflicts` dedupes across several passes and needs the key that\n * told them apart in the first place.\n */\nfunction findConflictsKeyed(\n entries: readonly Contribution<unknown>[],\n rules?: ReadonlyMap<string, Rule>,\n modes: readonly ActiveMode[] = KIT_MODES,\n): { key: string; conflict: Conflict }[] {\n const rows = buildRouteRegistry(entries);\n const groups = new Map<string, RegistryEntry[]>();\n for (const entry of rows) {\n // One bucket per arg the binding answers to, not one per display token.\n // `key: ['h','H']` and `key: 'H'` really do collide — `matchKey` takes any\n // member, case-insensitively — and joining the alternatives into `'h|H'`\n // put them in different buckets. Same for two `drop` specs whose MIME sets\n // overlap without being equal.\n for (const arg of argKeysOf(entry)) {\n const key = `${entry.phase}|${entry.gesture}|${arg}|${targetKey(entry)}|${canonicalModifiers(entry.modifiers)}`;\n const bucket = groups.get(key);\n if (bucket) { if (!bucket.includes(entry)) bucket.push(entry); }\n else groups.set(key, [entry]);\n }\n }\n // Only actions carry a rule, so a tool's or contribution's bindings count as eligible always.\n const ruleOf = (entry: RegistryEntry): Rule => rules?.get(entry.ownerId) ?? ALWAYS;\n const tie = (e: RegistryEntry, f: RegistryEntry): boolean =>\n viewsTie(e.views, f.views) && rulesCanHoldTogether(ruleOf(e), ruleOf(f), modes);\n const conflicts: { key: string; conflict: Conflict }[] = [];\n for (const [key, all] of groups) {\n // Keep only members that could tie with another member.\n const bucket = all.filter((e) => all.some((f) => f !== e && tie(e, f)));\n if (bucket.length < 2) continue;\n const first = bucket[0];\n conflicts.push({\n key,\n conflict: {\n phase: first.phase,\n gesture: first.gesture,\n arg: first.arg,\n target: first.target,\n modifiers: first.modifiers,\n ownerIds: bucket.map((e) => e.ownerId),\n },\n });\n }\n return conflicts;\n}\n\n/** Whether two bindings' `views` let them tie in some view. A binding is live\n * only in the views it names, and there it outranks one that names none\n * (`preferViewScoped`), so a scoped and an unscoped binding never tie; two\n * scoped ones tie where their views overlap. */\nfunction viewsTie(\n a: readonly (string | null)[] | undefined,\n b: readonly (string | null)[] | undefined,\n): boolean {\n if (a === undefined || b === undefined) return a === b;\n return a.some((v) => b.includes(v));\n}\n\n/** Every arg value an entry buckets under, lowercased — `matchKey` is\n * case-insensitive, so `'h'` and `'H'` are one arg. */\nfunction argKeysOf(entry: RegistryEntry): readonly string[] {\n const alts = entry.argAlternatives;\n if (alts && alts.length > 0) return [...new Set(alts.map((a) => a.toLowerCase()))];\n return [(entry.arg ?? '').toLowerCase()];\n}\n\n/** Bucket key for an entry's target slot. Predicate targets all render as\n * the same grammar token, so they're keyed by the predicate's identity —\n * two different functions are two different targets. */\nfunction targetKey(entry: RegistryEntry): string {\n if (entry.target !== PREDICATE_TARGET) return entry.target ?? '';\n const spec = entry.spec as { target?: unknown };\n const pred = spec.target;\n if (typeof pred !== 'object' || pred === null) return PREDICATE_TARGET;\n return `${PREDICATE_TARGET}#${predicateId(pred)}`;\n}\n\nconst PREDICATE_IDS = new WeakMap<object, number>();\nlet nextPredicateId = 0;\n\nfunction predicateId(pred: object): number {\n let id = PREDICATE_IDS.get(pred);\n if (id === undefined) {\n id = nextPredicateId++;\n PREDICATE_IDS.set(pred, id);\n }\n return id;\n}\n\n/**\n * The tool scopes as the dispatcher sees them — which is what decides whether\n * two same-tuple bindings can actually collide.\n */\nexport interface ToolScopes {\n /** Tools eligible for the active slot, keyed by id or as a flat list. */\n registry: readonly Contribution<unknown>[] | Readonly<Record<string, Contribution<unknown>>>;\n /** Always-on entries. Every one of these is live at once. */\n ambient?: readonly Contribution<unknown>[];\n /** Registered actions. Their `defaultBinding`s assemble at ambient scope\n * (hotkey scope when `Action.scope` says so), alongside the tools above. */\n actions?: readonly Action[];\n /** Every mode the canvas can be in (`activeModeOf` builds one from a\n * definition). Two gated actions conflict only when some mode lets both\n * rules hold. Default: the kit's `DEFAULT_MODES`. */\n modes?: readonly ActiveMode[];\n}\n\n/** An action's `defaultBinding`s in the shape the route registry reads, so a\n * tool-vs-action collision buckets with the tool-vs-tool ones. */\n/** Whether two rules can hold at once: never when {@link rulesExclusive}\n * proves it, and given the modes, only when one of them lets both hold. */\nfunction rulesCanHoldTogether(a: Rule, b: Rule, modes: readonly ActiveMode[]): boolean {\n if (rulesExclusive(a, b)) return false;\n return modes.some((m) => ruleCanHoldIn(a, m) && ruleCanHoldIn(b, m));\n}\n\nconst KIT_MODES: readonly ActiveMode[] = DEFAULT_MODES.map(activeModeOf);\n\nfunction actionAsEntry(action: Action): Contribution<unknown> {\n return { id: action.id, eligibility: {}, bindings: actionBindings(action) };\n}\n\nfunction eligibleRule(action: Action): Rule | undefined {\n const eligible = action.eligible;\n if (eligible === undefined) return undefined;\n return typeof eligible === 'function' ? eligible.rule : eligible;\n}\n\n/**\n * Detect the same-tuple overlaps that are *reachable* — the ones where the\n * dispatcher really does fall back on declaration order.\n *\n * `matchSorted` walks scopes in strict priority (hotkey > active > ambient)\n * and only sorts by specificity *within* a scope. So a cross-scope tie isn't\n * a tie at all: an ambient tool losing a tuple to the active tool is the\n * documented design, not an accident. Likewise two registry tools sharing a\n * tuple — `rect` and `ellipse` both binding a bare `drag` — can never both be\n * in the active slot, so they never compete.\n *\n * What's left, and what this reports:\n * - a single tool colliding with **itself** (possible since bindings became\n * an array), which is ambiguous in whichever slot it occupies;\n * - two **ambient** tools, all of which are live simultaneously and are\n * ordered only by registration;\n * - two **hotkey-capable** tools, which can stack.\n *\n * Registered actions join the same two buckets: their `defaultBinding`s\n * assemble at ambient scope (hotkey scope when `Action.scope` says so), so an\n * ambient tool and an action claiming one tuple really do fall back on\n * declaration order. An ambient action gated by an `eligible` rule is the\n * exception: when its rule holds it outranks every ungated binding\n * (`preferContextual`), so it is compared only with other gated actions.\n *\n * Within any of these groups, two actions whose `eligible` rules can never\n * hold together don't collide — each mode's own hotkey-scope Escape exit, say.\n * `rulesExclusive` proves some of those from the rules alone; the rest are the\n * pairs no mode in `scopes.modes` lets hold at once.\n */\nexport function findScopedConflicts(scopes: ToolScopes): Conflict[] {\n const registry = Array.isArray(scopes.registry)\n ? (scopes.registry as readonly Contribution<unknown>[])\n : Object.values(scopes.registry as Readonly<Record<string, Contribution<unknown>>>);\n const actions = scopes.actions ?? [];\n const rules = new Map<string, Rule>();\n for (const a of actions) {\n const rule = eligibleRule(a);\n if (rule) rules.set(a.id, rule);\n }\n const hotkeyActions = actions.filter((a) => a.scope === 'hotkey').map(actionAsEntry);\n const gatedActions: Contribution<unknown>[] = [];\n const ungated: Contribution<unknown>[] = [];\n for (const a of actions) {\n if (a.scope === 'hotkey') continue;\n (a.eligible !== undefined ? gatedActions : ungated).push(actionAsEntry(a));\n }\n const modes = scopes.modes ?? KIT_MODES;\n const ambient = [...(scopes.ambient ?? []), ...ungated];\n\n const out: Conflict[] = [];\n const seen = new Set<string>();\n const add = (keyed: readonly { key: string; conflict: Conflict }[]): void => {\n for (const { key, conflict } of keyed) {\n const dedupeKey = `${key}|${conflict.ownerIds.join(',')}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n out.push(conflict);\n }\n };\n\n // Self-collisions: every entry, whichever slot it lands in — actions\n // included. Both group passes below are guarded on having more than one\n // member, so a lone action is checked by nothing else.\n for (const tool of [...registry, ...ambient, ...gatedActions, ...hotkeyActions]) {\n add(findConflictsKeyed([tool], rules, modes));\n }\n // Ambient tools and ungated ambient actions are all live together.\n if (ambient.length > 1) add(findConflictsKeyed(ambient, rules, modes));\n if (gatedActions.length > 1) add(findConflictsKeyed(gatedActions, rules, modes));\n // Hotkey-capable tools can stack on each other. `hotkey` is declared on the\n // authored `ToolDef`, not carried onto the runtime `Tool` — `Tool.def` is\n // the reflection handle for exactly this kind of read, and it's typed\n // `unknown` so consumers cast at the use site.\n const hotkey = [\n ...registry.filter((t) => (t.def as { hotkey?: unknown } | undefined)?.hotkey !== undefined),\n ...hotkeyActions,\n ];\n if (hotkey.length > 1) add(findConflictsKeyed(hotkey, rules, modes));\n\n return out;\n}\n\n/**\n * Render a conflict as one line of human-readable text.\n *\n * The tuple is printed through {@link formatRoute}, so the message names the\n * collision in the same grammar the author wrote the binding in — modulo the\n * phase slot, which the bucket key collapses: a single phase prints as a bare\n * `'&'`-channel atom (`sel:engaged` and `&:engaged` collide, and the collapse\n * is what made them collide), and `'any'` prints as `*:*`.\n */\nexport function formatConflict(conflict: Conflict): string {\n const route = formatRoute({\n phases: [conflict.phase === 'any'\n ? { channel: '*', phase: '*' }\n : { channel: '&', phase: conflict.phase }],\n gesture: conflict.gesture,\n arg: conflict.arg,\n target: conflict.target,\n modifiers: conflict.modifiers,\n });\n return `${route} — declared by ${conflict.ownerIds.join(', ')}`;\n}\n\n/**\n * Detect reachable route conflicts in an assembled tool set and report each one.\n *\n * This is the wiring `findConflicts` spent its first life without: the kit\n * could detect the one class of genuine routing ambiguity it has and never\n * looked. Call it once wherever a tool set is assembled (`useTools` does),\n * behind a `process.env.NODE_ENV !== 'production'` guard.\n *\n * **Warn, never throw.** A conflict between a consumer's tool and a kit tool\n * is a design question — sometimes deliberate, since the loser can still take\n * the gesture by declining through `enabled()` — and exploding in a running\n * app is the wrong way to raise it. A conflict between two *kit* tools is\n * always a bug, but the place to fail on that is the kit's own test suite\n * (`canvas/SceneCanvas.routeConflicts.test.tsx`), not a consumer's console.\n *\n * @returns The conflicts found, so callers can dedupe repeat reports.\n */\nexport function reportRouteConflicts(\n scopes: ToolScopes,\n warn: (message: string) => void = (m) => console.warn(m),\n): Conflict[] {\n const conflicts = findScopedConflicts(scopes);\n for (const c of conflicts) {\n warn(\n `[weasel] route conflict: two bindings declare the same (phase, gesture, arg, target, modifiers) tuple `\n + `in the same scope, so declaration order alone decides which one fires.\\n ${formatConflict(c)}`,\n );\n }\n return conflicts;\n}\n","/**\n * Pure keyboard-binding helpers shared between the tool dispatcher\n * (`useKeybindings`), the gesture dispatcher (`useGestureDispatcher`), and\n * individual Tool declarations.\n *\n * Extracted from the deleted singular `useKeybinding` hook so the remaining\n * consumers don't depend on its disappearance.\n */\n\n/**\n * A key plus a modifier policy, as {@link matchesKeyBinding} tests it against a\n * `KeyboardEvent`. Every modifier left unset is forbidden, so `{ key: 'a' }`\n * does not fire on Cmd+A. The matcher ignores `skipInEditable`, `enabled` and\n * `preventDefault`; those are for whatever attaches the listener. Tools\n * declaring an activation key use `ToolKeybinding` instead.\n */\nexport interface KeyBinding {\n /**\n * Key or list of keys to match. Compared case-insensitively against\n * `event.key`, so `'a'` matches both `'a'` and `'A'`.\n */\n key: string | readonly string[];\n /**\n * Require Cmd (mac) or Ctrl (others). When `true`, exactly one of\n * `metaKey`/`ctrlKey` must be held. Default `false` (both forbidden).\n */\n mod?: boolean;\n /** Require Alt. Default `false` (forbidden). */\n alt?: boolean;\n /**\n * Shift policy. `undefined`/`false` forbids shift, `true` requires\n * shift, `'optional'` allows either. Default `undefined`.\n */\n shift?: boolean | 'optional';\n /** Skip when focus is in an editable element. Default `true`. */\n skipInEditable?: boolean;\n /** When `false`, the listener is not attached. Default `true`. */\n enabled?: boolean;\n /** Call `preventDefault` before the handler. Default `true`. */\n preventDefault?: boolean;\n}\n\n/** Returns true when the target is an input, textarea, or contenteditable element. */\nexport function isEditableTarget(target: EventTarget | null): boolean {\n if (!target || !(target instanceof Element)) return false;\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA') return true;\n if ((target as HTMLElement).isContentEditable) return true;\n const ce = target.getAttribute('contenteditable');\n return ce === 'true' || ce === '';\n}\n\nfunction keyMatches(eventKey: string, spec: string | readonly string[]): boolean {\n const want = typeof spec === 'string' ? [spec] : spec;\n const ek = eventKey.toLowerCase();\n return want.some((k) => k.toLowerCase() === ek);\n}\n\n/**\n * Pure matcher for `KeyBinding` against a `KeyboardEvent`. Only checks key +\n * modifier policy — does NOT apply the editable-target skip or\n * `preventDefault`. Shared by the tool dispatcher (`useKeybindings`) and the\n * gesture dispatcher so the rules can't drift.\n */\nexport function matchesKeyBinding(e: KeyboardEvent, b: KeyBinding): boolean {\n if (!keyMatches(e.key, b.key)) return false;\n\n const wantsMod = b.mod === true;\n const hasMod = e.metaKey || e.ctrlKey;\n if (wantsMod !== hasMod) return false;\n\n const wantsAlt = b.alt === true;\n if (wantsAlt !== e.altKey) return false;\n\n const shift = b.shift;\n if (shift === undefined || shift === false) {\n if (e.shiftKey) return false;\n } else if (shift === true) {\n if (!e.shiftKey) return false;\n }\n return true;\n}\n","/**\n * IngestItem materialization — turns a live `DataTransfer` (drop) or\n * clipboard `DataTransfer` (paste) into fully-owned `IngestItem[]`.\n *\n * `DataTransfer` items are only readable while the originating DOM event is\n * on the stack, so BOTH functions must be called synchronously from the event\n * handler. `itemsFromDataTransfer` kicks off every `getAsString` read\n * immediately and resolves once all strings are collected;\n * `itemsFromClipboardData` is fully synchronous (`getData` + `files`).\n *\n * MIME strings are normalized to bare lowercase `type/subtype` (parameters\n * like `;charset=utf-8` stripped) — downstream exact matching (binding\n * `types`, content-handler `match`) assumes the bare form.\n *\n * Output shape: **files first (source order), then strings (item order)**.\n * For paste (`itemsFromClipboardData`) string flavors are emitted in\n * `INGEST_STRING_MIMES` order: text/plain, text/html, text/uri-list.\n */\nimport type { IngestItem } from '@weasel-js/gestures';\n\nexport type { IngestItem };\n\n/** The string flavors the kit normalizes. Everything else (browser-internal\n * custom flavors, etc.) is dropped at materialization. */\nexport const INGEST_STRING_MIMES: ReadonlySet<string> = new Set([\n 'text/plain',\n 'text/html',\n 'text/uri-list',\n]);\n\nconst FALLBACK_MIME = 'application/octet-stream';\n\n/** Normalize a raw MIME to bare lowercase `type/subtype`. */\nfunction normalizeMime(raw: string): string {\n const bare = raw.split(';')[0].trim().toLowerCase();\n return bare || FALLBACK_MIME;\n}\n\n/** Wrap raw `File`s (file picker, `CanvasExtensionApi.ingest`) as\n * `IngestItem`s, normalizing each MIME the same way the drop/paste paths\n * do. Synchronous — `File` objects are already fully owned. */\nexport function itemsFromFiles(files: File[]): IngestItem[] {\n return files.map((file) => ({ kind: 'file', mime: normalizeMime(file.type), file }));\n}\n\n/** Materialize a drop's `DataTransfer`. MUST be called during the `drop`\n * event dispatch (see module doc). */\nexport function itemsFromDataTransfer(dt: DataTransfer): Promise<IngestItem[]> {\n const files: IngestItem[] = [];\n const strings: IngestItem[] = [];\n const reads: Promise<void>[] = [];\n\n for (const item of Array.from(dt.items ?? [])) {\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (file) files.push({ kind: 'file', mime: normalizeMime(file.type), file });\n } else if (item.kind === 'string') {\n const mime = normalizeMime(item.type);\n if (INGEST_STRING_MIMES.has(mime)) {\n const slot = strings.length;\n strings.push(null as never);\n reads.push(\n new Promise((resolve) => {\n item.getAsString((text) => {\n strings[slot] = { kind: 'string', mime, text };\n resolve();\n });\n }),\n );\n }\n }\n }\n\n // Some sources populate `files` without `items` (older engines, jsdom).\n if (files.length === 0 && reads.length === 0) {\n for (const file of Array.from(dt.files ?? [])) {\n files.push({ kind: 'file', mime: normalizeMime(file.type), file });\n }\n }\n\n return Promise.all(reads).then(() => [...files, ...strings]);\n}\n\n/** Materialize a paste's `clipboardData`. Fully synchronous. */\nexport function itemsFromClipboardData(cd: DataTransfer): IngestItem[] {\n const out: IngestItem[] = [];\n for (const file of Array.from(cd.files ?? [])) {\n out.push({ kind: 'file', mime: normalizeMime(file.type), file });\n }\n for (const mime of INGEST_STRING_MIMES) {\n const text = cd.getData(mime);\n if (text) out.push({ kind: 'string', mime, text });\n }\n return out;\n}\n","/**\n * Convert client coords to element CSS-pixel coords (relative to the element's\n * top-left). Apps drawing in CSS-pixel space feed the result directly into\n * world math when pan/zoom is identity. With pan/zoom, compose this with\n * your inverse-viewport transform.\n */\nexport function clientToCanvas(\n canvas: HTMLElement,\n clientX: number,\n clientY: number,\n): [number, number] {\n const rect = canvas.getBoundingClientRect();\n return [clientX - rect.left, clientY - rect.top];\n}\n\n/**\n * Rect-taking variant of `clientToCanvas` for call sites that already hold a\n * `DOMRect` (or any `{ left, top }` object) and don't have a canvas element\n * in scope.\n */\nexport function clientToCanvasRect(\n rect: { left: number; top: number },\n clientX: number,\n clientY: number,\n): [number, number] {\n return [clientX - rect.left, clientY - rect.top];\n}\n","/**\n * Namespaced, opt-in console tracing for the kit.\n *\n * Enable in the browser:\n *\n * localStorage.setItem('weasel.debug', '*') // all namespaces\n * localStorage.setItem('weasel.debug', 'tools,dispatch') // specific ones\n * localStorage.setItem('weasel.debug', '1') // legacy \"all\"\n *\n * Each call site picks a stable namespace string. Off by default; the flag\n * is read once and cached per page session — reload to pick up a change.\n *\n * Mirrors `packages/ui/src/dlog.ts` and `@weasel-js/core`'s `debug/flag.ts`.\n * The impls live in separate packages because none of them depends on the\n * others, but all read the same localStorage keys so behavior is uniform from\n * a debugger's POV.\n *\n * Known kit namespaces:\n * - tools — active-tool + hotkey transitions (useTools)\n * - dispatch — gesture start / end / cancel (dispatcher)\n * - drag-rect — useDragRect lifecycle\n * - drag-radial — useDragRadial lifecycle\n * - scene — restored-op replay gaps (history persistence)\n * - scene-canvas — SceneCanvas mount / unmount; adapter paste-translation warnings\n * - history — applyOps push, no-op suppression, serialize/restore\n * - clipboard — OS clipboard write/read failures, malformed payloads\n */\n\nconst KEYS = ['weasel.debug', 'weaseldraw.debug'] as const;\n\ninterface Cached {\n all: boolean;\n set: Set<string>;\n}\n\nlet cached: Cached | null = null;\n\nfunction read(): Cached {\n const empty: Cached = { all: false, set: new Set() };\n if (typeof localStorage === 'undefined') return empty;\n try {\n for (const k of KEYS) {\n const v = localStorage.getItem(k);\n if (v == null || v === '') continue;\n if (v === '1' || v === 'true' || v === '*') return { all: true, set: new Set() };\n return { all: false, set: new Set(v.split(/[\\s,]+/).filter(Boolean)) };\n }\n return empty;\n } catch {\n return empty;\n }\n}\n\nfunction get(): Cached {\n if (cached === null) cached = read();\n return cached;\n}\n\n/** True when `namespace` (or `*`) is enabled. Pass no argument to test\n * whether *any* namespace is on (legacy global-flag semantics). */\nexport function isDebugEnabled(namespace?: string): boolean {\n const c = get();\n if (c.all) return true;\n if (namespace === undefined) return c.set.size > 0;\n return c.set.has(namespace);\n}\n\n/** Conditional `console.debug` — no-op unless `namespace` (or `*`) is enabled.\n * Each call is prefixed with `[namespace]` so the source is searchable. */\nexport function dlog(namespace: string, ...args: unknown[]): void {\n if (!isDebugEnabled(namespace)) return;\n // eslint-disable-next-line no-console\n console.debug(`[${namespace}]`, ...args);\n}\n\n/** Conditional `console.warn` — like `dlog` but at warn level. Use for\n * diagnostics that indicate something worth surfacing during debugging\n * (e.g. no-op op batches suppressed). */\nexport function dwarn(namespace: string, ...args: unknown[]): void {\n if (!isDebugEnabled(namespace)) return;\n console.warn(`[${namespace}]`, ...args);\n}\n"]}
|