@paged-media/plugin-api 0.2.28-canary.0 → 0.2.30-canary.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/dist/editor.d.ts CHANGED
@@ -444,7 +444,18 @@ export interface PagedEditor {
444
444
  * scene channel (headless / older editor); `host.contribute.sceneLayer()`
445
445
  * then warns + no-ops and `supports("rendering.sceneLayer@1")` is false. */
446
446
  sceneLayers?: {
447
- submit(elementId: string, layer: SceneLayer): Promise<void>;
447
+ /**
448
+ * `caller` (C-34) — the plugin submitting. OPTIONAL, and omitting it
449
+ * keeps the prior behaviour exactly: the engine records no owner and
450
+ * enforces nothing.
451
+ *
452
+ * When present the engine records which plugin claimed the frame's
453
+ * render and refuses a foreign replace, because a frame's in-frame
454
+ * render belongs to ONE content type and the door used to be an
455
+ * unconditional insert. The SDK adapter fills it from the manifest
456
+ * id, so a bundle never passes it itself.
457
+ */
458
+ submit(elementId: string, layer: SceneLayer, caller?: string): Promise<void>;
448
459
  clear(elementId: string): Promise<void>;
449
460
  };
450
461
  /** C-6 (I-06) — the renderer RESOURCE-PROVIDER channel. The editor
package/dist/host.d.ts CHANGED
@@ -60,9 +60,37 @@ export interface EditContextContribution {
60
60
  * (a content-type name, e.g. `"vectorGraphic"`, `"webFrame"`), but
61
61
  * the bundle can only claim a type it declared. */
62
62
  type: string;
63
- /** How the user enters it. `"doubleClick"` wires the canvas
64
- * double-click entry; `"command"` is programmatic / menu-driven. */
65
- entry: "doubleClick" | "command";
63
+ /**
64
+ * How the user enters it. `"doubleClick"` wires the canvas
65
+ * double-click entry.
66
+ *
67
+ * THIS IS THE ONLY VALUE, and that is a product rule rather than a
68
+ * missing feature (K-13, 2026-08-07). **Any plugin that exposes
69
+ * content to the canvas is entered by double-clicking its frame.**
70
+ * The gesture must mean ONE thing across the product: a user learns
71
+ * "double-click to go inside" once, and it has to hold for a vector
72
+ * group, a spreadsheet, a web frame, a Word document and a raster
73
+ * image alike. A bundle with a bespoke entry would turn "how do I get
74
+ * into this thing" into plugin-specific trivia, which is a worse cost
75
+ * than any convenience a custom entry buys.
76
+ *
77
+ * `"command"` USED TO BE HERE, documented as "programmatic /
78
+ * menu-driven", and nothing ever implemented it: the registry is
79
+ * `register`-only, `BundleHost` has no enter member, and the shell's
80
+ * `enter` is a React hook no bundle can reach. So it was a value the
81
+ * platform accepted, validated and registered — and then silently
82
+ * never honoured, which is the `absent` lie one layer up. An audit at
83
+ * removal found 5 of 5 content plugins on `"doubleClick"` (draw, web,
84
+ * sheets, doc, image) and ZERO users of `"command"`, so removing it
85
+ * broke nothing and made the rule checkable by the compiler instead
86
+ * of by review.
87
+ *
88
+ * Kept as a one-member union rather than deleted outright: the field
89
+ * is where a SECOND entry gesture would be declared if one is ever
90
+ * genuinely warranted, and a plugin author reading it should see that
91
+ * the choice was made, not that it was never considered.
92
+ */
93
+ entry: "doubleClick";
66
94
  /** Does this element warrant entering THIS context? Pure predicate
67
95
  * over the candidate snapshot (kind / groupChain / this plugin's
68
96
  * metadata). When an `objectType` already routes a double-click to a
@@ -292,7 +292,9 @@ export interface PluginContributions {
292
292
  * nondeterminism is undebuggable. */
293
293
  editContexts?: Array<{
294
294
  type: string;
295
- entry: "doubleClick" | "command";
295
+ /** K-13 — the ONE entry gesture for canvas content. See
296
+ * `EditContextContribution.entry` and DESIGN.md §19. */
297
+ entry: "doubleClick";
296
298
  priority?: number;
297
299
  }>;
298
300
  /** Reserved (paged.web §9.1.2): plugin-defined object types under
@@ -1,101 +1,68 @@
1
- import type { ElementId, Mutation } from "./wire";
1
+ import type { Mutation } from "./wire";
2
2
  export type { ElementId, PageId, NodeId, NodeSpec, Mutation, Operation, PropertyPath, Value, PathAnchorSpec, PathAnchorTriple, PathAnchorsResult, PathPointAddress, PathPointRole, PathfinderKind, HitFilter, HitResult, CollectionName, DocumentMeta, ElementGeometryItem, SceneTreeNode, SelectionMode, ContentSelection, MainToWorker, MainToWorkerKind, WorkerToMain, SceneLayer, SceneItem, ScenePathSeg, ScenePaint, GestureType, GestureHandle, GestureModifiers, SwatchSpec, GradientSpec, GradientStopSpec, SwatchSummary, GradientSummary, LayerSummary, } from "./wire";
3
3
  /** v56 (Wave B) — close an OPEN subpath of a path element: the inverse
4
4
  * gesture of `pathOpenAt`'s scissors cut. `subpath` picks the contour
5
5
  * by index; omit for the default (the single/last open subpath).
6
6
  * Coincident endpoints — the duplicated pair a cut leaves — merge back
7
7
  * into one anchor; endpoints apart gain the implicit closing edge. */
8
- export type ClosePathMutation = {
8
+ export type ClosePathMutation = Extract<Mutation, {
9
9
  op: "closePath";
10
- args: {
11
- elementId: ElementId;
12
- subpath?: number | null;
13
- };
14
- };
10
+ }>;
15
11
  /** v56 (Wave B) — weld two OPEN single-contour path elements into one
16
12
  * (InDesign's Join): connect the NEAREST endpoints of `elementId` and
17
13
  * `otherId`, then delete `otherId`. Both endpoint pairs coincident
18
14
  * closes the result into a ring. Non-path / closed / multi-contour
19
15
  * inputs are rejected with an honest error (no-op). One undo step
20
16
  * restores BOTH elements. */
21
- export type JoinPathsMutation = {
17
+ export type JoinPathsMutation = Extract<Mutation, {
22
18
  op: "joinPaths";
23
- args: {
24
- elementId: ElementId;
25
- otherId: ElementId;
26
- };
27
- };
19
+ }>;
28
20
  /** v56 (B-18) — InDesign paste-into: nest an existing TOP-LEVEL page
29
21
  * item inside a container Rectangle / Oval / Polygon. The child keeps
30
22
  * its document-space geometry (nothing moves on canvas) and renders
31
23
  * clipped by the container's outline. Grouped / already-nested
32
24
  * children and non-container hosts are rejected with an honest error.
33
25
  * One undo pops the child back to its exact stacking slot. */
34
- export type PasteIntoMutation = {
26
+ export type PasteIntoMutation = Extract<Mutation, {
35
27
  op: "pasteInto";
36
- args: {
37
- containerId: ElementId;
38
- childId: ElementId;
39
- };
40
- };
28
+ }>;
41
29
  /** v56 (B-18) — the inverse gesture: pop a pasted-in child back to top
42
30
  * level (stacks on top), world transform preserved. One undo re-nests
43
31
  * it at the same child index. */
44
- export type ReleaseFromMutation = {
32
+ export type ReleaseFromMutation = Extract<Mutation, {
45
33
  op: "releaseFrom";
46
- args: {
47
- childId: ElementId;
48
- };
49
- };
34
+ }>;
50
35
  /** v57 (B-22) — every face of the arrangement becomes its own object,
51
36
  * keeping the attributes of the topmost input covering it. */
52
- export type PathfinderDivideMutation = {
37
+ export type PathfinderDivideMutation = Extract<Mutation, {
53
38
  op: "pathfinderDivide";
54
- args: {
55
- elementIds: ElementId[];
56
- };
57
- };
39
+ }>;
58
40
  /** v57 (B-22) — each input is clipped to the part nothing above it
59
41
  * covers, and loses its stroke. Inputs entirely hidden are deleted. */
60
- export type PathfinderTrimMutation = {
42
+ export type PathfinderTrimMutation = Extract<Mutation, {
61
43
  op: "pathfinderTrim";
62
- args: {
63
- elementIds: ElementId[];
64
- };
65
- };
44
+ }>;
66
45
  /** v57 (B-22) — Trim, then coalesce: inputs that share a fill colour
67
46
  * merge into one object. */
68
- export type PathfinderMergeMutation = {
47
+ export type PathfinderMergeMutation = Extract<Mutation, {
69
48
  op: "pathfinderMerge";
70
- args: {
71
- elementIds: ElementId[];
72
- };
73
- };
49
+ }>;
74
50
  /** v57 (B-22) — keep only what falls inside the TOPMOST input, coloured
75
51
  * by the objects beneath it; the topmost input is consumed as the
76
52
  * cookie cutter and disappears. */
77
- export type PathfinderCropMutation = {
53
+ export type PathfinderCropMutation = Extract<Mutation, {
78
54
  op: "pathfinderCrop";
79
- args: {
80
- elementIds: ElementId[];
81
- };
82
- };
55
+ }>;
83
56
  /** v57 (B-22) — fills become strokes: every arrangement edge (split at
84
57
  * each crossing) becomes an open `GraphicLine` stroked with the fill of
85
58
  * the input that contributed it. All inputs are consumed. */
86
- export type PathfinderOutlineMutation = {
59
+ export type PathfinderOutlineMutation = Extract<Mutation, {
87
60
  op: "pathfinderOutline";
88
- args: {
89
- elementIds: ElementId[];
90
- };
91
- };
61
+ }>;
92
62
  /** v57 (B-22) — the BACKMOST object minus every object in front of it. */
93
- export type PathfinderMinusBackMutation = {
63
+ export type PathfinderMinusBackMutation = Extract<Mutation, {
94
64
  op: "pathfinderMinusBack";
95
- args: {
96
- elementIds: ElementId[];
97
- };
98
- };
65
+ }>;
99
66
  /** v57 (B-22) — whether `pathfinderFaces` KEEPS the named faces or
100
67
  * REMOVES them (Shape Builder's drag vs alt-drag). */
101
68
  export type FaceSelectMode = "keep" | "remove";
@@ -105,14 +72,9 @@ export type FaceSelectMode = "keep" | "remove";
105
72
  * `elementIds` (ids are only stable per input set); `mode` picks
106
73
  * whether they are the faces kept or the faces removed. An unknown id
107
74
  * is REFUSED, not ignored — a stale face set fails loudly. */
108
- export type PathfinderFacesMutation = {
75
+ export type PathfinderFacesMutation = Extract<Mutation, {
109
76
  op: "pathfinderFaces";
110
- args: {
111
- elementIds: ElementId[];
112
- faces: string[];
113
- mode: FaceSelectMode;
114
- };
115
- };
77
+ }>;
116
78
  /** v58 (C-28) — how the mask artwork's coverage is read. `luminosity`
117
79
  * is Illustrator's default and PDF's `/S /Luminosity`; `alpha` reads
118
80
  * the artwork's alpha channel instead. Unpainted area means HIDDEN for
@@ -136,24 +98,15 @@ export type OpacityMaskType = "luminosity" | "alpha";
136
98
  * Vello output is now byte-identical to the CPU rasterizer across
137
99
  * luminosity, alpha and both inverted forms. Safe to build WYSIWYG UI
138
100
  * over. */
139
- export type ApplyOpacityMaskMutation = {
101
+ export type ApplyOpacityMaskMutation = Extract<Mutation, {
140
102
  op: "applyOpacityMask";
141
- args: {
142
- targetId: ElementId;
143
- maskId: ElementId;
144
- maskType?: OpacityMaskType | null;
145
- invert?: boolean | null;
146
- };
147
- };
103
+ }>;
148
104
  /** v58 (C-28) — drop the mask relation; the artwork returns to top level
149
105
  * with its geometry untouched. One undo re-applies the mask with its
150
106
  * original mode/invert at the same z slot. */
151
- export type ReleaseOpacityMaskMutation = {
107
+ export type ReleaseOpacityMaskMutation = Extract<Mutation, {
152
108
  op: "releaseOpacityMask";
153
- args: {
154
- targetId: ElementId;
155
- };
156
- };
109
+ }>;
157
110
  /** v58 (C-29) — **Type on a Path**: flow an existing story along an
158
111
  * existing path element. The engine could already RENDER type on a path
159
112
  * loaded from an IDML; until v58 nothing could create one.
@@ -164,24 +117,13 @@ export type ReleaseOpacityMaskMutation = {
164
117
  * Center honoured), `flipPathEffect` and the `startBracket`/`endBracket`
165
118
  * range are all live. `PathEffect` is deliberately NOT exposed — only
166
119
  * `RainbowPathEffect` actually renders. */
167
- export type AttachTextToPathMutation = {
120
+ export type AttachTextToPathMutation = Extract<Mutation, {
168
121
  op: "attachTextToPath";
169
- args: {
170
- elementId: ElementId;
171
- storyId: string;
172
- pathTypeAlignment?: string | null;
173
- flipPathEffect?: string | null;
174
- startBracket?: number | null;
175
- endBracket?: number | null;
176
- };
177
- };
122
+ }>;
178
123
  /** v58 (C-29) — unlink the text from the path; the exact inverse. */
179
- export type DetachTextFromPathMutation = {
124
+ export type DetachTextFromPathMutation = Extract<Mutation, {
180
125
  op: "detachTextFromPath";
181
- args: {
182
- elementId: ElementId;
183
- };
184
- };
126
+ }>;
185
127
  /** v59 (Arrange) — where `reorderElement` puts its target inside the
186
128
  * sibling list it already belongs to. `0` is the BACKMOST slot (painted
187
129
  * first). Prefer the four verbs: they are evaluated against the order
@@ -226,16 +168,19 @@ export type ZOrderTarget = "front" | "back" | "forward" | "backward" | {
226
168
  * existing source elements byte-for-byte and only places new ones, so a
227
169
  * reorder reverts on an export/reopen round trip. Do not present
228
170
  * Arrange as durable across IDML interchange yet. */
229
- export type ReorderElementMutation = {
171
+ export type ReorderElementMutation = Extract<Mutation, {
230
172
  op: "reorderElement";
231
- args: {
232
- elementId: ElementId;
233
- to: ZOrderTarget;
234
- };
235
- };
236
- /** The protocol-ahead ops, as one union — the delta between the
237
- * vendored `Mutation` (protocol 51) and core's protocol 59. Empties
238
- * itself on the next `sync-wire.mjs` run. */
173
+ }>;
174
+ /** The protocol-ahead ops, as one union.
175
+ *
176
+ * This said "the delta between the vendored `Mutation` (protocol 51)
177
+ * and core's protocol 59 — empties itself on the next `sync-wire.mjs`
178
+ * run". The run happened (the vendored stamp is 0.61.0) and the delta
179
+ * did NOT empty itself: `sync-wire.mjs` rewrites `wire.d.ts` and has
180
+ * no idea this file exists. So it is currently EMPTY in substance —
181
+ * every member is a member of `Mutation` — while still being a real
182
+ * union, and the gate at the foot of this file is what keeps that
183
+ * claim honest instead of asserting it in prose. */
239
184
  /** v57 (C-15) — name the id a creating sibling is about to mint, so a
240
185
  * LATER child of the same batch can address it as `"$h:<handle>"`.
241
186
  *
@@ -262,14 +207,40 @@ export type ReorderElementMutation = {
262
207
  * Generalises the v34 `$created` sentinel — which only two mutation
263
208
  * kinds understood — to any number of live names addressable from any
264
209
  * mutation kind. */
265
- export type BindCreatedMutation = {
210
+ export type BindCreatedMutation = Extract<Mutation, {
266
211
  op: "bindCreated";
267
- args: {
268
- handle: string;
269
- };
270
- };
212
+ }>;
271
213
  export type PendingMutation = BindCreatedMutation | ClosePathMutation | JoinPathsMutation | PasteIntoMutation | ReleaseFromMutation | PathfinderDivideMutation | PathfinderTrimMutation | PathfinderMergeMutation | PathfinderCropMutation | PathfinderOutlineMutation | PathfinderMinusBackMutation | PathfinderFacesMutation | ApplyOpacityMaskMutation | ReleaseOpacityMaskMutation | AttachTextToPathMutation | DetachTextFromPathMutation | ReorderElementMutation;
272
214
  /** What `host.document.mutate` ACCEPTS: the vendored op union plus the
273
215
  * protocol-ahead ops. Widening an accepted-input type is additive —
274
216
  * every existing `Mutation` call site still compiles. */
275
217
  export type MutationInput = Mutation | PendingMutation;
218
+ /** K-12 — THE DELTA IS A SUBSET OF `Mutation`, and this is the gate.
219
+ *
220
+ * `sync-wire.mjs` empties the delta in one direction only: it refreshes
221
+ * `wire.d.ts`, and nothing here notices that the ops it used to be
222
+ * ahead of have arrived. So the delta drained itself and no one told
223
+ * it — every member above is now IN the vendored union, and the block's
224
+ * own header has said so since 2026-08-06 while the members went on
225
+ * being independently-declared object literals.
226
+ *
227
+ * That is not cosmetic. A hand-written literal that HAPPENS to match a
228
+ * generated one is a second type that structural typing lets you get
229
+ * away with until the generated side changes a field — and then the
230
+ * error surfaces at the call site, not here. Declaring each member as
231
+ * `Extract<Mutation, …>` makes them one type by construction, so they
232
+ * cannot drift at all.
233
+ *
234
+ * This line is the check: if any member ever stops being part of
235
+ * `Mutation`, its `Extract` collapses to `never`, `PendingMutation`
236
+ * narrows, and the assignment below fails to compile — naming the
237
+ * regression here rather than in whichever bundle hit it first. When a
238
+ * genuinely protocol-ahead op is added, it will not be an `Extract`,
239
+ * and this line is what will (correctly) fail until it lands in a
240
+ * published wire and the member is folded back.
241
+ *
242
+ * Type-level, never a value: this module is the type-only façade, and
243
+ * a `const` here — even an unexported one — would put a runtime symbol
244
+ * in a package whose whole contract is that it has none. */
245
+ type Assert<T extends true> = T;
246
+ export type DeltaIsASubsetOfTheSettledUnion = Assert<PendingMutation extends Mutation ? true : false>;
package/dist/wire.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // GENERATED — do not edit. Vendored verbatim from the published
2
2
  // @paged-media/canvas-wasm .d.ts (tsify output from paged-media/core,
3
3
  // MPL-2.0 OR PMEL). Sync: node scripts/sync-wire.mjs · Check: --check.
4
- // Synced from @paged-media/canvas-wasm@0.51.0
4
+ // Synced from @paged-media/canvas-wasm@0.61.1
5
5
  /* tslint:disable */
6
6
  /* eslint-disable */
7
7
 
@@ -47,7 +47,7 @@ export type SceneBlendMode = "multiply" | "screen" | "overlay" | "darken" | "lig
47
47
  * the worker rejects each variant with `WorkerError::NotImplemented`.
48
48
  * Phase 3 lights these up incrementally.
49
49
  */
50
- export type Mutation = { op: "insertText"; args: { storyId: string; offset: number; text: string; cell?: TextCellAddr | null } } | { op: "deleteRange"; args: { storyId: string; start: number; end: number; cell?: TextCellAddr | null } } | { op: "applyStyle"; args: { storyId: string; start: number; end: number; style: string; scope: StyleScope } } | { op: "insertField"; args: { storyId: string; offset: number; field: FieldKind } } | { op: "setFieldValue"; args: { storyId: string; offset: number; value?: string | null } } | { op: "placeImage"; args: { elementId: string; uri: string; fit?: string | null } } | { op: "replaceImageBytes"; args: { elementId: string; bytes?: number[] | null } } | { op: "moveFrame"; args: { frameId: string; transform: [number, number, number, number, number, number] } } | { op: "resizeFrame"; args: { frameId: string; bounds: [number, number, number, number] } } | { op: "linkFrames"; args: { from: string; to: string } } | { op: "unlinkFrames"; args: { frame: string } } | { op: "insertPage"; args: { afterPageId: PageId | null; masterId: string | null } } | { op: "deletePage"; args: { pageId: PageId } } | { op: "resizePage"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertTextFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "deleteFrame"; args: { frameId: string } } | { op: "insertLine"; args: { pageId: PageId; start: [number, number]; end: [number, number] } } | { op: "insertPath"; args: { pageId: PageId; anchors: PathAnchorSpec[]; open: boolean; smooth?: boolean } } | { op: "setDocumentDefaults"; args: { fillColor: string | null; strokeColor: string | null; strokeWeight: number | null } } | { op: "setColorSettings"; args: { cmykProfileName: string | null; rgbPolicy: string | null; intent: string | null; bpc: boolean | null } } | { op: "setProofSetup"; args: { profileName: string | null; simulatePaperWhite?: boolean; intent: string | null } } | { op: "importSwatchLibrary"; args: { bytes: number[]; groupName?: string | null } } | { op: "setInkSetting"; args: { spotId: string; convertToProcess?: boolean; aliasTo?: string | null } } | { op: "setUseStandardLabForSpots"; args: { enabled: boolean } } | { op: "pathPointInsert"; args: { elementId: ElementId; index: number; anchor: PathAnchorSpec; prevSubpathStarts?: number[] | null } } | { op: "pathPointRemove"; args: { elementId: ElementId; index: number } } | { op: "pathOpenAt"; args: { elementId: ElementId; index: number } } | { op: "outlineStroke"; args: { elementId: ElementId; width: number; cap: string; join: string; miterLimit: number } } | { op: "offsetPath"; args: { elementId: ElementId; delta: number; join: string; miterLimit: number } } | { op: "simplifyPath"; args: { elementId: ElementId; tolerance: number } } | { op: "createGroup"; args: { memberIds: ElementId[] } } | { op: "dissolveGroup"; args: { groupId: string } } | { op: "setGroupTransform"; args: { groupId: string; transform?: [number, number, number, number, number, number] | null } } | { op: "setPluginMetadata"; args: { elementId: ElementId; key: string; value?: string | null; caller?: string | null } } | { op: "pathPointCurveType"; args: { elementId: ElementId; index: number; smooth: boolean } } | { op: "pathPointSet"; args: { elementId: ElementId; index: number; role: PathPointRole; position: [number, number] } } | { op: "batch"; args: { ops: Mutation[] } } | { op: "layerSetVisible"; args: { layerId: string; visible: boolean } } | { op: "layerSetLocked"; args: { layerId: string; locked: boolean } } | { op: "layerSetPrintable"; args: { layerId: string; printable: boolean } } | { op: "layerSetName"; args: { layerId: string; name: string } } | { op: "layerMove"; args: { layerId: string; newIndex: number } } | { op: "layerInsert"; args: { position: number; name: string } } | { op: "layerRemove"; args: { layerId: string } } | { op: "setElementProperty"; args: { elementId: ElementId; path: PropertyPath; value: Value } } | { op: "pathfinderBoolean"; args: { kept: ElementId; others: ElementId[]; kind: PathfinderKind } } | { op: "createSwatch"; args: { spec: SwatchSpec } } | { op: "editSwatch"; args: { swatchId: string; spec: SwatchSpec } } | { op: "deleteSwatch"; args: { swatchId: string } } | { op: "createGradient"; args: { spec: GradientSpec } } | { op: "editGradient"; args: { gradientId: string; spec: GradientSpec } } | { op: "deleteGradient"; args: { gradientId: string } } | { op: "createColorGroup"; args: { spec: ColorGroupSpec } } | { op: "editColorGroup"; args: { groupId: string; spec: ColorGroupSpec } } | { op: "deleteColorGroup"; args: { groupId: string } } | { op: "createNumberingList"; args: { spec: NumberingListSpec } } | { op: "editNumberingList"; args: { listId: string; spec: NumberingListSpec } } | { op: "deleteNumberingList"; args: { listId: string } } | { op: "createParagraphStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameParagraphStyle"; args: { styleId: string; name: string } } | { op: "deleteParagraphStyle"; args: { styleId: string } } | { op: "createCharacterStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCharacterStyle"; args: { styleId: string; name: string } } | { op: "deleteCharacterStyle"; args: { styleId: string } } | { op: "createObjectStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameObjectStyle"; args: { styleId: string; name: string } } | { op: "deleteObjectStyle"; args: { styleId: string } } | { op: "createCellStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCellStyle"; args: { styleId: string; name: string } } | { op: "deleteCellStyle"; args: { styleId: string } } | { op: "createTableStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameTableStyle"; args: { styleId: string; name: string } } | { op: "deleteTableStyle"; args: { styleId: string } } | { op: "setStyleProperty"; args: { collection: StyleCollection; styleId: string; path: PropertyPath; value: Value } } | { op: "insertOval"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertGuide"; args: { spreadId: string; orientation: GuideOrientationSpec; position: number; pageIndex?: number } } | { op: "moveGuide"; args: { guideId: string; position: number } } | { op: "deleteGuide"; args: { guideId: string } } | { op: "setConditionVisible"; args: { condition: string; visible: boolean } } | { op: "activateConditionSet"; args: { set: string } } | { op: "applyMasterToPage"; args: { page: PageId; master?: string | null } } | { op: "duplicatePage"; args: { page: PageId } } | { op: "insertSection"; args: { atPage: PageId; prefix?: string | null; numberingStyle?: string | null; startAt?: number | null } } | { op: "editSection"; args: { sectionId: string; prefix?: string | null | null; numberingStyle?: string | null; startAt?: number | null | null } } | { op: "deleteSection"; args: { sectionId: string } } | { op: "setRowHeight"; args: { storyId: string; tableId: string; row: number; height?: number | null } } | { op: "setColumnWidth"; args: { storyId: string; tableId: string; col: number; width?: number | null } } | { op: "insertTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "insertTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "insertHeaderRow"; args: { storyId: string; tableId: string } } | { op: "removeHeaderRow"; args: { storyId: string; tableId: string } } | { op: "insertFooterRow"; args: { storyId: string; tableId: string } } | { op: "removeFooterRow"; args: { storyId: string; tableId: string } } | { op: "setCellSpan"; args: { storyId: string; tableId: string; row: number; col: number; rowSpan: number; columnSpan: number } } | { op: "insertTable"; args: { storyId: string; rows: number; cols: number; headerRows?: number; footerRows?: number; columnWidths?: number[]; rowHeights?: number[] } };
50
+ export type Mutation = { op: "insertText"; args: { storyId: string; offset: number; text: string; cell?: TextCellAddr | null } } | { op: "deleteRange"; args: { storyId: string; start: number; end: number; cell?: TextCellAddr | null } } | { op: "applyStyle"; args: { storyId: string; start: number; end: number; style: string; scope: StyleScope; cell?: TextCellAddr | null } } | { op: "insertField"; args: { storyId: string; offset: number; field: FieldKind } } | { op: "insertAnchoredFrame"; args: { storyId: string; offset: number; width: number; height: number; imageUri?: string | null } } | { op: "insertHyperlink"; args: { storyId: string; start: number; end: number; url: string } } | { op: "setFieldValue"; args: { storyId: string; offset: number; value?: string | null } } | { op: "placeImage"; args: { elementId: string; uri: string; fit?: string | null } } | { op: "replaceImageBytes"; args: { elementId: string; bytes?: number[] | null } } | { op: "moveFrame"; args: { frameId: string; transform: [number, number, number, number, number, number] } } | { op: "resizeFrame"; args: { frameId: string; bounds: [number, number, number, number] } } | { op: "linkFrames"; args: { from: string; to: string } } | { op: "unlinkFrames"; args: { frame: string } } | { op: "insertPage"; args: { afterPageId: PageId | null; masterId: string | null } } | { op: "deletePage"; args: { pageId: PageId } } | { op: "resizePage"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertTextFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "deleteFrame"; args: { frameId: string } } | { op: "insertLine"; args: { pageId: PageId; start: [number, number]; end: [number, number] } } | { op: "insertPath"; args: { pageId: PageId; anchors: PathAnchorSpec[]; open: boolean; smooth?: boolean } } | { op: "setDocumentDefaults"; args: { fillColor: string | null; strokeColor: string | null; strokeWeight: number | null } } | { op: "setColorSettings"; args: { cmykProfileName: string | null; rgbPolicy: string | null; intent: string | null; bpc: boolean | null } } | { op: "setProofSetup"; args: { profileName: string | null; simulatePaperWhite?: boolean; intent: string | null } } | { op: "importSwatchLibrary"; args: { bytes: number[]; groupName?: string | null } } | { op: "setInkSetting"; args: { spotId: string; convertToProcess?: boolean; aliasTo?: string | null } } | { op: "setUseStandardLabForSpots"; args: { enabled: boolean } } | { op: "pathPointInsert"; args: { elementId: ElementId; index: number; anchor: PathAnchorSpec; prevSubpathStarts?: number[] | null } } | { op: "pathPointRemove"; args: { elementId: ElementId; index: number } } | { op: "pathOpenAt"; args: { elementId: ElementId; index: number } } | { op: "outlineStroke"; args: { elementId: ElementId; width: number; cap: string; join: string; miterLimit: number } } | { op: "offsetPath"; args: { elementId: ElementId; delta: number; join: string; miterLimit: number } } | { op: "simplifyPath"; args: { elementId: ElementId; tolerance: number } } | { op: "closePath"; args: { elementId: ElementId; subpath?: number | null } } | { op: "joinPaths"; args: { elementId: ElementId; otherId: ElementId } } | { op: "pasteInto"; args: { containerId: ElementId; childId: ElementId } } | { op: "releaseFrom"; args: { childId: ElementId } } | { op: "reorderElement"; args: { elementId: ElementId; to: ZOrderTarget } } | { op: "applyOpacityMask"; args: { targetId: ElementId; maskId: ElementId; maskType?: string | null; invert?: boolean | null } } | { op: "releaseOpacityMask"; args: { targetId: ElementId } } | { op: "attachTextToPath"; args: { elementId: ElementId; storyId: string; pathTypeAlignment?: string | null; flipPathEffect?: string | null; startBracket?: number | null; endBracket?: number | null } } | { op: "detachTextFromPath"; args: { elementId: ElementId } } | { op: "createGroup"; args: { memberIds: ElementId[] } } | { op: "dissolveGroup"; args: { groupId: string } } | { op: "setGroupTransform"; args: { groupId: string; transform?: [number, number, number, number, number, number] | null } } | { op: "setPluginMetadata"; args: { elementId: ElementId; key: string; value?: string | null; caller?: string | null } } | { op: "pathPointCurveType"; args: { elementId: ElementId; index: number; smooth: boolean } } | { op: "pathPointSet"; args: { elementId: ElementId; index: number; role: PathPointRole; position: [number, number] } } | { op: "batch"; args: { ops: Mutation[] } } | { op: "bindCreated"; args: { handle: string } } | { op: "layerSetVisible"; args: { layerId: string; visible: boolean } } | { op: "layerSetLocked"; args: { layerId: string; locked: boolean } } | { op: "layerSetPrintable"; args: { layerId: string; printable: boolean } } | { op: "layerSetName"; args: { layerId: string; name: string } } | { op: "layerMove"; args: { layerId: string; newIndex: number } } | { op: "layerInsert"; args: { position: number; name: string } } | { op: "layerRemove"; args: { layerId: string } } | { op: "setElementProperty"; args: { elementId: ElementId; path: PropertyPath; value: Value } } | { op: "pathfinderBoolean"; args: { kept: ElementId; others: ElementId[]; kind: PathfinderKind } } | { op: "pathfinderDivide"; args: { elementIds: ElementId[] } } | { op: "pathfinderTrim"; args: { elementIds: ElementId[] } } | { op: "pathfinderMerge"; args: { elementIds: ElementId[] } } | { op: "pathfinderCrop"; args: { elementIds: ElementId[] } } | { op: "pathfinderOutline"; args: { elementIds: ElementId[] } } | { op: "pathfinderMinusBack"; args: { elementIds: ElementId[] } } | { op: "pathfinderFaces"; args: { elementIds: ElementId[]; faces: string[]; mode: FaceSelectMode } } | { op: "createSwatch"; args: { spec: SwatchSpec } } | { op: "editSwatch"; args: { swatchId: string; spec: SwatchSpec } } | { op: "deleteSwatch"; args: { swatchId: string } } | { op: "createGradient"; args: { spec: GradientSpec } } | { op: "editGradient"; args: { gradientId: string; spec: GradientSpec } } | { op: "deleteGradient"; args: { gradientId: string } } | { op: "createColorGroup"; args: { spec: ColorGroupSpec } } | { op: "editColorGroup"; args: { groupId: string; spec: ColorGroupSpec } } | { op: "deleteColorGroup"; args: { groupId: string } } | { op: "createNumberingList"; args: { spec: NumberingListSpec } } | { op: "editNumberingList"; args: { listId: string; spec: NumberingListSpec } } | { op: "deleteNumberingList"; args: { listId: string } } | { op: "createParagraphStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameParagraphStyle"; args: { styleId: string; name: string } } | { op: "deleteParagraphStyle"; args: { styleId: string } } | { op: "createCharacterStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCharacterStyle"; args: { styleId: string; name: string } } | { op: "deleteCharacterStyle"; args: { styleId: string } } | { op: "createObjectStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameObjectStyle"; args: { styleId: string; name: string } } | { op: "deleteObjectStyle"; args: { styleId: string } } | { op: "createCellStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCellStyle"; args: { styleId: string; name: string } } | { op: "deleteCellStyle"; args: { styleId: string } } | { op: "createTableStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameTableStyle"; args: { styleId: string; name: string } } | { op: "deleteTableStyle"; args: { styleId: string } } | { op: "setStyleProperty"; args: { collection: StyleCollection; styleId: string; path: PropertyPath; value: Value } } | { op: "insertOval"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertGuide"; args: { spreadId: string; orientation: GuideOrientationSpec; position: number; pageIndex?: number } } | { op: "moveGuide"; args: { guideId: string; position: number } } | { op: "deleteGuide"; args: { guideId: string } } | { op: "setConditionVisible"; args: { condition: string; visible: boolean } } | { op: "activateConditionSet"; args: { set: string } } | { op: "applyMasterToPage"; args: { page: PageId; master?: string | null } } | { op: "duplicatePage"; args: { page: PageId } } | { op: "insertSection"; args: { atPage: PageId; prefix?: string | null; numberingStyle?: string | null; startAt?: number | null } } | { op: "editSection"; args: { sectionId: string; prefix?: string | null | null; numberingStyle?: string | null; startAt?: number | null | null } } | { op: "deleteSection"; args: { sectionId: string } } | { op: "setRowHeight"; args: { storyId: string; tableId: string; row: number; height?: number | null } } | { op: "setColumnWidth"; args: { storyId: string; tableId: string; col: number; width?: number | null } } | { op: "insertTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "insertTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "insertHeaderRow"; args: { storyId: string; tableId: string } } | { op: "removeHeaderRow"; args: { storyId: string; tableId: string } } | { op: "insertFooterRow"; args: { storyId: string; tableId: string } } | { op: "removeFooterRow"; args: { storyId: string; tableId: string } } | { op: "setCellSpan"; args: { storyId: string; tableId: string; row: number; col: number; rowSpan: number; columnSpan: number } } | { op: "insertTable"; args: { storyId: string; rows: number; cols: number; headerRows?: number; footerRows?: number; columnWidths?: number[]; rowHeights?: number[] } };
51
51
 
52
52
  /**
53
53
  * A plugin gradient paint for [`SceneItem::FillPathGradient`] (C-1.3).
@@ -197,6 +197,139 @@ export interface NearestPathPointResult {
197
197
  distance: number;
198
198
  }
199
199
 
200
+ /**
201
+ * B-22 (protocol v57) — `RequestPlanarRegions` reply.
202
+ */
203
+ export interface PlanarRegionsResult {
204
+ /**
205
+ * `false` when the request could not be answered at all — no
206
+ * document, an id that doesn\'t resolve, or more inputs than the
207
+ * kernel\'s cap. `reason` says which. Never a truncated answer.
208
+ */
209
+ found: boolean;
210
+ /**
211
+ * Populated when `found`. With a `point` in the request this holds
212
+ * at most one face (empty means the point is outside every input).
213
+ */
214
+ faces: PlanarFaceWire[];
215
+ /**
216
+ * How many inputs the arrangement was built from.
217
+ */
218
+ inputCount: number;
219
+ /**
220
+ * `true` when the resolved faces tile the union of the inputs.
221
+ * `false` flags that the enumeration missed a sliver — the faces
222
+ * listed are all real, the list just isn\'t exhaustive. Always
223
+ * `true` for a point query (one face is not a tiling claim).
224
+ */
225
+ complete: boolean;
226
+ /**
227
+ * Why `found` is false. `None` on success.
228
+ */
229
+ reason?: string | null;
230
+ }
231
+
232
+ /**
233
+ * B-22 (protocol v57) — one face of a planar arrangement: a connected
234
+ * region of the plane whose containment signature is constant.
235
+ *
236
+ * Coordinates are in the same RAW path space `PathAnchors` reports
237
+ * (per-element `ItemTransform`s are not composed in — the arrangement
238
+ * runs on the anchors as stored, exactly like `pathfinderBoolean`).
239
+ */
240
+ export interface PlanarFaceWire {
241
+ /**
242
+ * Stable id — `\"<signature>#<component>\"`, e.g. `\"0-1#0\"`. Stable
243
+ * across calls with the same inputs, which is what lets a hover
244
+ * query\'s id ride straight into `pathfinderFaces`.
245
+ */
246
+ id: string;
247
+ /**
248
+ * Indices into the REQUEST\'s `element_ids` whose interior contains
249
+ * this face.
250
+ */
251
+ signature: number[];
252
+ /**
253
+ * The face outline (closed). A face with holes carries them as
254
+ * extra contours.
255
+ */
256
+ anchors: PathAnchorTriple[];
257
+ /**
258
+ * Per-contour boundaries into `anchors`.
259
+ */
260
+ subpathStarts: number[];
261
+ /**
262
+ * Unsigned area, outer contour minus holes.
263
+ */
264
+ area: number;
265
+ /**
266
+ * A point strictly inside the face — what a hover highlight or a
267
+ * fill drop can key off without re-deriving containment.
268
+ */
269
+ inside: [number, number];
270
+ }
271
+
272
+ /**
273
+ * B-22 — the region-level Pathfinder verbs, all resolved over one
274
+ * planar arrangement (Illustrator\'s Pathfinder row, as opposed to the
275
+ * Shape Modes row that [`PathfinderKind`] covers).
276
+ *
277
+ * Every verb reads the arrangement\'s faces and decides, per face,
278
+ * WHICH input owns it. Ownership defaults to the TOPMOST input
279
+ * covering the face — `min(signature)`, since `elements` arrives
280
+ * top-to-bottom — which is what makes the results carry the fill you
281
+ * see on screen at that spot.
282
+ */
283
+ export type PathfinderRegionVerb = "divide" | "trim" | "merge" | "crop" | "outline" | "minusBack";
284
+
285
+ /**
286
+ * B-22 — whether `PathfinderFaces` keeps the named faces or removes
287
+ * them (Shape Builder\'s drag vs alt-drag).
288
+ */
289
+ export type FaceSelectMode = "keep" | "remove";
290
+
291
+ /**
292
+ * C-28 — wire mirror of [`paged_model::OpacityMaskType`] (the same
293
+ * mirror convention [`PathAnchorSpec`] follows: `paged-model` carries
294
+ * no `tsify` dependency, so wire-visible enums are declared here and
295
+ * converted at the boundary).
296
+ */
297
+ export type OpacityMaskMode = "luminosity" | "alpha";
298
+
299
+ /**
300
+ * C-29 — the `<TextPath>` knobs [`Operation::AttachTextToPath`]
301
+ * exposes. Grouped into one struct so the op, its inverse and the
302
+ * wire all name the same thing.
303
+ *
304
+ * Every field maps to an attribute the RENDERER ALREADY HONOURS
305
+ * (verified against `paged_renderer::pipeline::text_path`):
306
+ *
307
+ * * `path_type_alignment` → `PathTypeAlignment`: the glyph\'s
308
+ * vertical seat — `BaselinePathType` (default) / `CenterPathType`
309
+ * / `AscenderPathType` / `DescenderPathType`.
310
+ * * `flip_path_effect` → `FlipPathEffect`: `Flipped` reverses the
311
+ * path direction so the text reads the other way round.
312
+ * * `start_bracket` / `end_bracket` → `StartBracket` /
313
+ * `EndBracket`: the arc-length window the text flows within. The
314
+ * renderer clamps both to the tessellated path length, centres
315
+ * the run in the window when it fits, and drops glyphs past
316
+ * `EndBracket` while reporting `OversetTextDropped`.
317
+ *
318
+ * **Deliberately NOT exposed: `PathEffect`.** Only
319
+ * `RainbowPathEffect` actually renders; `SkewPathEffect`,
320
+ * `Path3DRibbonEffect`, `StairStepPathEffect` and
321
+ * `GravityPathEffect` parse but draw as Rainbow. A knob whose value
322
+ * is silently ignored is worse than no knob, so the op does not take
323
+ * one and the created `TextPath` leaves the attribute absent — which
324
+ * IS Rainbow, the IDML default.
325
+ */
326
+ export interface TextPathSpec {
327
+ pathTypeAlignment?: string | null;
328
+ flipPathEffect?: string | null;
329
+ startBracket?: number | null;
330
+ endBracket?: number | null;
331
+ }
332
+
200
333
  /**
201
334
  * Canonical selection / caret. `start == end` is a caret;
202
335
  * `start < end` is a range. Endpoints are normalised so `start ≤
@@ -346,6 +479,57 @@ export interface ExportPdfWireOptions {
346
479
  title?: string | null;
347
480
  }
348
481
 
482
+ /**
483
+ * DOC-03 (v54) — a story\'s full CONTENT: its paragraphs, each with its runs\'
484
+ * text + applied styles + direct character overrides. Where `StorySummary` gives
485
+ * counts, this gives the text and formatting a content plugin needs to read an
486
+ * edited document back (e.g. paged.doc diffs it against its import baseline to
487
+ * drive edited save-back). Surfaced by `CanvasModel::story_content()`; read via
488
+ * `RequestStoryContent { story_id }` → `StoryContentResult`.
489
+ */
490
+ export interface StoryContent {
491
+ /**
492
+ * IDML `Self` id (`Story/u123`).
493
+ */
494
+ selfId: string;
495
+ /**
496
+ * Paragraphs in body order.
497
+ */
498
+ paragraphs: ParagraphContent[];
499
+ }
500
+
501
+ /**
502
+ * DOC-03 — one paragraph\'s applied style + its runs.
503
+ */
504
+ export interface ParagraphContent {
505
+ /**
506
+ * The applied paragraph style id, if any (`w:pStyle` equivalent).
507
+ */
508
+ paragraphStyle?: string;
509
+ runs: RunContent[];
510
+ }
511
+
512
+ /**
513
+ * DOC-03 — one run\'s text + its applied character style + its DIRECT character
514
+ * overrides (each `None` = inherit). A run styled only through an applied style
515
+ * carries just `character_style`; direct editor formatting shows in the override
516
+ * fields. Field names mirror `paged_model::CharacterRun`.
517
+ */
518
+ export interface RunContent {
519
+ text: string;
520
+ characterStyle?: string;
521
+ font?: string;
522
+ fontStyle?: string;
523
+ pointSize?: number;
524
+ fillColor?: string;
525
+ underline?: boolean;
526
+ strikethru?: boolean;
527
+ capitalization?: string;
528
+ baselineShift?: number;
529
+ position?: string;
530
+ tracking?: number;
531
+ }
532
+
349
533
  /**
350
534
  * Description of a node about to be inserted. Carries the minimal
351
535
  * Stage-1 supported field set plus `item_transform` — `RemoveNode` →
@@ -366,10 +550,10 @@ export type CaretDirection = "up" | "down";
366
550
  /**
367
551
  * Discriminated payload of a `WorkerToMain` message.
368
552
  */
369
- export type WorkerToMainKind = { kind: "ready"; payload: { protocol: ProtocolVersion } } | { kind: "documentLoaded"; payload: DocumentHandle } | { kind: "loadFailed"; payload: { error: LoadError } } | { kind: "mutationFailed"; payload: { error: WorkerError } } | { kind: "displayListReady"; payload: { pageId: PageId; lod: LodTier; commands: number; layoutGeneration: number; numberingGeneration: number } } | { kind: "hitResult"; payload: HitResult } | { kind: "pagesDirty"; payload: { pageIds: PageId[] } } | { kind: "storyDirty"; payload: { storyId: string } } | { kind: "warning"; payload: { kind: string; details: string } } | { kind: "stats"; payload: DocumentStats } | { kind: "snapshotReady"; payload: SnapshotPng } | { kind: "snapshotFailed"; payload: { error: SnapshotError } } | { kind: "mutationApplied"; payload: { clientSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; createdId?: ElementId | null; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null; reflow?: FrameReflowInfo | null } } | { kind: "selectionGeometry"; payload: { rects: SelectionRect[] } } | { kind: "caretGeometry"; payload: { caret: CaretGeometry | null } } | { kind: "caretNavResult"; payload: { offset?: number | null } } | { kind: "lineBoundsResult"; payload: { bounds?: LineBounds | null } } | { kind: "wordBoundsResult"; payload: { bounds?: WordBounds | null } } | { kind: "paragraphBoundsResult"; payload: { bounds?: ParagraphBounds | null } } | { kind: "undoApplied"; payload: { undoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "redoApplied"; payload: { redoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "fontRegistered"; payload: { family: string } } | { kind: "fontRegistryCleared" } | { kind: "colorProfileRegistered"; payload: { name: string } } | { kind: "elementSelectionApplied"; payload: { ids: ElementId[] } } | { kind: "marqueeHits"; payload: { ids: ElementId[] } } | { kind: "elementGeometry"; payload: { items: ElementGeometryItem[] } } | { kind: "groupLeaves"; payload: { ids: ElementId[] } } | { kind: "pathAnchors"; payload: { result: PathAnchorsResult | null } } | { kind: "nearestPathPoint"; payload: { result: NearestPathPointResult | null } } | { kind: "layers"; payload: { items: LayerSummary[] } } | { kind: "collectionReply"; payload: { name: CollectionName; items: any } } | { kind: "frameChainResult"; payload: { links: FrameChainLink[] } } | { kind: "documentPlaceholders"; payload: { items: PlaceholderItem[] } } | { kind: "placedAssetBytes"; payload: { elementId: string; found: boolean; uri: string; width: number; height: number; encoded: number[] } } | { kind: "fontFaceBytes"; payload: { found: boolean; family: string; style: string | null; postscriptName: string | null; format: string; bytes: number[] } } | { kind: "measureTextResult"; payload: { advance: number; ascender: number; descender: number } } | { kind: "sceneLayerApplied"; payload: { elementId: string; applied: boolean } } | { kind: "resourceClaimApplied"; payload: { imageId: string; applied: boolean; needed?: ResourceTilesNeededWire[] } } | { kind: "resourceTilesNeeded"; payload: ResourceTilesNeededWire } | { kind: "frameReflow"; payload: { frameId: string; contentBox: [number, number, number, number] } } | { kind: "documentMetaReply"; payload: { meta: DocumentMeta } } | { kind: "colorPreviewReply"; payload: { result: ColorPreview | null } } | { kind: "colorComputeReply"; payload: { rgbHex: string; cmyk: [number, number, number, number] | null; outOfGamut: boolean } } | { kind: "gradientDetailReply"; payload: { result: GradientDetail | null } } | { kind: "swatchLibraryExported"; payload: { aseBytes: number[] } } | { kind: "exportPdfBegun"; payload: { session: number; pageCount: number } } | { kind: "exportPdfProgress"; payload: { session: number; done: number; total: number } } | { kind: "pdfExported"; payload: { pdfBytes: number[]; diagnostics: string[]; findings?: PreflightFinding[] } } | { kind: "exportPdfCancelled"; payload: { session: number } } | { kind: "exportPdfFailed"; payload: { error: string } } | { kind: "idmlExported"; payload: { idmlBytes: number[] } } | { kind: "exportIdmlFailed"; payload: { error: string } } | { kind: "pagedPartWritten"; payload: {} } | { kind: "pagedPartRead"; payload: { found: boolean; bytes: number[] } } | { kind: "pagedPartList"; payload: { paths: string[] } } | { kind: "pagedExported"; payload: { bytes: number[] } } | { kind: "pagedPartFailed"; payload: { error: string } } | { kind: "elementProperties"; payload: { result: ElementProperties | null } } | { kind: "sceneTree"; payload: { roots: SceneTreeNode[] } } | { kind: "scriptResult"; payload: { output: string[]; error: string | null; budgetKind?: ScriptBudgetKind } } | { kind: "gestureBegun"; payload: { handle: GestureHandle } } | { kind: "gestureUpdated"; payload: { handle: GestureHandle; pageIds: PageId[]; snapLines?: SnapLine[] } } | { kind: "gestureCommitted"; payload: { handle: GestureHandle; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats } } | { kind: "gestureCancelled"; payload: { handle: GestureHandle; pageIds: PageId[] } } | { kind: "gestureFailed"; payload: { error: GestureFailure } } | { kind: "attachReady"; payload: { gpuActive: boolean; sceneCacheBudget: number } } | { kind: "gestureSnapLines"; payload: { snapLines: SnapLine[] } } | { kind: "resolutionDone"; payload: ResolutionResult };
553
+ export type WorkerToMainKind = { kind: "ready"; payload: { protocol: ProtocolVersion } } | { kind: "documentLoaded"; payload: DocumentHandle } | { kind: "loadFailed"; payload: { error: LoadError } } | { kind: "mutationFailed"; payload: { error: WorkerError } } | { kind: "displayListReady"; payload: { pageId: PageId; lod: LodTier; commands: number; layoutGeneration: number; numberingGeneration: number } } | { kind: "hitResult"; payload: HitResult } | { kind: "pagesDirty"; payload: { pageIds: PageId[] } } | { kind: "storyDirty"; payload: { storyId: string } } | { kind: "warning"; payload: { kind: string; details: string } } | { kind: "stats"; payload: DocumentStats } | { kind: "snapshotReady"; payload: SnapshotPng } | { kind: "snapshotFailed"; payload: { error: SnapshotError } } | { kind: "mutationApplied"; payload: { clientSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; createdId?: ElementId | null; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null; reflow?: FrameReflowInfo | null } } | { kind: "selectionGeometry"; payload: { rects: SelectionRect[] } } | { kind: "caretGeometry"; payload: { caret: CaretGeometry | null } } | { kind: "caretNavResult"; payload: { offset?: number | null } } | { kind: "lineBoundsResult"; payload: { bounds?: LineBounds | null } } | { kind: "wordBoundsResult"; payload: { bounds?: WordBounds | null } } | { kind: "paragraphBoundsResult"; payload: { bounds?: ParagraphBounds | null } } | { kind: "storyContentResult"; payload: { content?: StoryContent | null } } | { kind: "undoApplied"; payload: { undoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "redoApplied"; payload: { redoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "fontRegistered"; payload: { family: string } } | { kind: "fontRegistryCleared" } | { kind: "colorProfileRegistered"; payload: { name: string } } | { kind: "elementSelectionApplied"; payload: { ids: ElementId[] } } | { kind: "marqueeHits"; payload: { ids: ElementId[] } } | { kind: "elementGeometry"; payload: { items: ElementGeometryItem[] } } | { kind: "groupLeaves"; payload: { ids: ElementId[] } } | { kind: "pathAnchors"; payload: { result: PathAnchorsResult | null } } | { kind: "planarRegions"; payload: { result: PlanarRegionsResult } } | { kind: "nearestPathPoint"; payload: { result: NearestPathPointResult | null } } | { kind: "layers"; payload: { items: LayerSummary[] } } | { kind: "collectionReply"; payload: { name: CollectionName; items: any } } | { kind: "frameChainResult"; payload: { links: FrameChainLink[] } } | { kind: "documentPlaceholders"; payload: { items: PlaceholderItem[] } } | { kind: "placedAssetBytes"; payload: { elementId: string; found: boolean; uri: string; width: number; height: number; encoded: number[] } } | { kind: "fontFaceBytes"; payload: { found: boolean; family: string; style: string | null; postscriptName: string | null; format: string; bytes: number[] } } | { kind: "measureTextResult"; payload: { advance: number; ascender: number; descender: number } } | { kind: "sceneLayerApplied"; payload: { elementId: string; applied: boolean } } | { kind: "resourceClaimApplied"; payload: { imageId: string; applied: boolean; needed?: ResourceTilesNeededWire[] } } | { kind: "resourceTilesNeeded"; payload: ResourceTilesNeededWire } | { kind: "frameReflow"; payload: { frameId: string; contentBox: [number, number, number, number] } } | { kind: "documentMetaReply"; payload: { meta: DocumentMeta } } | { kind: "colorPreviewReply"; payload: { result: ColorPreview | null } } | { kind: "colorComputeReply"; payload: { rgbHex: string; cmyk: [number, number, number, number] | null; outOfGamut: boolean } } | { kind: "gradientDetailReply"; payload: { result: GradientDetail | null } } | { kind: "swatchLibraryExported"; payload: { aseBytes: number[] } } | { kind: "exportPdfBegun"; payload: { session: number; pageCount: number } } | { kind: "exportPdfProgress"; payload: { session: number; done: number; total: number } } | { kind: "pdfExported"; payload: { pdfBytes: number[]; diagnostics: string[]; findings?: PreflightFinding[] } } | { kind: "exportPdfCancelled"; payload: { session: number } } | { kind: "exportPdfFailed"; payload: { error: string } } | { kind: "idmlExported"; payload: { idmlBytes: number[]; lost?: string[] } } | { kind: "exportIdmlFailed"; payload: { error: string } } | { kind: "pagedPartWritten"; payload: {} } | { kind: "pagedPartRead"; payload: { found: boolean; bytes: number[] } } | { kind: "pagedPartList"; payload: { paths: string[] } } | { kind: "pagedExported"; payload: { bytes: number[] } } | { kind: "pagedPartFailed"; payload: { error: string } } | { kind: "elementProperties"; payload: { result: ElementProperties | null } } | { kind: "sceneTree"; payload: { roots: SceneTreeNode[] } } | { kind: "scriptResult"; payload: { output: string[]; error: string | null; budgetKind?: ScriptBudgetKind } } | { kind: "gestureBegun"; payload: { handle: GestureHandle } } | { kind: "gestureUpdated"; payload: { handle: GestureHandle; pageIds: PageId[]; snapLines?: SnapLine[] } } | { kind: "gestureCommitted"; payload: { handle: GestureHandle; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats } } | { kind: "gestureCancelled"; payload: { handle: GestureHandle; pageIds: PageId[] } } | { kind: "gestureFailed"; payload: { error: GestureFailure } } | { kind: "attachReady"; payload: { gpuActive: boolean; sceneCacheBudget: number } } | { kind: "gestureSnapLines"; payload: { snapLines: SnapLine[] } } | { kind: "resolutionDone"; payload: ResolutionResult };
370
554
 
371
555
  /**
372
- * Editor-ops — wire mirror of `paged_parse::GradientFeatherParams`.
556
+ * Editor-ops — wire mirror of `paged_model::GradientFeatherParams`.
373
557
  * Whole-struct authoring (kind + axis + stop LIST change together;
374
558
  * `Value` has no generic list form, so the drop-shadow per-field
375
559
  * shape doesn\'t fit). The renderer already draws this effect; only
@@ -388,7 +572,7 @@ export interface GradientFeatherSpec {
388
572
  }
389
573
 
390
574
  /**
391
- * Editor-ops — wire mirror of `paged_parse::GradientFeatherStop`
575
+ * Editor-ops — wire mirror of `paged_model::GradientFeatherStop`
392
576
  * (the AST type predates `PartialEq`/`Tsify`; the mirror keeps the
393
577
  * op wire-shaped, the `PathAnchorSpec` precedent).
394
578
  */
@@ -738,7 +922,31 @@ export type GestureHandle = number;
738
922
  */
739
923
  export interface ElementGeometryItem {
740
924
  id: ElementId;
741
- pageId: PageId;
925
+ /**
926
+ * C-23 — the page this element sits on, or `None` when it sits on
927
+ * the PASTEBOARD and belongs to no page.
928
+ *
929
+ * This used to be a plain `PageId`, and the door did not report a
930
+ * pageless element as pageless — it dropped it from the reply
931
+ * entirely, so a plugin that generated art off-page (paged.draw\'s
932
+ * pattern bake, stepping a tile past the page edge) created and
933
+ * grouped something it then could not read back.
934
+ *
935
+ * **The convention `None` carries:** `bounds` + `item_transform`
936
+ * compose against the SPREAD origin rather than a page origin.
937
+ * `spread_id` names which spread, because without it the answer is
938
+ * unusable the moment a document has two.
939
+ *
940
+ * Runtime-safe to widen: every element of every existing document
941
+ * is on a page, so no existing reply changes shape. The `None`
942
+ * only appears for items this door used to omit.
943
+ */
944
+ pageId?: PageId | null;
945
+ /**
946
+ * C-23 — the owning spread. Always populated; the page-owned case
947
+ * carries it too, so a consumer never has to ask a second door.
948
+ */
949
+ spreadId?: string | null;
742
950
  /**
743
951
  * `[top, left, bottom, right]`.
744
952
  */
@@ -961,6 +1169,12 @@ export interface StorySummary {
961
1169
  * Preflight panel + the red \"+\" overset badge on the frame.
962
1170
  */
963
1171
  overset?: boolean;
1172
+ /**
1173
+ * When `overset`, *where* the flow overran — the continuation cursor
1174
+ * (`OversetAt`). `None` when the story fits. Additive/optional, so an
1175
+ * older client that ignores it still reads the `overset` flag.
1176
+ */
1177
+ oversetAt?: OversetAt;
964
1178
  }
965
1179
 
966
1180
  /**
@@ -983,6 +1197,26 @@ export interface SwatchSummary {
983
1197
  selfId: string;
984
1198
  name: string;
985
1199
  kind: string;
1200
+ /**
1201
+ * §21 advanced prepress — the swatch\'s total area coverage in
1202
+ * percent: how much ink every press plate lays down for it,
1203
+ * summed. A process CMYK swatch sums its four channels (a 60/40/
1204
+ * 40/100 rich black is 240%); a spot swatch is ONE plate, so it
1205
+ * contributes its own tint (100% PANTONE 286 C is 100%, not the
1206
+ * 175% its CMYK alternate would sum to).
1207
+ *
1208
+ * `None` — not `0.0` — when the swatch has no ink decomposition:
1209
+ * RGB, Lab, mixed-ink and unknown swatches separate at the RIP,
1210
+ * not here. The distinction is load-bearing; a UI must show a
1211
+ * blank, never a zero.
1212
+ *
1213
+ * This is the EXACT reading, computed from the palette with no
1214
+ * render involved, so it is resolution-free and catches an
1215
+ * over-limit colour wherever it is used — including in hairlines
1216
+ * that the rendered per-page coverage under-samples. Additive
1217
+ * read-only field; no protocol bump on its own.
1218
+ */
1219
+ totalAreaCoveragePct?: number | null;
986
1220
  }
987
1221
 
988
1222
  /**
@@ -1000,7 +1234,7 @@ export interface SwatchSummary {
1000
1234
  * `serde_json::Value::Array` for unimplemented entries, surfacing
1001
1235
  * a runtime warning rather than a panic.
1002
1236
  */
1003
- export type CollectionName = "swatches" | "gradients" | "colorGroups" | "paragraphStyles" | "characterStyles" | "objectStyles" | "cellStyles" | "tableStyles" | "layers" | "spreads" | "pages" | "masterPages" | "links" | "articles" | "hyperlinks" | "bookmarks" | "crossReferences" | "conditions" | "conditionSets" | "fonts" | "indexTopics" | "inks" | "sections" | "stories" | "numberingLists";
1237
+ export type CollectionName = "swatches" | "gradients" | "colorGroups" | "paragraphStyles" | "characterStyles" | "objectStyles" | "cellStyles" | "tableStyles" | "layers" | "spreads" | "pages" | "masterPages" | "links" | "articles" | "hyperlinks" | "bookmarks" | "crossReferences" | "conditions" | "conditionSets" | "fonts" | "indexTopics" | "inks" | "sections" | "stories" | "numberingLists" | "inkCoverage";
1004
1238
 
1005
1239
  /**
1006
1240
  * SDK Phase 5 (D1) — singleton document-level state. Per
@@ -1376,6 +1610,25 @@ export interface LinkSummary {
1376
1610
  * 300-ppi floor. `None` when the IDML omits it.
1377
1611
  */
1378
1612
  effectivePpi?: number | null;
1613
+ /**
1614
+ * C-27 — the placed image\'s OWN `<Image ItemTransform>`: how the
1615
+ * pixels sit inside the frame. `elementGeometry` reports the frame
1616
+ * and nothing reported this, so a plugin deriving geometry from the
1617
+ * pixels (Image Trace today; any measure or annotate tool later)
1618
+ * had to assume the image fills the frame — and quietly mis-placed
1619
+ * its output on every cropped or fitted placement.
1620
+ *
1621
+ * Row-major `[a, b, c, d, tx, ty]`, mapping the image\'s natural
1622
+ * pixel rect `(0, 0, width, height)` into the frame\'s INNER
1623
+ * coordinate space — the same matrix the renderer composes with
1624
+ * the frame\'s own transform. Compose it the same way and generated
1625
+ * geometry lands where the pixels do.
1626
+ *
1627
+ * `None` for synthetic IDMLs that omit the inner transform, which
1628
+ * is the case the renderer handles by stretching the image to the
1629
+ * frame bounds; a consumer seeing `None` may assume that fill.
1630
+ */
1631
+ imageTransform?: [number, number, number, number, number, number] | null;
1379
1632
  }
1380
1633
 
1381
1634
  /**
@@ -1490,7 +1743,15 @@ export type PageId = string;
1490
1743
  */
1491
1744
  export interface PathAnchorsResult {
1492
1745
  id: ElementId;
1493
- pageId: PageId;
1746
+ /**
1747
+ * C-23 — see [`ElementGeometryItem::page_id`]; same convention,
1748
+ * same reason. Anchors are in the element\'s own space either way.
1749
+ */
1750
+ pageId?: PageId | null;
1751
+ /**
1752
+ * C-23 — the owning spread; see [`ElementGeometryItem::spread_id`].
1753
+ */
1754
+ spreadId?: string | null;
1494
1755
  anchors: PathAnchorTriple[];
1495
1756
  /**
1496
1757
  * Per-contour boundaries. Empty for the common single-contour
@@ -1555,7 +1816,7 @@ export interface DocumentStats {
1555
1816
  * document\'s `BTreeMap` palettes/stylesheets rather than the scene
1556
1817
  * tree, so they\'re top-level variants rather than `InsertNode`.
1557
1818
  */
1558
- export type Operation = { kind: "SetProperty"; node: NodeId; path: PropertyPath; value: Value } | { kind: "InsertNode"; parent: NodeId; position: number; node: NodeSpec; z_slot?: number | null } | { kind: "RemoveNode"; node: NodeId } | { kind: "MoveNode"; node: NodeId; new_parent: NodeId; position: number } | { kind: "Batch"; ops: Operation[] } | { kind: "InsertPage"; after_page_id?: string | null; master_id?: string | null; spread_self_id?: string | null; page_self_id?: string | null; restore_spread_json?: string | null } | { kind: "RemovePage"; page_id: string } | { kind: "MoveLayer"; layer_id: string; new_index: number } | { kind: "InsertLayer"; position: number; name: string; self_id?: string | null } | { kind: "RemoveLayer"; layer_id: string } | { kind: "CreateSwatch"; spec: SwatchSpec } | { kind: "EditSwatch"; swatch_id: string; spec: SwatchSpec } | { kind: "DeleteSwatch"; swatch_id: string } | { kind: "CreateParagraphStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameParagraphStyle"; style_id: string; name: string } | { kind: "DeleteParagraphStyle"; style_id: string } | { kind: "CreateCharacterStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCharacterStyle"; style_id: string; name: string } | { kind: "DeleteCharacterStyle"; style_id: string } | { kind: "CreateObjectStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameObjectStyle"; style_id: string; name: string } | { kind: "DeleteObjectStyle"; style_id: string } | { kind: "CreateCellStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCellStyle"; style_id: string; name: string } | { kind: "DeleteCellStyle"; style_id: string } | { kind: "CreateTableStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameTableStyle"; style_id: string; name: string } | { kind: "DeleteTableStyle"; style_id: string } | { kind: "CreateGroup"; spec: GroupSpec } | { kind: "DissolveGroup"; group_id: string; restore_slots?: number[] | null } | { kind: "SetGroupTransform"; group: string; transform?: [number, number, number, number, number, number] | null; prev?: [number, number, number, number, number, number] | null } | { kind: "CreateGradient"; spec: GradientSpec } | { kind: "EditGradient"; gradient_id: string; spec: GradientSpec } | { kind: "DeleteGradient"; gradient_id: string } | { kind: "CreateColorGroup"; spec: ColorGroupSpec } | { kind: "EditColorGroup"; group_id: string; spec: ColorGroupSpec } | { kind: "DeleteColorGroup"; group_id: string } | { kind: "CreateNumberingList"; spec: NumberingListSpec } | { kind: "EditNumberingList"; list_id: string; spec: NumberingListSpec } | { kind: "DeleteNumberingList"; list_id: string } | { kind: "SetStyleProperty"; collection: StyleCollection; style_id: string; path: PropertyPath; value: Value } | { kind: "PathfinderBoolean"; kept: NodeId; others: NodeId[]; opKind: PathfinderKind } | { kind: "LinkFrames"; from: string; to: string } | { kind: "UnlinkFrames"; frame: string; prev_next?: string | null } | { kind: "ApplyStyle"; story_id: string; start: number; end: number; style: string; scope: StyleScope } | { kind: "InsertField"; story_id: string; offset: number; field: FieldKind } | { kind: "DeleteField"; story_id: string; offset: number; field: FieldKind } | { kind: "SetFieldValue"; story_id: string; offset: number; value?: string | null } | { kind: "PlaceImage"; frame: NodeId; image_uri?: string | null; fit?: string | null } | { kind: "ReplaceImageBytes"; frame: NodeId; bytes?: number[] | null; prior_has_image_element?: boolean | null } | { kind: "InsertGuide"; spread_id: string; orientation: GuideOrientationSpec; position: number; page_index?: number; guide_id?: string | null } | { kind: "MoveGuide"; guide_id: string; position: number } | { kind: "DeleteGuide"; guide_id: string } | { kind: "SetConditionVisible"; condition: string; visible: boolean } | { kind: "ActivateConditionSet"; set: string } | { kind: "RestoreConditionVisibility"; states: [string, boolean][] } | { kind: "ApplyMasterToPage"; page: string; master?: string | null } | { kind: "DuplicatePage"; page: string; clone_spread_json?: string | null } | { kind: "InsertSection"; at_page: string; prefix?: string | null; numbering_style?: string | null; start_at?: number | null; self_id?: string | null } | { kind: "EditSection"; section_id: string; prefix?: string | null | null; numbering_style?: string | null; start_at?: number | null | null } | { kind: "DeleteSection"; section_id: string } | { kind: "SetRowHeight"; story_id: string; table_id: string; row: number; height?: number | null } | { kind: "SetColumnWidth"; story_id: string; table_id: string; col: number; width?: number | null } | { kind: "InsertTableRow"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableRow"; story_id: string; table_id: string; at: number } | { kind: "InsertTableColumn"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableColumn"; story_id: string; table_id: string; at: number } | { kind: "InsertHeaderRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveHeaderRow"; story_id: string; table_id: string } | { kind: "InsertFooterRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveFooterRow"; story_id: string; table_id: string } | { kind: "SetCellSpan"; story_id: string; table_id: string; row: number; col: number; row_span: number; column_span: number };
1819
+ export type Operation = { kind: "SetProperty"; node: NodeId; path: PropertyPath; value: Value } | { kind: "InsertNode"; parent: NodeId; position: number; node: NodeSpec; z_slot?: number | null } | { kind: "RemoveNode"; node: NodeId } | { kind: "MoveNode"; node: NodeId; new_parent: NodeId; position: number } | { kind: "ReorderNode"; node: NodeId; target: ZOrderTarget } | { kind: "Batch"; ops: Operation[] } | { kind: "InsertPage"; after_page_id?: string | null; master_id?: string | null; spread_self_id?: string | null; page_self_id?: string | null; restore_spread_json?: string | null } | { kind: "RemovePage"; page_id: string } | { kind: "MoveLayer"; layer_id: string; new_index: number } | { kind: "InsertLayer"; position: number; name: string; self_id?: string | null } | { kind: "RemoveLayer"; layer_id: string } | { kind: "CreateSwatch"; spec: SwatchSpec } | { kind: "EditSwatch"; swatch_id: string; spec: SwatchSpec } | { kind: "DeleteSwatch"; swatch_id: string } | { kind: "CreateParagraphStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameParagraphStyle"; style_id: string; name: string } | { kind: "DeleteParagraphStyle"; style_id: string } | { kind: "CreateCharacterStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCharacterStyle"; style_id: string; name: string } | { kind: "DeleteCharacterStyle"; style_id: string } | { kind: "CreateObjectStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameObjectStyle"; style_id: string; name: string } | { kind: "DeleteObjectStyle"; style_id: string } | { kind: "CreateCellStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCellStyle"; style_id: string; name: string } | { kind: "DeleteCellStyle"; style_id: string } | { kind: "CreateTableStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameTableStyle"; style_id: string; name: string } | { kind: "DeleteTableStyle"; style_id: string } | { kind: "CreateGroup"; spec: GroupSpec } | { kind: "DissolveGroup"; group_id: string; restore_slots?: number[] | null } | { kind: "SetGroupTransform"; group: string; transform?: [number, number, number, number, number, number] | null; prev?: [number, number, number, number, number, number] | null } | { kind: "CreateGradient"; spec: GradientSpec } | { kind: "EditGradient"; gradient_id: string; spec: GradientSpec } | { kind: "DeleteGradient"; gradient_id: string } | { kind: "CreateColorGroup"; spec: ColorGroupSpec } | { kind: "EditColorGroup"; group_id: string; spec: ColorGroupSpec } | { kind: "DeleteColorGroup"; group_id: string } | { kind: "CreateNumberingList"; spec: NumberingListSpec } | { kind: "EditNumberingList"; list_id: string; spec: NumberingListSpec } | { kind: "DeleteNumberingList"; list_id: string } | { kind: "SetStyleProperty"; collection: StyleCollection; style_id: string; path: PropertyPath; value: Value } | { kind: "PathfinderBoolean"; kept: NodeId; others: NodeId[]; opKind: PathfinderKind } | { kind: "PathfinderRegion"; elements: NodeId[]; verb: PathfinderRegionVerb } | { kind: "PathfinderFaces"; elements: NodeId[]; faces: string[]; mode: FaceSelectMode } | { kind: "JoinPaths"; kept: NodeId; other: NodeId } | { kind: "PasteInto"; container: NodeId; child: NodeId; child_index?: number | null } | { kind: "ReleaseFrom"; child: NodeId; restore_slot?: number | null } | { kind: "ApplyOpacityMask"; target: NodeId; mask: NodeId; mask_type?: OpacityMaskMode; invert?: boolean } | { kind: "ReleaseOpacityMask"; target: NodeId; restore_slot?: number | null } | { kind: "AttachTextToPath"; host: NodeId; story_id: string; spec?: TextPathSpec } | { kind: "DetachTextFromPath"; host: NodeId; index?: number | null; restore?: TextPathSpec | null } | { kind: "LinkFrames"; from: string; to: string } | { kind: "UnlinkFrames"; frame: string; prev_next?: string | null } | { kind: "ApplyStyle"; story_id: string; start: number; end: number; style: string; scope: StyleScope; cell?: CellAddr | null } | { kind: "InsertField"; story_id: string; offset: number; field: FieldKind } | { kind: "DeleteField"; story_id: string; offset: number; field: FieldKind } | { kind: "InsertAnchoredFrame"; story_id: string; offset: number; width: number; height: number; image_uri?: string | null; self_id: string } | { kind: "RemoveAnchoredFrame"; story_id: string; self_id: string } | { kind: "InsertHyperlink"; story_id: string; start: number; end: number; url: string; source_id: string; dest_id: string; hyperlink_id: string } | { kind: "RemoveHyperlink"; story_id: string; start: number; end: number; url: string; source_id: string; dest_id: string; hyperlink_id: string } | { kind: "SetFieldValue"; story_id: string; offset: number; value?: string | null } | { kind: "PlaceImage"; frame: NodeId; image_uri?: string | null; fit?: string | null } | { kind: "ReplaceImageBytes"; frame: NodeId; bytes?: number[] | null; prior_has_image_element?: boolean | null } | { kind: "InsertGuide"; spread_id: string; orientation: GuideOrientationSpec; position: number; page_index?: number; guide_id?: string | null } | { kind: "MoveGuide"; guide_id: string; position: number } | { kind: "DeleteGuide"; guide_id: string } | { kind: "SetConditionVisible"; condition: string; visible: boolean } | { kind: "ActivateConditionSet"; set: string } | { kind: "RestoreConditionVisibility"; states: [string, boolean][] } | { kind: "ApplyMasterToPage"; page: string; master?: string | null } | { kind: "DuplicatePage"; page: string; clone_spread_json?: string | null } | { kind: "InsertSection"; at_page: string; prefix?: string | null; numbering_style?: string | null; start_at?: number | null; self_id?: string | null } | { kind: "EditSection"; section_id: string; prefix?: string | null | null; numbering_style?: string | null; start_at?: number | null | null } | { kind: "DeleteSection"; section_id: string } | { kind: "SetRowHeight"; story_id: string; table_id: string; row: number; height?: number | null } | { kind: "SetColumnWidth"; story_id: string; table_id: string; col: number; width?: number | null } | { kind: "InsertTableRow"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableRow"; story_id: string; table_id: string; at: number } | { kind: "InsertTableColumn"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableColumn"; story_id: string; table_id: string; at: number } | { kind: "InsertHeaderRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveHeaderRow"; story_id: string; table_id: string } | { kind: "InsertFooterRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveFooterRow"; story_id: string; table_id: string } | { kind: "SetCellSpan"; story_id: string; table_id: string; row: number; col: number; row_span: number; column_span: number };
1559
1820
 
1560
1821
  /**
1561
1822
  * The discriminated payload of a `MainToWorker` message. Tagged so
@@ -1564,10 +1825,10 @@ export type Operation = { kind: "SetProperty"; node: NodeId; path: PropertyPath;
1564
1825
  * variants so e.g. `cmyk_icc_profile` becomes `cmykIccProfile` on
1565
1826
  * the wire — the TS protocol mirror locks the camelCase contract.
1566
1827
  */
1567
- export type MainToWorkerKind = { kind: "hello" } | { kind: "loadDocument"; payload: { bytes: number[]; font?: number[] | null; cmykIccProfile?: number[] | null } } | { kind: "newBlankDocument"; payload: { widthPt: number; heightPt: number; font?: number[] | null } } | { kind: "registerFont"; payload: { family: string; style?: string | null; bytes: number[] } } | { kind: "clearFontRegistry" } | { kind: "registerColorProfile"; payload: { name: string; bytes: number[] } } | { kind: "mutate"; payload: Mutation } | { kind: "requestPage"; payload: { pageId: PageId; lod: LodTier } } | { kind: "hitTest"; payload: { pageId: PageId; docPoint: [number, number]; filter: HitFilter } } | { kind: "requestSnapshot"; payload: { pageId: PageId; targetWidthPx: number; dpi?: number | null } } | { kind: "setSelection"; payload: { selection: ContentSelection | null } } | { kind: "requestSelectionGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretNav"; payload: { storyId: string; offset: number; direction: CaretDirection; cell?: TextCellAddr | null } } | { kind: "requestLineBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestWordBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestParagraphBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "undo" } | { kind: "redo" } | { kind: "setElementSelection"; payload: { ids: ElementId[]; mode: SelectionMode } } | { kind: "requestMarqueeHits"; payload: { pageId: PageId; rect: [number, number, number, number] } } | { kind: "requestElementGeometry"; payload: { ids: ElementId[] } } | { kind: "requestGroupLeaves"; payload: { groupId: string } } | { kind: "requestPathAnchors"; payload: { id: ElementId } } | { kind: "requestNearestPathPoint"; payload: { id: ElementId; point: [number, number] } } | { kind: "requestLayers" } | { kind: "requestCollection"; payload: { name: CollectionName } } | { kind: "requestFrameChain"; payload: { storyId: string } } | { kind: "requestPlacedAssetBytes"; payload: { elementId: string } } | { kind: "requestFontFaceBytes"; payload: { family: string; style?: string | null } } | { kind: "requestMeasureText"; payload: { family: string; style?: string | null; text: string; sizePt: number } } | { kind: "submitSceneLayer"; payload: { elementId: string; layer: SceneLayer } } | { kind: "clearSceneLayer"; payload: { elementId: string } } | { kind: "submitPixelLayer"; payload: { elementId: string; layer: PixelLayer } } | { kind: "clearPixelLayer"; payload: { elementId: string } } | { kind: "claimImageResource"; payload: { imageId: string; levels: number; tileSize: number; baseWidth: number; baseHeight: number; revision: number } } | { kind: "releaseImageResource"; payload: { imageId: string } } | { kind: "submitResourceTiles"; payload: { imageId: string; level: number; tiles: ProviderTileWire[]; generation: number } } | { kind: "requestDocumentMeta" } | { kind: "requestDocumentPlaceholders" } | { kind: "requestColorPreview"; payload: { swatchId: string } } | { kind: "requestColorCompute"; payload: { space: string; value: number[]; tint?: number | null; model?: string | null; alternateSpace?: string | null; alternateValue?: number[] | null } } | { kind: "requestGradientDetail"; payload: { gradientId: string } } | { kind: "exportSwatchLibrary"; payload: { groupId?: string | null } } | { kind: "executeScript"; payload: { source: string } } | { kind: "exportPdfBegin"; payload: { options: ExportPdfWireOptions } } | { kind: "exportPdfPage"; payload: { session: number } } | { kind: "exportPdfFinish"; payload: { session: number } } | { kind: "exportPdfCancel"; payload: { session: number } } | { kind: "exportIdml"; payload: {} } | { kind: "writePagedPart"; payload: { path: string; bytes: number[] } } | { kind: "readPagedPart"; payload: { path: string } } | { kind: "listPagedParts"; payload: { prefix: string } } | { kind: "exportPaged"; payload: {} } | { kind: "requestElementProperties"; payload: { id: ElementId } } | { kind: "requestSceneTree" } | { kind: "beginGesture"; payload: { nodes: ElementId[]; gesture: GestureType; anchor?: GestureAnchor | null; cameraScale?: number | null } } | { kind: "updateGesture"; payload: { handle: GestureHandle; delta: [number, number]; modifiers: GestureModifiers } } | { kind: "commitGesture"; payload: { handle: GestureHandle } } | { kind: "cancelGesture"; payload: { handle: GestureHandle } };
1828
+ export type MainToWorkerKind = { kind: "hello" } | { kind: "loadDocument"; payload: { bytes: number[]; font?: number[] | null; cmykIccProfile?: number[] | null } } | { kind: "newBlankDocument"; payload: { widthPt: number; heightPt: number; font?: number[] | null } } | { kind: "registerFont"; payload: { family: string; style?: string | null; bytes: number[] } } | { kind: "clearFontRegistry" } | { kind: "registerColorProfile"; payload: { name: string; bytes: number[] } } | { kind: "mutate"; payload: Mutation } | { kind: "requestPage"; payload: { pageId: PageId; lod: LodTier } } | { kind: "hitTest"; payload: { pageId: PageId; docPoint: [number, number]; filter: HitFilter } } | { kind: "requestSnapshot"; payload: { pageId: PageId; targetWidthPx: number; dpi?: number | null } } | { kind: "setSelection"; payload: { selection: ContentSelection | null } } | { kind: "requestSelectionGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretNav"; payload: { storyId: string; offset: number; direction: CaretDirection; cell?: TextCellAddr | null } } | { kind: "requestLineBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestWordBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestParagraphBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "undo" } | { kind: "redo" } | { kind: "setElementSelection"; payload: { ids: ElementId[]; mode: SelectionMode } } | { kind: "requestMarqueeHits"; payload: { pageId: PageId; rect: [number, number, number, number] } } | { kind: "requestElementGeometry"; payload: { ids: ElementId[] } } | { kind: "requestGroupLeaves"; payload: { groupId: string } } | { kind: "requestPathAnchors"; payload: { id: ElementId } } | { kind: "requestNearestPathPoint"; payload: { id: ElementId; point: [number, number] } } | { kind: "requestPlanarRegions"; payload: { elementIds: ElementId[]; point?: [number, number] | null } } | { kind: "requestLayers" } | { kind: "requestCollection"; payload: { name: CollectionName } } | { kind: "requestFrameChain"; payload: { storyId: string } } | { kind: "requestStoryContent"; payload: { storyId: string } } | { kind: "requestPlacedAssetBytes"; payload: { elementId: string } } | { kind: "requestFontFaceBytes"; payload: { family: string; style?: string | null } } | { kind: "requestMeasureText"; payload: { family: string; style?: string | null; text: string; sizePt: number } } | { kind: "submitSceneLayer"; payload: { elementId: string; layer: SceneLayer; caller?: string } } | { kind: "clearSceneLayer"; payload: { elementId: string } } | { kind: "submitPixelLayer"; payload: { elementId: string; layer: PixelLayer } } | { kind: "clearPixelLayer"; payload: { elementId: string } } | { kind: "claimImageResource"; payload: { imageId: string; levels: number; tileSize: number; baseWidth: number; baseHeight: number; revision: number } } | { kind: "releaseImageResource"; payload: { imageId: string } } | { kind: "submitResourceTiles"; payload: { imageId: string; level: number; tiles: ProviderTileWire[]; generation: number } } | { kind: "requestDocumentMeta" } | { kind: "requestDocumentPlaceholders" } | { kind: "requestColorPreview"; payload: { swatchId: string } } | { kind: "requestColorCompute"; payload: { space: string; value: number[]; tint?: number | null; model?: string | null; alternateSpace?: string | null; alternateValue?: number[] | null } } | { kind: "requestGradientDetail"; payload: { gradientId: string } } | { kind: "exportSwatchLibrary"; payload: { groupId?: string | null } } | { kind: "executeScript"; payload: { source: string } } | { kind: "exportPdfBegin"; payload: { options: ExportPdfWireOptions } } | { kind: "exportPdfPage"; payload: { session: number } } | { kind: "exportPdfFinish"; payload: { session: number } } | { kind: "exportPdfCancel"; payload: { session: number } } | { kind: "exportIdml"; payload: {} } | { kind: "writePagedPart"; payload: { path: string; bytes: number[]; caller?: string } } | { kind: "readPagedPart"; payload: { path: string } } | { kind: "listPagedParts"; payload: { prefix: string } } | { kind: "exportPaged"; payload: {} } | { kind: "requestElementProperties"; payload: { id: ElementId } } | { kind: "requestSceneTree" } | { kind: "beginGesture"; payload: { nodes: ElementId[]; gesture: GestureType; anchor?: GestureAnchor | null; cameraScale?: number | null } } | { kind: "updateGesture"; payload: { handle: GestureHandle; delta: [number, number]; modifiers: GestureModifiers } } | { kind: "commitGesture"; payload: { handle: GestureHandle } } | { kind: "cancelGesture"; payload: { handle: GestureHandle } };
1568
1829
 
1569
1830
  /**
1570
- * Track J — wire-shape mirror of `paged_parse::PathAnchor`. The
1831
+ * Track J — wire-shape mirror of `paged_model::PathAnchor`. The
1571
1832
  * parse-side type doesn\'t carry `Deserialize`/`PartialEq`/`Tsify`,
1572
1833
  * and the mutate API needs all three so this Op crosses the wasm
1573
1834
  * boundary. The field shapes match exactly: `anchor` is the
@@ -1581,11 +1842,21 @@ export interface PathAnchorSpec {
1581
1842
  }
1582
1843
 
1583
1844
  /**
1584
- * Track M — wire-shape mirror of `paged_parse::Layer`. Surfaces
1845
+ * Track M — wire-shape mirror of `paged_model::Layer`. Surfaces
1585
1846
  * everything the Layers panel needs without leaking parse-side
1586
- * fields the wasm boundary doesn\'t understand. `z` is the layer\'s
1587
- * zero-based index in `designmap.layers` (top-first, matching the
1588
- * renderer\'s paint order via `layer_z_index`).
1847
+ * fields the wasm boundary doesn\'t understand.
1848
+ *
1849
+ * `z` is the layer\'s zero-based index in `designmap.layers`, and
1850
+ * **`z == 0` is the BACKMOST layer** — the first declared, painted
1851
+ * first. The topmost layer has the HIGHEST z.
1852
+ *
1853
+ * This comment previously said \"top-first … designmap[0] = topmost\",
1854
+ * which is the inversion `paged_scene::layer` records as a real bug
1855
+ * (its module doc: \"Cycle 2\'s Q-10 commit had this inverted\"), fixed
1856
+ * in the renderer and asserted by its own test. The wire comment kept
1857
+ * the wrong version, so a panel author sorting by `z` would have
1858
+ * stacked the list upside down. See `paged_scene::layer` for the
1859
+ * authority.
1589
1860
  */
1590
1861
  export interface LayerSummary {
1591
1862
  selfId: string;
@@ -1594,6 +1865,24 @@ export interface LayerSummary {
1594
1865
  locked: boolean;
1595
1866
  printable: boolean;
1596
1867
  z: number;
1868
+ /**
1869
+ * v60 — `Self` of the enclosing `<Layer>` when this layer is nested
1870
+ * inside a layer GROUP (folder) in InDesign\'s Layers panel; `None`
1871
+ * for a top-level layer, which is the overwhelmingly common case.
1872
+ *
1873
+ * Mirrors [`paged_model::Layer::parent_id`], which the model has
1874
+ * carried all along — the summary simply dropped it, so every
1875
+ * consumer of this wire type saw a FLAT layer list and a Layers
1876
+ * panel could not render a tree. Added when ADR 023\'s shared-panel
1877
+ * work hit exactly that wall.
1878
+ *
1879
+ * Note the renderer already resolves visibility and lock THROUGH
1880
+ * ancestors (a visible child inside a hidden parent group is
1881
+ * hidden), so `visible`/`locked` here are the layer\'s OWN flags,
1882
+ * not the resolved ones. A panel showing effective state must walk
1883
+ * the chain itself.
1884
+ */
1885
+ parentId?: string | null;
1597
1886
  }
1598
1887
 
1599
1888
  /**
@@ -1646,7 +1935,7 @@ export type LoadError = { kind: "parse"; message: string } | { kind: "scene"; me
1646
1935
  * of a specific kind; the apply layer\'s `TypeMismatch` error fires if
1647
1936
  * the variant doesn\'t match what the path expects.
1648
1937
  */
1649
- export type Value = { type: "bounds"; value: [number, number, number, number] } | { type: "colorRef"; value: string | null } | { type: "length"; value: number | null } | { type: "transform"; value: [number, number, number, number, number, number] | null } | { type: "pathPoint"; value: { address: PathPointAddress; position: [number, number] } } | { type: "pathPointInsert"; value: { index: number; anchor: PathAnchorSpec; prevSubpathStarts?: number[] | null } } | { type: "pathPointRemove"; value: { index: number; prevSubpathStarts?: number[] | null } } | { type: "pathPointCurveType"; value: { index: number; smooth: boolean; prev?: PathAnchorSpec | null } } | { type: "pluginMetadata"; value: { key: string; value: string | null; caller?: string | null; prev?: string | null | null } } | { type: "bool"; value: boolean } | { type: "text"; value: string } | { type: "framePath"; value: { anchors: PathAnchorSpec[]; subpathStarts: number[] } } | { type: "pathOpenAt"; value: { index: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "outlineStroke"; value: { width: number; cap: string; join: string; miterLimit: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "outlineStrokeVariable"; value: { widths: number[]; cap: string; join: string; miterLimit: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "offsetPath"; value: { delta: number; join: string; miterLimit: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "simplifyPath"; value: { tolerance: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "gradientFeather"; value: GradientFeatherSpec | null } | { type: "paragraphRule"; value: ParagraphRuleSpec | null } | { type: "tabStops"; value: TabStopSpec[] } | { type: "lengths"; value: number[] };
1938
+ export type Value = { type: "bounds"; value: [number, number, number, number] } | { type: "colorRef"; value: string | null } | { type: "length"; value: number | null } | { type: "transform"; value: [number, number, number, number, number, number] | null } | { type: "pathPoint"; value: { address: PathPointAddress; position: [number, number] } } | { type: "pathPointInsert"; value: { index: number; anchor: PathAnchorSpec; prevSubpathStarts?: number[] | null } } | { type: "pathPointRemove"; value: { index: number; prevSubpathStarts?: number[] | null } } | { type: "pathPointCurveType"; value: { index: number; smooth: boolean; prev?: PathAnchorSpec | null } } | { type: "pluginMetadata"; value: { key: string; value: string | null; caller?: string | null; prev?: string | null | null } } | { type: "bool"; value: boolean } | { type: "text"; value: string } | { type: "framePath"; value: { anchors: PathAnchorSpec[]; subpathStarts: number[] } } | { type: "pathOpenAt"; value: { index: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "outlineStroke"; value: { width: number; cap: string; join: string; miterLimit: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "outlineStrokeVariable"; value: { widths: number[]; cap: string; join: string; miterLimit: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "offsetPath"; value: { delta: number; join: string; miterLimit: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "simplifyPath"; value: { tolerance: number; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "closePath"; value: { subpath?: number | null; prevAnchors?: PathAnchorSpec[] | null; prevSubpathStarts?: number[] | null; prevSubpathOpen?: boolean[] | null } } | { type: "gradientFeather"; value: GradientFeatherSpec | null } | { type: "paragraphRule"; value: ParagraphRuleSpec | null } | { type: "tabStops"; value: TabStopSpec[] } | { type: "lengths"; value: number[] };
1650
1939
 
1651
1940
  /**
1652
1941
  * Typed property path for `SetProperty` Ops. A closed enum (rather
@@ -1656,7 +1945,7 @@ export type Value = { type: "bounds"; value: [number, number, number, number] }
1656
1945
  * (`\"fill.color\"`) — so JS callers don\'t need to learn the Rust
1657
1946
  * enum shape.
1658
1947
  */
1659
- export type PropertyPath = "frameBounds" | "frameFillColor" | "frameStrokeColor" | "frameStrokeWeight" | "frameOpacity" | "frameTransform" | "imageContentTransform" | "framePathPoint" | "pathPointInsert" | "pathPointRemove" | "pathPointCurveType" | "layerVisible" | "layerLocked" | "layerPrintable" | "layerName" | "characterFontSize" | "characterLeading" | "characterTracking" | "characterFillColor" | "paragraphSpaceBefore" | "paragraphSpaceAfter" | "paragraphFirstLineIndent" | "appliedParagraphStyle" | "appliedCharacterStyle" | "appliedObjectStyle" | "appliedCellStyle" | "appliedTableStyle" | "framePath" | "frameNonprinting" | "frameFillTint" | "frameGradientFillAngle" | "frameGradientFillLength" | "frameGradientStrokeAngle" | "frameGradientStrokeLength" | "pathOpenAt" | "outlineStroke" | "outlineStrokeVariable" | "offsetPath" | "simplifyPath" | "frameGradientFeather" | "pageBounds" | "frameDropShadowMode" | "frameDropShadowXOffset" | "frameDropShadowYOffset" | "frameDropShadowSize" | "frameDropShadowOpacity" | "frameDropShadowColor" | "frameDropShadow" | "frameFittingCrops" | "frameFittingType" | "frameTextWrapMode" | "frameTextWrapOffsets" | "frameTextWrapContourType" | "frameTextWrapContourIncludeInside" | "paragraphJustification" | "paragraphStyleNextStyle" | "paragraphAppliedNumberingList" | "frameStrokeEndCap" | "frameInsetSpacing" | "appliedConditions" | "characterFontFamily" | "characterFontStyle" | "characterKerningMethod" | "characterCase" | "characterPosition" | "characterLanguage" | "characterBaselineShift" | "characterHorizontalScale" | "characterVerticalScale" | "characterSkew" | "characterUnderline" | "characterStrikethru" | "characterLigatures" | "characterOtfFeatures" | "paragraphLeftIndent" | "paragraphRightIndent" | "paragraphDropCapCharacters" | "paragraphDropCapLines" | "paragraphHyphenation" | "paragraphKeepLinesTogether" | "paragraphKeepWithNext" | "paragraphRuleAbove" | "paragraphRuleBelow" | "paragraphTabStops" | "paragraphListType" | "paragraphBulletCharacter" | "paragraphNumberingFormat" | "textFrameColumnCount" | "textFrameColumnGutter" | "textFrameColumnBalance" | "textFrameVerticalJustification" | "textFrameAutoSizing" | "textFrameFirstBaseline" | "textWrapInvert" | "frameFittingReferencePoint" | "frameAutoFit" | "frameStrokeType" | "frameStrokeJoin" | "frameStrokeMiterLimit" | "frameStrokeAlignment" | "frameStrokeGapColor" | "frameStrokeGapTint" | "frameStrokeDashArray" | "frameCornerOptionTopLeft" | "frameCornerOptionTopRight" | "frameCornerOptionBottomLeft" | "frameCornerOptionBottomRight" | "frameCornerRadiusTopLeft" | "frameCornerRadiusTopRight" | "frameCornerRadiusBottomLeft" | "frameCornerRadiusBottomRight" | "frameRotationAngle" | "frameScaleX" | "frameScaleY" | "frameFlipH" | "frameFlipV" | "frameOverprintFill" | "frameOverprintStroke" | "frameInnerShadowEnabled" | "frameInnerShadowBlendMode" | "frameInnerShadowColor" | "frameInnerShadowOpacity" | "frameInnerShadowAngle" | "frameInnerShadowDistance" | "frameInnerShadowSize" | "frameInnerShadowChoke" | "frameInnerShadowNoise" | "frameOuterGlowEnabled" | "frameOuterGlowBlendMode" | "frameOuterGlowColor" | "frameOuterGlowOpacity" | "frameOuterGlowSpread" | "frameOuterGlowSize" | "frameOuterGlowNoise" | "frameInnerGlowEnabled" | "frameInnerGlowBlendMode" | "frameInnerGlowColor" | "frameInnerGlowOpacity" | "frameInnerGlowChoke" | "frameInnerGlowSize" | "frameInnerGlowSource" | "frameInnerGlowNoise" | "frameBevelEnabled" | "frameBevelStyle" | "frameBevelTechnique" | "frameBevelDepth" | "frameBevelDirection" | "frameBevelSize" | "frameBevelSoften" | "frameBevelAngle" | "frameBevelAltitude" | "frameBevelHighlightColor" | "frameBevelShadowColor" | "frameBevelHighlightOpacity" | "frameBevelShadowOpacity" | "frameSatinEnabled" | "frameSatinBlendMode" | "frameSatinColor" | "frameSatinOpacity" | "frameSatinAngle" | "frameSatinDistance" | "frameSatinSize" | "frameSatinInvert" | "frameFeatherEnabled" | "frameFeatherWidth" | "frameFeatherCornerType" | "frameFeatherNoise" | "frameFeatherChoke" | "frameDirectionalFeatherEnabled" | "frameDirectionalFeatherLeftWidth" | "frameDirectionalFeatherRightWidth" | "frameDirectionalFeatherTopWidth" | "frameDirectionalFeatherBottomWidth" | "frameDirectionalFeatherAngle" | "frameDirectionalFeatherNoise" | "frameDirectionalFeatherChoke" | "frameBlendMode" | "nextTextFrame" | "previousTextFrame" | "cellFillColor" | "cellFillTint" | "cellInsetTop" | "cellInsetLeft" | "cellInsetBottom" | "cellInsetRight" | "cellVerticalJustification" | "cellTopEdgeStrokeColor" | "cellTopEdgeStrokeWeight" | "cellTopEdgeStrokeTint" | "cellBottomEdgeStrokeColor" | "cellBottomEdgeStrokeWeight" | "cellBottomEdgeStrokeTint" | "cellLeftEdgeStrokeColor" | "cellLeftEdgeStrokeWeight" | "cellLeftEdgeStrokeTint" | "cellRightEdgeStrokeColor" | "cellRightEdgeStrokeWeight" | "cellRightEdgeStrokeTint" | "tableRowCount" | "tableColumnCount" | "pluginMetadata" | "anchoredPosition" | "anchorPoint" | "anchoredXOffset" | "anchoredYOffset" | "anchoredHorizontalReference" | "anchoredVerticalReference" | "anchoredHorizontalAlignment" | "anchoredVerticalAlignment" | "anchoredSpineRelative" | "anchoredLockPosition" | "elementVisible" | "elementLocked" | "frameStrokeStartArrowhead" | "frameStrokeEndArrowhead";
1948
+ export type PropertyPath = "frameBounds" | "frameFillColor" | "frameStrokeColor" | "frameStrokeWeight" | "frameOpacity" | "frameTransform" | "imageContentTransform" | "framePathPoint" | "pathPointInsert" | "pathPointRemove" | "pathPointCurveType" | "layerVisible" | "layerLocked" | "layerPrintable" | "layerName" | "characterFontSize" | "characterLeading" | "characterTracking" | "characterFillColor" | "paragraphSpaceBefore" | "paragraphSpaceAfter" | "paragraphFirstLineIndent" | "appliedParagraphStyle" | "appliedCharacterStyle" | "appliedObjectStyle" | "appliedCellStyle" | "appliedTableStyle" | "framePath" | "frameNonprinting" | "frameFillTint" | "frameGradientFillAngle" | "frameGradientFillLength" | "frameGradientStrokeAngle" | "frameGradientStrokeLength" | "pathOpenAt" | "outlineStroke" | "outlineStrokeVariable" | "offsetPath" | "simplifyPath" | "closePath" | "frameGradientFeather" | "pageBounds" | "frameDropShadowMode" | "frameDropShadowXOffset" | "frameDropShadowYOffset" | "frameDropShadowSize" | "frameDropShadowOpacity" | "frameDropShadowColor" | "frameDropShadow" | "frameFittingCrops" | "frameFittingType" | "frameTextWrapMode" | "frameTextWrapOffsets" | "frameTextWrapContourType" | "frameTextWrapContourIncludeInside" | "paragraphJustification" | "paragraphStyleNextStyle" | "paragraphAppliedNumberingList" | "frameStrokeEndCap" | "frameInsetSpacing" | "appliedConditions" | "characterFontFamily" | "characterFontStyle" | "characterKerningMethod" | "characterCase" | "characterPosition" | "characterLanguage" | "characterBaselineShift" | "characterHorizontalScale" | "characterVerticalScale" | "characterSkew" | "characterUnderline" | "characterStrikethru" | "characterLigatures" | "characterOtfFeatures" | "paragraphLeftIndent" | "paragraphRightIndent" | "paragraphDropCapCharacters" | "paragraphDropCapLines" | "paragraphHyphenation" | "paragraphKeepLinesTogether" | "paragraphKeepWithNext" | "paragraphRuleAbove" | "paragraphRuleBelow" | "paragraphTabStops" | "paragraphListType" | "paragraphBulletCharacter" | "paragraphNumberingFormat" | "textFrameColumnCount" | "textFrameColumnGutter" | "textFrameColumnBalance" | "textFrameVerticalJustification" | "textFrameAutoSizing" | "textFrameFirstBaseline" | "textWrapInvert" | "frameFittingReferencePoint" | "frameAutoFit" | "frameStrokeType" | "frameStrokeJoin" | "frameStrokeMiterLimit" | "frameStrokeAlignment" | "frameStrokeGapColor" | "frameStrokeGapTint" | "frameStrokeDashArray" | "frameCornerOptionTopLeft" | "frameCornerOptionTopRight" | "frameCornerOptionBottomLeft" | "frameCornerOptionBottomRight" | "frameCornerRadiusTopLeft" | "frameCornerRadiusTopRight" | "frameCornerRadiusBottomLeft" | "frameCornerRadiusBottomRight" | "frameRotationAngle" | "frameScaleX" | "frameScaleY" | "frameFlipH" | "frameFlipV" | "frameOverprintFill" | "frameOverprintStroke" | "frameInnerShadowEnabled" | "frameInnerShadowBlendMode" | "frameInnerShadowColor" | "frameInnerShadowOpacity" | "frameInnerShadowAngle" | "frameInnerShadowDistance" | "frameInnerShadowSize" | "frameInnerShadowChoke" | "frameInnerShadowNoise" | "frameOuterGlowEnabled" | "frameOuterGlowBlendMode" | "frameOuterGlowColor" | "frameOuterGlowOpacity" | "frameOuterGlowSpread" | "frameOuterGlowSize" | "frameOuterGlowNoise" | "frameInnerGlowEnabled" | "frameInnerGlowBlendMode" | "frameInnerGlowColor" | "frameInnerGlowOpacity" | "frameInnerGlowChoke" | "frameInnerGlowSize" | "frameInnerGlowSource" | "frameInnerGlowNoise" | "frameBevelEnabled" | "frameBevelStyle" | "frameBevelTechnique" | "frameBevelDepth" | "frameBevelDirection" | "frameBevelSize" | "frameBevelSoften" | "frameBevelAngle" | "frameBevelAltitude" | "frameBevelHighlightColor" | "frameBevelShadowColor" | "frameBevelHighlightOpacity" | "frameBevelShadowOpacity" | "frameSatinEnabled" | "frameSatinBlendMode" | "frameSatinColor" | "frameSatinOpacity" | "frameSatinAngle" | "frameSatinDistance" | "frameSatinSize" | "frameSatinInvert" | "frameFeatherEnabled" | "frameFeatherWidth" | "frameFeatherCornerType" | "frameFeatherNoise" | "frameFeatherChoke" | "frameDirectionalFeatherEnabled" | "frameDirectionalFeatherLeftWidth" | "frameDirectionalFeatherRightWidth" | "frameDirectionalFeatherTopWidth" | "frameDirectionalFeatherBottomWidth" | "frameDirectionalFeatherAngle" | "frameDirectionalFeatherNoise" | "frameDirectionalFeatherChoke" | "frameBlendMode" | "nextTextFrame" | "previousTextFrame" | "cellFillColor" | "cellFillTint" | "cellInsetTop" | "cellInsetLeft" | "cellInsetBottom" | "cellInsetRight" | "cellVerticalJustification" | "cellTopEdgeStrokeColor" | "cellTopEdgeStrokeWeight" | "cellTopEdgeStrokeTint" | "cellBottomEdgeStrokeColor" | "cellBottomEdgeStrokeWeight" | "cellBottomEdgeStrokeTint" | "cellLeftEdgeStrokeColor" | "cellLeftEdgeStrokeWeight" | "cellLeftEdgeStrokeTint" | "cellRightEdgeStrokeColor" | "cellRightEdgeStrokeWeight" | "cellRightEdgeStrokeTint" | "tableRowCount" | "tableColumnCount" | "pluginMetadata" | "anchoredPosition" | "anchorPoint" | "anchoredXOffset" | "anchoredYOffset" | "anchoredHorizontalReference" | "anchoredVerticalReference" | "anchoredHorizontalAlignment" | "anchoredVerticalAlignment" | "anchoredSpineRelative" | "anchoredLockPosition" | "elementVisible" | "elementLocked" | "frameStrokeStartArrowhead" | "frameStrokeEndArrowhead";
1660
1949
 
1661
1950
  /**
1662
1951
  * Typed worker-side error for non-load operations. Mutations,
@@ -1666,20 +1955,7 @@ export type PropertyPath = "frameBounds" | "frameFillColor" | "frameStrokeColor"
1666
1955
  export type WorkerError = { kind: "notImplemented"; details: { what: string } } | { kind: "unknownPage"; details: { pageId: PageId } } | { kind: "noDocument" };
1667
1956
 
1668
1957
  /**
1669
- * W0.2 — wire mirror of `paged_parse::TabStop`. The `ParagraphTabStops`
1670
- * path replaces the paragraph\'s whole `<TabList>` in one op; `Value`
1671
- * has no per-element list-edit form, so the UI sends the full new
1672
- * stop list (the gradient-feather stop-list precedent).
1673
- */
1674
- export interface TabStopSpec {
1675
- position: number;
1676
- alignment?: string | null;
1677
- alignmentCharacter?: string | null;
1678
- leader?: string | null;
1679
- }
1680
-
1681
- /**
1682
- * W0.2 — wire mirror of `paged_parse::styles::ParagraphRule` (the
1958
+ * W0.2 — wire mirror of `paged_model::ParagraphRule` (the
1683
1959
  * AST type predates `Tsify`; the mirror keeps the op wire-shaped,
1684
1960
  * the `GradientFeatherSpec` precedent). Carries every field the
1685
1961
  * parser models so the whole-struct `ParagraphRuleAbove` /
@@ -1697,10 +1973,17 @@ export interface ParagraphRuleSpec {
1697
1973
  }
1698
1974
 
1699
1975
  /**
1700
- * W0.5 — character- vs paragraph-level style application for
1701
- * [`Operation::ApplyStyle`].
1976
+ * W0.2 — wire mirror of `paged_model::TabStop`. The `ParagraphTabStops`
1977
+ * path replaces the paragraph\'s whole `<TabList>` in one op; `Value`
1978
+ * has no per-element list-edit form, so the UI sends the full new
1979
+ * stop list (the gradient-feather stop-list precedent).
1702
1980
  */
1703
- export type StyleScope = "paragraph" | "character";
1981
+ export interface TabStopSpec {
1982
+ position: number;
1983
+ alignment?: string | null;
1984
+ alignmentCharacter?: string | null;
1985
+ leader?: string | null;
1986
+ }
1704
1987
 
1705
1988
  /**
1706
1989
  * W0.5 — the kind of field marker inserted by
@@ -1708,12 +1991,12 @@ export type StyleScope = "paragraph" | "character";
1708
1991
  * built-ins (single private-use marker chars the renderer
1709
1992
  * substitutes); v43 (D-01) adds the plugin `Placeholder` — a tagged,
1710
1993
  * edit-surviving anchor run whose text is the field\'s cached display
1711
- * value (see `paged_parse::PlaceholderField`).
1994
+ * value (see `paged_model::PlaceholderField`).
1712
1995
  */
1713
1996
  export type FieldKind = "pageNumber" | "nextPageNumber" | { placeholder: { plugin: string; key: string; value?: string | undefined } };
1714
1997
 
1715
1998
  /**
1716
- * W0.5 — wire mirror of `paged_parse::GuideOrientation`
1999
+ * W0.5 — wire mirror of `paged_model::GuideOrientation`
1717
2000
  * (which is `Deserialize` but lives in the parse crate; kept here so
1718
2001
  * the operation wire type doesn\'t depend on the parser\'s
1719
2002
  * serialization shape).
@@ -1727,7 +2010,7 @@ export type GuideOrientationSpec = "vertical" | "horizontal";
1727
2010
  * ## The two-stream addressing model
1728
2011
  *
1729
2012
  * Table-cell text is stored out of band on `Table.cells[].paragraphs`
1730
- * (see `paged_parse`), disjoint from `Story.paragraphs`. So a content
2013
+ * (see `idml_import`), disjoint from `Story.paragraphs`. So a content
1731
2014
  * address needs to say *which* paragraph stream its byte offsets index:
1732
2015
  *
1733
2016
  * - `ContentSelection.cell == None` — offsets are story-local bytes
@@ -1807,7 +2090,7 @@ export interface NumberingListSummary {
1807
2090
 
1808
2091
  /**
1809
2092
  * W1.22 (engine gap 22) — wire description of a `<NumberingList>`
1810
- * resource, mirroring `paged_parse::styles::NumberingListDef`. The
2093
+ * resource, mirroring `paged_model::NumberingListDef`. The
1811
2094
  * CRUD ops (`CreateNumberingList` / `EditNumberingList` /
1812
2095
  * `DeleteNumberingList`) carry this. `self_id` is minted
1813
2096
  * (`NumberingList/u<n>`) when absent on create; echoed resolved in
@@ -1927,6 +2210,19 @@ export interface ResolutionResult {
1927
2210
  */
1928
2211
  export type HitFilter = "frame" | "text" | "any";
1929
2212
 
2213
+ /**
2214
+ * Where a story\'s flow overran its frame chain — the first-class overset
2215
+ * **continuation** the engine records (`paged_flow::Overset::Remains`, via
2216
+ * `RenderDiagnostics::overset_continuations()`). Lets the editor jump the
2217
+ * caret to the first clipped line / show \"overset at ¶N line M\" instead of
2218
+ * only a boolean overset badge. Addresses match the layout stream
2219
+ * (`paragraph` within the story\'s body flow, `line` within that paragraph).
2220
+ */
2221
+ export interface OversetAt {
2222
+ paragraph: number;
2223
+ line: number;
2224
+ }
2225
+
1930
2226
  /**
1931
2227
  * Which runtime budget a script exhausted (B-09 / W-08). The typed
1932
2228
  * half of a `ScriptResult`: lets the host distinguish a budget abort
@@ -1970,7 +2266,7 @@ export interface GradientSpec {
1970
2266
 
1971
2267
  /**
1972
2268
  * Wire-format description of a colour swatch (`<Color>`), mirroring
1973
- * the editable fields of `paged_parse::ColorEntry` with primitive,
2269
+ * the editable fields of `paged_model::ColorEntry` with primitive,
1974
2270
  * `Deserialize`-able types (the AST `ColorEntry` is `Serialize`-only).
1975
2271
  * Carried by the swatch-collection mutations so create / edit /
1976
2272
  * delete-undo are lossless. `space` / `model` / `alternate_space` are
@@ -2008,6 +2304,11 @@ export interface SwatchSpec {
2008
2304
  */
2009
2305
  export type GestureFailure = { kind: "noDocument" } | { kind: "unsupportedGesture"; details: { reason: string } } | { kind: "alreadyActive"; details: { handle: GestureHandle } } | { kind: "handleMismatch" } | { kind: "elementNotFound"; details: { id: ElementId } } | { kind: "rotatedFrameUnsupported" } | { kind: "emptySelection" } | { kind: "missingAnchor" } | { kind: "unknownAnchorPage"; details: { page_id: PageId } } | { kind: "other"; details: { message: string } };
2010
2306
 
2307
+ /**
2308
+ * [`Operation::ApplyStyle`].
2309
+ */
2310
+ export type StyleScope = "paragraph" | "character";
2311
+
2011
2312
  /**
2012
2313
  * `RequestLineBounds` reply payload.
2013
2314
  */
@@ -2167,6 +2468,143 @@ export interface ProviderTileWire {
2167
2468
  rgba: number[];
2168
2469
  }
2169
2470
 
2471
+ /**
2472
+ * v59 — where [`Operation::ReorderNode`] puts its target inside the
2473
+ * sibling list it already belongs to.
2474
+ *
2475
+ * **Both forms deliberately ship.** The four RELATIVE verbs are what a
2476
+ * UI and a plugin can actually express: they are read-modify-write
2477
+ * against whatever the list happens to be at apply time, so a
2478
+ * concurrent insert or delete between \"the caller read the order\" and
2479
+ * \"the engine applied the op\" cannot silently restack the wrong item —
2480
+ * there is no stale index to be wrong. They map 1:1 onto the Arrange
2481
+ * menu every DTP app ships (Illustrator\'s Object ▸ Arrange, InDesign\'s
2482
+ * Object ▸ Arrange, PowerPoint\'s Bring Forward…).
2483
+ *
2484
+ * [`ZOrderTarget::Index`] is the absolute form, and it is what makes
2485
+ * the inverse EXACT: the apply layer records the slot the node came
2486
+ * from and hands back `Index(that slot)`. It is also the honest way to
2487
+ * express \"restore this exact order\" for a drag in a layers panel.
2488
+ * Because an absolute index CAN go stale, an out-of-range `Index` is
2489
+ * rejected loudly (`OperationError::InvalidPosition`) instead of being
2490
+ * clamped — a caller working from a stale model should hear about it.
2491
+ *
2492
+ * Serialised externally-tagged (the [`FieldKind`] convention):
2493
+ * `\"front\"` / `\"back\"` / `\"forward\"` / `\"backward\"` / `{\"index\": 3}`.
2494
+ */
2495
+ export type ZOrderTarget = "front" | "back" | "forward" | "backward" | { index: number };
2496
+
2497
+ /**
2498
+ * §21 advanced prepress — one ink plate\'s coverage on one page.
2499
+ *
2500
+ * `area_pct` is the share of the WHOLE page this plate puts any ink
2501
+ * on — the \"does this plate earn its pass on press\" number.
2502
+ * `max_tint_pct` / `mean_tint_pct` describe how heavily, over the
2503
+ * inked pixels only.
2504
+ */
2505
+ export interface PlateCoverageSummary {
2506
+ /**
2507
+ * `\"cyan\"` / `\"magenta\"` / `\"yellow\"` / `\"black\"` for the process
2508
+ * inks; the spot swatch\'s `Color/<id>` for a named ink — the same
2509
+ * id `InkSummary::spot_id` uses, so the Ink Manager and this
2510
+ * surface address the same ink.
2511
+ */
2512
+ inkId: string;
2513
+ /**
2514
+ * Display name: `\"Cyan\"` … `\"Black\"`, or the spot swatch\'s
2515
+ * palette name (falling back to its id).
2516
+ */
2517
+ name: string;
2518
+ isSpot: boolean;
2519
+ areaPct: number;
2520
+ maxTintPct: number;
2521
+ meanTintPct: number;
2522
+ }
2523
+
2524
+ /**
2525
+ * §21 advanced prepress — one page\'s ink-coverage reading, produced
2526
+ * by rasterising the page and reading the CPU rasterizer\'s per-ink
2527
+ * plane state.
2528
+ *
2529
+ * # Read `separated_pct` before quoting any other number
2530
+ *
2531
+ * The raster lane only decomposes a pixel into inks when the draw
2532
+ * that made it carried a CMYK or spot swatch. Placed images, RGB and
2533
+ * Lab swatches, gradients, and anything inside a blend group carry no
2534
+ * ink decomposition — those pixels are **unknown**, not blank, and
2535
+ * every statistic below excludes them. `separatedPct` is how much of
2536
+ * the page was actually measured. A `maxTacPct` of 340 over a
2537
+ * `separatedPct` of 4 is a statement about 4% of the page.
2538
+ *
2539
+ * Nothing here estimates the unknown pixels. The renderer\'s RGB→CMYK
2540
+ * map is 100%-GCR (a rich black inverts to K-only / 100% TAC where a
2541
+ * real coated profile gives ~300%), so folding it in would make the
2542
+ * headline figure confidently wrong exactly where operators check it.
2543
+ */
2544
+ export interface InkCoverageSummary {
2545
+ pageId: PageId;
2546
+ pageIndex: number;
2547
+ /**
2548
+ * **Check this first.** `false` means the document has no active
2549
+ * CMYK working profile (none supplied at load, none named by the
2550
+ * designmap that the host had registered, no soft proof), and
2551
+ * therefore the renderer resolved every CMYK and spot swatch
2552
+ * straight to display RGB — there is no ink lane at all and every
2553
+ * figure below is structurally zero.
2554
+ *
2555
+ * That is a completely different condition from \"this page is all
2556
+ * RGB artwork\", and a surface MUST NOT render them the same way:
2557
+ * one says *activate a profile*, the other says *this content
2558
+ * separates at the RIP*. Both produce `separatedPct == 0`.
2559
+ *
2560
+ * `SwatchSummary::totalAreaCoveragePct` is unaffected — it is
2561
+ * palette arithmetic and needs no profile — so the swatch-level
2562
+ * ink-limit audit still works when this is `false`.
2563
+ */
2564
+ separationAvailable: boolean;
2565
+ /**
2566
+ * Sampling resolution of the analysis render, in dpi. An area
2567
+ * measurement is dpi-independent for solid tints; anti-aliased
2568
+ * edges dilute their ink with the paper they partly cover, so
2569
+ * sub-pixel hairlines under-report. Check hairline rich blacks
2570
+ * against `SwatchSummary::totalAreaCoveragePct`, which is exact.
2571
+ */
2572
+ analysisDpi: number;
2573
+ /**
2574
+ * The total-area-coverage limit `overLimitPixels` was counted
2575
+ * against, in percent.
2576
+ */
2577
+ limitPct: number;
2578
+ totalPixels: number;
2579
+ separatedPixels: number;
2580
+ /**
2581
+ * `separatedPixels / totalPixels`, 0..=100. The honesty
2582
+ * denominator — see the type docs.
2583
+ */
2584
+ separatedPct: number;
2585
+ maxTacPct: number;
2586
+ meanTacPct: number;
2587
+ overLimitPixels: number;
2588
+ /**
2589
+ * Share of the SEPARATED pixels over the limit, 0..=100.
2590
+ */
2591
+ overLimitPct: number;
2592
+ /**
2593
+ * Four process plates always, then one per spot ink used on the
2594
+ * page. A blank process plate still appears — \"Cyan: 0%\" is
2595
+ * itself a reading.
2596
+ */
2597
+ plates: PlateCoverageSummary[];
2598
+ /**
2599
+ * 81 counts over the separated pixels, bucket `i` covering
2600
+ * `[i·10%, (i+1)·10%)` of total area coverage (so 0–800%, which
2601
+ * leaves room for spot plates above the 400% process ceiling).
2602
+ * Lets a panel re-threshold the ink limit with a slider and no
2603
+ * re-render.
2604
+ */
2605
+ histogram: number[];
2606
+ }
2607
+
2170
2608
  export interface CaretGeometry {
2171
2609
  pageId: PageId;
2172
2610
  frameId: string | null;
@@ -2460,9 +2898,9 @@ export interface InitOutput {
2460
2898
  readonly qcms_white_point_sRGB: (a: number) => void;
2461
2899
  readonly lut_inverse_interp16: (a: number, b: number, c: number) => number;
2462
2900
  readonly lut_interp_linear16: (a: number, b: number, c: number) => number;
2463
- readonly wasm_bindgen__convert__closures_____invoke__he4c1c257c045c41d: (a: number, b: number, c: any) => [number, number];
2464
- readonly wasm_bindgen__convert__closures_____invoke__h98d8e723eec618c7: (a: number, b: number, c: any, d: any) => void;
2465
- readonly wasm_bindgen__convert__closures_____invoke__h10d8665c2d310494: (a: number, b: number, c: any) => void;
2901
+ readonly wasm_bindgen__convert__closures_____invoke__hba9dab33e391dce8: (a: number, b: number, c: any) => [number, number];
2902
+ readonly wasm_bindgen__convert__closures_____invoke__h2a9a86477ca3734e: (a: number, b: number, c: any, d: any) => void;
2903
+ readonly wasm_bindgen__convert__closures_____invoke__h84d34b615e684f5e: (a: number, b: number, c: any) => void;
2466
2904
  readonly __wbindgen_malloc: (a: number, b: number) => number;
2467
2905
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
2468
2906
  readonly __wbindgen_exn_store: (a: number) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paged-media/plugin-api",
3
- "version": "0.2.28-canary.0",
3
+ "version": "0.2.30-canary.0",
4
4
  "description": "The Paged plugin contract: manifest, bundle lifecycle, the BundleHost surface, and the contribution + engine wire types. Type-only.",
5
5
  "license": "MPL-2.0 OR LicenseRef-PMEL",
6
6
  "type": "module",
@@ -270,8 +270,7 @@
270
270
  },
271
271
  "entry": {
272
272
  "enum": [
273
- "doubleClick",
274
- "command"
273
+ "doubleClick"
275
274
  ]
276
275
  },
277
276
  "priority": {