@embedpdf/engine-core 3.0.0-next.14 → 3.0.0-next.16

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.
Files changed (135) hide show
  1. package/dist/AnnotationList-DcyhF2kU.d.cts +27691 -0
  2. package/dist/AnnotationList-DcyhF2kU.d.ts +27691 -0
  3. package/dist/Change-Ct-dB8D5.cjs +1133 -0
  4. package/dist/Change-Ct-dB8D5.cjs.map +1 -0
  5. package/dist/Change-tMR34hTU.js +978 -0
  6. package/dist/Change-tMR34hTU.js.map +1 -0
  7. package/dist/DocumentRenderService-9IjSQEIU.cjs +121 -0
  8. package/dist/DocumentRenderService-9IjSQEIU.cjs.map +1 -0
  9. package/dist/DocumentRenderService-DFrZ9wfW.js +86 -0
  10. package/dist/DocumentRenderService-DFrZ9wfW.js.map +1 -0
  11. package/dist/{DocumentSecurityService-Ca6EK3-3.d.ts → DocumentSecurityService-D2zA4NKi.d.cts} +100 -112
  12. package/dist/{DocumentSecurityService-CIx1MT0T.d.cts → DocumentSecurityService-YJV9df8P.d.ts} +100 -112
  13. package/dist/LocalDocumentHandle-D02FMm-Z.cjs +53 -0
  14. package/dist/LocalDocumentHandle-D02FMm-Z.cjs.map +1 -0
  15. package/dist/LocalDocumentHandle-DAPdaOt_.js +30 -0
  16. package/dist/LocalDocumentHandle-DAPdaOt_.js.map +1 -0
  17. package/dist/LocalEngine-DBt2-GWF.d.ts +1649 -0
  18. package/dist/LocalEngine-IA9zh3Jh.d.cts +1649 -0
  19. package/dist/PageInsertBlankInput-CXHAM7l6.cjs +17 -0
  20. package/dist/PageInsertBlankInput-CXHAM7l6.cjs.map +1 -0
  21. package/dist/PageInsertBlankInput-DhVYVJ_S.js +12 -0
  22. package/dist/PageInsertBlankInput-DhVYVJ_S.js.map +1 -0
  23. package/dist/authority-BFp6XM04.cjs +2997 -0
  24. package/dist/authority-BFp6XM04.cjs.map +1 -0
  25. package/dist/authority-PuxpGFhJ.js +2506 -0
  26. package/dist/authority-PuxpGFhJ.js.map +1 -0
  27. package/dist/builders-DV62HA3I.js +165 -0
  28. package/dist/builders-DV62HA3I.js.map +1 -0
  29. package/dist/builders-DgTAj_tP.cjs +188 -0
  30. package/dist/builders-DgTAj_tP.cjs.map +1 -0
  31. package/dist/calibrate-DJbi1wuK.cjs +3012 -0
  32. package/dist/calibrate-DJbi1wuK.cjs.map +1 -0
  33. package/dist/calibrate-nQFgCuki.js +2461 -0
  34. package/dist/calibrate-nQFgCuki.js.map +1 -0
  35. package/dist/charmap-Cprti1ta.js +239 -0
  36. package/dist/charmap-Cprti1ta.js.map +1 -0
  37. package/dist/charmap-aYlefQP9.cjs +304 -0
  38. package/dist/charmap-aYlefQP9.cjs.map +1 -0
  39. package/dist/conformance.cjs +18146 -5258
  40. package/dist/conformance.cjs.map +1 -1
  41. package/dist/conformance.d.cts +1024 -170
  42. package/dist/conformance.d.ts +1024 -170
  43. package/dist/conformance.js +18148 -5309
  44. package/dist/conformance.js.map +1 -1
  45. package/dist/format-Bp3QFSH1.cjs +574 -0
  46. package/dist/format-Bp3QFSH1.cjs.map +1 -0
  47. package/dist/format-Dgg428Kb.js +461 -0
  48. package/dist/format-Dgg428Kb.js.map +1 -0
  49. package/dist/index.cjs +342 -116
  50. package/dist/index.d.cts +2 -2
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.js +14 -5
  53. package/dist/pageRefs-B3ur7Ckm.cjs +51 -0
  54. package/dist/pageRefs-B3ur7Ckm.cjs.map +1 -0
  55. package/dist/pageRefs-DkbuxSCV.js +40 -0
  56. package/dist/pageRefs-DkbuxSCV.js.map +1 -0
  57. package/dist/public.cjs +59 -0
  58. package/dist/public.d.cts +5 -0
  59. package/dist/public.d.ts +5 -0
  60. package/dist/public.js +9 -0
  61. package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs +3646 -0
  62. package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs.map +1 -0
  63. package/dist/resolveAnnotationDraft-CUpf0SMh.js +3167 -0
  64. package/dist/resolveAnnotationDraft-CUpf0SMh.js.map +1 -0
  65. package/dist/{resolver-inAVzsWt.js → resolver-BBggAxQc.js} +298 -145
  66. package/dist/resolver-BBggAxQc.js.map +1 -0
  67. package/dist/{resolver-CYVNV4hn.cjs → resolver-BWSWSF6R.cjs} +351 -144
  68. package/dist/resolver-BWSWSF6R.cjs.map +1 -0
  69. package/dist/runtime-BaDKjxiu.d.ts +1959 -0
  70. package/dist/runtime-CWEuiwbk.d.cts +1959 -0
  71. package/dist/runtime.cjs +986 -297
  72. package/dist/runtime.cjs.map +1 -1
  73. package/dist/runtime.d.cts +5 -1372
  74. package/dist/runtime.d.ts +5 -1372
  75. package/dist/runtime.js +634 -179
  76. package/dist/runtime.js.map +1 -1
  77. package/dist/schema-6S2VmlAj.js +2087 -0
  78. package/dist/schema-6S2VmlAj.js.map +1 -0
  79. package/dist/schema-miH6tWQC.cjs +3046 -0
  80. package/dist/schema-miH6tWQC.cjs.map +1 -0
  81. package/dist/schemas-BE2QGOit.js +1851 -0
  82. package/dist/schemas-BE2QGOit.js.map +1 -0
  83. package/dist/schemas-DljJR9ut.cjs +2798 -0
  84. package/dist/schemas-DljJR9ut.cjs.map +1 -0
  85. package/dist/subtype-CG4WpIRj.js +129 -0
  86. package/dist/subtype-CG4WpIRj.js.map +1 -0
  87. package/dist/subtype-aDt5TFmK.cjs +158 -0
  88. package/dist/subtype-aDt5TFmK.cjs.map +1 -0
  89. package/dist/validation.cjs +578 -0
  90. package/dist/validation.cjs.map +1 -0
  91. package/dist/validation.d.cts +174 -0
  92. package/dist/validation.d.ts +174 -0
  93. package/dist/validation.js +571 -0
  94. package/dist/validation.js.map +1 -0
  95. package/dist/value-BFS1R8ek.cjs +435 -0
  96. package/dist/value-BFS1R8ek.cjs.map +1 -0
  97. package/dist/value-Dhc8eYcx.js +340 -0
  98. package/dist/value-Dhc8eYcx.js.map +1 -0
  99. package/dist/viewport-CHG9qQUb.cjs +671 -0
  100. package/dist/viewport-CHG9qQUb.cjs.map +1 -0
  101. package/dist/viewport-DQR5LyX3.js +540 -0
  102. package/dist/viewport-DQR5LyX3.js.map +1 -0
  103. package/dist/wire.cjs +1242 -420
  104. package/dist/wire.cjs.map +1 -1
  105. package/dist/wire.d.cts +14840 -830
  106. package/dist/wire.d.ts +14840 -830
  107. package/dist/wire.js +985 -261
  108. package/dist/wire.js.map +1 -1
  109. package/package.json +10 -1
  110. package/dist/AbortError-DwuHPK_I.js +0 -27
  111. package/dist/AbortError-DwuHPK_I.js.map +0 -1
  112. package/dist/AbortError-P0RU0Mgg.cjs +0 -38
  113. package/dist/AbortError-P0RU0Mgg.cjs.map +0 -1
  114. package/dist/AnnotationListSnapshot-D9R5n2Kf.d.cts +0 -7101
  115. package/dist/AnnotationListSnapshot-D9R5n2Kf.d.ts +0 -7101
  116. package/dist/Engine-EWWHhEIi.d.ts +0 -1277
  117. package/dist/Engine-FNaAEjfb.d.cts +0 -1277
  118. package/dist/derive-BbsDk_Kz.cjs +0 -880
  119. package/dist/derive-BbsDk_Kz.cjs.map +0 -1
  120. package/dist/derive-DAFJolWu.js +0 -647
  121. package/dist/derive-DAFJolWu.js.map +0 -1
  122. package/dist/format-Bbphf4zR.js +0 -435
  123. package/dist/format-Bbphf4zR.js.map +0 -1
  124. package/dist/format-D_epWlob.cjs +0 -518
  125. package/dist/format-D_epWlob.cjs.map +0 -1
  126. package/dist/resolver-CYVNV4hn.cjs.map +0 -1
  127. package/dist/resolver-inAVzsWt.js.map +0 -1
  128. package/dist/schemas-CFQGvWiu.js +0 -3243
  129. package/dist/schemas-CFQGvWiu.js.map +0 -1
  130. package/dist/schemas-D0g6tKa9.cjs +0 -4694
  131. package/dist/schemas-D0g6tKa9.cjs.map +0 -1
  132. package/dist/viewport-BWeNHZmb.cjs +0 -3503
  133. package/dist/viewport-BWeNHZmb.cjs.map +0 -1
  134. package/dist/viewport-CvMcadfQ.js +0 -3072
  135. package/dist/viewport-CvMcadfQ.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { An as HighlightDraft, Bd as PdfPoint, Hd as PdfRect, Ld as InkList, cf as DocumentMetadata, n as AnnotationListSnapshotAllPages, t as AnnotationListPageSnapshot, xl as CharMapAnchor, zd as LinePoints } from "./AnnotationListSnapshot-D9R5n2Kf.cjs";
2
- import { t as Engine } from "./Engine-FNaAEjfb.cjs";
1
+ import { F_ as PdfRect, Fs as AnnotationDraft, I_ as PdfRotation, Vd as AnnotationResources, _t as LineDraft, b_ as PageBox, dn as HighlightDraft, gh as PageTabOrder, iy as DocumentMetadata, nt as InkDraft, pv as Identity, t as AnnotationList, x_ as PagePoint, zp as CharMapAnchor } from "./AnnotationList-DcyhF2kU.cjs";
2
+ import { _ as Engine, t as LocalEngine, y as DocumentHandle } from "./LocalEngine-IA9zh3Jh.cjs";
3
3
  //#region src/conformance/runMetadataConformance.d.ts
4
4
  interface ConformanceTestRunner {
5
5
  describe(name: string, fn: () => void): void;
@@ -90,10 +90,10 @@ interface AnnotationReadConformanceFixture extends ConformanceFixture {
90
90
  /** At least this many `'caret'` annotations on the page. Defaults to 0. */
91
91
  minCaretCount?: number;
92
92
  /**
93
- * `true` if the fixture has at least one weak annotation (no /NM, direct
94
- * object). Drives the weak-ref + revision tests.
93
+ * `true` if the fixture page has at least one annotation born inline (a
94
+ * dictionary in `/Annots`, no object number). Drives the `baseIndex` tests.
95
95
  */
96
- expectsWeakAnnotation: boolean;
96
+ expectsInlineAnnotation: boolean;
97
97
  }
98
98
  interface AnnotationConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
99
99
  fixture: AnnotationReadConformanceFixture;
@@ -107,7 +107,7 @@ interface ActionsConformanceFixtures {
107
107
  annotation: ConformanceFixture;
108
108
  field: ConformanceFixture;
109
109
  /** `action_payloads.pdf` — every executable payload shape on one page of
110
- * /NM-keyed links. REQUIRED on both flavours: payload parity is a gate. */
110
+ * /NM-keyed links. Required on both flavours: payload parity is a gate. */
111
111
  payloads: ConformanceFixture;
112
112
  /** `open_action_dest.pdf` — a destination-form catalog `/OpenAction`. */
113
113
  openDestination: ConformanceFixture;
@@ -135,46 +135,37 @@ declare function runActionsConformance(runner: ConformanceTestRunner, opts: Acti
135
135
  interface AnnotationMutationConformanceFixture extends ConformanceFixture {
136
136
  /** PDF object number of the page used by the mutation tests. */
137
137
  pageObjectNumber: number;
138
- /** Page already has at least one weak annotation (no /NM, direct object). */
139
- expectsWeakAnnotation: boolean;
138
+ /** The page has at least one annotation born inline (a dictionary in `/Annots`, no object number). */
139
+ expectsInlineAnnotation: boolean;
140
140
  /**
141
- * QuadPoints to use for the create() smoke test. Coordinates are in
142
- * PDF user space; pick a small rectangle that fits anywhere on the
143
- * fixture page so we don't flake on different page sizes.
141
+ * QuadPoints to use for the create() smoke test, in page space; pick a
142
+ * small rectangle that fits anywhere on the fixture page so we don't
143
+ * flake on different page sizes.
144
144
  */
145
145
  createQuad?: HighlightDraft['quadPoints'];
146
146
  /**
147
- * `/Rect` to use for the shape (circle/square) create tests. PDF user
147
+ * The box to use for the shape (circle/square) create tests, in page
148
148
  * space; pick a small box that fits anywhere on the fixture page.
149
149
  */
150
- createShapeRect?: PdfRect;
150
+ createShapeRect?: PageBox;
151
151
  /**
152
- * `/Vertices` to use for the polygon/polyline create tests. PDF user
153
- * space; must fit inside `createShapeRect` (the rect the engine bakes
154
- * the appearance into). Defaults to a small triangle.
152
+ * `/Vertices` to use for the polygon/polyline create tests, in page
153
+ * space; must fit inside `createShapeRect`. Defaults to a small triangle.
155
154
  */
156
- createVertices?: PdfPoint[];
155
+ createVertices?: PagePoint[];
157
156
  /**
158
- * `/L` endpoints to use for the line create test. PDF user space; must
159
- * fit inside `createShapeRect`. Defaults to the rect's diagonal.
157
+ * `/L` endpoints to use for the line create test, in page space; must fit
158
+ * inside `createShapeRect`. Defaults to the rect's diagonal.
160
159
  */
161
- createLinePoints?: LinePoints;
160
+ createLinePoints?: LineDraft['linePoints'];
162
161
  /**
163
- * `/InkList` strokes to use for the ink create test. PDF user space; must
162
+ * `/InkList` strokes to use for the ink create test, in page space; must
164
163
  * fit inside `createShapeRect`. Defaults to a single short stroke.
165
164
  */
166
- createInkList?: InkList;
165
+ createInkList?: InkDraft['inkList'];
167
166
  }
168
167
  interface AnnotationMutationConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
169
168
  fixture: AnnotationMutationConformanceFixture;
170
- /**
171
- * `true` for engines that expose the raw RGBA appearance rasters
172
- * (`renderAppearances`). When set, the shape-create test additionally
173
- * asserts that creating a shape produces a baked `/AP` the appearance
174
- * reader can rasterize. The cloud engine ships encoded images instead
175
- * and leaves this `false`.
176
- */
177
- supportsAppearanceRasters?: boolean;
178
169
  }
179
170
  /**
180
171
  * Mutation conformance suite. Mirrors the read suite: tests are written
@@ -183,22 +174,220 @@ interface AnnotationMutationConformanceOptions extends Omit<ConformanceOptions,
183
174
  * @cloudpdf/server) implementations must pass identically.
184
175
  *
185
176
  * The locked rules being verified here:
186
- * - `create` is append-only: PDFium drops the new annotation at
187
- * `index = previousCount`, so no existing index shifts. Treated
188
- * as non-invalidating — revisions do NOT bump and weak refs
189
- * captured before the create remain valid.
190
- * - `update` is non-structural; revisions do NOT bump.
191
- * - Opportunistic /NM stamp upgrades a weak annotation's ref to
192
- * `kind: 'nm'` on update; an already-durable annotation's /NM is
193
- * NEVER touched.
194
- * - `delete` and `move` are the only index-shifting ops. They bump
195
- * the per-page revision and, on a page that had weak refs before
196
- * the mutation, surface `shouldRefetch: 'weakRefsInvalidated'`.
177
+ * - `create` is append-only: the new annotation paints on top of the
178
+ * page's others, and none of them moves.
179
+ * - Every annotation keeps its name through every write: an object
180
+ * number, or the `baseIndex` of one born inline in the file. No write
181
+ * stamps an /NM to name one.
197
182
  * - Abort propagates as `AbortError` even before the worker
198
183
  * responds.
199
184
  */
200
185
  declare function runAnnotationMutationConformance(runner: ConformanceTestRunner, opts: AnnotationMutationConformanceOptions): void;
201
186
  //#endregion
187
+ //#region src/conformance/runAnnotationAttributionConformance.d.ts
188
+ /** Who a session is and what it may do: open-time options locally, token claims on the cloud. */
189
+ interface AttributionSession {
190
+ readonly scope: ReadonlyArray<string>;
191
+ readonly identity: Identity;
192
+ }
193
+ interface AnnotationAttributionConformanceOptions {
194
+ label: string;
195
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
196
+ makeEngine: () => Promise<Engine> | Engine;
197
+ /**
198
+ * Open the authoring document, a document with annotations another tool
199
+ * wrote, as `session`. With `from`, the new session continues that open
200
+ * session's document and sees what it wrote (locally its downloaded bytes,
201
+ * on the cloud the same layer); the suite closes `from` afterwards.
202
+ */
203
+ openAs: (engine: Engine, session: AttributionSession, from?: DocumentHandle) => Promise<DocumentHandle>;
204
+ }
205
+ /**
206
+ * Attribution on both engines with the same identities:
207
+ * `create` stamps it from the session and ignores what the data says,
208
+ * `update` stamps only `modifiedAt` and `modifiedBy`, and a `groupId` other than
209
+ * the session's own passes the set-group check or is refused. The session's
210
+ * whole identity reaches `doc.security.identity`; only the name and the ids
211
+ * reach the annotation.
212
+ */
213
+ declare function runAnnotationAttributionConformance(runner: ConformanceTestRunner, opts: AnnotationAttributionConformanceOptions): void;
214
+ //#endregion
215
+ //#region src/conformance/runAnnotationResourceConformance.d.ts
216
+ /**
217
+ * The documents the suite opens, each a fresh copy:
218
+ *
219
+ * - `authoring`: any document; stamps are created on its first page.
220
+ * - `acrobat-stamps`: `stamp-opacity-acrobat.pdf`
221
+ * (`packages/engine/main/test/fixtures`): two stamps Acrobat saved at about
222
+ * 30% opacity, each appearance `/R0 gs /MWFOForm Do` with /R0 repeating the
223
+ * stamp's /CA.
224
+ * - `acrobat-rewrapped`: `stamp-rewrapped-acrobat.pdf`, stamps as EmbedPDF
225
+ * writes them after other tools edited them: `rewrapped-a`, turned 30
226
+ * degrees and set to 60% in Acrobat, under Acrobat's layer and four forms
227
+ * that only draw our wrapper; `rewrapped-b`, set to 100% in Acrobat, under
228
+ * one such form; `rewrapped-c`, our 35% layer with /CA dropped, 300 x 120.
229
+ * Each draws a 200 x 100 drawing, opaque where it paints.
230
+ * - `acrobat-roundtrip-60`, `acrobat-roundtrip-100`:
231
+ * `stamp-roundtrip-acrobat-{60,100}.pdf`, an "Approved" stamp made in the
232
+ * viewer, turned and set to 40%, then set to 60% and to 100% in Acrobat
233
+ * 26.2. Acrobat moves the form around our wrapper by 0.0008 pt, its box a
234
+ * fraction off the origin in its own arithmetic.
235
+ */
236
+ type AnnotationResourceFixture = 'authoring' | 'acrobat-stamps' | 'acrobat-rewrapped' | 'acrobat-roundtrip-60' | 'acrobat-roundtrip-100';
237
+ interface AnnotationResourceConformanceOptions {
238
+ label: string;
239
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
240
+ makeEngine: () => Promise<Engine> | Engine;
241
+ /** Open a fresh copy of a fixture, with `doc.download` among its scopes. */
242
+ open: (engine: Engine, fixture: AnnotationResourceFixture) => Promise<DocumentHandle>;
243
+ /** Open a fresh copy of a fixture with `scope` only: the import's rights tests run with it. */
244
+ openScoped?: (engine: Engine, fixture: AnnotationResourceFixture, scope: readonly string[]) => Promise<DocumentHandle>;
245
+ }
246
+ /**
247
+ * Resources beside an annotation's data, on both engines: `downloadResource`
248
+ * returns what `create(data, resources)` needs to make the same annotation
249
+ * again. A stamp's appearance is its drawing without the fit, rotation and
250
+ * opacity its data describes; a stamp another tool made is drawn as shown,
251
+ * in its own box, without a layer that only repeats its /CA. Stamps with
252
+ * the same artwork place one drawing. The opacity is painted once:
253
+ * in a copy, after a resize, and after a change.
254
+ */
255
+ declare function runAnnotationResourceConformance(runner: ConformanceTestRunner, opts: AnnotationResourceConformanceOptions): void;
256
+ //#endregion
257
+ //#region src/conformance/runAnnotationExportConformance.d.ts
258
+ /**
259
+ * `doc.annotations.export` on both engines: the annotations as a raw read
260
+ * returns them, each resource once under its hash, the same bytes
261
+ * `downloadResource` returns, and a selection with what it points at and, by
262
+ * default, its threads.
263
+ */
264
+ declare function runAnnotationExportConformance(runner: ConformanceTestRunner, opts: AnnotationResourceConformanceOptions): void;
265
+ //#endregion
266
+ //#region src/conformance/runAnnotationImportConformance.d.ts
267
+ /**
268
+ * `doc.annotations.import` on both engines, in `stamp` mode: a bundle comes
269
+ * back as the export had it, one fact per annotation as one transaction,
270
+ * what can't be carried left out and reported, pages mapped, and a refusal
271
+ * before anything is written. An import is a change: undone and redone with
272
+ * `doc.apply({ undoOf })`, answered again on a retry, and a restoring
273
+ * import's undo takes the import's rights.
274
+ */
275
+ declare function runAnnotationImportConformance(runner: ConformanceTestRunner, opts: AnnotationResourceConformanceOptions): void;
276
+ //#endregion
277
+ //#region src/conformance/runAnnotationTransferConformance.d.ts
278
+ interface AnnotationTransferConformanceOptions {
279
+ label: string;
280
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
281
+ makeEngine: () => Promise<Engine> | Engine;
282
+ /**
283
+ * The documents to round-trip. `'authoring'` is a document without
284
+ * annotations, which the suite fills with one annotation of every kind a
285
+ * create makes, two stamps sharing a drawing, a named comment with its
286
+ * popup and a reply, and a link.
287
+ */
288
+ fixtures: readonly string[];
289
+ /** Open a fresh copy of a fixture, with every scope, `doc.annotate.import` included. */
290
+ open: (engine: Engine, fixture: string) => Promise<DocumentHandle>;
291
+ }
292
+ /**
293
+ * Check annotation transfer over every fixture on both engines. The source
294
+ * bundle is imported into a copy without annotations, then exported again:
295
+ *
296
+ * - The normalized exports agree after unsupported fields are dropped, and
297
+ * every resource has the same bytes under the same id. A copy is drawn from
298
+ * its data, as Acrobat's FDF and XFDF carry it: only a stamp carries its
299
+ * drawing. So where the data is points, the box is the frame of our
300
+ * drawing, which holds the points, and an icon's box is our icon at the
301
+ * same anchor;
302
+ * - Restored attribution is the source's, while stamped attribution is
303
+ * the session's;
304
+ * - Every page keeps the source bundle's annotation order;
305
+ * - Replies, popups, their parents and link destinations point at the copies;
306
+ * - A stamp draws as its source, and in our own file every kind does,
307
+ * an edge moved by a fraction of a pixel aside (Acrobat moves a stamp's
308
+ * form by a fraction of a point, which the drawing leaves out);
309
+ * - A second import names nothing twice and adds no drawing already present.
310
+ * Export golden files and forced-failure tests cover the remaining cases.
311
+ */
312
+ declare function runAnnotationTransferConformance(runner: ConformanceTestRunner, opts: AnnotationTransferConformanceOptions): void;
313
+ //#endregion
314
+ //#region src/conformance/creatables.d.ts
315
+ /** A create's two arguments. */
316
+ interface Creatable {
317
+ data: AnnotationDraft;
318
+ resources?: AnnotationResources;
319
+ }
320
+ /** A note's or a file's icon at its usual 20 × 20, by its top-left corner. */
321
+ declare function iconRect(x: number, y: number): PageBox;
322
+ /** One create for every kind the engine can create, inside a box near the page's top-left. */
323
+ declare function creatables(): Creatable[];
324
+ //#endregion
325
+ //#region src/conformance/runDateConformance.d.ts
326
+ interface DateConformanceOptions {
327
+ label: string;
328
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
329
+ makeEngine: () => Promise<Engine> | Engine;
330
+ /**
331
+ * Open a fresh copy of `dates.pdf` (`packages/engine/main/test/fixtures`):
332
+ * one page (object 3) whose squares carry known `/CreationDate` and `/M`
333
+ * values, a file attachment annotation and an embedded file whose
334
+ * `/Params` carry dates, and an Info dictionary with dates.
335
+ */
336
+ open: (engine: Engine) => Promise<DocumentHandle>;
337
+ }
338
+ /**
339
+ * Dates on both engines: a PDF date reads as ISO 8601 with the offset it was
340
+ * written with, a read written back is the same moment in the same zone, a
341
+ * write takes the string or a `Date`, and a date that isn't one reads `null`.
342
+ */
343
+ declare function runDateConformance(runner: ConformanceTestRunner, opts: DateConformanceOptions): void;
344
+ //#endregion
345
+ //#region src/conformance/runAnnotationDeclarationConformance.d.ts
346
+ interface AnnotationDeclarationFixture {
347
+ /** Stable id used for the local engine; cloud uses its own id. */
348
+ id: string;
349
+ /** Bytes for the local engine. */
350
+ bytes: () => Uint8Array | Promise<Uint8Array>;
351
+ /** Override the cloud-side id. Defaults to `id`. */
352
+ cloudId?: string;
353
+ }
354
+ interface AnnotationDeclarationConformanceOptions {
355
+ label: string;
356
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
357
+ makeEngine: () => Promise<Engine> | Engine;
358
+ /** Engine 'kind' for opening: 'bytes' for local, 'id' for cloud. */
359
+ openKind: 'bytes' | 'id';
360
+ /**
361
+ * A document without inline annotations. One annotation of every kind the
362
+ * engine can create is added to its first page, then read back.
363
+ */
364
+ authoring: AnnotationDeclarationFixture;
365
+ /** Documents whose annotations are read as they are. */
366
+ documents: readonly AnnotationDeclarationFixture[];
367
+ /** A document with a link whose target a write can't make (a script, a viewer command). */
368
+ readOnlyLink: AnnotationDeclarationFixture;
369
+ }
370
+ /**
371
+ * Every annotation both engines read, from real documents and freshly created
372
+ * ones, is checked against its kind declaration.
373
+ */
374
+ declare function runAnnotationDeclarationConformance(runner: ConformanceTestRunner, opts: AnnotationDeclarationConformanceOptions): void;
375
+ //#endregion
376
+ //#region src/conformance/annotationReadDrift.d.ts
377
+ /**
378
+ * Compares annotation reads with their kind declarations. Each difference is
379
+ * one line, `<field>: <problem> (<kinds>)`:
380
+ *
381
+ * - `missing`: the declaration has the field, the read doesn't;
382
+ * - `invalid`: the read has a value the declaration doesn't accept;
383
+ * - `undeclared`: the read has a field the declaration doesn't know.
384
+ *
385
+ * `<kinds>` is `every kind` when the difference holds for every kind read,
386
+ * otherwise the affected subtypes. Lines are sorted, so two engines reading
387
+ * the same documents produce the same list.
388
+ */
389
+ declare function annotationReadDriftOf(reads: readonly unknown[]): string[];
390
+ //#endregion
202
391
  //#region src/conformance/runFormConformance.d.ts
203
392
  /**
204
393
  * The three fixtures the forms suite needs. Shapes (names, object numbers,
@@ -210,7 +399,7 @@ declare function runAnnotationMutationConformance(runner: ConformanceTestRunner,
210
399
  * `opt_check` (/Opt "Alpha", on-state "On"), hierarchical text field
211
400
  * `billing.name`.
212
401
  * - `orphanWidgets` — orphan_widgets.pdf: `linked_text` in /AcroForm
213
- * /Fields plus RECOVERED `orphan_check` and `orphan_radio`.
402
+ * /Fields plus recovered `orphan_check` and `orphan_radio`.
214
403
  * - `choiceFields` — listbox_form.pdf: `Listbox_MultiSelect` (options
215
404
  * Apple..), `Listbox_SingleSelect`.
216
405
  */
@@ -228,6 +417,12 @@ interface FormConformanceFixtures {
228
417
  * same bytes under a suffixed id the way the bytes transport does.
229
418
  */
230
419
  importTarget?: ConformanceFixture;
420
+ /**
421
+ * Another independent copy of `toggleFields`, whose merged field/widgets
422
+ * the delete test removes. Required for `openKind: 'id'` (cloud): the
423
+ * deletes are durable server state the other tests must not see.
424
+ */
425
+ deleteTarget?: ConformanceFixture;
231
426
  }
232
427
  interface FormConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
233
428
  fixtures: FormConformanceFixtures;
@@ -239,7 +434,7 @@ declare function runFormConformance(runner: ConformanceTestRunner, opts: FormCon
239
434
  * Per-fixture knowledge for the annotation appearance conformance suite. The
240
435
  * harness asserts thresholds (not exact wire content) so the same suite runs
241
436
  * unchanged against the local and cloud engines and proves they emit the same
242
- * set of appearances — including weak (index-only) annotations.
437
+ * set of appearances, including those of annotations born inline in the file.
243
438
  */
244
439
  interface AnnotationAppearanceConformanceFixture extends ConformanceFixture {
245
440
  /** PDF object number of the page whose appearances are rendered. */
@@ -247,21 +442,14 @@ interface AnnotationAppearanceConformanceFixture extends ConformanceFixture {
247
442
  /** At least this many `/AP` appearances are expected on that page. */
248
443
  minAppearanceCount: number;
249
444
  /**
250
- * `true` when the page has at least one weak (index-only) annotation that
251
- * carries an appearance stream. The whole point of this suite: that weak
252
- * appearance must still be emitted (it used to be dropped on the wire).
445
+ * `true` when the page has at least one annotation born inline in the
446
+ * file (named by `baseIndex`) that carries an appearance stream: it must
447
+ * be emitted too, under that name.
253
448
  */
254
- expectsWeakAppearance: boolean;
449
+ expectsInlineAppearance: boolean;
255
450
  }
256
451
  interface AnnotationAppearanceConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
257
452
  fixture: AnnotationAppearanceConformanceFixture;
258
- /**
259
- * `true` for engines that expose the raw RGBA rasters (`renderAppearances`).
260
- * The local engine's encoder needs a browser Canvas, so under node it can
261
- * only be exercised via the raw rasters; the cloud engine ships encoded
262
- * images (`renderAppearanceImages`) and leaves this `false`.
263
- */
264
- supportsRawRasters?: boolean;
265
453
  }
266
454
  declare function runAnnotationAppearanceConformance(runner: ConformanceTestRunner, opts: AnnotationAppearanceConformanceOptions): void;
267
455
  //#endregion
@@ -273,43 +461,32 @@ declare function runAnnotationAppearanceConformance(runner: ConformanceTestRunne
273
461
  * harness can exercise reorder permutations meaningfully.
274
462
  */
275
463
  interface PageReorderConformanceFixture extends ConformanceFixture {
276
- /** Stable, durable PONs of (at least) three distinct pages. Order
464
+ /** Stable, durable page object numbers of (at least) three distinct pages. Order
277
465
  * here is the *intended caller-visible* order, not the on-disk
278
466
  * order; the suite reads `pages.list()` first and works in document
279
467
  * order. */
280
- ponsForReorderTest?: number[];
281
- /**
282
- * Page used for the weak-ref-survival assertion. Defaults to the
283
- * first PON in `ponsForReorderTest`. The fixture page must already
284
- * have at least one weak annotation (no /NM, direct object) so the
285
- * harness can capture an `index`-kind ref before the page move and
286
- * re-use it after.
287
- */
288
- weakRefHostPon?: number;
289
- /** Quad to use for the `create()` step that produces a stable ref
290
- * the suite uses. */
291
- createQuad?: HighlightDraft['quadPoints'];
468
+ pageObjectNumbersForReorderTest?: number[];
292
469
  }
293
470
  interface PageReorderConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
294
471
  fixture: PageReorderConformanceFixture;
295
472
  }
296
473
  /**
297
474
  * Page reorder conformance suite. Verifies the architectural invariants
298
- * locked with the user, do NOT loosen these without re-reading
299
- * `PageMoveResult` and `DocumentPagesMutator`:
475
+ * locked with the user, do not loosen these without re-reading
476
+ * `PageReorderResult` and `DocumentPagesMutator`:
300
477
  *
301
478
  * 1. `pages.list()` returns every page in display order, addressed
302
479
  * by indirect `pageObjectNumber`.
303
- * 2. `pages.move()` returns the full new order + geometry via
480
+ * 2. `pages.reorder()` puts the pages next to a neighbour (or at the start
481
+ * or end) and returns the full new order + geometry via
304
482
  * `result.layout` (the same shape `pages.list()` returns). There is
305
483
  * no document-level revision; the wire never asks the caller for one.
306
- * 3. Index-based annotation refs survive a page reorder. This is the
307
- * whole reason per-page revisions stay put across a move: a user
308
- * shuffling pages mid-edit must not lose a pending highlight. (The
309
- * "move never bumps a RevisionToken" invariant is asserted directly
310
- * in the annotation mutation suite, where revision liveness lives.)
311
- * 4. Invalid inputs (duplicate PONs, unknown PONs, out-of-range
312
- * `destIndex`) reject with `InvalidArg`.
484
+ * 3. Annotation names survive a page reorder: a user shuffling pages
485
+ * mid-edit must not lose a pending highlight, so a `baseIndex` ref
486
+ * captured before the reorder works after it.
487
+ * 4. A page named twice, or a neighbour that is one of the moved pages,
488
+ * rejects with `InvalidArg`; an unknown page or neighbour with
489
+ * `NotFound`.
313
490
  * 5. Abort propagates as `AbortError`.
314
491
  *
315
492
  * Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
@@ -320,17 +497,17 @@ declare function runPageReorderConformance(runner: ConformanceTestRunner, opts:
320
497
  //#region src/conformance/runPageRotateConformance.d.ts
321
498
  /**
322
499
  * Page rotate conformance suite. Verifies the architectural invariants —
323
- * do NOT loosen these without re-reading `PageRotateResult`:
500
+ * do not loosen these without re-reading `PageRotateResult`:
324
501
  *
325
- * 1. Rotation is ABSOLUTE and idempotent: `rotate(pons, 90)` twice is
502
+ * 1. Rotation is absolute and idempotent: `rotate(pons, 90)` twice is
326
503
  * `rotate(pons, 90)` once. The wire never speaks "turn by".
327
- * 2. Rotation is presentation metadata over NORMALIZED content: the
504
+ * 2. Rotation is presentation metadata over normalized content: the
328
505
  * layout's `width`/`height` stay un-rotated, order and identity are
329
- * untouched, and per-page `RevisionToken`s survive (an index-based
330
- * annotation ref captured before the rotate works after it).
506
+ * untouched, and annotation names survive (a `baseIndex` ref captured
507
+ * before the rotate works after it).
331
508
  * 3. The result returns the full new `layout`; a subsequent `list()`
332
509
  * agrees with it.
333
- * 4. Invalid inputs (bad rotation value, duplicate PONs, unknown PONs)
510
+ * 4. Invalid inputs (bad rotation value, duplicate page object numbers, unknown page object numbers)
334
511
  * reject with `InvalidArg` / `NotFound`.
335
512
  * 5. Abort propagates as `AbortError`.
336
513
  *
@@ -339,20 +516,301 @@ declare function runPageReorderConformance(runner: ConformanceTestRunner, opts:
339
516
  */
340
517
  declare function runPageRotateConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
341
518
  //#endregion
519
+ //#region src/conformance/runAnnotationRotationConformance.d.ts
520
+ type AnnotationRotationFixture =
521
+ /** A one-page document without annotations. */
522
+ 'authoring' |
523
+ /** A stamp Acrobat turned 36° clockwise: `/Rotate -36`, the turn in its appearance. */
524
+ 'acrobat-stamp-rotated' |
525
+ /** A text box Acrobat added on a turned page (`/Rotate 90`), and one upright. */
526
+ 'acrobat-freetext-rotated';
527
+ interface AnnotationRotationConformanceOptions {
528
+ label: string;
529
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
530
+ makeEngine: () => Promise<Engine> | Engine;
531
+ /** Open a fresh copy of a fixture. */
532
+ open: (engine: Engine, fixture: AnnotationRotationFixture) => Promise<DocumentHandle>;
533
+ }
534
+ /**
535
+ * An annotation's `rotation` is degrees clockwise, as every rotation in the
536
+ * API, on both engines. What's drawn decides it: a turn another app made
537
+ * (Acrobat's `/Rotate` stamps and quarter-turned text boxes) reads as ours
538
+ * does, with the `box` the drawing turns, and a write keeps it. A turned
539
+ * box's `rect` is the upright box around all it draws, which the engine
540
+ * works out.
541
+ */
542
+ declare function runAnnotationRotationConformance(runner: ConformanceTestRunner, opts: AnnotationRotationConformanceOptions): void;
543
+ //#endregion
544
+ //#region src/conformance/runPageRenderConformance.d.ts
545
+ /**
546
+ * A 600 × 800 page cropped to [100 200 500 600], so its visible area does
547
+ * not start at 0,0, with a black square at 200..300 × 300..400 in file
548
+ * coordinates (the coordinates annotation rects use).
549
+ */
550
+ declare const CROP_OFFSET_PDF: Uint8Array<ArrayBufferLike>;
551
+ interface PageRenderConformanceOptions {
552
+ label: string;
553
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
554
+ makeEngine: () => Promise<Engine> | Engine;
555
+ /** Open a fresh copy of {@link CROP_OFFSET_PDF}. */
556
+ open: (engine: Engine) => Promise<DocumentHandle>;
557
+ }
558
+ /**
559
+ * Page images on both engines: an image reports the size of its pixels and
560
+ * where they are on the page (its transform, the one `pageTransform` gives
561
+ * without rendering), a target rect is in page space like every other place
562
+ * (so a page whose crop box doesn't start at 0,0 renders the area asked
563
+ * for), `blob()` is the image's bytes, and quality goes from 0 to 1.
564
+ */
565
+ declare function runPageRenderConformance(runner: ConformanceTestRunner, opts: PageRenderConformanceOptions): void;
566
+ //#endregion
567
+ //#region src/conformance/runPrintRenderConformance.d.ts
568
+ /**
569
+ * A 200 × 200 page with one black 40 × 40 square for each print rule, and an
570
+ * A0 page (2384 × 3370) with nothing on it:
571
+ *
572
+ * - a layer that only prints, and one only shown on screen (`/Usage`
573
+ * `/PrintState` and `/ViewState`, as Acrobat's watermarks write them);
574
+ * - four squares: one that only prints (`noView` + `print`), one only on
575
+ * screen (no `print`), one on both (`print`), one on neither (`hidden`);
576
+ * - two form fields: a push button only on screen (Acrobat's "Visible but
577
+ * doesn't print") and a text field that only prints ("Hidden but
578
+ * printable").
579
+ */
580
+ declare const PRINT_RULES_PDF: Uint8Array<ArrayBufferLike>;
581
+ /** The rights each case opens with: everything, no print, print but not high. */
582
+ declare const PRINT_SCOPES: {
583
+ readonly everything: readonly ["*"];
584
+ readonly screen: readonly ["doc.open", "doc.render", "doc.annotate.read", "doc.forms.read"];
585
+ readonly print: readonly ["doc.open", "doc.render", "doc.annotate.read", "doc.forms.read", "doc.print"];
586
+ };
587
+ interface PrintRenderConformanceOptions {
588
+ label: string;
589
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
590
+ makeEngine: () => Promise<Engine> | Engine;
591
+ /** Open a fresh copy of {@link PRINT_RULES_PDF} with `scope`. */
592
+ open: (engine: Engine, scope: readonly string[]) => Promise<DocumentHandle>;
593
+ }
594
+ /**
595
+ * Print pictures on both engines (`usage: 'print'` with a `dpi` viewport).
596
+ * A print picture follows
597
+ * the print rules where a screen picture follows the screen's: layers by
598
+ * their print state, annotations and form fields by their `print` flag,
599
+ * `noView` ones included, `hidden` ones never. It is the whole page at its
600
+ * DPI, never more pixels than the page fitted to A4 or Letter needs, and its
601
+ * transform is `pageTransform`'s. It needs `doc.print`, and 300 DPI
602
+ * `doc.print.high`; options that don't fit a print picture are refused.
603
+ */
604
+ declare function runPrintRenderConformance(runner: ConformanceTestRunner, opts: PrintRenderConformanceOptions): void;
605
+ /**
606
+ * The print copy on both engines: `pages.extract(pages, { flatten })` makes
607
+ * the pages as they draw for `flatten.usage`, so a print copy, printed, shows
608
+ * what a print picture of the page shows (layers by their print state,
609
+ * annotations and fields by their `print` flag), with nothing interactive
610
+ * left. `includeAnnotations` and `includeFormFields` choose what it paints,
611
+ * with a page picture's defaults; they take `flatten`. A flattened copy needs
612
+ * `doc.download` or `doc.download.flattened`, a plain one `doc.download`.
613
+ */
614
+ interface PrintCopyConformanceOptions extends PrintRenderConformanceOptions {
615
+ /** Open `bytes`, a copy the engine made, with every right. */
616
+ openCopy: (engine: Engine, bytes: Uint8Array) => Promise<DocumentHandle>;
617
+ }
618
+ declare function runPrintCopyConformance(runner: ConformanceTestRunner, opts: PrintCopyConformanceOptions): void;
619
+ //#endregion
620
+ //#region src/conformance/pageSpaceFixtures.d.ts
621
+ /**
622
+ * Small PDFs whose page boxes are odd in every way ISO 32000 allows, and in
623
+ * the ways broken files are odd, each with its answer written out by hand:
624
+ * the visible page box, the five boxes, the turn and the unit size. The
625
+ * answers come from the standard, never from our code, so a check against
626
+ * them is a check of our code:
627
+ * - ISO 32000-1 Table 30 and §7.7.3.4: which boxes a page inherits;
628
+ * - ISO 32000-1 §7.9.5: a box's corners in any order;
629
+ * - ISO 32000-1 §14.11.2: the defaults, and every box inside the media box.
630
+ * For broken files the standard has no answer; those carry our rule and say
631
+ * so.
632
+ *
633
+ * Each page draws black squares (`marks`) and words at known places in file
634
+ * coordinates, so a render shows where the page's corner really is.
635
+ */
636
+ /** A word drawn in Helvetica, its baseline starting at `x, y` (file coordinates). */
637
+ interface PageSpaceWord {
638
+ text: string;
639
+ x: number;
640
+ y: number;
641
+ size: number;
642
+ }
643
+ /** A destination: a spot on a page of the same file, as the file writes it, with its answer. */
644
+ interface PageSpaceGoTo {
645
+ /** The index of the page it goes to. */
646
+ toPage: number;
647
+ /** The destination array after the page reference, as the file writes it. */
648
+ view: string;
649
+ /**
650
+ * The destination measured from the top-left of the target page's visible
651
+ * box (x from its left edge, y from its top edge); `null` keeps the current
652
+ * value.
653
+ */
654
+ expected: {
655
+ kind: 'xyz' | 'fitH' | 'fitV' | 'fitR';
656
+ x?: number | null;
657
+ y?: number | null;
658
+ width?: number;
659
+ height?: number;
660
+ };
661
+ }
662
+ /** A link on a page to a spot on another page of the same file. */
663
+ interface PageSpaceLink extends PageSpaceGoTo {
664
+ /** Where the link sits, in file coordinates. */
665
+ rect: PdfRect;
666
+ }
667
+ interface PageSpaceBoxes {
668
+ media: PdfRect;
669
+ crop: PdfRect;
670
+ bleed: PdfRect;
671
+ trim: PdfRect;
672
+ art: PdfRect;
673
+ }
674
+ interface PageSpaceFixturePage {
675
+ /** The page dictionary's own entries: boxes, `/Rotate`, `/UserUnit`. */
676
+ entries: string;
677
+ marks: PdfRect[];
678
+ words: PageSpaceWord[];
679
+ links?: PageSpaceLink[];
680
+ /** The page's open action (`/AA /O`): a go-to. */
681
+ openAction?: PageSpaceGoTo;
682
+ expected: {
683
+ /** The visible page box: what the page shows, in file coordinates. */
684
+ visible: PdfRect;
685
+ /** The five boxes as ISO defines them: defaults applied, reduced to the media box. */
686
+ boxes: PageSpaceBoxes;
687
+ rotation: PdfRotation;
688
+ userUnit: number;
689
+ /** The order its annotations take focus in (`/Tabs`); none when the page sets none. */
690
+ tabOrder?: PageTabOrder;
691
+ };
692
+ }
693
+ interface PageSpaceFixture {
694
+ name: string;
695
+ /** The rule the fixture checks. */
696
+ about: string;
697
+ /**
698
+ * `iso`: the answers are the standard's. `recovery`: the file is broken and
699
+ * the answers are our rule, which is what Acrobat shows.
700
+ */
701
+ source: 'iso' | 'recovery';
702
+ /** Entries of the page tree node, inherited by pages that don't set them. */
703
+ treeEntries?: string;
704
+ /** The catalog's `/OpenAction` as a destination: where the document opens. */
705
+ openDestination?: PageSpaceGoTo;
706
+ /** A text field on the first page whose calculate script goes on (`/Next`) to a destination. */
707
+ fieldAction?: PageSpaceGoTo;
708
+ pages: PageSpaceFixturePage[];
709
+ bytes: Uint8Array;
710
+ }
711
+ declare const PAGE_SPACE_FIXTURES: readonly PageSpaceFixture[];
712
+ //#endregion
713
+ //#region src/conformance/runPageSpaceConformance.d.ts
714
+ interface PageSpaceConformanceOptions {
715
+ label: string;
716
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
717
+ makeEngine: () => Promise<Engine> | Engine;
718
+ /** Open a fresh copy of `fixture`. */
719
+ open: (engine: Engine, fixture: PageSpaceFixture) => Promise<DocumentHandle>;
720
+ /** Only these fixtures (by name); all when left out. */
721
+ only?: readonly string[];
722
+ }
723
+ /**
724
+ * Where things really are on a page, checked against what the renderer
725
+ * draws. An unturned render starts at the top-left of the visible page, so a
726
+ * position measured from there, times the scale, is a pixel. The fixtures
727
+ * write their answers out by hand from ISO 32000; this suite converts the
728
+ * engine's values with those answers, never with engine code, so it checks
729
+ * the engine's boxes, the renderer and every position the API returns.
730
+ */
731
+ declare function runPageSpaceConformance(runner: ConformanceTestRunner, opts: PageSpaceConformanceOptions): void;
732
+ //#endregion
733
+ //#region src/conformance/runColorConformance.d.ts
734
+ /**
735
+ * One page with a square whose border color the file stores as gray
736
+ * (`/C [0.5]`) and whose fill it stores as CMYK (`/IC [0 0 0 1]`).
737
+ */
738
+ declare const COLOR_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
739
+ interface ColorConformanceOptions {
740
+ label: string;
741
+ makeEngine: () => Promise<Engine> | Engine;
742
+ /** Open {@link COLOR_FIXTURE_PDF}, fresh for each call. */
743
+ open: (engine: Engine) => Promise<DocumentHandle>;
744
+ }
745
+ /**
746
+ * Colors are `'#rrggbb'`: lowercase when the engine gives one, either case
747
+ * when it takes one. A gray or CMYK color reads as its sRGB equivalent and,
748
+ * sent back unchanged, stays as the file stores it.
749
+ */
750
+ declare function runColorConformance(runner: ConformanceTestRunner, opts: ColorConformanceOptions): void;
751
+ //#endregion
752
+ //#region src/conformance/runAppearanceStatesConformance.d.ts
753
+ /**
754
+ * One 200 × 200 page with a check box that is off and stores every mode:
755
+ * normal Yes red and Off green, down Yes blue and Off yellow, rollover Yes
756
+ * black. Beside it, a square whose normal appearance is one stream (cyan).
757
+ * Each appearance fills its box, so a picture's middle names its state.
758
+ */
759
+ declare const APPEARANCE_STATES_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
760
+ interface AppearanceStatesConformanceOptions {
761
+ label: string;
762
+ makeEngine: () => Promise<Engine> | Engine;
763
+ /** Open {@link APPEARANCE_STATES_FIXTURE_PDF}, fresh for each call. */
764
+ open: (engine: Engine) => Promise<DocumentHandle>;
765
+ }
766
+ /**
767
+ * Appearance states and modes, and form fields in page renders, the same on
768
+ * every engine. A page's appearance batch holds every appearance an
769
+ * annotation stores: each mode it has, and every state of each mode, each
770
+ * image labelled with both, whatever `/AS` says. The annotation's
771
+ * `appearanceState` says which state it shows. Each family has its own
772
+ * batch: `page.annotations` the square's, `page.forms` the check box's, and
773
+ * neither holds the other's. A page picture draws what its two options ask
774
+ * for, the annotations and the form fields, each without the other.
775
+ */
776
+ declare function runAppearanceStatesConformance(runner: ConformanceTestRunner, opts: AppearanceStatesConformanceOptions): void;
777
+ //#endregion
778
+ //#region src/conformance/runDrawingDetailsConformance.d.ts
779
+ /**
780
+ * One 300 × 300 page with what other apps write and the engine only reads:
781
+ * a typewriter box (`/IT /FreeTextTypeWriter`) and a square with a beveled
782
+ * border.
783
+ */
784
+ declare const DRAWING_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
785
+ /** The fixtures the suite opens: its own, and Acrobat's text boxes (`freetext-rotated-acrobat.pdf`). */
786
+ type DrawingDetailsFixture = 'drawing' | 'acrobat-freetext';
787
+ interface DrawingDetailsConformanceOptions {
788
+ label: string;
789
+ makeEngine: () => Promise<Engine> | Engine;
790
+ /** A fresh copy of `fixture` for each call: the tests write to their documents. */
791
+ open: (engine: Engine, fixture: DrawingDetailsFixture) => Promise<DocumentHandle>;
792
+ }
793
+ /**
794
+ * How annotations draw and what a write takes: free text colors and
795
+ * defaults, dashes, the points a shape needs, printing, a note's `open` and
796
+ * its popup, and links.
797
+ */
798
+ declare function runDrawingDetailsConformance(runner: ConformanceTestRunner, opts: DrawingDetailsConformanceOptions): void;
799
+ //#endregion
342
800
  //#region src/conformance/runPageDeleteConformance.d.ts
343
801
  /**
344
802
  * Page delete conformance suite. Verifies the architectural invariants —
345
- * do NOT loosen these without re-reading `PageDeleteResult`:
803
+ * do not loosen these without re-reading `PageDeleteResult`:
346
804
  *
347
805
  * 1. `pages.delete()` removes exactly the listed pages and returns the
348
806
  * full surviving layout; a subsequent `list()` agrees.
349
- * 2. Deleted PONs are RETIRED: addressing a deleted page afterwards is a
807
+ * 2. Deleted page object numbers are retired: addressing a deleted page afterwards is a
350
808
  * clean `NotFound` (an API-level error, never native-memory danger).
351
- * 3. SURVIVING pages keep identity and `RevisionToken`s — an index-based
352
- * annotation ref on an unrelated page survives a neighbour's deletion.
809
+ * 3. Surviving pages keep identity, and their annotations keep their
810
+ * names — a `baseIndex` ref survives a neighbour's deletion.
353
811
  * 4. Deleting every page is rejected (`InvalidArg`) — a document keeps at
354
812
  * least one page.
355
- * 5. Duplicate / unknown PONs reject with `InvalidArg` / `NotFound`;
813
+ * 5. Duplicate / unknown page object numbers reject with `InvalidArg` / `NotFound`;
356
814
  * abort propagates as `AbortError`.
357
815
  *
358
816
  * Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
@@ -362,7 +820,7 @@ declare function runPageDeleteConformance(runner: ConformanceTestRunner, opts: C
362
820
  //#endregion
363
821
  //#region src/conformance/runNamedPagesConformance.d.ts
364
822
  /**
365
- * Named-pages conformance: the catalog's `/Names /Pages` registry as LAYOUT
823
+ * Named-pages conformance: the catalog's `/Names /Pages` registry as layout
366
824
  * data. Locks the invariants both engines must share — do not loosen
367
825
  * without re-reading `NamedPageEntry` and `PageNameResult`:
368
826
  *
@@ -370,7 +828,7 @@ declare function runPageDeleteConformance(runner: ConformanceTestRunner, opts: C
370
828
  * registration resolves to a page in `pages`, a template, or is
371
829
  * reported dangling — never silently dropped.
372
830
  * 2. `pages.setName()` creates or replaces by decoded key (idempotent),
373
- * `replace` renames in one job, and the result IS the new layout.
831
+ * `replace` renames in one job, and the result is the new layout.
374
832
  * 3. `pages.removeName()` drops the registration and nothing else.
375
833
  * 4. Deleting a page removes every registration pointing at it — inside
376
834
  * the delete, with no plugin in the loop.
@@ -397,7 +855,7 @@ declare function runAnnotationFlattenConformance(runner: ConformanceTestRunner,
397
855
  //#region src/conformance/runAnnotationAppearanceExportConformance.d.ts
398
856
  /**
399
857
  * `page(pon).annotations.exportAppearance(refs)`: the chosen annotations'
400
- * appearances as ONE single-page PDF sized to their union /Rect. Locks:
858
+ * appearances as one single-page PDF sized to their union /Rect. Locks:
401
859
  * 1. bytes are a PDF; the source page is untouched (no mutation, no
402
860
  * revision bump);
403
861
  * 2. re-opened (local engines), the page is exactly the union size and the
@@ -412,30 +870,39 @@ declare function runAnnotationAppearanceExportConformance(runner: ConformanceTes
412
870
  declare function runPageFlattenConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
413
871
  //#endregion
414
872
  //#region src/conformance/runRedactionApplyConformance.d.ts
873
+ /**
874
+ * One 300-point page with neither /Contents nor /Resources, as some
875
+ * generators write a blank page.
876
+ */
877
+ declare const BARE_PAGE_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
878
+ interface RedactionApplyConformanceOptions extends ConformanceOptions {
879
+ /** Open {@link BARE_PAGE_FIXTURE_PDF}, fresh for each call, with write access. */
880
+ openBarePage: (engine: Engine) => Promise<DocumentHandle>;
881
+ }
415
882
  /**
416
883
  * Transport-neutral coverage for the destructive redaction-apply rail.
417
- * Runs against a fixture page with NO pre-existing annotations so the
884
+ * Runs against a fixture page with no pre-existing annotations so the
418
885
  * collateral counts are exact. Content-removal fidelity itself is pinned by
419
886
  * the native embeddertests; this suite pins the transport contract: scopes,
420
- * statuses, counts, revision bumps, events, and preflight rejection.
887
+ * statuses, counts, affected pages, events, and preflight rejection.
421
888
  */
422
- declare function runRedactionApplyConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
889
+ declare function runRedactionApplyConformance(runner: ConformanceTestRunner, opts: RedactionApplyConformanceOptions): void;
423
890
  //#endregion
424
891
  //#region src/conformance/runPageExtractConformance.d.ts
425
892
  /**
426
- * Page extract conformance suite. `pages.extract?` is OPTIONAL on the
893
+ * Page extract conformance suite. `pages.extract?` is optional on the
427
894
  * contract (the `downloadLayer?` pattern) — the suite runs only when the
428
895
  * implementation provides it, so a cloud engine that has not shipped the
429
896
  * server endpoint yet skips cleanly instead of failing.
430
897
  *
431
898
  * Invariants:
432
899
  * 1. `pages.extract([pon])` returns standalone PDF bytes (magic header).
433
- * 2. The SOURCE document is untouched: identical layout before/after,
900
+ * 2. The source document is untouched: identical layout before/after,
434
901
  * and page revisions do not bump (extract is a read).
435
902
  * 3. Caller order is preserved and page geometry survives the copy
436
903
  * (asserted by re-opening the extracted bytes — bytes-open engines
437
904
  * only, since a cloud engine cannot re-open loose bytes).
438
- * 4. Empty / duplicate PONs reject `InvalidArg`; unknown PONs reject
905
+ * 4. Empty / duplicate page object numbers reject `InvalidArg`; unknown page object numbers reject
439
906
  * `NotFound` (or `InvalidArg`); abort propagates as `AbortError`.
440
907
  */
441
908
  declare function runPageExtractConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
@@ -443,98 +910,392 @@ declare function runPageExtractConformance(runner: ConformanceTestRunner, opts:
443
910
  //#region src/conformance/runAttachmentConformance.d.ts
444
911
  /**
445
912
  * Attachment conformance suite. Fixture requirement: a document whose
446
- * `/EmbeddedFiles` name tree contains AT LEAST ONE embedded file.
913
+ * `/EmbeddedFiles` name tree contains at least one embedded file.
447
914
  *
448
- * Both attachment surfaces are OPTIONAL on the contract (the
449
- * `downloadLayer?` pattern), probed independently and skipped cleanly:
450
- * - `doc.attachments?` — document-level EmbeddedFiles (list/download)
451
- * - `page.annotations.downloadFile?` — annotation-level file bytes
915
+ * Both homes of a file: `doc.attachments` (the `/EmbeddedFiles` name tree)
916
+ * and a file-attachment annotation's `file` resource
917
+ * (`page.annotations.downloadResource(ref, 'file')`). Both downloads answer
918
+ * the bytes; the name and type are what the listing says.
452
919
  *
453
920
  * Invariants:
454
921
  * 1. `list()` reflects the name tree: positional indices, non-empty
455
922
  * names, and repeated calls agree (a read).
456
- * 2. `download(index)` round-trips the listed metadata and returns
457
- * exactly `size` decoded bytes when the fixture declares one.
458
- * 3. Unknown indices reject with an `EngineError`.
923
+ * 2. `download(ref)` returns exactly `size` decoded bytes when the
924
+ * fixture declares one.
925
+ * 3. Unknown keys reject with an `EngineError`.
459
926
  * 4. A created file-attachment annotation round-trips its file:
460
927
  * metadata inline on the DTO (never bytes), bytes byte-identical
461
- * through `downloadFile(ref)`.
928
+ * as its `file` resource.
462
929
  * 5. A created text (sticky-note) annotation round-trips icon + color.
463
930
  */
464
931
  declare function runAttachmentConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
465
932
  //#endregion
466
933
  //#region src/conformance/runPageInsertConformance.d.ts
467
- /**
468
- * Page insert conformance. `pages.insert` is a REQUIRED member — this suite
469
- * runs unconditionally on every engine, so an implementation that loses the
470
- * verb fails loudly instead of being skipped past.
471
- *
472
- * Invariants:
473
- * 1. Every page of the source bytes is COPIED in at `destIndex` (omitted →
474
- * append), in source order; the result lists the fresh PONs in
475
- * insertion order and they agree with the returned layout.
476
- * 2. Pre-existing pages keep their identity: same PONs before and after,
477
- * in the expected positions (an insert never invalidates neighbours).
478
- * 3. The mutation persists through save → re-open (bytes engines only).
479
- * 4. Empty bytes / malformed bytes / out-of-range destIndex reject with
480
- * InvalidArg / MalformedPdf, leaving the document untouched.
481
- */
482
934
  declare function runPageInsertConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
483
935
  //#endregion
484
936
  //#region src/conformance/runPageInsertBlankConformance.d.ts
485
937
  /**
486
- * Blank-page insert conformance. `pages.insertBlank` is a REQUIRED member —
938
+ * Blank-page insert conformance. `pages.insertBlank` is a required member —
487
939
  * the suite runs unconditionally on every engine (no fixture bytes are
488
940
  * needed at all, which is the point of the verb), so an implementation that
489
941
  * loses the verb fails loudly instead of being skipped past.
490
942
  *
491
943
  * Invariants:
492
- * 1. `count` blank pages of exactly `size` appear at `destIndex` (omitted
493
- * → append), rotation 0; the result lists their fresh PONs in insertion
944
+ * 1. `count` blank pages of exactly `size` appear at `toIndex` (omitted
945
+ * → append), rotation 0; the result lists their fresh page object numbers in insertion
494
946
  * order and they agree with the returned layout.
495
- * 2. Pre-existing pages keep their identity: same PONs before and after,
947
+ * 2. Pre-existing pages keep their identity: same page object numbers before and after,
496
948
  * in the expected positions (an insert never invalidates neighbours).
497
949
  * 3. The mutation persists through save → re-open (bytes engines only).
498
950
  * 4. Non-positive size / count outside [1, PAGE_INSERT_BLANK_MAX_COUNT] /
499
- * out-of-range destIndex reject with InvalidArg, leaving the document
951
+ * out-of-range toIndex reject with InvalidArg, leaving the document
500
952
  * untouched.
501
953
  */
502
954
  declare function runPageInsertBlankConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
503
955
  //#endregion
956
+ //#region src/conformance/runObjectNumberConformance.d.ts
957
+ /**
958
+ * Two pages and a form. The first page holds a merged text field and widget
959
+ * (object 5, `merged`), the second nothing.
960
+ */
961
+ declare const OBJECT_NUMBER_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
962
+ interface ObjectNumberConformanceOptions {
963
+ label: string;
964
+ makeEngine: () => Promise<Engine> | Engine;
965
+ /** Open {@link OBJECT_NUMBER_FIXTURE_PDF}, fresh for each call, with write access. */
966
+ open: (engine: Engine) => Promise<DocumentHandle>;
967
+ }
968
+ /**
969
+ * Names at birth, and the order and ids of writes:
970
+ *
971
+ * - A create that names an object number from the document's pool makes its
972
+ * object at exactly that number, so its ref is known before the engine
973
+ * answers; what the engine makes for itself lands elsewhere.
974
+ * - A number the session doesn't hold is refused `not-held`; one a call uses
975
+ * twice is `taken`. A refused call changes nothing.
976
+ * - Writes made without waiting apply in the order they were made: a page
977
+ * named at birth takes an annotation at once.
978
+ * - Every event of a write carries its `opId` as `origin.tx`.
979
+ */
980
+ declare function runObjectNumberConformance(runner: ConformanceTestRunner, opts: ObjectNumberConformanceOptions): void;
981
+ //#endregion
982
+ //#region src/conformance/runChangeConformance.d.ts
983
+ /**
984
+ * Two pages and a form. The first page holds, from the file: a blue square
985
+ * by Ann (object 5); Ann's note (6) with its popup (7) and Bea's reply to it
986
+ * (8); and a merged text field and widget `name` with the value `Ann` (9).
987
+ * The second page is empty. Both share an empty content stream (10).
988
+ */
989
+ declare const CHANGE_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
990
+ interface ChangeConformanceOptions {
991
+ label: string;
992
+ makeEngine: () => Promise<Engine> | Engine;
993
+ /** Open {@link CHANGE_FIXTURE_PDF}, fresh for each call, with write access. */
994
+ open: (engine: Engine) => Promise<DocumentHandle>;
995
+ /**
996
+ * Open the document `doc` is on as another user, with write access. A local
997
+ * session has one user, so without it the test of who may undo is skipped.
998
+ */
999
+ openAsAnotherUser?: (engine: Engine, doc: DocumentHandle) => Promise<DocumentHandle>;
1000
+ }
1001
+ /**
1002
+ * `doc.apply`, one user action as one change:
1003
+ *
1004
+ * - The ops apply in order, all or none, as one write: one `opId`, one burst
1005
+ * of events sharing it. Later ops name what earlier ones create, by the
1006
+ * numbers the creates were given.
1007
+ * - `{ undoOf }` reverses a change as the engine recorded it, op by op in
1008
+ * reverse order, where the document still shows what the change set; what
1009
+ * it leaves alone is reported as `skipped`. Every op type round-trips:
1010
+ * undo gives exactly the state before, the undo's undo the state after.
1011
+ * - A deleted annotation comes back as the same objects, with the layer's
1012
+ * edits, its popup and its replies.
1013
+ * - `expect` refuses a change whose assumption doesn't hold.
1014
+ * - Every answer is kept under its `opId`, refusals included: asking again
1015
+ * answers the same, and a different change under it is refused.
1016
+ * - A redaction apply ends undo for the changes before it.
1017
+ */
1018
+ declare function runChangeConformance(runner: ConformanceTestRunner, opts: ChangeConformanceOptions): void;
1019
+ //#endregion
1020
+ //#region src/conformance/pdfOf.d.ts
1021
+ /** A PDF file of `objects`, numbered from 1, with its cross-reference table. */
1022
+ declare function pdfOf(objects: readonly string[]): Uint8Array;
1023
+ //#endregion
1024
+ //#region src/conformance/runOutlineConformance.d.ts
1025
+ /**
1026
+ * Two pages of 300 × 300 and an outline, five items showing when it opens:
1027
+ *
1028
+ * - A (6), open: to page 3 at (20, 280) in the file; its child A1 (10) fits page 4.
1029
+ * - B (7): red and bold, a URI action.
1030
+ * - C (8), closed: the named destination `chapter-two` (page 4, `/FitH` 250);
1031
+ * its child C1 (11) goes nowhere.
1032
+ * - D (9): a JavaScript action.
1033
+ */
1034
+ declare const OUTLINE_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
1035
+ /**
1036
+ * An outline a write never made: One (4) and Two (5), whose `/Next` comes
1037
+ * back to One, and after One a direct item no one can name.
1038
+ */
1039
+ declare const BROKEN_OUTLINE_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
1040
+ interface OutlineConformanceOptions {
1041
+ label: string;
1042
+ makeEngine: () => Promise<Engine> | Engine;
1043
+ /** Open `bytes`, one of the fixtures here, fresh for each call, with write access. */
1044
+ open: (engine: Engine, bytes: Uint8Array) => Promise<DocumentHandle>;
1045
+ /** Open `bytes` with the rights to open and read it only (`doc.open`, `doc.render`). */
1046
+ openReadOnly: (engine: Engine, bytes: Uint8Array) => Promise<DocumentHandle>;
1047
+ }
1048
+ /**
1049
+ * The document's outline (`doc.outline`), the same on every engine:
1050
+ *
1051
+ * - A read lists every item depth first, with its parent, its target read the
1052
+ * way a link's is (in page space, a named destination resolved), its `/A`
1053
+ * tree, its colour and style, and whether it opens.
1054
+ * - Writes name items by object number and places by neighbour; moves keep
1055
+ * subtrees and numbers; deletes take the items under an item with it, and
1056
+ * an undo brings the same items back.
1057
+ * - Each write publishes its `outline.*` event; without `doc.outline.modify`
1058
+ * every write is refused and reading still works.
1059
+ * - A target reads the same however the file stores it: written into the
1060
+ * item or shared, named in the `/Names` tree or the old `/Dests`, a page
1061
+ * by index. A new target or an undo never changes an action an item shares.
1062
+ * - A broken outline reads what it can and says `incomplete`.
1063
+ */
1064
+ declare function runOutlineConformance(runner: ConformanceTestRunner, opts: OutlineConformanceOptions): void;
1065
+ //#endregion
1066
+ //#region src/conformance/runPermissionConformance.d.ts
1067
+ /**
1068
+ * The two read families, through three tokens: one that may do everything,
1069
+ * one that may only fill the form, one that may only comment. Each token
1070
+ * reads, sees and writes its own family, and is refused the other one, on
1071
+ * every surface: the lists, the appearance images, the page pictures, the
1072
+ * writes, and (on an engine where sessions share a document) the events of
1073
+ * another session's writes. A widget is the form's: the annotation verbs
1074
+ * refuse one as the wrong family (`InvalidArg`), whatever the token.
1075
+ *
1076
+ * It runs on {@link CHANGE_FIXTURE_PDF}: a square (5), a note (6) with its
1077
+ * popup (7) and a reply (8), and the text field `name`, merged with its
1078
+ * widget (9), all on the first page.
1079
+ */
1080
+ declare const PERMISSION_TOKENS: {
1081
+ readonly everything: readonly ["*"];
1082
+ readonly fill: readonly ["doc.open", "doc.render", "doc.forms.fill"];
1083
+ readonly comment: readonly ["doc.open", "doc.render", "doc.annotate.modify"];
1084
+ };
1085
+ type PermissionToken = keyof typeof PERMISSION_TOKENS;
1086
+ interface PermissionConformanceOptions {
1087
+ label: string;
1088
+ makeEngine: () => Promise<Engine> | Engine;
1089
+ /** Open a fresh copy of {@link CHANGE_FIXTURE_PDF} with `scope`. */
1090
+ open: (engine: Engine, scope: readonly string[]) => Promise<DocumentHandle>;
1091
+ /**
1092
+ * Open the document `doc` is on again, on `engine`, with `scope`: another
1093
+ * user's session. Every open is its own session, even on the same engine.
1094
+ * A local document is its own open's alone, so without it the events test
1095
+ * is skipped.
1096
+ */
1097
+ openSameDocument?: (engine: Engine, doc: DocumentHandle, scope: readonly string[]) => Promise<DocumentHandle>;
1098
+ }
1099
+ declare function runPermissionConformance(runner: ConformanceTestRunner, opts: PermissionConformanceOptions): void;
1100
+ //#endregion
1101
+ //#region src/conformance/runFormScriptConformance.d.ts
1102
+ /**
1103
+ * A field's scripts, written through `create` and `update`, and the form's
1104
+ * calculation order, which follows the calculate scripts and moves by
1105
+ * neighbour; a widget's actions, written through its placement and
1106
+ * `updateWidget`. Undo puts them back. A field event takes JavaScript only;
1107
+ * writing a script, a submit or a link takes `doc.forms.script`, while the
1108
+ * actions that only change the view (go to, reset, show and hide) need
1109
+ * `doc.forms.modify` alone.
1110
+ *
1111
+ * It runs on {@link CHANGE_FIXTURE_PDF}: the text field `name`, merged with
1112
+ * its widget (9) on the first page, and no calculation order.
1113
+ */
1114
+ interface FormScriptConformanceOptions {
1115
+ label: string;
1116
+ makeEngine: () => Promise<Engine> | Engine;
1117
+ /** Open a fresh copy of {@link CHANGE_FIXTURE_PDF} with `scope`. */
1118
+ open: (engine: Engine, scope: readonly string[]) => Promise<DocumentHandle>;
1119
+ }
1120
+ declare function runFormScriptConformance(runner: ConformanceTestRunner, opts: FormScriptConformanceOptions): void;
1121
+ //#endregion
1122
+ //#region src/conformance/runFormAttributionConformance.d.ts
1123
+ /**
1124
+ * Who made a field and who filled it in, on both engines with the same
1125
+ * identities. The engine stamps it from the session: `create` names the
1126
+ * creator, a write that changes a value names its filler (a script's value
1127
+ * counts as filled by the user whose fill ran it), a reset and an anonymous
1128
+ * fill name nobody, and an undo puts the previous filler back. A widget row
1129
+ * reports no attribution: the field holds it.
1130
+ *
1131
+ * It runs on {@link CHANGE_FIXTURE_PDF}: the text field `name`, merged with
1132
+ * its widget (9), holding `Ann`.
1133
+ */
1134
+ interface FormAttributionConformanceOptions {
1135
+ label: string;
1136
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
1137
+ makeEngine: () => Promise<Engine> | Engine;
1138
+ /**
1139
+ * Open a fresh copy of {@link CHANGE_FIXTURE_PDF} as `session`. With
1140
+ * `from`, the new session continues that open session's document and sees
1141
+ * what it wrote (locally its downloaded bytes, on the cloud the same
1142
+ * layer); the suite closes `from` afterwards.
1143
+ */
1144
+ openAs: (engine: Engine, session: AttributionSession, from?: DocumentHandle) => Promise<DocumentHandle>;
1145
+ }
1146
+ declare function runFormAttributionConformance(runner: ConformanceTestRunner, opts: FormAttributionConformanceOptions): void;
1147
+ //#endregion
1148
+ //#region src/conformance/runFormTransferConformance.d.ts
1149
+ /**
1150
+ * `doc.forms.export`, `doc.forms.import` and `doc.forms.importValues` on
1151
+ * both engines. A design import copies whole fields, with their widgets,
1152
+ * values, scripts, actions and calculation order, so the copy exports as
1153
+ * its source, apart from refs, object numbers and the attribution its mode
1154
+ * writes. A values import fills fields of the same name and reports what it
1155
+ * leaves out. Both are one change each: undone and redone with
1156
+ * `doc.apply({ undoOf })`, answered again on a retry, refused before
1157
+ * anything is written.
1158
+ *
1159
+ * It runs on {@link TWO_PAGES_PDF}: two empty pages (3 and 4) and no form.
1160
+ */
1161
+ interface FormTransferConformanceOptions {
1162
+ label: string;
1163
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
1164
+ makeEngine: () => Promise<Engine> | Engine;
1165
+ /** Open a fresh document of `bytes` as `session`. */
1166
+ openAs: (engine: Engine, session: AttributionSession, bytes: Uint8Array) => Promise<DocumentHandle>;
1167
+ }
1168
+ /** Two empty 300 × 300 pages (3 and 4), and no form. */
1169
+ declare const TWO_PAGES_PDF: Uint8Array<ArrayBufferLike>;
1170
+ declare function runFormTransferConformance(runner: ConformanceTestRunner, opts: FormTransferConformanceOptions): void;
1171
+ //#endregion
1172
+ //#region src/conformance/runWidgetRotationConformance.d.ts
1173
+ /**
1174
+ * A widget turns as a box kind does: `box` is the frame its contents are
1175
+ * laid out in, `rotation` a quarter turn, clockwise (`/MK /R`, which the
1176
+ * file holds counterclockwise), and `rect` where it stands on the page, the
1177
+ * box turned. On both engines: Acrobat's turned fields read so, a placement
1178
+ * turns a new field, an update turns, moves and resizes one, undo puts it
1179
+ * back, and a form bundle carries the turn.
1180
+ *
1181
+ * It runs on {@link TURNED_FIELDS_PDF}.
1182
+ */
1183
+ interface WidgetRotationConformanceOptions {
1184
+ label: string;
1185
+ /** Build a fresh engine for this suite. The suite tears it down at the end. */
1186
+ makeEngine: () => Promise<Engine> | Engine;
1187
+ /** Open a fresh document of `bytes` with every scope. */
1188
+ open: (engine: Engine, bytes: Uint8Array) => Promise<DocumentHandle>;
1189
+ }
1190
+ /**
1191
+ * Two 300 × 300 pages: the first upright (3), the second shown turned 90°
1192
+ * (`/Rotate 90`, page 4). Text fields with `/MK /R` as Acrobat writes it,
1193
+ * counterclockwise: `upright` (none), `r90` (90, the text runs up the page),
1194
+ * `r180`, `r270`, `odd` (45, which no viewer draws turned), `negative`
1195
+ * (-90, the same turn as 270), and `on-turned` on the turned page (90: an
1196
+ * upright field there, as Acrobat adds one).
1197
+ */
1198
+ declare const TURNED_FIELDS_PDF: Uint8Array<ArrayBufferLike>;
1199
+ declare function runWidgetRotationConformance(runner: ConformanceTestRunner, opts: WidgetRotationConformanceOptions): void;
1200
+ //#endregion
1201
+ //#region src/conformance/runWidgetFindingConformance.d.ts
1202
+ interface WidgetFindingCase {
1203
+ /** What the file does. */
1204
+ readonly does: string;
1205
+ readonly pdf: Uint8Array;
1206
+ /** The page whose `/Annots` holds the widget, or `null` when no page shows it. */
1207
+ readonly page: number | null;
1208
+ /** The name of the field the form reads the widget into, or `null` for a widget in no field. */
1209
+ readonly field: string | null;
1210
+ }
1211
+ /** The cases, by name. Object 3 is the first page in each. */
1212
+ declare const WIDGET_FINDING_CASES: {
1213
+ readonly 'annots-only': {
1214
+ readonly does: "a merged field/widget in a page's /Annots that the field tree doesn't list";
1215
+ readonly pdf: Uint8Array<ArrayBufferLike>;
1216
+ readonly page: 3;
1217
+ readonly field: "orphan";
1218
+ };
1219
+ readonly inline: {
1220
+ readonly does: "a widget written straight into a page's /Annots, as no object of its own";
1221
+ readonly pdf: Uint8Array<ArrayBufferLike>;
1222
+ readonly page: 3;
1223
+ readonly field: null;
1224
+ };
1225
+ readonly 'no-acroform': {
1226
+ readonly does: "a field widget in a file that has no /AcroForm at all";
1227
+ readonly pdf: Uint8Array<ArrayBufferLike>;
1228
+ readonly page: 3;
1229
+ readonly field: "lonely";
1230
+ };
1231
+ readonly 'stale-p': {
1232
+ readonly does: "a widget in the second page's /Annots whose /P names the first page";
1233
+ readonly pdf: Uint8Array<ArrayBufferLike>;
1234
+ readonly page: 4;
1235
+ readonly field: "moved";
1236
+ };
1237
+ readonly 'deleted-page': {
1238
+ readonly does: "a field whose widget was on a page the document no longer has";
1239
+ readonly pdf: Uint8Array<ArrayBufferLike>;
1240
+ readonly page: null;
1241
+ readonly field: "gone";
1242
+ };
1243
+ readonly 'no-field-type': {
1244
+ readonly does: "a widget with no field type anywhere on its /Parent chain";
1245
+ readonly pdf: Uint8Array<ArrayBufferLike>;
1246
+ readonly page: 3;
1247
+ readonly field: null;
1248
+ };
1249
+ };
1250
+ type WidgetFindingCaseName = keyof typeof WIDGET_FINDING_CASES;
1251
+ interface WidgetFindingConformanceOptions {
1252
+ label: string;
1253
+ makeEngine: () => Promise<Engine> | Engine;
1254
+ /** Open `pdf` with every right, as a document of its own. */
1255
+ open: (engine: Engine, pdf: Uint8Array, name: WidgetFindingCaseName) => Promise<DocumentHandle>;
1256
+ }
1257
+ declare function runWidgetFindingConformance(runner: ConformanceTestRunner, opts: WidgetFindingConformanceOptions): void;
1258
+ //#endregion
504
1259
  //#region src/conformance/runPieceInfoConformance.d.ts
1260
+ interface PieceInfoConformanceOptions {
1261
+ label: string;
1262
+ /** Build a fresh local engine for this suite. The suite tears it down at the end. */
1263
+ makeEngine: () => Promise<LocalEngine> | LocalEngine;
1264
+ fixture: ConformanceFixture;
1265
+ }
505
1266
  /**
506
- * `/PieceInfo` conformance (doc + page level). The service is OPTIONAL on
507
- * the contract (`downloadLayer?` pattern) — the suite runs only where the
508
- * implementation provides it, so an engine that has not shipped it yet
509
- * skips cleanly.
1267
+ * `/PieceInfo` conformance (doc + page level), on the local engine: the
1268
+ * only one with `/PieceInfo`.
510
1269
  *
511
1270
  * Invariants:
512
1271
  * 1. The full value vocabulary round-trips at both levels: string,
513
1272
  * number, boolean, name, string-array — read back with the same tags.
514
- * 2. Writes PERSIST: download() → re-open → identical read (bytes-open
515
- * engines only, since cloud cannot re-open loose bytes).
1273
+ * 2. Writes persist: download() → re-open → identical read.
516
1274
  * 3. `null` deletes a key; sibling keys and sibling applications
517
1275
  * survive both key deletes and whole-entry clears.
518
1276
  * 4. An absent application reads as `null`; `applications()` enumerates
519
- * what is present; every write refreshes `lastModified`.
1277
+ * what is present; every write refreshes `modifiedAt`.
520
1278
  */
521
- declare function runPieceInfoConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
1279
+ declare function runPieceInfoConformance(runner: ConformanceTestRunner, opts: PieceInfoConformanceOptions): void;
522
1280
  //#endregion
523
1281
  //#region src/conformance/runDocumentEventsConformance.d.ts
524
1282
  /**
525
1283
  * Document event stream conformance suite. Verifies the invariants the
526
- * collaboration design rests on — do NOT loosen these without re-reading
1284
+ * collaboration design rests on — do not loosen these without re-reading
527
1285
  * `DocumentEvent`:
528
1286
  *
529
- * 1. EXACTLY ONCE: every confirmed mutation produces exactly one event,
1287
+ * 1. Exactly once: every confirmed mutation produces exactly one event,
530
1288
  * in mutation order, regardless of engine (local worker or cloud HTTP).
531
- * 2. GROUND TRUTH: a failed mutation publishes nothing; events fire only
1289
+ * 2. Ground truth: a failed mutation publishes nothing; events fire only
532
1290
  * after confirmation.
533
- * 3. RESULTS RIDE VERBATIM: each event embeds the result the caller
1291
+ * 3. Results ride verbatim: each event embeds the result the caller
534
1292
  * received, deep-equal field for field.
535
- * 4. PROVENANCE: own mutations are `origin.kind: 'local'` with a stable
536
- * per-engine-instance `sessionId`.
537
- * 5. Unsubscribe stops delivery.
1293
+ * 4. Provenance: own mutations are `origin.kind: 'local'` with the
1294
+ * handle's one `sessionId`.
1295
+ * 5. Unsubscribe stops delivery; `on(type)` hears only its type.
1296
+ * 6. Published before settlement: the event for a session's own mutation
1297
+ * reaches subscribers before the mutation's promise settles, so a
1298
+ * caller that awaits the mutation already sees state derived from it.
538
1299
  *
539
1300
  * Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
540
1301
  * implementations must pass identically.
@@ -568,11 +1329,11 @@ declare function runPageTextConformance(runner: ConformanceTestRunner, opts: Pag
568
1329
  //#endregion
569
1330
  //#region src/conformance/runTextDivergenceConformance.d.ts
570
1331
  /**
571
- * Index-space divergence conformance: the cases where a page's CHARACTER
1332
+ * Index-space divergence conformance: the cases where a page's character
572
1333
  * space (what geometry tiles and selection/search ranges address) and its
573
- * extracted TEXT differ — and the `charMap` contract that bridges them.
1334
+ * extracted text differ — and the `charMap` contract that bridges them.
574
1335
  *
575
- * Fixtures pin EXACT values (text, charCount, anchors) verified against the
1336
+ * Fixtures pin exact values (text, charCount, anchors) verified against the
576
1337
  * wasm runtime, so both engines must produce byte-identical snapshots:
577
1338
  *
578
1339
  * - a non-printing character occupying a character slot with no text unit
@@ -581,17 +1342,17 @@ declare function runPageTextConformance(runner: ConformanceTestRunner, opts: Pag
581
1342
  * characters in lockstep with the text, identity map, real segments);
582
1343
  * - supplementary-plane text via a ToUnicode surrogate pair
583
1344
  * (`embedpdf_astral_tounicode.pdf` — two lockstep surrogate entries,
584
- * identity map, astral content SURVIVES extraction).
1345
+ * identity map, astral content survives extraction).
585
1346
  *
586
- * The search probe closes the loop: a hit's `charStart`/`charCount` must be
587
- * CHARACTER-space (segments join geometry), and slicing the snapshot by the
1347
+ * The search probe closes the loop: a hit's `start`/`count` must be
1348
+ * character-space (segments join geometry), and slicing the snapshot by the
588
1349
  * hit's range must reproduce the matched text exactly — the law that makes
589
1350
  * select-this-match and copy compose.
590
1351
  */
591
1352
  interface TextDivergenceConformanceFixture extends ConformanceFixture {
592
1353
  /** PDF indirect object number of the probed page. */
593
1354
  pageObjectNumber: number;
594
- /** The EXACT extracted text (UTF-16 faithful). */
1355
+ /** The exact extracted text (UTF-16 faithful). */
595
1356
  exactText: string;
596
1357
  /** The character-space size (may differ from `exactText.length`). */
597
1358
  expectedCharCount: number;
@@ -599,15 +1360,15 @@ interface TextDivergenceConformanceFixture extends ConformanceFixture {
599
1360
  expectedCharMap: ReadonlyArray<CharMapAnchor> | null;
600
1361
  /** Char-space slice expectations (half-open). */
601
1362
  slices?: ReadonlyArray<{
602
- from: number;
603
- to: number;
1363
+ start: number;
1364
+ count: number;
604
1365
  text: string;
605
1366
  }>;
606
- /** Literal search probe with expected CHARACTER-space hit range. */
1367
+ /** Literal search probe with expected character-space hit range. */
607
1368
  search?: {
608
1369
  query: string;
609
- charStart: number;
610
- charCount: number;
1370
+ start: number;
1371
+ count: number;
611
1372
  matchedText: string;
612
1373
  };
613
1374
  }
@@ -621,7 +1382,7 @@ type TextDivergenceCase = Omit<TextDivergenceConformanceFixture, 'id' | 'bytes'
621
1382
  resource: string;
622
1383
  };
623
1384
  /**
624
- * THE pinned divergence cases — one table, consumed by both engines' suites
1385
+ * The pinned divergence cases — one table, consumed by both engines' suites
625
1386
  * so expected values cannot drift. Values verified against the wasm runtime
626
1387
  * (see each case). All fixtures are single-page; the page's indirect object
627
1388
  * number is 3 in each.
@@ -645,7 +1406,7 @@ interface PageGeometryOrientationFixture extends ConformanceFixture {
645
1406
  kind: 'empty-only';
646
1407
  } | {
647
1408
  kind: 'rotated';
648
- /** Baseline angles (radians, CCW, PDF y-up) rotated runs may carry. */
1409
+ /** Turns (degrees clockwise) rotated runs may carry. */
649
1410
  rotations: number[];
650
1411
  ascentFlip: boolean;
651
1412
  /**
@@ -685,21 +1446,16 @@ interface SearchConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
685
1446
  }
686
1447
  declare function runSearchConformance(runner: ConformanceTestRunner, opts: SearchConformanceOptions): void;
687
1448
  //#endregion
688
- //#region src/conformance/diffAnnotationListSnapshot.d.ts
1449
+ //#region src/conformance/diffAnnotationList.d.ts
689
1450
  /**
690
1451
  * Returns a list of human-readable difference strings between two
691
- * snapshots. Empty array means parity. Used by `engine-node.ts` to assert
692
- * that local and cloud emit identical annotations for the same fixture.
693
- *
694
- * `RevisionToken.docSessionId` is intentionally NOT compared — sessions
695
- * are disjoint. We do compare `pageObjectNumber` and `generation` (which
696
- * should be 0 for fresh reads on both sides). Page order is no longer part
697
- * of `PageState`; it lives in `PageLayout.index` (see `pages.list()`).
698
- * `auditHead` is likewise not compared: it is a cloud-only reconciliation
699
- * cursor, absent on local snapshots by design.
1452
+ * `annotations.list()` results, page by page. Empty array means parity.
1453
+ * Used by `engine-node.ts` to assert that local and cloud emit identical
1454
+ * annotations for the same fixture: the same pages, and on each the same
1455
+ * annotations under the same names. `auditHead` is not compared: it is a
1456
+ * cloud-only reconciliation cursor, absent on local lists by design.
700
1457
  */
701
- declare function diffAnnotationListSnapshot(a: AnnotationListPageSnapshot, b: AnnotationListPageSnapshot): string[];
702
- declare function diffAnnotationListSnapshotAll(a: AnnotationListSnapshotAllPages, b: AnnotationListSnapshotAllPages): string[];
1458
+ declare function diffAnnotationList(a: AnnotationList, b: AnnotationList): string[];
703
1459
  //#endregion
704
1460
  //#region src/conformance/runSignatureConformance.d.ts
705
1461
  interface SignatureConformanceFixtures {
@@ -748,12 +1504,12 @@ interface SignatureConformanceOptions {
748
1504
  fixtures: SignatureConformanceFixtures;
749
1505
  }
750
1506
  /**
751
- * Digital signatures, read side. The service is OPTIONAL on the contract
1507
+ * Digital signatures, read side. The service is optional on the contract
752
1508
  * (`downloadLayer?` pattern) — the suite runs only where the engine
753
1509
  * provides it.
754
1510
  *
755
1511
  * Invariants:
756
- * 1. Byte facts describe the LOADED bytes: a revision is a byte prefix,
1512
+ * 1. Byte facts describe the loaded bytes: a revision is a byte prefix,
757
1513
  * a whole-revision signature seals exactly one, the digest over its
758
1514
  * `/ByteRange` is what the file's bytes hash to, and an unsaved edit
759
1515
  * changes none of it.
@@ -768,5 +1524,103 @@ interface SignatureConformanceOptions {
768
1524
  */
769
1525
  declare function runSignatureConformance(runner: ConformanceTestRunner, opts: SignatureConformanceOptions): void;
770
1526
  //#endregion
771
- export { type ActionsConformanceFixtures, type ActionsConformanceOptions, type AnnotationAppearanceConformanceFixture, type AnnotationAppearanceConformanceOptions, type AnnotationConformanceOptions, type AnnotationMutationConformanceFixture, type AnnotationMutationConformanceOptions, type AnnotationReadConformanceFixture, type ConformanceExpect, type ConformanceFixture, type ConformanceOptions, type ConformanceTestRunner, type FormConformanceFixtures, type FormConformanceOptions, type PageGeometryOrientationFixture, type PageGeometryOrientationOptions, type PageReorderConformanceFixture, type PageReorderConformanceOptions, type PageTextConformanceFixture, type PageTextConformanceOptions, type SearchConformanceFixture, type SearchConformanceOptions, type SignatureConformanceFixtures, type SignatureConformanceOptions, TEXT_DIVERGENCE_CASES, type TextDivergenceCase, type TextDivergenceConformanceFixture, type TextDivergenceConformanceOptions, diffAnnotationListSnapshot, diffAnnotationListSnapshotAll, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationAppearanceExportConformance, runAnnotationFlattenConformance, runAnnotationMutationConformance, runAnnotationReadConformance, runAttachmentConformance, runDocumentEventsConformance, runFormConformance, runMeasurementConformance, runMetadataConformance, runNamedPagesConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageGeometryOrientationConformance, runPageInsertBlankConformance, runPageInsertConformance, runPageReorderConformance, runPageRotateConformance, runPageTextConformance, runPieceInfoConformance, runRedactionApplyConformance, runSearchConformance, runSignatureConformance, runTextDivergenceConformance };
1527
+ //#region src/conformance/runAnnotationPredictionConformance.d.ts
1528
+ /** One blank US Letter page. */
1529
+ declare const PREDICTION_FIXTURE_PDF: Uint8Array<ArrayBufferLike>;
1530
+ interface AnnotationPredictionConformanceOptions {
1531
+ label: string;
1532
+ makeEngine: () => Promise<Engine> | Engine;
1533
+ /** Open {@link PREDICTION_FIXTURE_PDF}. Called once; every case adds its own annotation. */
1534
+ open: (engine: Engine) => Promise<DocumentHandle>;
1535
+ }
1536
+ /**
1537
+ * What a write does, predicted: `applyAnnotationPatch(read, patch)` equals the
1538
+ * annotation the engine reads back after `update(ref, patch)`, and
1539
+ * `annotationOfDraft(draft, context)` the one it reads back after
1540
+ * `create(draft)`, on every field but the ones the engine works out from its
1541
+ * drawing or stamps on each write.
1542
+ * A viewer shows a pending change this way, so the prediction is what the
1543
+ * user sees until the engine answers.
1544
+ */
1545
+ declare function runAnnotationPredictionConformance(runner: ConformanceTestRunner, opts: AnnotationPredictionConformanceOptions): void;
1546
+ //#endregion
1547
+ //#region src/conformance/runFormPredictionConformance.d.ts
1548
+ interface FormPredictionConformanceOptions {
1549
+ label: string;
1550
+ makeEngine: () => Promise<Engine> | Engine;
1551
+ /** Open `PREDICTION_FIXTURE_PDF` (one blank page). Called once; every case adds its own field. */
1552
+ open: (engine: Engine) => Promise<DocumentHandle>;
1553
+ }
1554
+ /**
1555
+ * What a form op leaves, predicted (`forms/predict.ts`): each op of every
1556
+ * family run against a fresh field, and the field and its widgets' rows the
1557
+ * engine reads back compared with the prediction, field by field. What the
1558
+ * engine stamps on a write (dates, who filled it in), its fonts from the
1559
+ * document's default appearance and the names it mints are left out.
1560
+ */
1561
+ declare function runFormPredictionConformance(runner: ConformanceTestRunner, opts: FormPredictionConformanceOptions): void;
1562
+ //#endregion
1563
+ //#region src/conformance/runFieldGroupsConformance.d.ts
1564
+ /**
1565
+ * Field groups: who fills in and signs which fields. On a buyer and seller
1566
+ * contract, the same on every engine:
1567
+ * - each signer fills in and signs only their own group's fields;
1568
+ * - a field a script calculates moves with a fill of the signer's own;
1569
+ * - a designer puts fields in their own group, or one they may set;
1570
+ * - a values import leaves out the fields the token may not fill;
1571
+ * - signing a grouped signature field locks the rest of its group.
1572
+ *
1573
+ * It runs on {@link FIELD_GROUPS_PDF}.
1574
+ */
1575
+ /**
1576
+ * One page with a buyer's and a seller's fields, each field's group in its
1577
+ * `/EMBD_Metadata /GroupID`: `buyer_name` and `buyer_price` (buyer),
1578
+ * `seller_name` (seller), `total` (no group; a calculate script, in the
1579
+ * calculation order), and the signature fields `buyer_sig` (buyer) and
1580
+ * `seller_sig` (seller).
1581
+ */
1582
+ declare const FIELD_GROUPS_PDF: Uint8Array<ArrayBufferLike>;
1583
+ /** The tokens of the contract's parties. */
1584
+ declare const FIELD_GROUP_TOKENS: {
1585
+ /** The buyer: fills in and signs the buyer's fields. */
1586
+ readonly buyer: {
1587
+ readonly scope: readonly ["doc.open", "doc.render", "fields:fill:group=buyer", "fields:sign:group=buyer"];
1588
+ readonly identity: {
1589
+ readonly userId: "alice";
1590
+ readonly displayName: "Alice";
1591
+ };
1592
+ };
1593
+ /** The seller, as a share link would grant it: everything on the seller's fields. */
1594
+ readonly seller: {
1595
+ readonly scope: readonly ["doc.open", "doc.render", "fields:*:group=seller"];
1596
+ readonly identity: {};
1597
+ };
1598
+ /** The designer: her fields go in legal; she may put fields in the buyer's group too. */
1599
+ readonly designer: {
1600
+ readonly scope: readonly ["doc.open", "doc.render", "doc.forms.modify", "fields:set-group:group=buyer"];
1601
+ readonly identity: {
1602
+ readonly userId: "lisa";
1603
+ readonly groupId: "legal";
1604
+ };
1605
+ };
1606
+ readonly everything: {
1607
+ readonly scope: readonly ["*"];
1608
+ readonly identity: {};
1609
+ };
1610
+ };
1611
+ type FieldGroupToken = keyof typeof FIELD_GROUP_TOKENS;
1612
+ interface FieldGroupsConformanceOptions {
1613
+ label: string;
1614
+ makeEngine: () => Promise<Engine> | Engine;
1615
+ /** Open a fresh copy of `bytes` (default {@link FIELD_GROUPS_PDF}) with `scope`, acting for `identity`. */
1616
+ open: (engine: Engine, scope: readonly string[], identity: Identity, bytes?: Uint8Array) => Promise<DocumentHandle>;
1617
+ /**
1618
+ * Whether a signing completes on this engine with a placeholder CMS, so
1619
+ * the lock it installs can be read back. Default `true`.
1620
+ */
1621
+ completesSignings?: boolean;
1622
+ }
1623
+ declare function runFieldGroupsConformance(runner: ConformanceTestRunner, opts: FieldGroupsConformanceOptions): void;
1624
+ //#endregion
1625
+ export { APPEARANCE_STATES_FIXTURE_PDF, type ActionsConformanceFixtures, type ActionsConformanceOptions, type AnnotationAppearanceConformanceFixture, type AnnotationAppearanceConformanceOptions, type AnnotationAttributionConformanceOptions, type AnnotationConformanceOptions, type AnnotationDeclarationConformanceOptions, type AnnotationDeclarationFixture, type AnnotationMutationConformanceFixture, type AnnotationMutationConformanceOptions, type AnnotationPredictionConformanceOptions, type AnnotationReadConformanceFixture, type AnnotationResourceConformanceOptions, type AnnotationResourceFixture, type AnnotationRotationConformanceOptions, type AnnotationRotationFixture, type AnnotationTransferConformanceOptions, type AppearanceStatesConformanceOptions, type AttributionSession, BARE_PAGE_FIXTURE_PDF, BROKEN_OUTLINE_FIXTURE_PDF, CHANGE_FIXTURE_PDF, COLOR_FIXTURE_PDF, CROP_OFFSET_PDF, type ChangeConformanceOptions, type ColorConformanceOptions, type ConformanceExpect, type ConformanceFixture, type ConformanceOptions, type ConformanceTestRunner, type Creatable, DRAWING_FIXTURE_PDF, type DateConformanceOptions, type DrawingDetailsConformanceOptions, type DrawingDetailsFixture, FIELD_GROUPS_PDF, FIELD_GROUP_TOKENS, type FieldGroupToken, type FieldGroupsConformanceOptions, type FormAttributionConformanceOptions, type FormConformanceFixtures, type FormConformanceOptions, type FormPredictionConformanceOptions, type FormScriptConformanceOptions, type FormTransferConformanceOptions, OBJECT_NUMBER_FIXTURE_PDF, OUTLINE_FIXTURE_PDF, type ObjectNumberConformanceOptions, type OutlineConformanceOptions, PAGE_SPACE_FIXTURES, PERMISSION_TOKENS, PREDICTION_FIXTURE_PDF, PRINT_RULES_PDF, PRINT_SCOPES, type PageGeometryOrientationFixture, type PageGeometryOrientationOptions, type PageRenderConformanceOptions, type PageReorderConformanceFixture, type PageReorderConformanceOptions, type PageSpaceConformanceOptions, type PageSpaceFixture, type PageSpaceFixturePage, type PageTextConformanceFixture, type PageTextConformanceOptions, type PermissionConformanceOptions, type PermissionToken, type PieceInfoConformanceOptions, type PrintCopyConformanceOptions, type PrintRenderConformanceOptions, type RedactionApplyConformanceOptions, type SearchConformanceFixture, type SearchConformanceOptions, type SignatureConformanceFixtures, type SignatureConformanceOptions, TEXT_DIVERGENCE_CASES, TURNED_FIELDS_PDF, TWO_PAGES_PDF, type TextDivergenceCase, type TextDivergenceConformanceFixture, type TextDivergenceConformanceOptions, WIDGET_FINDING_CASES, type WidgetFindingCase, type WidgetFindingCaseName, type WidgetFindingConformanceOptions, type WidgetRotationConformanceOptions, annotationReadDriftOf, creatables, diffAnnotationList, iconRect, pdfOf, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationAppearanceExportConformance, runAnnotationAttributionConformance, runAnnotationDeclarationConformance, runAnnotationExportConformance, runAnnotationFlattenConformance, runAnnotationImportConformance, runAnnotationMutationConformance, runAnnotationPredictionConformance, runAnnotationReadConformance, runAnnotationResourceConformance, runAnnotationRotationConformance, runAnnotationTransferConformance, runAppearanceStatesConformance, runAttachmentConformance, runChangeConformance, runColorConformance, runDateConformance, runDocumentEventsConformance, runDrawingDetailsConformance, runFieldGroupsConformance, runFormAttributionConformance, runFormConformance, runFormPredictionConformance, runFormScriptConformance, runFormTransferConformance, runMeasurementConformance, runMetadataConformance, runNamedPagesConformance, runObjectNumberConformance, runOutlineConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageGeometryOrientationConformance, runPageInsertBlankConformance, runPageInsertConformance, runPageRenderConformance, runPageReorderConformance, runPageRotateConformance, runPageSpaceConformance, runPageTextConformance, runPermissionConformance, runPieceInfoConformance, runPrintCopyConformance, runPrintRenderConformance, runRedactionApplyConformance, runSearchConformance, runSignatureConformance, runTextDivergenceConformance, runWidgetFindingConformance, runWidgetRotationConformance };
772
1626
  //# sourceMappingURL=conformance.d.cts.map