@docx-editor.dev/core 2.9.2 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/automation.cjs +1 -1
  2. package/dist/automation.d.cts +14 -5
  3. package/dist/automation.d.ts +14 -5
  4. package/dist/automation.js +1 -1
  5. package/dist/binding.cjs +1 -1
  6. package/dist/binding.d.cts +78 -13
  7. package/dist/binding.d.ts +78 -13
  8. package/dist/binding.js +1 -1
  9. package/dist/chunk-34BNQUD4.js +10 -0
  10. package/dist/chunk-5AVHO75P.cjs +19 -0
  11. package/dist/chunk-6HMSC7UV.js +2 -0
  12. package/dist/chunk-6JIJOZDW.js +1 -0
  13. package/dist/chunk-76Y3Y45J.cjs +2 -0
  14. package/dist/chunk-BP7ANXGA.js +1 -0
  15. package/dist/chunk-BTQKU64Q.cjs +1 -0
  16. package/dist/chunk-CRZR6K5Z.js +19 -0
  17. package/dist/chunk-D5EHDHYV.js +1 -0
  18. package/dist/chunk-EJATEGJZ.cjs +1 -0
  19. package/dist/{chunk-PSZH2VXP.js → chunk-GOEBQ26R.js} +1 -1
  20. package/dist/chunk-GRDFEH5Q.cjs +2 -0
  21. package/dist/chunk-GWV65NQW.cjs +10 -0
  22. package/dist/chunk-GXLZCXEH.js +2 -0
  23. package/dist/chunk-JUQOPVSK.cjs +2 -0
  24. package/dist/chunk-LAETEBHD.js +1 -0
  25. package/dist/chunk-M6Z3KFXM.cjs +5 -0
  26. package/dist/{chunk-YMYCPY5Y.cjs → chunk-OHJQ7GPZ.cjs} +1 -1
  27. package/dist/chunk-UQFOYZJO.cjs +18 -0
  28. package/dist/chunk-WPQMPHNR.cjs +1 -0
  29. package/dist/chunk-WXQ245MQ.js +18 -0
  30. package/dist/chunk-WZHIFNSU.js +5 -0
  31. package/dist/chunk-X7A5XART.js +2 -0
  32. package/dist/chunk-ZKWRCLT2.cjs +1 -0
  33. package/dist/collaboration/replication.cjs +1 -0
  34. package/dist/collaboration/replication.d.cts +216 -0
  35. package/dist/collaboration/replication.d.ts +216 -0
  36. package/dist/collaboration/replication.js +1 -0
  37. package/dist/collaboration.cjs +1 -0
  38. package/dist/collaboration.d.cts +176 -0
  39. package/dist/collaboration.d.ts +176 -0
  40. package/dist/collaboration.js +1 -0
  41. package/dist/contracts/document.d.cts +6 -1
  42. package/dist/contracts/document.d.ts +6 -1
  43. package/dist/contracts/editor.cjs +1 -1
  44. package/dist/contracts/editor.d.cts +8 -9
  45. package/dist/contracts/editor.d.ts +8 -9
  46. package/dist/contracts/editor.js +1 -1
  47. package/dist/contracts/interaction.d.cts +8 -9
  48. package/dist/contracts/interaction.d.ts +8 -9
  49. package/dist/contracts/modules.cjs +1 -1
  50. package/dist/contracts/modules.d.cts +20 -8
  51. package/dist/contracts/modules.d.ts +20 -8
  52. package/dist/contracts/modules.js +1 -1
  53. package/dist/custom-node-writes-CwkYRw3V.d.cts +310 -0
  54. package/dist/custom-node-writes-JfTn-Sy6.d.ts +310 -0
  55. package/dist/document-properties-D6Ahr8D6.d.cts +28 -0
  56. package/dist/document-properties-D6Ahr8D6.d.ts +28 -0
  57. package/dist/{editor-Cvd7Geoc.d.ts → editor-BogcVHXk.d.ts} +176 -59
  58. package/dist/{editor-cAEf1uXW.d.cts → editor-C8edZgy5.d.cts} +176 -59
  59. package/dist/editor.cjs +1 -1
  60. package/dist/editor.css +1 -7698
  61. package/dist/editor.d.cts +26 -25
  62. package/dist/editor.d.ts +26 -25
  63. package/dist/editor.js +1 -1
  64. package/dist/failure-BnGjoXf0.d.cts +64 -0
  65. package/dist/failure-BnGjoXf0.d.ts +64 -0
  66. package/dist/{index-DRqY5JVF.d.ts → index-BNv-ZLQP.d.ts} +327 -86
  67. package/dist/{index-wb-iOxfh.d.cts → index-Dn0lOp9Z.d.cts} +327 -86
  68. package/dist/index.cjs +1 -1
  69. package/dist/index.d.cts +20 -19
  70. package/dist/index.d.ts +20 -19
  71. package/dist/index.js +1 -1
  72. package/dist/layout.cjs +1 -1
  73. package/dist/layout.d.cts +92 -55
  74. package/dist/layout.d.ts +92 -55
  75. package/dist/layout.js +1 -1
  76. package/dist/{note-properties-jvnw_DGG.d.ts → note-properties-BmoSdyKS.d.ts} +1 -1
  77. package/dist/{note-properties-CQlxjic_.d.cts → note-properties-BvGfHk5e.d.cts} +1 -1
  78. package/dist/{omml-equation-Dd3mBep-.d.ts → omml-equation-Ciq5rgb7.d.ts} +1 -1
  79. package/dist/{omml-equation-BD-LsmWE.d.cts → omml-equation-CqQOt_dD.d.cts} +1 -1
  80. package/dist/output.cjs +1 -1
  81. package/dist/output.d.cts +6 -8
  82. package/dist/output.d.ts +6 -8
  83. package/dist/output.js +1 -1
  84. package/dist/{protocol-UuZOcOp7.d.cts → protocol-BB-WP3zk.d.cts} +2 -2
  85. package/dist/{protocol-C7ahrdUx.d.ts → protocol-Ckl7hWsv.d.ts} +2 -2
  86. package/dist/{review-items-bdGxFWNA.d.ts → review-items-BdeLNRi2.d.cts} +1 -2
  87. package/dist/{review-items-B8tffIXj.d.cts → review-items-CkYyXhXM.d.ts} +1 -2
  88. package/dist/{review-reads-Bxz03tHG.d.cts → review-reads-BOLSBm5w.d.cts} +2 -2
  89. package/dist/{review-reads-CHODU0LI.d.ts → review-reads-Crf0Xn42.d.ts} +2 -2
  90. package/dist/{revision-projection-CILpvv4M.d.ts → revision-projection-Ae2CWa8E.d.ts} +1 -1
  91. package/dist/{revision-projection-Cc4wz30g.d.cts → revision-projection-C2S8PSQm.d.cts} +1 -1
  92. package/dist/{semantic-cell-selection-BPzx6DdT.d.cts → semantic-cell-selection-C0OFD4D9.d.cts} +4 -4
  93. package/dist/{semantic-cell-selection-CsHcr-yk.d.ts → semantic-cell-selection-DdmoxC-y.d.ts} +4 -4
  94. package/dist/{semantic-interaction-D-RZ9Ust.d.ts → semantic-interaction-COyhZ9WH.d.ts} +21 -2
  95. package/dist/{semantic-interaction-BfWDD_0V.d.cts → semantic-interaction-Cs2jErnt.d.cts} +21 -2
  96. package/dist/{semantic-paint-WhVtSDJK.d.ts → semantic-paint-UHaj3sBY.d.cts} +2 -2
  97. package/dist/{semantic-paint-Bd7EqzXV.d.cts → semantic-paint-vA-oLSdV.d.ts} +2 -2
  98. package/dist/{semantic-records-DadVT_E1.d.cts → semantic-records-5AOQJmLX.d.cts} +20 -5
  99. package/dist/{semantic-records-DCt-ZwKU.d.ts → semantic-records-9xhwbJ23.d.ts} +20 -5
  100. package/dist/{shaped-measurer-CninrHr_.d.cts → shaped-measurer-NeF2mPSu.d.cts} +1 -1
  101. package/dist/{shaped-measurer-B9f4A7QA.d.ts → shaped-measurer-vzsY88oK.d.ts} +1 -1
  102. package/dist/store.cjs +1 -1
  103. package/dist/store.d.cts +193 -19
  104. package/dist/store.d.ts +193 -19
  105. package/dist/store.js +1 -1
  106. package/dist/tree-op-types-BPyXNxyL.d.cts +3053 -0
  107. package/dist/tree-op-types-DnzAOnc9.d.ts +3053 -0
  108. package/dist/{custom-node-writes-D6SGwebL.d.ts → tree-package-fragment-BjZ3RWAS.d.cts} +128 -312
  109. package/dist/{custom-node-writes-Dy3b20PS.d.cts → tree-package-fragment-CDER0G3B.d.ts} +128 -312
  110. package/dist/{tree-session-ZuBFOhIh.d.ts → tree-session-contract-BF2FVBOM.d.cts} +52 -106
  111. package/dist/{tree-session-Df02ajqc.d.cts → tree-session-contract-DhdsFT_z.d.ts} +52 -106
  112. package/dist/{tree-store-B_sJBMIS.d.cts → tree-store-CNZ3O83s.d.ts} +130 -25
  113. package/dist/{tree-store-DgETo6Mf.d.ts → tree-store-DfZi7FqY.d.cts} +130 -25
  114. package/package.json +14 -3
  115. package/dist/chunk-6JWP2H7K.js +0 -2
  116. package/dist/chunk-6KNLLEUW.cjs +0 -18
  117. package/dist/chunk-7ADTI533.cjs +0 -10
  118. package/dist/chunk-7ETDCPF6.cjs +0 -2
  119. package/dist/chunk-7I3BSGGS.js +0 -1
  120. package/dist/chunk-7UU5YFCD.cjs +0 -2
  121. package/dist/chunk-7VQ7YLW3.cjs +0 -1
  122. package/dist/chunk-CKDAK3MV.js +0 -10
  123. package/dist/chunk-DIMEYVNS.js +0 -2
  124. package/dist/chunk-GQQOL4PV.js +0 -1
  125. package/dist/chunk-H2656QDI.cjs +0 -1
  126. package/dist/chunk-KQGENNL5.cjs +0 -15
  127. package/dist/chunk-LIXPSV4T.js +0 -18
  128. package/dist/chunk-O4UULRAQ.cjs +0 -5
  129. package/dist/chunk-SIIFNE6U.js +0 -15
  130. package/dist/chunk-VXYECPKA.js +0 -5
  131. package/dist/hf-references-Dvk6De4Q.d.cts +0 -70
  132. package/dist/hf-references-z5Y4N1ab.d.ts +0 -70
  133. package/dist/image-resources-BgA9EQxY.d.ts +0 -203
  134. package/dist/image-resources-BiA-IXgo.d.cts +0 -203
  135. package/dist/note-nodes-BNCANoGN.d.ts +0 -108
  136. package/dist/note-nodes-DL-Au22P.d.cts +0 -108
  137. package/dist/ooxml-package-CdEy9ufK.d.cts +0 -1222
  138. package/dist/ooxml-package-CdEy9ufK.d.ts +0 -1222
  139. package/dist/tree-op-types-CnRb7AYo.d.ts +0 -1589
  140. package/dist/tree-op-types-D1vNJ7XC.d.cts +0 -1589
@@ -0,0 +1,3053 @@
1
+ import { ParagraphTabStop } from './contracts/types.cjs';
2
+
3
+ /**
4
+ * The engine's trust-boundary caps: recursion depth, element counts, and the rest.
5
+ *
6
+ * A caller may LOWER any of these but never raise or disable one — an override of `Infinity`,
7
+ * zero, a negative or `NaN` clamps into `(0, ceiling]` rather than turning the limit off. These
8
+ * are security ceilings, not performance budgets.
9
+ */
10
+ interface ResourceLimits {
11
+ /** Max nested-structure recursion (tables/shapes/SDT/groups). */
12
+ readonly maxRecursionDepth: number;
13
+ /** Max total parsed element count. */
14
+ readonly maxElementCount: number;
15
+ /** Max package part count. */
16
+ readonly maxPartCount: number;
17
+ /** Max total decompressed bytes (zip-bomb guard). */
18
+ readonly maxDecompressedBytes: number;
19
+ /** Max total compressed input bytes. */
20
+ readonly maxCompressedBytes: number;
21
+ /** Max decompressed:compressed ratio per entry. */
22
+ readonly maxCompressionRatio: number;
23
+ /** In-memory chunk budget for streaming/spooling. */
24
+ readonly maxChunkBytes: number;
25
+ /** Max pagination passes before non-convergence is declared. */
26
+ readonly maxPaginationPasses: number;
27
+ /** Max queued items in any bounded work queue. */
28
+ readonly maxQueueDepth: number;
29
+ }
30
+ /** Non-disableable hard ceilings: no resolved limit may exceed these. */
31
+ declare const HARD_CEILINGS: ResourceLimits;
32
+ /** Finite defaults, all <= their hard ceiling. */
33
+ declare const DEFAULT_LIMITS: ResourceLimits;
34
+ /**
35
+ * Resolve caller overrides into a frozen, always-finite limit set. Each value is
36
+ * `min(override>0 ? override : default, ceiling)`. Infinity/0/negative/NaN can
37
+ * never disable a limit — the hard ceiling always wins.
38
+ */
39
+ declare function resolveLimits(overrides?: Partial<ResourceLimits>): ResourceLimits;
40
+ /** Bounded image decode limits (typed-drawings-and-images task 4). */
41
+ /** Trust-boundary caps specific to image decoding and embedding. */
42
+ interface ImageResourceLimits {
43
+ readonly maxEncodedBytes: number;
44
+ readonly maxDecodedBytes: number;
45
+ readonly maxPixels: number;
46
+ readonly maxDimension: number;
47
+ readonly maxPolygonPoints: number;
48
+ readonly maxExternalRedirects: number;
49
+ }
50
+ /** Image caps nothing can raise past. A caller's override clamps into these. */
51
+ declare const IMAGE_RESOURCE_HARD_CEILINGS: ImageResourceLimits;
52
+ /** The image caps in force when a host configures none. Conservative and finite. */
53
+ declare const DEFAULT_IMAGE_RESOURCE_LIMITS: ImageResourceLimits;
54
+ /** Resolve caller overrides into frozen image limits; hard ceilings cannot be raised. */
55
+ declare function resolveImageResourceLimits(overrides?: Partial<ImageResourceLimits>): ImageResourceLimits;
56
+
57
+ /**
58
+ * Why a part or relationship name was refused.
59
+ *
60
+ * Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
61
+ * than normalized, because normalizing is how a crafted package reaches outside itself.
62
+ */
63
+ type NameRejection = 'empty' | 'control-char' | 'backslash' | 'drive-or-unc' | 'encoded-separator' | 'encoded-dot' | 'bad-encoding' | 'empty-segment' | 'dot-segment' | 'unsafe-key' | 'segment-trailing-dot' | 'traversal-escape' | 'not-absolute-uri' | 'unsafe-scheme';
64
+ /** A validated OPC name, or the typed reason it was refused. */
65
+ type NameResult = {
66
+ readonly ok: true;
67
+ readonly partName: string;
68
+ } | {
69
+ readonly ok: false;
70
+ readonly reason: NameRejection;
71
+ };
72
+ /**
73
+ * Normalize a ZIP entry name or OPC part name into a canonical part name
74
+ * (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
75
+ * rejects traversal, dot segments, and the attack surface. Duplicate detection
76
+ * folds ASCII case (OPC part-name equivalence).
77
+ */
78
+ declare function normalizePartName(raw: string): NameResult;
79
+ /**
80
+ * ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
81
+ * case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
82
+ * could let two "equivalent" part names evade duplicate detection.
83
+ */
84
+ declare function asciiFold(s: string): string;
85
+ /** Case-folded key for OPC part-name equivalence / duplicate detection. */
86
+ declare function partNameKey(partName: string): string;
87
+ /**
88
+ * Detect archive entries that collide after normalization (before inflation).
89
+ * Returns the case-folded keys that more than one raw name maps to.
90
+ */
91
+ declare function detectDuplicateNames(rawNames: readonly string[]): {
92
+ readonly duplicates: readonly string[];
93
+ readonly rejected: readonly {
94
+ raw: string;
95
+ reason: NameRejection;
96
+ }[];
97
+ };
98
+ /**
99
+ * Resolve an internal relationship target against its owner part, without
100
+ * escaping the package root. `ownerPartName` is a canonical part name; the base
101
+ * is its containing folder. A leading "/" target is package-absolute. `.`/`..`
102
+ * segments resolve on a stack; popping above root is `traversal-escape`.
103
+ */
104
+ declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
105
+ /**
106
+ * Validate an external-mode relationship target. It MUST be an absolute URI, is
107
+ * retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
108
+ * Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
109
+ * the raw lexical form is still preserved separately by the authored record.
110
+ */
111
+ declare function validateExternalTarget(raw: string): NameResult;
112
+
113
+ /** One `<Default>`: a file extension mapped to a content type. */
114
+ interface DefaultRecord {
115
+ readonly extension: string;
116
+ readonly contentType: string;
117
+ readonly order: number;
118
+ }
119
+ /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
120
+ interface OverrideRecord {
121
+ readonly partName: string;
122
+ readonly contentType: string;
123
+ readonly order: number;
124
+ }
125
+ /**
126
+ * The authored `[Content_Types].xml` records, in significant order.
127
+ *
128
+ * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
129
+ * part of what a lossless save re-emits.
130
+ */
131
+ interface ContentTypeRecords {
132
+ readonly defaults: readonly DefaultRecord[];
133
+ readonly overrides: readonly OverrideRecord[];
134
+ }
135
+ /**
136
+ * Why content-type records could not be indexed.
137
+ *
138
+ * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
139
+ * invalid MIME syntax are refused rather than resolved by picking one.
140
+ */
141
+ type ContentTypeError = {
142
+ readonly code: 'invalid-mime';
143
+ readonly value: string;
144
+ } | {
145
+ readonly code: 'conflicting-default';
146
+ readonly extension: string;
147
+ } | {
148
+ readonly code: 'duplicate-override';
149
+ readonly partName: string;
150
+ } | {
151
+ readonly code: 'invalid-override-name';
152
+ readonly partName: string;
153
+ } | {
154
+ readonly code: 'too-many-records';
155
+ readonly limit: number;
156
+ };
157
+ /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
158
+ declare function isValidMime(value: string): boolean;
159
+ /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
160
+ declare function extensionKey(extension: string): string;
161
+ /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
162
+ interface ContentTypeIndex {
163
+ /** ext key -> single MIME (identical duplicates collapsed). */
164
+ readonly defaults: ReadonlyMap<string, string>;
165
+ /** case-folded part name -> MIME. */
166
+ readonly overrides: ReadonlyMap<string, string>;
167
+ }
168
+ /** The built index, or the conflict that made it impossible. */
169
+ type IndexResult = {
170
+ readonly ok: true;
171
+ readonly index: ContentTypeIndex;
172
+ } | {
173
+ readonly ok: false;
174
+ readonly error: ContentTypeError;
175
+ };
176
+ /**
177
+ * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
178
+ * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
179
+ */
180
+ declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
181
+ /**
182
+ * A part's content type, or why it has none.
183
+ *
184
+ * An orphan record never determines a part's type — a Default with no matching part is preserved
185
+ * inertly rather than applied.
186
+ */
187
+ type ResolveResult = {
188
+ readonly ok: true;
189
+ readonly contentType: string;
190
+ readonly source: 'override' | 'default';
191
+ } | {
192
+ readonly ok: false;
193
+ readonly reason: 'unknown';
194
+ };
195
+ /** Resolve a part's content type: Override wins over Default; else unknown. */
196
+ declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
197
+
198
+ /** OOXML image relationship type for embedded or linked media parts. */
199
+ declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
200
+ /**
201
+ * Whether a relationship points inside the package or out of it.
202
+ *
203
+ * The security-relevant distinction: an `External` target is retained VERBATIM and never
204
+ * owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
205
+ * external fetch.
206
+ */
207
+ type TargetMode = 'Internal' | 'External';
208
+ /**
209
+ * One authored relationship, with nothing materialized away: owner part, id, type, raw target
210
+ * lexical form, mode, and position.
211
+ */
212
+ interface RelationshipRecord {
213
+ readonly ownerPart: string;
214
+ readonly id: string;
215
+ readonly type: string;
216
+ readonly rawTarget: string;
217
+ readonly targetMode: TargetMode;
218
+ readonly order: number;
219
+ }
220
+ /** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
221
+ type RelationshipError = {
222
+ readonly code: 'duplicate-id';
223
+ readonly ownerPart: string;
224
+ readonly id: string;
225
+ };
226
+ /** The validated relationship set, or the conflict that rejected it. */
227
+ type RelationshipSetResult = {
228
+ readonly ok: true;
229
+ readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
230
+ } | {
231
+ readonly ok: false;
232
+ readonly error: RelationshipError;
233
+ };
234
+ /** Group relationships by owner in authored order; reject duplicate ids per owner. */
235
+ declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
236
+ /**
237
+ * A relationship resolved to a part, or the reason it could not be.
238
+ *
239
+ * External targets resolve to a refusal by design: they are never followed from a file.
240
+ */
241
+ type ResolvedRelationship = {
242
+ readonly mode: 'Internal';
243
+ readonly target: NameResult;
244
+ readonly raw: string;
245
+ } | {
246
+ readonly mode: 'External';
247
+ readonly sinkSafe: NameResult;
248
+ readonly raw: string;
249
+ };
250
+ /**
251
+ * Resolve a relationship to a runtime projection while the raw target stays
252
+ * authored. Internal -> owner-relative part name; External -> sink-safe
253
+ * validation only (never owner-resolved, never fetched). `raw` is always the
254
+ * verbatim authored target.
255
+ */
256
+ declare function resolveRelationship(rec: RelationshipRecord): ResolvedRelationship;
257
+ /**
258
+ * An image relationship resolved to package bytes, or why it was refused.
259
+ *
260
+ * External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
261
+ * rule applies to images exactly as it does to links.
262
+ */
263
+ type ImageRelationshipResolution = {
264
+ readonly mode: 'internal';
265
+ readonly partName: string;
266
+ readonly raw: string;
267
+ } | {
268
+ readonly mode: 'external';
269
+ readonly sinkSafe: boolean;
270
+ readonly raw: string;
271
+ } | {
272
+ readonly mode: 'missing';
273
+ };
274
+ /**
275
+ * Resolve an image relationship id from an owner part. Internal targets resolve
276
+ * owner-relative; external targets are never fetched; a missing id is `missing`.
277
+ */
278
+ declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
279
+
280
+ /**
281
+ * One parsed XML node, preserving significant order, whitespace and raw lexical values.
282
+ *
283
+ * Attribute records have a NULL prototype: attribute names come from a file and become object
284
+ * keys, so `__proto__` must be inert by construction rather than by filtering.
285
+ */
286
+ type XmlNode = {
287
+ readonly type: 'element';
288
+ readonly name: string;
289
+ readonly attributes: Readonly<Record<string, string>>;
290
+ readonly children: readonly XmlNode[];
291
+ } | {
292
+ readonly type: 'text';
293
+ readonly value: string;
294
+ };
295
+ /**
296
+ * Why XML was refused at the trust boundary.
297
+ *
298
+ * DTDs, entity declarations and external-entity references are PRE-rejected before parsing —
299
+ * blocking XXE and billion-laughs by never handing the parser the construct, rather than by
300
+ * trusting it to be configured safely.
301
+ */
302
+ type XmlRejection = 'too-large' | 'dtd-forbidden' | 'entity-forbidden' | 'too-deep' | 'too-many-elements' | 'invalid-limits' | 'parse-error';
303
+ /** A parsed document, or a typed refusal. Never throws — the input is untrusted. */
304
+ type XmlResult = {
305
+ readonly ok: true;
306
+ readonly nodes: readonly XmlNode[];
307
+ } | {
308
+ readonly ok: false;
309
+ readonly reason: XmlRejection;
310
+ };
311
+ /** Per-part caps on size, element count and depth. Clamped into the hard ceilings. */
312
+ interface XmlLimits {
313
+ readonly maxBytes: number;
314
+ readonly maxElements?: number;
315
+ }
316
+ /** Read XML into an ordered tree, refusing DTDs/entities and bounding size. */
317
+ /**
318
+ * Read XML at the trust boundary: bounded, entity-free, and fidelity-preserving.
319
+ *
320
+ * Pre-rejects DTDs and entity constructs, disables expansion and value coercion, and keeps child
321
+ * order, attributes, whitespace and raw lexical form — everything a lossless re-emit needs.
322
+ */
323
+ declare function readXml(xml: string, limits?: XmlLimits): XmlResult;
324
+ /** Find the first descendant element with the given qualified name. */
325
+ declare function findElement(nodes: readonly XmlNode[], name: string): Extract<XmlNode, {
326
+ type: 'element';
327
+ }> | undefined;
328
+ /** All direct child elements with the given name. */
329
+ declare function childElements(node: Extract<XmlNode, {
330
+ type: 'element';
331
+ }>, name: string): Extract<XmlNode, {
332
+ type: 'element';
333
+ }>[];
334
+ /** Concatenated text content of an element (all descendant text nodes). */
335
+ declare function textContent(node: Extract<XmlNode, {
336
+ type: 'element';
337
+ }>): string;
338
+
339
+ /** The WordprocessingML main namespace — the `w:` prefix in every `word/document.xml`. */
340
+ declare const WML_NAMESPACE_URI = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
341
+ /** The reserved `xml:` namespace, which carries `xml:space`. */
342
+ declare const XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
343
+ /** The reserved `xmlns:` namespace that namespace declarations themselves live in. */
344
+ declare const XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
345
+ /** The `w14` wordml-2010 extension namespace — `w14:paraId`/`w14:textId` live here. */
346
+ declare const W14_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2010/wordml";
347
+ declare const DRAWINGML_MAIN_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/main";
348
+ declare const WP_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
349
+ declare const PIC_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/picture";
350
+ /** The four content-position revision wrappers, which nest and carry runs. */
351
+ declare function isContentRevisionKind(kind: OoxmlNode['kind']): kind is 'revisionInsert' | 'revisionDelete' | 'revisionMoveFrom' | 'revisionMoveTo';
352
+ /** Move-range and comment-range boundary markers, which are empty and sit between runs. */
353
+ declare function isRangeMarkerKind(kind: OoxmlNode['kind']): kind is 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
354
+ /**
355
+ * OOXML on/off toggle: on only when a same-namespace child is present and its `w:val`
356
+ * (same namespace as the child) does not explicitly disable. Foreign-namespace siblings
357
+ * with the same local name cannot turn the flag on.
358
+ */
359
+ declare function readOnOffChild(parent: OoxmlNode, localName: string, namespaceUri?: string): boolean;
360
+
361
+ /**
362
+ * A node's stable identity within its part.
363
+ *
364
+ * Minted deterministically from the structural path at parse, then RETAINED through structural
365
+ * sharing — the same bytes always produce the same ids, and an edit elsewhere in the document
366
+ * does not renumber untouched nodes. Every tree op addresses nodes by these.
367
+ */
368
+ type OoxmlNodeId = string;
369
+ /**
370
+ * One `xmlns:` declaration carried on a node.
371
+ *
372
+ * Preserved rather than normalized away: a document that binds `w14` at the root and a document
373
+ * that binds it on a paragraph are different bytes, and re-emitting the wrong one is a fidelity
374
+ * loss even though the semantics match.
375
+ */
376
+ interface OoxmlNamespaceBinding {
377
+ readonly prefix: string;
378
+ readonly namespaceUri: string;
379
+ }
380
+ interface OoxmlAttributeBase {
381
+ readonly namespaceUri: string;
382
+ readonly localName: string;
383
+ readonly prefix?: string;
384
+ readonly value: string;
385
+ }
386
+ /** `xml:space`, which decides whether a run's leading and trailing whitespace survives. */
387
+ interface OoxmlXmlSpaceAttribute extends OoxmlAttributeBase {
388
+ readonly kind: 'xmlSpace';
389
+ readonly namespaceUri: typeof XML_NAMESPACE_URI;
390
+ readonly localName: 'space';
391
+ readonly prefix: 'xml';
392
+ readonly value: 'default' | 'preserve';
393
+ }
394
+ /** `w:val` — the attribute nearly every WordprocessingML property carries its value in. */
395
+ interface OoxmlWmlValAttribute extends OoxmlAttributeBase {
396
+ readonly kind: 'wmlVal';
397
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
398
+ readonly localName: 'val';
399
+ }
400
+ /**
401
+ * Any attribute outside the typed vocabulary, carried verbatim.
402
+ *
403
+ * Where losslessness actually happens: an attribute this engine has no model for is preserved
404
+ * exactly rather than dropped, so a save re-emits what the file said.
405
+ */
406
+ interface OoxmlGenericExtensionAttribute extends OoxmlAttributeBase {
407
+ readonly kind: 'genericExtension';
408
+ }
409
+ /** Any attribute on any node: the two typed ones, plus the verbatim catch-all. */
410
+ type OoxmlAttribute = OoxmlXmlSpaceAttribute | OoxmlWmlValAttribute | OoxmlGenericExtensionAttribute;
411
+ /**
412
+ * Attributes a TYPED node may carry.
413
+ *
414
+ * Excludes `w:val` on purpose: a node the engine models keeps its value in typed fields, and
415
+ * allowing a stray `w:val` alongside them would create two sources of truth for one property.
416
+ */
417
+ type OoxmlKnownNodeAttribute = OoxmlXmlSpaceAttribute | OoxmlGenericExtensionAttribute;
418
+ interface OoxmlElementBase<Children extends readonly OoxmlNode[] = readonly OoxmlNode[], Attributes extends readonly OoxmlAttribute[] = readonly OoxmlAttribute[]> {
419
+ readonly id: OoxmlNodeId;
420
+ readonly namespaceUri: string;
421
+ readonly localName: string;
422
+ /** Authored prefix retained as non-authoritative fidelity evidence. */
423
+ readonly prefix?: string;
424
+ /** Namespace declarations authored directly on this element, in source order. */
425
+ readonly namespaceBindings: readonly OoxmlNamespaceBinding[];
426
+ readonly attributes: Attributes;
427
+ readonly children: Children;
428
+ }
429
+ /** `w:document` — the root of a main document part. */
430
+ interface OoxmlDocumentNode extends OoxmlElementBase<readonly (OoxmlBodyNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
431
+ readonly kind: 'document';
432
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
433
+ readonly localName: 'document';
434
+ }
435
+ /** `w:body` — the main story's block content. */
436
+ interface OoxmlBodyNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
437
+ readonly kind: 'body';
438
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
439
+ readonly localName: 'body';
440
+ }
441
+ interface OoxmlTableNode extends OoxmlElementBase<readonly (OoxmlTablePropertiesNode | OoxmlTableGridNode | OoxmlTableRowNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
442
+ readonly kind: 'table';
443
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
444
+ readonly localName: 'tbl';
445
+ }
446
+ interface OoxmlTableRowNode extends OoxmlElementBase<readonly (OoxmlTableCellNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
447
+ readonly kind: 'tableRow';
448
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
449
+ readonly localName: 'tr';
450
+ }
451
+ interface OoxmlTableCellNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
452
+ readonly kind: 'tableCell';
453
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
454
+ readonly localName: 'tc';
455
+ }
456
+ /** Grid children (`w:gridCol`) stay generic: they are property leaves, not structure. */
457
+ interface OoxmlTableGridNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
458
+ readonly kind: 'tableGrid';
459
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
460
+ readonly localName: 'tblGrid';
461
+ }
462
+ /** Property children stay generic, mirroring `runProperties`. */
463
+ interface OoxmlTablePropertiesNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
464
+ readonly kind: 'tableProperties';
465
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
466
+ readonly localName: 'tblPr';
467
+ }
468
+ /**
469
+ * `w:p` — a paragraph, and the unit every offset in this engine is relative to.
470
+ *
471
+ * Positions are addressed as this node's id plus a UTF-16 offset, which is what makes a paragraph
472
+ * inside a table cell no different from one at the top level.
473
+ */
474
+ interface OoxmlParagraphNode extends OoxmlElementBase<readonly (OoxmlParagraphPropertiesNode | OoxmlRunNode | OoxmlHyperlinkNode | OoxmlContentControlNode | OoxmlBookmarkStartNode | OoxmlBookmarkEndNode | OoxmlRevisionContentNode | OoxmlRangeMarkerNode | OoxmlFldSimpleNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
475
+ readonly kind: 'paragraph';
476
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
477
+ readonly localName: 'p';
478
+ }
479
+ /**
480
+ * `CT_Hyperlink` (ECMA-376 §17.16.22) — a RUN CONTAINER, not a leaf.
481
+ *
482
+ * Its runs are part of the paragraph's inline sequence: they measure, paint, select and
483
+ * take offsets exactly like a run written directly under the `w:p`. Typing the element is
484
+ * what lets them in; while it was generic, its runs never reached the token stream and the
485
+ * words inside every link simply did not paint.
486
+ *
487
+ * Targets live in the ATTRIBUTES, and §17.16.22 declares exactly six. They divide into two
488
+ * groups, and the difference is load-bearing:
489
+ *
490
+ * MODELED `r:id` (a relationship, resolved against the owning part's rels), `w:anchor`
491
+ * (a bookmark name in this document) and `w:tooltip`. These are the three the
492
+ * ops read and write — `setHyperlinkTarget` sets one target attribute and
493
+ * CLEARS the other, so a link never carries both and resolves by the wrong one.
494
+ *
495
+ * PRESERVED `w:tgtFrame`, `w:docLocation` and `w:history`. Nothing in this engine
496
+ * interprets them and no op names them; they survive because attributes are
497
+ * carried verbatim, and `setHyperlinkTarget` must leave them exactly as
498
+ * authored. That is a REQUIREMENT, not an incidental property of the current
499
+ * applier: `w:docLocation` names a location inside the target document, so
500
+ * silently dropping it on a retarget would change where a link goes.
501
+ * `hyperlink-lossless-editing.test.ts` pins both against a retarget.
502
+ *
503
+ * Nothing here is a runtime URL — the sanitized projection is computed separately (see
504
+ * `hyperlinkTargetOf`), and only that reaches a DOM or navigation sink.
505
+ *
506
+ * Bookmark markers are admitted as children because Word writes them inside links; anything
507
+ * else it can carry (a drawing, a field, a nested SDT) stays `generic` at its position, so a
508
+ * link around a picture keeps both the picture and the link.
509
+ *
510
+ * A link may contain ANOTHER link: §17.16.22's content model is `EG_PContent`, which lists
511
+ * `w:hyperlink` among its own members. That is why this child union is self-referential
512
+ * rather than bottoming out at runs. Demoting the inner one to `generic` would have been the
513
+ * easier type, and it would have reintroduced exactly the bug typing this element fixed —
514
+ * a generic link's runs never reach the token stream, so the words inside it stop painting.
515
+ * Every walk that descends a link therefore recurses (`segmentsOf`, `runsUnder`,
516
+ * `runPropertyEdits`) instead of descending one level.
517
+ */
518
+ interface OoxmlHyperlinkNode extends OoxmlElementBase<readonly (OoxmlRunNode | OoxmlHyperlinkNode | OoxmlContentControlNode | OoxmlBookmarkStartNode | OoxmlBookmarkEndNode | OoxmlRevisionContentNode | OoxmlRangeMarkerNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
519
+ readonly kind: 'hyperlink';
520
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
521
+ readonly localName: 'hyperlink';
522
+ }
523
+ /**
524
+ * A content-position revision wrapper — `w:ins`, `w:del`, `w:moveFrom`, `w:moveTo`.
525
+ *
526
+ * These wrap runs, so a walk that visits only direct `run` children never reaches
527
+ * the content inside them. Typing them is what lets layout descend deliberately
528
+ * rather than treating tracked content as unknown markup.
529
+ *
530
+ * ECMA-376 §17.13.5.18/.14/.25/.29. All four extend `CT_TrackChange`: `@w:id` and
531
+ * `@w:author` are required, `@w:date` is optional and is never fabricated.
532
+ *
533
+ * The SAME element names appear in property positions — `w:pPr/w:rPr/w:ins` marks a
534
+ * paragraph mark, `w:trPr/w:del` marks a row — where they carry no content and mean
535
+ * something structurally different. Those stay generic; see `contentRevisionKind`.
536
+ */
537
+ interface OoxmlRevisionContentNode extends OoxmlElementBase<readonly (OoxmlRunNode | OoxmlRevisionContentNode | OoxmlHyperlinkNode | OoxmlRangeMarkerNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
538
+ readonly kind: 'revisionInsert' | 'revisionDelete' | 'revisionMoveFrom' | 'revisionMoveTo';
539
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
540
+ readonly localName: 'ins' | 'del' | 'moveFrom' | 'moveTo';
541
+ }
542
+ /**
543
+ * `w:bookmarkStart` — a ZERO-LENGTH point anchor (`@w:id`, `@w:name`).
544
+ *
545
+ * It takes no text offset and paints nothing; it only marks a position, which is what an
546
+ * internal hyperlink's `w:anchor` names. Split and join place it by that position, the
547
+ * behaviour `tree-op-split-anchors.test.ts` pins.
548
+ */
549
+ interface OoxmlBookmarkStartNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
550
+ readonly kind: 'bookmarkStart';
551
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
552
+ readonly localName: 'bookmarkStart';
553
+ }
554
+ /** `w:bookmarkEnd` — the closing point anchor (`@w:id`), zero-length like its start. */
555
+ interface OoxmlBookmarkEndNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
556
+ readonly kind: 'bookmarkEnd';
557
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
558
+ readonly localName: 'bookmarkEnd';
559
+ }
560
+ /**
561
+ * A range marker: the move-range and comment-range boundaries.
562
+ *
563
+ * Three of the base types in this family disagree, and the disagreement is load-bearing:
564
+ *
565
+ * - `w:moveFromRangeStart` / `w:moveToRangeStart` are `CT_MoveBookmark` (§17.13.5.22/.26):
566
+ * `@w:name`, `@w:author`, and `@w:date` are all REQUIRED.
567
+ * - `w:moveFromRangeEnd` / `w:moveToRangeEnd` / `w:commentRangeStart` / `w:commentRangeEnd`
568
+ * are `CT_MarkupRange` (§17.13.5.21): `@w:id` only, with NO author and NO date. Requiring
569
+ * provenance here refuses valid files; writing it emits invalid XML.
570
+ *
571
+ * Two different join keys ride on these: `@w:name` pairs a `moveFrom` range with its
572
+ * `moveTo` range, while `@w:id` pairs a range start with its own range end. In a real
573
+ * document the two halves of a named pair carry different ids, so neither key substitutes
574
+ * for the other.
575
+ */
576
+ interface OoxmlRangeMarkerNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
577
+ readonly kind: 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
578
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
579
+ readonly localName: 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
580
+ }
581
+ /** `w:commentReference` — the in-run mark that carries the comment's anchor point. */
582
+ interface OoxmlCommentReferenceNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
583
+ readonly kind: 'commentReference';
584
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
585
+ readonly localName: 'commentReference';
586
+ }
587
+ /** The `word/comments.xml` root (`CT_Comments`, §17.13.4.2). */
588
+ interface OoxmlCommentsNode extends OoxmlElementBase<readonly (OoxmlCommentNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
589
+ readonly kind: 'comments';
590
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
591
+ readonly localName: 'comments';
592
+ }
593
+ /**
594
+ * One comment (`CT_Comment`, §17.13.4.4) — `CT_TrackChange` plus `@w:initials`, holding
595
+ * block content. The block content is why a comment body is a story rather than a string.
596
+ */
597
+ interface OoxmlCommentNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
598
+ readonly kind: 'comment';
599
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
600
+ readonly localName: 'comment';
601
+ }
602
+ /** `w:r` — a run: text and atoms sharing one set of character properties. */
603
+ interface OoxmlRunNode extends OoxmlElementBase<readonly (OoxmlRunPropertiesNode | OoxmlTextElementNode | OoxmlDeletedTextNode | OoxmlTabNode | OoxmlHardBreakNode | OoxmlCommentReferenceNode | OoxmlFldCharNode | OoxmlInstrTextNode | OoxmlNoteReferenceNode | OoxmlNoteRefNode | OoxmlSeparatorNode | OoxmlContinuationSeparatorNode | OoxmlDrawingNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
604
+ readonly kind: 'run';
605
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
606
+ readonly localName: 'r';
607
+ }
608
+ /** `w:drawing` — run content only; exactly one typed inline or anchored child. */
609
+ interface OoxmlDrawingNode extends OoxmlElementBase<readonly (OoxmlInlineDrawingNode | OoxmlAnchoredDrawingNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
610
+ readonly kind: 'drawing';
611
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
612
+ readonly localName: 'drawing';
613
+ }
614
+ /** `wp:inline` / `wp:anchor` shared payload children. */
615
+ type OoxmlDrawingAnchorChild = OoxmlDrawingExtentNode | OoxmlDrawingEffectExtentNode | OoxmlDrawingDocPrNode | OoxmlDrawingGraphicFramePrNode | OoxmlDrawingGraphicNode | OoxmlDrawingSimplePosNode | OoxmlDrawingPositionHNode | OoxmlDrawingPositionVNode | OoxmlDrawingWrapNoneNode | OoxmlDrawingWrapSquareNode | OoxmlDrawingWrapTightNode | OoxmlDrawingWrapThroughNode | OoxmlDrawingWrapTopBottomNode | OoxmlGenericElementNode;
616
+ /** `wp:inline` (`CT_Inline`) — typed only under `w:drawing`. */
617
+ interface OoxmlInlineDrawingNode extends OoxmlElementBase<readonly OoxmlDrawingAnchorChild[], readonly OoxmlKnownNodeAttribute[]> {
618
+ readonly kind: 'inlineDrawing';
619
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
620
+ readonly localName: 'inline';
621
+ }
622
+ /** `wp:anchor` (`CT_Anchor`) — typed only under `w:drawing`. */
623
+ interface OoxmlAnchoredDrawingNode extends OoxmlElementBase<readonly OoxmlDrawingAnchorChild[], readonly OoxmlKnownNodeAttribute[]> {
624
+ readonly kind: 'anchoredDrawing';
625
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
626
+ readonly localName: 'anchor';
627
+ }
628
+ interface OoxmlDrawingExtentNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
629
+ readonly kind: 'drawingExtent';
630
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
631
+ readonly localName: 'extent';
632
+ }
633
+ interface OoxmlDrawingEffectExtentNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
634
+ readonly kind: 'drawingEffectExtent';
635
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
636
+ readonly localName: 'effectExtent';
637
+ }
638
+ interface OoxmlDrawingDocPrNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
639
+ readonly kind: 'drawingDocPr';
640
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
641
+ readonly localName: 'docPr';
642
+ }
643
+ interface OoxmlDrawingGraphicFramePrNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
644
+ readonly kind: 'drawingGraphicFramePr';
645
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
646
+ readonly localName: 'cNvGraphicFramePr';
647
+ }
648
+ interface OoxmlDrawingGraphicNode extends OoxmlElementBase<readonly (OoxmlDrawingGraphicDataNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
649
+ readonly kind: 'drawingGraphic';
650
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
651
+ readonly localName: 'graphic';
652
+ }
653
+ interface OoxmlDrawingGraphicDataNode extends OoxmlElementBase<readonly (OoxmlPictureNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
654
+ readonly kind: 'drawingGraphicData';
655
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
656
+ readonly localName: 'graphicData';
657
+ }
658
+ interface OoxmlDrawingSimplePosNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
659
+ readonly kind: 'drawingSimplePos';
660
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
661
+ readonly localName: 'simplePos';
662
+ }
663
+ interface OoxmlDrawingPositionHNode extends OoxmlElementBase<readonly (OoxmlDrawingPositionAlignNode | OoxmlDrawingPositionOffsetNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
664
+ readonly kind: 'drawingPositionH';
665
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
666
+ readonly localName: 'positionH';
667
+ }
668
+ interface OoxmlDrawingPositionVNode extends OoxmlElementBase<readonly (OoxmlDrawingPositionAlignNode | OoxmlDrawingPositionOffsetNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
669
+ readonly kind: 'drawingPositionV';
670
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
671
+ readonly localName: 'positionV';
672
+ }
673
+ interface OoxmlDrawingPositionAlignNode extends OoxmlElementBase<readonly (OoxmlTextNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
674
+ readonly kind: 'drawingPositionAlign';
675
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
676
+ readonly localName: 'align';
677
+ }
678
+ interface OoxmlDrawingPositionOffsetNode extends OoxmlElementBase<readonly (OoxmlTextNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
679
+ readonly kind: 'drawingPositionOffset';
680
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
681
+ readonly localName: 'posOffset';
682
+ }
683
+ interface OoxmlDrawingWrapNoneNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
684
+ readonly kind: 'drawingWrapNone';
685
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
686
+ readonly localName: 'wrapNone';
687
+ }
688
+ interface OoxmlDrawingWrapSquareNode extends OoxmlElementBase<readonly (OoxmlDrawingEffectExtentNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
689
+ readonly kind: 'drawingWrapSquare';
690
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
691
+ readonly localName: 'wrapSquare';
692
+ }
693
+ interface OoxmlDrawingWrapTightNode extends OoxmlElementBase<readonly (OoxmlDrawingWrapPolygonNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
694
+ readonly kind: 'drawingWrapTight';
695
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
696
+ readonly localName: 'wrapTight';
697
+ }
698
+ interface OoxmlDrawingWrapThroughNode extends OoxmlElementBase<readonly (OoxmlDrawingWrapPolygonNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
699
+ readonly kind: 'drawingWrapThrough';
700
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
701
+ readonly localName: 'wrapThrough';
702
+ }
703
+ interface OoxmlDrawingWrapTopBottomNode extends OoxmlElementBase<readonly (OoxmlDrawingEffectExtentNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
704
+ readonly kind: 'drawingWrapTopBottom';
705
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
706
+ readonly localName: 'wrapTopAndBottom';
707
+ }
708
+ interface OoxmlDrawingWrapPolygonNode extends OoxmlElementBase<readonly (OoxmlDrawingWrapPolygonStartNode | OoxmlDrawingWrapPolygonLineToNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
709
+ readonly kind: 'drawingWrapPolygon';
710
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
711
+ readonly localName: 'wrapPolygon';
712
+ }
713
+ interface OoxmlDrawingWrapPolygonStartNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
714
+ readonly kind: 'drawingWrapPolygonStart';
715
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
716
+ readonly localName: 'start';
717
+ }
718
+ interface OoxmlDrawingWrapPolygonLineToNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
719
+ readonly kind: 'drawingWrapPolygonLineTo';
720
+ readonly namespaceUri: typeof WP_NAMESPACE_URI;
721
+ readonly localName: 'lineTo';
722
+ }
723
+ /** `pic:pic` (`CT_Picture`) — typed only under picture `a:graphicData`. */
724
+ interface OoxmlPictureNode extends OoxmlElementBase<readonly (OoxmlPictureNvPicPrNode | OoxmlPictureBlipFillNode | OoxmlPictureShapePropertiesNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
725
+ readonly kind: 'picture';
726
+ readonly namespaceUri: typeof PIC_NAMESPACE_URI;
727
+ readonly localName: 'pic';
728
+ }
729
+ interface OoxmlPictureNvPicPrNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
730
+ readonly kind: 'pictureNvPicPr';
731
+ readonly namespaceUri: typeof PIC_NAMESPACE_URI;
732
+ readonly localName: 'nvPicPr';
733
+ }
734
+ interface OoxmlPictureBlipFillNode extends OoxmlElementBase<readonly (OoxmlPictureBlipNode | OoxmlPictureSrcRectNode | OoxmlPictureStretchNode | OoxmlPictureTileNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
735
+ readonly kind: 'pictureBlipFill';
736
+ readonly namespaceUri: typeof PIC_NAMESPACE_URI;
737
+ readonly localName: 'blipFill';
738
+ }
739
+ interface OoxmlPictureBlipNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
740
+ readonly kind: 'pictureBlip';
741
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
742
+ readonly localName: 'blip';
743
+ }
744
+ interface OoxmlPictureSrcRectNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
745
+ readonly kind: 'pictureSrcRect';
746
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
747
+ readonly localName: 'srcRect';
748
+ }
749
+ interface OoxmlPictureStretchNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
750
+ readonly kind: 'pictureStretch';
751
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
752
+ readonly localName: 'stretch';
753
+ }
754
+ interface OoxmlPictureTileNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
755
+ readonly kind: 'pictureTile';
756
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
757
+ readonly localName: 'tile';
758
+ }
759
+ interface OoxmlPictureShapePropertiesNode extends OoxmlElementBase<readonly (OoxmlPictureTransformNode | OoxmlPicturePresetGeometryNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
760
+ readonly kind: 'pictureShapeProperties';
761
+ readonly namespaceUri: typeof PIC_NAMESPACE_URI;
762
+ readonly localName: 'spPr';
763
+ }
764
+ interface OoxmlPictureTransformNode extends OoxmlElementBase<readonly (OoxmlPictureTransformOffsetNode | OoxmlPictureTransformExtentNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
765
+ readonly kind: 'pictureTransform';
766
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
767
+ readonly localName: 'xfrm';
768
+ }
769
+ interface OoxmlPictureTransformOffsetNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
770
+ readonly kind: 'pictureTransformOffset';
771
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
772
+ readonly localName: 'off';
773
+ }
774
+ interface OoxmlPictureTransformExtentNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
775
+ readonly kind: 'pictureTransformExtent';
776
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
777
+ readonly localName: 'ext';
778
+ }
779
+ interface OoxmlPicturePresetGeometryNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
780
+ readonly kind: 'picturePresetGeometry';
781
+ readonly namespaceUri: typeof DRAWINGML_MAIN_NAMESPACE_URI;
782
+ readonly localName: 'prstGeom';
783
+ }
784
+ /**
785
+ * `w:delText` (§17.3.3.7) — the text container a run uses once its content is deleted.
786
+ *
787
+ * Structurally identical to `w:t`, and deliberately a DIFFERENT kind: it must never flow
788
+ * as ordinary text, and rejecting the deletion that contains it turns it back into `w:t`.
789
+ */
790
+ interface OoxmlDeletedTextNode extends OoxmlElementBase<readonly OoxmlTextNode[], readonly OoxmlKnownNodeAttribute[]> {
791
+ readonly kind: 'deletedText';
792
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
793
+ readonly localName: 'delText';
794
+ }
795
+ /**
796
+ * `w:rPr` — a run's character properties, whose children stay GENERIC.
797
+ *
798
+ * Deliberately unmodelled below this point: the property vocabulary is large and mostly
799
+ * uninteresting to layout, so carrying it verbatim preserves everything without the engine having
800
+ * to know what each element means.
801
+ */
802
+ interface OoxmlRunPropertiesNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
803
+ readonly kind: 'runProperties';
804
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
805
+ readonly localName: 'rPr';
806
+ }
807
+ /** `w:t` — the element holding a run's literal characters. */
808
+ interface OoxmlTextElementNode extends OoxmlElementBase<readonly OoxmlTextNode[], readonly OoxmlKnownNodeAttribute[]> {
809
+ readonly kind: 'text';
810
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
811
+ readonly localName: 't';
812
+ }
813
+ /** `w:pPr` — a paragraph's properties. Children stay generic, like `w:rPr`'s. */
814
+ interface OoxmlParagraphPropertiesNode extends OoxmlElementBase<readonly (OoxmlRunPropertiesNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
815
+ readonly kind: 'paragraphProperties';
816
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
817
+ readonly localName: 'pPr';
818
+ }
819
+ /** `w:tab` inside a run — one tab character as its own element. */
820
+ interface OoxmlTabNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
821
+ readonly kind: 'tab';
822
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
823
+ readonly localName: 'tab';
824
+ }
825
+ /** `w:br` — a line, column or page break inside a run. */
826
+ interface OoxmlHardBreakNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
827
+ readonly kind: 'hardBreak';
828
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
829
+ readonly localName: 'br';
830
+ }
831
+ /**
832
+ * Complex-field character (`w:fldChar`).
833
+ *
834
+ * Children stay generic so `w:ffData` (legacy form fields / macros) round-trips as inert
835
+ * payload and is never promoted to an executable surface. `@w:fldCharType`, `@w:dirty`,
836
+ * and `@w:fldLock` are preserved on `attributes`.
837
+ */
838
+ interface OoxmlFldCharNode extends OoxmlElementBase<readonly OoxmlGenericElementNode[], readonly OoxmlKnownNodeAttribute[]> {
839
+ readonly kind: 'fldChar';
840
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
841
+ readonly localName: 'fldChar';
842
+ }
843
+ /**
844
+ * Field instruction text (`w:instrText`), same text-carrier shape as `w:t`.
845
+ *
846
+ * Instruction strings are never executed; layout may recognize allowlisted page-number
847
+ * keywords only.
848
+ */
849
+ interface OoxmlInstrTextNode extends OoxmlElementBase<readonly OoxmlTextNode[], readonly OoxmlKnownNodeAttribute[]> {
850
+ readonly kind: 'instrText';
851
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
852
+ readonly localName: 'instrText';
853
+ }
854
+ /**
855
+ * Simple field (`w:fldSimple`) at paragraph content level.
856
+ *
857
+ * `@w:instr`, `@w:dirty`, and `@w:fldLock` round-trip on `attributes`. Cached result
858
+ * children stay structurally preserved; the field is one atomic addressable unit.
859
+ */
860
+ interface OoxmlFldSimpleNode extends OoxmlElementBase<readonly (OoxmlRunNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
861
+ readonly kind: 'fldSimple';
862
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
863
+ readonly localName: 'fldSimple';
864
+ }
865
+ /**
866
+ * Footnotes part root (`w:footnotes`). Children are typed notes or preserved generics.
867
+ * Never a story root itself — each note body is its own story for layout.
868
+ */
869
+ interface OoxmlFootnotesNode extends OoxmlElementBase<readonly (OoxmlNoteNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
870
+ readonly kind: 'footnotes';
871
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
872
+ readonly localName: 'footnotes';
873
+ }
874
+ /**
875
+ * Endnotes part root (`w:endnotes`). Same content model as {@link OoxmlFootnotesNode}.
876
+ */
877
+ interface OoxmlEndnotesNode extends OoxmlElementBase<readonly (OoxmlNoteNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
878
+ readonly kind: 'endnotes';
879
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
880
+ readonly localName: 'endnotes';
881
+ }
882
+ /**
883
+ * One footnote or endnote (`w:footnote` / `w:endnote`).
884
+ *
885
+ * Discriminated by `localName`. `@w:id` and optional `@w:type` (`ST_FtnEdn`, including
886
+ * authored `normal`) live on `attributes`. Children are ordinary block content.
887
+ */
888
+ interface OoxmlNoteNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
889
+ readonly kind: 'note';
890
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
891
+ readonly localName: 'footnote' | 'endnote';
892
+ }
893
+ /**
894
+ * Body citation (`w:footnoteReference` / `w:endnoteReference`) as a typed run child.
895
+ * Display mark is derived — never stored as text. One UTF-16 atom in addressing.
896
+ */
897
+ interface OoxmlNoteReferenceNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
898
+ readonly kind: 'noteReference';
899
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
900
+ readonly localName: 'footnoteReference' | 'endnoteReference';
901
+ }
902
+ /**
903
+ * Auto mark inside a note body (`w:footnoteRef` / `w:endnoteRef`).
904
+ * One UTF-16 atom; display digit is derived at paint time.
905
+ */
906
+ interface OoxmlNoteRefNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
907
+ readonly kind: 'noteRef';
908
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
909
+ readonly localName: 'footnoteRef' | 'endnoteRef';
910
+ }
911
+ /** Run-inner separator rule (`w:separator`). One UTF-16 atom. */
912
+ interface OoxmlSeparatorNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
913
+ readonly kind: 'separator';
914
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
915
+ readonly localName: 'separator';
916
+ }
917
+ /** Run-inner continuation separator (`w:continuationSeparator`). One UTF-16 atom. */
918
+ interface OoxmlContinuationSeparatorNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
919
+ readonly kind: 'continuationSeparator';
920
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
921
+ readonly localName: 'continuationSeparator';
922
+ }
923
+ /**
924
+ * `w:sdt` — structured document tag (content control) at block, inline, row, or cell level.
925
+ *
926
+ * Placement is not a separate kind: the same element name appears in every `EG_*Content`
927
+ * group. Child shape is the union of those placements; parents admit the control wherever
928
+ * `generic` was previously accepted (see `isPreservedChild`). Identity is the node id —
929
+ * `w:id` inside `w:sdtPr` is optional, preserved when present, never fabricated here.
930
+ */
931
+ interface OoxmlContentControlNode extends OoxmlElementBase<readonly (OoxmlContentControlPropertiesNode | OoxmlContentControlEndPropertiesNode | OoxmlContentControlContentNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
932
+ readonly kind: 'contentControl';
933
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
934
+ readonly localName: 'sdt';
935
+ }
936
+ /**
937
+ * `w:sdtPr` (`CT_SdtPr`) — schema-ordered properties. Unmodelled children (alias/tag/id/lock
938
+ * leaves with `w:val`, `w15:*`, empty type markers) stay `generic` in position. Typed
939
+ * payloads: dropdown/combo/listItem, date (+ leaves), text, dataBinding, `w14:checkbox`.
940
+ */
941
+ interface OoxmlContentControlPropertiesNode extends OoxmlElementBase<readonly (OoxmlRunPropertiesNode | OoxmlContentControlDataBindingNode | OoxmlContentControlDropDownListNode | OoxmlContentControlComboBoxNode | OoxmlContentControlDateNode | OoxmlContentControlTextNode | OoxmlContentControlCheckboxNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
942
+ readonly kind: 'contentControlProperties';
943
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
944
+ readonly localName: 'sdtPr';
945
+ }
946
+ /** `w:sdtEndPr` — end-character properties; children are `w:rPr` or generic. */
947
+ interface OoxmlContentControlEndPropertiesNode extends OoxmlElementBase<readonly (OoxmlRunPropertiesNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
948
+ readonly kind: 'contentControlEndProperties';
949
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
950
+ readonly localName: 'sdtEndPr';
951
+ }
952
+ /**
953
+ * `w:sdtContent` — control contents for every placement. Block content is paragraphs/tables;
954
+ * inline content is runs/hyperlinks; row/cell content is rows/cells. Nested controls stay typed.
955
+ */
956
+ interface OoxmlContentControlContentNode extends OoxmlElementBase<readonly OoxmlNode[], readonly OoxmlKnownNodeAttribute[]> {
957
+ readonly kind: 'contentControlContent';
958
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
959
+ readonly localName: 'sdtContent';
960
+ }
961
+ /** `w:dropDownList` — `@w:lastValue` plus typed `w:listItem` children. */
962
+ interface OoxmlContentControlDropDownListNode extends OoxmlElementBase<readonly (OoxmlContentControlListItemNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
963
+ readonly kind: 'contentControlDropDownList';
964
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
965
+ readonly localName: 'dropDownList';
966
+ }
967
+ /** `w:comboBox` — same payload shape as dropdown; free entry is an editing concern. */
968
+ interface OoxmlContentControlComboBoxNode extends OoxmlElementBase<readonly (OoxmlContentControlListItemNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
969
+ readonly kind: 'contentControlComboBox';
970
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
971
+ readonly localName: 'comboBox';
972
+ }
973
+ /** `w:listItem` — `@w:displayText` / `@w:value` as preserved attributes (not `w:val`). */
974
+ interface OoxmlContentControlListItemNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
975
+ readonly kind: 'contentControlListItem';
976
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
977
+ readonly localName: 'listItem';
978
+ }
979
+ /**
980
+ * `w:date` — `@w:fullDate` plus typed dateFormat/lid/storeMappedDataAs/calendar leaves.
981
+ * Those leaves allow `w:val` (the only known kinds that do) so they are not demoted.
982
+ */
983
+ interface OoxmlContentControlDateNode extends OoxmlElementBase<readonly (OoxmlContentControlDateFormatNode | OoxmlContentControlLidNode | OoxmlContentControlStoreMappedDataAsNode | OoxmlContentControlCalendarNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
984
+ readonly kind: 'contentControlDate';
985
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
986
+ readonly localName: 'date';
987
+ }
988
+ /** `w:dateFormat` — the picture string a date picker formats its value with. */
989
+ interface OoxmlContentControlDateFormatNode extends OoxmlElementBase<readonly [], readonly (OoxmlKnownNodeAttribute | OoxmlWmlValAttribute)[]> {
990
+ readonly kind: 'contentControlDateFormat';
991
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
992
+ readonly localName: 'dateFormat';
993
+ }
994
+ /** `w:lid` — the language id a date picker parses and formats under. */
995
+ interface OoxmlContentControlLidNode extends OoxmlElementBase<readonly [], readonly (OoxmlKnownNodeAttribute | OoxmlWmlValAttribute)[]> {
996
+ readonly kind: 'contentControlLid';
997
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
998
+ readonly localName: 'lid';
999
+ }
1000
+ /** `w:storeMappedDataAs` — which representation a bound date is written to its XML part as. */
1001
+ interface OoxmlContentControlStoreMappedDataAsNode extends OoxmlElementBase<readonly [], readonly (OoxmlKnownNodeAttribute | OoxmlWmlValAttribute)[]> {
1002
+ readonly kind: 'contentControlStoreMappedDataAs';
1003
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
1004
+ readonly localName: 'storeMappedDataAs';
1005
+ }
1006
+ /** `w:calendar` — which calendar system a date picker uses (Gregorian, Hijri, …). */
1007
+ interface OoxmlContentControlCalendarNode extends OoxmlElementBase<readonly [], readonly (OoxmlKnownNodeAttribute | OoxmlWmlValAttribute)[]> {
1008
+ readonly kind: 'contentControlCalendar';
1009
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
1010
+ readonly localName: 'calendar';
1011
+ }
1012
+ /** `w:text` (`CT_SdtText`) — distinct from `w:t` (`kind: 'text'`). `@w:multiLine` preserved. */
1013
+ interface OoxmlContentControlTextNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
1014
+ readonly kind: 'contentControlText';
1015
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
1016
+ readonly localName: 'text';
1017
+ }
1018
+ /**
1019
+ * `w:dataBinding` — xpath / storeItemID / prefixMappings preserved as attributes.
1020
+ * This tree never resolves or fetches the binding target.
1021
+ */
1022
+ interface OoxmlContentControlDataBindingNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
1023
+ readonly kind: 'contentControlDataBinding';
1024
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
1025
+ readonly localName: 'dataBinding';
1026
+ }
1027
+ /**
1028
+ * `w14:checkbox` — Microsoft extension, not an ECMA-376 type choice. Distinguishable from
1029
+ * untyped rich-text controls that merely wrap a `w:sym`.
1030
+ */
1031
+ interface OoxmlContentControlCheckboxNode extends OoxmlElementBase<readonly (OoxmlContentControlCheckedNode | OoxmlContentControlCheckedStateNode | OoxmlContentControlUncheckedStateNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
1032
+ readonly kind: 'contentControlCheckbox';
1033
+ readonly namespaceUri: typeof W14_NAMESPACE_URI;
1034
+ readonly localName: 'checkbox';
1035
+ }
1036
+ /** `w14:checked` — a checkbox's recorded state, independent of the glyph drawn for it. */
1037
+ interface OoxmlContentControlCheckedNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
1038
+ readonly kind: 'contentControlChecked';
1039
+ readonly namespaceUri: typeof W14_NAMESPACE_URI;
1040
+ readonly localName: 'checked';
1041
+ }
1042
+ /** `w14:checkedState` — the font and code point drawn when a checkbox is checked. */
1043
+ interface OoxmlContentControlCheckedStateNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
1044
+ readonly kind: 'contentControlCheckedState';
1045
+ readonly namespaceUri: typeof W14_NAMESPACE_URI;
1046
+ readonly localName: 'checkedState';
1047
+ }
1048
+ /** `w14:uncheckedState` — the font and code point drawn when a checkbox is not checked. */
1049
+ interface OoxmlContentControlUncheckedStateNode extends OoxmlElementBase<readonly [], readonly OoxmlKnownNodeAttribute[]> {
1050
+ readonly kind: 'contentControlUncheckedState';
1051
+ readonly namespaceUri: typeof W14_NAMESPACE_URI;
1052
+ readonly localName: 'uncheckedState';
1053
+ }
1054
+ /**
1055
+ * Any element the typed vocabulary does not cover — the other half of the preservation model.
1056
+ *
1057
+ * Also where a KNOWN element lands when it appears somewhere invalid: an element is demoted to
1058
+ * generic rather than rejected, so malformed or unfamiliar content is carried losslessly and
1059
+ * never locks editing.
1060
+ */
1061
+ interface OoxmlGenericElementNode extends OoxmlElementBase<readonly OoxmlNode[]> {
1062
+ readonly kind: 'generic';
1063
+ }
1064
+ /** A literal text value. The only node kind with no children and no attributes. */
1065
+ interface OoxmlTextNode {
1066
+ readonly id: OoxmlNodeId;
1067
+ readonly kind: 'textValue';
1068
+ readonly value: string;
1069
+ }
1070
+ /** Every element node kind: the typed vocabulary plus the generic catch-all. */
1071
+ type OoxmlElement = OoxmlDocumentNode | OoxmlBodyNode | OoxmlParagraphNode | OoxmlRunNode | OoxmlHyperlinkNode | OoxmlBookmarkStartNode | OoxmlBookmarkEndNode | OoxmlRunPropertiesNode | OoxmlTextElementNode | OoxmlDeletedTextNode | OoxmlParagraphPropertiesNode | OoxmlTabNode | OoxmlHardBreakNode | OoxmlFldCharNode | OoxmlInstrTextNode | OoxmlFldSimpleNode | OoxmlFootnotesNode | OoxmlEndnotesNode | OoxmlNoteNode | OoxmlNoteReferenceNode | OoxmlNoteRefNode | OoxmlSeparatorNode | OoxmlContinuationSeparatorNode | OoxmlTableNode | OoxmlTableRowNode | OoxmlTableCellNode | OoxmlTableGridNode | OoxmlTablePropertiesNode | OoxmlRevisionContentNode | OoxmlRangeMarkerNode | OoxmlCommentReferenceNode | OoxmlCommentsNode | OoxmlCommentNode | OoxmlContentControlNode | OoxmlContentControlPropertiesNode | OoxmlContentControlEndPropertiesNode | OoxmlContentControlContentNode | OoxmlContentControlDropDownListNode | OoxmlContentControlComboBoxNode | OoxmlContentControlListItemNode | OoxmlContentControlDateNode | OoxmlContentControlDateFormatNode | OoxmlContentControlLidNode | OoxmlContentControlStoreMappedDataAsNode | OoxmlContentControlCalendarNode | OoxmlContentControlTextNode | OoxmlContentControlDataBindingNode | OoxmlContentControlCheckboxNode | OoxmlContentControlCheckedNode | OoxmlContentControlCheckedStateNode | OoxmlContentControlUncheckedStateNode | OoxmlDrawingNode | OoxmlInlineDrawingNode | OoxmlAnchoredDrawingNode | OoxmlDrawingExtentNode | OoxmlDrawingEffectExtentNode | OoxmlDrawingDocPrNode | OoxmlDrawingGraphicFramePrNode | OoxmlDrawingGraphicNode | OoxmlDrawingGraphicDataNode | OoxmlDrawingSimplePosNode | OoxmlDrawingPositionHNode | OoxmlDrawingPositionVNode | OoxmlDrawingPositionAlignNode | OoxmlDrawingPositionOffsetNode | OoxmlDrawingWrapNoneNode | OoxmlDrawingWrapSquareNode | OoxmlDrawingWrapTightNode | OoxmlDrawingWrapThroughNode | OoxmlDrawingWrapTopBottomNode | OoxmlDrawingWrapPolygonNode | OoxmlDrawingWrapPolygonStartNode | OoxmlDrawingWrapPolygonLineToNode | OoxmlPictureNode | OoxmlPictureNvPicPrNode | OoxmlPictureBlipFillNode | OoxmlPictureBlipNode | OoxmlPictureSrcRectNode | OoxmlPictureStretchNode | OoxmlPictureTileNode | OoxmlPictureShapePropertiesNode | OoxmlPictureTransformNode | OoxmlPictureTransformOffsetNode | OoxmlPictureTransformExtentNode | OoxmlPicturePresetGeometryNode | OoxmlGenericElementNode;
1072
+ /**
1073
+ * Any node in the canonical tree.
1074
+ *
1075
+ * Typed where layout needs structure, generic everywhere else — one tree carries a whole document
1076
+ * whether or not the engine understands every part of it.
1077
+ */
1078
+ type OoxmlNode = OoxmlElement | OoxmlTextNode;
1079
+ /** One XML part of the package, parsed into a canonical tree. */
1080
+ interface OoxmlPart {
1081
+ readonly id: string;
1082
+ /** Canonical part name, e.g. `/word/document.xml`. */
1083
+ readonly name: string;
1084
+ readonly contentType: string;
1085
+ readonly root: OoxmlElement;
1086
+ }
1087
+ /** A part's identity without its tree — enough to enumerate a package cheaply. */
1088
+ interface OoxmlPartMetadata {
1089
+ readonly name: string;
1090
+ readonly contentType: string;
1091
+ }
1092
+ /**
1093
+ * Why a part could not be read into a tree.
1094
+ *
1095
+ * Widens the XML-level rejections with the tree-level ones. All of them describe the FILE, which
1096
+ * is why reading returns a result rather than throwing.
1097
+ */
1098
+ type OoxmlReadRejection = XmlRejection | 'missing-root' | 'multiple-roots' | 'invalid-name' | 'invalid-namespace' | 'undeclared-prefix' | 'duplicate-expanded-attribute';
1099
+ /** A parsed part, or a typed refusal. Never throws — the input is untrusted by definition. */
1100
+ type OoxmlReadResult = {
1101
+ readonly ok: true;
1102
+ readonly part: OoxmlPart;
1103
+ } | {
1104
+ readonly ok: false;
1105
+ readonly reason: OoxmlReadRejection;
1106
+ };
1107
+ /**
1108
+ * The node-identity contract, written down as a type so it is checkable rather than merely
1109
+ * documented.
1110
+ *
1111
+ * Ids are deterministic from a normalized parse, retained through structural sharing, explicit on
1112
+ * replacement, and unique within a part. Everything that addresses nodes — ops, the caret, the
1113
+ * paraId bimap — depends on all four holding.
1114
+ */
1115
+ interface OoxmlNodeIdentityRules {
1116
+ readonly initial: 'deterministic-structural-path-after-normalized-parse';
1117
+ readonly unchanged: 'retain-id-through-structural-sharing';
1118
+ readonly replacement: 'explicitly-retain-or-allocate';
1119
+ readonly uniqueness: 'unique-within-part';
1120
+ }
1121
+ /**
1122
+ * Identity policy for future immutable tree edits. This defines the boundary
1123
+ * without implementing task 2.4 edit primitives.
1124
+ */
1125
+ declare const OOXML_NODE_IDENTITY_RULES: OoxmlNodeIdentityRules;
1126
+ /** What a tree invariant walk found wrong. Each names a rule the canonical tree must satisfy. */
1127
+ type OoxmlInvariantIssueCode = 'invalid-id' | 'duplicate-id' | 'invalid-name' | 'invalid-namespace' | 'invalid-qname' | 'duplicate-expanded-attribute' | 'invalid-xml-value' | 'known-node-invariant';
1128
+ /** One invariant violation, located by structural path and node id. */
1129
+ interface OoxmlInvariantIssue {
1130
+ readonly code: OoxmlInvariantIssueCode;
1131
+ readonly path: string;
1132
+ readonly nodeId?: string;
1133
+ }
1134
+ /** Whether a tree satisfies its invariants, listing every violation when it does not. */
1135
+ type OoxmlInvariantResult = {
1136
+ readonly ok: true;
1137
+ } | {
1138
+ readonly ok: false;
1139
+ readonly issues: readonly OoxmlInvariantIssue[];
1140
+ };
1141
+ /**
1142
+ * Read one XML part into the additive typed/generic foundation. Existing package
1143
+ * parsing and DocumentStore models intentionally remain unchanged until their
1144
+ * later migration tasks; this tree is not yet the repository's sole runtime authority.
1145
+ * Structural-path IDs are deterministic across normalized reopen. Preserving an
1146
+ * identity through moves and edits is deferred to PackageModel/DocumentStore integration.
1147
+ */
1148
+ declare function readOoxmlPart(xml: string, metadata: OoxmlPartMetadata, limits?: XmlLimits): OoxmlReadResult;
1149
+
1150
+ /**
1151
+ * Why a zip was refused at the trust boundary.
1152
+ *
1153
+ * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
1154
+ * an entry with `..` or a leading `/` is rejected rather than normalized.
1155
+ */
1156
+ type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
1157
+ /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
1158
+ interface ZipLimits {
1159
+ readonly maxEntries: number;
1160
+ /** Max total UNCOMPRESSED bytes across the archive. */
1161
+ readonly maxTotalBytes: number;
1162
+ /** Max per-entry uncompressed:compressed ratio (zip-bomb guard). */
1163
+ readonly maxRatio?: number;
1164
+ }
1165
+ /** The archive caps in force when a host configures none. Conservative and finite. */
1166
+ declare const DEFAULT_ZIP_LIMITS: ZipLimits;
1167
+ /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
1168
+ type ZipReadResult = {
1169
+ readonly ok: true;
1170
+ readonly entries: ReadonlyMap<string, Uint8Array>;
1171
+ } | {
1172
+ readonly ok: false;
1173
+ readonly reason: ZipRejection;
1174
+ readonly detail?: string;
1175
+ };
1176
+ /**
1177
+ * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count,
1178
+ * compression-ratio, and total-uncompressed-size limits are enforced BEFORE each
1179
+ * entry is decompressed (via fflate's pre-inflation filter), so a zip bomb or a
1180
+ * traversal name is rejected without ever being inflated. Keys are canonical part
1181
+ * names.
1182
+ */
1183
+ declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
1184
+ /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
1185
+ * is re-validated through the OPC normalization profile before writing, so a
1186
+ * traversal/encoded/normalized-alias name from an untrusted serialized model can
1187
+ * never be smuggled into a ZIP entry (write-side path-traversal guard). */
1188
+ declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
1189
+
1190
+ /** The relationship namespace `r:id` lives in. */
1191
+ declare const OFFICE_RELATIONSHIP_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
1192
+ /** The `Type` a hyperlink relationship declares. */
1193
+ declare const HYPERLINK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
1194
+ /**
1195
+ * What a part's relationships answer for one `r:id`: the authored target and whether the
1196
+ * package declared it external. `null` for an id the part does not declare — a DANGLING
1197
+ * relationship, which is a real thing in real documents.
1198
+ */
1199
+ type RelationshipTargetResolver = (relationshipId: string) => {
1200
+ readonly target: string;
1201
+ readonly external: boolean;
1202
+ /**
1203
+ * The PACKAGE's own verdict on this target (`validateExternalTarget`): whether it is an
1204
+ * absolute URI with a safe scheme.
1205
+ *
1206
+ * Carried separately because `sanitizeHref` cannot answer it. That function is a SCHEME
1207
+ * allowlist and deliberately admits relative URLs — the right rule for a value the host
1208
+ * authored, and the wrong one for a value a `.docx` did. A file-supplied
1209
+ * `Target="/admin/delete-account"` has no scheme to refuse, so it would pass the
1210
+ * allowlist and resolve against the EMBEDDING APPLICATION'S origin: a link reading
1211
+ * "Company policy" that issues an authenticated same-origin request to whatever host
1212
+ * app the editor is mounted in. Absent, a target is treated as unverified.
1213
+ */
1214
+ readonly sinkSafe?: boolean;
1215
+ } | null;
1216
+ /**
1217
+ * What a hyperlink points at, which decides what activating it may do.
1218
+ *
1219
+ * The security-relevant split: an `external` link goes through `sanitizeHref` and opens only on
1220
+ * explicit user action, while an anchor merely scrolls and never navigates.
1221
+ */
1222
+ type HyperlinkKind =
1223
+ /** `r:id` → a relationship with `TargetMode="External"`. Opens somewhere else. */
1224
+ 'external'
1225
+ /** `w:anchor` → a bookmark in this document. Scrolls, never navigates. */
1226
+ | 'internal'
1227
+ /**
1228
+ * `r:id` naming a relationship the part does not declare, or one that is not external.
1229
+ *
1230
+ * The link keeps its runs — the text is never lost twice — but there is nothing to
1231
+ * activate, so it paints inert exactly like a refused scheme.
1232
+ */
1233
+ | 'unresolved';
1234
+ /** A resolved hyperlink: its kind, its target, and the tooltip Word shows on hover. */
1235
+ interface HyperlinkTarget {
1236
+ readonly kind: HyperlinkKind;
1237
+ /**
1238
+ * The authored target, verbatim: the relationship's `Target` for an `r:id` link, the
1239
+ * anchor name for an internal one. Save re-emits from the tree, never from this — it is
1240
+ * here so a UI can show what the document actually says.
1241
+ */
1242
+ readonly authored: string;
1243
+ /**
1244
+ * The sanitized runtime projection, or `null` when there is nothing safe to navigate to.
1245
+ * The ONLY value permitted in a DOM `href`, `window.open`, or a copied link.
1246
+ */
1247
+ readonly href: string | null;
1248
+ /** `w:anchor`, for an internal link. */
1249
+ readonly anchor?: string;
1250
+ /** `w:tooltip` — Word's hover text; paint puts it on the anchor's `title`. */
1251
+ readonly tooltip?: string;
1252
+ /** The authored `r:id`, so an edit can rewrite the relationship it names. */
1253
+ readonly relationshipId?: string;
1254
+ }
1255
+ /** Whether a node is a typed `w:hyperlink`. */
1256
+ declare function isHyperlinkNode(node: OoxmlNode): boolean;
1257
+ /** A typed hyperlink's `w:anchor`, or undefined. */
1258
+ declare function hyperlinkAnchorOf(link: OoxmlNode): string | undefined;
1259
+ /** A typed hyperlink's `r:id`, or undefined. */
1260
+ declare function hyperlinkRelationshipIdOf(link: OoxmlNode): string | undefined;
1261
+ /**
1262
+ * Read a typed `w:hyperlink` into its target record.
1263
+ *
1264
+ * `r:id` wins over `w:anchor` when a link carries both, matching Word: the relationship
1265
+ * names the document and the anchor names a place inside it, so the pair is a link to a
1266
+ * bookmark in ANOTHER file — which this engine will not follow, but whose external half is
1267
+ * the part that decides where it points.
1268
+ *
1269
+ * A link with neither is `unresolved`: it paints its runs and does nothing.
1270
+ */
1271
+ declare function hyperlinkTargetOf(link: OoxmlNode, resolve: RelationshipTargetResolver): HyperlinkTarget;
1272
+
1273
+ interface DrawingProjectionLimits {
1274
+ readonly maxCompatibilityBranches: number;
1275
+ readonly maxVisitedElements: number;
1276
+ readonly maxDrawingDepth: number;
1277
+ }
1278
+ interface DrawingDiagnostic {
1279
+ readonly code: 'malformed-drawing' | 'unsupported-graphic' | 'unresolvable-frame' | 'invalid-geometry' | 'resource-refused' | 'wrap-polygon-over-limit' | 'wrap-polygon-malformed';
1280
+ readonly nodeId: string;
1281
+ readonly detail: string | null;
1282
+ }
1283
+
1284
+ /**
1285
+ * The renderable subset of a `wps:wsp` non-picture graphic: closed polygon subpaths
1286
+ * (`a:custGeom` with move/line/close verbs only, or `a:prstGeom prst="rect"`) with a
1287
+ * solid sRGB fill and/or stroke. Anything richer (curves, theme fills, text bodies,
1288
+ * rotation) projects as `null` and paints the labelled placeholder instead.
1289
+ */
1290
+ interface VectorShapeProjection {
1291
+ /** The drawing extent that frames the subpath coordinate space. */
1292
+ readonly extentEmu: Readonly<{
1293
+ cx: number;
1294
+ cy: number;
1295
+ }>;
1296
+ /** Closed subpath polygons in extent-EMU space; fill rule is even-odd. */
1297
+ readonly subpathsEmu: readonly (readonly Readonly<{
1298
+ x: number;
1299
+ y: number;
1300
+ }>[])[];
1301
+ /** Validated 6-digit sRGB hex (no `#`), or null for no fill. */
1302
+ readonly fillHex: string | null;
1303
+ /** Validated 6-digit sRGB hex (no `#`), or null for no stroke. */
1304
+ readonly strokeHex: string | null;
1305
+ /** Stroke width in EMU; 0 when absent. */
1306
+ readonly strokeWidthEmu: number;
1307
+ }
1308
+ /**
1309
+ * The story carried by a `wps:wsp` text box (`wps:txbx` → `w:txbxContent`).
1310
+ *
1311
+ * The projection captures only the story root and the shape chrome reads; it never walks the
1312
+ * story content, so the per-drawing element budget is not spent on paragraphs. Layout collects
1313
+ * blocks from `content` under its own caps.
1314
+ */
1315
+ interface TextboxStoryProjection {
1316
+ /** Canonical node id of the `w:txbxContent` element. */
1317
+ readonly contentNodeId: string;
1318
+ /** The `w:txbxContent` element itself; treated as an opaque story root here. */
1319
+ readonly content: OoxmlElement;
1320
+ /** `wps:bodyPr` insets with the OOXML defaults (91440 EMU l/r, 45720 EMU t/b) when absent. */
1321
+ readonly insetsEmu: Readonly<{
1322
+ top: number;
1323
+ right: number;
1324
+ bottom: number;
1325
+ left: number;
1326
+ }>;
1327
+ /** `wps:bodyPr/@anchor` collapsed to the three renderable positions; default top. */
1328
+ readonly verticalAnchor: 'top' | 'center' | 'bottom';
1329
+ /** Autofit child of `wps:bodyPr`; extent stays authoritative either way (diagnostic only). */
1330
+ readonly autofit: 'none' | 'shape' | 'normal';
1331
+ /** Solid fill of the hosting shape, painted behind the story; null for no fill. */
1332
+ readonly fillHex: string | null;
1333
+ /** Solid outline of the hosting shape; null for no outline. */
1334
+ readonly strokeHex: string | null;
1335
+ /** Outline width in EMU; 0 when absent. */
1336
+ readonly strokeWidthEmu: number;
1337
+ }
1338
+
1339
+ /**
1340
+ * Whether a drawing sits in the text flow or is positioned against a frame.
1341
+ *
1342
+ * The distinction that decides everything downstream: an inline drawing occupies a character
1343
+ * position, while an anchored one has offsets relative to a page, margin or column.
1344
+ */
1345
+ type DrawingKind = 'inline' | 'anchored';
1346
+ /** Nine Word wrap menu targets (inline plus eight floating modes). @public */
1347
+ type ImageWrapTarget = 'inline' | 'square' | 'squareLeft' | 'squareRight' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';
1348
+ /** Every text-wrap mode a drawing may be set to, including `inline`. */
1349
+ declare const IMAGE_WRAP_TARGETS: readonly ImageWrapTarget[];
1350
+ type DrawingWrapElement = 'none' | 'square' | 'tight' | 'through' | 'topAndBottom';
1351
+ type DrawingHorizontalReferenceFrame = 'character' | 'column' | 'insideMargin' | 'leftMargin' | 'margin' | 'outsideMargin' | 'page' | 'rightMargin';
1352
+ type DrawingVerticalReferenceFrame = 'bottomMargin' | 'insideMargin' | 'line' | 'margin' | 'outsideMargin' | 'page' | 'paragraph' | 'topMargin';
1353
+ /** `a:srcRect` — how much of each edge of the source image is cropped away, as fractions. */
1354
+ interface SourceCrop {
1355
+ readonly left: number;
1356
+ readonly top: number;
1357
+ readonly right: number;
1358
+ readonly bottom: number;
1359
+ }
1360
+ interface DrawingTransform {
1361
+ readonly rotationDegrees: number;
1362
+ readonly flipHorizontal: boolean;
1363
+ readonly flipVertical: boolean;
1364
+ /** Source `a:off` in EMU; defaults to origin when absent. */
1365
+ readonly offsetEmu: Readonly<{
1366
+ x: number;
1367
+ y: number;
1368
+ }>;
1369
+ /** Source `a:ext` in EMU; zero falls back to `wp:extent` at geometry time. */
1370
+ readonly extentEmu: Readonly<{
1371
+ cx: number;
1372
+ cy: number;
1373
+ }>;
1374
+ }
1375
+ /**
1376
+ * What a drawing refuses: selection, movement, resizing, aspect change.
1377
+ *
1378
+ * Read and honoured rather than advisory — chrome that offered a handle the store will refuse
1379
+ * would promise an edit that cannot happen.
1380
+ */
1381
+ interface DrawingLocks {
1382
+ readonly select: boolean;
1383
+ readonly move: boolean;
1384
+ readonly resize: boolean;
1385
+ readonly changeAspect: boolean;
1386
+ }
1387
+ interface DrawingLocksInput {
1388
+ readonly select?: boolean;
1389
+ readonly move?: boolean;
1390
+ readonly resize?: boolean;
1391
+ readonly changeAspect?: boolean;
1392
+ }
1393
+ /**
1394
+ * An anchored drawing's position: offsets, and the frames they are relative to.
1395
+ *
1396
+ * The relative-to bases matter as much as the offsets. Writing an offset without preserving its
1397
+ * base re-anchors the drawing against a different reference and moves it somewhere nobody asked.
1398
+ */
1399
+ interface DrawingPositionInput {
1400
+ /**
1401
+ * `'simple'` when `@simplePos="1"`: `horizontalEmu` / `verticalEmu` are authoritative
1402
+ * `wp:simplePos` x/y. `'frame'` (default) uses positionH/V relative frames.
1403
+ */
1404
+ readonly mode?: 'frame' | 'simple';
1405
+ readonly horizontalEmu?: number;
1406
+ readonly verticalEmu?: number;
1407
+ readonly relativeToH?: DrawingHorizontalReferenceFrame;
1408
+ readonly relativeToV?: DrawingVerticalReferenceFrame;
1409
+ }
1410
+ interface DrawingProjection {
1411
+ readonly drawingNodeId: string;
1412
+ readonly ownerPartName: string;
1413
+ readonly kind: DrawingKind;
1414
+ readonly relationshipId: string | null;
1415
+ readonly docPrId: number | null;
1416
+ readonly name: string;
1417
+ readonly title: string;
1418
+ readonly description: string;
1419
+ readonly hyperlinkHref: string | null;
1420
+ readonly hidden: boolean;
1421
+ readonly extentEmu: Readonly<{
1422
+ cx: number;
1423
+ cy: number;
1424
+ }>;
1425
+ readonly effectExtentEmu: Readonly<{
1426
+ top: number;
1427
+ right: number;
1428
+ bottom: number;
1429
+ left: number;
1430
+ }>;
1431
+ readonly inlineDistancesEmu: Readonly<{
1432
+ top: number;
1433
+ right: number;
1434
+ bottom: number;
1435
+ left: number;
1436
+ }>;
1437
+ readonly wrap: ImageWrapTarget;
1438
+ readonly wrapGeometry: DrawingWrapProjection | null;
1439
+ readonly position: DrawingPositionProjection | null;
1440
+ readonly anchor: Readonly<{
1441
+ simplePos: boolean;
1442
+ relativeHeight: number;
1443
+ behindDocument: boolean;
1444
+ layoutInCell: boolean;
1445
+ allowOverlap: boolean;
1446
+ }> | null;
1447
+ readonly picture: PictureProjection | null;
1448
+ readonly vectorShape: VectorShapeProjection | null;
1449
+ readonly textboxStory: TextboxStoryProjection | null;
1450
+ readonly locks: DrawingLocks;
1451
+ readonly effects: Readonly<{
1452
+ grayscale: boolean;
1453
+ brightness: number;
1454
+ contrast: number;
1455
+ }>;
1456
+ readonly compatibilityBranchNodeId: string | null;
1457
+ readonly diagnostics: readonly DrawingDiagnostic[];
1458
+ }
1459
+ interface DrawingAccessibility {
1460
+ readonly hidden: boolean;
1461
+ readonly decorative: boolean;
1462
+ readonly label: string | null;
1463
+ }
1464
+ interface DrawingPositionProjection {
1465
+ readonly simplePosition: Readonly<{
1466
+ xEmu: number;
1467
+ yEmu: number;
1468
+ }>;
1469
+ readonly horizontal: Readonly<{
1470
+ relativeFrom: DrawingHorizontalReferenceFrame;
1471
+ align: string | null;
1472
+ offsetEmu: number | null;
1473
+ }>;
1474
+ readonly vertical: Readonly<{
1475
+ relativeFrom: DrawingVerticalReferenceFrame;
1476
+ align: string | null;
1477
+ offsetEmu: number | null;
1478
+ }>;
1479
+ }
1480
+ interface DrawingWrapProjection {
1481
+ readonly element: DrawingWrapElement;
1482
+ readonly textSide: 'bothSides' | 'left' | 'right' | 'largest';
1483
+ readonly distancesEmu: Readonly<{
1484
+ top: number;
1485
+ right: number;
1486
+ bottom: number;
1487
+ left: number;
1488
+ }>;
1489
+ readonly polygon: readonly Readonly<{
1490
+ x: number;
1491
+ y: number;
1492
+ }>[];
1493
+ }
1494
+ interface PictureProjection {
1495
+ readonly embeddedRelationshipId: string | null;
1496
+ readonly linkedRelationshipId: string | null;
1497
+ readonly crop: SourceCrop;
1498
+ readonly fillMode: 'stretch' | 'tile';
1499
+ readonly transform: DrawingTransform;
1500
+ readonly presetGeometry: string | null;
1501
+ }
1502
+ /**
1503
+ * Project one `w:drawing` into the resolved shape layout and chrome read.
1504
+ *
1505
+ * Bounded throughout: extents, crops and nesting all come from a file. Returns a projection that
1506
+ * reports `hidden` and its locks rather than throwing, so an unusable drawing degrades to
1507
+ * something the surface can skip.
1508
+ */
1509
+ declare function projectDrawing(drawing: OoxmlDrawingNode, context: Readonly<{
1510
+ ownerPartName: string;
1511
+ supportedMcRequires: ReadonlySet<string>;
1512
+ limits: DrawingProjectionLimits;
1513
+ namespaceScope?: ReadonlyMap<string, string>;
1514
+ resolveRelationship?: RelationshipTargetResolver;
1515
+ }>): DrawingProjection | null;
1516
+
1517
+ /** Opaque handle — bytes are reachable only through {@link mintValidatedImageBytes}. */
1518
+ interface ValidatedImageBytesHandle {
1519
+ readonly registryId: number;
1520
+ readonly resourceKey: string;
1521
+ readonly contentId: string;
1522
+ readonly generation: number;
1523
+ }
1524
+
1525
+ /**
1526
+ * Raster media the decode port measures and any authoring path may write.
1527
+ *
1528
+ * BMP and WebP are here for the same reason the other three are: an `<img>` decodes them
1529
+ * natively, so they need a signature and a structural header and nothing else. BMP is what
1530
+ * older documents carry; WebP is what current Word writes.
1531
+ */
1532
+ type SupportedImageMime = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp' | 'image/webp';
1533
+ /**
1534
+ * Vector media painted straight from validated bytes. An `<img>` renders SVG in the
1535
+ * browser's secure static mode — no script, no external subresource loads — so there is
1536
+ * no decode step and no raster buffer sized by a file-supplied number.
1537
+ */
1538
+ type VectorImageMime = 'image/svg+xml';
1539
+ /** Every mime the painter can hand to an `<img>`. */
1540
+ type RenderableImageMime = SupportedImageMime | VectorImageMime;
1541
+ /**
1542
+ * Media kept in the package byte-for-byte that the painter cannot hand to an `<img>`.
1543
+ * A decode port may rasterize it; without one it paints as a labelled placeholder.
1544
+ */
1545
+ type PreservedImageMime = 'image/tiff' | 'image/x-emf' | 'image/x-wmf';
1546
+ /**
1547
+ * What is known about one embedded image: validated, refused, or still decoding.
1548
+ *
1549
+ * Content type is a CLAIM. Signature sniffing, structural header validation and the decode port
1550
+ * are authoritative, and bytes that fail them never enter public state.
1551
+ */
1552
+ type ImageResourceState = {
1553
+ readonly kind: 'ready';
1554
+ readonly partName: string;
1555
+ readonly contentId: string;
1556
+ readonly resourceKey: string;
1557
+ readonly validatedHandle: ValidatedImageBytesHandle;
1558
+ readonly mime: RenderableImageMime;
1559
+ readonly pixelWidth: number;
1560
+ readonly pixelHeight: number;
1561
+ readonly dpiX: number;
1562
+ readonly dpiY: number;
1563
+ } | {
1564
+ readonly kind: 'unrenderable';
1565
+ readonly partName: string | null;
1566
+ readonly mime: RenderableImageMime | PreservedImageMime | 'unknown';
1567
+ readonly reason: 'unsupported-format' | 'non-picture-graphic' | 'signature-mismatch' | 'decode-failed' | 'resource-limit';
1568
+ } | {
1569
+ readonly kind: 'external';
1570
+ readonly relationshipId: string;
1571
+ readonly sinkSafe: boolean;
1572
+ } | {
1573
+ readonly kind: 'missing';
1574
+ readonly relationshipId: string;
1575
+ } | {
1576
+ readonly kind: 'pending';
1577
+ readonly resourceKey: string;
1578
+ };
1579
+ /**
1580
+ * The injected image decoder.
1581
+ *
1582
+ * A port rather than a direct `Image`/`createImageBitmap` call, so a worker or server runtime
1583
+ * supplies its own and the engine never reaches for a browser global.
1584
+ */
1585
+ interface ImageDecodePort {
1586
+ decode(bytes: Uint8Array, mime: SupportedImageMime, limits: ImageResourceLimits): Promise<Readonly<{
1587
+ pixelWidth: number;
1588
+ pixelHeight: number;
1589
+ dpiX: number;
1590
+ dpiY: number;
1591
+ }>>;
1592
+ /**
1593
+ * Optional conversion of media an `<img>` cannot render (EMF/WMF metafiles, TIFF) into a
1594
+ * renderable raster. The returned bytes are untrusted and re-enter the full raster
1595
+ * validation path (sniff, header, pixel caps, decode) before they can become a ready
1596
+ * resource. A null return declines the format and keeps the labelled placeholder; so does
1597
+ * a throw, as `decode-failed`.
1598
+ */
1599
+ convertPreserved?(bytes: Uint8Array, mime: PreservedImageMime, limits: ImageResourceLimits): Promise<Readonly<{
1600
+ bytes: Uint8Array;
1601
+ mime: SupportedImageMime;
1602
+ }> | null>;
1603
+ }
1604
+ /** Resolves a relationship id to a validated image resource, or reports why it could not. */
1605
+ interface ImageResourceLookup {
1606
+ readonly resolveEmbedded: (ownerPartName: string, relationshipId: string) => Promise<ImageResourceState>;
1607
+ readonly resolveLinked: (ownerPartName: string, relationshipId: string) => ImageResourceState;
1608
+ readonly resolveForProjection: (projection: DrawingProjection) => Promise<ImageResourceState>;
1609
+ readonly liveReferenceCount: (partName: string) => number;
1610
+ readonly dispose: () => void;
1611
+ }
1612
+ /** Maximum prefix inspected for SVG root detection (exported for bounded-scan tests). */
1613
+ declare const MAX_SVG_SNIFF_BYTES = 512;
1614
+ /** A raster header that passed structural validation: its real MIME type and pixel extent. */
1615
+ interface ValidatedRasterHeader {
1616
+ readonly pixelWidth: number;
1617
+ readonly pixelHeight: number;
1618
+ }
1619
+ /** Bounded scan for an `<svg` document root (optional `<?xml` prolog only). */
1620
+ declare function hasBoundedSvgRoot(bytes: Uint8Array): boolean;
1621
+ /** Signature sniffing — authoritative over declared content type. */
1622
+ declare function sniffImageMime(bytes: Uint8Array): RenderableImageMime | PreservedImageMime | 'unknown';
1623
+ /** Structural PNG IHDR validation before decode. */
1624
+ declare function validatePngHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
1625
+ /** Structural GIF logical screen descriptor validation before decode. */
1626
+ declare function validateGifHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
1627
+ /** Bounded JPEG marker scan through the first supported SOF marker. */
1628
+ declare function validateJpegHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
1629
+ /**
1630
+ * Intrinsic size of an SVG, resolved the way a browser sizes one: absolute `width`/`height`
1631
+ * first, then `viewBox` for the missing axis or ratio, then the CSS 300x150 default.
1632
+ *
1633
+ * This is metadata for insert and reset-to-natural-size only. Layout uses the authored
1634
+ * `wp:extent` and the browser rasterizes into that box, so nothing here sizes an allocation
1635
+ * and an out-of-range value is clamped rather than refused.
1636
+ */
1637
+ declare function resolveSvgIntrinsicSize(bytes: Uint8Array, limits: ImageResourceLimits): ValidatedRasterHeader | null;
1638
+ /**
1639
+ * Validate a raster image's header structurally and report its real MIME type and extent.
1640
+ *
1641
+ * Content type is a CLAIM; this is what makes it a fact. A file declaring `image/png` over JPEG
1642
+ * bytes is caught here rather than at decode.
1643
+ */
1644
+ declare function validateRasterHeader(bytes: Uint8Array, mime: SupportedImageMime): ValidatedRasterHeader | null;
1645
+ /** Package-wide live drawing references to a media part name. */
1646
+ declare function liveDrawingReferenceCount(pkg: OoxmlPackage, partName: string): number;
1647
+ /** How the image cache decodes, and what it will spend doing so. */
1648
+ interface CreateImageResourceCacheOptions {
1649
+ readonly limits?: Partial<ImageResourceLimits>;
1650
+ readonly decodePort: ImageDecodePort;
1651
+ }
1652
+ /**
1653
+ * Derived cache for one immutable package snapshot. Registry identity is
1654
+ * `(package snapshot, decodePort object, normalized limits)` — the first caller
1655
+ * never imposes its decoder or limits on later callers with different options.
1656
+ */
1657
+ declare function imageResourceLookupFor(pkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
1658
+ /** @deprecated Prefer {@link imageResourceLookupFor} — registry binds cache to package identity. */
1659
+ /** Build the per-document image cache. Validated bytes only; refusals are remembered too. */
1660
+ declare function createImageResourceCache(initialPkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
1661
+
1662
+ /** Caps applied while loading a package: zip, XML, part count and relationship count. */
1663
+ interface OoxmlPackageLimits {
1664
+ readonly zip?: ZipLimits;
1665
+ readonly xml?: XmlLimits;
1666
+ /** Cap on parts converted into canonical trees (N/N+1 gate, not a soft target). */
1667
+ readonly maxXmlParts?: number;
1668
+ /** Cap on relationship records across every rels part. */
1669
+ readonly maxRelationships?: number;
1670
+ }
1671
+ /** The limits in force when a host configures none. Conservative and finite. */
1672
+ declare const DEFAULT_OOXML_PACKAGE_LIMITS: Required<Pick<OoxmlPackageLimits, 'maxXmlParts' | 'maxRelationships'>>;
1673
+ /**
1674
+ * An external relationship target. Retained verbatim as authored evidence, with the
1675
+ * sink-safety verdict alongside it. Never resolved against the package, never fetched.
1676
+ */
1677
+ interface OoxmlExternalTarget {
1678
+ readonly ownerPart: string;
1679
+ readonly id: string;
1680
+ readonly type: string;
1681
+ readonly rawTarget: string;
1682
+ /** False when the target is not a safe sink (javascript:, file:, ...). Still not fetched. */
1683
+ readonly sinkSafe: boolean;
1684
+ }
1685
+ /**
1686
+ * A loaded package: every XML part as a canonical tree, plus the non-XML parts kept verbatim.
1687
+ *
1688
+ * The preservation model in one value. Modelled parts re-emit normalized; everything else is
1689
+ * byte-identical, which is why an unrecognized part never costs a document anything.
1690
+ */
1691
+ interface OoxmlPackage {
1692
+ /** Canonical trees, keyed by canonical part name. Non-XML parts are absent by design. */
1693
+ readonly parts: ReadonlyMap<string, OoxmlPart>;
1694
+ /** Raw bytes of every entry, including the non-XML parts that have no tree. */
1695
+ readonly partBytes: ReadonlyMap<string, Uint8Array>;
1696
+ /** Internal relationships by owner part, in authored order. */
1697
+ readonly relationships: ReadonlyMap<string, readonly RelationshipRecord[]>;
1698
+ readonly externalTargets: readonly OoxmlExternalTarget[];
1699
+ readonly contentTypes: ContentTypeIndex;
1700
+ /** Canonical name of the part the root `officeDocument` relationship points at. */
1701
+ readonly mainDocumentPart: string;
1702
+ }
1703
+ /** Why a package could not be loaded. Every code describes the FILE, not the caller. */
1704
+ type OoxmlPackageRejection = ZipRejection | OoxmlReadRejection | 'no-content-types' | 'bad-content-types' | 'no-main-document' | 'bad-relationship-target' | 'duplicate-relationship-id' | 'too-many-relationships' | 'too-many-xml-parts';
1705
+ /** A loaded package, or a typed refusal. Never throws. */
1706
+ type OoxmlPackageResult = {
1707
+ readonly ok: true;
1708
+ readonly package: OoxmlPackage;
1709
+ } | {
1710
+ readonly ok: false;
1711
+ readonly reason: OoxmlPackageRejection;
1712
+ readonly detail?: string;
1713
+ };
1714
+ declare function readOoxmlPackage(bytes: Uint8Array, limits?: OoxmlPackageLimits): OoxmlPackageResult;
1715
+ /**
1716
+ * Serialize a canonical package back to DOCX bytes.
1717
+ *
1718
+ * Starts from the ORIGINAL entry bytes and overwrites only the parts held as trees. A part
1719
+ * the loader did not model — media, fonts, an XML part outside the modeled set — passes
1720
+ * through untouched, so round-tripping a document cannot lose a part the engine never
1721
+ * claimed to understand.
1722
+ *
1723
+ * The modeled parts are re-emitted NORMALIZED from the tree rather than patched as text.
1724
+ * That is the whole point of the canonical tree: correctness is judged by the two D9
1725
+ * oracles (the namespace-aware fingerprint and the save/reopen semantic digest), not by
1726
+ * byte equality, so a different-but-equivalent spelling is not a defect.
1727
+ *
1728
+ * `writeZip` re-validates every part name, so a name that became unsafe between load and
1729
+ * save cannot be smuggled into the archive.
1730
+ */
1731
+ declare function writeOoxmlPackage(pkg: OoxmlPackage): Uint8Array;
1732
+ /** Replace one part's tree, returning a new package. Pure, like the tree edits themselves. */
1733
+ declare function withPart(pkg: OoxmlPackage, part: OoxmlPart): OoxmlPackage;
1734
+
1735
+ /** How deep controls may nest before a walk stops descending. Shared by every lane. */
1736
+ declare const MAX_CONTENT_CONTROL_NESTING = 32;
1737
+ /** Cap on controls one walk reports, so a hostile file cannot make a read unbounded. */
1738
+ declare const MAX_CONTENT_CONTROLS_PER_PART = 10000;
1739
+ /** `CT_SdtPr/w:id` is `ST_DecimalNumber`; Word treats it as a signed 32-bit integer. */
1740
+ declare const CONTENT_CONTROL_ID_MAX = 2147483647;
1741
+ /** `ST_Lock` (§17.5.2.24). An absent `w:lock` is `unlocked`. */
1742
+ /**
1743
+ * `w:lock` — what a control refuses.
1744
+ *
1745
+ * `sdtLocked` protects the wrapper, `contentLocked` the text inside it, and `sdtContentLocked`
1746
+ * both. A control inside a locked one is locked in effect regardless of its own value.
1747
+ */
1748
+ type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
1749
+ /**
1750
+ * What kind of control this is.
1751
+ *
1752
+ * `checkbox` is the Microsoft `w14:checkbox` extension rather than an ECMA-376 type
1753
+ * element, and the two are not mutually exclusive with "declares no type": four controls
1754
+ * in the comprehensive fixture declare the extension and no `w:`-prefixed type, so a scan
1755
+ * that read only the ECMA-376 choice reported them untyped. `untyped` means the control
1756
+ * declares neither — a rich-text container, which is what Word treats it as.
1757
+ */
1758
+ /** Which kind of control a `w:sdt` is, and therefore what a written value must look like. */
1759
+ type ContentControlKind = 'richText' | 'plainText' | 'checkbox' | 'dropDownList' | 'comboBox' | 'date' | 'picture' | 'docPartObj' | 'docPartList' | 'group' | 'citation' | 'bibliography' | 'equation' | 'untyped';
1760
+ /** One declared option of a dropdown or combo box: its display text and its stored value. */
1761
+ interface ContentControlListItem {
1762
+ readonly displayText: string;
1763
+ readonly value: string;
1764
+ }
1765
+ /** A date picker's authored format and locale, for rendering and for parsing what it stores. */
1766
+ interface ContentControlDateFormat {
1767
+ readonly fullDate?: string;
1768
+ readonly dateFormat?: string;
1769
+ readonly lid?: string;
1770
+ readonly storeMappedDataAs?: string;
1771
+ readonly calendar?: string;
1772
+ }
1773
+ /** One of a checkbox's two glyphs: the font and code point it is drawn with. */
1774
+ interface ContentControlCheckboxState {
1775
+ /** The `w14:val` hex code point of the glyph, exactly as the control declares it. */
1776
+ readonly value: string;
1777
+ readonly font?: string;
1778
+ }
1779
+ /**
1780
+ * A checkbox's state and the two glyphs it chooses between.
1781
+ *
1782
+ * Both glyphs matter on a write: setting the value has to update `w14:checked` AND the run's
1783
+ * character, or the document's glyph and its recorded state disagree.
1784
+ */
1785
+ interface ContentControlCheckbox {
1786
+ readonly checked: boolean;
1787
+ readonly checkedState?: ContentControlCheckboxState;
1788
+ readonly uncheckedState?: ContentControlCheckboxState;
1789
+ }
1790
+ /** `CT_DataBinding` — preserved metadata. Never resolved, never fetched. */
1791
+ /** `w:dataBinding` — the custom-XML part and XPath a control's value is bound to. */
1792
+ interface ContentControlDataBinding {
1793
+ readonly xpath?: string;
1794
+ readonly storeItemID?: string;
1795
+ readonly prefixMappings?: string;
1796
+ }
1797
+ /**
1798
+ * A control's whole `w:sdtPr`, projected into one typed shape.
1799
+ *
1800
+ * What every other lane reads instead of walking `localName` strings — which also means a Word
1801
+ * re-save that demotes the properties node to generic does not break the projection.
1802
+ */
1803
+ interface ContentControlProperties {
1804
+ readonly type: ContentControlKind;
1805
+ readonly alias?: string;
1806
+ readonly tag?: string;
1807
+ /** `@w:val` of `w:id` when the file declares a parseable one. Never fabricated. */
1808
+ readonly id?: number;
1809
+ readonly lock: ContentControlLock;
1810
+ /** The glossary entry named by `w:placeholder/w:docPart`. Preserved, never loaded. */
1811
+ readonly placeholderDocPart?: string;
1812
+ readonly temporary: boolean;
1813
+ readonly showingPlaceholder: boolean;
1814
+ readonly dataBinding?: ContentControlDataBinding;
1815
+ readonly label?: string;
1816
+ readonly tabIndex?: number;
1817
+ /** Items a dropdown or combo box offers. Empty for every other type. */
1818
+ readonly listItems: readonly ContentControlListItem[];
1819
+ readonly lastValue?: string;
1820
+ readonly date?: ContentControlDateFormat;
1821
+ readonly multiLine?: boolean;
1822
+ readonly checkbox?: ContentControlCheckbox;
1823
+ }
1824
+ /** Whether a node is a `w:sdt` wrapper. */
1825
+ declare function isContentControlNode(node: OoxmlNode): node is OoxmlContentControlNode;
1826
+ /** Whether a node is a `w:sdtContent` — the container holding a control's actual content. */
1827
+ declare function isContentControlContentNode(node: OoxmlNode): node is OoxmlContentControlContentNode;
1828
+ /**
1829
+ * A `w:sdt` wrapper, TYPED or DEMOTED.
1830
+ *
1831
+ * Flattening predates typing and must not stop at a control the reader refused to type: a
1832
+ * demoted wrapper still renders its content in place in Word, so a walk that only saw the
1833
+ * typed kind would drop every paragraph inside a malformed control out of the story.
1834
+ */
1835
+ declare function isContentControlWrapper(node: OoxmlNode): boolean;
1836
+ /**
1837
+ * The children of a wrapper's `w:sdtContent`, typed or demoted, in order.
1838
+ *
1839
+ * The one place that knows a control's content is reached through an intermediate element,
1840
+ * so the four flattening walks (story blocks, layout, header/footer references, list
1841
+ * resolution) ask the same question rather than each re-deriving it.
1842
+ */
1843
+ declare function contentControlContentChildren(wrapper: OoxmlNode): readonly OoxmlNode[];
1844
+ /**
1845
+ * A container's children with every content-control wrapper flattened away, bounded in depth.
1846
+ *
1847
+ * ONE unwrap rule, for the places where a control sits between a container and the children that
1848
+ * container is defined in terms of. `CT_SdtRow` puts it between `w:tbl` and `w:tr`, `CT_SdtCell`
1849
+ * between `w:tr` and `w:tc`, and a walk that filtered on the child's kind dropped the row or cell
1850
+ * entirely: not measured, not painted, not addressable. Flattening at the point of the filter
1851
+ * means a controlled row is the same row to the grid pass, the pagination pass and the story walk.
1852
+ *
1853
+ * Returns the SAME array identity when there is nothing to unwrap, so the tables that carry no
1854
+ * controls — nearly all of them — allocate nothing and the incremental layout cache still sees
1855
+ * its own inputs.
1856
+ */
1857
+ declare function flattenContentControls(children: readonly OoxmlNode[], maxDepth?: number): readonly OoxmlNode[];
1858
+ /** A control's `w:sdtPr`, or null. Matches structurally, so a Word-demoted node still resolves. */
1859
+ declare function contentControlPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlPropertiesNode | undefined;
1860
+ /** A control's `w:sdtEndPr` — the run properties applied to its closing marker. */
1861
+ declare function contentControlEndPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlEndPropertiesNode | undefined;
1862
+ /** A control's `w:sdtContent`, or null when the wrapper has none. */
1863
+ declare function contentControlContentNodeOf(control: OoxmlNode): OoxmlContentControlContentNode | undefined;
1864
+ /** A signed 32-bit `ST_DecimalNumber`, or undefined when the file wrote something else. */
1865
+ declare function parseContentControlId(raw: string | undefined): number | undefined;
1866
+ /**
1867
+ * Read a control's properties.
1868
+ *
1869
+ * Total: a control with no `w:sdtPr` at all answers the same shape with the defaults an
1870
+ * absent property means, so no caller has to branch on the container's existence.
1871
+ */
1872
+ declare function contentControlPropertiesOf(control: OoxmlNode): ContentControlProperties;
1873
+ /** Where a control sits, read off what its content holds. */
1874
+ type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell' | 'empty';
1875
+ /**
1876
+ * How deeply a control is nested inside other controls.
1877
+ *
1878
+ * Bounded by {@link MAX_CONTENT_CONTROL_NESTING}: nesting depth comes from a file and is a
1879
+ * recursion bound.
1880
+ */
1881
+ declare function contentControlLevelOf(control: OoxmlNode): ContentControlLevel;
1882
+ /** One control, plus how deeply it is nested and the controls that enclose it. */
1883
+ interface ContentControlEntry {
1884
+ readonly node: OoxmlContentControlNode;
1885
+ /** 0 for a top-level control; the nesting depth otherwise. */
1886
+ readonly depth: number;
1887
+ /** Enclosing controls, outermost first. Empty at depth 0. */
1888
+ readonly ancestors: readonly OoxmlContentControlNode[];
1889
+ }
1890
+ /**
1891
+ * Every control under a node, in document order, bounded in depth and in count.
1892
+ *
1893
+ * ONE walk, shared. The nesting bound is the same one layout flattens with, so a control
1894
+ * a lane can address is a control every lane can address — and a file that nests past it
1895
+ * keeps its content in the tree (the serializer never stops) while no walk recurses
1896
+ * further.
1897
+ */
1898
+ declare function contentControlsIn(root: OoxmlNode, options?: {
1899
+ readonly maxDepth?: number;
1900
+ readonly limit?: number;
1901
+ }): readonly ContentControlEntry[];
1902
+ /** Find one control by canonical node id, with the same bounded walk. */
1903
+ declare function findContentControl(root: OoxmlNode, nodeId: string): ContentControlEntry | null;
1904
+ /**
1905
+ * The plain text a control's content holds, in reading order.
1906
+ *
1907
+ * `w:delText` is excluded: struck text is not the control's value, and a dropdown whose
1908
+ * old item is still present as a tracked deletion would otherwise report both.
1909
+ */
1910
+ declare function contentControlTextOf(control: OoxmlNode): string;
1911
+ /**
1912
+ * Resolve the lock a position inherits from the controls enclosing it.
1913
+ *
1914
+ * CONSERVATIVE, because a template that says a field cannot be edited and sits inside a
1915
+ * section that says it cannot be removed means both. Each half of `ST_Lock` is taken
1916
+ * independently and the strongest wins, so an unlocked control inside a `contentLocked`
1917
+ * one is still content-locked — a nested control cannot grant a permission its parent
1918
+ * withheld, which is the only reading under which a lock is a lock.
1919
+ */
1920
+ declare function resolveContentControlLock(chain: readonly ContentControlLock[]): ContentControlLock;
1921
+ /** Whether a resolved lock forbids editing the content it covers. */
1922
+ declare function lockForbidsEdit(lock: ContentControlLock): boolean;
1923
+ /** Whether a resolved lock forbids removing the control itself. */
1924
+ declare function lockForbidsRemoval(lock: ContentControlLock): boolean;
1925
+ /**
1926
+ * `CT_SdtPr`'s declared child order (§17.5.2.38), followed by the type choice.
1927
+ *
1928
+ * Serialization re-emits children in tree order, so the ONLY way a write keeps the
1929
+ * sequence valid is to place the child it authors at its schema position — which is what
1930
+ * {@link orderedContentControlProperties} does.
1931
+ */
1932
+ declare const CONTENT_CONTROL_PROPERTY_ORDER: readonly string[];
1933
+ /**
1934
+ * Rebuild a `w:sdtPr`'s children in schema order.
1935
+ *
1936
+ * Modelled children sort to their declared position and the type element follows them,
1937
+ * as the sequence requires. Everything else — a `w15:repeatingSection`, a vendor
1938
+ * extension, the `w14:checkbox` that is not part of the ECMA-376 choice — keeps the order
1939
+ * it was authored in and follows the modelled block, so a write that touches one property
1940
+ * neither drops nor reorders anything it does not name.
1941
+ */
1942
+ declare function orderedContentControlProperties(children: readonly OoxmlNode[]): readonly OoxmlNode[];
1943
+ /**
1944
+ * The next `w:id` to write.
1945
+ *
1946
+ * Solo: one past the document's own maximum. Never a clock, a timestamp, a random source
1947
+ * or a hash: those collide with ids already in the file and produce values Word rejects.
1948
+ * Null when the document already reaches the signed 32-bit bound, so the caller refuses
1949
+ * rather than wrapping into a negative id. Hostile or out-of-range existing values are
1950
+ * ignored for seeding rather than counted past.
1951
+ *
1952
+ * When a collaboration actor is bound (explicit argument or the open store transaction),
1953
+ * the next id is the next unused value in that actor's stripe. Two peers inserting a
1954
+ * generic content control — including a custom node authored as `w:sdt` — from the same
1955
+ * snapshot then cannot share a `w:id`.
1956
+ */
1957
+ declare function allocateContentControlId(root: OoxmlNode, actorId?: string): number | null;
1958
+
1959
+ /** The value a control accepts, by what kind of control it is. */
1960
+ type ContentControlValueInput = {
1961
+ readonly kind: 'text';
1962
+ readonly text: string;
1963
+ } | {
1964
+ readonly kind: 'listItem';
1965
+ readonly value: string;
1966
+ } | {
1967
+ readonly kind: 'checkbox';
1968
+ readonly checked: boolean;
1969
+ }
1970
+ /** A calendar date, `YYYY-MM-DD` or a full ISO-8601 instant. */
1971
+ | {
1972
+ readonly kind: 'date';
1973
+ readonly iso: string;
1974
+ };
1975
+ /** The control types an insertion may author. Picture and repeating section are deferred. */
1976
+ declare const INSERTABLE_CONTENT_CONTROL_TYPES: readonly ["richText", "plainText", "dropDownList", "comboBox", "date"];
1977
+ /**
1978
+ * The OOXML spellings the store writes.
1979
+ *
1980
+ * NOT the contract's `InsertableContentControlType`, which is the same set of kinds in the
1981
+ * READ vocabulary (`dropdown`) plus this lane's spelling of it (`dropDownList`). The editor
1982
+ * maps between the two; the names differ so a reader can tell which vocabulary a value is in.
1983
+ */
1984
+ type InsertableContentControlKind = (typeof INSERTABLE_CONTENT_CONTROL_TYPES)[number];
1985
+
1986
+ /** Allowlisted OOXML table border line styles — store/layout authority. */
1987
+ declare const TABLE_BORDER_STYLES: readonly ["single", "dashed", "dotted", "double", "triple", "thick"];
1988
+ /**
1989
+ * One of the border line styles this engine draws.
1990
+ *
1991
+ * An ALLOWLIST, not the full `ST_Border` enumeration: a file may name any of the seventy-odd
1992
+ * OOXML border styles, and anything outside this set falls back rather than being passed through
1993
+ * to paint.
1994
+ */
1995
+ type TableBorderStyle = (typeof TABLE_BORDER_STYLES)[number];
1996
+
1997
+ /**
1998
+ * How a tracked change is addressed: `@w:id`, `@w:author` and `@w:date` together, within a
1999
+ * part.
2000
+ *
2001
+ * All of them, always. `@w:id` is unique only within a part, so an id alone names two
2002
+ * revisions in any package with a header or a comments part — and it is not author-scoped
2003
+ * either, so `(part, id)` would merge two authors' distinct revisions. One logical revision is
2004
+ * also deliberately many elements sharing an id, as a tracked row insertion is, which no
2005
+ * uniqueness rule could express.
2006
+ */
2007
+ interface RevisionAddress {
2008
+ readonly id: string;
2009
+ readonly author: string;
2010
+ /** Absent when the file wrote no `@w:date`; part of the identity either way. */
2011
+ readonly date?: string;
2012
+ }
2013
+ /** The author and timestamp a tracked edit is recorded under. */
2014
+ interface RevisionAttributionInput {
2015
+ readonly author: string;
2016
+ /** ISO-8601. Omitted writes no `@w:date`. */
2017
+ readonly date?: string;
2018
+ }
2019
+
2020
+ /** JSON-safe color input carried on table cell property ops. Theme/auto require a validated literal. */
2021
+ /**
2022
+ * A colour as an op carries it: a literal, a theme reference, or automatic.
2023
+ *
2024
+ * Theme references stay references so the document keeps following its theme; flattening one to
2025
+ * hex at write time would freeze the resolved value into the file.
2026
+ */
2027
+ type TreeDocColorValue = {
2028
+ readonly kind: 'hex';
2029
+ readonly value: string;
2030
+ } | {
2031
+ readonly kind: 'theme';
2032
+ readonly slot: string;
2033
+ readonly resolvedHex: string;
2034
+ readonly tint?: number;
2035
+ readonly shade?: number;
2036
+ } | {
2037
+ readonly kind: 'auto';
2038
+ readonly resolvedHex: string;
2039
+ };
2040
+ /** Which cell edges a selected-cell border op targets. */
2041
+ /** Which edges a border op addresses — the four sides, the interiors, all, or clear. */
2042
+ type TableBorderTarget = 'all' | 'outside' | 'inside' | 'none' | 'top' | 'bottom' | 'left' | 'right';
2043
+ /** Concrete edge scopes that apply or clear a complete border spec. */
2044
+ /** A {@link TableBorderTarget} that draws something — everything except clear. */
2045
+ type TableBorderEdgeTarget = Exclude<TableBorderTarget, 'none'>;
2046
+ /** Complete border spec for non-`none` selected-cell border scopes. Size is in eighths of a point. */
2047
+ /** A complete border spec: style, width and colour. Ops carry all three, never a partial edit. */
2048
+ interface TableBorderSpecInput {
2049
+ readonly style: TableBorderStyle;
2050
+ readonly size: number;
2051
+ readonly color: TreeDocColorValue;
2052
+ }
2053
+ /**
2054
+ * The accepted RUN property boundary (design D8), as the OOXML element names that carry it.
2055
+ *
2056
+ * An explicit allowlist rather than "any `w:rPr` child": a property outside D8 has no
2057
+ * resolver, no layout behavior and no support claim, so accepting it here would let an
2058
+ * operation assert support the engine does not have. Unknown properties still ROUND-TRIP —
2059
+ * they are generic nodes in the tree — they simply cannot be authored by an op.
2060
+ */
2061
+ declare const ACCEPTED_RUN_PROPERTIES: readonly ["rFonts", "sz", "szCs", "color", "b", "bCs", "i", "iCs", "u", "strike", "dstrike", "highlight", "vertAlign", "position", "caps", "smallCaps", "spacing", "w", "kern"];
2062
+ /** The accepted PARAGRAPH property boundary (design D8). */
2063
+ declare const ACCEPTED_PARAGRAPH_PROPERTIES: readonly ["pStyle", "jc", "spacing", "ind", "tabs", "numPr", "keepNext", "keepLines", "widowControl", "pageBreakBefore", "contextualSpacing", "shd"];
2064
+ /**
2065
+ * One tab stop an op can author: where it sits, how it aligns, and what fills the gap.
2066
+ *
2067
+ * An alias, not a second declaration. The contract lane already names this shape, and two
2068
+ * public names for one shape is a trap — a caller building a stop for a read and for an op
2069
+ * would otherwise have to name it two things.
2070
+ */
2071
+ type TabStopWrite = ParagraphTabStop;
2072
+ /**
2073
+ * One authored property: an element name plus its `w:`-namespace attributes.
2074
+ *
2075
+ * Modeled as name+attributes rather than a typed record per property because that is what
2076
+ * the tree holds, so an op maps to nodes without a lossy intermediate vocabulary. Attribute
2077
+ * VALUES are validated as XML text; their meaning is the resolver's business.
2078
+ *
2079
+ * Deliberately structural rather than a typed union: the accepted property lists bound WHICH
2080
+ * properties may be written, so the shape itself does not need to enumerate them.
2081
+ */
2082
+ interface OoxmlProperty {
2083
+ readonly localName: string;
2084
+ readonly attributes?: Readonly<Record<string, string>>;
2085
+ }
2086
+
2087
+ /**
2088
+ * Every mutation the store accepts, as one JSON-safe discriminated union.
2089
+ *
2090
+ * The ONLY write path into a document. Each op addresses nodes by id plus UTF-16 offset, which is
2091
+ * what makes editing a paragraph inside a table cell no different from editing one at the top
2092
+ * level. Declarative and serializable, so the same op crosses a worker or transport boundary
2093
+ * unchanged.
2094
+ */
2095
+ type TreeDocOp = {
2096
+ /**
2097
+ * Replace one story's complete block structure with fresh plain paragraphs.
2098
+ *
2099
+ * Unlike a span replacement, this removes section-ending paragraphs and content-control
2100
+ * wrappers. A body's final direct `w:sectPr` survives to retain the page setup.
2101
+ */
2102
+ readonly op: 'replaceStoryBlocks';
2103
+ readonly storyRootId: string;
2104
+ readonly paragraphs: readonly string[];
2105
+ } | {
2106
+ /**
2107
+ * Insert an SDT-wrapped TOC immediately before a body paragraph.
2108
+ * The initial cached result and any heading bookmarks land in one undo unit.
2109
+ */
2110
+ readonly op: 'insertToc';
2111
+ readonly beforeParagraphId: string;
2112
+ readonly instruction: string;
2113
+ readonly alias: string;
2114
+ readonly entries: readonly {
2115
+ readonly level: number;
2116
+ readonly text: string;
2117
+ readonly headingParagraphId: string;
2118
+ readonly bookmarkName: string;
2119
+ readonly pageNumberText: string;
2120
+ }[];
2121
+ readonly bookmarksToCreate: readonly {
2122
+ readonly paragraphId: string;
2123
+ readonly name: string;
2124
+ }[];
2125
+ } | {
2126
+ readonly op: 'insertText';
2127
+ readonly paragraphId: string;
2128
+ readonly offset: number;
2129
+ readonly text: string;
2130
+ /**
2131
+ * Write this as a TRACKED insertion, attributed here.
2132
+ *
2133
+ * On the op rather than on the store, so suggesting stays a decision the surface makes
2134
+ * per edit and the write vocabulary stays explicit — a global "everything is tracked
2135
+ * now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
2136
+ * depend on state the op does not carry.
2137
+ */
2138
+ readonly revision?: RevisionAttributionInput;
2139
+ /**
2140
+ * When set, the text belongs INSIDE this content control, whatever sits at the offset.
2141
+ *
2142
+ * A boundary offset is owned by the run that starts there, which at a control's trailing
2143
+ * edge is the run after the control — so an offset alone cannot say "append to this field",
2144
+ * the way it cannot say which run of a field result to format (see `targetRunIds`). A
2145
+ * caller that names the control gets the text in the control; one that does not gets the
2146
+ * plain offset rule, which is what a keystroke beside a field means.
2147
+ */
2148
+ readonly inside?: string;
2149
+ /**
2150
+ * Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
2151
+ * the next character takes the formatting of the character before the caret.
2152
+ *
2153
+ * `'right'` is for a caller that is not typing but placing text inside the run that
2154
+ * STARTS at the offset — the hyperlink editor rewriting a link's display text, where
2155
+ * landing left of the boundary would put the new text outside the link. Ignored when
2156
+ * the offset falls strictly inside a run, which has no boundary to choose.
2157
+ */
2158
+ readonly bias?: 'left' | 'right';
2159
+ } | {
2160
+ readonly op: 'deleteText';
2161
+ readonly paragraphId: string;
2162
+ readonly start: number;
2163
+ readonly end: number;
2164
+ /** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
2165
+ readonly revision?: RevisionAttributionInput;
2166
+ } | {
2167
+ /**
2168
+ * Mark a paragraph's own MARK as inserted or deleted (`w:pPr/w:rPr/w:ins|w:del`,
2169
+ * §17.13.5). The change is to the paragraph break itself, so no character carries it.
2170
+ */
2171
+ readonly op: 'setParagraphMarkRevision';
2172
+ readonly paragraphId: string;
2173
+ readonly kind: 'ins' | 'del';
2174
+ readonly revision: RevisionAttributionInput;
2175
+ } | {
2176
+ /**
2177
+ * Propose merging this paragraph into its PREDECESSOR by striking the predecessor's
2178
+ * mark. Addressed by the SECOND paragraph so a multi-paragraph delete marks each
2179
+ * paragraph's own predecessor rather than stamping the group head N times.
2180
+ */
2181
+ readonly op: 'proposeParagraphMerge';
2182
+ readonly paragraphId: string;
2183
+ readonly revision: RevisionAttributionInput;
2184
+ } | {
2185
+ /**
2186
+ * Place one piece of comment markup at a model offset.
2187
+ *
2188
+ * Separate from the comment BODY, which lives in another part: this op is the story half
2189
+ * of a comment write, and the two are staged in one package transaction.
2190
+ */
2191
+ readonly op: 'insertCommentMarker';
2192
+ readonly paragraphId: string;
2193
+ readonly offset: number;
2194
+ readonly commentId: string;
2195
+ readonly marker: 'start' | 'end' | 'reference';
2196
+ } | {
2197
+ /**
2198
+ * Accept one revision, resolving every site in this part that carries its triple.
2199
+ */
2200
+ readonly op: 'acceptRevision';
2201
+ readonly revision: RevisionAddress;
2202
+ /** When set, only wrappers with this element local name resolve (ins/del/moveFrom/moveTo). */
2203
+ readonly localName?: string;
2204
+ } | {
2205
+ readonly op: 'rejectRevision';
2206
+ readonly revision: RevisionAddress;
2207
+ readonly localName?: string;
2208
+ } | {
2209
+ /**
2210
+ * Accept every revision in the part, or in one exact note root, in ONE transaction and one
2211
+ * history entry.
2212
+ *
2213
+ * Deliberately not a loop over `acceptRevision`: a reviewer who accepts a document's
2214
+ * changes made one decision, and one undo should restore all of them.
2215
+ */
2216
+ readonly op: 'acceptAllRevisions';
2217
+ /** Internal shared-notes scope. When present, this must be the canonical id of a note root. */
2218
+ readonly scopeRootId?: string;
2219
+ } | {
2220
+ readonly op: 'rejectAllRevisions';
2221
+ /** Internal shared-notes scope. When present, this must be the canonical id of a note root. */
2222
+ readonly scopeRootId?: string;
2223
+ } | {
2224
+ readonly op: 'insertTab';
2225
+ readonly paragraphId: string;
2226
+ readonly offset: number;
2227
+ /** Write this as a TRACKED insertion, on the same terms as `insertText`. */
2228
+ readonly revision?: RevisionAttributionInput;
2229
+ } | {
2230
+ readonly op: 'insertHardBreak';
2231
+ readonly paragraphId: string;
2232
+ readonly offset: number;
2233
+ /** Write this as a TRACKED insertion, on the same terms as `insertText`. */
2234
+ readonly revision?: RevisionAttributionInput;
2235
+ } | {
2236
+ readonly op: 'insertPageBreak';
2237
+ readonly paragraphId: string;
2238
+ readonly offset: number;
2239
+ /** Write this as a TRACKED insertion, on the same terms as `insertText`. */
2240
+ readonly revision?: RevisionAttributionInput;
2241
+ } | {
2242
+ /**
2243
+ * Insert an allowlisted page-number complex field at a UTF-16 offset.
2244
+ *
2245
+ * `PAGE_X_OF_Y` is PAGE + literal " of " + NUMPAGES in one undoable op. Non-page
2246
+ * instructions are refused — never authored through this path.
2247
+ */
2248
+ readonly op: 'insertPageField';
2249
+ readonly paragraphId: string;
2250
+ readonly offset: number;
2251
+ readonly field: 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES' | 'PAGE_X_OF_Y';
2252
+ /**
2253
+ * Write this as a TRACKED insertion, on the same terms as `insertText`.
2254
+ *
2255
+ * The whole field — every `w:fldChar`, the instruction, the `PAGE_X_OF_Y` literal —
2256
+ * goes into ONE `w:ins`, because the field is one proposal: rejecting it must take
2257
+ * the complete atom back, never leave a `begin` standing without its `end`.
2258
+ */
2259
+ readonly revision?: RevisionAttributionInput;
2260
+ } | {
2261
+ /**
2262
+ * Move a numbered paragraph to another `w:numPr/w:ilvl`.
2263
+ *
2264
+ * A list item's LEVEL is what selects its format out of `numbering.xml`, so this is
2265
+ * the op behind Increase/Decrease Indent on a list: the marker changes with it. A
2266
+ * paragraph carrying no `w:numPr` is refused rather than silently numbered.
2267
+ */
2268
+ readonly op: 'setListLevel';
2269
+ readonly paragraphId: string;
2270
+ readonly level: number;
2271
+ } | {
2272
+ /**
2273
+ * Put a paragraph in a list, or take it out of one.
2274
+ *
2275
+ * `numId` names a `w:num` in `numbering.xml`; null removes `w:numPr` entirely, which
2276
+ * is what turning a bullet off means. Everything else in `w:pPr` survives.
2277
+ */
2278
+ /**
2279
+ * Run properties of the PARAGRAPH MARK (`w:pPr/w:rPr`, ECMA-376 17.3.1.29).
2280
+ *
2281
+ * The mark carries the formatting a paragraph's own pilcrow has, and Word keeps it
2282
+ * in step whenever formatting is applied to a whole paragraph. It is what a list
2283
+ * marker inherits its face from — so without it, sizing a bulleted paragraph leaves
2284
+ * the bullet at the old size.
2285
+ */
2286
+ readonly op: 'setParagraphMarkProperties';
2287
+ readonly paragraphId: string;
2288
+ readonly properties: readonly OoxmlProperty[];
2289
+ /** Record this as a TRACKED format change (`w:pPr/w:rPr/w:rPrChange`, §17.13.5.31). */
2290
+ readonly revision?: RevisionAttributionInput;
2291
+ } | {
2292
+ readonly op: 'setListNumbering';
2293
+ readonly paragraphId: string;
2294
+ readonly numId: string | null;
2295
+ readonly level?: number;
2296
+ } | {
2297
+ /**
2298
+ * Replace a paragraph's custom tab stops, or clear them with an empty list.
2299
+ *
2300
+ * Its OWN op rather than a `w:tabs` entry in `setParagraphProperties`, because
2301
+ * `OoxmlProperty` is flat and `w:tabs` carries its meaning in `w:tab` children — the
2302
+ * same reason `setListNumbering` exists for `w:numPr`.
2303
+ */
2304
+ readonly op: 'setParagraphTabStops';
2305
+ readonly paragraphId: string;
2306
+ readonly stops: readonly TabStopWrite[];
2307
+ /**
2308
+ * Every stop position IN FORCE when the editor read the paragraph, including the
2309
+ * ones a style supplied.
2310
+ *
2311
+ * Tab stops are read through the cascade and written at the paragraph level, so a
2312
+ * replace alone cannot remove an inherited stop — the user clears a row, the style
2313
+ * puts it straight back, and the command reports success. A position that was in
2314
+ * force and is not in `stops` is suppressed with `w:val="clear"`, which is what the
2315
+ * value exists for (§17.3.1.37). Omit when the caller has no cascade to speak of;
2316
+ * the write is then a plain paragraph-level replace.
2317
+ */
2318
+ readonly inForcePositionsTwips?: readonly number[];
2319
+ } | {
2320
+ readonly op: 'splitParagraph';
2321
+ readonly paragraphId: string;
2322
+ readonly offset: number;
2323
+ /**
2324
+ * The `w:pStyle` the MINTED tail takes, instead of the head's own.
2325
+ *
2326
+ * A split otherwise clones the whole `w:pPr`, which is right for every property but
2327
+ * the style when the caller is an Enter at the end of a paragraph: Word gives that
2328
+ * new paragraph the style's `w:next`, so a heading is followed by body text rather
2329
+ * than by a second heading. `null` authors no `w:pStyle` at all, which is what the
2330
+ * document's default style is spelled as. Omit to clone the head's style unchanged.
2331
+ */
2332
+ readonly tailStyleId?: string | null;
2333
+ } | {
2334
+ /**
2335
+ * Split one `w:p` at MANY offsets in a single op.
2336
+ *
2337
+ * Equivalent to applying `splitParagraph` at each offset from the last to the first,
2338
+ * but the paragraph's content is cut in one pass and the parent's child sequence is
2339
+ * rebuilt once. A plain-text paste is a paragraph mark per line: as individual ops,
2340
+ * a large paste rebuilt the body — and re-sliced the pasted text — once per line,
2341
+ * which is quadratic in paste size.
2342
+ */
2343
+ readonly op: 'splitParagraphMany';
2344
+ readonly paragraphId: string;
2345
+ /**
2346
+ * Non-decreasing UTF-16 offsets; each produces one paragraph boundary. A repeated
2347
+ * offset produces an empty paragraph between the two boundaries — a blank line.
2348
+ */
2349
+ readonly offsets: readonly number[];
2350
+ /**
2351
+ * Propose the breaks rather than making them, exactly as the single split does.
2352
+ *
2353
+ * Every boundary is a paragraph mark this author is adding, so each paragraph that
2354
+ * PRECEDES one carries `w:rPr/w:ins`. Without it a multi-line paste in suggesting mode
2355
+ * tracked its text and not its breaks, and Reject left the extra paragraphs standing.
2356
+ */
2357
+ readonly revision?: RevisionAttributionInput;
2358
+ } | {
2359
+ readonly op: 'joinParagraphs';
2360
+ readonly firstId: string;
2361
+ readonly secondId: string;
2362
+ } | {
2363
+ readonly op: 'setRunProperties';
2364
+ readonly paragraphId: string;
2365
+ readonly start: number;
2366
+ readonly end: number;
2367
+ readonly properties: readonly OoxmlProperty[];
2368
+ /**
2369
+ * Record this as a TRACKED format change: each run keeps its new `w:rPr` and gains a
2370
+ * `w:rPrChange` (§17.13.5.30) holding the properties it had, so Reject restores them.
2371
+ */
2372
+ readonly revision?: RevisionAttributionInput;
2373
+ /**
2374
+ * When set, format only these runs (field result ownership). Offset range still
2375
+ * gates the edit and drives edge splits; without this, multi-run field results that
2376
+ * share one atom offset would homogenise under a single property bag.
2377
+ */
2378
+ readonly targetRunIds?: readonly string[];
2379
+ } | {
2380
+ readonly op: 'setParagraphProperties';
2381
+ readonly paragraphId: string;
2382
+ readonly properties: readonly OoxmlProperty[];
2383
+ /** Record this as a TRACKED format change (`w:pPrChange`, §17.13.5.29). */
2384
+ readonly revision?: RevisionAttributionInput;
2385
+ } | {
2386
+ /**
2387
+ * Set page-setup fields — page size, orientation, margins — on every targeted
2388
+ * `w:sectPr`: all of them (Word's "Apply to: Whole document", the default) or
2389
+ * only the one governing `anchorParagraphId`. A document whose write must reach
2390
+ * the implicit tail section gets a body-level `w:sectPr` minted as the body's
2391
+ * last child. Omitted fields are left exactly as authored per section. Explicit
2392
+ * dimensions are written literally; `orientation` WITHOUT dimensions swaps each
2393
+ * section's own (see `plannedSectionDimensions`), so distinct paper sizes
2394
+ * survive a whole-document flip.
2395
+ */
2396
+ readonly op: 'setSectionProperties';
2397
+ readonly pageWidthTwips?: number;
2398
+ readonly pageHeightTwips?: number;
2399
+ readonly orientation?: 'portrait' | 'landscape';
2400
+ readonly marginTopTwips?: number;
2401
+ readonly marginRightTwips?: number;
2402
+ readonly marginBottomTwips?: number;
2403
+ readonly marginLeftTwips?: number;
2404
+ /**
2405
+ * Word's "Apply to: This section": update only the section GOVERNING this
2406
+ * paragraph — the nearest mid-body `w:sectPr` at or after it, else the body-level
2407
+ * one. Absent means every section.
2408
+ */
2409
+ readonly anchorParagraphId?: string;
2410
+ } | {
2411
+ /**
2412
+ * End a section AT this paragraph: mint a `w:pPr/w:sectPr` cloning the governing
2413
+ * section's effective page setup, so the blocks up to and including this paragraph
2414
+ * become their own section. The paragraph must not already carry one.
2415
+ */
2416
+ readonly op: 'setSectionMark';
2417
+ readonly paragraphId: string;
2418
+ /**
2419
+ * Where the section that STARTS after this mark begins — Word's Breaks menu.
2420
+ *
2421
+ * `w:type` states how a section starts relative to the previous one (§17.6.22), so it
2422
+ * is written on the section FOLLOWING the mark, never on the minted one, which keeps
2423
+ * the cloned type because it starts where the section it was cut from did. `'nextPage'`
2424
+ * clears `w:type` (absent IS nextPage), so a next-page break inside a continuous
2425
+ * section really starts a page. Omitted leaves the following section untouched.
2426
+ */
2427
+ readonly breakType?: 'nextPage' | 'continuous';
2428
+ } | {
2429
+ /**
2430
+ * Wrap `[start, end)` of a paragraph in a `w:hyperlink`.
2431
+ *
2432
+ * The RANGE is the link — text and formatting inside it are untouched, and runs that
2433
+ * straddle either edge are divided so the link covers exactly the characters asked
2434
+ * for. Exactly one of `relationshipId` (an external target, already minted on the
2435
+ * package) or `anchor` (a bookmark in this document) names where it goes.
2436
+ *
2437
+ * A collapsed range is refused: a link with no text is markup with nothing to click,
2438
+ * and the caller that wants "insert a link with display text" inserts the text first.
2439
+ */
2440
+ readonly op: 'insertHyperlink';
2441
+ readonly paragraphId: string;
2442
+ readonly start: number;
2443
+ readonly end: number;
2444
+ readonly relationshipId?: string;
2445
+ readonly anchor?: string;
2446
+ readonly tooltip?: string;
2447
+ /**
2448
+ * Character style to mark the linked runs with (`w:rStyle`), normally `Hyperlink`.
2449
+ *
2450
+ * Written HERE rather than through `setRunProperties` because `w:rStyle` is preserved,
2451
+ * not accepted: it is not in the set a property write replaces, and putting it there
2452
+ * would make a later bold toggle delete it. Marking the text is part of making it a
2453
+ * link — Word does both in one operation — so the op that wraps it also styles it.
2454
+ * Omitted for a document that declares no such style.
2455
+ */
2456
+ readonly styleId?: string;
2457
+ } | {
2458
+ /**
2459
+ * Re-aim an existing link. `relationshipId` moves it to another external target,
2460
+ * `anchor` to a bookmark; supplying one CLEARS the other, so a link never ends up
2461
+ * carrying both and resolving by the wrong one.
2462
+ */
2463
+ readonly op: 'setHyperlinkTarget';
2464
+ readonly linkId: string;
2465
+ readonly relationshipId?: string;
2466
+ readonly anchor?: string;
2467
+ readonly tooltip?: string;
2468
+ } | {
2469
+ /**
2470
+ * Unlink: splice the `w:hyperlink`'s children into the paragraph in its place.
2471
+ *
2472
+ * The runs keep their identity, their formatting and their order, and any bookmark
2473
+ * markers inside the link stay exactly where they were. Only the link element goes,
2474
+ * which is what Word's Remove Hyperlink does — the text is not the link's, it was
2475
+ * only wrapped by it.
2476
+ */
2477
+ readonly op: 'removeHyperlink';
2478
+ readonly linkId: string;
2479
+ } | {
2480
+ /**
2481
+ * Replace one preserved `m:oMath` atom from bounded linear-math input.
2482
+ *
2483
+ * The complete equation changes as one unit. Internal OMML text never enters the
2484
+ * paragraph offset space, so callers cannot leave a partially edited math tree.
2485
+ */
2486
+ readonly op: 'setMathEquation';
2487
+ readonly equationId: string;
2488
+ readonly linear: string;
2489
+ } | {
2490
+ /** Remove one complete `m:oMath` atom. */
2491
+ readonly op: 'removeMathEquation';
2492
+ readonly equationId: string;
2493
+ } | {
2494
+ /**
2495
+ * Insert a NEW run-level content control at a text offset: `w:sdt` with a
2496
+ * `w:sdtPr` carrying the given tag (and alias/lock) and a `w:sdtContent`
2497
+ * holding one run of `text`.
2498
+ *
2499
+ * The write half of the custom-node contract (pro-review-and-custom-nodes):
2500
+ * a node's identity lives in `w:tag`, `sdtLocked` keeps Word users from
2501
+ * unwrapping the anchor, and the literal run text is what Word (and the
2502
+ * free tier) render. The TAG IS ATTACKER-ADJACENT ON READ but authored
2503
+ * here; it is written as an ordinary attribute value, so the serializer's
2504
+ * escaping covers it like every other attribute.
2505
+ */
2506
+ readonly op: 'insertInlineContentControl';
2507
+ readonly paragraphId: string;
2508
+ readonly offset: number;
2509
+ readonly tag: string;
2510
+ readonly text: string;
2511
+ readonly alias?: string;
2512
+ /** `w:lock` value; omitted writes no lock. */
2513
+ readonly lock?: 'sdtLocked' | 'sdtContentLocked' | 'contentLocked';
2514
+ /**
2515
+ * `w:dataBinding` — the customXml data part node this control mirrors.
2516
+ *
2517
+ * The payload half of the custom-node contract: `w:tag` caps at 64
2518
+ * characters, so anything larger lives in a data part and the control
2519
+ * points at it. All three attributes travel together because Word needs
2520
+ * all three — the store's `ds:itemID`, the XPath to the node's label, and
2521
+ * the prefix declaration that XPath's steps resolve through.
2522
+ *
2523
+ * A control that carries one is READ-ONLY in Word (verified against
2524
+ * `sdt-custom-node-databinding-word-roundtrip.docx`), and this engine
2525
+ * refuses content edits inside it for the same reason — see
2526
+ * `bindingRefusal`. That is what keeps the store and the page from
2527
+ * drifting: there is no edit that could move one without the other.
2528
+ *
2529
+ * Nothing here is resolved or fetched. The op writes the three strings and
2530
+ * the store lane owns the part they name.
2531
+ */
2532
+ readonly dataBinding?: {
2533
+ readonly prefixMappings: string;
2534
+ readonly xpath: string;
2535
+ readonly storeItemId: string;
2536
+ };
2537
+ } | {
2538
+ /** Repeating-section item insert — unsupported at this layer (out of scope). */
2539
+ readonly op: 'addRepeatingSectionItem';
2540
+ readonly controlId: string;
2541
+ readonly index?: number;
2542
+ } | {
2543
+ /** Repeating-section item remove — unsupported at this layer (out of scope). */
2544
+ readonly op: 'removeRepeatingSectionItem';
2545
+ readonly controlId: string;
2546
+ readonly index: number;
2547
+ } | {
2548
+ /**
2549
+ * Remove a typed block and everything under it.
2550
+ *
2551
+ * Validation restricts this structural operation to `w:p`, `w:tbl`, and `w:tr`, and
2552
+ * refuses removals that would violate required-container or section-mark invariants.
2553
+ */
2554
+ readonly op: 'deleteBlock';
2555
+ readonly blockId: string;
2556
+ } | {
2557
+ /**
2558
+ * Insert a fresh empty table immediately before a block-level paragraph.
2559
+ *
2560
+ * Before, never after, so the anchor paragraph stays as the block that follows the
2561
+ * table: a `w:tbl` is not a valid final child of a story container, and two tables
2562
+ * that end up adjacent merge into one when the file is reopened. When the anchor's
2563
+ * previous sibling is already a table, a separating empty paragraph is authored with
2564
+ * it, which is what Word does for the same reason.
2565
+ */
2566
+ readonly op: 'insertTable';
2567
+ readonly beforeParagraphId: string;
2568
+ readonly rows: number;
2569
+ readonly cols: number;
2570
+ /** Width of every grid column, in twips. The caller divides the content width. */
2571
+ readonly columnWidthTwips: number;
2572
+ } | {
2573
+ /** Insert a fresh row above or below a canonical table row. */
2574
+ readonly op: 'insertTableRow';
2575
+ readonly tableId: string;
2576
+ readonly rowId: string;
2577
+ readonly where: 'above' | 'below';
2578
+ /** When present, author the row as a Word tracked insertion. */
2579
+ readonly revision?: RevisionAttributionInput;
2580
+ } | {
2581
+ /** Delete one canonical table row; refuses the final row. */
2582
+ readonly op: 'deleteTableRow';
2583
+ readonly tableId: string;
2584
+ readonly rowId: string;
2585
+ /** Optional anchor cell for column-aware caret recovery after deletion. */
2586
+ readonly referenceCellId?: string;
2587
+ /** When present, retain the row and author a Word tracked deletion. */
2588
+ readonly revision?: RevisionAttributionInput;
2589
+ } | {
2590
+ /** Insert one grid column left or right of a canonical `w:gridCol`. */
2591
+ readonly op: 'insertTableColumn';
2592
+ readonly tableId: string;
2593
+ readonly where: 'left' | 'right';
2594
+ readonly gridColumnId: string;
2595
+ } | {
2596
+ /**
2597
+ * Insert one grid column beside a first-row reference cell when `w:tblGrid` is absent.
2598
+ * Synthesizes a canonical grid before mutation.
2599
+ */
2600
+ readonly op: 'insertTableColumn';
2601
+ readonly tableId: string;
2602
+ readonly where: 'left' | 'right';
2603
+ readonly referenceCellId: string;
2604
+ } | {
2605
+ /** Delete one canonical grid column; refuses the final column. */
2606
+ readonly op: 'deleteTableColumn';
2607
+ readonly tableId: string;
2608
+ readonly gridColumnId: string;
2609
+ } | {
2610
+ /**
2611
+ * Resize one internal divider between two adjacent canonical grid columns.
2612
+ * Preserves the pair total and sets fixed table layout.
2613
+ */
2614
+ readonly op: 'setTableColumnWidths';
2615
+ readonly tableId: string;
2616
+ readonly leftGridColumnId: string;
2617
+ readonly rightGridColumnId: string;
2618
+ readonly leftWidthTwips: number;
2619
+ readonly rightWidthTwips: number;
2620
+ } | {
2621
+ /**
2622
+ * Resize the outer-right edge: last grid column, matching cells, and `w:tblW` total.
2623
+ */
2624
+ readonly op: 'setTableRightEdgeWidth';
2625
+ readonly tableId: string;
2626
+ readonly gridColumnId: string;
2627
+ readonly columnWidthTwips: number;
2628
+ readonly tableWidthTwips: number;
2629
+ } | {
2630
+ /** Set one authored table row to an exact height in twips. */
2631
+ readonly op: 'setTableRowHeight';
2632
+ readonly tableId: string;
2633
+ readonly rowId: string;
2634
+ readonly heightTwips: number;
2635
+ } | {
2636
+ /** Clear the active edge target on a bounded rectangular cell selection. */
2637
+ readonly op: 'setTableCellBorders';
2638
+ readonly tableId: string;
2639
+ readonly cellIds: readonly string[];
2640
+ readonly scope: 'none';
2641
+ readonly target: TableBorderEdgeTarget;
2642
+ } | {
2643
+ /** Apply a complete border spec to the requested edge target. */
2644
+ readonly op: 'setTableCellBorders';
2645
+ readonly tableId: string;
2646
+ readonly cellIds: readonly string[];
2647
+ readonly scope: TableBorderEdgeTarget;
2648
+ readonly spec: TableBorderSpecInput;
2649
+ } | {
2650
+ /** Write or remove direct selected-cell shading (`w:tcPr/w:shd`). */
2651
+ readonly op: 'setTableCellFill';
2652
+ readonly tableId: string;
2653
+ readonly cellIds: readonly string[];
2654
+ readonly color: TreeDocColorValue | null;
2655
+ } | {
2656
+ /** Set direct selected-cell vertical alignment (`w:tcPr/w:vAlign`). */
2657
+ readonly op: 'setTableCellVerticalAlignment';
2658
+ readonly tableId: string;
2659
+ readonly cellIds: readonly string[];
2660
+ readonly alignment: 'top' | 'center' | 'bottom';
2661
+ } | {
2662
+ /** Allocate an empty header/footer part and declare it on a section. Package-level. */
2663
+ readonly op: 'createHeaderFooter';
2664
+ readonly sectionIndex: number;
2665
+ readonly kind: 'header' | 'footer';
2666
+ readonly variant: 'default' | 'first' | 'even';
2667
+ /** When true, also set section `w:titlePg` in the same package transaction. */
2668
+ readonly titlePage?: boolean;
2669
+ /** When true, also set document `w:evenAndOddHeaders` in the same package transaction. */
2670
+ readonly evenAndOddHeaders?: boolean;
2671
+ } | {
2672
+ /** Remove a section's declared header/footer reference; GC when orphaned. Package-level. */
2673
+ readonly op: 'deleteHeaderFooter';
2674
+ readonly sectionIndex: number;
2675
+ readonly kind: 'header' | 'footer';
2676
+ readonly variant: 'default' | 'first' | 'even';
2677
+ } | {
2678
+ /** Drop a declared ref so the section inherits from the previous. Package-level. */
2679
+ readonly op: 'linkToPrevious';
2680
+ readonly sectionIndex: number;
2681
+ readonly kind: 'header' | 'footer';
2682
+ readonly variant: 'default' | 'first' | 'even';
2683
+ } | {
2684
+ /** Clone an inherited part into a new declared reference. Package-level. */
2685
+ readonly op: 'unlinkFromPrevious';
2686
+ readonly sectionIndex: number;
2687
+ readonly kind: 'header' | 'footer';
2688
+ readonly variant: 'default' | 'first' | 'even';
2689
+ } | {
2690
+ /**
2691
+ * Section/document furniture options: `titlePg`, header/footer distances on the
2692
+ * section; `evenAndOddHeaders` document-wide in settings. Package-level.
2693
+ */
2694
+ readonly op: 'setSectionFurnitureOptions';
2695
+ readonly sectionIndex?: number;
2696
+ readonly titlePage?: boolean;
2697
+ readonly evenAndOddHeaders?: boolean;
2698
+ readonly headerDistanceTwips?: number;
2699
+ readonly footerDistanceTwips?: number;
2700
+ } | {
2701
+ /**
2702
+ * Insert a footnote or endnote: body reference + notes-part body (+ create the
2703
+ * notes part/rel/content-type when missing). Package-level; one ModelChange.
2704
+ */
2705
+ readonly op: 'insertNote';
2706
+ readonly noteKind: 'footnote' | 'endnote';
2707
+ readonly paragraphId: string;
2708
+ readonly offset: number;
2709
+ /**
2710
+ * Write the citing REFERENCE as a tracked insertion (`w:ins` around the reference
2711
+ * run), on the same terms as `insertText`. The note body itself is not revision
2712
+ * markup: rejecting the reference removes it, and the body cascade sweeps the
2713
+ * orphaned note exactly as an untracked reference deletion does.
2714
+ */
2715
+ readonly revision?: RevisionAttributionInput;
2716
+ } | {
2717
+ /**
2718
+ * Delete a note body and every matching reference (body, HF, other notes).
2719
+ * Package-level; one ModelChange.
2720
+ */
2721
+ readonly op: 'deleteNote';
2722
+ readonly noteKind: 'footnote' | 'endnote';
2723
+ readonly noteId: number;
2724
+ } | {
2725
+ /** Convert a footnote ↔ endnote, reallocating id in the target part. Package-level. */
2726
+ readonly op: 'convertNote';
2727
+ readonly fromKind: 'footnote' | 'endnote';
2728
+ readonly noteId: number;
2729
+ } | {
2730
+ /**
2731
+ * Convert every normal footnote↔endnote of `fromKind` in one package transaction.
2732
+ * One ModelChange / undo unit; bounded by notes-part size.
2733
+ */
2734
+ readonly op: 'convertAllNotes';
2735
+ readonly fromKind: 'footnote' | 'endnote';
2736
+ } | {
2737
+ /**
2738
+ * Write a content control's VALUE, in the vocabulary its own type accepts.
2739
+ *
2740
+ * One transaction for the whole transition: the content, `w:showingPlcHdr`, and the
2741
+ * type's own record of the value (`@w:lastValue`, `@w:fullDate`, `w14:checked`) move
2742
+ * together, because a control whose glyph says checked and whose flag says unchecked is
2743
+ * a document Word and this engine read differently.
2744
+ */
2745
+ readonly op: 'setContentControlValue';
2746
+ readonly controlId: string;
2747
+ /** String is the editor-facing v2 form; structured input is the automation form. */
2748
+ readonly value: string | ContentControlValueInput;
2749
+ } | {
2750
+ /**
2751
+ * Author the metadata a control carries: its tag, its title, its lock.
2752
+ *
2753
+ * `null` removes the property. Everything else in `CT_SdtPr` — the type payload, a data
2754
+ * binding, an extension this vocabulary does not model — survives in schema order.
2755
+ */
2756
+ readonly op: 'setContentControlProperties';
2757
+ readonly controlId: string;
2758
+ readonly tag?: string | null;
2759
+ readonly alias?: string | null;
2760
+ readonly lock?: ContentControlLock;
2761
+ } | {
2762
+ /**
2763
+ * Remove a control. `keepContent` splices its content into its place — Word's own
2764
+ * "Remove content control" — and false takes the content with it.
2765
+ */
2766
+ readonly op: 'removeContentControl';
2767
+ readonly controlId: string;
2768
+ /** Defaults to true for the editor-facing v2 operation. */
2769
+ readonly keepContent?: boolean;
2770
+ } | {
2771
+ /**
2772
+ * Wrap `[start, end)` of a paragraph in a new control of the named type.
2773
+ *
2774
+ * A control is a SIBLING of runs, never a thing inside one, so a range ending mid-run
2775
+ * splits that run at both edges first. The characters and their formatting are the ones
2776
+ * that were there; only the run boundaries move.
2777
+ */
2778
+ readonly op: 'insertContentControl';
2779
+ readonly paragraphId: string;
2780
+ readonly start: number;
2781
+ readonly end: number;
2782
+ readonly type: InsertableContentControlKind;
2783
+ readonly tag?: string;
2784
+ readonly alias?: string;
2785
+ readonly lock?: ContentControlLock;
2786
+ } | {
2787
+ /**
2788
+ * Author `w:footnotePr` / `w:endnotePr` at document (settings) or section scope.
2789
+ * Refuse endnote `pageBottom`. Package-level; does not invent props on unedited saves.
2790
+ */
2791
+ readonly op: 'setNoteProperties';
2792
+ readonly scope: 'document' | 'section';
2793
+ readonly sectionIndex?: number;
2794
+ readonly footnote?: {
2795
+ readonly numFmt?: string;
2796
+ readonly numRestart?: string;
2797
+ readonly position?: string;
2798
+ readonly numStart?: number;
2799
+ };
2800
+ readonly endnote?: {
2801
+ readonly numFmt?: string;
2802
+ readonly numRestart?: string;
2803
+ readonly position?: string;
2804
+ readonly numStart?: number;
2805
+ };
2806
+ } | {
2807
+ /**
2808
+ * Insert clipboard-fragment blocks at a paragraph position, atomically.
2809
+ *
2810
+ * Blocks only — resources (styles, numbering, media, rels, note parts) merge through
2811
+ * the package-edit path in the same transaction, and the whole commit is promoted to
2812
+ * a package undo unit. A merged edge paragraph takes the properties of the paragraph
2813
+ * mark that ends it: the fragment's first mark leading, the host's original mark
2814
+ * trailing. Nodes receive fresh ids at apply.
2815
+ */
2816
+ readonly op: 'insertFragment';
2817
+ readonly paragraphId: string;
2818
+ readonly offset: number;
2819
+ readonly blocks: readonly OoxmlNode[];
2820
+ /** True when the fragment's last paragraph mark travelled (its paragraph stays whole). */
2821
+ readonly lastMarkCovered?: boolean;
2822
+ } | {
2823
+ readonly op: 'insertDrawing';
2824
+ readonly paragraphId: string;
2825
+ readonly offset: number;
2826
+ readonly drawing: OoxmlDrawingNode;
2827
+ /** Present in suggesting mode: the drawing's run goes into a `w:ins` as one proposal. */
2828
+ readonly revision?: RevisionAttributionInput;
2829
+ } | {
2830
+ readonly op: 'replaceDrawingResource';
2831
+ readonly drawingNodeId: string;
2832
+ readonly relationshipId: string;
2833
+ } | {
2834
+ readonly op: 'deleteDrawing';
2835
+ readonly drawingNodeId: string;
2836
+ /** Suggesting-mode tracked deletion is refused; owned by typed-revisions-and-comments. */
2837
+ readonly revision?: RevisionAttributionInput;
2838
+ } | {
2839
+ readonly op: 'resizeDrawing';
2840
+ readonly drawingNodeId: string;
2841
+ readonly extentEmu: {
2842
+ readonly cx: number;
2843
+ readonly cy: number;
2844
+ };
2845
+ } | {
2846
+ readonly op: 'cropDrawing';
2847
+ readonly drawingNodeId: string;
2848
+ readonly crop: SourceCrop;
2849
+ } | {
2850
+ readonly op: 'positionDrawing';
2851
+ readonly drawingNodeId: string;
2852
+ readonly position: DrawingPositionInput;
2853
+ } | {
2854
+ readonly op: 'setDrawingWrap';
2855
+ readonly drawingNodeId: string;
2856
+ readonly wrap: ImageWrapTarget;
2857
+ } | {
2858
+ readonly op: 'setDrawingMetadata';
2859
+ readonly drawingNodeId: string;
2860
+ readonly title: string;
2861
+ readonly description: string;
2862
+ /** Omitted preserves existing `a:hlinkClick`; null removes it; a URL needs a package transaction. */
2863
+ readonly hyperlink?: string | null;
2864
+ } | {
2865
+ readonly op: 'setDrawingLocks';
2866
+ readonly drawingNodeId: string;
2867
+ readonly locks: DrawingLocksInput;
2868
+ } | {
2869
+ readonly op: 'transformDrawing';
2870
+ readonly drawingNodeId: string;
2871
+ readonly action: 'rotateCW' | 'rotateCCW' | 'flipH' | 'flipV';
2872
+ } | {
2873
+ /**
2874
+ * Replace a detected TOC field's cached result paragraphs and ensure heading bookmarks.
2875
+ * Preserves field chrome / instruction. One undo unit (phase A of TOC refresh).
2876
+ */
2877
+ readonly op: 'replaceTocResult';
2878
+ readonly tocId: string;
2879
+ readonly entries: readonly {
2880
+ readonly level: number;
2881
+ readonly text: string;
2882
+ readonly headingParagraphId: string;
2883
+ readonly bookmarkName: string;
2884
+ readonly pageNumberText: string;
2885
+ }[];
2886
+ readonly bookmarksToCreate: readonly {
2887
+ readonly paragraphId: string;
2888
+ readonly name: string;
2889
+ }[];
2890
+ } | {
2891
+ /**
2892
+ * Rewrite page-number text runs inside existing TOC result paragraphs.
2893
+ * One undo unit (phase B of TOC refresh).
2894
+ */
2895
+ readonly op: 'rewriteTocPageNumbers';
2896
+ readonly tocId: string;
2897
+ readonly updates: readonly {
2898
+ readonly paragraphId: string;
2899
+ readonly pageNumberText: string;
2900
+ }[];
2901
+ };
2902
+ /** Drawing mutation ops from typed-drawings-and-images task 11. */
2903
+ type DrawingTreeDocOp = Extract<TreeDocOp, {
2904
+ readonly op: 'insertDrawing' | 'replaceDrawingResource' | 'deleteDrawing' | 'resizeDrawing' | 'cropDrawing' | 'positionDrawing' | 'setDrawingWrap' | 'setDrawingMetadata' | 'setDrawingLocks' | 'transformDrawing';
2905
+ }>;
2906
+ /** Just the `op` discriminants, for dispatch tables and validation. */
2907
+ type TreeDocOpKind = TreeDocOp['op'];
2908
+ /** Every {@link TreeDocOpKind}, for validation and exhaustiveness checks. */
2909
+ declare const TREE_DOC_OP_KINDS: readonly ["replaceStoryBlocks", "insertText", "deleteText", "setParagraphMarkRevision", "proposeParagraphMerge", "insertCommentMarker", "acceptRevision", "rejectRevision", "acceptAllRevisions", "rejectAllRevisions", "insertTab", "insertHardBreak", "insertPageBreak", "insertPageField", "setListLevel", "setListNumbering", "setParagraphTabStops", "setParagraphMarkProperties", "splitParagraph", "splitParagraphMany", "joinParagraphs", "setRunProperties", "setParagraphProperties", "setSectionProperties", "setSectionMark", "insertHyperlink", "setHyperlinkTarget", "removeHyperlink", "setMathEquation", "removeMathEquation", "setContentControlValue", "removeContentControl", "insertInlineContentControl", "addRepeatingSectionItem", "removeRepeatingSectionItem", "deleteBlock", "insertTable", "insertTableRow", "deleteTableRow", "insertTableColumn", "deleteTableColumn", "setTableColumnWidths", "setTableRightEdgeWidth", "setTableRowHeight", "setTableCellBorders", "setTableCellFill", "setTableCellVerticalAlignment", "createHeaderFooter", "deleteHeaderFooter", "linkToPrevious", "unlinkFromPrevious", "setSectionFurnitureOptions", "insertNote", "deleteNote", "convertNote", "convertAllNotes", "setNoteProperties", "setContentControlProperties", "insertContentControl", "insertFragment", "insertDrawing", "replaceDrawingResource", "deleteDrawing", "resizeDrawing", "cropDrawing", "positionDrawing", "setDrawingWrap", "setDrawingMetadata", "setDrawingLocks", "transformDrawing", "insertToc", "replaceTocResult", "rewriteTocPageNumbers"];
2910
+ /**
2911
+ * How far a committed op can reach, so layout can scope its work (task 5.2).
2912
+ *
2913
+ * `text-local` touches one paragraph's characters; `paragraph-local` changes one
2914
+ * paragraph's own properties; `flow-structural` changes the block sequence and can
2915
+ * repaginate everything after it; `global` invalidates every page that shares the
2916
+ * edited story (header/footer parts attached to many sections/pages).
2917
+ */
2918
+ /**
2919
+ * How far an op's effects reach — what layout must re-do after it.
2920
+ *
2921
+ * The knob incremental layout turns: a `text-local` edit re-breaks one paragraph, while a
2922
+ * `global` one invalidates the document.
2923
+ */
2924
+ type ImpactClass = 'text-local' | 'paragraph-local' | 'flow-structural' | 'global';
2925
+ /**
2926
+ * What one applied op changed: the ids dirtied, created and deleted.
2927
+ *
2928
+ * These ids are what let layout and paint re-do only what moved instead of the whole document.
2929
+ */
2930
+ interface TreeOpEffect {
2931
+ readonly dirty: readonly string[];
2932
+ readonly created: readonly string[];
2933
+ readonly deleted: readonly string[];
2934
+ readonly split?: {
2935
+ readonly from: string;
2936
+ readonly tail: string;
2937
+ };
2938
+ /** One entry per boundary of a many-way split, in document order. */
2939
+ readonly splits?: readonly {
2940
+ readonly from: string;
2941
+ readonly tail: string;
2942
+ }[];
2943
+ readonly join?: {
2944
+ readonly kept: string;
2945
+ readonly removed: string;
2946
+ };
2947
+ readonly dependencyKeys: readonly string[];
2948
+ readonly impact: ImpactClass;
2949
+ /** First post-edit caret paragraph for table column structural ops. */
2950
+ readonly caret?: {
2951
+ readonly paragraphId: string;
2952
+ };
2953
+ }
2954
+ /**
2955
+ * Why an op was refused.
2956
+ *
2957
+ * `not-adjacent-siblings` is the notable one: a join across table cells is refused rather than
2958
+ * silently merging content out of the cell that owned it.
2959
+ */
2960
+ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' | 'offset-out-of-range' | 'invalid-range' | 'not-a-list-paragraph' | 'splits-surrogate-pair' | 'invalid-text' | 'unsupported-property' | 'invalid-property-value' | 'not-adjacent-siblings'
2961
+ /**
2962
+ * The addressed position is strictly inside content nothing can divide: a hyperlink, an
2963
+ * inline content control, a revision wrapper, or an atomic field.
2964
+ *
2965
+ * Distinct from `invalid-range`, which is an offset the paragraph does not have. This one is
2966
+ * a real offset that is not a PLACE — refused rather than resolved to the nearest one, so a
2967
+ * caller learns the node would not have landed where they asked.
2968
+ */
2969
+ | 'indivisible-content' | 'unknown-block' | 'not-a-block' | 'block-required' | 'carries-section-mark'
2970
+ /** The transaction named a part the package does not hold. */
2971
+ | 'unknown-part'
2972
+ /**
2973
+ * The transaction would have published a package that does not open: a relationship
2974
+ * pointing at a part nobody created, or a part with no declared content type.
2975
+ */
2976
+ | 'package-invariant'
2977
+ /** No revision in this part carries the addressed `(id, author, date)` triple. */
2978
+ | 'unknown-revision'
2979
+ /**
2980
+ * A matched revision is a kind whose accept/reject semantics are structural and not
2981
+ * implemented. Refusing is deliberate: removing the markup alone would report the decision
2982
+ * applied while leaving the row, cell, or section it describes untouched.
2983
+ */
2984
+ | 'unsupported-revision' | 'tree-invariant'
2985
+ /** No content control in this part carries the addressed node id. */
2986
+ | 'unknown-content-control'
2987
+ /** The addressed node exists and is not a `w:sdt`. */
2988
+ | 'not-a-content-control'
2989
+ /**
2990
+ * A content control's `w:lock` — or one an enclosing control imposes — forbids this.
2991
+ *
2992
+ * The same code for an edit inside `contentLocked` content and for the removal of an
2993
+ * `sdtLocked` control: both are "the document says no", and the two halves are already
2994
+ * distinguished by which operation was refused.
2995
+ */
2996
+ | 'locked'
2997
+ /** The control declares `w:dataBinding`; its value belongs to a custom XML part. */
2998
+ | 'bound'
2999
+ /** The value offered is not one this control's type accepts. */
3000
+ | 'typeMismatch' | 'unknown-control' | 'unsupported'
3001
+ /** Malformed lifecycle args / first-section link — mirrors Editor `invalidArgs`. */
3002
+ | 'invalidArgs'
3003
+ /** The addressed table id is missing, duplicated, or not a typed table. */
3004
+ | 'unknown-table'
3005
+ /** The addressed row id is missing or not a direct child of the table. */
3006
+ | 'unknown-row'
3007
+ /** A table property container appears more than once on a typed node. */
3008
+ | 'duplicate-property-container'
3009
+ /**
3010
+ * A row holds a `w:tc` inside a cell-level wrapper such as `w:sdt`, so the row's grid
3011
+ * mapping cannot be trusted and the inserted row would not match it.
3012
+ */
3013
+ | 'row-hides-cell'
3014
+ /** Column edit refused because the table carries horizontal or vertical merges. */
3015
+ | 'table-has-merge'
3016
+ /** The addressed grid column id is missing or ambiguous without `w:tblGrid`. */
3017
+ | 'unknown-grid-column'
3018
+ /** The operation would exceed bounded table topology limits. */
3019
+ | 'resource-limit'
3020
+ /** The addressed node is not a top-level `w:drawing`. */
3021
+ | 'not-a-drawing'
3022
+ /** No `w:drawing` with this id exists in the part. */
3023
+ | 'unknown-drawing'
3024
+ /** The drawing's graphic payload is not a supported picture. */
3025
+ | 'not-a-picture-drawing'
3026
+ /** A lock flag or `@locked` forbids this mutation. */
3027
+ | 'drawing-locked'
3028
+ /** Finite EMU extent, crop, or position value is out of range. */
3029
+ | 'invalid-drawing-value'
3030
+ /** Insertion would cross a table-cell boundary or wrong story container. */
3031
+ | 'cross-cell-drawing'
3032
+ /** Suggesting-mode drawing deletion is not implemented in this change. */
3033
+ | 'trackedDrawingDeletionUnsupported'
3034
+ /** Hyperlink target creation or change needs an OPC relationship in a package transaction. */
3035
+ | 'packageTransactionRequired'
3036
+ /** A clipboard fragment block nests deeper than the recursion cap. */
3037
+ | 'fragment-too-deep'
3038
+ /** A clipboard fragment block is not a paragraph, table, or content control subtree. */
3039
+ | 'fragment-invalid-block'
3040
+ /** A clipboard fragment exceeds its block or node budget. */
3041
+ | 'fragment-resource-budget';
3042
+ /** Whether an op applied, with the effect it produced or the reason it was refused. */
3043
+ type TreeOpResult = {
3044
+ readonly ok: true;
3045
+ readonly part: OoxmlPart;
3046
+ readonly effect: TreeOpEffect;
3047
+ } | {
3048
+ readonly ok: false;
3049
+ readonly reason: TreeOpRejection;
3050
+ readonly detail?: string;
3051
+ };
3052
+
3053
+ export { type ContentControlKind as $, type DrawingVerticalReferenceFrame as A, type VectorImageMime as B, type ImageDecodePort as C, type DrawingKind as D, type RevisionAttributionInput as E, type DrawingTreeDocOp as F, type TreeDocColorValue as G, DEFAULT_IMAGE_RESOURCE_LIMITS as H, type ImpactClass as I, IMAGE_WRAP_TARGETS as J, type ImageResourceLimits as K, resolveImageResourceLimits as L, resolveSvgIntrinsicSize as M, sniffImageMime as N, type OoxmlPart as O, type PreservedImageMime as P, validateRasterHeader as Q, type RevisionAddress as R, type SourceCrop as S, type TreeDocOp as T, type DrawingAccessibility as U, type ValidatedImageBytesHandle as V, type DrawingTransform as W, type VectorShapeProjection as X, type DrawingProjection as Y, type OoxmlDrawingNode as Z, type TableBorderStyle as _, type OoxmlNode as a, type OoxmlContentControlStoreMappedDataAsNode as a$, type ContentControlLevel as a0, type ContentControlLock as a1, type ContentControlDataBinding as a2, type ResourceLimits as a3, type OoxmlInvariantResult as a4, type RelationshipRecord as a5, type OoxmlInvariantIssue as a6, type OoxmlHardBreakNode as a7, type OoxmlFldCharNode as a8, type OoxmlFldSimpleNode as a9, IMAGE_RESOURCE_HARD_CEILINGS as aA, type ImageRelationshipResolution as aB, type ImageResourceLookup as aC, type IndexResult as aD, MAX_CONTENT_CONTROLS_PER_PART as aE, MAX_CONTENT_CONTROL_NESTING as aF, MAX_SVG_SNIFF_BYTES as aG, type NameRejection as aH, type NameResult as aI, OFFICE_RELATIONSHIP_NAMESPACE_URI as aJ, OOXML_NODE_IDENTITY_RULES as aK, type OoxmlBodyNode as aL, type OoxmlBookmarkEndNode as aM, type OoxmlBookmarkStartNode as aN, type OoxmlContentControlCalendarNode as aO, type OoxmlContentControlCheckboxNode as aP, type OoxmlContentControlCheckedNode as aQ, type OoxmlContentControlCheckedStateNode as aR, type OoxmlContentControlComboBoxNode as aS, type OoxmlContentControlDataBindingNode as aT, type OoxmlContentControlDateFormatNode as aU, type OoxmlContentControlDateNode as aV, type OoxmlContentControlDropDownListNode as aW, type OoxmlContentControlEndPropertiesNode as aX, type OoxmlContentControlLidNode as aY, type OoxmlContentControlListItemNode as aZ, type OoxmlContentControlPropertiesNode as a_, type OoxmlInstrTextNode as aa, type OoxmlAttribute as ab, type TreeOpResult as ac, ACCEPTED_PARAGRAPH_PROPERTIES as ad, ACCEPTED_RUN_PROPERTIES as ae, CONTENT_CONTROL_ID_MAX as af, CONTENT_CONTROL_PROPERTY_ORDER as ag, type ContentControlCheckbox as ah, type ContentControlCheckboxState as ai, type ContentControlDateFormat as aj, type ContentControlEntry as ak, type ContentControlListItem as al, type ContentControlProperties as am, type ContentTypeError as an, type ContentTypeIndex as ao, type ContentTypeRecords as ap, type CreateImageResourceCacheOptions as aq, DEFAULT_LIMITS as ar, DEFAULT_OOXML_PACKAGE_LIMITS as as, DEFAULT_ZIP_LIMITS as at, type DefaultRecord as au, HARD_CEILINGS as av, HYPERLINK_RELATIONSHIP_TYPE as aw, type HyperlinkKind as ax, type HyperlinkTarget as ay, IMAGE_RELATIONSHIP_TYPE as az, type OoxmlPackage as b, flattenContentControls as b$, type OoxmlContentControlTextNode as b0, type OoxmlContentControlUncheckedStateNode as b1, type OoxmlDocumentNode as b2, type OoxmlExternalTarget as b3, type OoxmlGenericExtensionAttribute as b4, type OoxmlHyperlinkNode as b5, type OoxmlInvariantIssueCode as b6, type OoxmlKnownNodeAttribute as b7, type OoxmlNamespaceBinding as b8, type OoxmlNodeIdentityRules as b9, XMLNS_NAMESPACE_URI as bA, XML_NAMESPACE_URI as bB, type XmlLimits as bC, type XmlNode as bD, type XmlRejection as bE, type XmlResult as bF, type ZipLimits as bG, type ZipReadResult as bH, type ZipRejection as bI, allocateContentControlId as bJ, asciiFold as bK, buildContentTypeIndex as bL, buildRelationshipSet as bM, childElements as bN, contentControlContentChildren as bO, contentControlContentNodeOf as bP, contentControlEndPropertiesNodeOf as bQ, contentControlLevelOf as bR, contentControlPropertiesNodeOf as bS, contentControlPropertiesOf as bT, contentControlTextOf as bU, contentControlsIn as bV, createImageResourceCache as bW, detectDuplicateNames as bX, extensionKey as bY, findContentControl as bZ, findElement as b_, type OoxmlPackageResult as ba, type OoxmlParagraphPropertiesNode as bb, type OoxmlPartMetadata as bc, type OoxmlReadRejection as bd, type OoxmlReadResult as be, type OoxmlRunNode as bf, type OoxmlRunPropertiesNode as bg, type OoxmlTabNode as bh, type OoxmlTextElementNode as bi, type OoxmlTextNode as bj, type OoxmlWmlValAttribute as bk, type OoxmlXmlSpaceAttribute as bl, type OverrideRecord as bm, type RelationshipError as bn, type RelationshipSetResult as bo, type RelationshipTargetResolver as bp, type ResolveResult as bq, type ResolvedRelationship as br, TABLE_BORDER_STYLES as bs, TREE_DOC_OP_KINDS as bt, type TabStopWrite as bu, type TargetMode as bv, type TreeDocOpKind as bw, type TreeOpEffect as bx, type ValidatedRasterHeader as by, WML_NAMESPACE_URI as bz, type OoxmlNodeId as c, hasBoundedSvgRoot as c0, hyperlinkAnchorOf as c1, hyperlinkRelationshipIdOf as c2, hyperlinkTargetOf as c3, imageResourceLookupFor as c4, isContentControlContentNode as c5, isContentControlNode as c6, isContentControlWrapper as c7, isContentRevisionKind as c8, isHyperlinkNode as c9, withPart as cA, writeOoxmlPackage as cB, writeZip as cC, isRangeMarkerKind as ca, isValidMime as cb, liveDrawingReferenceCount as cc, lockForbidsEdit as cd, lockForbidsRemoval as ce, normalizePartName as cf, orderedContentControlProperties as cg, parseContentControlId as ch, partNameKey as ci, projectDrawing as cj, readOnOffChild as ck, readOoxmlPackage as cl, readOoxmlPart as cm, readXml as cn, readZip as co, resolveContentControlLock as cp, resolveContentType as cq, resolveImageRelationship as cr, resolveInternalTarget as cs, resolveLimits as ct, resolveRelationship as cu, textContent as cv, validateExternalTarget as cw, validateGifHeader as cx, validateJpegHeader as cy, validatePngHeader as cz, type OoxmlGenericElementNode as d, type OoxmlPackageLimits as e, type OoxmlPackageRejection as f, type OoxmlElement as g, type OoxmlContentControlNode as h, type OoxmlContentControlContentNode as i, type OoxmlParagraphNode as j, type OoxmlNoteNode as k, type OoxmlContinuationSeparatorNode as l, type OoxmlEndnotesNode as m, type OoxmlFootnotesNode as n, type OoxmlNoteRefNode as o, type OoxmlNoteReferenceNode as p, type OoxmlSeparatorNode as q, type TreeOpRejection as r, type OoxmlProperty as s, type RenderableImageMime as t, type ImageWrapTarget as u, type DrawingPositionInput as v, type DrawingLocks as w, type ImageResourceState as x, type SupportedImageMime as y, type DrawingHorizontalReferenceFrame as z };