@embedpdf/core-annotation 3.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/dist/index.cjs +5781 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1636 -0
- package/dist/index.d.ts +1636 -0
- package/dist/index.js +5680 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["NO_ANNOTATION_FLAGS","NO_ENDINGS","unionBoundsOf"],"sources":["../src/kinds.ts","../src/flags.ts","../src/group.ts","../src/cloudy.ts","../src/endings.ts","../src/geometry.ts","../src/anchor.ts","../src/hit.ts","../src/props.ts","../src/placement.ts","../src/snap.ts","../src/ink.ts","../src/update.ts","../src/scene.ts","../src/view.ts"],"sourcesContent":["/**\n * The annotation KIND table — the single declarative source for \"what an\n * annotation of this subtype IS and what you can do to it\". Pure DATA (no\n * closures), keyed by subtype, so it ports to Rust as a static table and replaces\n * the scattered `subtype`/`geom.t` switches and the old binary `EDITABLE_SUBTYPES`.\n *\n * Two layers meet here:\n * • `variant` — which {@link Geom} primitive the kind renders/hit-tests as.\n * Several subtypes share one (square+circle → `rect`, the markups → `quads`).\n * • `caps` — ORTHOGONAL capability flags. \"Editable\" was one boolean that\n * conflated selectable / movable / resizable / vertex-editable; splitting it\n * is what lets text-markup be *selectable but not movable*, a note icon be\n * *movable but not resizable*, and so on — without new code paths.\n *\n * Creation lives on TOOLS (a later layer), not here: many tools can target one\n * kind (ink vs ink-highlight, line vs arrow). A kind is the editing/identity\n * surface; a tool is the authoring surface.\n */\nimport type { Geom, Subtype } from './types';\n\n/**\n * One editable property of a kind, as a UI contract: which {@link AnnotationProps}\n * key, rendered how (the union arm fixes the control + its constraints), labelled\n * what by default. A property sidebar is a `switch (spec.key)` over these — the\n * per-kind lists below are the v2 snippet's hand-rolled `TOOL_PROPERTIES` schema,\n * promoted into the library so every consumer gets it for free.\n *\n * `label` is a default (English) display name — apps with i18n map `key`s to\n * their own strings and ignore it. Array ORDER is display order.\n */\nexport type PropSpec =\n | { key: 'color'; label: string }\n | { key: 'interiorColor'; label: string }\n | { key: 'fontColor'; label: string }\n | { key: 'opacity'; label: string; min: number; max: number; step: number }\n | { key: 'strokeWidth'; label: string; min: number; max: number; step: number }\n | { key: 'fontSize'; label: string; min: number; max: number; step: number }\n /** Border style picker; `cloudy` says whether this kind honours a cloudy border. */\n | { key: 'border'; label: string; cloudy: boolean }\n | { key: 'lineEndings'; label: string }\n | { key: 'fontFamily'; label: string }\n | { key: 'textAlign'; label: string }\n | { key: 'blendMode'; label: string }\n /** `/Name` icon picker for icon kinds; `options` are the legal names. */\n | { key: 'icon'; label: string; options: readonly string[] }\n /** Link-target editor (URL / page destination). Declared by the link kind\n * (its own target) and by every kind that may carry an ATTACHED link;\n * kinds that omit it (widgets, caret, redact…) simply cannot be links —\n * `applyProps` drops the key and menus never show the control. */\n | { key: 'link'; label: string };\n\n/** Orthogonal capability flags. Static data — the annotation's `/F` flags are\n * the runtime overrides (a locked annotation is never transformable, a hidden\n * one never renders, regardless of these — see flags.ts). */\nexport interface KindCaps {\n /** Can be clicked to select. */\n selectable: boolean;\n /** Can be dragged (by its body) to translate. */\n movable: boolean;\n /** Exposes the 8 box resize handles (shapes). */\n resizable: boolean;\n /** Exposes per-vertex handles (line endpoints, polygon/polyline vertices). */\n vertexEditable: boolean;\n /** Can be rotated (shapes, free text, lines/polys/ink). */\n rotatable: boolean;\n /** Can be MOVED as part of a multi-target (group) transform. */\n groupMovable: boolean;\n /** Can be uniformly SCALED as part of a multi-target (group) transform — ON\n * even for vertex kinds that have no single-shape box resize (their handles\n * ARE the vertices; in a group they scale fine). */\n groupResizable: boolean;\n /** Can be ROTATED as part of a multi-target (group) transform. */\n groupRotatable: boolean;\n /** Carries editable text content (free text, the comment popup). */\n textEditable: boolean;\n /** Can carry a comment/note + threaded replies (`/Contents` + `/Popup`). */\n commentable: boolean;\n /** Has a popup as its primary surface (the comment/Text icon). */\n hasPopup: boolean;\n /** Bound to underlying text (markup, caret) — never freely moved/resized. */\n anchored: boolean;\n /** Has an interior fill (`/IC`). */\n hasFill: boolean;\n /** Has line endings (`/LE` — line, polyline). */\n hasEndings: boolean;\n /** Can take a cloudy border effect (`/BE` — shapes). */\n hasCloudy: boolean;\n /** The whole body is visible content, so hit-testing grabs anywhere inside\n * the box (stamp images) — NOT just the stroke/fill like outline shapes. */\n opaqueBody: boolean;\n /** The `/F` ReadOnly flag is IGNORED for this kind (ISO 32000: widgets — a\n * ReadOnly form FIELD must still be movable by a form designer; the\n * form-filling layer enforces field ReadOnly itself). */\n ignoresReadOnly: boolean;\n /** Behaves as if `/F` NoZoom is always set (screen-constant size — the\n * spec's rule for Text/note icons). See anchor.ts. */\n noZoom: boolean;\n /** Behaves as if `/F` NoRotate is always set (screen-upright — the spec's\n * rule for Text/note icons). See anchor.ts. */\n noRotate: boolean;\n}\n\nexport interface AnnotationKind {\n subtype: Subtype;\n /** Future: PDF `/IT` intent (free-text vs callout, caret insert vs replace). */\n intent?: string;\n variant: Geom['t'];\n caps: KindCaps;\n /** The kind's editable properties, in DISPLAY ORDER — the contract a property\n * sidebar renders from (see {@link PropSpec}). Empty = nothing to edit. */\n props: PropSpec[];\n}\n\n/* Shared spec entries — plain data, spread into the per-kind lists below. */\nconst OPACITY: PropSpec = { key: 'opacity', label: 'Opacity', min: 0.1, max: 1, step: 0.05 };\nconst ICON_COLOR: PropSpec = { key: 'color', label: 'Color' };\n\n/* `/Name` values per icon kind — mirrors the engine's NoteIcon /\n * FileAttachmentIcon unions (the appearance generator's vocabulary). */\nconst NOTE_ICONS = [\n 'comment',\n 'key',\n 'note',\n 'help',\n 'new-paragraph',\n 'paragraph',\n 'insert',\n] as const;\nconst FILE_ATTACHMENT_ICONS = ['push-pin', 'paperclip', 'graph', 'tag'] as const;\nconst STROKE: PropSpec = { key: 'color', label: 'Stroke' };\nconst FILL: PropSpec = { key: 'interiorColor', label: 'Fill' };\nconst STROKE_WIDTH: PropSpec = {\n key: 'strokeWidth',\n label: 'Stroke width',\n min: 0.5,\n max: 30,\n step: 0.5,\n};\nconst BORDER_CLOUDY: PropSpec = { key: 'border', label: 'Border', cloudy: true };\nconst BORDER_PLAIN: PropSpec = { key: 'border', label: 'Border', cloudy: false };\nconst LINE_ENDINGS: PropSpec = { key: 'lineEndings', label: 'Line endings' };\nconst BLEND_MODE: PropSpec = { key: 'blendMode', label: 'Blend mode' };\n\n/**\n * \"This annotation links somewhere\" — one spec, shared by every kind that can\n * carry an attached link (a grouped `/Link` child; see AnnotationProps.link).\n * Deliberately absent from: widget-* (a widget's `/A` is forms-plane\n * behavior, not an attached link), caret (an anchored edit marker),\n * file-attachment (its click means \"open the attachment\"), and redact.\n */\nconst LINKABLE: PropSpec = { key: 'link', label: 'Link' };\n\n/** Shapes with a fill + a (possibly cloudy) border: square / circle / polygon. */\nconst SHAPE_PROPS: PropSpec[] = [STROKE, FILL, OPACITY, STROKE_WIDTH, BORDER_CLOUDY, LINKABLE];\n\n// Widget-plane styling: every family has a box; text-bearing families add\n// the /DA vocabulary. Same flat keys as every other kind — the writer maps\n// them onto /MK//BS//DA//Q underneath. One PDF subtype, several CLIENT\n// kinds (the free-text/callout precedent): the field FAMILY picks the kind,\n// so a radio never offers a font and the schema-driven sidebar needs no\n// widget-specific code.\nconst WIDGET_BOX_PROPS: PropSpec[] = [\n { key: 'color', label: 'Border color' },\n { key: 'interiorColor', label: 'Background' },\n { key: 'strokeWidth', label: 'Border width', min: 0, max: 12, step: 0.5 },\n { key: 'border', label: 'Border style', cloudy: false },\n];\nconst WIDGET_TEXT_PROPS: PropSpec[] = [\n ...WIDGET_BOX_PROPS,\n { key: 'fontFamily', label: 'Font' },\n { key: 'fontSize', label: 'Font size', min: 0, max: 96, step: 1 },\n { key: 'fontColor', label: 'Text color' },\n { key: 'textAlign', label: 'Alignment' },\n];\n/** Stroked vertex kinds with `/LE` endings: line / polyline. The fill colours a\n * CLOSED ending (closed arrow / circle / square / diamond). */\nconst LINE_PROPS: PropSpec[] = [\n STROKE,\n FILL,\n OPACITY,\n STROKE_WIDTH,\n BORDER_PLAIN,\n LINE_ENDINGS,\n LINKABLE,\n];\n/** Text markup: colour/opacity plus its appearance-stream blend mode. */\nconst MARK_PROPS: PropSpec[] = [{ key: 'color', label: 'Color' }, OPACITY, BLEND_MODE, LINKABLE];\n/** Carets are anchored text-edit markers, without a blend-mode control. */\nconst CARET_PROPS: PropSpec[] = [{ key: 'color', label: 'Color' }, OPACITY];\nconst INK_PROPS: PropSpec[] = [\n { key: 'color', label: 'Color' },\n OPACITY,\n STROKE_WIDTH,\n BLEND_MODE,\n LINKABLE,\n];\n/** Redaction marks: outline at rest; the fill + label are what apply paints.\n * Label size 0 = auto-fit to the region (the engine's convention). */\nconst REDACT_PROPS: PropSpec[] = [\n { key: 'color', label: 'Outline' },\n FILL,\n OPACITY,\n { key: 'fontFamily', label: 'Label font' },\n { key: 'fontSize', label: 'Label size', min: 0, max: 96, step: 1 },\n { key: 'fontColor', label: 'Label color' },\n { key: 'textAlign', label: 'Align' },\n];\n/** Free text: font first (the primary surface), then box background + border. */\nconst TEXT_PROPS: PropSpec[] = [\n { key: 'fontFamily', label: 'Font' },\n { key: 'fontSize', label: 'Font size', min: 4, max: 96, step: 1 },\n { key: 'fontColor', label: 'Text color' },\n { key: 'textAlign', label: 'Align' },\n OPACITY,\n { key: 'interiorColor', label: 'Background' },\n { key: 'color', label: 'Border' },\n { key: 'strokeWidth', label: 'Border width', min: 0, max: 12, step: 0.5 },\n LINKABLE,\n];\n\n/** Build caps from a sparse override — everything not named is `false`. */\nconst caps = (c: Partial<KindCaps>): KindCaps => ({\n selectable: false,\n movable: false,\n resizable: false,\n vertexEditable: false,\n rotatable: false,\n groupMovable: false,\n groupResizable: false,\n groupRotatable: false,\n textEditable: false,\n commentable: false,\n hasPopup: false,\n anchored: false,\n hasFill: false,\n hasEndings: false,\n hasCloudy: false,\n opaqueBody: false,\n ignoresReadOnly: false,\n noZoom: false,\n noRotate: false,\n ...c,\n});\n\n/** Read-only fallback for unknown/unsupported subtypes (render baked, no editing). */\nconst READONLY: KindCaps = caps({});\n\n/** The built-in kinds. Shapes resize, lines/polys vertex-edit, markup is anchored\n * (selectable + recolor/delete, never move/resize). */\nexport const KINDS: Record<string, AnnotationKind> = {\n 'widget-text': {\n subtype: 'widget-text',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_TEXT_PROPS,\n },\n 'widget-choice': {\n subtype: 'widget-choice',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_TEXT_PROPS,\n },\n 'widget-button': {\n subtype: 'widget-button',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_TEXT_PROPS,\n },\n 'widget-toggle': {\n subtype: 'widget-toggle',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_BOX_PROPS,\n },\n 'widget-box': {\n subtype: 'widget-box',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_BOX_PROPS,\n },\n 'free-text': {\n subtype: 'free-text',\n variant: 'text',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true, // the box resizes (8 handles); text reflows\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n textEditable: true,\n commentable: true,\n hasFill: true, // `/C` box background\n }),\n props: TEXT_PROPS,\n },\n square: {\n subtype: 'square',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n }),\n props: SHAPE_PROPS,\n },\n circle: {\n subtype: 'circle',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n }),\n props: SHAPE_PROPS,\n },\n line: {\n subtype: 'line',\n variant: 'line',\n caps: caps({\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasEndings: true,\n }),\n props: LINE_PROPS,\n },\n polygon: {\n subtype: 'polygon',\n variant: 'poly',\n caps: caps({\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n }),\n props: SHAPE_PROPS,\n },\n polyline: {\n subtype: 'polyline',\n variant: 'poly',\n caps: caps({\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasEndings: true,\n }),\n props: LINE_PROPS,\n },\n // Ink: freehand strokes. Selectable + movable as a whole; no single-shape\n // resize/vertex handles (the strokes are the geometry), but rotatable and\n // group-resizable. Created by a freehand drag.\n ink: {\n subtype: 'ink',\n variant: 'ink',\n caps: caps({\n selectable: true,\n movable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n }),\n props: INK_PROPS,\n },\n // Text markup: selectable + anchored (bound to text — recolor/delete, never\n // move/resize). Created from a text selection, not a drag (see the markup tool).\n highlight: {\n subtype: 'highlight',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n underline: {\n subtype: 'underline',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n squiggly: {\n subtype: 'squiggly',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n strikeout: {\n subtype: 'strikeout',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n // Redaction mark (the non-destructive stage of the two-stage model): created\n // from a text selection (per-line quads) OR an area drag (rect-only geometry).\n // Text marks are anchored like markup; area marks move/resize — the\n // anchored+quads transform gate in hit.ts lets one caps set serve both\n // geometries.\n redact: {\n subtype: 'redact',\n variant: 'quads',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n anchored: true,\n commentable: true,\n hasFill: true,\n }),\n props: REDACT_PROPS,\n },\n caret: {\n subtype: 'caret',\n variant: 'caret',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: CARET_PROPS,\n },\n // Sticky note (\"comment\"): a fixed 20x20 icon whose visual is the\n // engine-baked /AP (generated from /C + /Name). Screen-constant and\n // screen-upright per the spec's Text-icon rule (noZoom/noRotate); its\n // popup thread is the primary surface once comments land.\n text: {\n subtype: 'text',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n groupMovable: true,\n commentable: true,\n hasPopup: true,\n opaqueBody: true,\n noZoom: true,\n noRotate: true,\n }),\n props: [{ key: 'icon', label: 'Icon', options: NOTE_ICONS }, ICON_COLOR, OPACITY, LINKABLE],\n },\n // File attachment: the same fixed-icon shape as the note, but its primary\n // surface is the embedded FILE (open/download), not a popup.\n 'file-attachment': {\n subtype: 'file-attachment',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n groupMovable: true,\n commentable: true,\n opaqueBody: true,\n noZoom: true,\n noRotate: true,\n }),\n props: [{ key: 'icon', label: 'Icon', options: FILE_ATTACHMENT_ICONS }, ICON_COLOR, OPACITY],\n },\n // Stamp: a rect-variant kind whose visual is ALWAYS the engine-baked /AP\n // (image or vector appearance authored at create time) — never a vector\n // re-render, so it declares no editable style props. Geometry edits\n // (move/resize/rotate) re-fit the appearance natively on the engine side.\n stamp: {\n subtype: 'stamp',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n opaqueBody: true,\n }),\n props: [LINKABLE],\n },\n // Link: an invisible hit rectangle that navigates somewhere. Paints nothing\n // of its own (scene() skips it; any /AP a PDF baked shows via the page\n // raster); `opaqueBody` gives whole-box hit-testing so the invisible rect\n // is grabbable when the link tool makes it editable. Its `link` prop is\n // its OWN target (`/A`) — the one kind where the key doesn't route to an\n // attached child. No rotate: a link has no reading orientation.\n link: {\n subtype: 'link',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n opaqueBody: true,\n }),\n props: [LINKABLE],\n },\n};\n\n/** The capabilities of a subtype, or the read-only default for unknown kinds. */\nexport const capsFor = (subtype: string): KindCaps => KINDS[subtype]?.caps ?? READONLY;\n\nconst NO_PROPS: PropSpec[] = [];\n\n/** A kind's editable properties in display order — empty for unknown kinds.\n * Stable references, so selectors can compare by identity. */\nexport const propsFor = (subtype: string): PropSpec[] => KINDS[subtype]?.props ?? NO_PROPS;\n\n/** A text-markup kind (highlight/underline/squiggly/strikeout). These are drawn\n * on the text layer, which always sits beneath every other annotation. */\nexport const isMarkup = (subtype: string): boolean => KINDS[subtype]?.variant === 'quads';\n","/**\n * Annotation `/F` flags — the ONE interpretation of ISO 32000-2 Table 167.\n *\n * `Annot.flags` carries the named booleans verbatim from the engine DTO; every\n * behavioral question (can I see it? click it? move it? edit its text?) is\n * answered HERE and nowhere else, so rendering, hit-testing, chrome, and the\n * reducer can never disagree about what a flag means.\n *\n * The flag→behavior split, in one line each:\n * hidden — gone everywhere (screen, interaction, print)\n * noView — gone on screen, may still print\n * toggleNoView — reveals a noView annotation while engaged (v1: selected)\n * readOnly — visible but inert (ignored for widget kinds, per spec —\n * the form layer owns field-level ReadOnly)\n * locked — selectable but frozen: no move/resize/rotate/delete/restyle\n * lockedContents — `/Contents` text cannot change; geometry still can\n * print — include when printing (carried for the print pipeline)\n * noZoom/noRotate — screen-anchored body (see anchor.ts)\n * invisible — legacy: hide unknown subtypes with no handler\n */\nimport { NO_ANNOTATION_FLAGS, type AnnotationFlags } from '@embedpdf/engine-core/runtime';\nimport { capsFor } from './kinds';\n\nexport type { AnnotationFlags };\nexport { NO_ANNOTATION_FLAGS };\n\n/** The `/F` every freshly DRAWN annotation starts with: `print` set (Acrobat\n * parity — without it the annotation silently disappears when printed). */\nexport const DRAWN_FLAGS: AnnotationFlags = { ...NO_ANNOTATION_FLAGS, print: true };\n\n/** All ten flags, for iteration/equality — kept in the primitives' order. */\nexport const FLAG_KEYS = Object.keys(NO_ANNOTATION_FLAGS) as ReadonlyArray<keyof AnnotationFlags>;\n\nexport const flagsEqual = (a: AnnotationFlags, b: AnnotationFlags): boolean =>\n FLAG_KEYS.every((k) => a[k] === b[k]);\n\n/** Merge a partial write over the current flags. */\nexport const mergeFlags = (\n base: AnnotationFlags,\n patch: Partial<AnnotationFlags>,\n): AnnotationFlags => ({\n ...base,\n ...patch,\n});\n\n/**\n * On-screen visibility. `hidden` beats everything; `noView` hides unless\n * `toggleNoView` and the annotation is ENGAGED — the spec says hover/selection,\n * and v1 uses selection (the model tracks no hover).\n */\nexport const viewable = (f: AnnotationFlags, engaged = false): boolean =>\n !f.hidden && (!f.noView || (f.toggleNoView && engaged));\n\n/** Any pointer interaction (click-to-select, hover). ReadOnly kills it. */\nexport const interactive = (f: AnnotationFlags): boolean => !f.hidden && !f.noView && !f.readOnly;\n\n/** The subset of an Annot these predicates read — keeps them testable bare. */\nexport interface FlagBearer {\n subtype: string;\n flags: AnnotationFlags;\n}\n\n/** Interaction gate for a concrete annotation: widget kinds ignore `readOnly`\n * (ISO 32000 — a ReadOnly form field must still be movable by a form designer;\n * the form-filling layer enforces field ReadOnly itself). */\nexport const annotInteractive = (a: FlagBearer): boolean =>\n capsFor(a.subtype).ignoresReadOnly ? !a.flags.hidden && !a.flags.noView : interactive(a.flags);\n\n/** Geometry/style/delete mutations — `locked` freezes the OBJECT, not its\n * contents (that's `lockedContents`). */\nexport const annotTransformable = (a: FlagBearer): boolean =>\n annotInteractive(a) && !a.flags.locked;\n\n/** `/Contents` text edits — the contents counterpart of `locked`. */\nexport const annotContentsEditable = (a: FlagBearer): boolean =>\n annotInteractive(a) && !a.flags.lockedContents;\n","/**\n * Group membership — the pure, model-level view of an annotation group.\n *\n * A group is a primary annotation plus its subordinate members. Persistence is\n * the engine's `/IRT` + `/RT /Group` relationship; in the model a subordinate\n * carries `group = <primary's id>` (its `refKey`). The primary is NOT stamped —\n * it is simply the annotation whose `id` equals the group key, so membership is\n * the set of annotations pointing at it plus the primary itself.\n */\nimport { capsFor } from './kinds';\nimport { annotTransformable } from './flags';\nimport type { Id, Model } from './types';\n\n/**\n * The transform capabilities of a multi-target (group) selection: a group can\n * move/resize/rotate only if EVERY member's kind allows that group op AND no\n * member is locked. This is the SINGLE resolver every adapter consumes (v2\n * duplicated the `.every(...)` across three framework components). The iso-vs-\n * aniso resize choice is computed separately, per-gesture, since it depends on\n * the live `rot` of the members, not the static caps.\n */\nexport interface GroupCaps {\n movable: boolean;\n resizable: boolean;\n rotatable: boolean;\n}\n\nexport function groupCaps(m: Model, ids: Id[]): GroupCaps {\n const members = ids.map((id) => m.byId[id]).filter((a): a is NonNullable<typeof a> => !!a);\n if (members.length === 0) return { movable: false, resizable: false, rotatable: false };\n const ok = (pick: (c: ReturnType<typeof capsFor>) => boolean): boolean =>\n members.every((a) => annotTransformable(a) && pick(capsFor(a.subtype)));\n return {\n movable: ok((c) => c.groupMovable),\n resizable: ok((c) => c.groupResizable),\n rotatable: ok((c) => c.groupRotatable),\n };\n}\n\n/**\n * The key of the group `id` belongs to, or `null` when it is ungrouped. A\n * subordinate's key is its `group` field; a primary's key is its own id (it is\n * the target of at least one member's `group`). An annotation that is neither a\n * subordinate nor the target of any subordinate is ungrouped.\n */\nexport function groupKeyOf(m: Model, id: Id): Id | null {\n const a = m.byId[id];\n if (!a) return null;\n if (a.group) return a.group;\n for (const other of m.order) {\n if (m.byId[other]?.group === id) return id;\n }\n return null;\n}\n\n/**\n * Every member of the group containing `id` (primary first), or just `[id]`\n * when it is ungrouped. The primary is the annotation whose id is the key; the\n * rest are everything whose `group` equals the key, in `order`.\n */\nexport function groupMembers(m: Model, id: Id): Id[] {\n const key = groupKeyOf(m, id);\n if (key == null) return [id];\n const members: Id[] = [];\n if (m.byId[key]) members.push(key);\n for (const other of m.order) {\n if (other !== key && m.byId[other]?.group === key) members.push(other);\n }\n return members;\n}\n\n/** Union of every id's full group — the selection seen as whole groups. */\nexport function expandGroups(m: Model, ids: Id[]): Id[] {\n const out: Id[] = [];\n const seen = new Set<Id>();\n for (const id of ids) {\n for (const member of groupMembers(m, id)) {\n if (!seen.has(member)) {\n seen.add(member);\n out.push(member);\n }\n }\n }\n return out;\n}\n","/**\n * Cloudy-border (scalloped outline) path generation for shape annotations.\n *\n * Derived from Apache PDFBox's CloudyBorder.java (Apache-2.0):\n * https://github.com/apache/pdfbox — the arc/curl placement is theirs, and we\n * keep it because it visually matches what PDFium bakes into the `/BE` appearance\n * stream, so our live SVG preview and the saved PDF agree.\n *\n * What's v3-specific: this is a PURE function. It takes a content-space box plus\n * the border `intensity`/`strokeWidth` and returns SVG path data in ABSOLUTE\n * content coordinates (the same space `geomScene`'s rect/ellipse nodes use). There\n * is no stored `/RD`, no border-style enum, no bbox bookkeeping — the inset is\n * derived (`cloudyBorderExtent`) and the outer edge of the scallops lands exactly\n * on the box, so the box stays the annotation's outer boundary (its `/Rect`).\n *\n * The internal math runs in PDFBox's y-UP frame; `PathBuilder` flips back to\n * y-down and translates into the box's content-space origin on the way out.\n */\nimport type { Rect, Vec } from './types';\n\nconst ANGLE_180 = Math.PI;\nconst ANGLE_90 = Math.PI / 2;\nconst ANGLE_34 = (34 * Math.PI) / 180;\nconst ANGLE_30 = (30 * Math.PI) / 180;\nconst ANGLE_12 = (12 * Math.PI) / 180;\n\ninterface P {\n x: number;\n y: number;\n}\n\nconst r = (n: number): string => Number(n.toFixed(4)).toString();\n\n/**\n * Accumulates SVG path commands. Input is PDFBox's y-up frame; output is y-down\n * content space, offset into the box origin (ox, oy) so the `d` string is in the\n * same absolute coordinates as every other render node.\n */\nclass PathBuilder {\n private parts: string[] = [];\n private started = false;\n constructor(\n private ox: number,\n private oy: number,\n ) {}\n moveTo(x: number, y: number): void {\n this.parts.push(`M ${r(x + this.ox)} ${r(-y + this.oy)}`);\n this.started = true;\n }\n curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void {\n this.parts.push(\n `C ${r(x1 + this.ox)} ${r(-y1 + this.oy)}, ${r(x2 + this.ox)} ${r(-y2 + this.oy)}, ${r(x3 + this.ox)} ${r(-y3 + this.oy)}`,\n );\n }\n close(): void {\n if (this.started) this.parts.push('Z');\n }\n build(): string {\n return this.parts.join(' ');\n }\n}\n\n/* ── geometry helpers ─────────────────────────────────────────────────────── */\n\nconst distance = (a: P, b: P): number => Math.hypot(b.x - a.x, b.y - a.y);\nconst cosine = (dx: number, hyp: number): number => (hyp === 0 ? 0 : dx / hyp);\nconst sine = (dy: number, hyp: number): number => (hyp === 0 ? 0 : dy / hyp);\n\n/** Signed area (shoelace): positive = counter-clockwise. */\nfunction polygonDirection(pts: P[]): number {\n let a = 0;\n for (let i = 0; i < pts.length; i++) {\n const j = (i + 1) % pts.length;\n a += pts[i].x * pts[j].y - pts[i].y * pts[j].x;\n }\n return a;\n}\nfunction ensurePositiveWinding(pts: P[]): void {\n if (polygonDirection(pts) < 0) pts.reverse();\n}\nfunction removeZeroLengthSegments(polygon: P[]): P[] {\n if (polygon.length <= 2) return polygon;\n const tol = 0.5;\n const out: P[] = [polygon[0]];\n for (let i = 1; i < polygon.length; i++) {\n const prev = out[out.length - 1];\n const cur = polygon[i];\n if (Math.abs(cur.x - prev.x) >= tol || Math.abs(cur.y - prev.y) >= tol) out.push(cur);\n }\n return out;\n}\n\n/* ── elliptical-arc Bézier approximation ──────────────────────────────────── */\n\nfunction arcSegment(\n startAng: number,\n endAng: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n out: PathBuilder,\n addMoveTo: boolean,\n): void {\n const cosA = Math.cos(startAng);\n const sinA = Math.sin(startAng);\n const cosB = Math.cos(endAng);\n const sinB = Math.sin(endAng);\n const denom = Math.sin((endAng - startAng) / 2);\n if (denom === 0) {\n if (addMoveTo) out.moveTo(cx + rx * cosA, cy + ry * sinA);\n return;\n }\n const bcp = ((4 / 3) * (1 - Math.cos((endAng - startAng) / 2))) / denom;\n if (addMoveTo) out.moveTo(cx + rx * cosA, cy + ry * sinA);\n out.curveTo(\n cx + rx * (cosA - bcp * sinA),\n cy + ry * (sinA + bcp * cosA),\n cx + rx * (cosB + bcp * sinB),\n cy + ry * (sinB - bcp * cosB),\n cx + rx * cosB,\n cy + ry * sinB,\n );\n}\n\nfunction arcSegmentToArray(startAng: number, endAng: number, rx: number, ry: number): P[] {\n const cosA = Math.cos(startAng);\n const sinA = Math.sin(startAng);\n const cosB = Math.cos(endAng);\n const sinB = Math.sin(endAng);\n const denom = Math.sin((endAng - startAng) / 2);\n if (denom === 0) return [];\n const bcp = ((4 / 3) * (1 - Math.cos((endAng - startAng) / 2))) / denom;\n return [\n { x: rx * (cosA - bcp * sinA), y: ry * (sinA + bcp * cosA) },\n { x: rx * (cosB + bcp * sinB), y: ry * (sinB - bcp * cosB) },\n { x: rx * cosB, y: ry * sinB },\n ];\n}\n\nfunction getArc(\n startAng: number,\n endAng: number,\n rx: number,\n ry: number,\n cx: number,\n cy: number,\n out: PathBuilder,\n addMoveTo: boolean,\n): void {\n let angleTodo = endAng - startAng;\n while (angleTodo < 0) angleTodo += 2 * Math.PI;\n const sweep = angleTodo;\n let angleDone = 0;\n if (addMoveTo) out.moveTo(cx + rx * Math.cos(startAng), cy + ry * Math.sin(startAng));\n while (angleTodo > ANGLE_90) {\n arcSegment(startAng + angleDone, startAng + angleDone + ANGLE_90, cx, cy, rx, ry, out, false);\n angleDone += ANGLE_90;\n angleTodo -= ANGLE_90;\n }\n if (angleTodo > 0) arcSegment(startAng + angleDone, startAng + sweep, cx, cy, rx, ry, out, false);\n}\n\n/* ── curls ─────────────────────────────────────────────────────────────────── */\n\nfunction addCornerCurl(\n anglePrev: number,\n angleCur: number,\n radius: number,\n cx: number,\n cy: number,\n alpha: number,\n alphaPrev: number,\n out: PathBuilder,\n addMoveTo: boolean,\n): void {\n const a = anglePrev + ANGLE_180 + alphaPrev;\n const b = a - (22 * Math.PI) / 180;\n arcSegment(a, b, cx, cy, radius, radius, out, addMoveTo);\n getArc(b, angleCur - alpha, radius, radius, cx, cy, out, false);\n}\n\nfunction addFirstIntermediateCurl(\n angleCur: number,\n rad: number,\n alpha: number,\n cx: number,\n cy: number,\n out: PathBuilder,\n): void {\n const a = angleCur + ANGLE_180;\n arcSegment(a + alpha, a + alpha - ANGLE_30, cx, cy, rad, rad, out, false);\n arcSegment(a + alpha - ANGLE_30, a + ANGLE_90, cx, cy, rad, rad, out, false);\n arcSegment(a + ANGLE_90, a + ANGLE_180 - ANGLE_34, cx, cy, rad, rad, out, false);\n}\n\nfunction intermediateCurlTemplate(angleCur: number, rad: number): P[] {\n const a = angleCur + ANGLE_180;\n return [\n ...arcSegmentToArray(a + ANGLE_34, a + ANGLE_12, rad, rad),\n ...arcSegmentToArray(a + ANGLE_12, a + ANGLE_90, rad, rad),\n ...arcSegmentToArray(a + ANGLE_90, a + ANGLE_180 - ANGLE_34, rad, rad),\n ];\n}\nfunction outputCurlTemplate(template: P[], x: number, y: number, out: PathBuilder): void {\n for (let i = 0; i + 2 < template.length; i += 3) {\n out.curveTo(\n template[i].x + x,\n template[i].y + y,\n template[i + 1].x + x,\n template[i + 1].y + y,\n template[i + 2].x + x,\n template[i + 2].y + y,\n );\n }\n}\n\n/* ── cloud radius (PDFBox constants, deduced from Acrobat) ─────────────────── */\n\nconst ellipseCloudRadius = (intensity: number, lineWidth: number): number =>\n 4.75 * intensity + 0.5 * lineWidth;\nconst polygonCloudRadius = (intensity: number, lineWidth: number): number =>\n 4 * intensity + 0.5 * lineWidth;\n\n/* ── polygon core ──────────────────────────────────────────────────────────── */\n\nfunction computeParamsPolygon(\n idealRadius: number,\n k: number,\n length: number,\n): { n: number; adjustedRadius: number } {\n if (length === 0) return { n: -1, adjustedRadius: idealRadius };\n const remaining = length - 2 * k * idealRadius;\n if (remaining <= 0) return { n: 0, adjustedRadius: idealRadius };\n const n = Math.max(1, Math.ceil(remaining / (2 * k * idealRadius)));\n return { n, adjustedRadius: remaining / (n * 2 * k) };\n}\n\nfunction cloudyPolygonImpl(\n vertices: P[],\n isEllipse: boolean,\n intensity: number,\n lineWidth: number,\n out: PathBuilder,\n): void {\n const polygon = removeZeroLengthSegments(vertices);\n ensurePositiveWinding(polygon);\n const n = polygon.length;\n if (n < 2) return;\n\n if (intensity <= 0) {\n out.moveTo(polygon[0].x, polygon[0].y);\n for (let i = 1; i < n; i++)\n out.curveTo(\n polygon[i].x,\n polygon[i].y,\n polygon[i].x,\n polygon[i].y,\n polygon[i].x,\n polygon[i].y,\n );\n return;\n }\n\n let idealRadius = isEllipse\n ? ellipseCloudRadius(intensity, lineWidth)\n : polygonCloudRadius(intensity, lineWidth);\n if (idealRadius < 0.5) idealRadius = 0.5;\n const k = Math.cos(ANGLE_34);\n\n const edgeAlphas: number[] = [];\n for (let j = 0; j + 1 < n; j++) {\n const len = distance(polygon[j], polygon[j + 1]);\n edgeAlphas.push(\n len <= 0 || len >= 2 * k * idealRadius\n ? ANGLE_34\n : Math.acos(Math.min(1, len / (2 * idealRadius))),\n );\n }\n\n let anglePrev = 0;\n let started = false;\n for (let j = 0; j + 1 < n; j++) {\n const pt = polygon[j];\n const ptNext = polygon[j + 1];\n const len = distance(pt, ptNext);\n if (len === 0) continue;\n\n const params = computeParamsPolygon(idealRadius, k, len);\n if (params.n < 0) {\n if (!started) {\n out.moveTo(pt.x, pt.y);\n started = true;\n }\n continue;\n }\n\n const edgeRadius = Math.max(0.5, params.adjustedRadius);\n const intermAdvance = 2 * k * edgeRadius;\n const firstAdvance = k * idealRadius + k * edgeRadius;\n const angleCur = Math.atan2(ptNext.y - pt.y, ptNext.x - pt.x);\n if (j === 0) {\n const ptPrev = polygon[n - 2];\n anglePrev = Math.atan2(pt.y - ptPrev.y, pt.x - ptPrev.x);\n }\n const cos = cosine(ptNext.x - pt.x, len);\n const sin = sine(ptNext.y - pt.y, len);\n let x = pt.x;\n let y = pt.y;\n const alpha = edgeAlphas[j];\n const alphaPrev = edgeAlphas[j === 0 ? n - 2 : j - 1] ?? ANGLE_34;\n\n addCornerCurl(anglePrev, angleCur, idealRadius, pt.x, pt.y, alpha, alphaPrev, out, !started);\n started = true;\n\n if (params.n === 0) {\n x += len * cos;\n y += len * sin;\n } else {\n x += firstAdvance * cos;\n y += firstAdvance * sin;\n let numInterm = params.n;\n if (params.n >= 1) {\n addFirstIntermediateCurl(angleCur, edgeRadius, ANGLE_34, x, y, out);\n x += intermAdvance * cos;\n y += intermAdvance * sin;\n numInterm = params.n - 1;\n }\n const template = intermediateCurlTemplate(angleCur, edgeRadius);\n for (let i = 0; i < numInterm; i++) {\n outputCurlTemplate(template, x, y, out);\n x += intermAdvance * cos;\n y += intermAdvance * sin;\n }\n }\n anglePrev = angleCur;\n }\n}\n\n/* ── ellipse core ──────────────────────────────────────────────────────────── */\n\nfunction flattenEllipse(left: number, bottom: number, right: number, top: number): P[] {\n const cx = (left + right) / 2;\n const cy = (bottom + top) / 2;\n const rx = (right - left) / 2;\n const ry = (top - bottom) / 2;\n if (rx <= 0 || ry <= 0) return [];\n const segments = Math.max(32, Math.ceil(Math.max(rx, ry) * 2));\n const pts: P[] = [];\n for (let i = 0; i <= segments; i++) {\n const angle = (2 * Math.PI * i) / segments;\n pts.push({ x: cx + rx * Math.cos(angle), y: cy + ry * Math.sin(angle) });\n }\n return pts;\n}\n\nfunction computeParamsEllipse(pt: P, ptNext: P, rad: number, curlAdv: number): number {\n const len = distance(pt, ptNext);\n if (len === 0) return ANGLE_34;\n const arg = (curlAdv / 2 + (len - curlAdv) / 2) / rad;\n return arg < -1 || arg > 1 ? 0 : Math.acos(arg);\n}\n\nfunction cloudyEllipseImpl(\n left: number,\n bottom: number,\n right: number,\n top: number,\n intensity: number,\n lineWidth: number,\n out: PathBuilder,\n): void {\n const plainEllipse = () => {\n const rx = Math.abs(right - left) / 2;\n const ry = Math.abs(top - bottom) / 2;\n getArc(0, 2 * Math.PI, rx, ry, (left + right) / 2, (bottom + top) / 2, out, true);\n };\n\n if (intensity <= 0) return plainEllipse();\n\n const width = right - left;\n const height = top - bottom;\n let cloudRadius = ellipseCloudRadius(intensity, lineWidth);\n\n if (width < 0.5 * cloudRadius && height < 0.5 * cloudRadius) return plainEllipse();\n\n // very long & thin → treat as a rectangle so the scallops read correctly\n if ((width < 5 && height > 20) || (width > 20 && height < 5)) {\n return cloudyPolygonImpl(\n [\n { x: left, y: bottom },\n { x: right, y: bottom },\n { x: right, y: top },\n { x: left, y: top },\n { x: left, y: bottom },\n ],\n true,\n intensity,\n lineWidth,\n out,\n );\n }\n\n // shrink so the cloud tails touch the original outline\n const radiusAdj = Math.sin(ANGLE_12) * cloudRadius - 1.5;\n let adjLeft = left;\n let adjRight = right;\n let adjBottom = bottom;\n let adjTop = top;\n if (width > 2 * radiusAdj) {\n adjLeft += radiusAdj;\n adjRight -= radiusAdj;\n } else {\n const mid = (left + right) / 2;\n adjLeft = mid - 0.1;\n adjRight = mid + 0.1;\n }\n if (height > 2 * radiusAdj) {\n adjBottom += radiusAdj;\n adjTop -= radiusAdj;\n } else {\n const mid = (top + bottom) / 2;\n adjTop = mid + 0.1;\n adjBottom = mid - 0.1;\n }\n\n const flat = flattenEllipse(adjLeft, adjBottom, adjRight, adjTop);\n if (flat.length < 2) return;\n let totLen = 0;\n for (let i = 1; i < flat.length; i++) totLen += distance(flat[i - 1], flat[i]);\n\n const k = Math.cos(ANGLE_34);\n let n = Math.ceil(totLen / (2 * k * cloudRadius));\n if (n < 2) return plainEllipse();\n\n let curlAdvance = totLen / n;\n cloudRadius = curlAdvance / (2 * k);\n if (cloudRadius < 0.5) {\n cloudRadius = 0.5;\n curlAdvance = 2 * k * cloudRadius;\n } else if (cloudRadius < 3.0) {\n return plainEllipse();\n }\n\n // distribute curl centers along the flattened perimeter\n const centers: P[] = [];\n let remain = 0;\n const toler = lineWidth * 0.1;\n for (let i = 0; i + 1 < flat.length; i++) {\n const p1 = flat[i];\n const p2 = flat[i + 1];\n const segLen = distance(p1, p2);\n if (segLen === 0) continue;\n let todo = segLen + remain;\n if (todo >= curlAdvance - toler || i === flat.length - 2) {\n const cos = cosine(p2.x - p1.x, segLen);\n const sin = sine(p2.y - p1.y, segLen);\n let d = curlAdvance - remain;\n while (todo >= curlAdvance - toler) {\n centers.push({ x: p1.x + d * cos, y: p1.y + d * sin });\n todo -= curlAdvance;\n d += curlAdvance;\n }\n remain = Math.max(0, todo);\n } else {\n remain += segLen;\n }\n }\n\n const m = centers.length;\n let anglePrev = 0;\n let alphaPrev = 0;\n for (let i = 0; i < m; i++) {\n const pt = centers[i];\n const ptNext = centers[(i + 1) % m];\n if (i === 0) {\n const ptPrev = centers[m - 1];\n anglePrev = Math.atan2(pt.y - ptPrev.y, pt.x - ptPrev.x);\n alphaPrev = computeParamsEllipse(ptPrev, pt, cloudRadius, curlAdvance);\n }\n const angleCur = Math.atan2(ptNext.y - pt.y, ptNext.x - pt.x);\n const alpha = computeParamsEllipse(pt, ptNext, cloudRadius, curlAdvance);\n addCornerCurl(anglePrev, angleCur, cloudRadius, pt.x, pt.y, alpha, alphaPrev, out, i === 0);\n anglePrev = angleCur;\n alphaPrev = alpha;\n }\n}\n\n/* ── public API ────────────────────────────────────────────────────────────── */\n\n/**\n * The per-side inset (content units) from a shape's outer box to the cloud's\n * inner boundary — the scallop radius plus half the stroke. This IS the `/RD`\n * the engine stores, and it's sized so the scallop peaks reach back out to the\n * box edge: the box remains the annotation's outer boundary.\n */\nexport function cloudyBorderExtent(\n intensity: number,\n strokeWidth: number,\n ellipse: boolean,\n): number {\n const cr = ellipse\n ? ellipseCloudRadius(intensity, strokeWidth)\n : polygonCloudRadius(intensity, strokeWidth);\n return cr + strokeWidth / 2;\n}\n\n/**\n * SVG path data for a cloudy POLYGON border, in ABSOLUTE content coordinates.\n * Unlike the box kinds (whose scallops inset back INTO the outer box), a\n * polygon's curls are centred ON the vertex path and reach OUTWARD by the cloud\n * radius — the same rule PDFium's `GenerateCloudyPolygonPath` bakes into the\n * /AP, so the live preview and the saved appearance agree. The visual therefore\n * extends `cloudyBorderExtent` beyond the vertices (see `geomVisualBounds`).\n *\n * The v3 counterpart of v2's `generateCloudyPolygonPath` (same steps: y-flip,\n * close the ring, run the polygon core). Stroke it with ROUND joins — the curl\n * tails reverse direction by design, and `scene()` sets `join: 'round'` to\n * match PDFium's `1 j`; a miter join turns every seam into a spike.\n */\nexport function cloudyPolyPath(points: Vec[], intensity: number, strokeWidth: number): string {\n const out = new PathBuilder(0, 0);\n // Content space is y-down; the PDFBox core runs y-up (PathBuilder flips back).\n const ring = points.map((p) => ({ x: p.x, y: -p.y }));\n const first = ring[0];\n const last = ring[ring.length - 1];\n // The impl walks edges of a CLOSED ring (first vertex repeated at the end).\n if (first && (first.x !== last.x || first.y !== last.y)) ring.push({ ...first });\n cloudyPolygonImpl(ring, false, intensity, strokeWidth, out);\n out.close();\n return out.build();\n}\n\n/**\n * SVG path data for a cloudy square (rect) or circle (ellipse), in ABSOLUTE\n * content coordinates. The scallops are generated on the box inset by\n * `cloudyBorderExtent` and bulge back out to `box`'s edge.\n */\nexport function cloudyPath(\n box: Rect,\n ellipse: boolean,\n intensity: number,\n strokeWidth: number,\n): string {\n const inset = cloudyBorderExtent(intensity, strokeWidth, ellipse);\n const out = new PathBuilder(box.x, box.y);\n const left = inset;\n const top = inset;\n const right = box.width - inset;\n const bottom = box.height - inset;\n if (ellipse) {\n cloudyEllipseImpl(left, -bottom, right, -top, intensity, strokeWidth, out);\n } else {\n cloudyPolygonImpl(\n [\n { x: left, y: -top },\n { x: right, y: -top },\n { x: right, y: -bottom },\n { x: left, y: -bottom },\n { x: left, y: -top },\n ],\n false,\n intensity,\n strokeWidth,\n out,\n );\n }\n out.close();\n return out.build();\n}\n","/**\n * Line endings (/LE) — the arrowheads and tip shapes drawn at the ends of line\n * and polyline annotations. ONE spec per ending kind drives BOTH the rendered\n * geometry (`endingNodes`) and the bounding-box points (`endingPoints`), so the\n * visual and the engine `/Rect` can never drift. Pure content-space math (PDF\n * points, y-down) — no DOM, no SVG strings — so it ports to Rust like the rest.\n *\n * Convention: each spec is authored in a LOCAL frame with the tip at the origin\n * and the body pointing back along −X. `endingNodes`/`endingPoints` rotate it by\n * the segment angle (into the tip) and translate it to the tip point. Sizes\n * scale with the stroke width, matching the v2 renderer.\n */\nimport type { LineEnding, RenderNode, Vec } from './types';\n\ninterface EndingSpec {\n shape: 'poly' | 'ellipse';\n /** Poly: closed path (so it fills with the annotation's fill colour) vs an open\n * polyline that is stroke-only (open arrow / butt / slash). Ellipses are always\n * closed. Fill colour is the renderer's job — the spec only states closed-ness. */\n closed: boolean;\n /** Final rotation (radians) given the segment angle pointing INTO the tip. */\n rotation: (angle: number) => number;\n /** Local-frame points (tip at origin, body along −X). */\n points: (sw: number) => Vec[];\n}\n\nconst arrow = (closed: boolean): EndingSpec => ({\n shape: 'poly',\n closed,\n rotation: (a) => a,\n points: (sw) => {\n const len = sw * 9;\n const wing = Math.PI / 6; // 30°\n const x = -len * Math.cos(wing);\n const y = len * Math.sin(wing);\n return closed\n ? [\n { x: 0, y: 0 },\n { x, y },\n { x, y: -y },\n ]\n : [\n { x, y },\n { x: 0, y: 0 },\n { x, y: -y },\n ];\n },\n});\n\nconst lineCap = (factor: number, rotation: (a: number) => number): EndingSpec => ({\n shape: 'poly',\n closed: false,\n rotation,\n points: (sw) => {\n const half = (sw * factor) / 2;\n return [\n { x: -half, y: 0 },\n { x: half, y: 0 },\n ];\n },\n});\n\nconst ENDINGS: Partial<Record<LineEnding, EndingSpec>> = {\n 'open-arrow': arrow(false),\n 'closed-arrow': arrow(true),\n 'r-open-arrow': { ...arrow(false), rotation: (a) => a + Math.PI },\n 'r-closed-arrow': { ...arrow(true), rotation: (a) => a + Math.PI },\n circle: {\n shape: 'ellipse',\n closed: true,\n rotation: () => 0, // a circle reads the same at any angle\n points: (sw) => {\n const r = (sw * 5) / 2;\n return [\n { x: -r, y: -r },\n { x: r, y: r },\n ];\n },\n },\n square: {\n shape: 'poly',\n closed: true,\n rotation: (a) => a,\n points: (sw) => {\n const h = (sw * 6) / 2;\n return [\n { x: -h, y: -h },\n { x: h, y: -h },\n { x: h, y: h },\n { x: -h, y: h },\n ];\n },\n },\n diamond: {\n shape: 'poly',\n closed: true,\n rotation: (a) => a,\n points: (sw) => {\n const h = (sw * 6) / 2;\n return [\n { x: h, y: 0 },\n { x: 0, y: h },\n { x: -h, y: 0 },\n { x: 0, y: -h },\n ];\n },\n },\n butt: lineCap(6, (a) => a + Math.PI / 2),\n slash: lineCap(18, (a) => a + Math.PI / 1.5),\n};\n\nconst rotateTranslate = (p: Vec, angle: number, tip: Vec): Vec => {\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return { x: tip.x + p.x * c - p.y * s, y: tip.y + p.x * s + p.y * c };\n};\n\nconst specOf = (ending: LineEnding | undefined): EndingSpec | undefined =>\n ending && ending !== 'none' ? ENDINGS[ending] : undefined;\n\n/** Content-space points contributed by an ending — for the visual bounding box. */\nexport function endingPoints(\n tip: Vec,\n angle: number,\n ending: LineEnding | undefined,\n strokeWidth: number,\n): Vec[] {\n const spec = specOf(ending);\n if (!spec) return [];\n const rot = spec.rotation(angle);\n return spec.points(strokeWidth).map((p) => rotateTranslate(p, rot, tip));\n}\n\n/** Content-space render nodes for an ending — what the framework renderer draws. */\nexport function endingNodes(\n tip: Vec,\n angle: number,\n ending: LineEnding | undefined,\n strokeWidth: number,\n): RenderNode[] {\n const spec = specOf(ending);\n if (!spec) return [];\n const rot = spec.rotation(angle);\n const pts = spec.points(strokeWidth).map((p) => rotateTranslate(p, rot, tip));\n if (spec.shape === 'ellipse') {\n const [a, b] = pts;\n return [\n {\n kind: 'ellipse',\n rect: {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n },\n },\n ];\n }\n return [{ kind: 'poly', points: pts, closed: spec.closed }];\n}\n","/**\n * Pure content-space geometry, dispatched on the `Geom` union. This is the whole\n * per-kind surface: bounds, hit-testing (stroke + fill, with a configurable\n * margin), handles (with cursors), translate, handle-drag, and the dumb scene.\n * The PDF↔content bridge (crop-relative y-flip) is the only engine seam.\n */\nimport type { PdfPoint, PdfRect } from '@embedpdf/engine-core/runtime';\nimport {\n applyPoint,\n applyRect,\n invert,\n isQuarterTurn,\n pdfToContentMatrix,\n rotateAbout,\n type Mat2D,\n type PageRotation,\n type PointIn,\n type RectIn,\n type Size,\n} from '@embedpdf/core-geometry';\nimport { cloudyBorderExtent, cloudyPath, cloudyPolyPath } from './cloudy';\nimport { endingNodes, endingPoints } from './endings';\nimport type {\n Border,\n Cursor,\n Geom,\n Handle,\n LineEnding,\n Quad,\n Rect,\n RenderNode,\n Style,\n Vec,\n} from './types';\n\nconst MIN_SIZE = 4;\n\n/* ── rect handles ─────────────────────────────────────────────────────────── */\n\nexport type RectHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';\nexport const RECT_HANDLES: RectHandle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\nconst RECT_CURSOR: Record<RectHandle, Cursor> = {\n nw: 'nwse-resize',\n se: 'nwse-resize',\n ne: 'nesw-resize',\n sw: 'nesw-resize',\n n: 'ns-resize',\n s: 'ns-resize',\n e: 'ew-resize',\n w: 'ew-resize',\n};\n/** Each handle's compass direction (deg CW from north) on the unrotated box. */\nconst HANDLE_BASE_ANGLE: Record<RectHandle, number> = {\n n: 0,\n ne: 45,\n e: 90,\n se: 135,\n s: 180,\n sw: 225,\n w: 270,\n nw: 315,\n};\n/** The resize cursor per 45° compass sector (index = sector, 0 = north). */\nconst SECTOR_CURSORS: Cursor[] = [\n 'ns-resize',\n 'nesw-resize',\n 'ew-resize',\n 'nwse-resize',\n 'ns-resize',\n 'nesw-resize',\n 'ew-resize',\n 'nwse-resize',\n];\n/** The resize cursor for a handle on a box tilted by `rot` deg: rotate the\n * handle's compass direction with the box and pick the nearest 45° sector.\n * At `rot = 0` this reproduces {@link RECT_CURSOR} exactly. */\nexport const rotatedHandleCursor = (h: RectHandle, rot: number): Cursor =>\n SECTOR_CURSORS[Math.round(normalizeDeg(HANDLE_BASE_ANGLE[h] + rot) / 45) % 8];\nconst rectEdges = (h: RectHandle) => ({\n w: h === 'nw' || h === 'w' || h === 'sw',\n e: h === 'ne' || h === 'e' || h === 'se',\n n: h === 'nw' || h === 'n' || h === 'ne',\n s: h === 'sw' || h === 's' || h === 'se',\n});\nconst rectHandlePoint = (r: Rect, h: RectHandle): Vec => {\n const e = rectEdges(h);\n return {\n x: e.w ? r.x : e.e ? r.x + r.width : r.x + r.width / 2,\n y: e.n ? r.y : e.s ? r.y + r.height : r.y + r.height / 2,\n };\n};\nfunction resizeRect(base: Rect, h: RectHandle, to: Vec): Rect {\n const e = rectEdges(h);\n let l = base.x;\n let r = base.x + base.width;\n let t = base.y;\n let b = base.y + base.height;\n if (e.w) l = to.x;\n if (e.e) r = to.x;\n if (e.n) t = to.y;\n if (e.s) b = to.y;\n return {\n x: Math.min(l, r),\n y: Math.min(t, b),\n width: Math.max(MIN_SIZE, Math.abs(r - l)),\n height: Math.max(MIN_SIZE, Math.abs(b - t)),\n };\n}\n\n/* ── small math ───────────────────────────────────────────────────────────── */\n\nexport const rectFromPoints = (a: Vec, b: Vec): Rect => ({\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n});\nexport const rectsIntersect = (a: Rect, b: Rect): boolean =>\n a.x <= b.x + b.width && a.x + a.width >= b.x && a.y <= b.y + b.height && a.y + a.height >= b.y;\nconst rectContains = (r: Rect, p: Vec): boolean =>\n p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height;\n\n/** Distance from point p to segment ab. */\nfunction segDist(p: Vec, a: Vec, b: Vec): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len2 = dx * dx + dy * dy;\n const t = len2 === 0 ? 0 : Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / len2));\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));\n}\n/** Even-odd point-in-polygon. */\nfunction pointInPoly(p: Vec, pts: Vec[]): boolean {\n let inside = false;\n for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {\n const a = pts[i];\n const b = pts[j];\n if (a.y > p.y !== b.y > p.y && p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x)\n inside = !inside;\n }\n return inside;\n}\nconst polyPoints = (geom: Extract<Geom, { t: 'poly' }>): Vec[] => geom.points;\n\nexport function unionRect(pts: Vec[]): Rect {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const p of pts) {\n x0 = Math.min(x0, p.x);\n y0 = Math.min(y0, p.y);\n x1 = Math.max(x1, p.x);\n y1 = Math.max(y1, p.y);\n }\n return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };\n}\n\nconst expandRect = (r: Rect, pad: number): Rect => ({\n x: r.x - pad,\n y: r.y - pad,\n width: r.width + 2 * pad,\n height: r.height + 2 * pad,\n});\n\nconst rectCornerPoints = (r: Rect): Vec[] => [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x + r.width, y: r.y + r.height },\n { x: r.x, y: r.y + r.height },\n];\n\n/* ── rotation ──────────────────────────────────────────────────────────────\n * Annotation rotation, layered on the generic `@embedpdf/core-geometry` affine\n * primitives (`rotateAbout`). Box kinds carry an UNROTATED `rect` + a `rot`\n * angle; vertex kinds carry already-rotated points + an ADVISORY `rot`. These\n * helpers know that split and compose the matrix builders — they never hand-roll\n * a rotation matrix. See `Geom` in types.ts.\n * ──────────────────────────────────────────────────────────────────────────── */\n\nconst DEG2RAD = Math.PI / 180;\n\n/** How far (content units) the rotate knob hangs off the top edge of the box. */\nexport const ROTATE_KNOB_OFFSET = 24;\n\n/** Fallback chrome geometry (content units) when the caller supplies none —\n * the pre-settings behavior, so bare-core callers and tests stay stable. */\nexport const DEFAULT_CHROME_GEOM = {\n handleTol: 6,\n knobTol: 6,\n knobOffset: ROTATE_KNOB_OFFSET,\n} as const;\n\n/** Normalize degrees into `[0, 360)`. */\nexport const normalizeDeg = (d: number): number => ((d % 360) + 360) % 360;\n\n/** A geom's applied rotation (deg), or 0 for the non-rotatable kinds. */\nexport function geomRotation(g: Geom): number {\n if (g.t === 'rect' || g.t === 'line' || g.t === 'poly' || g.t === 'ink' || g.t === 'text')\n return g.rot ?? 0;\n return 0;\n}\n\nconst rectCenter = (r: Rect): Vec => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });\n\nconst rotateAboutM = (pivot: Vec, deg: number): Mat2D<'content', 'content'> =>\n rotateAbout(pivot as PointIn<'content'>, deg * DEG2RAD);\n\n/** Rotate one point about a pivot by `deg` (CW, content space). */\nexport const rotatePoint = (p: Vec, pivot: Vec, deg: number): Vec =>\n applyPoint(rotateAboutM(pivot, deg), p as PointIn<'content'>);\n\n/**\n * The rotation PIVOT for a single shape: a box turns about its own `rect`\n * centre; a vertex shape about the CENTROID of its points (the mean). Rotating a\n * point set about its centroid leaves the centroid fixed, so the advisory `rot`\n * stays cleanly additive across gestures and reset is exact.\n */\nexport function centroidOf(g: Geom): Vec {\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return rectCenter(g.rect);\n if (g.t === 'line') return { x: (g.a.x + g.b.x) / 2, y: (g.a.y + g.b.y) / 2 };\n const pts = g.t === 'poly' ? g.points : g.t === 'ink' ? g.strokes.flat() : g.quads.flat();\n let sx = 0;\n let sy = 0;\n for (const p of pts) {\n sx += p.x;\n sy += p.y;\n }\n const n = pts.length || 1;\n return { x: sx / n, y: sy / n };\n}\n\n/** Is this kind rotatable (the geometry carries a meaningful `rot`)? */\nexport function isRotatableGeom(g: Geom): boolean {\n return (\n g.t === 'rect' ||\n g.t === 'line' ||\n g.t === 'poly' ||\n g.t === 'ink' ||\n (g.t === 'text' && !g.callout)\n );\n}\n\n/**\n * Rotate a geom by `deltaDeg` (clockwise) about `pivot`.\n * - BOX (`rect`/plain `text`): orbit the box centre about the pivot (a rigid\n * translation of the unrotated `rect`) and add the angle to `rot`. When the\n * pivot IS the box centre this is a pure `rot += delta`.\n * - VERTEX (`line`/`poly`/`ink`): map every point through the rotation AND bump\n * the advisory `rot` (the points stay the authoritative visual).\n * Non-rotatable kinds (caret/quads, callouts) are returned unchanged.\n */\nexport function geomRotateAbout(g: Geom, pivot: Vec, deltaDeg: number): Geom {\n if (deltaDeg === 0) return g;\n const nextRot = normalizeDeg(geomRotation(g) + deltaDeg);\n if (g.t === 'rect') {\n const c = rotatePoint(rectCenter(g.rect), pivot, deltaDeg);\n return {\n ...g,\n rect: { ...g.rect, x: c.x - g.rect.width / 2, y: c.y - g.rect.height / 2 },\n rot: nextRot,\n };\n }\n if (g.t === 'text') {\n // The rotate GESTURE stays out of scope for callouts (no knob/orbit); the\n // box may still carry a creation-time `rot` from the upright policy.\n if (g.callout) return g;\n const c = rotatePoint(rectCenter(g.rect), pivot, deltaDeg);\n return {\n ...g,\n rect: { ...g.rect, x: c.x - g.rect.width / 2, y: c.y - g.rect.height / 2 },\n rot: nextRot,\n };\n }\n const rp = (p: Vec) => rotatePoint(p, pivot, deltaDeg);\n if (g.t === 'line') return { ...g, a: rp(g.a), b: rp(g.b), rot: nextRot };\n if (g.t === 'poly') return { ...g, points: g.points.map(rp), rot: nextRot };\n if (g.t === 'ink') return { ...g, strokes: g.strokes.map((s) => s.map(rp)), rot: nextRot };\n return g;\n}\n\n/**\n * The size of the frame an engine-baked `/AP` is authored into: the UNROTATED\n * box for box kinds (rotation is stripped to `apRot` and re-applied at the\n * blit), the point bounds for vertex kinds (their points ARE the visual).\n * Position is deliberately absent — a translation never invalidates a raster.\n */\nfunction apFrameSize(g: Geom): Size {\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret')\n return { width: g.rect.width, height: g.rect.height };\n const pts =\n g.t === 'line'\n ? [g.a, g.b]\n : g.t === 'poly'\n ? g.points\n : g.t === 'ink'\n ? g.strokes.flat()\n : g.quads.flat();\n const b = unionRect(pts);\n return { width: b.width, height: b.height };\n}\n\n/**\n * Did an edit change the SIZE of the geometry's `/AP` authoring frame — i.e.\n * will the engine's re-bake produce NEW raster content? One rule for every\n * gesture, so the commit sites never enumerate kinds: a move/rotate preserves\n * the frame (false), a resize/scale changes it (true). The 0.01pt tolerance\n * absorbs float noise from the gesture math.\n */\nexport function apSizeChanged(before: Geom, after: Geom): boolean {\n const a = apFrameSize(before);\n const b = apFrameSize(after);\n return Math.abs(a.width - b.width) > 0.01 || Math.abs(a.height - b.height) > 0.01;\n}\n\n/** The AABB of `rect` rotated `deg` about its own centre. */\nexport function rotatedAabb(rect: Rect, deg: number): Rect {\n if (!deg) return rect;\n const c = rectCenter(rect);\n return unionRect(rectCornerPoints(rect).map((p) => rotatePoint(p, c, deg)));\n}\n\n/* ── upright placement (counter-rotating against the DISPLAY rotation) ────────\n * An `upright` tool commits `rot = -displayRotation` so the annotation reads\n * horizontally on the rotated page. These two helpers are the ONLY placement\n * math that rule needs; both are exact for quarter-turns and pure content-space\n * (they never know about the view).\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/**\n * The counter-rotation (CW content degrees) that makes an annotation read\n * upright at `displayRotation`: on screen the two compose to 0.\n */\nexport const uprightRotation = (displayRotation: number): number => normalizeDeg(-displayRotation);\n\n/** `rect` with width↔height swapped about its own centre — the unrotated box\n * whose quarter-turn AABB is exactly `rect` again. */\nexport function transposedAboutCenter(rect: Rect): Rect {\n const c = rectCenter(rect);\n return {\n x: c.x - rect.height / 2,\n y: c.y - rect.width / 2,\n width: rect.height,\n height: rect.width,\n };\n}\n\n/**\n * The unrotated content rect for a DEFAULT-SIZE upright box \"placed at\" a\n * point: positioned so that, after the upright counter-rotation, the box shows\n * `width`×`height` with its TOP-LEFT at `anchor` in the ROTATED view — the\n * same on-screen feel as the rotation-0 `{ x: anchor.x, y: anchor.y }` box at\n * every quarter-turn (a click-created free-text box always opens down-right of\n * the cursor as the author sees it). Derived by placing the box in the display\n * frame and pulling its AABB back through the quarter-turn; the page dims\n * cancel, so no page box is needed.\n */\nexport function uprightAnchoredRect(\n anchor: Vec,\n width: number,\n height: number,\n displayRotation: number,\n): Rect {\n const r = normalizeDeg(displayRotation);\n const c: Vec =\n r === 90\n ? { x: anchor.x + height / 2, y: anchor.y - width / 2 }\n : r === 180\n ? { x: anchor.x - width / 2, y: anchor.y - height / 2 }\n : r === 270\n ? { x: anchor.x - height / 2, y: anchor.y + width / 2 }\n : { x: anchor.x + width / 2, y: anchor.y + height / 2 };\n return { x: c.x - width / 2, y: c.y - height / 2, width, height };\n}\n\nconst clampScalar = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\n/**\n * The LOGICAL (unrotated) content-space box for a stamp placed at `center`,\n * sized `desired` (points), fit onto the page and clamped fully within it —\n * the v2 rubber-stamp rule: keep the image's own size unless it would overflow\n * the page, then scale down (aspect preserved, never up) so it just fits.\n *\n * Under an upright quarter-turn the on-page FOOTPRINT is the box transposed\n * (w↔h), so BOTH the fit and the edge clamp use that footprint — a landscape\n * stamp uprighted onto a portrait page fits by its rotated silhouette, not its\n * logical box. The box centre and its footprint AABB centre coincide (rotation\n * is about the centre), so clamping one clamps the other.\n */\nexport function fitStampBox(center: Vec, desired: Size, page: Size, rotCW: number): Rect {\n const quarter = isQuarterTurn((normalizeDeg(rotCW) as PageRotation) ?? 0);\n // Footprint (AABB) dims for the desired size, before fitting.\n const fw0 = quarter ? desired.height : desired.width;\n const fh0 = quarter ? desired.width : desired.height;\n const s = Math.min(1, fw0 > 0 ? page.width / fw0 : 1, fh0 > 0 ? page.height / fh0 : 1);\n const width = desired.width * s;\n const height = desired.height * s;\n const fw = quarter ? height : width;\n const fh = quarter ? width : height;\n // Clamp the centre so the footprint stays fully on the page (the fit above\n // guarantees fw ≤ page.width and fh ≤ page.height, so the range is valid).\n const cx = clampScalar(center.x, fw / 2, page.width - fw / 2);\n const cy = clampScalar(center.y, fh / 2, page.height - fh / 2);\n return { x: cx - width / 2, y: cy - height / 2, width, height };\n}\n\n/** Reset a geom to its as-authored orientation (`rot → 0`). Box: drop `rot`.\n * Vertex: spin the points by `-rot` about their centroid so they return to the\n * orientation they were drawn at, in place. */\nexport function geomResetRotation(g: Geom): Geom {\n const rot = geomRotation(g);\n if (!rot) return g;\n if (g.t === 'rect' || g.t === 'text') return { ...g, rot: 0 };\n const c = centroidOf(g);\n const rotated = geomRotateAbout(g, c, -rot);\n // geomRotateAbout already set rot = normalize(rot - rot) = 0.\n return rotated;\n}\n\n/**\n * The oriented selection box (OBB) of a rotatable geom: four corners (in order\n * nw, ne, se, sw of the LOCAL box, transformed) + the angle. For a box this is\n * the `rect` rotated about its centre; for a vertex shape it is reconstructed\n * from the advisory `rot` — un-rotate the points to recover the as-authored\n * shape, take that tight local box, then rotate it back — giving the snug tilted\n * rectangle. Returns null for non-rotatable kinds.\n */\nexport function obbFromGeom(\n g: Geom,\n strokeWidth: number,\n border?: Border,\n): { corners: [Vec, Vec, Vec, Vec]; angle: number } | null {\n if (!isRotatableGeom(g)) return null;\n const rot = geomRotation(g);\n if (g.t === 'rect' || g.t === 'text') {\n const c = rectCenter(g.rect);\n const corners = rectCornerPoints(g.rect).map((p) => rotatePoint(p, c, rot));\n return { corners: corners as [Vec, Vec, Vec, Vec], angle: rot };\n }\n // vertex: reconstruct the local (as-authored) box from rot about the centroid.\n const c = centroidOf(g);\n const unrotated = rot ? geomRotateAbout(g, c, -rot) : g;\n const localBox = selectionBounds(unrotated, strokeWidth, border);\n const corners = rectCornerPoints(localBox).map((p) => rotatePoint(p, c, rot));\n return { corners: corners as [Vec, Vec, Vec, Vec], angle: rot };\n}\n\n/* ── group (multi-target) scaling ─────────────────────────────────────────────\n * A multi-selection scales as one box about a fixed anchor (the opposite handle\n * corner/edge). Resize is ANISOTROPIC only when every member has `rot == 0`\n * (otherwise an off-axis scale would shear a rotated shape it can't represent —\n * so we fall back to a uniform scale). The iso/aniso choice is decided by the\n * caller (it needs the live selection); these helpers take the resolved factors.\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/** The 8 box resize handles (corner + edge, with cursors) of a plain rect — used\n * for the multi-target group box. */\nexport function rectHandlesFor(r: Rect): Handle[] {\n return RECT_HANDLES.map((h) => ({ id: h, at: rectHandlePoint(r, h), cursor: RECT_CURSOR[h] }));\n}\n\n/** The fixed point of a group resize: the OPPOSITE handle's point on the box. */\nexport function groupResizeAnchor(base: Rect, handle: string): Vec {\n return rectHandlePoint(base, OPPOSITE_HANDLE[handle as RectHandle] ?? 'nw');\n}\n\n/**\n * The live group resize box for a drag. Anisotropic = the plain axis-aligned\n * `resizeRect`; isotropic = a uniform scale of `base` about the anchor by the\n * larger of the two drag ratios (so the preview matches the committed scale and\n * never shears a rotated member).\n */\nexport function groupResizeBox(base: Rect, handle: string, to: Vec, isotropic: boolean): Rect {\n const raw = resizeRect(base, handle as RectHandle, to);\n if (!isotropic) return raw;\n const sx = base.width > 0 ? raw.width / base.width : 1;\n const sy = base.height > 0 ? raw.height / base.height : 1;\n const s = Math.max(MIN_SIZE / Math.max(base.width, base.height, 1), Math.max(sx, sy));\n const anchor = groupResizeAnchor(base, handle);\n return {\n x: anchor.x + (base.x - anchor.x) * s,\n y: anchor.y + (base.y - anchor.y) * s,\n width: base.width * s,\n height: base.height * s,\n };\n}\n\n/** The (sx, sy) factors a `base`→`cur` group resize applied about its anchor. */\nexport function groupResizeFactors(base: Rect, cur: Rect): { sx: number; sy: number } {\n return {\n sx: base.width > 0 ? cur.width / base.width : 1,\n sy: base.height > 0 ? cur.height / base.height : 1,\n };\n}\n\n/**\n * Scale a geom about `anchor` by `(sx, sy)`. For a rotated box (iso scale, so\n * `sx === sy`) the unrotated `rect` is scaled about the anchor and `rot` is\n * preserved (a uniform scale commutes with rotation). For unrotated members\n * (the anisotropic case) every point/extent scales directly.\n */\nexport function geomScaleAbout(g: Geom, anchor: Vec, sx: number, sy: number): Geom {\n const sp = (p: Vec): Vec => ({\n x: anchor.x + (p.x - anchor.x) * sx,\n y: anchor.y + (p.y - anchor.y) * sy,\n });\n if (g.t === 'rect' || g.t === 'text') {\n if (g.t === 'text' && g.callout) return g;\n const c = sp(rectCenter(g.rect));\n const w = Math.max(MIN_SIZE, g.rect.width * Math.abs(sx));\n const h = Math.max(MIN_SIZE, g.rect.height * Math.abs(sy));\n return { ...g, rect: { x: c.x - w / 2, y: c.y - h / 2, width: w, height: h } };\n }\n if (g.t === 'line') return { ...g, a: sp(g.a), b: sp(g.b) };\n if (g.t === 'poly') return { ...g, points: g.points.map(sp) };\n if (g.t === 'ink') return { ...g, strokes: g.strokes.map((s) => s.map(sp)) };\n if (g.t === 'caret') {\n const c = sp(rectCenter(g.rect));\n const w = Math.max(MIN_SIZE, g.rect.width * Math.abs(sx));\n const h = Math.max(MIN_SIZE, g.rect.height * Math.abs(sy));\n return { ...g, rect: { x: c.x - w / 2, y: c.y - h / 2, width: w, height: h } };\n }\n return g; // quads scale with their points\n}\n\n/** Where the rotate knob sits, given the OBB corners (nw, ne, se, sw) and the\n * outward offset (content units). `from` is the top-edge midpoint the connector\n * stalk anchors to; `at` is the grab dot, offset along the outward normal. */\nexport function rotateKnob(corners: [Vec, Vec, Vec, Vec], offset: number): { at: Vec; from: Vec } {\n const [nw, ne, , sw] = corners;\n const from = { x: (nw.x + ne.x) / 2, y: (nw.y + ne.y) / 2 };\n // outward normal = from the bottom edge toward the top edge (away from shape).\n const down = { x: sw.x - nw.x, y: sw.y - nw.y };\n const len = Math.hypot(down.x, down.y) || 1;\n const up = { x: -down.x / len, y: -down.y / len };\n return { at: { x: from.x + up.x * offset, y: from.y + up.y * offset }, from };\n}\n\nconst insideRect = (r: Rect, p: Vec): boolean =>\n p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height;\n\n/**\n * The chord of `box` cut by the infinite line through `p` at `angleDeg` (CW,\n * y-down) — the full-bleed rotation guide: no magic lengths, the line simply\n * spans the page. Slab-clipped (Liang–Barsky); null when the line misses the\n * box entirely (a far-off-page pivot).\n */\nexport function chordThrough(box: Rect, p: Vec, angleDeg: number): { a: Vec; b: Vec } | null {\n const d = { x: Math.cos(angleDeg * DEG2RAD), y: Math.sin(angleDeg * DEG2RAD) };\n let tMin = -Infinity;\n let tMax = Infinity;\n for (const [dc, pc, lo, hi] of [\n [d.x, p.x, box.x, box.x + box.width],\n [d.y, p.y, box.y, box.y + box.height],\n ] as const) {\n if (Math.abs(dc) < 1e-12) {\n if (pc < lo || pc > hi) return null; // parallel outside the slab\n continue;\n }\n const t1 = (lo - pc) / dc;\n const t2 = (hi - pc) / dc;\n tMin = Math.max(tMin, Math.min(t1, t2));\n tMax = Math.min(tMax, Math.max(t1, t2));\n }\n if (tMin >= tMax || !Number.isFinite(tMin) || !Number.isFinite(tMax)) return null;\n return {\n a: { x: p.x + d.x * tMin, y: p.y + d.y * tMin },\n b: { x: p.x + d.x * tMax, y: p.y + d.y * tMax },\n };\n}\n\n/**\n * `rotateKnob` with a TOTAL page-bound placement policy: annotations, gestures\n * and chrome are all page-bound, so the grab dot must land inside `pageBox` —\n * off-page it is unreachable (the pointer dispatch resolves pages by\n * containment). Policy: top edge (the default) → FLIP to the bottom edge when\n * the stalk exits the page → CLAMP the top candidate inside (degenerate: the\n * selection spans ~the whole page; the knob may then overlap the shape, and\n * hit-testing checks it first so it stays grabbable). Both render (`chrome`)\n * and hit-test (`hitTest`) place the knob through THIS function, so what you\n * see is what you can grab — by construction. No `pageBox` → the raw knob.\n */\nexport function placeRotateKnob(\n corners: [Vec, Vec, Vec, Vec],\n offset: number,\n pageBox?: Rect,\n): { at: Vec; from: Vec } {\n const top = rotateKnob(corners, offset);\n if (!pageBox || insideRect(pageBox, top.at)) return top;\n // FLIP: the same outward-normal math off the OPPOSITE (bottom) edge. On a\n // rotated OBB this exits through whichever page edge the stalk crossed.\n const [nw, , se, sw] = corners;\n const from = { x: (sw.x + se.x) / 2, y: (sw.y + se.y) / 2 };\n const down = { x: sw.x - nw.x, y: sw.y - nw.y };\n const len = Math.hypot(down.x, down.y) || 1;\n const at = {\n x: from.x + (down.x / len) * offset,\n y: from.y + (down.y / len) * offset,\n };\n if (insideRect(pageBox, at)) return { at, from };\n return {\n at: {\n x: Math.min(Math.max(top.at.x, pageBox.x), pageBox.x + pageBox.width),\n y: Math.min(Math.max(top.at.y, pageBox.y), pageBox.y + pageBox.height),\n },\n from: top.from,\n };\n}\n\n/* ── callout leader ───────────────────────────────────────────────────────────\n * A free-text callout draws a 2–3 point leader (`/CL`) from the called-out `tip`\n * to the text box, with an arrow (`/LE`) at the tip. The point where the leader\n * meets the box is DERIVED — never stored — so it tracks the box and knee.\n */\n\n/** The box-edge midpoint the leader connects to: the side `ref` (the knee, else\n * the tip) points toward, by horizontal/vertical dominance vs the box centre.\n * With `rot` (a callout box tilted by the upright policy) the decision runs in\n * the box's LOCAL frame and the midpoint lands back on the ROTATED edge — the\n * edge the user actually sees. Mirror of v2's `computeCalloutConnectionPoint`. */\nexport function calloutConnection(box: Rect, ref: Vec, rot = 0): Vec {\n if (rot) {\n const c = rectCenter(box);\n return rotatePoint(calloutConnection(box, rotatePoint(ref, c, -rot)), c, rot);\n }\n const cx = box.x + box.width / 2;\n const cy = box.y + box.height / 2;\n const dx = ref.x - cx;\n const dy = ref.y - cy;\n if (Math.abs(dx) >= Math.abs(dy)) {\n return dx >= 0 ? { x: box.x + box.width, y: cy } : { x: box.x, y: cy };\n }\n return dy >= 0 ? { x: cx, y: box.y + box.height } : { x: cx, y: box.y };\n}\n\n/** The leader polyline `[tip, knee?, conn]`, with `conn` derived from the box\n * (its ROTATED footprint when the box carries `rot`). */\nexport function calloutLinePoints(g: Extract<Geom, { t: 'text' }>): Vec[] {\n const c = g.callout;\n if (!c) return [];\n const conn = calloutConnection(g.rect, c.knee ?? c.tip, g.rot ?? 0);\n return c.knee ? [c.tip, c.knee, conn] : [c.tip, conn];\n}\n\n/** The leader's single ending segment (arrow at the tip), pointing OUT of the\n * body into the tip — so the arrowhead opens back along the leader. */\nfunction calloutEndingSeg(pts: Vec[], ending: LineEnding): EndingSeg | null {\n if (pts.length < 2) return null;\n return {\n tip: pts[0],\n angle: Math.atan2(pts[0].y - pts[1].y, pts[0].x - pts[1].x),\n ending,\n };\n}\n\n/** Shrink a rect inward by `pad` on every side, staying centred and never\n * collapsing past zero (a thick stroke on a tiny shape just yields a 0-extent\n * path rather than an inverted one). The inverse of `expandRect` for shapes. */\nconst insetRect = (r: Rect, pad: number): Rect => {\n const width = Math.max(0, r.width - 2 * pad);\n const height = Math.max(0, r.height - 2 * pad);\n return { x: r.x + (r.width - width) / 2, y: r.y + (r.height - height) / 2, width, height };\n};\n\n/**\n * The stored `rect` for a freshly-drawn shape, given the box the user dragged. A\n * cloudy border stores the OUTER box (dragged + cloud extent), so the dragged box\n * is its inner edge and the scallops bulge out to the stored box — just like a\n * solid shape, whose /Rect is the dragged box. So `g.rect` is ALWAYS the outer box;\n * the cloud-vs-solid difference lives only here, at creation.\n */\nexport function shapeRectFor(dragged: Rect, ellipse: boolean, style: Style): Rect {\n return style.border.kind === 'cloudy'\n ? expandRect(dragged, cloudyBorderExtent(style.border.intensity, style.strokeWidth, ellipse))\n : dragged;\n}\n\nexport function caretRectFromTextEnd(lineRect: Rect): Rect {\n const height = lineRect.height / 2;\n const width = height;\n const lineEndX = lineRect.x + lineRect.width;\n return {\n x: lineEndX - width / 2,\n y: lineRect.y + lineRect.height / 2,\n width,\n height,\n };\n}\n\n/* ── line endings ─────────────────────────────────────────────────────────────\n * The breathing room a stroked line/poly needs beyond its vertices, as a factor\n * of the stroke width (matches v2): the half-stroke under the centre-line plus a\n * little extra so caps/joins are never clipped by the engine `/Rect`.\n */\n/** Miter limit shared by the bounds math AND the SVG renderer (`stroke-miterlimit`),\n * so the computed box and the drawn stroke always agree on where a sharp join\n * bevels instead of spiking. 10 = the PDF default (also what the baked /AP uses). */\nexport const MITER_LIMIT = 10;\n\n/**\n * The outline points of a mitred, butt-capped polyline (open or closed) stroked\n * at `strokeWidth`: each segment's two side offsets (the straight extents + both\n * bevel corners) PLUS each interior join's OUTER miter tip — added only while the\n * join is within `MITER_LIMIT` (past that the renderer bevels it, and the segment\n * offsets already bound it). `unionRect` of these is the tight, ASYMMETRIC visual\n * box: a pointy join grows the box only on the side it actually spikes.\n *\n * Miter kinds only (line / polyline / polygon). Ink is round-capped/round-joined,\n * never spikes, and is bounded elsewhere by a plain `h` grow.\n */\nfunction strokeOutlinePoints(pts: Vec[], closed: boolean, strokeWidth: number): Vec[] {\n const h = strokeWidth / 2;\n const n = pts.length;\n if (n === 0) return [];\n if (n === 1 || h === 0) return [...pts];\n\n const segCount = closed ? n : n - 1;\n const dir: Vec[] = [];\n const nrm: Vec[] = [];\n for (let i = 0; i < segCount; i++) {\n const a = pts[i];\n const b = pts[(i + 1) % n];\n const len = Math.hypot(b.x - a.x, b.y - a.y) || 1;\n const ux = (b.x - a.x) / len;\n const uy = (b.y - a.y) / len;\n dir.push({ x: ux, y: uy });\n nrm.push({ x: -uy, y: ux }); // a unit normal (either side; sign is re-picked below)\n }\n\n const out: Vec[] = [];\n // Segment side offsets at both ends — covers the straight extents, the butt\n // caps at open ends, and the bevel corners of any beveled join.\n for (let i = 0; i < segCount; i++) {\n const a = pts[i];\n const b = pts[(i + 1) % n];\n const nx = nrm[i].x * h;\n const ny = nrm[i].y * h;\n out.push({ x: a.x + nx, y: a.y + ny }, { x: a.x - nx, y: a.y - ny });\n out.push({ x: b.x + nx, y: b.y + ny }, { x: b.x - nx, y: b.y - ny });\n }\n\n // Interior joins: the outer miter tip, gated by the miter limit.\n const joinStart = closed ? 0 : 1;\n const joinEnd = closed ? n : n - 1; // vertices [joinStart, joinEnd)\n for (let v = joinStart; v < joinEnd; v++) {\n const inIdx = closed ? (v - 1 + n) % n : v - 1;\n const outIdx = closed ? v : v; // segment starting at v\n const a = dir[inIdx]; // prev -> v\n const b = dir[outIdx]; // v -> next\n const n1 = nrm[inIdx];\n const n2 = nrm[outIdx];\n // Outer bisector direction: opposite the interior bisector `b - a`.\n const bx = a.x - b.x;\n const by = a.y - b.y;\n if (Math.hypot(bx, by) < 1e-9) continue; // straight run: no spike beyond the offsets\n let mhx = n1.x + n2.x;\n let mhy = n1.y + n2.y;\n const ml = Math.hypot(mhx, mhy);\n if (ml < 1e-9) continue; // exact hairpin: renderer bevels\n mhx /= ml;\n mhy /= ml;\n if (mhx * bx + mhy * by < 0) {\n mhx = -mhx; // point the miter unit vector to the OUTER side\n mhy = -mhy;\n }\n const cosHalf = Math.abs(mhx * n1.x + mhy * n1.y); // cos(deviation/2)\n if (cosHalf < 1e-9) continue;\n const miterLen = h / cosHalf;\n if (miterLen > MITER_LIMIT * h) continue; // too sharp: renderer bevels → offsets bound it\n const V = pts[v];\n out.push({ x: V.x + mhx * miterLen, y: V.y + mhy * miterLen });\n }\n return out;\n}\n\ntype EndingSeg = { tip: Vec; angle: number; ending: LineEnding | undefined };\n\n/** The start/end tips of a line / open poly, each with the segment angle pointing\n * OUT of the body into the tip (so an arrowhead opens back toward the line). */\nfunction endingSegs(g: Geom): EndingSeg[] {\n if (g.t === 'line' && g.ends) {\n return [\n { tip: g.a, angle: Math.atan2(g.a.y - g.b.y, g.a.x - g.b.x), ending: g.ends.start },\n { tip: g.b, angle: Math.atan2(g.b.y - g.a.y, g.b.x - g.a.x), ending: g.ends.end },\n ];\n }\n if (g.t === 'poly' && !g.closed && g.ends && g.points.length >= 2) {\n const p = g.points;\n const n = p.length;\n return [\n { tip: p[0], angle: Math.atan2(p[0].y - p[1].y, p[0].x - p[1].x), ending: g.ends.start },\n {\n tip: p[n - 1],\n angle: Math.atan2(p[n - 1].y - p[n - 2].y, p[n - 1].x - p[n - 2].x),\n ending: g.ends.end,\n },\n ];\n }\n return [];\n}\n\n/**\n * A geom's VISUAL bounds: the rect that encloses the drawn appearance, so the\n * baked /AP is never clipped and the selection outline wraps exactly what's drawn.\n *\n * A shape's `rect` IS its visual box (the PDF /Rect): solid/dashed strokes draw\n * inside it, and a cloudy border's scallops also inset back into it (the dragged\n * inner edge sits `/RD` in from it — see `shapeRectFor`). So growing the stroke or\n * the cloud thickens inward, never spilling past the handles. Lines / polylines /\n * ink have no box, so they expand by the stroke (+ endings) — the SAME math feeds\n * `geomScene`, so the visual box and what's drawn always agree.\n *\n * `border` matters for ONE case: a CLOSED poly with a cloudy border, whose curls\n * are centred on the vertex path and reach OUTWARD (there is no outer box to\n * inset into) — the bounds grow by the cloud extent, and the engine `/Rect`\n * (via `geomPdfBounds`) grows with them so the baked scallops are never clipped.\n */\nexport function geomVisualBounds(g: Geom, strokeWidth: number, border?: Border): Rect {\n if (g.t === 'poly' && g.closed && border?.kind === 'cloudy') {\n // Corner curls are arcs of the cloud radius centred at the vertices, and the\n // stroke straddles them — so ink reaches radius + strokeWidth/2 beyond the\n // vertex hull on every side: exactly `cloudyBorderExtent`.\n return expandRect(\n unionRect(g.points),\n cloudyBorderExtent(border.intensity, strokeWidth, false),\n );\n }\n if (g.t === 'text' && g.callout) {\n // The overall /Rect: the union of the text box (its ROTATED corners when the\n // box carries an upright tilt), the leader points, and the arrow-ending\n // polygon at the tip (same ending math as line/poly).\n const pts = calloutLinePoints(g);\n const seg = calloutEndingSeg(pts, g.callout.ending);\n const rot = g.rot ?? 0;\n const c = rectCenter(g.rect);\n const corners = rectCornerPoints(g.rect).map((p) => (rot ? rotatePoint(p, c, rot) : p));\n const all = [...corners, ...pts];\n if (seg) all.push(...endingPoints(seg.tip, seg.angle, seg.ending, strokeWidth));\n return expandRect(unionRect(all), strokeWidth / 2);\n }\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return g.rect;\n if (g.t === 'quads') return expandRect(unionRect(g.quads.flat()), strokeWidth / 2);\n // Ink is round-capped/round-joined: it never spikes, so a plain `h` grow of the\n // freehand hull is exact — left as-is (the freehand look must not change).\n if (g.t === 'ink') return expandRect(unionRect(g.strokes.flat()), strokeWidth / 2);\n // Line / polyline / polygon: the miter kinds. Wrap the ACTUAL stroke outline\n // (per-join, asymmetric) instead of a flat pad — for the body AND each ending,\n // so a mitred arrowhead tip is enclosed exactly (not under-covered by a flat h).\n const raw = g.t === 'line' ? [g.a, g.b] : g.points;\n const closed = g.t === 'poly' && g.closed;\n const pts = strokeOutlinePoints(raw, closed, strokeWidth);\n for (const seg of endingSegs(g)) {\n for (const node of endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth)) {\n if (node.kind === 'poly') {\n // arrowheads / diamonds / squares are stroked polys: their sharp corners\n // miter exactly like the body, so wrap the real outline (tip included).\n pts.push(...strokeOutlinePoints(node.points, node.closed, strokeWidth));\n } else if (node.kind === 'ellipse') {\n // a stroked ellipse (circle ending) grows uniformly by h — no miters.\n pts.push(...rectCornerPoints(expandRect(node.rect, strokeWidth / 2)));\n }\n }\n }\n return unionRect(pts);\n}\n\n/**\n * The rect the SELECTION wraps — and the region a SELECTED annotation can be grabbed\n * from. Centre-line geometries (line / polyline / polygon / ink) straddle their path,\n * so this is their VISUAL bounds (the join-aware stroke outline + endings) — a\n * polygon's outline wraps its stroke exactly like a polyline. Box kinds (square /\n * circle / free-text) sit tight on their `rect` (their stroke draws INSIDE the box,\n * so the 8 resize handles land on the corners). The chrome outline AND the selected\n * hit-test both call this, so what you see highlighted is exactly what you can grab —\n * they can never drift.\n */\nexport function selectionBounds(g: Geom, strokeWidth: number, border?: Border): Rect {\n if (g.t === 'line' || g.t === 'ink' || g.t === 'poly')\n return geomVisualBounds(g, strokeWidth, border);\n // A callout's tilted text box (the upright policy): the selection wraps the box\n // the user SEES — its rotated footprint. Exact for the quarter-turns upright\n // produces (the footprint stays axis-aligned), so outline and handles agree.\n if (g.t === 'text' && g.callout && (g.rot ?? 0) !== 0) return rotatedAabb(g.rect, g.rot!);\n return geomBounds(g);\n}\n\n/**\n * The four corners of the ORIENTED selection box — the SAME quad `chrome` draws.\n * For a rotatable kind this is the OBB (the tilted box, from `obbFromGeom`); at\n * `rot == 0` those are just the axis-aligned corners of `selectionBounds`, and\n * for non-rotatable kinds (markup quads, callouts) it falls back to the rect\n * corners. The grab region, the floating-menu anchor and the multi/group union\n * all consume this, so what you can grab / where the menu sits never drifts from\n * the outline you see.\n */\nexport function selectionQuad(g: Geom, strokeWidth: number, border?: Border): [Vec, Vec, Vec, Vec] {\n const obb = obbFromGeom(g, strokeWidth, border);\n if (obb) return obb.corners;\n return rectCornerPoints(selectionBounds(g, strokeWidth, border)) as [Vec, Vec, Vec, Vec];\n}\n\n/** Is the point inside the (convex) selection quad? Even-odd ring test. */\nexport const pointInQuad = (p: Vec, quad: [Vec, Vec, Vec, Vec]): boolean => pointInPoly(p, quad);\n\n/**\n * Does the (convex) selection quad intersect an axis-aligned rect? Separating\n * axis test on the only four candidate axes — the rect's x/y plus the quad's\n * two edge normals; a gap on any axis proves disjoint, otherwise they overlap\n * (touching counts). This is the marquee's predicate: it must catch a tilted\n * shape by the ORIENTED box that is actually drawn — the AABB of that quad has\n * empty corners covering most of the unrotated footprint, so testing it selects\n * shapes the marquee never touched. At `rot 0` the quad is axis-aligned and\n * this degenerates to exactly `rectsIntersect`.\n */\nexport function quadIntersectsRect(quad: [Vec, Vec, Vec, Vec], r: Rect): boolean {\n const rectPts = rectCornerPoints(r);\n const axes: Vec[] = [\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -(quad[1].y - quad[0].y), y: quad[1].x - quad[0].x },\n { x: -(quad[3].y - quad[0].y), y: quad[3].x - quad[0].x },\n ];\n for (const ax of axes) {\n if (Math.abs(ax.x) < 1e-12 && Math.abs(ax.y) < 1e-12) continue; // degenerate edge\n let qLo = Infinity;\n let qHi = -Infinity;\n for (const p of quad) {\n const d = p.x * ax.x + p.y * ax.y;\n qLo = Math.min(qLo, d);\n qHi = Math.max(qHi, d);\n }\n let rLo = Infinity;\n let rHi = -Infinity;\n for (const p of rectPts) {\n const d = p.x * ax.x + p.y * ax.y;\n rLo = Math.min(rLo, d);\n rHi = Math.max(rHi, d);\n }\n if (qHi < rLo || rHi < qLo) return false; // separated on this axis\n }\n return true;\n}\n\n/**\n * The centre of the ORIENTED selection box — the middle of the rect you see.\n * For box kinds this is the rect centre (so squares/circles are unchanged); for\n * vertex kinds it is the OBB centre, so rotation spins the shape in place rather\n * than swinging it about the off-centre vertex mean (`centroidOf`).\n */\nexport function selectionCenter(g: Geom, strokeWidth: number): Vec {\n const q = selectionQuad(g, strokeWidth);\n return {\n x: (q[0].x + q[1].x + q[2].x + q[3].x) / 4,\n y: (q[0].y + q[1].y + q[2].y + q[3].y) / 4,\n };\n}\n\n/**\n * Is the content point ON a line/poly's drawn ENDINGS — so an arrowhead is as\n * clickable as the stroke. Uses the SAME ending nodes the renderer draws: a closed\n * shape (closed arrow, circle, square, diamond) hits inside OR near its edge; an\n * open one (open arrow, butt, slash) hits near its stroke. `tol` is the stroke\n * band already widened by the hit margin.\n */\nfunction endingNodesHit(nodes: RenderNode[], p: Vec, tol: number): boolean {\n for (const node of nodes) {\n if (node.kind === 'ellipse') {\n const r = node.rect;\n const rx = r.width / 2;\n const ry = r.height / 2;\n if (rx <= 0 || ry <= 0) continue;\n const nx = (p.x - (r.x + rx)) / rx;\n const ny = (p.y - (r.y + ry)) / ry;\n if (Math.hypot(nx, ny) <= 1 + tol / Math.min(rx, ry)) return true; // filled disc + band\n } else if (node.kind === 'poly') {\n const pts = node.points;\n for (let i = 0; i < pts.length - 1; i++)\n if (segDist(p, pts[i], pts[i + 1]) <= tol) return true;\n if (node.closed) {\n if (pts.length > 2 && segDist(p, pts[pts.length - 1], pts[0]) <= tol) return true;\n if (pointInPoly(p, pts)) return true; // filled head interior\n }\n }\n }\n return false;\n}\n\nfunction endingHit(g: Geom, p: Vec, tol: number, strokeWidth: number): boolean {\n for (const seg of endingSegs(g))\n if (endingNodesHit(endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth), p, tol))\n return true;\n return false;\n}\n\n/* ── geom ops ─────────────────────────────────────────────────────────────── */\n\nexport function geomBounds(g: Geom): Rect {\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return g.rect;\n if (g.t === 'line') return rectFromPoints(g.a, g.b);\n if (g.t === 'poly') return unionRect(g.points);\n if (g.t === 'ink') return unionRect(g.strokes.flat());\n return unionRect(g.quads.flat());\n}\n\n/**\n * Is the content point ON the annotation: within `margin` of the stroke, or\n * inside the fill (when `filled`). The stroke band widens with the stroke width.\n *\n * A shape's stroke is drawn INSIDE its box, centred on `insetRect(rect, sw/2)`\n * (see `geomScene`), so the clickable band follows that inset centre-line — not\n * the box edge. The fill still reaches the box. (Cloudy scallops aren't modelled\n * here; with their typically thin stroke the inset is sub-pixel, so this matches.)\n */\nexport function geomHit(\n g: Geom,\n p: Vec,\n margin: number,\n filled: boolean,\n strokeWidth: number,\n): boolean {\n const tol = margin + strokeWidth / 2;\n // A rotated box stores its UNROTATED `rect`; inverse-rotate the pointer into\n // that local frame and run the normal axis-aligned tests. Vertex kinds carry\n // already-rotated points, so they hit-test directly (rot is advisory). A\n // callout is COMPOUND: only its box rotates (the leader is page-space), so the\n // inverse rotation applies to the box test alone — see the text branch below.\n if ((g.t === 'rect' || (g.t === 'text' && !g.callout)) && (g.rot ?? 0) !== 0) {\n p = rotatePoint(p, rectCenter(g.rect), -(g.rot ?? 0));\n }\n // A text box is a solid hit target anywhere inside it (+ the click margin).\n if (g.t === 'caret') return rectContains(expandRect(g.rect, margin), p);\n if (g.t === 'text') {\n // Box test in the box's LOCAL frame (a tilted callout box); leader/arrow\n // tests in the PAGE frame (their points are already where they're drawn).\n const rot = g.callout ? (g.rot ?? 0) : 0;\n const pBox = rot ? rotatePoint(p, rectCenter(g.rect), -rot) : p;\n if (rectContains(expandRect(g.rect, margin), pBox)) return true;\n if (g.callout) {\n const pts = calloutLinePoints(g);\n for (let i = 0; i < pts.length - 1; i++)\n if (segDist(p, pts[i], pts[i + 1]) <= tol) return true;\n const seg = calloutEndingSeg(pts, g.callout.ending);\n if (seg && endingNodesHit(endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth), p, tol))\n return true;\n }\n return false;\n }\n if (g.t === 'rect') {\n const r = g.rect;\n if (g.ellipse) {\n const cx = r.x + r.width / 2;\n const cy = r.y + r.height / 2;\n const orx = r.width / 2; // outer (box) radii — the fill reaches here\n const ory = r.height / 2;\n if (orx <= 0 || ory <= 0) return false;\n if (filled && Math.hypot((p.x - cx) / orx, (p.y - cy) / ory) <= 1) return true;\n // stroke band centred on the inset path (its outer edge sits on the box)\n const rx = Math.max(0.01, orx - strokeWidth / 2);\n const ry = Math.max(0.01, ory - strokeWidth / 2);\n const d = Math.hypot((p.x - cx) / rx, (p.y - cy) / ry);\n const band = tol / Math.min(rx, ry); // approximate normalized stroke band\n return Math.abs(d - 1) <= band;\n }\n if (filled && rectContains(r, p)) return true;\n // near any of the 4 edges of the inset (drawn) rectangle\n const c = insetRect(r, strokeWidth / 2);\n const edges: [Vec, Vec][] = [\n [\n { x: c.x, y: c.y },\n { x: c.x + c.width, y: c.y },\n ],\n [\n { x: c.x + c.width, y: c.y },\n { x: c.x + c.width, y: c.y + c.height },\n ],\n [\n { x: c.x + c.width, y: c.y + c.height },\n { x: c.x, y: c.y + c.height },\n ],\n [\n { x: c.x, y: c.y + c.height },\n { x: c.x, y: c.y },\n ],\n ];\n return edges.some(([a, b]) => segDist(p, a, b) <= tol);\n }\n if (g.t === 'line') return segDist(p, g.a, g.b) <= tol || endingHit(g, p, tol, strokeWidth);\n if (g.t === 'poly') {\n if (filled && g.closed && pointInPoly(p, g.points)) return true;\n const pts = g.points;\n const n = pts.length;\n for (let i = 0; i < n - 1; i++) if (segDist(p, pts[i], pts[i + 1]) <= tol) return true;\n if (g.closed && n > 2 && segDist(p, pts[n - 1], pts[0]) <= tol) return true;\n return endingHit(g, p, tol, strokeWidth);\n }\n if (g.t === 'ink') {\n // near any segment of any stroke (ink is stroke-only, never filled)\n for (const stroke of g.strokes)\n for (let i = 0; i < stroke.length - 1; i++)\n if (segDist(p, stroke[i], stroke[i + 1]) <= tol) return true;\n return false;\n }\n // quads (markup): axis-aligned per-line rects — hit anywhere inside any quad.\n // (Use the quad's bbox: robust to the PDF /QuadPoints corner order, which is\n // UL,UR,LL,LR — a self-intersecting ring for a generic point-in-poly test.)\n return g.quads.some((q) => rectContains(unionRect(q), p));\n}\n\nexport function geomHandles(g: Geom): Handle[] {\n if (g.t === 'rect' || g.t === 'text') {\n const rot = g.rot ?? 0;\n const c = rectCenter(g.rect);\n const handles: Handle[] = RECT_HANDLES.map((h) => ({\n id: h,\n // box handles sit on the UNROTATED rect; rotate each into place so they\n // ride the tilted box. The cursor rotates WITH the handle (the visually\n // right-edge handle of a 90°-tilted box resizes horizontally).\n at: rot ? rotatePoint(rectHandlePoint(g.rect, h), c, rot) : rectHandlePoint(g.rect, h),\n cursor: rotatedHandleCursor(h, rot),\n }));\n // A callout adds vertex handles for the leader tip and (if present) knee, so\n // the called-out point and the elbow can be dragged independently of the box.\n if (g.t === 'text' && g.callout) {\n handles.push({ id: 'callout-tip', at: g.callout.tip, cursor: 'crosshair' });\n if (g.callout.knee)\n handles.push({ id: 'callout-knee', at: g.callout.knee, cursor: 'crosshair' });\n }\n return handles;\n }\n if (g.t === 'line') {\n return [\n { id: 'v0', at: g.a, cursor: 'crosshair' },\n { id: 'v1', at: g.b, cursor: 'crosshair' },\n ];\n }\n if (g.t === 'poly') {\n return g.points.map((at, i) => ({ id: `v${i}`, at, cursor: 'crosshair' }));\n }\n return []; // markup: move only\n}\n\nexport function geomTranslate(g: Geom, d: Vec): Geom {\n const mv = (p: Vec): Vec => ({ x: p.x + d.x, y: p.y + d.y });\n if (g.t === 'text') {\n const rect = { ...g.rect, x: g.rect.x + d.x, y: g.rect.y + d.y };\n if (!g.callout) return { ...g, rect };\n return {\n ...g,\n rect,\n callout: {\n ...g.callout,\n tip: mv(g.callout.tip),\n knee: g.callout.knee ? mv(g.callout.knee) : undefined,\n },\n };\n }\n if (g.t === 'rect' || g.t === 'caret')\n return { ...g, rect: { ...g.rect, x: g.rect.x + d.x, y: g.rect.y + d.y } };\n if (g.t === 'line') return { ...g, a: mv(g.a), b: mv(g.b) };\n if (g.t === 'poly') return { ...g, points: g.points.map(mv) };\n if (g.t === 'ink') return { ...g, strokes: g.strokes.map((s) => s.map(mv)) };\n return { ...g, quads: g.quads.map((q) => q.map(mv) as Quad) };\n}\n\nconst OPPOSITE_HANDLE: Record<RectHandle, RectHandle> = {\n nw: 'se',\n ne: 'sw',\n se: 'nw',\n sw: 'ne',\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\n/**\n * Resize a ROTATED box by `handle`, keeping the opposite corner/edge fixed in\n * WORLD space. The pointer is mapped into the box's local (unrotated) frame, the\n * axis-aligned `resizeRect` runs there, then the new box is repositioned so the\n * anchor (the opposite handle's point) lands back where it was — and the box\n * still rotates about its OWN centre. With `rot === 0` this is exactly the plain\n * `resizeRect`.\n */\nfunction resizeRotatedRect(base: Rect, rot: number, handle: RectHandle, to: Vec): Rect {\n if (!rot) return resizeRect(base, handle, to);\n const c0 = rectCenter(base);\n const localTo = rotatePoint(to, c0, -rot);\n const next = resizeRect(base, handle, localTo);\n const anchorLocal = rectHandlePoint(base, OPPOSITE_HANDLE[handle]);\n const anchorWorld = rotatePoint(anchorLocal, c0, rot);\n const nextCenterLocal = rectCenter(next);\n // offset of the anchor from the new centre, in the local frame; rotate it to\n // world orientation and place the new centre so the anchor stays put.\n const offX = anchorLocal.x - nextCenterLocal.x;\n const offY = anchorLocal.y - nextCenterLocal.y;\n const rad = rot * DEG2RAD;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const rOffX = cos * offX - sin * offY;\n const rOffY = sin * offX + cos * offY;\n const cx = anchorWorld.x - rOffX;\n const cy = anchorWorld.y - rOffY;\n return {\n x: cx - next.width / 2,\n y: cy - next.height / 2,\n width: next.width,\n height: next.height,\n };\n}\n\nexport function geomDragHandle(g: Geom, handle: string, to: Vec): Geom {\n if (g.t === 'text') {\n if (handle === 'callout-tip' && g.callout) return { ...g, callout: { ...g.callout, tip: to } };\n if (handle === 'callout-knee' && g.callout)\n return { ...g, callout: { ...g.callout, knee: to } };\n return { ...g, rect: resizeRotatedRect(g.rect, g.rot ?? 0, handle as RectHandle, to) };\n }\n if (g.t === 'rect')\n return { ...g, rect: resizeRotatedRect(g.rect, g.rot ?? 0, handle as RectHandle, to) };\n if (g.t === 'line') return handle === 'v0' ? { ...g, a: to } : { ...g, b: to };\n if (g.t === 'poly') {\n const i = Number(handle.slice(1));\n if (!Number.isInteger(i) || i < 0 || i >= g.points.length) return g;\n const points = g.points.slice();\n points[i] = to;\n return { ...g, points };\n }\n return g;\n}\n\nexport function geomScene(g: Geom, strokeWidth = 0, border?: Border): RenderNode[] {\n // A plain text box draws no vector nodes — the framework renders its editable\n // element. A callout still draws its leader (open polyline) + arrow at the tip,\n // plus a stroke-only box border (the DOM owns the text + background).\n if (g.t === 'text') {\n if (!g.callout) return [];\n const pts = calloutLinePoints(g);\n const nodes: RenderNode[] = [{ kind: 'poly', points: pts, closed: false }];\n const seg = calloutEndingSeg(pts, g.callout.ending);\n if (seg) nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n if (strokeWidth > 0) {\n // A tilted box (the upright policy) draws as its rotated corner ring —\n // the scene stays plane-agnostic, so every framework painter gets the\n // tilt for free (the leader above is page-space and never rotates).\n const rot = g.rot ?? 0;\n const c = rectCenter(g.rect);\n nodes.push(\n rot\n ? {\n kind: 'poly',\n points: rectCornerPoints(g.rect).map((p) => rotatePoint(p, c, rot)),\n closed: true,\n }\n : { kind: 'rect', rect: g.rect },\n );\n }\n return nodes;\n }\n if (g.t === 'caret') {\n const r = g.rect;\n const midX = r.x + r.width / 2;\n const bottom = r.y + r.height;\n const d = [\n `M ${r.x} ${bottom}`,\n `C ${r.x + r.width * 0.27} ${bottom} ${midX} ${r.y + r.height * 0.56} ${midX} ${r.y}`,\n `C ${midX} ${r.y + r.height * 0.56} ${r.x + r.width * 0.73} ${bottom} ${r.x + r.width} ${bottom}`,\n 'Z',\n ].join(' ');\n return [{ kind: 'path', d }];\n }\n if (g.t === 'rect') {\n // A cloudy border's scallops inset back into `g.rect` (the OUTER box): the troughs\n // land at the dragged inner edge (`g.rect` − extent) and the peaks on `g.rect`.\n // Only drawn when the box can hold them — a box smaller than 2× the inset (e.g.\n // a 0-drag, or after cranking intensity) falls through to the plain outline.\n if (border?.kind === 'cloudy') {\n const inset = cloudyBorderExtent(border.intensity, strokeWidth, g.ellipse);\n if (g.rect.width > 2 * inset && g.rect.height > 2 * inset) {\n return [{ kind: 'path', d: cloudyPath(g.rect, g.ellipse, border.intensity, strokeWidth) }];\n }\n }\n // Otherwise the stroke sits INSIDE the box: inset the drawn path by half the\n // stroke so its outer edge lands on `g.rect`, not straddling it.\n const r = insetRect(g.rect, strokeWidth / 2);\n return [g.ellipse ? { kind: 'ellipse', rect: r } : { kind: 'rect', rect: r }];\n }\n if (g.t === 'line') {\n const nodes: RenderNode[] = [{ kind: 'line', a: g.a, b: g.b }];\n for (const seg of endingSegs(g))\n nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n return nodes;\n }\n if (g.t === 'poly') {\n // A closed poly takes a cloudy border: curls centred on the vertex path,\n // reaching outward — the same geometry PDFium bakes (no /RD, unlike boxes).\n if (g.closed && border?.kind === 'cloudy' && g.points.length >= 3) {\n return [{ kind: 'path', d: cloudyPolyPath(g.points, border.intensity, strokeWidth) }];\n }\n const nodes: RenderNode[] = [{ kind: 'poly', points: g.points, closed: g.closed }];\n for (const seg of endingSegs(g))\n nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n return nodes;\n }\n if (g.t === 'ink') {\n // each pen stroke is an open polyline (stroke-only; `scene` paints it)\n return g.strokes.map((stroke) => ({ kind: 'poly', points: stroke, closed: false }));\n }\n // markup fallback: a closed ring per quad. Reorder UL,UR,LL,LR → UL,UR,LR,LL so\n // it's a simple (non-self-intersecting) rectangle. (The framework markup layer\n // renders these per-subtype; this keeps the generic scene correct regardless.)\n return g.quads.map((q) => ({ kind: 'poly', points: [q[0], q[1], q[3], q[2]], closed: true }));\n}\n\n/* ── PDF ↔ content bridge ─────────────────────────────────────────────────────\n * The ONE engine seam: PDF user space (y-up, crop bottom-left) ↔ content space\n * (y-down, crop top-left). The y-flip itself lives in `@embedpdf/core-geometry`\n * (`pdfToContentMatrix`) and is applied through its generic Mat2D primitives, so\n * this file never hand-rolls the rule. The only local work is bridging the\n * engine's edge-based `PdfRect` to geometry's corner+extent `RectIn`.\n * ──────────────────────────────────────────────────────────────────────────── */\n\nconst pdfRectToCorner = (r: PdfRect): RectIn<'pdf'> =>\n ({ x: r.left, y: r.bottom, width: r.right - r.left, height: r.top - r.bottom }) as RectIn<'pdf'>;\nconst cornerToPdfRect = (r: RectIn<'pdf'>): PdfRect => ({\n left: r.x,\n bottom: r.y,\n right: r.x + r.width,\n top: r.y + r.height,\n});\n\nexport const pdfToContentPoint = (p: PdfPoint, crop: PdfRect): Vec =>\n applyPoint(pdfToContentMatrix(crop), p as PointIn<'pdf'>);\nexport const contentToPdfPoint = (p: Vec, crop: PdfRect): PdfPoint =>\n applyPoint(invert(pdfToContentMatrix(crop)), p as PointIn<'content'>);\nexport const pdfToContentRect = (pdf: PdfRect, crop: PdfRect): Rect =>\n applyRect(pdfToContentMatrix(crop), pdfRectToCorner(pdf));\nexport const contentToPdfRect = (r: Rect, crop: PdfRect): PdfRect =>\n cornerToPdfRect(applyRect(invert(pdfToContentMatrix(crop)), r as RectIn<'content'>));\n\n/** A geom's VISUAL bounding box (geometry + stroke + line endings) as a PdfRect —\n * the engine requires an explicit `rect` that encloses the baked /AP. */\nexport const geomPdfBounds = (\n g: Geom,\n strokeWidth: number,\n crop: PdfRect,\n border?: Border,\n): PdfRect => contentToPdfRect(geomVisualBounds(g, strokeWidth, border), crop);\n","/**\n * Screen-anchored annotations — `noZoom` / `noRotate` (ISO 32000-2 §12.5.3).\n *\n * The mental model: these flags are DISPLAY-TRANSFORM EXEMPTIONS, nothing\n * more. The view composes content space onto the screen with\n * `zoom × pageRotation`; a flagged annotation asks it to skip the zoom factor\n * (`noZoom`) and/or the page-rotation factor (`noRotate`), holding the\n * `/Rect` upper-left — the geometry's bounds top-left — fixed on the page.\n *\n * The flags do NOT restrict editing. The annotation keeps its full\n * content-space identity: a size (`/Rect`, which now reads as \"screen size at\n * zoom 1\") and an authored orientation (`rot` / rotated points, which now\n * reads as \"screen tilt at every page rotation\") — and both stay editable.\n * Edit restrictions come from kind caps (a note kind declares\n * `resizable: false`) and `locked`, never from here.\n *\n * Everything derives from ONE projection, {@link anchoredGeom}: the effective\n * content-space geometry of the body at the current view — a similarity\n * (uniform scale `1/s` + rotation `-r`) about the anchor. Rendering,\n * hit-testing, chrome, marquee, and clamping all read it, so what you see,\n * what you click, and what commits can never disagree (the v2 failure: only\n * the DOM containers compensated).\n *\n * GESTURES compose in VIEW space: project first, then apply the gesture to\n * the projected geometry — for un-flagged annotations the projection is the\n * identity, so this is the ordinary pipeline. A pointer-driven commit maps\n * the final view-space geometry back to stored space through\n * {@link unanchoredGeom}, the exact closed-form inverse — chosen so that the\n * committed geometry's OWN re-projection reproduces the released preview\n * (zero release-jump, any zoom, any rotation).\n *\n * The core stays zoom-free: the view environment is passed PER CALL (the\n * `pageBox`/`chrome` pattern) and captured on pointer drafts at DOWN; it is\n * never stored on the model.\n */\nimport {\n geomBounds,\n geomRotateAbout,\n geomScaleAbout,\n geomTranslate,\n normalizeDeg,\n rotatePoint,\n} from './geometry';\nimport { capsFor } from './kinds';\nimport type { FlagBearer } from './flags';\nimport type { Geom, Vec, ViewEnv } from './types';\n\nexport type { ViewEnv };\n\n/** Which display factors this annotation is exempt from: `zoom` =\n * screen-constant size, `upright` = screen-constant orientation. */\nexport interface AnchorMode {\n zoom: boolean;\n upright: boolean;\n}\n\n/**\n * The anchor behaviors of one annotation: its `/F` flags OR'd with the kind's\n * statics — the spec's \"Text (note) annotations behave as if NoZoom and\n * NoRotate are ALWAYS set\", expressed as kind caps. Null when not anchored.\n */\nexport function anchorModeOf(a: FlagBearer): AnchorMode | null {\n const caps = capsFor(a.subtype);\n const zoom = a.flags.noZoom || caps.noZoom;\n const upright = a.flags.noRotate || caps.noRotate;\n return zoom || upright ? { zoom, upright } : null;\n}\n\n/**\n * The geometries the projection applies to: every kind with free content-space\n * geometry — boxes AND vertex kinds (line / poly / ink). Text-anchored\n * geometries (markup quads, carets) and callouts pass through: their position\n * is bound to page text, so a screen-constant body is meaningless there; the\n * flags still round-trip untouched.\n */\nconst projectable = (g: Geom): boolean =>\n g.t === 'rect' ||\n g.t === 'line' ||\n g.t === 'poly' ||\n g.t === 'ink' ||\n (g.t === 'text' && !g.callout);\n\n/** The fixed page point: the geometry's bounds top-left in content space\n * (y-down) — which IS the spec's \"upper-left corner of the annotation\n * rectangle\", since `/Rect` is emitted from these bounds. */\nexport const anchorOf = (g: Geom): Vec => {\n const b = geomBounds(g);\n return { x: b.x, y: b.y };\n};\n\nconst ORIGIN: Vec = { x: 0, y: 0 };\n\n/** The projection's factors for a mode at a view; `null` when it is the\n * identity (nothing to do). `s`/`r` are the STORED→VIEW inverse factors:\n * the forward projection applies `1/s` and `-r`.\n *\n * `s` clamps to `max(zoom, 1)` — Adobe's rule: `noZoom` holds the body at\n * its 100% size while zooming IN, but below 100% the body scales WITH the\n * page (a screen-constant body at 25% zoom would dwarf the page it\n * annotates, and its chrome would drift off-screen). */\nfunction factors(\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): { s: number; r: number } | null {\n if (!mode || !view) return null;\n const s = mode.zoom ? Math.max(view.zoom || 1, 1) : 1;\n const r = mode.upright ? normalizeDeg(view.rotation) : 0;\n return s !== 1 || r !== 0 ? { s, r } : null;\n}\n\n/**\n * THE effective content-space geometry of a screen-anchored body at `view`:\n * the stored geometry scaled by `1/max(zoom, 1)` about the anchor (`zoom`\n * exemption, Adobe-clamped) and counter-rotated by `-rotation` about it\n * (`upright`), so that after the page's own display transform the body reads\n * at its 100%-zoom size and its authored tilt, hanging from the fixed anchor.\n * Returns `g` unchanged when there is nothing to do — callers apply it\n * unconditionally.\n */\nexport function anchoredGeom(g: Geom, mode: AnchorMode | null, view: ViewEnv | undefined): Geom {\n const f = factors(mode, view);\n if (!f || !projectable(g)) return g;\n const a = anchorOf(g);\n let out: Geom = g;\n if (f.s !== 1) out = geomScaleAbout(out, a, 1 / f.s, 1 / f.s);\n if (f.r !== 0) out = geomRotateAbout(out, a, normalizeDeg(-f.r));\n return out;\n}\n\n/**\n * The exact inverse of {@link anchoredGeom} for a VIEW-space geometry a\n * gesture produced: the stored geometry whose OWN projection is `target`.\n *\n * Solving `anchoredGeom(stored) = target` where the projection anchors at\n * `stored`'s (unknown) bounds top-left `a` gives a closed form: map `target`\n * through the pure linear part (scale `s` + rotate `r` about the origin),\n * then translate so the result's bounds top-left `b` lands where the\n * projection needs it — at `a = R(-r)·b / s`, the unique fixed point. This is\n * what makes a released gesture commit EXACTLY what its preview showed.\n */\nexport function unanchoredGeom(\n target: Geom,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): Geom {\n const f = factors(mode, view);\n if (!f || !projectable(target)) return target;\n let lin: Geom = target;\n if (f.s !== 1) lin = geomScaleAbout(lin, ORIGIN, f.s, f.s);\n if (f.r !== 0) lin = geomRotateAbout(lin, ORIGIN, f.r);\n const b = anchorOf(lin);\n const a = rotatePoint(b, ORIGIN, -f.r);\n return geomTranslate(lin, { x: a.x / f.s - b.x, y: a.y / f.s - b.y });\n}\n\n/** Stroke width in the projected (view) space: a `noZoom` body's line weight\n * scales with its geometry so it stays screen-constant — through the SAME\n * factors (incl. the ≤100% clamp) the geometry projects with. */\nexport const anchoredStrokeWidth = (\n width: number,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): number => {\n const f = factors(mode, view);\n return f ? width / f.s : width;\n};\n\n/**\n * The similarity image of an axis-aligned box (a baked raster's AP `/Rect`)\n * under the anchor projection, as the blit vocabulary expects it: an\n * UNROTATED box (the projected centre + scaled size) plus the rotation to\n * re-apply about its centre. `anchor` is the OWNING GEOMETRY's anchor — the\n * raster rides its annotation's projection, it doesn't anchor itself. Null\n * when the projection is the identity.\n */\nexport function anchoredBox(\n box: { x: number; y: number; width: number; height: number },\n anchor: Vec,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): { box: { x: number; y: number; width: number; height: number }; rot: number } | null {\n const f = factors(mode, view);\n if (!f) return null;\n const c = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const scaled = {\n x: anchor.x + (c.x - anchor.x) / f.s,\n y: anchor.y + (c.y - anchor.y) / f.s,\n };\n const pc = f.r !== 0 ? rotatePoint(scaled, anchor, normalizeDeg(-f.r)) : scaled;\n const w = box.width / f.s;\n const h = box.height / f.s;\n return {\n box: { x: pc.x - w / 2, y: pc.y - h / 2, width: w, height: h },\n rot: normalizeDeg(-f.r),\n };\n}\n","import {\n geomHandles,\n geomHit,\n obbFromGeom,\n placeRotateKnob,\n pointInQuad,\n rectHandlesFor,\n selectionCenter,\n selectionQuad,\n unionRect,\n} from './geometry';\nimport { capsFor, isMarkup } from './kinds';\nimport { groupCaps } from './group';\nimport { annotInteractive, annotTransformable, viewable } from './flags';\nimport { anchoredGeom, anchoredStrokeWidth, anchorModeOf, type ViewEnv } from './anchor';\nimport {\n type Annot,\n type ChromeGeom,\n type Cursor,\n type Geom,\n type Id,\n type Model,\n type Rect,\n type Vec,\n} from './types';\n\nexport type Target =\n | { t: 'handle'; id: Id; handle: string; cursor: Cursor }\n // The rotate knob of the current selection (single shape or multi-target\n // group). `pivot` is the rotation centre the gesture turns about.\n | { t: 'rotate'; ids: Id[]; pivot: Vec }\n // A resize handle of the multi-target group box (the union box of the\n // selection). `box` is that union box; `ids` the members it scales.\n | { t: 'group-handle'; ids: Id[]; handle: string; cursor: Cursor; box: Rect }\n | { t: 'annot'; id: Id }\n | { t: 'empty' };\n\n/** Page annotation ids in PAINT order (back→front): text-layer markups first\n * (always beneath), then every other kind, each group preserving creation\n * z-order. The ONE z-order shared by rendering (`pageItems`) and hit-testing —\n * and the ONE visibility cull: what `/F` hides (hidden / un-engaged noView)\n * neither paints nor hits, so an invisible annotation can never eat a click. */\nexport function paintOrder(m: Model, pon: number): Id[] {\n const markup: Id[] = [];\n const other: Id[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n if (!viewable(a.flags, m.selected.includes(id))) continue;\n (isMarkup(a.subtype) ? markup : other).push(id);\n }\n return [...markup, ...other];\n}\n\n/** Can this annotation be clicked to select? (`/F` interaction flags override\n * all caps — hidden/noView/readOnly are inert; LOCKED stays selectable, it\n * just won't transform.) */\nexport const isSelectable = (m: Model, id: Id): boolean => {\n const a = m.byId[id];\n return !!a && annotInteractive(a) && capsFor(a.subtype).selectable;\n};\n\n/** An anchored kind's QUAD geometry is bound to underlying text — never moved\n * or resized. This is what lets one caps set serve both redaction shapes:\n * area marks (rect geometry) keep their transforms, text marks (quads) are\n * as fixed as classic markup. Markup kinds themselves have `movable: false`\n * and never reach this gate. */\nconst textBound = (a: Annot): boolean => capsFor(a.subtype).anchored && a.geom.t === 'quads';\n\n/** Can this annotation be dragged by its body to move? (`locked` freezes it.) */\nexport const canMove = (m: Model, id: Id): boolean => {\n const a = m.byId[id];\n return !!a && annotTransformable(a) && capsFor(a.subtype).movable && !textBound(a);\n};\n\n/** Does this kind expose drag handles (box resize OR per-vertex)? Only\n * `locked` (and inert `/F` states) suppress them at runtime — a\n * screen-anchored body keeps its handles: `noZoom`/`noRotate` exempt it from\n * the display transform, they don't freeze its size or vertices. */\nconst hasHandles = (a: Annot): boolean => {\n if (!annotTransformable(a) || textBound(a)) return false;\n const c = capsFor(a.subtype);\n return c.resizable || c.vertexEditable;\n};\n\n/** The geometry a pointer actually meets: the anchored (screen-constant)\n * projection for `noZoom`/`noRotate` annotations, the stored geom otherwise.\n * The SAME projection `pageItems` renders, so click matches paint. */\nconst hitGeomOf = (a: Annot, view: ViewEnv | undefined): Geom =>\n anchoredGeom(a.geom, anchorModeOf(a), view);\n\n/** Stroke width in EFFECTIVE content units (a noZoom body's line weight scales\n * with its geometry). */\nconst hitStrokeOf = (a: Annot, view: ViewEnv | undefined): number =>\n anchoredStrokeWidth(a.style.strokeWidth, anchorModeOf(a), view);\n\n// `opaqueBody` kinds (stamp images) are visible across their whole box, so they\n// hit like a filled shape. NOT keyed on `source: 'baked'` — every annotation\n// loaded from a PDF starts baked, and an unfilled square must still be grabbed\n// only on its outline.\nconst isFilled = (a: Annot): boolean =>\n a.style.interiorColor != null || a.geom.t === 'quads' || capsFor(a.subtype).opaqueBody;\nconst inRect = (b: Rect, p: Vec): boolean =>\n p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;\n// A SELECTED annotation is grabbable from anywhere inside its SELECTION region — the\n// SAME oriented quad the chrome outlines — so the grab area matches what you see\n// highlighted, tilt included (a rotated box is grabbable across its tilted body, not\n// just its unrotated footprint; a thin arrow's whole outline box, arrowhead and all).\nconst inBounds = (a: Annot, p: Vec, view: ViewEnv | undefined): boolean =>\n pointInQuad(p, selectionQuad(hitGeomOf(a, view), hitStrokeOf(a, view), a.style.border));\n\n/**\n * The union of the SELECTION bounds of every selected, movable annotation on a\n * page — the SAME box `chrome` outlines for a multi-selection. Null unless 2+\n * such annotations are selected here. This is the grab region for the gaps\n * BETWEEN grouped/multi-selected annotations, so dragging the whole selection\n * works from anywhere inside its visible outline (not only on a member).\n */\nfunction selectionUnionBounds(m: Model, pon: number, view: ViewEnv | undefined): Rect | null {\n const sel = m.selected.filter(\n (id) => m.byId[id]?.pon === pon && isSelectable(m, id) && canMove(m, id),\n );\n if (sel.length < 2) return null;\n const corners: Vec[] = [];\n for (const id of sel) {\n const a = m.byId[id];\n corners.push(...selectionQuad(hitGeomOf(a, view), hitStrokeOf(a, view), a.style.border));\n }\n return unionRect(corners);\n}\n\n/** The axis-aligned union of the SELECTION bounds of every selected annotation on\n * a page (no movable/lock filter) — the box group chrome + group rotate use. */\nexport function groupUnionBounds(m: Model, pon: number, view?: ViewEnv): Rect | null {\n const corners: Vec[] = [];\n for (const id of m.selected) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n corners.push(...selectionQuad(hitGeomOf(a, view), hitStrokeOf(a, view), a.style.border));\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/**\n * What's under the content point.\n * 1. a resize/vertex handle of the single selection,\n * 2. an editable annotation body — a SELECTED one anywhere in its bounds (so you\n * can drag to move it), an UNSELECTED one only on its stroke/fill (margin-aware,\n * so an unfilled circle is grabbed only on its outline),\n * 3. else empty.\n */\nexport function hitTest(\n m: Model,\n pon: number,\n p: Vec,\n geom: ChromeGeom,\n strokeMargin: number,\n pageBox?: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Target {\n if (m.selected.length === 1 && isSelectable(m, m.selected[0])) {\n const a = m.byId[m.selected[0]];\n if (a.pon === pon) {\n // The rotate knob (checked first — it floats outside the box, clear of\n // the handles), placed on the PROJECTED geometry so it sits exactly\n // where the chrome drew it — a screen-anchored body rotates too (the\n // gesture edits its authored tilt; `noRotate` only exempts it from the\n // PAGE's rotation). Locked suppresses it. `placeRotateKnob` keeps it\n // inside `pageBox`.\n if (capsFor(a.subtype).rotatable && annotTransformable(a)) {\n const hg = hitGeomOf(a, view);\n const obb = obbFromGeom(hg, hitStrokeOf(a, view), a.style.border);\n if (obb) {\n const knob = placeRotateKnob(obb.corners, geom.knobOffset, pageBox);\n if (\n Math.abs(knob.at.x - p.x) <= geom.knobTol &&\n Math.abs(knob.at.y - p.y) <= geom.knobTol\n ) {\n return {\n t: 'rotate',\n ids: [a.id],\n // VIEW-space pivot: the projected shape's centre — the point the\n // user sees the shape turn about (the commit conjugates back).\n pivot: selectionCenter(hg, hitStrokeOf(a, view)),\n };\n }\n }\n }\n if (hasHandles(a)) {\n // Handles live on the PROJECTED geometry — the handle gesture then\n // runs entirely in view space (see the `handle` draft).\n for (const h of geomHandles(hitGeomOf(a, view))) {\n if (\n Math.abs(h.at.x - p.x) <= geom.handleTol &&\n Math.abs(h.at.y - p.y) <= geom.handleTol\n ) {\n return { t: 'handle', id: a.id, handle: h.id, cursor: h.cursor };\n }\n }\n }\n }\n } else if (m.selected.length > 1) {\n // Multi-target group: a rotate knob hanging off the union box, gated by the\n // group caps (every member rotatable + none locked). Screen-anchored\n // members rotate WYSIWYG like everyone else (their authored tilt turns).\n const gc = groupCaps(m, m.selected);\n if (gc.rotatable) {\n const union = groupUnionBounds(m, pon, view);\n if (union) {\n const corners: [Vec, Vec, Vec, Vec] = [\n { x: union.x, y: union.y },\n { x: union.x + union.width, y: union.y },\n { x: union.x + union.width, y: union.y + union.height },\n { x: union.x, y: union.y + union.height },\n ];\n const knob = placeRotateKnob(corners, geom.knobOffset, pageBox);\n if (\n Math.abs(knob.at.x - p.x) <= geom.knobTol &&\n Math.abs(knob.at.y - p.y) <= geom.knobTol\n ) {\n const pivot = { x: union.x + union.width / 2, y: union.y + union.height / 2 };\n return { t: 'rotate', ids: m.selected.filter((id) => m.byId[id]?.pon === pon), pivot };\n }\n }\n }\n if (gc.resizable) {\n const union = groupUnionBounds(m, pon, view);\n if (union) {\n for (const h of rectHandlesFor(union)) {\n if (\n Math.abs(h.at.x - p.x) <= geom.handleTol &&\n Math.abs(h.at.y - p.y) <= geom.handleTol\n ) {\n return {\n t: 'group-handle',\n ids: m.selected.filter((id) => m.byId[id]?.pon === pon),\n handle: h.id,\n cursor: h.cursor,\n box: union,\n };\n }\n }\n }\n }\n }\n const order = paintOrder(m, pon);\n for (let i = order.length - 1; i >= 0; i--) {\n const id = order[i];\n const a = m.byId[id];\n // `inert` ids (engaged Behaviors — form widgets under a fill tool) are\n // invisible here: their own DOM owns the pointer.\n if (!a || inert?.has(id) || !isSelectable(m, id)) continue;\n // A SELECTED annotation is sticky-grabbable from anywhere in its bounds, but\n // only if it can actually move; otherwise it's grabbed on its stroke/fill like\n // an unselected one (so a selectable-but-anchored kind still re-selects cleanly).\n const hit =\n m.selected.includes(id) && canMove(m, id)\n ? inBounds(a, p, view)\n : geomHit(hitGeomOf(a, view), p, strokeMargin, isFilled(a), hitStrokeOf(a, view));\n if (hit) return { t: 'annot', id };\n }\n // Nothing under the point directly — but a multi-selection is grabbable across\n // its WHOLE union box (the gaps between members included), so a drag there moves\n // the group as a unit instead of clearing it. Resolve to the top-most selected\n // member so `editDown` keeps the selection and arms the move.\n const union = selectionUnionBounds(m, pon, view);\n if (union && inRect(union, p)) {\n for (let i = order.length - 1; i >= 0; i--) {\n if (m.selected.includes(order[i]) && canMove(m, order[i]))\n return { t: 'annot', id: order[i] };\n }\n }\n return { t: 'empty' };\n}\n\n/** The cursor to show on hover: a resize cursor over a handle, move/pointer over a body. */\nexport function cursorAt(\n m: Model,\n pon: number,\n p: Vec,\n geom: ChromeGeom,\n strokeMargin: number,\n pageBox?: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Cursor | null {\n const t = hitTest(m, pon, p, geom, strokeMargin, pageBox, inert, view);\n if (t.t === 'handle') return t.cursor;\n if (t.t === 'group-handle') return t.cursor;\n if (t.t === 'rotate') return 'grab';\n if (t.t === 'annot') return m.selected.includes(t.id) && canMove(m, t.id) ? 'move' : 'pointer';\n return null;\n}\n","/**\n * The flat property vocabulary over the model: read and apply\n * {@link AnnotationProps} keys on an `Annot`, routing each key to where it is\n * stored (`style`, `geom.ends`, or `text`) so callers never learn the storage.\n * Which keys a kind takes is declared in the KIND table (`propsFor`); keys a\n * kind doesn't declare are ignored — that's what lets ONE patch restyle a\n * mixed selection.\n */\nimport { propsFor, type PropSpec } from './kinds';\nimport { annotTransformable } from './flags';\nimport type {\n Annot,\n AnnotationProps,\n AnnotationPropsPatch,\n Geom,\n LineEndings,\n PropKey,\n Style,\n TextStyle,\n} from './types';\n\nconst NO_ENDINGS: LineEndings = { start: 'none', end: 'none' };\n\n/** Base text styling for kinds/tools with no explicit defaults. */\nexport const initialTextStyle: TextStyle = {\n fontFamily: 'helvetica',\n fontSize: 14,\n fontColor: '#000000',\n textAlign: 'left',\n};\n\n/** The `Style` slice of a resolved props bag (the create-time projection). */\nexport const styleFromProps = (p: AnnotationProps): Style => ({\n color: p.color,\n interiorColor: p.interiorColor,\n strokeWidth: p.strokeWidth,\n opacity: p.opacity,\n blendMode: p.blendMode,\n border: p.border,\n});\n\n/** The `TextStyle` slice of a resolved props bag (the create-time projection). */\nexport const textStyleFromProps = (p: AnnotationProps): TextStyle => ({\n fontFamily: p.fontFamily,\n fontSize: p.fontSize,\n fontColor: p.fontColor,\n textAlign: p.textAlign,\n});\n\n/** A geom that carries `/LE` endings: a line, or an OPEN poly (polyline). */\nconst endingsGeom = (g: Geom): g is Extract<Geom, { t: 'line' } | { t: 'poly' }> =>\n g.t === 'line' || (g.t === 'poly' && !g.closed);\n\n/**\n * Read one property off an annotation — from wherever it lives — or `undefined`\n * when the annotation's kind doesn't carry it (a `fontSize` on a square, endings\n * on a polygon). The read side of `applyProps`.\n */\nexport function readProp<K extends PropKey>(a: Annot, key: K): AnnotationProps[K] | undefined {\n const out = ((): AnnotationProps[PropKey] | undefined => {\n switch (key) {\n case 'color':\n return a.style.color;\n case 'interiorColor':\n return a.style.interiorColor;\n case 'strokeWidth':\n return a.style.strokeWidth;\n case 'opacity':\n return a.style.opacity;\n case 'blendMode':\n return a.style.blendMode;\n case 'border':\n return a.style.border;\n case 'lineEndings':\n return endingsGeom(a.geom) ? (a.geom.ends ?? NO_ENDINGS) : undefined;\n case 'fontFamily':\n return a.text?.fontFamily;\n case 'fontSize':\n return a.text?.fontSize;\n case 'fontColor':\n return a.text?.fontColor;\n case 'textAlign':\n return a.text?.textAlign;\n case 'icon':\n return a.icon;\n case 'link':\n return a.link;\n }\n })();\n return out as AnnotationProps[K] | undefined;\n}\n\n/**\n * Apply a property patch to one annotation, honouring its kind's declared keys.\n * Returns the changed annotation, or `null` when nothing applied (locked /\n * read-only per its `/F` flags, or no declared key in the patch) — so the\n * caller emits no spurious engine write. Flags themselves are NOT props: they\n * write through the `setFlags` message, which is deliberately not gated here\n * (unlocking must work on a locked annotation).\n */\nexport function applyProps(a: Annot, patch: AnnotationPropsPatch): Annot | null {\n if (!annotTransformable(a)) return null;\n const takes = new Set<PropKey>(propsFor(a.subtype).map((s) => s.key));\n let next = a;\n\n // `!== undefined` (not truthiness): `interiorColor: null` means CLEAR the fill.\n const style: Style = { ...a.style };\n let styleChanged = false;\n if (patch.color !== undefined && takes.has('color')) {\n style.color = patch.color;\n styleChanged = true;\n }\n if (patch.interiorColor !== undefined && takes.has('interiorColor')) {\n style.interiorColor = patch.interiorColor;\n styleChanged = true;\n }\n if (patch.strokeWidth !== undefined && takes.has('strokeWidth')) {\n style.strokeWidth = patch.strokeWidth;\n styleChanged = true;\n }\n if (patch.opacity !== undefined && takes.has('opacity')) {\n style.opacity = patch.opacity;\n styleChanged = true;\n }\n if (patch.blendMode !== undefined && takes.has('blendMode')) {\n style.blendMode = patch.blendMode;\n styleChanged = true;\n }\n if (patch.border !== undefined && takes.has('border')) {\n style.border = patch.border;\n styleChanged = true;\n }\n if (styleChanged) next = { ...next, style };\n\n if (patch.lineEndings && takes.has('lineEndings') && endingsGeom(next.geom)) {\n const ends: LineEndings = { ...(next.geom.ends ?? NO_ENDINGS), ...patch.lineEndings };\n next = { ...next, geom: { ...next.geom, ends } };\n }\n\n if (patch.icon !== undefined && takes.has('icon')) {\n next = { ...next, icon: patch.icon };\n }\n\n if (patch.link !== undefined && takes.has('link')) {\n next = { ...next, link: patch.link };\n }\n\n if (next.text) {\n const text: TextStyle = { ...next.text };\n let textChanged = false;\n if (patch.fontFamily !== undefined && takes.has('fontFamily')) {\n text.fontFamily = patch.fontFamily;\n textChanged = true;\n }\n if (patch.fontSize !== undefined && takes.has('fontSize')) {\n text.fontSize = patch.fontSize;\n textChanged = true;\n }\n if (patch.fontColor !== undefined && takes.has('fontColor')) {\n text.fontColor = patch.fontColor;\n textChanged = true;\n }\n if (patch.textAlign !== undefined && takes.has('textAlign')) {\n text.textAlign = patch.textAlign;\n textChanged = true;\n }\n if (textChanged) next = { ...next, text };\n }\n\n return next === a ? null : next;\n}\n\n/**\n * The ordered property specs EVERY given kind declares — the schema for a mixed\n * selection, in the FIRST kind's display order. One kind → its own list, verbatim.\n */\nexport function sharedProps(subtypes: readonly string[]): PropSpec[] {\n const unique = [...new Set(subtypes)];\n if (!unique.length) return [];\n const first = propsFor(unique[0]);\n if (unique.length === 1) return first;\n const rest = unique.slice(1).map((s) => new Set(propsFor(s).map((p) => p.key)));\n return first.filter((p) => rest.every((keys) => keys.has(p.key)));\n}\n","/**\n * Click-create PLACEMENT — the pure, plane-agnostic layer.\n *\n * `resolveClickPlacement` answers \"where does a bare click put the thing\": a\n * box (anchored per POLICY, upright-aware, slid onto the page) or a segment\n * (default length/angle from the point, slid onto the page as a unit). It is\n * THE single source for that answer — the annotation core's click commit, the\n * hover footprint ghost, and the form plugin's field placement all consume\n * the same result, so preview ≡ commit by construction.\n *\n * It deliberately returns LOGICAL geometry: no annotation visual semantics\n * (no cloudy-border outer-box expansion, no ellipse) — a form field takes\n * `rect` straight to `doc.forms.createField`. The annotation-only conversion\n * to a committable/renderable `Geom` is {@link clickCreateGeom} below; that\n * is where `shapeRectFor` and ellipse semantics apply.\n */\nimport {\n rectFromPoints,\n shapeRectFor,\n transposedAboutCenter,\n uprightAnchoredRect,\n uprightRotation,\n} from './geometry';\nimport { styleFromProps } from './props';\nimport type { PageRotation } from '@embedpdf/core-geometry';\nimport type { AnnotationProps, ClickCreate, Geom, Rect, Subtype, Vec } from './types';\n\n/** A resolved click placement: what the click will occupy, page-clamped. */\nexport type ClickPlacement =\n | {\n kind: 'box';\n rect: Rect;\n /** Upright counter-rotation captured for the commit (deg CW; 0 = none). */\n rot: number;\n }\n | { kind: 'segment'; a: Vec; b: Vec };\n\n/** Slide a rect (as a unit) to sit inside `box`; pins at the origin edge when\n * it doesn't fit. Placements are page-bound; the pointer isn't. */\nexport const clampRectToBox = (r: Rect, box: Rect | undefined): Rect => {\n if (!box) return r;\n return {\n ...r,\n x: Math.min(Math.max(r.x, box.x), Math.max(box.x, box.x + box.width - r.width)),\n y: Math.min(Math.max(r.y, box.y), Math.max(box.y, box.y + box.height - r.height)),\n };\n};\n\n/**\n * Resolve a click-create POLICY at a content point. `anchor` defaults to\n * `center`; under `upright` a box counter-rotates against the page's display\n * rotation exactly as the drag commit would (centre-anchored boxes transpose\n * about their centre, top-left boxes anchor in the DISPLAY frame).\n */\nexport function resolveClickPlacement(\n point: Vec,\n policy: ClickCreate,\n opts: { pageBox?: Rect; upright?: boolean; displayRotation?: PageRotation } = {},\n): ClickPlacement {\n if ('length' in policy) {\n const ang = ((policy.angleDeg ?? 0) * Math.PI) / 180;\n const b = {\n x: point.x + Math.cos(ang) * policy.length,\n y: point.y + Math.sin(ang) * policy.length,\n };\n const bounds = rectFromPoints(point, b);\n const placed = clampRectToBox(bounds, opts.pageBox);\n const dx = placed.x - bounds.x;\n const dy = placed.y - bounds.y;\n return {\n kind: 'segment',\n a: { x: point.x + dx, y: point.y + dy },\n b: { x: b.x + dx, y: b.y + dy },\n };\n }\n const { width, height } = policy;\n const rot = opts.upright && opts.displayRotation ? uprightRotation(opts.displayRotation) : 0;\n let rect: Rect;\n if (policy.anchor === 'top-left') {\n rect = rot\n ? uprightAnchoredRect(point, width, height, opts.displayRotation!)\n : { x: point.x, y: point.y, width, height };\n } else {\n rect = { x: point.x - width / 2, y: point.y - height / 2, width, height };\n // A quarter-turn transposes the unrotated box so the DISPLAYED box keeps\n // the configured width×height (same rule as a dragged box).\n if (rot === 90 || rot === 270) rect = transposedAboutCenter(rect);\n }\n return { kind: 'box', rect: clampRectToBox(rect, opts.pageBox), rot };\n}\n\n/**\n * ANNOTATION-ONLY: convert a placement into the `Geom` the commit stores and\n * the ghost paints, for a routing kind. This is where annotation VISUAL\n * semantics live — ellipse for circles, the cloudy outer-box via\n * `shapeRectFor`. Forms never call this; a field box is the placement rect\n * itself. Null for kinds a click cannot author.\n */\nexport function clickCreateGeom(\n subtype: Subtype,\n placement: ClickPlacement,\n def: AnnotationProps,\n): Geom | null {\n if (placement.kind === 'segment') {\n return subtype === 'line'\n ? { t: 'line', a: placement.a, b: placement.b, ends: def.lineEndings }\n : null;\n }\n const { rect, rot } = placement;\n if (subtype === 'free-text') {\n return { t: 'text', rect, ...(rot ? { rot } : {}) };\n }\n if (subtype === 'square' || subtype === 'circle') {\n return {\n t: 'rect',\n rect: shapeRectFor(rect, subtype === 'circle', styleFromProps(def)),\n ellipse: subtype === 'circle',\n ...(rot ? { rot } : {}),\n };\n }\n return null;\n}\n","/**\n * Pure alignment snapping for the move gesture. Compares the moving selection's\n * edges + centers against every other annotation on the page (and the page\n * box); if a pair lands within the threshold, nudges the delta to align them\n * and reports a guide line to draw. One snap per axis — the closest wins.\n * Threshold is in content units (the `hitMargin` convention).\n */\nimport { anchorModeOf } from './anchor';\nimport { selectionQuad, unionRect } from './geometry';\nimport { isSelectable } from './hit';\nimport type { Guide, Id, Model, Rect, Vec } from './types';\n\nexport interface SnapResult {\n delta: Vec;\n guides: Guide[];\n}\n\ninterface Bounds {\n min: Vec;\n max: Vec;\n}\n\n/** Overshoot the shapes a little so the guide reads as a through-line. */\nconst GUIDE_PAD = 14;\n\nconst toBounds = (r: Rect): Bounds => ({\n min: { x: r.x, y: r.y },\n max: { x: r.x + r.width, y: r.y + r.height },\n});\nconst keysX = (b: Bounds) => [b.min.x, (b.min.x + b.max.x) / 2, b.max.x];\nconst keysY = (b: Bounds) => [b.min.y, (b.min.y + b.max.y) / 2, b.max.y];\nconst shift = (b: Bounds, d: Vec): Bounds => ({\n min: { x: b.min.x + d.x, y: b.min.y + d.y },\n max: { x: b.max.x + d.x, y: b.max.y + d.y },\n});\n\n/** An annotation's visual footprint corners — the ORIENTED quad, so a rotated\n * shape snaps by what's actually drawn, not its unrotated box. */\nconst annotQuad = (m: Model, id: Id): Vec[] =>\n selectionQuad(m.byId[id].geom, m.byId[id].style.strokeWidth, m.byId[id].style.border);\n\n/**\n * Snap a move delta: shift the selection's union bounds by `raw`, compare its\n * 3 keys per axis (min / center / max) against every target's, and take the\n * closest in-threshold pair per axis as an adjustment. Targets are the page box\n * (edges + center) and every non-moving annotation on the page.\n */\nexport function computeMoveSnap(\n m: Model,\n ids: Id[],\n pon: number,\n raw: Vec,\n threshold: number,\n pageBox: Rect | undefined,\n): SnapResult {\n const moving = new Set(ids);\n // Screen-anchored (`noZoom`/`noRotate`) annotations sit OUTSIDE the snapping\n // system, both ways: their content-space footprint depends on the view, so\n // an alignment made at one zoom is a lie at every other zoom. A selection\n // that contains one doesn't snap; one that's parked on the page is never a\n // reference edge. (The page-edge CLAMP is unaffected — it uses projected\n // bounds per event.)\n if (ids.some((id) => m.byId[id] && anchorModeOf(m.byId[id]))) {\n return { delta: raw, guides: [] };\n }\n const base = toBounds(unionRect(ids.flatMap((id) => annotQuad(m, id))));\n const movingBox = shift(base, raw);\n\n const targets: Bounds[] = [\n ...(pageBox ? [toBounds(pageBox)] : []),\n ...m.order\n .filter(\n (id) =>\n !moving.has(id) &&\n m.byId[id].pon === pon &&\n isSelectable(m, id) &&\n !anchorModeOf(m.byId[id]),\n )\n .map((id) => toBounds(unionRect(annotQuad(m, id)))),\n ];\n\n let bx: { adjust: number; at: number; tb: Bounds } | null = null;\n let by: { adjust: number; at: number; tb: Bounds } | null = null;\n for (const tb of targets) {\n for (const tk of keysX(tb))\n for (const mk of keysX(movingBox)) {\n const diff = tk - mk;\n if (Math.abs(diff) < threshold && (!bx || Math.abs(diff) < Math.abs(bx.adjust)))\n bx = { adjust: diff, at: tk, tb };\n }\n for (const tk of keysY(tb))\n for (const mk of keysY(movingBox)) {\n const diff = tk - mk;\n if (Math.abs(diff) < threshold && (!by || Math.abs(diff) < Math.abs(by.adjust)))\n by = { adjust: diff, at: tk, tb };\n }\n }\n\n const delta = { x: raw.x + (bx?.adjust ?? 0), y: raw.y + (by?.adjust ?? 0) };\n const snapped = shift(base, delta);\n const guides: Guide[] = [];\n if (bx)\n guides.push({\n axis: 'x',\n at: bx.at,\n lo: Math.min(snapped.min.y, bx.tb.min.y) - GUIDE_PAD,\n hi: Math.max(snapped.max.y, bx.tb.max.y) + GUIDE_PAD,\n });\n if (by)\n guides.push({\n axis: 'y',\n at: by.at,\n lo: Math.min(snapped.min.x, by.tb.min.x) - GUIDE_PAD,\n hi: Math.max(snapped.max.x, by.tb.max.x) + GUIDE_PAD,\n });\n return { delta, guides };\n}\n","import type { InkStraightenOptions, Vec } from './types';\n\n/**\n * Recognise a sufficiently straight freehand stroke and axis-snap it when it is\n * close to horizontal or vertical. Diagonal strokes remain untouched: this is\n * a highlighter aid, not a general line simplifier.\n */\nexport function straightenInkStroke(points: readonly Vec[], options: InkStraightenOptions): Vec[] {\n if (points.length < 3) return [...points];\n const first = points[0];\n const last = points[points.length - 1];\n const dx = last.x - first.x;\n const dy = last.y - first.y;\n const length = Math.hypot(dx, dy);\n if (length < 3) return [...points];\n\n const maxDeviation = points.reduce((max, point) => {\n const distance = Math.abs(dx * (first.y - point.y) - (first.x - point.x) * dy) / length;\n return Math.max(max, distance);\n }, 0);\n if (maxDeviation / length >= options.deviationThreshold) return [...points];\n\n const angle = Math.atan2(Math.abs(dy), Math.abs(dx)) * (180 / Math.PI);\n if (angle <= options.axisSnapDegrees) {\n const y = points.reduce((sum, point) => sum + point.y, 0) / points.length;\n return [\n { x: first.x, y },\n { x: last.x, y },\n ];\n }\n if (angle >= 90 - options.axisSnapDegrees) {\n const x = points.reduce((sum, point) => sum + point.x, 0) / points.length;\n return [\n { x, y: first.y },\n { x, y: last.y },\n ];\n }\n return [...points];\n}\n","/**\n * The pure annotation core: update(model, msg) → [model, effects].\n *\n * Editing is intent-driven (the shell's edit handler sends `editPointer`, the draw\n * handler `createPointer`). Geometry lives in the `Geom` union; all the per-kind\n * math is in geometry.ts. Effects (create/patch/delete) are the only impurities.\n */\nimport type { AnnotationFlags, AnnotationRef, InkIntent } from '@embedpdf/engine-core/runtime';\nimport { expandGroups, groupMembers } from './group';\nimport { canMove, groupUnionBounds, hitTest, isSelectable } from './hit';\nimport { capsFor } from './kinds';\nimport {\n annotContentsEditable,\n annotTransformable,\n DRAWN_FLAGS,\n flagsEqual,\n mergeFlags,\n} from './flags';\nimport { anchoredGeom, anchorModeOf, unanchoredGeom, type ViewEnv } from './anchor';\nimport {\n apSizeChanged,\n caretRectFromTextEnd,\n DEFAULT_CHROME_GEOM,\n geomDragHandle,\n geomResetRotation,\n geomRotateAbout,\n geomRotation,\n geomScaleAbout,\n geomTranslate,\n groupResizeAnchor,\n groupResizeBox,\n groupResizeFactors,\n normalizeDeg,\n quadIntersectsRect,\n rectFromPoints,\n selectionCenter,\n selectionQuad,\n shapeRectFor,\n transposedAboutCenter,\n unionRect,\n uprightAnchoredRect,\n uprightRotation,\n} from './geometry';\nimport { clickCreateGeom, resolveClickPlacement } from './placement';\nimport { applyProps, initialTextStyle, styleFromProps, textStyleFromProps } from './props';\nimport { computeMoveSnap } from './snap';\nimport { straightenInkStroke } from './ink';\nimport type {\n Annot,\n AnnotationProps,\n AnnotationPropsPatch,\n ClickCreate,\n Draft,\n Effect,\n Geom,\n Id,\n InkStraightenOptions,\n LineEndings,\n Model,\n Msg,\n PointerInput,\n PropKey,\n Quad,\n Rect,\n Style,\n Subtype,\n Vec,\n} from './types';\n\n/** The click ↔ drag threshold (content units): a press-release whose width AND\n * height both stay under it is a CLICK. Exported so every gesture owner (the\n * draw handler, the form plugin's place handler) shares ONE definition. */\nexport const MIN_DRAG = 3;\nconst isPolySubtype = (subtype: Subtype): subtype is 'polygon' | 'polyline' =>\n subtype === 'polygon' || subtype === 'polyline';\n\nexport const initialStyle: Style = {\n color: '#e5484d',\n interiorColor: null,\n strokeWidth: 2,\n opacity: 1,\n blendMode: 'normal',\n border: { kind: 'solid' },\n};\n\nconst NO_ENDINGS: LineEndings = { start: 'none', end: 'none' };\n\nexport const initialModel: Model = {\n byId: {},\n order: [],\n selected: [],\n hovered: null,\n draft: null,\n preview: null,\n seq: 0,\n style: initialStyle,\n defaults: {},\n hitMargin: 6,\n editing: null,\n snap: {\n guides: true,\n guideThreshold: 5,\n rotation: true,\n rotationAngles: [0, 90, 180, 270],\n rotationThreshold: 4,\n },\n};\n\n/**\n * Resolve a tool's effective defaults as a FULL flat props bag: the base `style`\n * + the font/endings base, with the per-tool override layered on top. This is\n * what a defaults-editing UI reads, and what creation projects `style`/`text`\n * from (`styleFromProps` / `textStyleFromProps`).\n */\nexport function defaultsFor(m: Model, subtype: Subtype): AnnotationProps {\n const d = m.defaults[subtype];\n return {\n ...m.style,\n ...initialTextStyle,\n ...d,\n lineEndings: { ...NO_ENDINGS, ...d?.lineEndings },\n };\n}\n\n/** Flip an annotation to live (vector) rendering — we now own its appearance, so\n * the engine's baked AP is no longer authoritative. Idempotent. */\nconst toVector = (a: Annot): Annot => (a.source === 'vector' ? a : { ...a, source: 'vector' });\n/**\n * Take ownership of the appearance after a GEOMETRY edit. Vector kinds flip to\n * live rendering; `opaqueBody` kinds (stamp images) have NO vector render — they\n * stay `baked`, with the raster box following the committed geometry (the bitmap\n * shows stretched until the engine's natively re-fit appearance arrives with the\n * DTO sync). Call with the NEW geometry already applied.\n */\nconst ownGeometry = (a: Annot): Annot => {\n if (!capsFor(a.subtype).opaqueBody) return toVector(a);\n return 'rect' in a.geom ? { ...a, apBox: a.geom.rect } : a;\n};\n/**\n * Does this committed edit invalidate an engine-baked raster? Only when the\n * annotation STAYS baked (an opaque-body kind — everything else just flipped to\n * vector via {@link ownGeometry} and renders live from its geometry) AND the\n * edit changed the /AP frame's SIZE, does the engine's re-bake produce new\n * raster content. In practice: a stamp resize. Moves and rotations keep the\n * frame (the blit translates/rotates the same pixels), so they emit false and\n * a committed drag costs zero appearance re-renders. Call with the NEXT\n * (post-{@link ownGeometry}) annot and the geometry it had BEFORE the edit.\n */\nconst apInvalidated = (next: Annot, before: Geom): boolean =>\n next.source === 'baked' && apSizeChanged(before, next.geom);\n/** The patch effect for a committed geometry edit. `apChanged` is attached ONLY\n * when the edit invalidated a baked raster (a stamp resize) — so every other\n * edit keeps the bare `{ fx, id }` shape and never triggers an appearance\n * re-fetch. `next` is the post-{@link ownGeometry} annot, `before` its old geom. */\nconst patchFx = (id: Id, next: Annot, before: Geom): Effect =>\n apInvalidated(next, before)\n ? { fx: 'patch', id, scope: { kind: 'geometry' }, apChanged: true }\n : { fx: 'patch', id, scope: { kind: 'geometry' } };\nconst sub = (a: Vec, b: Vec): Vec => ({ x: a.x - b.x, y: a.y - b.y });\nconst translateRect = (r: Rect, d: Vec): Rect => ({ ...r, x: r.x + d.x, y: r.y + d.y });\n\n/**\n * Commit a VIEW-space gesture result for one annotation: apply `op` to the\n * PROJECTED geometry (the identity for un-flagged annotations — `op` then\n * simply runs on the stored geom) and map the result back to stored space\n * through `unanchoredGeom`. The exact composition `effGeom` previewed, so a\n * released gesture commits what it showed — for screen-anchored and plain\n * annotations alike, through ONE code path.\n */\nconst commitViewGesture = (a: Annot, view: ViewEnv | undefined, op: (g: Geom) => Geom): Geom => {\n const mode = anchorModeOf(a);\n return unanchoredGeom(op(anchoredGeom(a.geom, mode, view)), mode, view);\n};\n\n/* ── page-bound gestures ──────────────────────────────────────────────────────\n * Annotations are page-bound; the pointer isn't. Two rules keep them apart:\n * 1. FRAME: a gesture is anchored to the page it started on. A sample resolved\n * against another page is in a different coordinate frame (each page's\n * content space has its own origin) — subtracting across frames produced\n * the teleport-to-page-top bug, so foreign-page samples are ignored.\n * 2. CLAMP: within the home frame, geometry pins to the page box (v2 rule):\n * an overshooting pointer slides the shape along the edge; a shape larger\n * than the page pins to the page's top/left (lo wins when lo > hi).\n */\nconst clampAxis = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\nconst clampPointToBox = (p: Vec, box: Rect | undefined): Vec =>\n box\n ? {\n x: clampAxis(p.x, box.x, box.x + box.width),\n y: clampAxis(p.y, box.y, box.y + box.height),\n }\n : p;\n\n/** The pointer sample's view environment (relative zoom + display rotation),\n * when the caller supplied one — screen-anchored annotations hit-test and\n * page-clamp at their EFFECTIVE geometry with it. Absent → stored geometry\n * (headless). */\nconst viewOf = (input: PointerInput): ViewEnv | undefined =>\n input.zoom != null || input.displayRotation != null\n ? { zoom: input.zoom ?? 1, rotation: input.displayRotation ?? 0 }\n : undefined;\n\n/** The union of the ids' SELECTION bounds (the outline the user sees) — the box\n * the page-clamp keeps inside the page during a move. Screen-anchored members\n * count at their effective (view-projected) footprint. */\nfunction unionBoundsOf(m: Model, ids: Id[], view?: ViewEnv): Rect | null {\n const corners: Vec[] = [];\n for (const id of ids) {\n const a = m.byId[id];\n if (!a) continue;\n const g = anchoredGeom(a.geom, anchorModeOf(a), view);\n corners.push(...selectionQuad(g, a.style.strokeWidth, a.style.border));\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/** Clamp a move delta so the selection's union bounds stay inside the page.\n * Per-axis, so a pointer past the bottom edge still slides the selection\n * horizontally along that edge. */\nfunction clampMoveDelta(\n m: Model,\n ids: Id[],\n delta: Vec,\n page: Rect | undefined,\n view?: ViewEnv,\n): Vec {\n if (!page) return delta;\n const b = unionBoundsOf(m, ids, view);\n if (!b) return delta;\n return {\n x: clampAxis(delta.x, page.x - b.x, page.x + page.width - (b.x + b.width)),\n y: clampAxis(delta.y, page.y - b.y, page.y + page.height - (b.y + b.height)),\n };\n}\n\n/** The page an edit draft is anchored to — every edit gesture lives on ONE page. */\nfunction editDraftPon(m: Model, d: Draft): number | null {\n const id = d.g === 'handle' ? d.id : 'ids' in d && d.ids.length ? d.ids[0] : null;\n return id != null ? (m.byId[id]?.pon ?? null) : null;\n}\nconst geomEqual = (a: Geom, b: Geom): boolean => JSON.stringify(a) === JSON.stringify(b);\nconst RAD2DEG = 180 / Math.PI;\n\n/** The signed CW angle (deg) of `p` relative to `pivot`, in content space (y-down). */\nconst angleAt = (pivot: Vec, p: Vec): number => Math.atan2(p.y - pivot.y, p.x - pivot.x) * RAD2DEG;\n\n/** Shortest signed arc from `a` to `b` (deg), in (-180, 180]. */\nconst arcTo = (a: number, b: number): number => ((b - a + 540) % 360) - 180;\n\n/**\n * The live rotation of a rotate draft, snapping applied — the ONE angle rule\n * shared by the preview (`effGeom`), the commit (`editUp`) and the angle chip,\n * so they can never disagree. The selection's ABSOLUTE angle (a single member's\n * `rot` + the raw pointer delta; a group's raw delta from 0) locks onto the\n * configured angles within the threshold; `free` (shift held) bypasses.\n * `delta` is what `geomRotateAbout` applies; `angle` is what the chip shows.\n */\nexport function rotateDraftDelta(\n m: Model,\n d: Extract<Draft, { g: 'rotate' }>,\n): { delta: number; angle: number; snapped: boolean } {\n const raw = angleAt(d.pivot, d.cur) - angleAt(d.pivot, d.start);\n const one = d.ids.length === 1 ? m.byId[d.ids[0]] : null;\n // The absolute angle is read off the PROJECTED geometry (identity when\n // un-flagged): the chip and the snap targets speak about what the user SEES\n // — a noRotate shape's on-screen tilt, not its stored one.\n const base = one ? geomRotation(anchoredGeom(one.geom, anchorModeOf(one), d.view)) : 0;\n const angle = normalizeDeg(base + raw);\n if (!m.snap.rotation || d.free) return { delta: raw, angle, snapped: false };\n for (const target of m.snap.rotationAngles) {\n const adjust = arcTo(angle, normalizeDeg(target));\n if (Math.abs(adjust) <= m.snap.rotationThreshold)\n return { delta: raw + adjust, angle: normalizeDeg(target), snapped: true };\n }\n return { delta: raw, angle, snapped: false };\n}\n\n/** A group resize is isotropic (uniform) when ANY selected member is rotated —\n * an off-axis scale across a rotated rect+rot is a shear it can't represent. A\n * vertex member's advisory `rot` counts (preserves obbFromTheta + reset). */\nconst selectionHasRotation = (m: Model, ids: Id[]): boolean =>\n ids.some((id) => geomRotation(m.byId[id]?.geom ?? ({ t: 'caret' } as Geom)) !== 0);\n\nexport function update(m: Model, msg: Msg): [Model, Effect[]] {\n switch (msg.t) {\n case 'editPointer':\n return editPointer(m, msg.phase, msg.in);\n case 'marqueePointer':\n return marqueePointer(m, msg.phase, msg.in);\n case 'createPointer':\n return createPointer(\n m,\n msg.phase,\n msg.subtype,\n msg.in,\n msg.preset,\n msg.intent,\n msg.deferInkCommit,\n msg.straightenInk,\n msg.clickCreate,\n msg.flags,\n );\n case 'finishInkDraft':\n return finishInkCreate(m);\n case 'finishCreationDraft':\n return finishPolyCreate(m);\n case 'createCaret':\n return createCaret(m, msg.pon, msg.rect, msg.flags);\n case 'createReplaceText':\n return createReplaceText(m, msg.pon, msg.rects, msg.endRect, msg.preset);\n case 'createMarkup':\n return createMarkup(m, msg.subtype, msg.pon, msg.rects, msg.preset, msg.flags);\n case 'setMarkupPreview':\n return setMarkupPreview(m, msg.subtype, msg.rectsByPage, msg.preset);\n case 'clearMarkupPreview':\n return m.preview ? [{ ...m, preview: null }, []] : [m, []];\n case 'select': {\n const ids = expandGroups(\n m,\n msg.ids.filter((id) => isSelectable(m, id)),\n );\n if (!ids.length) return [m, []];\n const selected = msg.add ? [...new Set([...m.selected, ...ids])] : ids;\n return [{ ...m, selected }, []];\n }\n case 'deselect': {\n if (!m.selected.length) return [m, []];\n // With `ids`: drop only those (an engaged Behavior retroactively un-selects\n // its annotations — engaged ⇒ not selectable ⇒ not selected). Without: all.\n if (!msg.ids) return [{ ...m, selected: [] }, []];\n const drop = new Set(msg.ids);\n const selected = m.selected.filter((id) => !drop.has(id));\n return selected.length === m.selected.length ? [m, []] : [{ ...m, selected }, []];\n }\n case 'setProps':\n return setProps(m, msg.patch);\n case 'setFlags':\n return setFlags(m, msg.patch, msg.ids);\n case 'setDefaults':\n return setDefaults(m, msg.subtype, msg.patch);\n case 'setSnap':\n return [{ ...m, snap: { ...m.snap, ...msg.patch } }, []];\n case 'rotate90':\n return rotateSelection(m, 90);\n case 'resetRotation':\n return resetRotation(m);\n case 'delete':\n return deleteSelection(m);\n case 'cancel':\n return [{ ...m, draft: null }, []];\n case 'loaded':\n return [mergeLoaded(m, msg.annots), []];\n case 'created':\n return [reconcile(m, msg.tempId, msg.id, msg.ref), []];\n case 'createFailed':\n return [removeAnnots(m, [msg.tempId]), []];\n case 'upsert':\n return [upsertAnnots(m, msg.annots, msg.bumpAp), []];\n case 'bumpAp':\n return [bumpAp(m, msg.ids), []];\n case 'hover':\n // Pure view-model state; the capability diffs before dispatching, so\n // this fires at enter/leave cadence only.\n return m.hovered === msg.id ? [m, []] : [{ ...m, hovered: msg.id }, []];\n case 'remove': {\n const next = removeAnnots(m, msg.ids);\n // A removed annotation can't stay hovered.\n return [next.hovered && !next.byId[next.hovered] ? { ...next, hovered: null } : next, []];\n }\n case 'beginTextEdit':\n // `lockedContents` (or an inert `/F` state) blocks entering text edit —\n // the geometry gates don't apply here: locked-only contents still edit.\n return m.byId[msg.id] && annotContentsEditable(m.byId[msg.id])\n ? [{ ...m, editing: msg.id, selected: [msg.id], draft: null }, []]\n : [m, []];\n case 'setText':\n return setText(m, msg.id, msg.text);\n case 'endTextEdit':\n return m.editing ? [{ ...m, editing: null }, []] : [m, []];\n }\n}\n\n/** Apply the editor's plain text optimistically. Updates `contents` on the\n * DTO-backed model and flips the box to `vector` so the live text shows. Emits\n * NO effect — the plugin owns the (debounced) engine write while you type, so\n * the model never churns mid-keystroke. */\nfunction setText(m: Model, id: Id, text: string): [Model, Effect[]] {\n const a = m.byId[id];\n if (!a) return [m, []];\n const next = toVector({ ...a, data: a.data ? { ...a.data, contents: text } : a.data });\n return [{ ...m, byId: { ...m.byId, [id]: next } }, []];\n}\n\nfunction editPointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n): [Model, Effect[]] {\n if (phase === 'down') return editDown(m, input);\n if (phase === 'move') return m.draft ? editMove(m, input) : [m, []];\n return m.draft ? editUp(m) : [m, []];\n}\n\nfunction editDown(m: Model, input: PointerInput): [Model, Effect[]] {\n // `pageBox` + `chrome` reach the hit-test so the page-bound rotate knob\n // (flipped / clamped near an edge) is grabbed exactly where the chrome drew\n // it, with the caller's (screen-constant) grab zones. The view env rides\n // along so screen-anchored annotations are grabbed where they're PAINTED.\n const hit = hitTest(\n m,\n input.pon,\n input.point,\n input.chrome ?? DEFAULT_CHROME_GEOM,\n m.hitMargin,\n input.pageBox,\n input.inert,\n viewOf(input),\n );\n if (hit.t === 'handle') {\n // The handle gesture runs in VIEW space: `base` is the PROJECTED geometry\n // the user grabbed (identity for un-flagged annotations), and the commit\n // maps the result back via `unanchoredGeom` with the SAME captured view.\n const a = m.byId[hit.id];\n const view = viewOf(input);\n const base = anchoredGeom(a.geom, anchorModeOf(a), view);\n return [\n {\n ...m,\n draft: {\n g: 'handle',\n id: hit.id,\n handle: hit.handle,\n base,\n cur: base,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.t === 'rotate') {\n const view = viewOf(input);\n return [\n {\n ...m,\n draft: {\n g: 'rotate',\n ids: hit.ids,\n pivot: hit.pivot,\n start: input.point,\n cur: input.point,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.t === 'group-handle') {\n const view = viewOf(input);\n return [\n {\n ...m,\n draft: {\n g: 'group',\n op: 'resize',\n ids: hit.ids,\n handle: hit.handle,\n anchor: groupResizeAnchor(hit.box, hit.handle),\n base: hit.box,\n cur: hit.box,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.t === 'annot') {\n // A hit on any member acts on the WHOLE group — select/toggle/drag as a unit.\n const grp = groupMembers(m, hit.id);\n const inSel = m.selected.includes(hit.id);\n const selected = input.shift\n ? inSel\n ? m.selected.filter((x) => !grp.includes(x)) // shift+click a member → drop the group\n : [...m.selected, ...grp.filter((x) => !m.selected.includes(x))]\n : inSel\n ? m.selected\n : grp;\n // Only arm a move gesture if every selected annotation can move; an anchored\n // kind (markup/caret) still selects, it just won't drag.\n const movable = selected.length > 0 && selected.every((id) => canMove(m, id));\n const draft: Draft | null = movable\n ? { g: 'move', ids: selected, start: input.point, delta: { x: 0, y: 0 }, guides: [] }\n : null;\n return [{ ...m, selected, draft }, []];\n }\n return [{ ...m, selected: [] }, []]; // empty (the handler usually pre-empts via 'deselect')\n}\n\nfunction editMove(m: Model, input: PointerInput): [Model, Effect[]] {\n const d = m.draft!;\n // Foreign coordinate frame (see the page-bound gesture rules above) — ignore.\n const home = editDraftPon(m, d);\n if (home != null && input.pon !== home) return [m, []];\n if (d.g === 'move') {\n const view = viewOf(input);\n const raw = clampMoveDelta(m, d.ids, sub(input.point, d.start), input.pageBox, view);\n if (!m.snap.guides || input.shift)\n return [{ ...m, draft: { ...d, delta: raw, guides: [] } }, []];\n // Snap guides read STORED geometry (an anchored mover aligns by its /Rect\n // box) — a deliberate simplification; the clamp above is view-exact.\n const snap = computeMoveSnap(m, d.ids, input.pon, raw, m.snap.guideThreshold, input.pageBox);\n // A snap adjusts by ≤ threshold, but never past the page edge: re-clamp, and\n // drop the guide on an axis the clamp took back (its line would be a lie).\n const delta = clampMoveDelta(m, d.ids, snap.delta, input.pageBox, view);\n const guides = snap.guides.filter((g) =>\n g.axis === 'x' ? delta.x === snap.delta.x : delta.y === snap.delta.y,\n );\n return [{ ...m, draft: { ...d, delta, guides } }, []];\n }\n const point = clampPointToBox(input.point, input.pageBox);\n if (d.g === 'handle')\n return [{ ...m, draft: { ...d, cur: geomDragHandle(d.base, d.handle, point) } }, []];\n // Rotation reads the pointer as an ANGLE about the pivot — the raw point is\n // valid (and better) outside the page; the geometry itself never translates.\n // `free` (shift) records the snap bypass for this sample.\n if (d.g === 'rotate') return [{ ...m, draft: { ...d, cur: input.point, free: input.shift } }, []];\n if (d.g === 'group') {\n const iso = selectionHasRotation(m, d.ids);\n return [{ ...m, draft: { ...d, cur: groupResizeBox(d.base, d.handle, point, iso) } }, []];\n }\n return [m, []];\n}\n\nfunction editUp(m: Model): [Model, Effect[]] {\n const d = m.draft!;\n if (d.g === 'handle') {\n // A grab that didn't actually resize leaves the appearance untouched → keep\n // it baked, no engine write.\n if (geomEqual(d.base, d.cur)) return [{ ...m, draft: null }, []];\n // A resize changes the appearance: we own it now → live (vector) render\n // (opaque-body kinds stay baked; the engine re-fits their AP natively).\n // `cur` is VIEW-space (the projected geometry the user dragged); the\n // commit maps it back to stored space — the identity when un-flagged.\n const before = m.byId[d.id];\n const stored = unanchoredGeom(d.cur, anchorModeOf(before), d.view);\n const a = ownGeometry({ ...before, geom: stored });\n return [{ ...m, byId: { ...m.byId, [d.id]: a }, draft: null }, [patchFx(d.id, a, before.geom)]];\n }\n if (d.g === 'rotate') {\n const { delta } = rotateDraftDelta(m, d);\n if (Math.abs(delta) < 0.01) return [{ ...m, draft: null }, []];\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of d.ids) {\n const a = byId[id];\n if (!a) continue;\n // rotation re-bakes the appearance → live (vector) render + patch. The\n // gesture composed in VIEW space (`effGeom`); the commit replays the\n // same composition and unprojects — a screen-anchored member's AUTHORED\n // tilt turns WYSIWYG, exactly as previewed.\n const geom = commitViewGesture(a, d.view, (g) => geomRotateAbout(g, d.pivot, delta));\n byId[id] = ownGeometry({ ...a, geom });\n fx.push(patchFx(id, byId[id], a.geom));\n }\n return [{ ...m, byId, draft: null }, fx];\n }\n if (d.g === 'group') {\n const { sx, sy } = groupResizeFactors(d.base, d.cur);\n if (Math.abs(sx - 1) < 1e-4 && Math.abs(sy - 1) < 1e-4) return [{ ...m, draft: null }, []];\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of d.ids) {\n const a = byId[id];\n if (!a) continue;\n const geom = commitViewGesture(a, d.view, (g) => geomScaleAbout(g, d.anchor, sx, sy));\n byId[id] = ownGeometry({ ...a, geom });\n fx.push(patchFx(id, byId[id], a.geom));\n }\n return [{ ...m, byId, draft: null }, fx];\n }\n if (d.g === 'move') {\n if (Math.hypot(d.delta.x, d.delta.y) < 0.01) return [{ ...m, draft: null }, []]; // a click\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of d.ids) {\n const a = byId[id];\n // A move is a rigid translation — the appearance is unchanged, so a baked\n // annotation STAYS baked and its raster box rides along. Source preserved.\n byId[id] = {\n ...a,\n geom: geomTranslate(a.geom, d.delta),\n apBox: a.apBox ? translateRect(a.apBox, d.delta) : undefined,\n };\n fx.push({ fx: 'patch', id, scope: { kind: 'geometry' } }); // a move never invalidates the raster\n }\n return [{ ...m, byId, draft: null }, fx];\n }\n return [{ ...m, draft: null }, []];\n}\n\nfunction marqueePointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n): [Model, Effect[]] {\n // The marquee lives on one page and pins to its box (same rules as editMove).\n const point = clampPointToBox(input.point, input.pageBox);\n if (phase === 'down') {\n return [{ ...m, draft: { g: 'marquee', pon: input.pon, from: point, to: point } }, []];\n }\n if (m.draft?.g !== 'marquee') return [m, []];\n if (m.draft.pon !== input.pon) return [m, []]; // foreign frame — ignore\n if (phase === 'move') {\n return [{ ...m, draft: { ...m.draft, to: point } }, []];\n }\n\n // A marquee that touches one member takes the whole group with it.\n const hits = expandGroups(\n m,\n annotsInBox(m, m.draft.pon, m.draft.from, point, input.inert, viewOf(input)),\n );\n const selected = input.shift ? toggleSelection(m.selected, hits) : hits;\n return [{ ...m, selected, draft: null }, []];\n}\n\nfunction toggleSelection(base: Id[], ids: Id[]): Id[] {\n const next = new Set(base);\n for (const id of ids) {\n if (next.has(id)) next.delete(id);\n else next.add(id);\n }\n return [...next];\n}\n\nfunction createPointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n subtype: Subtype,\n input: PointerInput,\n preset: string = subtype,\n intent?: InkIntent,\n deferInkCommit = false,\n straightenInk?: InkStraightenOptions,\n clickCreate?: ClickCreate | false,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n // An in-progress creation is anchored to its page: a move/up sample from\n // another page is a foreign frame — ignore it. (A DOWN on another page is a\n // fresh intent: the per-subtype branches below start/restart the draft there.)\n if (phase !== 'down' && m.draft && 'pon' in m.draft && m.draft.pon !== input.pon) return [m, []];\n // Shapes can't be drawn past the page edge — the pointer pins to it.\n if (input.pageBox) input = { ...input, point: clampPointToBox(input.point, input.pageBox) };\n if (subtype === 'free-text-callout') return calloutPointer(m, phase, input, preset, flags);\n if (phase === 'down') {\n if (isPolySubtype(subtype)) {\n if (input.finish) return finishPolyCreate(m);\n if (\n m.draft?.g === 'create-poly' &&\n m.draft.subtype === subtype &&\n m.draft.pon === input.pon\n ) {\n return [\n {\n ...m,\n draft: { ...m.draft, points: [...m.draft.points, input.point], cur: input.point },\n },\n [],\n ];\n }\n return [\n {\n ...m,\n selected: [],\n draft: {\n g: 'create-poly',\n subtype,\n preset,\n pon: input.pon,\n points: [input.point],\n cur: input.point,\n closed: subtype === 'polygon',\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n const draft: Draft | null =\n subtype === 'line'\n ? {\n g: 'create-line',\n subtype,\n preset,\n pon: input.pon,\n from: input.point,\n to: input.point,\n ...(clickCreate !== undefined ? { clickCreate } : {}),\n ...(flags ? { flags } : {}),\n }\n : subtype === 'ink'\n ? m.draft?.g === 'create-ink' &&\n m.draft.subtype === subtype &&\n m.draft.preset === preset &&\n m.draft.pon === input.pon\n ? { ...m.draft, strokes: [...m.draft.strokes, [input.point]] }\n : {\n g: 'create-ink',\n subtype,\n preset,\n pon: input.pon,\n strokes: [[input.point]],\n intent,\n ...(flags ? { flags } : {}),\n }\n : subtype === 'square' ||\n subtype === 'circle' ||\n subtype === 'free-text' ||\n subtype === 'redact' ||\n subtype === 'link'\n ? {\n g: 'create-rect',\n subtype,\n preset,\n pon: input.pon,\n from: input.point,\n to: input.point,\n ellipse: subtype === 'circle',\n // Captured at DOWN (the gesture's home page); a rotation of 0\n // makes upright a no-op, so the draft stays clean then.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(clickCreate !== undefined ? { clickCreate } : {}),\n ...(flags ? { flags } : {}),\n }\n : null;\n return draft ? [{ ...m, selected: [], draft }, []] : [m, []];\n }\n if (phase === 'move') {\n if (m.draft?.g === 'create-poly') {\n return [{ ...m, draft: { ...m.draft, cur: input.point } }, []];\n }\n if (m.draft?.g === 'create-rect' || m.draft?.g === 'create-line') {\n return [{ ...m, draft: { ...m.draft, to: input.point } }, []];\n }\n if (m.draft?.g === 'create-ink') {\n // append to the active (last) stroke as the pen moves\n const strokes = m.draft.strokes.slice();\n strokes[strokes.length - 1] = [...strokes[strokes.length - 1], input.point];\n return [{ ...m, draft: { ...m.draft, strokes } }, []];\n }\n return [m, []];\n }\n // up\n const d = m.draft;\n if (d?.g !== 'create-rect' && d?.g !== 'create-line' && d?.g !== 'create-ink') return [m, []];\n\n if (d.g === 'create-ink') {\n let next = m;\n if (straightenInk && d.strokes.length) {\n const strokes = d.strokes.slice();\n const last = strokes.length - 1;\n strokes[last] = straightenInkStroke(strokes[last], straightenInk);\n next = { ...m, draft: { ...d, strokes } };\n }\n return deferInkCommit ? [next, []] : finishInkCreate(next);\n }\n\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const style = styleFromProps(def);\n let geom: Geom | null = null;\n // The upright counter-rotation for a BOX commit (0 when the tool/page don't\n // ask for one). A DRAGGED box keeps the on-screen footprint the author drew:\n // for a quarter-turn the unrotated box is the drag rect TRANSPOSED about its\n // centre, so spinning it by `rot` lands exactly back on the dragged region.\n const upRot =\n d.g === 'create-rect' && d.upright && d.displayRotation\n ? uprightRotation(d.displayRotation)\n : 0;\n const uprightBox = (dragged: Rect): Rect =>\n upRot === 90 || upRot === 270 ? transposedAboutCenter(dragged) : dragged;\n // Click commits resolve through the SHARED placement layer (placement.ts) —\n // the same `resolveClickPlacement` the footprint ghost and the form plugin\n // consume, so preview ≡ commit by construction. The core only supplies the\n // kind-level fallback for free text (a click must always yield a typable\n // box) and converts the placement to a Geom via `clickCreateGeom`.\n const clickGeom = (policy: ClickCreate): Geom | null =>\n clickCreateGeom(\n d.subtype,\n resolveClickPlacement(d.from, policy, {\n pageBox: input.pageBox,\n upright: d.g === 'create-rect' ? d.upright : undefined,\n displayRotation: d.g === 'create-rect' ? d.displayRotation : undefined,\n }),\n def,\n );\n if (d.g === 'create-rect' && d.subtype === 'free-text') {\n // Free-text: a dragged box, or — on a mere click — a default box you can\n // immediately type into (created unless the tool says `clickCreate: false`;\n // an empty text box is unreachable by drag alone, hence the kind-level\n // fallback: 180×40, top-left anchored so the box hangs where you'll type).\n const dragged = rectFromPoints(d.from, d.to);\n const isClick = dragged.width < MIN_DRAG && dragged.height < MIN_DRAG;\n if (!isClick) {\n geom = { t: 'text', rect: uprightBox(dragged), ...(upRot ? { rot: upRot } : {}) };\n } else if (d.clickCreate !== false) {\n geom = clickGeom(\n d.clickCreate && 'width' in d.clickCreate\n ? d.clickCreate\n : { width: 180, height: 40, anchor: 'top-left' },\n );\n }\n } else if (d.g === 'create-rect') {\n const dragged = rectFromPoints(d.from, d.to);\n if (dragged.width >= MIN_DRAG || dragged.height >= MIN_DRAG) {\n // cloudy stores the OUTER box (dragged + extent) so the dragged box is its inner edge\n geom = {\n t: 'rect',\n rect: shapeRectFor(uprightBox(dragged), d.ellipse, style),\n ellipse: d.ellipse,\n ...(upRot ? { rot: upRot } : {}),\n };\n } else if (d.clickCreate && 'width' in d.clickCreate) {\n geom = clickGeom(d.clickCreate);\n }\n } else if (d.g === 'create-line') {\n if (Math.hypot(d.to.x - d.from.x, d.to.y - d.from.y) >= MIN_DRAG) {\n geom = { t: 'line', a: d.from, b: d.to, ends: def.lineEndings };\n } else if (d.clickCreate && 'length' in d.clickCreate) {\n geom = clickGeom(d.clickCreate);\n }\n }\n if (!geom) return [{ ...m, draft: null }, []];\n\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: d.subtype,\n geom,\n style,\n // A text kind carries its text styling from birth, so the tool's font\n // defaults actually apply to what you draw.\n ...(geom.t === 'text' ? { text: textStyleFromProps(def) } : {}),\n // A drawn link starts at the tool preset's target ('docs-link' style\n // presets), or dead (`null` — the create-then-edit flow).\n ...(d.subtype === 'link' ? { link: def.link ?? null } : {}),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n // A freshly drawn free-text box opens straight into edit (type immediately).\n editing: geom.t === 'text' ? id : m.editing,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Commit all strokes accumulated by a grouped ink gesture. */\nfunction finishInkCreate(m: Model): [Model, Effect[]] {\n const d = m.draft;\n if (d?.g !== 'create-ink') return [m, []];\n const points = d.strokes.flat();\n if (!d.strokes.some((stroke) => stroke.length >= 2) || points.length === 0)\n return [{ ...m, draft: null }, []];\n const bounds = unionRect(points);\n if (Math.max(bounds.width, bounds.height) < MIN_DRAG) return [{ ...m, draft: null }, []];\n\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: d.subtype,\n geom: { t: 'ink', strokes: d.strokes },\n style: styleFromProps(defaultsFor(m, d.preset ?? d.subtype)),\n ...(d.intent ? { intent: d.intent } : {}),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Default text-box size for a callout placed with a click (no box drag). */\nconst CALLOUT_BOX = { width: 150, height: 40 };\n\n/** The callout draft's upright counter-rotation (deg CW; 0 = none) — the SAME\n * rule the rect commit applies, shared by `calloutBox`, the ghost preview and\n * the commit so all three agree by construction. */\nexport function calloutUprightRot(d: Extract<Draft, { g: 'create-callout' }>): number {\n return d.upright && d.displayRotation ? uprightRotation(d.displayRotation) : 0;\n}\n\n/**\n * The text-box rect for an in-progress callout's `box` step — the ONE rule both\n * the live preview and the commit use, so what you see is what you get. Only a\n * drag past `MIN_DRAG` sizes the box; a press-without-drag (a click) keeps the\n * default-size box anchored at the press point, so it never collapses to a sliver\n * while you decide whether you're dragging (the \"bounce\"). Before the press\n * (hover), the default box tracks the cursor.\n *\n * Under `upright` this returns the UNROTATED logical box (the frame text is laid\n * out in): a DRAGGED box keeps the on-screen footprint the author drew (quarter\n * turns transpose it about its centre — spinning by `rot` lands exactly back on\n * the dragged region), and the default box anchors so its DISPLAYED top-left\n * hangs at the point, down-right of the cursor as the author sees it — the same\n * two rules the free-text drag/click commits use.\n */\nexport function calloutBox(d: Extract<Draft, { g: 'create-callout' }>): Rect {\n const rot = calloutUprightRot(d);\n const quarter = rot === 90 || rot === 270;\n const defaultBox = (at: Vec): Rect =>\n rot\n ? uprightAnchoredRect(at, CALLOUT_BOX.width, CALLOUT_BOX.height, d.displayRotation!)\n : { x: at.x, y: at.y, ...CALLOUT_BOX };\n if (d.boxFrom) {\n const dragged = d.boxTo ? rectFromPoints(d.boxFrom, d.boxTo) : null;\n if (dragged && (dragged.width >= MIN_DRAG || dragged.height >= MIN_DRAG))\n return quarter ? transposedAboutCenter(dragged) : dragged;\n return defaultBox(d.boxFrom);\n }\n return defaultBox(d.cur);\n}\n\n/**\n * The free-text callout's multi-step creation, a v2-style 3-click flow:\n * click 1 (down) → set the leader `tip`, advance to the `knee` step\n * hover/move → preview the leader to the cursor\n * click 2 (down) → set the `knee`, advance to the `box` step\n * drag/click (up) → lay the text box (dragged, or a default box on a click)\n * Commit creates a `free-text` annotation with a `callout` geom and opens it for\n * editing — the connection point to the box is always derived, never stored.\n */\nfunction calloutPointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n preset: string = 'free-text-callout',\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const d = m.draft;\n if (phase === 'down') {\n if (d?.g !== 'create-callout' || d.pon !== input.pon) {\n return [\n {\n ...m,\n selected: [],\n draft: {\n g: 'create-callout',\n subtype: 'free-text-callout',\n preset,\n pon: input.pon,\n step: 'knee',\n tip: input.point,\n cur: input.point,\n // Captured at the TIP click (the gesture's home page) — the box\n // step may span later samples that don't carry the rotation. A\n // rotation of 0 makes upright a no-op, so the draft stays clean.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n if (d.step === 'knee') {\n return [{ ...m, draft: { ...d, knee: input.point, step: 'box', cur: input.point } }, []];\n }\n // box step: begin the box drag at this point\n return [{ ...m, draft: { ...d, boxFrom: input.point, boxTo: input.point } }, []];\n }\n if (phase === 'move') {\n if (d?.g !== 'create-callout') return [m, []];\n if (d.step === 'box' && d.boxFrom) return [{ ...m, draft: { ...d, boxTo: input.point } }, []];\n return [{ ...m, draft: { ...d, cur: input.point } }, []];\n }\n // up: only the box step (with a started box) commits; the tip/knee clicks no-op.\n if (d?.g !== 'create-callout' || d.step !== 'box' || !d.boxFrom) return [m, []];\n const rect = calloutBox(d); // the SAME box the preview showed\n // The upright counter-rotation applies to the text BOX only (about its own\n // centre) — the leader tip/knee are page-space anchors and never turn.\n const rot = calloutUprightRot(d);\n const def = defaultsFor(m, d.preset ?? 'free-text-callout');\n const ending = def.lineEndings.end !== 'none' ? def.lineEndings.end : 'open-arrow';\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: 'free-text',\n geom: {\n t: 'text',\n rect,\n callout: { tip: d.tip, knee: d.knee, ending },\n ...(rot ? { rot } : {}),\n },\n style: styleFromProps(def),\n text: textStyleFromProps(def),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n editing: id,\n },\n [{ fx: 'create', id }],\n ];\n}\n\nfunction finishPolyCreate(m: Model): [Model, Effect[]] {\n const d = m.draft;\n if (d?.g !== 'create-poly') return [m, []];\n const minPoints = d.closed ? 3 : 2;\n if (d.points.length < minPoints) return [{ ...m, draft: null }, []];\n\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const geom: Geom = {\n t: 'poly',\n points: d.points,\n closed: d.closed,\n ends: d.closed ? undefined : def.lineEndings,\n };\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: d.subtype,\n geom,\n style: styleFromProps(def),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Per-line selection rects → /QuadPoints quads (content space, y-down: UL, UR,\n * LL, LR). Shared by markup creation and the live preview. */\nconst rectsToQuads = (rects: Rect[]): Quad[] =>\n rects\n .filter((r) => r.width > 0 && r.height > 0)\n .map((r) => [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x, y: r.y + r.height },\n { x: r.x + r.width, y: r.y + r.height },\n ]);\n\n/**\n * Build a text-markup annotation from the selection's per-line rects. The new\n * annotation is `vector` (rendered live by the overlay) and selected, mirroring\n * `createPointer`. One call per page the selection spans. Clears any live preview.\n */\nfunction createMarkup(\n m: Model,\n subtype: Subtype,\n pon: Annot['pon'],\n rects: Rect[],\n preset: string = subtype,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const quads = rectsToQuads(rects);\n if (!quads.length) return [m, []];\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon,\n subtype,\n geom: { t: 'quads', quads },\n style: styleFromProps(defaultsFor(m, preset)),\n flags: { ...DRAWN_FLAGS, ...flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n preview: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/**\n * Create Adobe-compatible Replace Text as one optimistic logical annotation:\n * a top-level Caret (`/IT /Replace`) plus a StrikeOut subordinate\n * (`/IT /StrikeOutTextEdit`, `/IRT` caret, `/RT /Group`). Persistence performs\n * the two ordered writes and rolls the primary back if the subordinate fails.\n */\nfunction createReplaceText(\n m: Model,\n pon: Annot['pon'],\n rects: Rect[],\n textEndRect: Rect,\n preset = 'replace-text',\n): [Model, Effect[]] {\n const quads = rectsToQuads(rects);\n if (!quads.length || textEndRect.width <= 0 || textEndRect.height <= 0) return [m, []];\n const primaryId = `tmp:${m.seq + 1}`;\n const strikeoutId = `tmp:${m.seq + 2}`;\n const style = styleFromProps(defaultsFor(m, preset));\n const caret: Annot = {\n id: primaryId,\n ref: null,\n pon,\n subtype: 'caret',\n intent: 'replace',\n geom: { t: 'caret', rect: caretRectFromTextEnd(textEndRect) },\n style,\n flags: DRAWN_FLAGS,\n source: 'vector',\n };\n const strikeout: Annot = {\n id: strikeoutId,\n ref: null,\n pon,\n subtype: 'strikeout',\n intent: 'strikeout-text-edit',\n geom: { t: 'quads', quads },\n style,\n flags: DRAWN_FLAGS,\n source: 'vector',\n irt: primaryId,\n group: primaryId,\n };\n return [\n {\n ...m,\n seq: m.seq + 2,\n byId: { ...m.byId, [primaryId]: caret, [strikeoutId]: strikeout },\n order: [...m.order, primaryId, strikeoutId],\n selected: [primaryId, strikeoutId],\n draft: null,\n preview: null,\n },\n [{ fx: 'createGroup', primary: primaryId, members: [strikeoutId] }],\n ];\n}\n\nfunction createCaret(\n m: Model,\n pon: Annot['pon'],\n textEndRect: Rect,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n if (textEndRect.width <= 0 || textEndRect.height <= 0) return [m, []];\n const id = `tmp:${m.seq + 1}`;\n const def = defaultsFor(m, 'caret');\n const annot: Annot = {\n id,\n ref: null,\n pon,\n subtype: 'caret',\n geom: { t: 'caret', rect: caretRectFromTextEnd(textEndRect) },\n style: styleFromProps(def),\n flags: { ...DRAWN_FLAGS, ...flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n preview: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Set / replace the live markup preview from the selection's per-page rects. */\nfunction setMarkupPreview(\n m: Model,\n subtype: Subtype,\n rectsByPage: Record<number, Rect[]>,\n preset: string = subtype,\n): [Model, Effect[]] {\n const byPage: Record<number, Quad[]> = {};\n for (const k in rectsByPage) {\n const quads = rectsToQuads(rectsByPage[k]);\n if (quads.length) byPage[Number(k)] = quads;\n }\n return [{ ...m, preview: { subtype, preset, byPage } }, []];\n}\n\n/**\n * Apply a flat property patch to the current selection. Each member takes only\n * the keys its KIND declares (see `applyProps` — routing to `style`, `geom.ends`\n * or `text` happens there) and ignores the rest, so one patch restyles a mixed\n * selection. Changed members flip to `vector` (we own the appearance now) and\n * emit one engine patch each. The base style / tool defaults are NEVER touched:\n * editing existing annotations must not change what the next drawn one looks like.\n */\nfunction setProps(m: Model, patch: AnnotationPropsPatch): [Model, Effect[]] {\n if (!m.selected.length) return [m, []];\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n // The effect carries the user's keys VERBATIM — the shell lowers exactly\n // this intent to wire fields; the changed-prop set IS the artifact.\n const keys = (Object.keys(patch) as PropKey[]).filter((k) => patch[k] !== undefined);\n for (const id of m.selected) {\n const a = byId[id];\n if (!a) continue;\n const next = applyProps(a, patch);\n if (!next) continue; // locked, or no declared key in the patch\n // The `link` slot is NOT appearance: on a non-link kind it is the folded\n // attached-link target, materialized as separate child annotations. A\n // link-only change therefore keeps the render source, skips the engine\n // patch, and emits the declarative `syncLink` instead — the shell's\n // reconciler owns the child operations. Slot spreads in `applyProps`\n // make the identity checks exact.\n const linkChanged = next.link !== a.link;\n const otherChanged =\n next.style !== a.style ||\n next.geom !== a.geom ||\n next.text !== a.text ||\n next.icon !== a.icon;\n // A restyle flips to vector (we own the appearance now) — EXCEPT\n // `opaqueBody` kinds (widgets), which have no vector render: they stay\n // baked and the shell re-fetches the engine's re-baked raster on resolve.\n // Flipping them would also drop them out of `appearanceEpoch`, freezing\n // their raster forever.\n byId[id] = capsFor(a.subtype).opaqueBody || !otherChanged ? next : toVector(next);\n // The link KIND's target lives on its own DTO — a plain engine patch.\n if (otherChanged || (linkChanged && a.subtype === 'link'))\n fx.push({ fx: 'patch', id, scope: { kind: 'props', keys } });\n if (linkChanged && a.subtype !== 'link') fx.push({ fx: 'syncLink', id });\n }\n return fx.length ? [{ ...m, byId }, fx] : [m, []];\n}\n\n/**\n * Merge a `/F` flags patch into the selection (or explicit ids). NOT the props\n * path, on purpose: flags aren't appearance — members keep their render\n * `source` (a baked raster stays valid; nothing re-bakes) — and the write is\n * NOT gated by `locked`, because unlocking a locked annotation is the whole\n * point (Acrobat's Locked checkbox stays live). One `flags` effect per changed\n * COMMITTED member; uncommitted drafts just merge (their create draft carries\n * the flags when it commits).\n */\nfunction setFlags(m: Model, patch: Partial<AnnotationFlags>, ids?: Id[]): [Model, Effect[]] {\n const targets = ids ?? m.selected;\n if (!targets.length) return [m, []];\n const fx: Effect[] = [];\n let byId: Model['byId'] | null = null;\n for (const id of targets) {\n const a = (byId ?? m.byId)[id];\n if (!a) continue;\n const flags = mergeFlags(a.flags, patch);\n if (flagsEqual(flags, a.flags)) continue; // no spurious engine writes\n byId ??= { ...m.byId };\n byId[id] = { ...a, flags };\n if (a.ref) fx.push({ fx: 'flags', id });\n }\n return byId ? [{ ...m, byId }, fx] : [m, []];\n}\n\nfunction setDefaults(m: Model, subtype: Subtype, patch: AnnotationPropsPatch): [Model, Effect[]] {\n const prev = m.defaults[subtype] ?? {};\n const next: AnnotationPropsPatch = { ...prev, ...patch };\n // Endings merge per side, so `{ end: 'open-arrow' }` keeps a configured start.\n if (patch.lineEndings) next.lineEndings = { ...prev.lineEndings, ...patch.lineEndings };\n return [{ ...m, defaults: { ...m.defaults, [subtype]: next } }, []];\n}\n\n/**\n * Rotate the current selection by `deltaDeg` (clockwise) — the toolbar\n * \"rotate 90°\" affordance. A single shape turns about its own centre; a\n * multi-target group about the union-box centre (gated by `groupRotatable` for\n * groups, `rotatable` for a single shape). Emits one patch per rotated member.\n */\nfunction rotateSelection(m: Model, deltaDeg: number): [Model, Effect[]] {\n const ids = m.selected.filter((id) => {\n const a = m.byId[id];\n return a && annotTransformable(a) && capsFor(a.subtype).rotatable;\n });\n if (!ids.length) return [m, []];\n // pivot: a single shape's own selection-rect centre (so vertex kinds spin in\n // place, not about their off-centre vertex mean); a group's union-box centre.\n // Stored space throughout — a screen-anchored member's AUTHORED tilt turns,\n // which is exactly its on-screen tilt (the display adds nothing to it); at\n // high zoom the anchor may re-seat by a hair, which the toolbar action\n // accepts (the knob gesture, which is pointer-exact, goes through the\n // view-space commit instead).\n let pivot: Vec;\n if (ids.length === 1) {\n const a = m.byId[ids[0]];\n pivot = selectionCenter(a.geom, a.style.strokeWidth);\n } else {\n const pon = m.byId[ids[0]].pon;\n const union = groupUnionBounds({ ...m, selected: ids }, pon);\n if (!union) return [m, []];\n pivot = { x: union.x + union.width / 2, y: union.y + union.height / 2 };\n }\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of ids) {\n const a = byId[id];\n const before = a.geom;\n byId[id] = ownGeometry({ ...a, geom: geomRotateAbout(before, pivot, deltaDeg) });\n fx.push(patchFx(id, byId[id], before));\n }\n return [{ ...m, byId }, fx];\n}\n\n/** Reset rotation on the selection to the as-authored orientation. For a\n * screen-anchored annotation that IS its on-screen orientation, so reset is\n * as meaningful as for anyone else. */\nfunction resetRotation(m: Model): [Model, Effect[]] {\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of m.selected) {\n const a = byId[id];\n if (!a || !annotTransformable(a) || geomRotation(a.geom) === 0) continue;\n byId[id] = ownGeometry({ ...a, geom: geomResetRotation(a.geom) });\n fx.push(patchFx(id, byId[id], a.geom));\n }\n return fx.length ? [{ ...m, byId }, fx] : [m, []];\n}\n\nfunction deleteSelection(m: Model): [Model, Effect[]] {\n // `locked` (and inert `/F` states) protect against deletion — only the\n // transformable members go; the rest keep their selection, so a mixed\n // selection deletes what it may and leaves the frozen ones visibly selected.\n const deletable = m.selected.filter((id) => {\n const a = m.byId[id];\n return !!a && annotTransformable(a);\n });\n if (!deletable.length) return [m, []];\n const fx: Effect[] = [];\n for (const id of deletable) {\n const a = m.byId[id];\n if (a?.ref) fx.push({ fx: 'delete', ref: a.ref });\n // Attached link children die with their parent — besides the shell's\n // reconciler, this is the ONE other consumer of `linkRefs`. (The\n // children aren't model annotations, so `removeAnnots` never sees them.)\n for (const childRef of a?.linkRefs ?? []) fx.push({ fx: 'delete', ref: childRef });\n }\n return [removeAnnots(m, deletable), fx];\n}\n\n/* ── marquee helper; exported for tests ───────────────────────────────────── */\nexport function annotsInBox(\n m: Model,\n pon: number,\n a: Vec,\n b: Vec,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Id[] {\n const box = rectFromPoints(a, b);\n return m.order.filter((id) => {\n const annot = m.byId[id];\n if (annot?.pon !== pon || inert?.has(id) || !isSelectable(m, id)) return false;\n // intersect against what is actually DRAWN: the oriented selection quad\n // (exact, via SAT) — the SAME quad the chrome outlines and the grab region\n // uses (screen-anchored bodies at their view-projected footprint). Its\n // AABB is a coarse superset whose empty corners cover most of a tilted\n // shape's unrotated footprint, so testing the AABB selected shapes the\n // marquee never touched.\n const g = anchoredGeom(annot.geom, anchorModeOf(annot), view);\n return quadIntersectsRect(selectionQuad(g, annot.style.strokeWidth, annot.style.border), box);\n });\n}\n\n/* ── store maintenance ───────────────────────────────────────────────────── */\n\nfunction mergeLoaded(m: Model, annots: Annot[]): Model {\n const byId = { ...m.byId };\n const order = [...m.order];\n for (const a of annots) {\n if (byId[a.id]) continue;\n byId[a.id] = a;\n order.push(a.id);\n }\n return { ...m, byId, order };\n}\n\n/**\n * Add-or-replace by id. Unlike `mergeLoaded` (which skips ids it already has,\n * for the bulk page read), this OVERWRITES — it's how the data API re-syncs an\n * annotation from the authoritative engine DTO and how a remote edit lands.\n * New ids append to `order`; existing ones keep their position. An annotation\n * currently being dragged (its id is in a `move`/`handle` draft) is left as-is\n * so a remote echo can't yank geometry out from under the local gesture.\n */\nfunction upsertAnnots(m: Model, annots: Annot[], bumpAp = false): Model {\n const dragging = draftIds(m.draft);\n const byId = { ...m.byId };\n const order = [...m.order];\n for (const a of annots) {\n if (dragging.has(a.id)) continue;\n if (!byId[a.id]) order.push(a.id);\n const prev = byId[a.id];\n // The attached-link fold (`link` + `linkRefs` on a NON-link kind) is\n // model-owned, like `apVersion`: a DTO-derived re-sync knows nothing of\n // it, so an upsert that doesn't carry `linkRefs` PRESERVES the fold.\n // The reconciler's own refreshes pass `linkRefs` explicitly ([] to\n // clear), which wins here.\n const fold =\n a.linkRefs === undefined && prev?.linkRefs?.length && a.subtype !== 'link'\n ? { link: a.link !== undefined ? a.link : prev.link, linkRefs: prev.linkRefs }\n : {};\n // `apVersion` is model-owned, not DTO-derived: carry it across the replace,\n // +1 when this upsert confirms an engine re-bake with new raster content.\n byId[a.id] = { ...a, ...fold, apVersion: (prev?.apVersion ?? 0) + (bumpAp ? 1 : 0) };\n }\n return { ...m, byId, order };\n}\n\n/** Advance `apVersion` for known ids — an engine /AP re-bake that arrived\n * WITHOUT new model data (a form value write repainting its widgets). */\nfunction bumpAp(m: Model, ids: Id[]): Model {\n let byId: Model['byId'] | null = null;\n for (const id of ids) {\n const a = m.byId[id];\n if (!a) continue;\n byId ??= { ...m.byId };\n byId[id] = { ...a, apVersion: (a.apVersion ?? 0) + 1 };\n }\n return byId ? { ...m, byId } : m;\n}\n\n/** Ids locked by an in-progress local gesture (don't let an upsert clobber them). */\nfunction draftIds(draft: Draft | null): Set<Id> {\n if (!draft) return new Set();\n if (draft.g === 'move') return new Set(draft.ids);\n if (draft.g === 'handle') return new Set([draft.id]);\n if (draft.g === 'rotate' || draft.g === 'group') return new Set(draft.ids);\n return new Set();\n}\n\nfunction removeAnnots(m: Model, ids: Id[]): Model {\n const gone = new Set(ids);\n const byId = { ...m.byId };\n for (const id of ids) delete byId[id];\n return {\n ...m,\n byId,\n order: m.order.filter((id) => !gone.has(id)),\n selected: m.selected.filter((id) => !gone.has(id)),\n draft: null,\n editing: m.editing && gone.has(m.editing) ? null : m.editing,\n };\n}\n\nfunction reconcile(m: Model, tempId: Id, id: Id, ref: AnnotationRef): Model {\n const a = m.byId[tempId];\n if (!a) return m;\n const { [tempId]: _drop, ...rest } = m.byId;\n const byId: Record<Id, Annot> = { ...rest, [id]: { ...a, id, ref } };\n // Composite creations can relate another optimistic annotation to this temp\n // id. Keep the relationship coherent across the temp→durable id swap.\n for (const key of Object.keys(byId)) {\n const other = byId[key]!;\n if (other.irt === tempId || other.group === tempId) {\n byId[key] = {\n ...other,\n ...(other.irt === tempId ? { irt: id } : {}),\n ...(other.group === tempId ? { group: id } : {}),\n };\n }\n }\n return {\n ...m,\n byId,\n order: m.order.map((x) => (x === tempId ? id : x)),\n selected: m.selected.map((x) => (x === tempId ? id : x)),\n // keep the just-drawn box in edit mode across the temp→durable id swap\n editing: m.editing === tempId ? id : m.editing,\n };\n}\n","/**\n * `scene(item)` — the render contract. Turns an annotation render-item into a flat\n * list of fully-PAINTED nodes (geometry + how to paint it). A framework renderer\n * just maps each node to one element and applies `paint`; it owns no per-kind\n * appearance logic, so adding a framework (or a kind) never duplicates drawing.\n *\n * Geometry comes from `geomScene` (shared with hit-testing); paint is layered on\n * here. Text markup is the one family whose paint varies per node (highlight FILLS,\n * underline/strikeout/squiggly STROKE, widths derived from the line height), so it\n * has its own small painter — but it still emits the same generic SceneNodes.\n */\nimport { geomScene } from './geometry';\nimport type {\n Geom,\n Paint,\n Quad,\n Rect,\n RenderItem,\n SceneNode,\n Style,\n Subtype,\n TextStyle,\n} from './types';\n\nconst num = (n: number): number => Number(n.toFixed(3));\n\n/** Uniform paint for a shape/line/poly node. Fill only lands on closed nodes; the\n * dash comes solely from the border style — so a live draft (ghost) previews\n * exactly how the committed annotation will look, not as a dashed hint. */\n/** CSS mix-blend-mode for live vector paint. `normal` needs no style override. */\nexport function blendFor(style: Style): Paint['blend'] {\n return style.blendMode === 'normal' ? undefined : style.blendMode;\n}\n\nfunction shapePaint(style: Style, closed: boolean): Paint {\n return {\n fill: closed ? (style.interiorColor ?? undefined) : undefined,\n stroke: style.color,\n width: style.strokeWidth,\n opacity: style.opacity,\n dash: style.border.kind === 'dashed' ? style.border.dash : undefined,\n // Cloud curls end in deliberate direction reversals (the 22° curl-back\n // tails), which a miter join blows up into spikes. PDFium bakes cloudy\n // borders with `1 j` (round join) for exactly this reason — match it, so\n // the live path and the baked /AP render the same seams.\n ...(style.border.kind === 'cloudy' ? { join: 'round' as const } : {}),\n };\n}\n\n/** A smooth squiggle (quadratic-bezier wave) along a baseline, adapted from v2's\n * tile: one `Q` hump then reflected `T` segments alternate up/down across the run. */\nfunction squigglePath(x: number, y: number, w: number, amp: number): string {\n const half = Math.max(2, amp * 1.5); // half a wavelength\n let d = `M ${num(x)} ${num(y)} Q ${num(x + half / 2)} ${num(y - amp)} ${num(x + half)} ${num(y)}`;\n for (let px = x + half; px + half <= x + w + 0.5; px += half) {\n d += ` T ${num(px + half)} ${num(y)}`;\n }\n return d;\n}\n\n/** Per-subtype markup nodes. Quads are axis-aligned per-line rects (UL,UR,LL,LR);\n * the colour is the markup `/C` (our model keeps stroke==fill). */\nfunction markupScene(subtype: Subtype, quads: Quad[], style: Style): SceneNode[] {\n const color = style.color;\n const opacity = style.opacity;\n const nodes: SceneNode[] = [];\n for (const q of quads) {\n const x = q[0].x;\n const y = q[0].y;\n const w = q[1].x - q[0].x;\n const h = q[2].y - q[0].y;\n if (w <= 0 || h <= 0) continue;\n const lw = Math.min(2.5, Math.max(0.75, h * 0.06));\n if (subtype === 'underline') {\n const yy = y + h - lw;\n nodes.push({\n kind: 'line',\n a: { x, y: yy },\n b: { x: x + w, y: yy },\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else if (subtype === 'strikeout') {\n const yy = y + h / 2;\n nodes.push({\n kind: 'line',\n a: { x, y: yy },\n b: { x: x + w, y: yy },\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else if (subtype === 'squiggly') {\n const amp = Math.min(2, Math.max(1, h * 0.08));\n nodes.push({\n kind: 'path',\n d: squigglePath(x, y + h - amp, w, amp),\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else {\n // highlight: translucent fill with `multiply` so the text reads through it\n nodes.push({\n kind: 'rect',\n rect: { x, y, width: w, height: h },\n paint: { fill: color, opacity, blend: blendFor(style) },\n });\n }\n }\n return nodes;\n}\n\n/** A redact mark's regions: per-quad boxes (text marks) or the rect (area). */\nfunction redactRegions(geom: Geom): Rect[] {\n if (geom.t === 'quads') {\n const out: Rect[] = [];\n for (const q of geom.quads) {\n const w = q[1].x - q[0].x;\n const h = q[2].y - q[0].y;\n if (w > 0 && h > 0) out.push({ x: q[0].x, y: q[0].y, width: w, height: h });\n }\n return out;\n }\n if (geom.t === 'rect') return [geom.rect];\n return [];\n}\n\n/**\n * Redaction label layout — the SAME reading of ISO 32000-2 the engine's\n * apply-time painter uses, as pure math: top-aligned, `/Q` horizontal\n * alignment, `/Repeat` tiling a full grid that FITS the region (no partial\n * glyph bleed — the scene has no clipping). Character advance is estimated\n * (0.55em Helvetica-ish); this is a live preview, the engine bakes the truth.\n */\nexport function layoutRedactLabel(\n region: Rect,\n label: { text: string; repeat: boolean },\n text: TextStyle | undefined,\n): SceneNode[] {\n if (!label.text) return [];\n const fontSize = Math.max(4, text && text.fontSize > 0 ? text.fontSize : region.height * 0.6);\n const charW = fontSize * 0.55;\n const textW = label.text.length * charW;\n const lineH = fontSize * 1.2;\n const paint: Paint = { fill: text?.fontColor ?? '#ffffff', opacity: 1 };\n const base = { fontSize, ...(text?.fontFamily ? { fontFamily: text.fontFamily } : {}), paint };\n const baseline = (rowTop: number) => rowTop + fontSize * 0.95;\n\n if (!label.repeat) {\n if (fontSize > region.height) return [];\n const x =\n text?.textAlign === 'center'\n ? region.x + Math.max(0, (region.width - textW) / 2)\n : text?.textAlign === 'right'\n ? region.x + Math.max(0, region.width - textW)\n : region.x;\n return [{ kind: 'text', at: { x, y: baseline(region.y) }, text: label.text, ...base }];\n }\n\n const cols = Math.max(1, Math.floor((region.width + charW) / (textW + charW)));\n const rows = Math.max(1, Math.floor(region.height / lineH));\n const nodes: SceneNode[] = [];\n for (let r = 0; r < rows && nodes.length < 400; r++) {\n for (let c = 0; c < cols && nodes.length < 400; c++) {\n nodes.push({\n kind: 'text',\n at: { x: region.x + c * (textW + charW), y: baseline(region.y + r * lineH) },\n text: label.text,\n ...base,\n });\n }\n }\n return nodes;\n}\n\n/**\n * Redaction marks: at REST an outline per region, nothing filled. On HOVER\n * the applied-look preview — the `/IC` fill plus the tiled `/OverlayText`\n * label — exactly what the destructive apply will paint. All pure data, so\n * every framework renders the preview from the same scene.\n */\nfunction redactScene(item: RenderItem): SceneNode[] {\n const regions = redactRegions(item.geom);\n if (!item.hovered) {\n const paint = {\n stroke: item.style.color,\n width: item.style.strokeWidth || 1.5,\n opacity: item.style.opacity,\n };\n return regions.map((rect) => ({ kind: 'rect', rect, paint }) as SceneNode);\n }\n const nodes: SceneNode[] = [];\n if (item.style.interiorColor) {\n const fill = { fill: item.style.interiorColor, opacity: 1 };\n for (const rect of regions) nodes.push({ kind: 'rect', rect, paint: fill });\n }\n if (item.label) {\n for (const region of regions) nodes.push(...layoutRedactLabel(region, item.label, item.text));\n }\n return nodes;\n}\n\n/** The full painted scene for one annotation. */\nexport function scene(item: RenderItem): SceneNode[] {\n // Links paint NOTHING: an invisible hit rectangle is the norm (any visible\n // border a PDF authored shows through the page raster). Selection chrome\n // still outlines it, so an editable link is findable when selected.\n if (item.subtype === 'link') return [];\n if (item.subtype === 'redact') return redactScene(item);\n if (item.geom.t === 'quads') return markupScene(item.subtype, item.geom.quads, item.style);\n if (item.geom.t === 'caret') {\n return geomScene(item.geom).map((n) => ({\n ...n,\n paint: {\n fill: item.style.color,\n stroke: item.style.color,\n width: 0.5,\n opacity: item.style.opacity,\n },\n })) as SceneNode[];\n }\n const ink = item.geom.t === 'ink'; // freehand: round the pen-stroke ends (caps)\n return geomScene(item.geom, item.style.strokeWidth, item.style.border).map((n) => {\n const closed =\n n.kind === 'rect' ||\n n.kind === 'ellipse' ||\n n.kind === 'path' ||\n (n.kind === 'poly' && n.closed);\n const paint = { ...shapePaint(item.style, closed), blend: blendFor(item.style) };\n // Ink is freehand: round the pen-stroke ends AND joins. Every other kind keeps\n // the default butt caps + sharp (miter) joins — square corners and poly knees\n // stay crisp.\n return { ...n, paint: ink ? { ...paint, cap: 'round', join: 'round' } : paint } as SceneNode;\n });\n}\n","/**\n * Pure view selectors. `pageItems` is the per-annotation render list (live gesture\n * applied) for customRenderer wrapping; `chrome` is the selection overlay\n * (handles carry their resize cursor, group box, marquee).\n */\nimport {\n chordThrough,\n geomHandles,\n geomRotateAbout,\n geomRotation,\n geomScaleAbout,\n geomTranslate,\n geomVisualBounds,\n groupResizeFactors,\n obbFromGeom,\n placeRotateKnob,\n rectFromPoints,\n rectHandlesFor,\n normalizeDeg,\n rotatePoint,\n selectionBounds,\n selectionQuad,\n shapeRectFor,\n unionRect,\n ROTATE_KNOB_OFFSET,\n} from './geometry';\nimport { groupCaps } from './group';\nimport { isSelectable, paintOrder } from './hit';\nimport { capsFor } from './kinds';\nimport { annotTransformable, viewable } from './flags';\nimport {\n anchoredBox,\n anchoredGeom,\n anchoredStrokeWidth,\n anchorModeOf,\n anchorOf,\n type ViewEnv,\n} from './anchor';\nimport { blendFor } from './scene';\nimport { styleFromProps } from './props';\nimport { calloutBox, calloutUprightRot, defaultsFor, rotateDraftDelta } from './update';\nimport type { Annot, ChromeNode, Geom, Id, Model, Rect, RenderItem, Style, Vec } from './types';\nimport type { CreationDraftAnchor } from './types';\n\nconst DRAFT_ID = '__draft__';\nconst PREVIEW_ID = '__markup_preview__';\n\nconst polyPreviewPoints = (points: Vec[], cur: Vec): Vec[] => {\n const last = points[points.length - 1];\n return last && (cur.x !== last.x || cur.y !== last.y) ? [...points, cur] : points;\n};\n\n/**\n * The gesture-effective geometry, in VIEW space: PROJECT FIRST (screen-\n * anchored bodies to their effective footprint — the identity for everyone\n * else), then apply the live gesture. Gestures compose in view space: the\n * pointer, the drafts' pivots/boxes, and a `handle` draft's geometry all live\n * there already, so ONE code path serves flagged and unflagged annotations —\n * and the commit (`editUp`) maps the same composition back through\n * `unanchoredGeom`, so preview ≡ commit by construction. THE geometry every\n * selector below hands out, so render/chrome/bounds agree with hit.\n */\nfunction effGeom(m: Model, id: Id, view: ViewEnv | undefined): Geom {\n const a = m.byId[id];\n const g = anchoredGeom(a.geom, anchorModeOf(a), view);\n const d = m.draft;\n if (d) {\n if (d.g === 'move' && d.ids.includes(id)) return geomTranslate(g, d.delta);\n if (d.g === 'handle' && d.id === id) return d.cur; // already view space\n if (d.g === 'rotate' && d.ids.includes(id)) {\n // The SAME snapped angle rule the commit uses (see `rotateDraftDelta`).\n return geomRotateAbout(g, d.pivot, rotateDraftDelta(m, d).delta);\n }\n if (d.g === 'group' && d.ids.includes(id)) {\n const { sx, sy } = groupResizeFactors(d.base, d.cur);\n return geomScaleAbout(g, d.anchor, sx, sy);\n }\n }\n return g;\n}\n\n/** Style with the stroke width an anchored VECTOR body renders at (screen-\n * constant line weight); everyone else keeps their style verbatim. */\nfunction effStyle(a: Annot, view: ViewEnv | undefined): Style {\n const mode = anchorModeOf(a);\n if (!mode?.zoom || !view) return a.style;\n return { ...a.style, strokeWidth: anchoredStrokeWidth(a.style.strokeWidth, mode, view) };\n}\n\n/** The blit placement for a baked raster: its box (view space, live move\n * applied) + the rotation to re-apply about the box centre.\n *\n * `opaqueBody` kinds (stamp images): the raster IS the visual, so the box\n * follows EVERY live gesture — the unrotated rect of the effective geometry\n * covers move, resize, and group-scale in one rule, and the effective\n * rotation drives the blit transform (a stamp spins with the gesture).\n *\n * Everyone else blits by the AP `/Rect`: for a screen-anchored annotation\n * that box rides the SAME similarity the geometry projects through\n * (`anchoredBox`), composing its counter-rotation with any engine-stripped\n * `apRot` — so a baked noZoom/noRotate body renders screen-constant too. */\nfunction effAp(m: Model, id: Id, view: ViewEnv | undefined): { box?: Rect; rot?: number } {\n const a = m.byId[id];\n if (capsFor(a.subtype).opaqueBody) {\n const g = effGeom(m, id, view);\n return {\n box: 'rect' in g ? g.rect : a.apBox,\n rot: geomRotation(g) || undefined,\n };\n }\n if (!a.apBox) return { rot: a.apRot };\n const projected = anchoredBox(a.apBox, anchorOf(a.geom), anchorModeOf(a), view);\n let box = projected?.box ?? a.apBox;\n const rot = normalizeDeg((a.apRot ?? 0) + (projected?.rot ?? 0)) || undefined;\n const d = m.draft;\n if (d?.g === 'move' && d.ids.includes(id)) {\n box = { ...box, x: box.x + d.delta.x, y: box.y + d.delta.y };\n }\n return { box, rot };\n}\n\n/** Render source for one annotation: an in-progress resize renders LIVE (the\n * baked raster can't stretch), even though the commit hasn't flipped `source`\n * yet — so the drag is crisp and a no-op grab can revert to baked. */\nfunction effSource(m: Model, id: Id): 'baked' | 'vector' {\n const a = m.byId[id];\n // `opaqueBody` kinds have NO vector render: they stay baked through every\n // gesture — the bitmap stretches with `effApBox` and tilts via the item's\n // live `rot`, then the engine's re-fit appearance replaces it on commit.\n if (capsFor(a.subtype).opaqueBody) return a.source;\n const d = m.draft;\n // A live resize/rotate/group transform must render LIVE — the baked raster\n // can't stretch or tilt — even before the commit flips `source`.\n if (d?.g === 'handle' && d.id === id) return 'vector';\n if ((d?.g === 'rotate' || d?.g === 'group') && d.ids.includes(id)) return 'vector';\n return a.source;\n}\n\n/** A free-text box renders as a LIVE element (editable / reflowing) while it's\n * being edited or while its source is vector (a resize, in-progress or committed);\n * otherwise it renders as the engine's baked /AP image, exactly like a shape. */\nfunction textIsLive(m: Model, id: Id): boolean {\n return m.editing === id || effSource(m, id) === 'vector';\n}\n\nexport function pageItems(m: Model, pon: number, view?: ViewEnv): RenderItem[] {\n const items: RenderItem[] = [];\n // `paintOrder` puts text-layer markups beneath every other kind (back→front),\n // so a highlight drawn after a circle still paints under it — and culls what\n // `/F` hides. The SAME order hit-testing uses, so what you click matches\n // what you see.\n for (const id of paintOrder(m, pon)) {\n const a = m.byId[id];\n // Live (editing / resizing) free-text is rendered by the framework as an editable\n // element (see `textBoxes`); a baked, idle box renders as its engine /AP image —\n // the SAME path shapes use. So only skip text while it's live. A callout is the\n // exception: even while live, its leader/arrow/box-border draw via the vector\n // scene (only its TEXT is the DOM element), so it stays in the render list.\n if (a.geom.t === 'text' && !a.geom.callout && textIsLive(m, id)) continue;\n const geom = effGeom(m, id, view);\n const style = effStyle(a, view);\n // Blit box + rotation for the baked raster (see `effAp`): opaqueBody kinds\n // follow the live effective geometry; everyone else blits by the AP /Rect,\n // projected through the anchor similarity for screen-anchored bodies and\n // composed with any engine-stripped `apRot`.\n const ap = effAp(m, id, view);\n items.push({\n id,\n ref: a.ref,\n subtype: a.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n apBox: ap.box,\n style,\n ...(a.text ? { text: a.text } : {}),\n ...(a.label ? { label: a.label } : {}),\n source: effSource(m, id),\n selected: m.selected.includes(id),\n ...(m.hovered === id ? { hovered: true } : {}),\n rot: geomRotation(geom),\n ...(ap.rot ? { apRot: ap.rot } : {}),\n blend: blendFor(a.style),\n });\n }\n const d = m.draft;\n if (\n (d?.g === 'create-rect' ||\n d?.g === 'create-line' ||\n d?.g === 'create-poly' ||\n d?.g === 'create-ink') &&\n d.pon === pon\n ) {\n // Preview with the tool's RESOLVED defaults (base + per-subtype override), so the\n // ghost is a faithful WYSIWYG of what will commit — not the bare base style. A\n // cloudy rect stores the OUTER box (see `shapeRectFor`), so the cloud grows out\n // from the cursor; a 0-drag draws nothing (skipped, like a solid 0×0).\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const style = styleFromProps(def);\n const dragged = d.g === 'create-rect' ? rectFromPoints(d.from, d.to) : null;\n const geom: Geom | null =\n d.g === 'create-rect'\n ? dragged && (dragged.width > 0 || dragged.height > 0)\n ? { t: 'rect', rect: shapeRectFor(dragged, d.ellipse, style), ellipse: d.ellipse }\n : null\n : d.g === 'create-line'\n ? { t: 'line', a: d.from, b: d.to, ends: def.lineEndings }\n : d.g === 'create-poly'\n ? {\n t: 'poly',\n points: polyPreviewPoints(d.points, d.cur),\n closed: d.closed,\n ends: d.closed ? undefined : def.lineEndings,\n }\n : { t: 'ink', strokes: d.strokes };\n if (geom)\n items.push({\n id: DRAFT_ID,\n ref: null,\n subtype: d.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n style,\n source: 'ghost',\n selected: false,\n });\n }\n // Callout creation ghost: the in-progress leader (tip → cur, then tip → knee →\n // box) and the text-box preview, painted through the SAME vector scene.\n if (d?.g === 'create-callout' && d.pon === pon) {\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const style = styleFromProps(def);\n const ending = def.lineEndings.end !== 'none' ? def.lineEndings.end : 'open-arrow';\n // The box preview carries the SAME upright rot the commit will apply, so\n // the ghost box (and its leader connection) is what you actually get.\n const rot = calloutUprightRot(d);\n const geom: Geom =\n d.step === 'knee'\n ? { t: 'line', a: d.tip, b: d.cur, ends: { start: ending, end: 'none' } }\n : {\n t: 'text',\n rect: calloutBox(d),\n callout: { tip: d.tip, knee: d.knee, ending },\n ...(rot ? { rot } : {}),\n };\n items.push({\n id: DRAFT_ID,\n ref: null,\n subtype: d.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n style,\n source: 'ghost',\n selected: false,\n });\n }\n // Live text-markup preview: the in-progress selection rendered as the markup it\n // will become (same `scene()` paint as the committed annotation).\n const quads = m.preview?.byPage[pon];\n if (m.preview && quads?.length) {\n const geom: Geom = { t: 'quads', quads };\n items.push({\n id: PREVIEW_ID,\n ref: null,\n subtype: m.preview.subtype,\n geom,\n box: geomVisualBounds(geom, 0),\n style: styleFromProps(defaultsFor(m, m.preview.preset)),\n source: 'ghost',\n selected: false,\n });\n }\n return items;\n}\n\n/** One free-text box, geometry only (the live move/resize gesture applied), with\n * its edit flag. The framework renders an editable element here; the plugin\n * layers the DTO-derived text style on top. */\nexport interface TextBox {\n id: Id;\n box: Rect;\n editing: boolean;\n /** Applied rotation (deg, CW). `box` is the UNROTATED text box; the framework\n * rotates the editable element about its centre by this. 0/undefined = none. */\n rot?: number;\n}\n\n/** The free-text boxes on a page — the text counterpart of `pageItems`. */\nexport function textBoxes(m: Model, pon: number, view?: ViewEnv): TextBox[] {\n const out: TextBox[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (a.pon !== pon || a.geom.t !== 'text') continue;\n if (!viewable(a.flags, m.selected.includes(id))) continue; // `/F`-hidden\n if (!textIsLive(m, id)) continue; // baked → rendered as the /AP image instead\n const g = effGeom(m, id, view);\n if (g.t !== 'text') continue;\n out.push({ id, box: g.rect, editing: m.editing === id, rot: geomRotation(g) });\n }\n return out;\n}\n\n/** The currently selected annotations as render items (live gesture applied) —\n * cross-page, for selection-aware toolbars (style + line-ending editing). */\nexport function selectedItems(m: Model, view?: ViewEnv): RenderItem[] {\n const items: RenderItem[] = [];\n for (const id of m.selected) {\n const a = m.byId[id];\n if (!a) continue;\n const geom = effGeom(m, id, view);\n const style = effStyle(a, view);\n items.push({\n id,\n ref: a.ref,\n subtype: a.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n style,\n source: a.source,\n selected: true,\n rot: geomRotation(geom),\n });\n }\n return items;\n}\n\nconst boxCorners = (r: Rect): [Vec, Vec, Vec, Vec] => [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x + r.width, y: r.y + r.height },\n { x: r.x, y: r.y + r.height },\n];\n\n/**\n * The union of the selection's bounds on `pon`, reading each member through\n * `geomOf` — `effGeom` for the group chrome, so the outline/handles/knob RIDE\n * a live move/scale exactly like single-selection chrome; the COMMITTED\n * geometry for a rotate gesture's rest anchor. Hit-testing keeps its own\n * committed union (hit.ts `groupUnionBounds`): hits only happen between\n * gestures, where the two are identical.\n */\nfunction unionBoundsOf(\n m: Model,\n pon: number,\n geomOf: (id: Id) => Geom,\n view?: ViewEnv,\n): Rect | null {\n const corners: Vec[] = [];\n for (const id of m.selected) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n corners.push(...selectionQuad(geomOf(id), effStyle(a, view).strokeWidth, a.style.border));\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/** The page-bound knob placement for the selection on `pon`, reading each\n * member's geometry through `geomOf` — `effGeom` for the live view, the\n * COMMITTED geometry for a rotate gesture's rest anchor (see `selectionKnob`). */\nfunction placeSelectionKnob(\n m: Model,\n pon: number,\n pageBox: Rect | undefined,\n knobOffset: number,\n geomOf: (id: Id) => Geom,\n view?: ViewEnv,\n): { at: Vec; from: Vec } | null {\n const sel = m.selected.filter((id) => isSelectable(m, id) && m.byId[id].pon === pon);\n if (sel.length === 1) {\n const a = m.byId[sel[0]];\n // No knob for a locked (frozen) annotation — the SAME gate hitTest\n // applies, so the drawn knob is always grabbable and vice versa. A\n // screen-anchored body keeps its knob: rotating edits its AUTHORED tilt\n // (`noRotate` only exempts it from the page's rotation). The obb takes\n // the PROJECTED stroke width (`effStyle`) — with the raw width, the knob\n // drifts off the outline as zoom grows.\n if (!capsFor(a.subtype).rotatable || !annotTransformable(a)) return null;\n const obb = obbFromGeom(geomOf(sel[0]), effStyle(a, view).strokeWidth, a.style.border);\n return obb ? placeRotateKnob(obb.corners, knobOffset, pageBox) : null;\n }\n if (sel.length > 1 && groupCaps(m, sel).rotatable) {\n const union = unionBoundsOf(m, pon, geomOf, view);\n if (union) return placeRotateKnob(boxCorners(union), knobOffset, pageBox);\n }\n return null;\n}\n\n/**\n * The rotate knob for the current selection on `pon` — the SAME knob `chrome`\n * draws — or null when the selection has none (non-rotatable single, or a group\n * whose caps aren't rotatable). A single shape's knob hangs off its OBB top edge;\n * a group's off the union box. With `pageBox` the knob is placed PAGE-BOUND\n * (`placeRotateKnob`: flip below / clamp inside) — off-page it would be visible\n * but unreachable, since pointer dispatch resolves pages by containment. Shared\n * by `chrome` (to draw) and `selectionAnchor` (to push the menu clear of it), so\n * the two can never disagree on where it is.\n *\n * The placement DECISION is made at rest; a gesture never re-decides — it RIDES.\n * During a live rotate the knob starts exactly where it was grabbed (the rest\n * placement on the COMMITTED geometry) and turns rigidly about the pivot by the\n * same snapped delta the shape uses; the policy re-evaluates only on release.\n * Re-deciding per frame would jump at grab and side-switch mid-spin.\n */\nexport function selectionKnob(\n m: Model,\n pon: number,\n pageBox?: Rect,\n knobOffset: number = ROTATE_KNOB_OFFSET,\n view?: ViewEnv,\n): { at: Vec; from: Vec } | null {\n const d = m.draft;\n if (d?.g === 'rotate' && m.byId[d.ids[0]]?.pon === pon) {\n const rest = placeSelectionKnob(\n m,\n pon,\n pageBox,\n knobOffset,\n (id) => anchoredGeom(m.byId[id].geom, anchorModeOf(m.byId[id]), view),\n view,\n );\n if (!rest) return null;\n const { delta } = rotateDraftDelta(m, d);\n return {\n at: rotatePoint(rest.at, d.pivot, delta),\n from: rotatePoint(rest.from, d.pivot, delta),\n };\n }\n return placeSelectionKnob(m, pon, pageBox, knobOffset, (id) => effGeom(m, id, view), view);\n}\n\nexport function chrome(\n m: Model,\n pon: number,\n pageBox?: Rect,\n knobOffset: number = ROTATE_KNOB_OFFSET,\n view?: ViewEnv,\n): ChromeNode[] {\n const nodes: ChromeNode[] = [];\n if (m.draft?.g === 'marquee' && m.draft.pon === pon) {\n nodes.push({ kind: 'marquee', rect: rectFromPoints(m.draft.from, m.draft.to) });\n }\n // Live alignment guides of a snapped move (the gesture lives on ONE page —\n // its members' page).\n if (m.draft?.g === 'move' && m.draft.guides.length && m.byId[m.draft.ids[0]]?.pon === pon) {\n for (const g of m.draft.guides)\n nodes.push({ kind: 'guide', axis: g.axis, at: g.at, lo: g.lo, hi: g.hi });\n }\n // A live rotate on THIS page's selection. While it runs, the chrome switches\n // modes (v2 behaviour): the readout chip + full-bleed guides appear, and the\n // handles/knob are suppressed below — the pointer holds capture, so grab\n // affordances are noise; \"how far am I\" feedback is everything.\n const rd = m.draft?.g === 'rotate' && m.byId[m.draft.ids[0]]?.pon === pon ? m.draft : null;\n if (rd) {\n const { angle } = rotateDraftDelta(m, rd);\n nodes.push({ kind: 'angle-chip', at: rd.cur, angle: Math.round(angle) });\n // Guides as chords of the PAGE through the pivot — the fixed 0°/90°\n // reference cross + the live indicator at the SAME snapped angle the chip\n // shows and the commit applies. Full-bleed beats a magic length constant;\n // no pageBox (headless) → a generous fixed span around the pivot.\n const span = pageBox ?? { x: rd.pivot.x - 300, y: rd.pivot.y - 300, width: 600, height: 600 };\n const lines: Array<{ a: Vec; b: Vec; role: 'axis' | 'indicator' }> = [];\n for (const [deg, role] of [\n [0, 'axis'],\n [90, 'axis'],\n [angle, 'indicator'],\n ] as const) {\n const c = chordThrough(span, rd.pivot, deg);\n if (c) lines.push({ ...c, role });\n }\n nodes.push({ kind: 'rotate-guides', center: rd.pivot, angle, lines });\n }\n const sel = m.selected.filter((id) => isSelectable(m, id) && m.byId[id].pon === pon);\n if (sel.length === 1) {\n const a = m.byId[sel[0]];\n const g = effGeom(m, sel[0], view);\n const style = effStyle(a, view);\n const caps = capsFor(a.subtype);\n const rot = geomRotation(g);\n const obb = caps.rotatable ? obbFromGeom(g, style.strokeWidth, a.style.border) : null;\n if (obb && rot !== 0) {\n // a tilted shape: draw the oriented box + the rotate knob off its top edge.\n nodes.push({ kind: 'obb', corners: obb.corners, angle: obb.angle });\n } else {\n nodes.push({\n kind: 'outline',\n rect: selectionBounds(g, style.strokeWidth, a.style.border),\n });\n }\n // handles for kinds that resize (box) or vertex-edit; anchored/markup show\n // a bare outline — and so do locked (frozen) annotations, the SAME gate\n // hitTest applies. Screen-anchored bodies keep their handles, placed on\n // the PROJECTED geometry (`g`), so they sit exactly where hitTest grabs\n // them. `geomHandles` already places them on the rotated box; `rot`\n // additionally tilts each handle GLYPH so it rides the box's orientation.\n // Suppressed during a live rotate (`rd`) — guides own that mode.\n if (!rd && annotTransformable(a) && (caps.resizable || caps.vertexEditable)) {\n for (const h of geomHandles(g))\n nodes.push({ kind: 'handle', at: h.at, cursor: h.cursor, ...(rot ? { rot } : {}) });\n }\n } else if (sel.length > 1 && !rd) {\n // The LIVE union (draft-effective geometry): the outline and its handles\n // ride a group move/scale exactly like single-selection chrome. During a\n // live rotate the members spin away from any axis-aligned box, so the\n // whole block is suppressed — the guides own that mode.\n const union = unionBoundsOf(m, pon, (id) => effGeom(m, id, view), view);\n if (union) {\n nodes.push({ kind: 'outline', rect: union });\n const gc = groupCaps(m, sel);\n if (gc.resizable) {\n for (const h of rectHandlesFor(union))\n nodes.push({ kind: 'handle', at: h.at, cursor: h.cursor });\n }\n }\n }\n // The rotate knob (single shape or group) — one source of truth with the menu\n // anchor, so the menu is always pushed clear of exactly this point. Hidden\n // while a rotate runs (the gesture holds capture; the guides own the mode).\n if (!rd) {\n const knob = selectionKnob(m, pon, pageBox, knobOffset, view);\n if (knob) nodes.push({ kind: 'rotate-knob', at: knob.at, from: knob.from });\n }\n return nodes;\n}\n\n/** The content-space union of the selectable selected items on `pon`, or null if\n * the page holds none. This is the SAME box the chrome outline draws, so a\n * floating menu sits exactly on the selection. */\nexport function selectionBoundsOnPage(m: Model, pon: number, view?: ViewEnv): Rect | null {\n const sel = m.selected.filter((id) => isSelectable(m, id) && m.byId[id].pon === pon);\n if (sel.length === 0) return null;\n // The rotated AABB: the axis-aligned box that encloses the ORIENTED selection\n // quad. For a tilted shape this tracks the live `rot`, so the upright floating\n // menu floats above the whole tilted shape instead of the (fixed) unrotated box.\n const corners = sel.flatMap((id) =>\n selectionQuad(\n effGeom(m, id, view),\n effStyle(m.byId[id], view).strokeWidth,\n m.byId[id].style.border,\n ),\n );\n return unionRect(corners);\n}\n\n/** The anchor for a selection-aware floating menu: the PRIMARY page (the first\n * selectable selected id) + the union box of the selection on that page (content\n * space). Null when nothing selectable is selected. A cross-page selection\n * anchors to its primary page, so there is exactly one menu. `pageBoxOf` is a\n * lookup (the anchor resolves its own page) feeding the page-bound knob\n * placement — the menu then dodges the knob where it ACTUALLY sits. */\nexport function selectionAnchor(\n m: Model,\n pageBoxOf?: (pon: number) => Rect | undefined,\n knobOffsetOf?: (pon: number) => number | undefined,\n viewOf?: (pon: number) => ViewEnv | undefined,\n): { pon: number; bounds: Rect; knob?: Vec } | null {\n // No menu while a rotate gesture runs (v2 behaviour): the chrome is in\n // guides mode and a floating menu chasing a spinning box is pure noise.\n if (m.draft?.g === 'rotate') return null;\n const id = m.selected.find((x) => isSelectable(m, x));\n if (id == null) return null;\n const pon = m.byId[id].pon;\n const view = viewOf?.(pon);\n const bounds = selectionBoundsOnPage(m, pon, view);\n if (!bounds) return null;\n // `bounds` is the plain selection box (the menu stays centred on it). The knob\n // rides ALONGSIDE it so the menu can nudge ONLY the edge it sits on, and only\n // when the handle would otherwise hide under it — never shifting the centre.\n const knob = selectionKnob(\n m,\n pon,\n pageBoxOf?.(pon),\n knobOffsetOf?.(pon) ?? ROTATE_KNOB_OFFSET,\n view,\n );\n return knob ? { pon, bounds, knob: knob.at } : { pon, bounds };\n}\n\n/** Anchor for controls that finish/cancel an active multi-click creation draft.\n * It is rect-based like selectionAnchor, using the committed vertices only so\n * the menu remains stable while the hover preview follows the pointer. */\nexport function creationDraftAnchor(m: Model): CreationDraftAnchor | null {\n const d = m.draft;\n if (d?.g !== 'create-poly') return null;\n if (!d.points.length) return null;\n const minPoints = d.closed ? 3 : 2;\n return {\n kind: 'poly',\n subtype: d.closed ? 'polygon' : 'polyline',\n pon: d.pon,\n bounds: unionRect(d.points),\n pointCount: d.points.length,\n minPoints,\n canFinish: d.points.length >= minPoints,\n };\n}\n"],"mappings":"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"}
|