@embedpdf/core-annotation 3.0.0-next.1 → 3.0.0-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AnnotationDTO, AnnotationFlags, AnnotationFlags as AnnotationFlags$1, AnnotationRef, BlendMode, BlendMode as BlendMode$1, CaretIntent, InkIntent, LineEnding, LineEndings, NO_ANNOTATION_FLAGS, PdfLinkTarget, PdfPoint, PdfRect, StrikeoutIntent } from "@embedpdf/engine-core/runtime";
2
2
  import { PageObjectNumber } from "@embedpdf/core";
3
- import { PageRotation, Point, Rect as Rect$1, Size } from "@embedpdf/core-geometry";
3
+ import { PageRotation, Point, Rect as Rect$1, Size, TextQuad, TextQuad as TextQuad$1 } from "@embedpdf/core-geometry";
4
4
  //#region src/flags.d.ts
5
5
  /** The `/F` every freshly DRAWN annotation starts with: `print` set (Acrobat
6
6
  * parity — without it the annotation silently disappears when printed). */
@@ -22,14 +22,27 @@ declare const interactive: (f: AnnotationFlags) => boolean;
22
22
  interface FlagBearer {
23
23
  subtype: string;
24
24
  flags: AnnotationFlags;
25
+ /** Session authority projected at ingest (permissions.md). Absent =
26
+ * unstamped (drafts, wildcard local engines, tests) = allowed. */
27
+ authority?: {
28
+ update: boolean;
29
+ delete: boolean;
30
+ };
25
31
  }
26
32
  /** Interaction gate for a concrete annotation: widget kinds ignore `readOnly`
27
33
  * (ISO 32000 — a ReadOnly form field must still be movable by a form designer;
28
34
  * the form-filling layer enforces field ReadOnly itself). */
29
35
  declare const annotInteractive: (a: FlagBearer) => boolean;
30
- /** Geometry/style/delete mutations — `locked` freezes the OBJECT, not its
31
- * contents (that's `lockedContents`). */
36
+ /**
37
+ * Geometry/style mutations — `locked` freezes the OBJECT, not its contents
38
+ * (that's `lockedContents`), AND the session must hold update authority over
39
+ * the record. One predicate for hit-test, chrome, and props alike, so a
40
+ * record you may not edit renders and behaves exactly like a locked one.
41
+ */
32
42
  declare const annotTransformable: (a: FlagBearer) => boolean;
43
+ /** Deletion — the delete half of the authority split (a narrowed grant can
44
+ * allow update but not delete, or vice versa). Flags gate like transforms. */
45
+ declare const annotDeletable: (a: FlagBearer) => boolean;
33
46
  /** `/Contents` text edits — the contents counterpart of `locked`. */
34
47
  declare const annotContentsEditable: (a: FlagBearer) => boolean;
35
48
  //#endregion
@@ -42,8 +55,19 @@ declare const annotContentsEditable: (a: FlagBearer) => boolean;
42
55
  */
43
56
  type Vec = Point;
44
57
  type Rect = Rect$1;
45
- /** Four content-space points (a /QuadPoints quad). */
58
+ /** Four POSITIONAL content-space points — selection chrome / OBB corners.
59
+ * Text-markup geometry uses the corner-NAMED {@link TextQuad} instead. */
46
60
  type Quad = [Vec, Vec, Vec, Vec];
61
+ /**
62
+ * Where a text-edit annotation (caret / replace-text) anchors: the boundary
63
+ * glyph's oriented cell plus the READING direction along its baseline
64
+ * (+1 = toward `end`, −1 = toward `start` — sequence-derived, never inferred
65
+ * from geometry).
66
+ */
67
+ interface TextEndAnchor {
68
+ glyphQuad: TextQuad$1;
69
+ advance: 1 | -1;
70
+ }
47
71
  type Id = string;
48
72
  type Cursor = string;
49
73
  type PolySubtype = 'polygon' | 'polyline';
@@ -115,10 +139,11 @@ type Geom = {
115
139
  rot?: number;
116
140
  } | {
117
141
  t: 'quads';
118
- quads: Quad[];
142
+ quads: TextQuad$1[];
119
143
  } | {
120
144
  t: 'caret';
121
145
  rect: Rect;
146
+ rot?: number;
122
147
  } | {
123
148
  t: 'ink';
124
149
  strokes: Vec[][];
@@ -274,6 +299,20 @@ interface Annot {
274
299
  * is still pixel-exact, so those cost zero re-renders.
275
300
  */
276
301
  apVersion?: number;
302
+ /**
303
+ * This SESSION's authority over this record, projected from the security
304
+ * service's collab mirrors at ingest (see permissions.md) — model-owned
305
+ * derived state like `apVersion`, never DTO-derived. Fused into
306
+ * `annotTransformable`/`annotDeletable`, so a record the session may not
307
+ * edit renders and behaves exactly like a `locked` one (bare outline, no
308
+ * handles, no drag). Absent = unstamped (a local draft, a wildcard local
309
+ * engine, tests) and treated as allowed — the client gate is a COURTESY
310
+ * that keeps the UI truthful; the engine independently enforces.
311
+ */
312
+ authority?: {
313
+ update: boolean;
314
+ delete: boolean;
315
+ };
277
316
  /**
278
317
  * The canonical engine DTO this annotation was derived from (PDF-space, sRGB)
279
318
  * — the single source of truth for its data. `geom` and `style` are
@@ -285,20 +324,13 @@ interface Annot {
285
324
  /** Normalized PDF `/IT` for intent-bearing annotations authored before a DTO exists. */
286
325
  intent?: CaretIntent | StrikeoutIntent | InkIntent;
287
326
  /**
288
- * The `link` prop's value (see {@link AnnotationProps.link}): the link
289
- * kind's own target, or — on other linkable kinds — the folded attached
290
- * link's target. Editable via `setProps`.
327
+ * The link KIND's own `/A` target (see {@link AnnotationProps.link}) —
328
+ * present only on `subtype: 'link'`. Every OTHER kind's link is an
329
+ * attached child annotation in the substrate, read through the `linkOf`
330
+ * lens and materialized by the shell's `syncLink` reconciler; parents
331
+ * store nothing.
291
332
  */
292
333
  link?: PdfLinkTarget | null;
293
- /**
294
- * INTERNAL join keys, never a prop: the engine refs of the attached link
295
- * child annotation(s) this parent's `link` value is materialized as (one
296
- * per visual segment for markup). Maintained by the repository fold and
297
- * consumed by the shell's `syncLink` reconciler + delete expansion — the
298
- * ONLY code allowed to touch those children. Absent on the link kind
299
- * itself and on anything without an attached link.
300
- */
301
- linkRefs?: AnnotationRef[];
302
334
  /**
303
335
  * Relationship to another annotation. `irt` ("in reply to") links a child to a
304
336
  * parent — a reply in a comment thread, or a caret bound to its strikeout in a
@@ -454,7 +486,7 @@ interface MarkupPreview {
454
486
  subtype: Subtype;
455
487
  /** Defaults key, distinct from subtype for presets such as replace-text. */
456
488
  preset: string;
457
- byPage: Record<number, Quad[]>;
489
+ byPage: Record<number, TextQuad$1[]>;
458
490
  }
459
491
  /** Anchor + affordance state for UI that controls an in-progress creation draft. */
460
492
  interface CreationDraftAnchor {
@@ -613,26 +645,26 @@ type Msg = {
613
645
  } | {
614
646
  t: 'createCaret';
615
647
  pon: PageObjectNumber;
616
- rect: Rect;
648
+ anchor: TextEndAnchor;
617
649
  flags?: Partial<AnnotationFlags$1>;
618
650
  } | {
619
651
  t: 'createReplaceText';
620
652
  pon: PageObjectNumber;
621
- rects: Rect[];
622
- endRect: Rect;
653
+ quads: TextQuad$1[];
654
+ anchor: TextEndAnchor;
623
655
  preset?: string;
624
656
  } | {
625
657
  t: 'createMarkup';
626
658
  subtype: Subtype;
627
659
  pon: PageObjectNumber;
628
- rects: Rect[];
660
+ quads: TextQuad$1[];
629
661
  preset?: string;
630
662
  /** The tool's `/F` seed — merged over {@link DRAWN_FLAGS} at commit. */
631
663
  flags?: Partial<AnnotationFlags$1>;
632
664
  } | {
633
665
  t: 'setMarkupPreview';
634
666
  subtype: Subtype;
635
- rectsByPage: Record<number, Rect[]>;
667
+ quadsByPage: Record<number, TextQuad$1[]>;
636
668
  preset?: string;
637
669
  } | {
638
670
  t: 'clearMarkupPreview';
@@ -644,7 +676,12 @@ type Msg = {
644
676
  {
645
677
  t: 'hover';
646
678
  id: Id | null;
647
- } | {
679
+ } |
680
+ /** Force/clear session visibility for specific annotations (the actions
681
+ * plane's Hide sink). Hiding also clears transient engagement (selection,
682
+ * editing, hover) for the hidden ids. Unknown ids no-op. Zero effects. */
683
+ /** Drop overrides for truly DELETED annotations (never for reloads). */
684
+ {
648
685
  t: 'select';
649
686
  ids: Id[];
650
687
  add?: boolean;
@@ -673,6 +710,21 @@ type Msg = {
673
710
  } | {
674
711
  t: 'loaded';
675
712
  annots: Annot[];
713
+ } |
714
+ /**
715
+ * Whole-document hydration ingest (and desync re-ingest): the snapshot is
716
+ * the committed TRUTH. Incoming annots overwrite by id (gesture-locked ids
717
+ * excepted, as in `upsert`); committed model entries ABSENT from the
718
+ * snapshot are reaped — they were deleted while we could not watch.
719
+ * Uncommitted `tmp:` drafts and gesture-locked ids are never reaped, and
720
+ * an in-progress draft survives (unlike `remove`). `bumpAp` marks a
721
+ * desync re-ingest: rasters may have changed invisibly during the gap,
722
+ * so every replaced annotation re-fetches once.
723
+ */
724
+ {
725
+ t: 'hydrated';
726
+ annots: Annot[];
727
+ bumpAp?: boolean;
676
728
  } | {
677
729
  t: 'created';
678
730
  tempId: Id;
@@ -739,6 +791,7 @@ type Effect = {
739
791
  {
740
792
  fx: 'syncLink';
741
793
  id: Id;
794
+ target: PdfLinkTarget | null;
742
795
  } | {
743
796
  fx: 'delete';
744
797
  ref: AnnotationRef;
@@ -1198,6 +1251,36 @@ declare function groupMembers(m: Model, id: Id): Id[];
1198
1251
  /** Union of every id's full group — the selection seen as whole groups. */
1199
1252
  declare function expandGroups(m: Model, ids: Id[]): Id[];
1200
1253
  //#endregion
1254
+ //#region src/plane.d.ts
1255
+ /** True when this annotation belongs to the conversation plane only —
1256
+ * never painted, hit, marquee-selected, or counted into a page's
1257
+ * appearance epoch. */
1258
+ declare function isConversationOnly(a: Pick<Annot, 'irt' | 'group' | 'subtype' | 'data'>): boolean;
1259
+ /**
1260
+ * A link CHILD attached to another annotation — a `/Link` grouped
1261
+ * (`/IRT` + `/RT /Group`) under a non-link parent. Pure substrate: it is
1262
+ * the parent's `link` PROPERTY while authoring (derived via `linkOf`) and
1263
+ * the navigation plane's anchor while reading — never painted, never hit
1264
+ * as itself. Its rect is RECONCILED from the parent's geometry, so direct
1265
+ * manipulation would be overwritten anyway.
1266
+ */
1267
+ declare function isAttachedLink(a: Pick<Annot, 'subtype' | 'group'>): boolean;
1268
+ /**
1269
+ * The ONE page-surface cull: everything that lives in the substrate but is
1270
+ * not a page visual of its own — conversation members (replies, review
1271
+ * states) and attached link children. Paint order, hit-testing, marquee
1272
+ * and the appearance epoch all filter through THIS, never the parts.
1273
+ */
1274
+ declare function isSubstrateOnly(a: Pick<Annot, 'irt' | 'group' | 'subtype' | 'data'>): boolean;
1275
+ //#endregion
1276
+ //#region src/links.d.ts
1277
+ /** Every attached link child of `parentId`, in z-order (multi-segment
1278
+ * markup parents carry several children with one shared target). */
1279
+ declare function linkChildrenOf(m: Model, parentId: Id): Annot[];
1280
+ /** The parent's link target, derived from its first attached child — the
1281
+ * read side of the `syncLink` reconciler. Null when no child exists. */
1282
+ declare function linkOf(m: Model, parentId: Id): PdfLinkTarget | null;
1283
+ //#endregion
1201
1284
  //#region src/kinds.d.ts
1202
1285
  /**
1203
1286
  * One editable property of a kind, as a UI contract: which {@link AnnotationProps}
@@ -1386,7 +1469,10 @@ declare const DEFAULT_CHROME_GEOM: {
1386
1469
  };
1387
1470
  /** Normalize degrees into `[0, 360)`. */
1388
1471
  declare const normalizeDeg: (d: number) => number;
1389
- /** A geom's applied rotation (deg), or 0 for the non-rotatable kinds. */
1472
+ /** A geom's applied rotation (deg), or 0 for the non-rotatable kinds. A
1473
+ * caret's `rot` is AUTHORING metadata (its text's baseline tilt): reported
1474
+ * here so the renderer and selection chrome follow it, while the caret's
1475
+ * caps (not movable/resizable) keep every rotate gesture away from it. */
1390
1476
  declare function geomRotation(g: Geom): number;
1391
1477
  /**
1392
1478
  * The rotation PIVOT for a single shape: a box turns about its own `rect`
@@ -1395,7 +1481,10 @@ declare function geomRotation(g: Geom): number;
1395
1481
  * stays cleanly additive across gestures and reset is exact.
1396
1482
  */
1397
1483
  declare function centroidOf(g: Geom): Vec;
1398
- /** Is this kind rotatable (the geometry carries a meaningful `rot`)? */
1484
+ /** Does the geometry carry a meaningful `rot` (an oriented local box exists)?
1485
+ * ORIENTATION is a geometry fact; whether the USER may rotate is the separate
1486
+ * `caps.rotatable` gate — a caret is oriented (it rides its text's tilt) yet
1487
+ * offers no rotate gesture. */
1399
1488
  declare function isRotatableGeom(g: Geom): boolean;
1400
1489
  /**
1401
1490
  * Rotate a geom by `deltaDeg` (clockwise) about `pivot`.
@@ -1404,7 +1493,10 @@ declare function isRotatableGeom(g: Geom): boolean;
1404
1493
  * pivot IS the box centre this is a pure `rot += delta`.
1405
1494
  * - VERTEX (`line`/`poly`/`ink`): map every point through the rotation AND bump
1406
1495
  * the advisory `rot` (the points stay the authoritative visual).
1407
- * Non-rotatable kinds (caret/quads, callouts) are returned unchanged.
1496
+ * Kinds without a rotate VERB are returned unchanged: quads and callouts, and
1497
+ * also the caret — oriented (`isRotatableGeom`) but text-anchored, so its tilt
1498
+ * is authoring metadata that no gesture edits (`geomResetRotation` still
1499
+ * clears it).
1408
1500
  */
1409
1501
  declare function geomRotateAbout(g: Geom, pivot: Vec, deltaDeg: number): Geom;
1410
1502
  /** The AABB of `rect` rotated `deg` about its own centre. */
@@ -1520,6 +1612,26 @@ declare function calloutLinePoints(g: Extract<Geom, {
1520
1612
  */
1521
1613
  declare function shapeRectFor(dragged: Rect, ellipse: boolean, style: Style): Rect;
1522
1614
  declare function caretRectFromTextEnd(lineRect: Rect): Rect;
1615
+ /**
1616
+ * Caret box for a text-edit anchor: half the glyph's ink height, centered on
1617
+ * the TRAILING baseline corner in READING direction (`advance` decides which
1618
+ * end — RTL carets land on the visual left), sitting on the baseline. The box
1619
+ * stays axis-aligned; use {@link caretGeomFromAnchor} for the tilt-carrying
1620
+ * geometry.
1621
+ */
1622
+ declare function caretRectFromAnchor(anchor: TextEndAnchor): Rect;
1623
+ /**
1624
+ * Caret GEOMETRY for a text-edit anchor: the box-family pair — an UNROTATED
1625
+ * box whose centre sits half a caret-size ascent-ward of the trailing
1626
+ * baseline corner, plus `rot` = the text's baseline tilt (deg, CW in y-down
1627
+ * content space). Rotating the box about its centre by `rot` lands it
1628
+ * hugging the rotated baseline, symbol pointing at its text. For upright
1629
+ * anchors this degenerates EXACTLY to {@link caretRectFromAnchor} with no
1630
+ * `rot` key — the dominant case is byte-identical.
1631
+ */
1632
+ declare function caretGeomFromAnchor(anchor: TextEndAnchor): Extract<Geom, {
1633
+ t: 'caret';
1634
+ }>;
1523
1635
  /** Miter limit shared by the bounds math AND the SVG renderer (`stroke-miterlimit`),
1524
1636
  * so the computed box and the drawn stroke always agree on where a sharp join
1525
1637
  * bevels instead of spiking. 10 = the PDF default (also what the baked /AP uses). */
@@ -1632,5 +1744,5 @@ declare function scene(item: RenderItem): SceneNode[];
1632
1744
  */
1633
1745
  declare function straightenInkStroke(points: readonly Vec[], options: InkStraightenOptions): Vec[];
1634
1746
  //#endregion
1635
- export { type AnchorMode, type Annot, type AnnotationFlags, type AnnotationKind, type AnnotationProps, type AnnotationPropsPatch, type BlendMode, type Border, type Callout, type ChromeGeom, type ChromeNode, type ClickCreate, type ClickPlacement, type CreationDraftAnchor, type Cursor, DEFAULT_CHROME_GEOM, DRAWN_FLAGS, type Draft, type Effect, FLAG_KEYS, type FlagBearer, type Geom, type GroupCaps, type Guide, type Handle, type Id, type InkStraightenOptions, KINDS, type KindCaps, type LineEnding, type LineEndings, MIN_DRAG, MITER_LIMIT, type Model, type Msg, NO_ANNOTATION_FLAGS, type Paint, type PatchScope, type PointerInput, type PropKey, type PropSpec, type Quad, RECT_HANDLES, ROTATE_KNOB_OFFSET, type Rect, type RectHandle, type RenderItem, type RenderNode, type SceneNode, type SnapResult, type SnapSettings, type Style, type Subtype, type Target, type TextAlign, type TextBox, type TextStyle, type Vec, type ViewEnv, anchorModeOf, anchorOf, anchoredBox, anchoredGeom, anchoredStrokeWidth, annotContentsEditable, annotInteractive, annotTransformable, applyProps, calloutConnection, calloutLinePoints, canMove, capsFor, caretRectFromTextEnd, centroidOf, chrome, clampRectToBox, clickCreateGeom, cloudyBorderExtent, cloudyPath, computeMoveSnap, contentToPdfPoint, contentToPdfRect, creationDraftAnchor, cursorAt, defaultsFor, expandGroups, fitStampBox, flagsEqual, geomBounds, geomDragHandle, geomHandles, geomHit, geomPdfBounds, geomResetRotation, geomRotateAbout, geomRotation, geomScaleAbout, geomScene, geomTranslate, geomVisualBounds, groupCaps, groupKeyOf, groupMembers, groupResizeAnchor, groupResizeBox, groupResizeFactors, hitTest, initialModel, initialStyle, initialTextStyle, interactive, isRotatableGeom, isSelectable, mergeFlags, normalizeDeg, obbFromGeom, pageItems, pdfToContentPoint, pdfToContentRect, placeRotateKnob, pointInQuad, propsFor, quadIntersectsRect, readProp, rectFromPoints, resolveClickPlacement, rotateDraftDelta, rotateKnob, rotatedAabb, rotatedHandleCursor, scene, selectedItems, selectionAnchor, selectionBounds, selectionBoundsOnPage, selectionCenter, selectionKnob, selectionQuad, shapeRectFor, sharedProps, straightenInkStroke, styleFromProps, textBoxes, textStyleFromProps, transposedAboutCenter, unanchoredGeom, unionRect, update, uprightAnchoredRect, uprightRotation, viewable };
1747
+ export { type AnchorMode, type Annot, type AnnotationFlags, type AnnotationKind, type AnnotationProps, type AnnotationPropsPatch, type BlendMode, type Border, type Callout, type ChromeGeom, type ChromeNode, type ClickCreate, type ClickPlacement, type CreationDraftAnchor, type Cursor, DEFAULT_CHROME_GEOM, DRAWN_FLAGS, type Draft, type Effect, FLAG_KEYS, type FlagBearer, type Geom, type GroupCaps, type Guide, type Handle, type Id, type InkStraightenOptions, KINDS, type KindCaps, type LineEnding, type LineEndings, MIN_DRAG, MITER_LIMIT, type Model, type Msg, NO_ANNOTATION_FLAGS, type Paint, type PatchScope, type PointerInput, type PropKey, type PropSpec, type Quad, RECT_HANDLES, ROTATE_KNOB_OFFSET, type Rect, type RectHandle, type RenderItem, type RenderNode, type SceneNode, type SnapResult, type SnapSettings, type Style, type Subtype, type Target, type TextAlign, type TextBox, type TextEndAnchor, type TextQuad, type TextStyle, type Vec, type ViewEnv, anchorModeOf, anchorOf, anchoredBox, anchoredGeom, anchoredStrokeWidth, annotContentsEditable, annotDeletable, annotInteractive, annotTransformable, applyProps, calloutConnection, calloutLinePoints, canMove, capsFor, caretGeomFromAnchor, caretRectFromAnchor, caretRectFromTextEnd, centroidOf, chrome, clampRectToBox, clickCreateGeom, cloudyBorderExtent, cloudyPath, computeMoveSnap, contentToPdfPoint, contentToPdfRect, creationDraftAnchor, cursorAt, defaultsFor, expandGroups, fitStampBox, flagsEqual, geomBounds, geomDragHandle, geomHandles, geomHit, geomPdfBounds, geomResetRotation, geomRotateAbout, geomRotation, geomScaleAbout, geomScene, geomTranslate, geomVisualBounds, groupCaps, groupKeyOf, groupMembers, groupResizeAnchor, groupResizeBox, groupResizeFactors, hitTest, initialModel, initialStyle, initialTextStyle, interactive, isAttachedLink, isConversationOnly, isRotatableGeom, isSelectable, isSubstrateOnly, linkChildrenOf, linkOf, mergeFlags, normalizeDeg, obbFromGeom, pageItems, pdfToContentPoint, pdfToContentRect, placeRotateKnob, pointInQuad, propsFor, quadIntersectsRect, readProp, rectFromPoints, resolveClickPlacement, rotateDraftDelta, rotateKnob, rotatedAabb, rotatedHandleCursor, scene, selectedItems, selectionAnchor, selectionBounds, selectionBoundsOnPage, selectionCenter, selectionKnob, selectionQuad, shapeRectFor, sharedProps, straightenInkStroke, styleFromProps, textBoxes, textStyleFromProps, transposedAboutCenter, unanchoredGeom, unionRect, update, uprightAnchoredRect, uprightRotation, viewable };
1636
1748
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AnnotationDTO, AnnotationFlags, AnnotationFlags as AnnotationFlags$1, AnnotationRef, BlendMode, BlendMode as BlendMode$1, CaretIntent, InkIntent, LineEnding, LineEndings, NO_ANNOTATION_FLAGS, PdfLinkTarget, PdfPoint, PdfRect, StrikeoutIntent } from "@embedpdf/engine-core/runtime";
2
- import { PageRotation, Point, Rect as Rect$1, Size } from "@embedpdf/core-geometry";
2
+ import { PageRotation, Point, Rect as Rect$1, Size, TextQuad, TextQuad as TextQuad$1 } from "@embedpdf/core-geometry";
3
3
  import { PageObjectNumber } from "@embedpdf/core";
4
4
  //#region src/flags.d.ts
5
5
  /** The `/F` every freshly DRAWN annotation starts with: `print` set (Acrobat
@@ -22,14 +22,27 @@ declare const interactive: (f: AnnotationFlags) => boolean;
22
22
  interface FlagBearer {
23
23
  subtype: string;
24
24
  flags: AnnotationFlags;
25
+ /** Session authority projected at ingest (permissions.md). Absent =
26
+ * unstamped (drafts, wildcard local engines, tests) = allowed. */
27
+ authority?: {
28
+ update: boolean;
29
+ delete: boolean;
30
+ };
25
31
  }
26
32
  /** Interaction gate for a concrete annotation: widget kinds ignore `readOnly`
27
33
  * (ISO 32000 — a ReadOnly form field must still be movable by a form designer;
28
34
  * the form-filling layer enforces field ReadOnly itself). */
29
35
  declare const annotInteractive: (a: FlagBearer) => boolean;
30
- /** Geometry/style/delete mutations — `locked` freezes the OBJECT, not its
31
- * contents (that's `lockedContents`). */
36
+ /**
37
+ * Geometry/style mutations — `locked` freezes the OBJECT, not its contents
38
+ * (that's `lockedContents`), AND the session must hold update authority over
39
+ * the record. One predicate for hit-test, chrome, and props alike, so a
40
+ * record you may not edit renders and behaves exactly like a locked one.
41
+ */
32
42
  declare const annotTransformable: (a: FlagBearer) => boolean;
43
+ /** Deletion — the delete half of the authority split (a narrowed grant can
44
+ * allow update but not delete, or vice versa). Flags gate like transforms. */
45
+ declare const annotDeletable: (a: FlagBearer) => boolean;
33
46
  /** `/Contents` text edits — the contents counterpart of `locked`. */
34
47
  declare const annotContentsEditable: (a: FlagBearer) => boolean;
35
48
  //#endregion
@@ -42,8 +55,19 @@ declare const annotContentsEditable: (a: FlagBearer) => boolean;
42
55
  */
43
56
  type Vec = Point;
44
57
  type Rect = Rect$1;
45
- /** Four content-space points (a /QuadPoints quad). */
58
+ /** Four POSITIONAL content-space points — selection chrome / OBB corners.
59
+ * Text-markup geometry uses the corner-NAMED {@link TextQuad} instead. */
46
60
  type Quad = [Vec, Vec, Vec, Vec];
61
+ /**
62
+ * Where a text-edit annotation (caret / replace-text) anchors: the boundary
63
+ * glyph's oriented cell plus the READING direction along its baseline
64
+ * (+1 = toward `end`, −1 = toward `start` — sequence-derived, never inferred
65
+ * from geometry).
66
+ */
67
+ interface TextEndAnchor {
68
+ glyphQuad: TextQuad$1;
69
+ advance: 1 | -1;
70
+ }
47
71
  type Id = string;
48
72
  type Cursor = string;
49
73
  type PolySubtype = 'polygon' | 'polyline';
@@ -115,10 +139,11 @@ type Geom = {
115
139
  rot?: number;
116
140
  } | {
117
141
  t: 'quads';
118
- quads: Quad[];
142
+ quads: TextQuad$1[];
119
143
  } | {
120
144
  t: 'caret';
121
145
  rect: Rect;
146
+ rot?: number;
122
147
  } | {
123
148
  t: 'ink';
124
149
  strokes: Vec[][];
@@ -274,6 +299,20 @@ interface Annot {
274
299
  * is still pixel-exact, so those cost zero re-renders.
275
300
  */
276
301
  apVersion?: number;
302
+ /**
303
+ * This SESSION's authority over this record, projected from the security
304
+ * service's collab mirrors at ingest (see permissions.md) — model-owned
305
+ * derived state like `apVersion`, never DTO-derived. Fused into
306
+ * `annotTransformable`/`annotDeletable`, so a record the session may not
307
+ * edit renders and behaves exactly like a `locked` one (bare outline, no
308
+ * handles, no drag). Absent = unstamped (a local draft, a wildcard local
309
+ * engine, tests) and treated as allowed — the client gate is a COURTESY
310
+ * that keeps the UI truthful; the engine independently enforces.
311
+ */
312
+ authority?: {
313
+ update: boolean;
314
+ delete: boolean;
315
+ };
277
316
  /**
278
317
  * The canonical engine DTO this annotation was derived from (PDF-space, sRGB)
279
318
  * — the single source of truth for its data. `geom` and `style` are
@@ -285,20 +324,13 @@ interface Annot {
285
324
  /** Normalized PDF `/IT` for intent-bearing annotations authored before a DTO exists. */
286
325
  intent?: CaretIntent | StrikeoutIntent | InkIntent;
287
326
  /**
288
- * The `link` prop's value (see {@link AnnotationProps.link}): the link
289
- * kind's own target, or — on other linkable kinds — the folded attached
290
- * link's target. Editable via `setProps`.
327
+ * The link KIND's own `/A` target (see {@link AnnotationProps.link}) —
328
+ * present only on `subtype: 'link'`. Every OTHER kind's link is an
329
+ * attached child annotation in the substrate, read through the `linkOf`
330
+ * lens and materialized by the shell's `syncLink` reconciler; parents
331
+ * store nothing.
291
332
  */
292
333
  link?: PdfLinkTarget | null;
293
- /**
294
- * INTERNAL join keys, never a prop: the engine refs of the attached link
295
- * child annotation(s) this parent's `link` value is materialized as (one
296
- * per visual segment for markup). Maintained by the repository fold and
297
- * consumed by the shell's `syncLink` reconciler + delete expansion — the
298
- * ONLY code allowed to touch those children. Absent on the link kind
299
- * itself and on anything without an attached link.
300
- */
301
- linkRefs?: AnnotationRef[];
302
334
  /**
303
335
  * Relationship to another annotation. `irt` ("in reply to") links a child to a
304
336
  * parent — a reply in a comment thread, or a caret bound to its strikeout in a
@@ -454,7 +486,7 @@ interface MarkupPreview {
454
486
  subtype: Subtype;
455
487
  /** Defaults key, distinct from subtype for presets such as replace-text. */
456
488
  preset: string;
457
- byPage: Record<number, Quad[]>;
489
+ byPage: Record<number, TextQuad$1[]>;
458
490
  }
459
491
  /** Anchor + affordance state for UI that controls an in-progress creation draft. */
460
492
  interface CreationDraftAnchor {
@@ -613,26 +645,26 @@ type Msg = {
613
645
  } | {
614
646
  t: 'createCaret';
615
647
  pon: PageObjectNumber;
616
- rect: Rect;
648
+ anchor: TextEndAnchor;
617
649
  flags?: Partial<AnnotationFlags$1>;
618
650
  } | {
619
651
  t: 'createReplaceText';
620
652
  pon: PageObjectNumber;
621
- rects: Rect[];
622
- endRect: Rect;
653
+ quads: TextQuad$1[];
654
+ anchor: TextEndAnchor;
623
655
  preset?: string;
624
656
  } | {
625
657
  t: 'createMarkup';
626
658
  subtype: Subtype;
627
659
  pon: PageObjectNumber;
628
- rects: Rect[];
660
+ quads: TextQuad$1[];
629
661
  preset?: string;
630
662
  /** The tool's `/F` seed — merged over {@link DRAWN_FLAGS} at commit. */
631
663
  flags?: Partial<AnnotationFlags$1>;
632
664
  } | {
633
665
  t: 'setMarkupPreview';
634
666
  subtype: Subtype;
635
- rectsByPage: Record<number, Rect[]>;
667
+ quadsByPage: Record<number, TextQuad$1[]>;
636
668
  preset?: string;
637
669
  } | {
638
670
  t: 'clearMarkupPreview';
@@ -644,7 +676,12 @@ type Msg = {
644
676
  {
645
677
  t: 'hover';
646
678
  id: Id | null;
647
- } | {
679
+ } |
680
+ /** Force/clear session visibility for specific annotations (the actions
681
+ * plane's Hide sink). Hiding also clears transient engagement (selection,
682
+ * editing, hover) for the hidden ids. Unknown ids no-op. Zero effects. */
683
+ /** Drop overrides for truly DELETED annotations (never for reloads). */
684
+ {
648
685
  t: 'select';
649
686
  ids: Id[];
650
687
  add?: boolean;
@@ -673,6 +710,21 @@ type Msg = {
673
710
  } | {
674
711
  t: 'loaded';
675
712
  annots: Annot[];
713
+ } |
714
+ /**
715
+ * Whole-document hydration ingest (and desync re-ingest): the snapshot is
716
+ * the committed TRUTH. Incoming annots overwrite by id (gesture-locked ids
717
+ * excepted, as in `upsert`); committed model entries ABSENT from the
718
+ * snapshot are reaped — they were deleted while we could not watch.
719
+ * Uncommitted `tmp:` drafts and gesture-locked ids are never reaped, and
720
+ * an in-progress draft survives (unlike `remove`). `bumpAp` marks a
721
+ * desync re-ingest: rasters may have changed invisibly during the gap,
722
+ * so every replaced annotation re-fetches once.
723
+ */
724
+ {
725
+ t: 'hydrated';
726
+ annots: Annot[];
727
+ bumpAp?: boolean;
676
728
  } | {
677
729
  t: 'created';
678
730
  tempId: Id;
@@ -739,6 +791,7 @@ type Effect = {
739
791
  {
740
792
  fx: 'syncLink';
741
793
  id: Id;
794
+ target: PdfLinkTarget | null;
742
795
  } | {
743
796
  fx: 'delete';
744
797
  ref: AnnotationRef;
@@ -1198,6 +1251,36 @@ declare function groupMembers(m: Model, id: Id): Id[];
1198
1251
  /** Union of every id's full group — the selection seen as whole groups. */
1199
1252
  declare function expandGroups(m: Model, ids: Id[]): Id[];
1200
1253
  //#endregion
1254
+ //#region src/plane.d.ts
1255
+ /** True when this annotation belongs to the conversation plane only —
1256
+ * never painted, hit, marquee-selected, or counted into a page's
1257
+ * appearance epoch. */
1258
+ declare function isConversationOnly(a: Pick<Annot, 'irt' | 'group' | 'subtype' | 'data'>): boolean;
1259
+ /**
1260
+ * A link CHILD attached to another annotation — a `/Link` grouped
1261
+ * (`/IRT` + `/RT /Group`) under a non-link parent. Pure substrate: it is
1262
+ * the parent's `link` PROPERTY while authoring (derived via `linkOf`) and
1263
+ * the navigation plane's anchor while reading — never painted, never hit
1264
+ * as itself. Its rect is RECONCILED from the parent's geometry, so direct
1265
+ * manipulation would be overwritten anyway.
1266
+ */
1267
+ declare function isAttachedLink(a: Pick<Annot, 'subtype' | 'group'>): boolean;
1268
+ /**
1269
+ * The ONE page-surface cull: everything that lives in the substrate but is
1270
+ * not a page visual of its own — conversation members (replies, review
1271
+ * states) and attached link children. Paint order, hit-testing, marquee
1272
+ * and the appearance epoch all filter through THIS, never the parts.
1273
+ */
1274
+ declare function isSubstrateOnly(a: Pick<Annot, 'irt' | 'group' | 'subtype' | 'data'>): boolean;
1275
+ //#endregion
1276
+ //#region src/links.d.ts
1277
+ /** Every attached link child of `parentId`, in z-order (multi-segment
1278
+ * markup parents carry several children with one shared target). */
1279
+ declare function linkChildrenOf(m: Model, parentId: Id): Annot[];
1280
+ /** The parent's link target, derived from its first attached child — the
1281
+ * read side of the `syncLink` reconciler. Null when no child exists. */
1282
+ declare function linkOf(m: Model, parentId: Id): PdfLinkTarget | null;
1283
+ //#endregion
1201
1284
  //#region src/kinds.d.ts
1202
1285
  /**
1203
1286
  * One editable property of a kind, as a UI contract: which {@link AnnotationProps}
@@ -1386,7 +1469,10 @@ declare const DEFAULT_CHROME_GEOM: {
1386
1469
  };
1387
1470
  /** Normalize degrees into `[0, 360)`. */
1388
1471
  declare const normalizeDeg: (d: number) => number;
1389
- /** A geom's applied rotation (deg), or 0 for the non-rotatable kinds. */
1472
+ /** A geom's applied rotation (deg), or 0 for the non-rotatable kinds. A
1473
+ * caret's `rot` is AUTHORING metadata (its text's baseline tilt): reported
1474
+ * here so the renderer and selection chrome follow it, while the caret's
1475
+ * caps (not movable/resizable) keep every rotate gesture away from it. */
1390
1476
  declare function geomRotation(g: Geom): number;
1391
1477
  /**
1392
1478
  * The rotation PIVOT for a single shape: a box turns about its own `rect`
@@ -1395,7 +1481,10 @@ declare function geomRotation(g: Geom): number;
1395
1481
  * stays cleanly additive across gestures and reset is exact.
1396
1482
  */
1397
1483
  declare function centroidOf(g: Geom): Vec;
1398
- /** Is this kind rotatable (the geometry carries a meaningful `rot`)? */
1484
+ /** Does the geometry carry a meaningful `rot` (an oriented local box exists)?
1485
+ * ORIENTATION is a geometry fact; whether the USER may rotate is the separate
1486
+ * `caps.rotatable` gate — a caret is oriented (it rides its text's tilt) yet
1487
+ * offers no rotate gesture. */
1399
1488
  declare function isRotatableGeom(g: Geom): boolean;
1400
1489
  /**
1401
1490
  * Rotate a geom by `deltaDeg` (clockwise) about `pivot`.
@@ -1404,7 +1493,10 @@ declare function isRotatableGeom(g: Geom): boolean;
1404
1493
  * pivot IS the box centre this is a pure `rot += delta`.
1405
1494
  * - VERTEX (`line`/`poly`/`ink`): map every point through the rotation AND bump
1406
1495
  * the advisory `rot` (the points stay the authoritative visual).
1407
- * Non-rotatable kinds (caret/quads, callouts) are returned unchanged.
1496
+ * Kinds without a rotate VERB are returned unchanged: quads and callouts, and
1497
+ * also the caret — oriented (`isRotatableGeom`) but text-anchored, so its tilt
1498
+ * is authoring metadata that no gesture edits (`geomResetRotation` still
1499
+ * clears it).
1408
1500
  */
1409
1501
  declare function geomRotateAbout(g: Geom, pivot: Vec, deltaDeg: number): Geom;
1410
1502
  /** The AABB of `rect` rotated `deg` about its own centre. */
@@ -1520,6 +1612,26 @@ declare function calloutLinePoints(g: Extract<Geom, {
1520
1612
  */
1521
1613
  declare function shapeRectFor(dragged: Rect, ellipse: boolean, style: Style): Rect;
1522
1614
  declare function caretRectFromTextEnd(lineRect: Rect): Rect;
1615
+ /**
1616
+ * Caret box for a text-edit anchor: half the glyph's ink height, centered on
1617
+ * the TRAILING baseline corner in READING direction (`advance` decides which
1618
+ * end — RTL carets land on the visual left), sitting on the baseline. The box
1619
+ * stays axis-aligned; use {@link caretGeomFromAnchor} for the tilt-carrying
1620
+ * geometry.
1621
+ */
1622
+ declare function caretRectFromAnchor(anchor: TextEndAnchor): Rect;
1623
+ /**
1624
+ * Caret GEOMETRY for a text-edit anchor: the box-family pair — an UNROTATED
1625
+ * box whose centre sits half a caret-size ascent-ward of the trailing
1626
+ * baseline corner, plus `rot` = the text's baseline tilt (deg, CW in y-down
1627
+ * content space). Rotating the box about its centre by `rot` lands it
1628
+ * hugging the rotated baseline, symbol pointing at its text. For upright
1629
+ * anchors this degenerates EXACTLY to {@link caretRectFromAnchor} with no
1630
+ * `rot` key — the dominant case is byte-identical.
1631
+ */
1632
+ declare function caretGeomFromAnchor(anchor: TextEndAnchor): Extract<Geom, {
1633
+ t: 'caret';
1634
+ }>;
1523
1635
  /** Miter limit shared by the bounds math AND the SVG renderer (`stroke-miterlimit`),
1524
1636
  * so the computed box and the drawn stroke always agree on where a sharp join
1525
1637
  * bevels instead of spiking. 10 = the PDF default (also what the baked /AP uses). */
@@ -1632,5 +1744,5 @@ declare function scene(item: RenderItem): SceneNode[];
1632
1744
  */
1633
1745
  declare function straightenInkStroke(points: readonly Vec[], options: InkStraightenOptions): Vec[];
1634
1746
  //#endregion
1635
- export { type AnchorMode, type Annot, type AnnotationFlags, type AnnotationKind, type AnnotationProps, type AnnotationPropsPatch, type BlendMode, type Border, type Callout, type ChromeGeom, type ChromeNode, type ClickCreate, type ClickPlacement, type CreationDraftAnchor, type Cursor, DEFAULT_CHROME_GEOM, DRAWN_FLAGS, type Draft, type Effect, FLAG_KEYS, type FlagBearer, type Geom, type GroupCaps, type Guide, type Handle, type Id, type InkStraightenOptions, KINDS, type KindCaps, type LineEnding, type LineEndings, MIN_DRAG, MITER_LIMIT, type Model, type Msg, NO_ANNOTATION_FLAGS, type Paint, type PatchScope, type PointerInput, type PropKey, type PropSpec, type Quad, RECT_HANDLES, ROTATE_KNOB_OFFSET, type Rect, type RectHandle, type RenderItem, type RenderNode, type SceneNode, type SnapResult, type SnapSettings, type Style, type Subtype, type Target, type TextAlign, type TextBox, type TextStyle, type Vec, type ViewEnv, anchorModeOf, anchorOf, anchoredBox, anchoredGeom, anchoredStrokeWidth, annotContentsEditable, annotInteractive, annotTransformable, applyProps, calloutConnection, calloutLinePoints, canMove, capsFor, caretRectFromTextEnd, centroidOf, chrome, clampRectToBox, clickCreateGeom, cloudyBorderExtent, cloudyPath, computeMoveSnap, contentToPdfPoint, contentToPdfRect, creationDraftAnchor, cursorAt, defaultsFor, expandGroups, fitStampBox, flagsEqual, geomBounds, geomDragHandle, geomHandles, geomHit, geomPdfBounds, geomResetRotation, geomRotateAbout, geomRotation, geomScaleAbout, geomScene, geomTranslate, geomVisualBounds, groupCaps, groupKeyOf, groupMembers, groupResizeAnchor, groupResizeBox, groupResizeFactors, hitTest, initialModel, initialStyle, initialTextStyle, interactive, isRotatableGeom, isSelectable, mergeFlags, normalizeDeg, obbFromGeom, pageItems, pdfToContentPoint, pdfToContentRect, placeRotateKnob, pointInQuad, propsFor, quadIntersectsRect, readProp, rectFromPoints, resolveClickPlacement, rotateDraftDelta, rotateKnob, rotatedAabb, rotatedHandleCursor, scene, selectedItems, selectionAnchor, selectionBounds, selectionBoundsOnPage, selectionCenter, selectionKnob, selectionQuad, shapeRectFor, sharedProps, straightenInkStroke, styleFromProps, textBoxes, textStyleFromProps, transposedAboutCenter, unanchoredGeom, unionRect, update, uprightAnchoredRect, uprightRotation, viewable };
1747
+ export { type AnchorMode, type Annot, type AnnotationFlags, type AnnotationKind, type AnnotationProps, type AnnotationPropsPatch, type BlendMode, type Border, type Callout, type ChromeGeom, type ChromeNode, type ClickCreate, type ClickPlacement, type CreationDraftAnchor, type Cursor, DEFAULT_CHROME_GEOM, DRAWN_FLAGS, type Draft, type Effect, FLAG_KEYS, type FlagBearer, type Geom, type GroupCaps, type Guide, type Handle, type Id, type InkStraightenOptions, KINDS, type KindCaps, type LineEnding, type LineEndings, MIN_DRAG, MITER_LIMIT, type Model, type Msg, NO_ANNOTATION_FLAGS, type Paint, type PatchScope, type PointerInput, type PropKey, type PropSpec, type Quad, RECT_HANDLES, ROTATE_KNOB_OFFSET, type Rect, type RectHandle, type RenderItem, type RenderNode, type SceneNode, type SnapResult, type SnapSettings, type Style, type Subtype, type Target, type TextAlign, type TextBox, type TextEndAnchor, type TextQuad, type TextStyle, type Vec, type ViewEnv, anchorModeOf, anchorOf, anchoredBox, anchoredGeom, anchoredStrokeWidth, annotContentsEditable, annotDeletable, annotInteractive, annotTransformable, applyProps, calloutConnection, calloutLinePoints, canMove, capsFor, caretGeomFromAnchor, caretRectFromAnchor, caretRectFromTextEnd, centroidOf, chrome, clampRectToBox, clickCreateGeom, cloudyBorderExtent, cloudyPath, computeMoveSnap, contentToPdfPoint, contentToPdfRect, creationDraftAnchor, cursorAt, defaultsFor, expandGroups, fitStampBox, flagsEqual, geomBounds, geomDragHandle, geomHandles, geomHit, geomPdfBounds, geomResetRotation, geomRotateAbout, geomRotation, geomScaleAbout, geomScene, geomTranslate, geomVisualBounds, groupCaps, groupKeyOf, groupMembers, groupResizeAnchor, groupResizeBox, groupResizeFactors, hitTest, initialModel, initialStyle, initialTextStyle, interactive, isAttachedLink, isConversationOnly, isRotatableGeom, isSelectable, isSubstrateOnly, linkChildrenOf, linkOf, mergeFlags, normalizeDeg, obbFromGeom, pageItems, pdfToContentPoint, pdfToContentRect, placeRotateKnob, pointInQuad, propsFor, quadIntersectsRect, readProp, rectFromPoints, resolveClickPlacement, rotateDraftDelta, rotateKnob, rotatedAabb, rotatedHandleCursor, scene, selectedItems, selectionAnchor, selectionBounds, selectionBoundsOnPage, selectionCenter, selectionKnob, selectionQuad, shapeRectFor, sharedProps, straightenInkStroke, styleFromProps, textBoxes, textStyleFromProps, transposedAboutCenter, unanchoredGeom, unionRect, update, uprightAnchoredRect, uprightRotation, viewable };
1636
1748
  //# sourceMappingURL=index.d.ts.map