@docx-editor.dev/core 2.26.0 → 2.28.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 (122) hide show
  1. package/dist/automation.cjs +1 -1
  2. package/dist/automation.d.ts +30 -13
  3. package/dist/automation.js +1 -1
  4. package/dist/binding.cjs +1 -1
  5. package/dist/binding.d.ts +20 -9
  6. package/dist/binding.js +1 -1
  7. package/dist/chunk-2GO5T2JU.cjs +1 -0
  8. package/dist/chunk-2RC2EPND.js +3 -0
  9. package/dist/chunk-4GBTELJV.cjs +28 -0
  10. package/dist/chunk-4R3TEXMN.js +18 -0
  11. package/dist/chunk-5CSUYANV.js +1 -0
  12. package/dist/chunk-6APGXLBB.cjs +3 -0
  13. package/dist/chunk-6AWEKBLB.cjs +1 -0
  14. package/dist/chunk-6EYYL7FL.js +1 -0
  15. package/dist/chunk-E7BQA6UP.js +2 -0
  16. package/dist/chunk-EO4C5QJW.cjs +2 -0
  17. package/dist/chunk-ETTO6GK3.js +1 -0
  18. package/dist/chunk-FIJZIQXA.cjs +18 -0
  19. package/dist/chunk-FRXAOVTB.js +28 -0
  20. package/dist/chunk-J6BVWIDB.js +2 -0
  21. package/dist/chunk-JGNVNT2A.cjs +2 -0
  22. package/dist/chunk-K5U2PLDP.cjs +2 -0
  23. package/dist/chunk-KKIJG3C6.js +2 -0
  24. package/dist/chunk-LWDSDCMO.js +27 -0
  25. package/dist/chunk-NBCVVZOM.cjs +1 -0
  26. package/dist/chunk-O2AL2HSJ.cjs +1 -0
  27. package/dist/{chunk-AJCCS53D.js → chunk-O5INAWZQ.js} +1 -1
  28. package/dist/chunk-QMLCVPCD.cjs +1 -0
  29. package/dist/chunk-RCHS4ZEH.cjs +27 -0
  30. package/dist/chunk-SRPILEWV.cjs +5 -0
  31. package/dist/chunk-TSLBZ26X.js +1 -0
  32. package/dist/chunk-VDNNLG6X.js +2 -0
  33. package/dist/chunk-VHAVHCQY.js +7 -0
  34. package/dist/chunk-VX43VBAX.cjs +7 -0
  35. package/dist/chunk-Z6WBFXJU.js +5 -0
  36. package/dist/chunk-ZUHOMK52.cjs +2 -0
  37. package/dist/collaboration/replication.cjs +1 -1
  38. package/dist/collaboration/replication.d.ts +50 -5
  39. package/dist/collaboration/replication.js +1 -1
  40. package/dist/collaboration.cjs +1 -1
  41. package/dist/collaboration.d.ts +98 -6
  42. package/dist/collaboration.js +1 -1
  43. package/dist/contracts/document.d.ts +17 -2
  44. package/dist/contracts/editor.d.ts +19 -9
  45. package/dist/contracts/interaction.d.ts +29 -0
  46. package/dist/contracts/modules.cjs +1 -1
  47. package/dist/contracts/modules.d.ts +29 -16
  48. package/dist/contracts/modules.js +1 -1
  49. package/dist/contracts/types.d.ts +10 -1
  50. package/dist/{custom-node-writes-Cy9imOjA.d.ts → custom-node-writes-cvL5rhcD.d.ts} +2 -2
  51. package/dist/{document-protection-Bp19Ad4I.d.ts → document-protection-BAGVGqaP.d.ts} +1 -1
  52. package/dist/{editor-DYUlyKmb.d.ts → editor-Ci7IZGmG.d.ts} +410 -163
  53. package/dist/editor.cjs +1 -1
  54. package/dist/editor.css +5 -5
  55. package/dist/editor.d.ts +417 -31
  56. package/dist/editor.js +1 -1
  57. package/dist/export.cjs +2 -2
  58. package/dist/export.d.ts +37 -15
  59. package/dist/export.js +2 -2
  60. package/dist/failure-NS2lsya4.d.ts +115 -0
  61. package/dist/{font-resolver-u_nE0PI1.d.ts → font-resolver-BVQB14qT.d.ts} +1 -1
  62. package/dist/{headless-document-view-R9bzzepb.d.ts → headless-document-view-qH331moE.d.ts} +2 -2
  63. package/dist/{image-resources-DfagDguq.d.ts → image-resources-BN-hUgCn.d.ts} +9 -9
  64. package/dist/{index-Docw8Dcb.d.ts → index-Bsg7oIKP.d.ts} +270 -115
  65. package/dist/index.cjs +1 -1
  66. package/dist/index.d.ts +46 -18
  67. package/dist/index.js +1 -1
  68. package/dist/{layout-shaping-DWitwY73.d.ts → layout-shaping-BEyuiQOk.d.ts} +1 -1
  69. package/dist/layout.cjs +1 -1
  70. package/dist/layout.d.ts +177 -249
  71. package/dist/layout.js +1 -1
  72. package/dist/{note-properties-CmfvOJsi.d.ts → note-properties-4Y9o6Gyk.d.ts} +1 -1
  73. package/dist/{omml-equation-CZ6IG2ja.d.ts → omml-equation-CuzBL5DD.d.ts} +1 -1
  74. package/dist/output.cjs +1 -1
  75. package/dist/output.d.ts +18 -7
  76. package/dist/output.js +1 -1
  77. package/dist/{protocol-DniKeDb8.d.ts → protocol-Bqk4Izjc.d.ts} +48 -7
  78. package/dist/review-pane-D9jm8DcY.d.ts +128 -0
  79. package/dist/{review-paragraph-order-Dc8Q6tfM.d.ts → review-paragraph-order-DT-n6ouC.d.ts} +5 -2
  80. package/dist/{revision-projection-DfWxdBqA.d.ts → revision-projection-DZ4kKVev.d.ts} +74 -3
  81. package/dist/{semantic-cell-selection-Dy_BmmpL.d.ts → semantic-cell-selection-D9D1KSXq.d.ts} +8 -6
  82. package/dist/{semantic-interaction-CvFAj0GR.d.ts → semantic-interaction-CIC-PooQ.d.ts} +25 -34
  83. package/dist/{semantic-paint-Bk9wIXdZ.d.ts → semantic-paint-BME37OMv.d.ts} +57 -5
  84. package/dist/semantic-record-queries-CBlZqZNa.d.ts +177 -0
  85. package/dist/{semantic-records-COqi8pjP.d.ts → semantic-records-4B3WwFAi.d.ts} +84 -42
  86. package/dist/store.cjs +1 -1
  87. package/dist/store.d.ts +165 -137
  88. package/dist/store.js +1 -1
  89. package/dist/{tree-package-fragment-YPyYC1aD.d.ts → tree-package-fragment-BeeKxDw8.d.ts} +77 -57
  90. package/dist/{tree-session-contract-AeY2v0x9.d.ts → tree-session-contract-CVbmlMlq.d.ts} +7 -5
  91. package/dist/{types-barrel-BO73JqHG.d.ts → types-barrel-D3xCgQX6.d.ts} +595 -471
  92. package/package.json +3 -3
  93. package/dist/chunk-2BK4G4ZN.js +0 -2
  94. package/dist/chunk-2SJX44PC.cjs +0 -2
  95. package/dist/chunk-5BIASAN3.js +0 -1
  96. package/dist/chunk-6SEIXJTX.js +0 -1
  97. package/dist/chunk-73PG6L2X.js +0 -1
  98. package/dist/chunk-7RJSH72J.cjs +0 -5
  99. package/dist/chunk-AGKIHLWQ.cjs +0 -1
  100. package/dist/chunk-AN6WM4X4.js +0 -2
  101. package/dist/chunk-ANZ44KQT.cjs +0 -12
  102. package/dist/chunk-CYT3OQFZ.cjs +0 -1
  103. package/dist/chunk-DDGGSBAN.js +0 -12
  104. package/dist/chunk-EEAV3WIN.js +0 -3
  105. package/dist/chunk-ELQFXMJ5.cjs +0 -1
  106. package/dist/chunk-EYK4K2J6.js +0 -1
  107. package/dist/chunk-JNTETUNZ.cjs +0 -1
  108. package/dist/chunk-L6V3IJ3S.js +0 -5
  109. package/dist/chunk-LWCI65EL.js +0 -1
  110. package/dist/chunk-LZDI4P6I.cjs +0 -1
  111. package/dist/chunk-NS22DVWT.cjs +0 -2
  112. package/dist/chunk-QIE3YTU4.cjs +0 -2
  113. package/dist/chunk-QVBFPAGO.js +0 -5
  114. package/dist/chunk-RCCOLZEQ.js +0 -2
  115. package/dist/chunk-SUN62YU6.cjs +0 -5
  116. package/dist/chunk-TKQH7BNE.cjs +0 -1
  117. package/dist/chunk-TKR2MXX4.cjs +0 -3
  118. package/dist/chunk-UJL2GDIM.cjs +0 -25
  119. package/dist/chunk-WQTADNHK.cjs +0 -27
  120. package/dist/chunk-XSHXBJ2J.js +0 -25
  121. package/dist/chunk-YXZEBTDF.js +0 -27
  122. package/dist/failure-BIPVQbRm.d.ts +0 -65
@@ -1072,6 +1072,56 @@ interface InsertBuildingBlockOp {
1072
1072
  readonly blocks: readonly OoxmlNode[];
1073
1073
  }
1074
1074
 
1075
+ /**
1076
+ * Why a zip was refused at the trust boundary.
1077
+ *
1078
+ * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
1079
+ * an entry with `..` or a leading `/` is rejected rather than normalized.
1080
+ */
1081
+ type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
1082
+ /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
1083
+ interface ZipLimits {
1084
+ readonly maxEntries: number;
1085
+ /** Max total UNCOMPRESSED bytes across the archive. */
1086
+ readonly maxTotalBytes: number;
1087
+ /**
1088
+ * Max ratio of the archive's total declared uncompressed bytes to the archive's own byte
1089
+ * length (zip-bomb guard). Applies once that total exceeds 8 MiB, so a small archive is
1090
+ * never refused for compressing well.
1091
+ */
1092
+ readonly maxRatio?: number;
1093
+ }
1094
+ /** The archive caps in force when a host configures none. Conservative and finite. */
1095
+ declare const DEFAULT_ZIP_LIMITS: ZipLimits;
1096
+ /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
1097
+ type ZipReadResult = {
1098
+ readonly ok: true;
1099
+ readonly entries: ReadonlyMap<string, Uint8Array>;
1100
+ } | {
1101
+ readonly ok: false;
1102
+ readonly reason: ZipRejection;
1103
+ readonly detail?: string;
1104
+ readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
1105
+ };
1106
+ /**
1107
+ * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count, archive
1108
+ * ratio, and total-uncompressed-size limits are enforced BEFORE each entry is decompressed
1109
+ * (via fflate's pre-inflation filter), so a zip bomb or a traversal name is rejected without
1110
+ * ever being inflated. Keys are canonical part names.
1111
+ *
1112
+ * The budgets count each entry's DECLARED sizes, and the declared size is also a hard cap on
1113
+ * what the entry may produce: fflate inflates into a buffer of exactly `originalSize` bytes
1114
+ * and never grows it, so an entry whose stream holds more than it declares is truncated (or
1115
+ * refused as `inflate-error`), never expanded past its budget. A stored entry is copied at
1116
+ * its compressed size, so the larger of its two declared sizes is what counts.
1117
+ */
1118
+ declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
1119
+ /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
1120
+ * is re-validated through the OPC normalization profile before writing, so a
1121
+ * traversal/encoded/normalized-alias name from an untrusted serialized model can
1122
+ * never be smuggled into a ZIP entry (write-side path-traversal guard). */
1123
+ declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
1124
+
1075
1125
  /**
1076
1126
  * Why a part or relationship name was refused.
1077
1127
  *
@@ -1128,91 +1178,6 @@ declare function resolveInternalTarget(ownerPartName: string, rawTarget: string)
1128
1178
  */
1129
1179
  declare function validateExternalTarget(raw: string): NameResult;
1130
1180
 
1131
- /** One `<Default>`: a file extension mapped to a content type. */
1132
- interface DefaultRecord {
1133
- readonly extension: string;
1134
- readonly contentType: string;
1135
- readonly order: number;
1136
- }
1137
- /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
1138
- interface OverrideRecord {
1139
- readonly partName: string;
1140
- readonly contentType: string;
1141
- readonly order: number;
1142
- }
1143
- /**
1144
- * The authored `[Content_Types].xml` records, in significant order.
1145
- *
1146
- * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
1147
- * part of what a lossless save re-emits.
1148
- */
1149
- interface ContentTypeRecords {
1150
- readonly defaults: readonly DefaultRecord[];
1151
- readonly overrides: readonly OverrideRecord[];
1152
- }
1153
- /**
1154
- * Why content-type records could not be indexed.
1155
- *
1156
- * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
1157
- * invalid MIME syntax are refused rather than resolved by picking one.
1158
- */
1159
- type ContentTypeError = {
1160
- readonly code: 'invalid-mime';
1161
- readonly value: string;
1162
- } | {
1163
- readonly code: 'conflicting-default';
1164
- readonly extension: string;
1165
- } | {
1166
- readonly code: 'duplicate-override';
1167
- readonly partName: string;
1168
- } | {
1169
- readonly code: 'invalid-override-name';
1170
- readonly partName: string;
1171
- } | {
1172
- readonly code: 'too-many-records';
1173
- readonly limit: number;
1174
- };
1175
- /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
1176
- declare function isValidMime(value: string): boolean;
1177
- /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
1178
- declare function extensionKey(extension: string): string;
1179
- /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
1180
- interface ContentTypeIndex {
1181
- /** ext key -> single MIME (identical duplicates collapsed). */
1182
- readonly defaults: ReadonlyMap<string, string>;
1183
- /** case-folded part name -> MIME. */
1184
- readonly overrides: ReadonlyMap<string, string>;
1185
- }
1186
- /** The built index, or the conflict that made it impossible. */
1187
- type IndexResult = {
1188
- readonly ok: true;
1189
- readonly index: ContentTypeIndex;
1190
- } | {
1191
- readonly ok: false;
1192
- readonly error: ContentTypeError;
1193
- };
1194
- /**
1195
- * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
1196
- * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
1197
- */
1198
- declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
1199
- /**
1200
- * A part's content type, or why it has none.
1201
- *
1202
- * An orphan record never determines a part's type — a Default with no matching part is preserved
1203
- * inertly rather than applied.
1204
- */
1205
- type ResolveResult = {
1206
- readonly ok: true;
1207
- readonly contentType: string;
1208
- readonly source: 'override' | 'default';
1209
- } | {
1210
- readonly ok: false;
1211
- readonly reason: 'unknown';
1212
- };
1213
- /** Resolve a part's content type: Override wins over Default; else unknown. */
1214
- declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
1215
-
1216
1181
  /** OOXML image relationship type for embedded or linked media parts. */
1217
1182
  declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
1218
1183
  /**
@@ -1295,165 +1260,90 @@ type ImageRelationshipResolution = {
1295
1260
  */
1296
1261
  declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
1297
1262
 
1263
+ /** One `<Default>`: a file extension mapped to a content type. */
1264
+ interface DefaultRecord {
1265
+ readonly extension: string;
1266
+ readonly contentType: string;
1267
+ readonly order: number;
1268
+ }
1269
+ /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
1270
+ interface OverrideRecord {
1271
+ readonly partName: string;
1272
+ readonly contentType: string;
1273
+ readonly order: number;
1274
+ }
1298
1275
  /**
1299
- * Why a zip was refused at the trust boundary.
1276
+ * The authored `[Content_Types].xml` records, in significant order.
1300
1277
  *
1301
- * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
1302
- * an entry with `..` or a leading `/` is rejected rather than normalized.
1278
+ * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
1279
+ * part of what a lossless save re-emits.
1303
1280
  */
1304
- type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
1305
- /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
1306
- interface ZipLimits {
1307
- readonly maxEntries: number;
1308
- /** Max total UNCOMPRESSED bytes across the archive. */
1309
- readonly maxTotalBytes: number;
1310
- /** Max per-entry uncompressed:compressed ratio (zip-bomb guard). */
1311
- readonly maxRatio?: number;
1281
+ interface ContentTypeRecords {
1282
+ readonly defaults: readonly DefaultRecord[];
1283
+ readonly overrides: readonly OverrideRecord[];
1312
1284
  }
1313
- /** The archive caps in force when a host configures none. Conservative and finite. */
1314
- declare const DEFAULT_ZIP_LIMITS: ZipLimits;
1315
- /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
1316
- type ZipReadResult = {
1285
+ /**
1286
+ * Why content-type records could not be indexed.
1287
+ *
1288
+ * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
1289
+ * invalid MIME syntax are refused rather than resolved by picking one.
1290
+ */
1291
+ type ContentTypeError = {
1292
+ readonly code: 'invalid-mime';
1293
+ readonly value: string;
1294
+ } | {
1295
+ readonly code: 'conflicting-default';
1296
+ readonly extension: string;
1297
+ } | {
1298
+ readonly code: 'duplicate-override';
1299
+ readonly partName: string;
1300
+ } | {
1301
+ readonly code: 'invalid-override-name';
1302
+ readonly partName: string;
1303
+ } | {
1304
+ readonly code: 'too-many-records';
1305
+ readonly limit: number;
1306
+ };
1307
+ /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
1308
+ declare function isValidMime(value: string): boolean;
1309
+ /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
1310
+ declare function extensionKey(extension: string): string;
1311
+ /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
1312
+ interface ContentTypeIndex {
1313
+ /** ext key -> single MIME (identical duplicates collapsed). */
1314
+ readonly defaults: ReadonlyMap<string, string>;
1315
+ /** case-folded part name -> MIME. */
1316
+ readonly overrides: ReadonlyMap<string, string>;
1317
+ }
1318
+ /** The built index, or the conflict that made it impossible. */
1319
+ type IndexResult = {
1317
1320
  readonly ok: true;
1318
- readonly entries: ReadonlyMap<string, Uint8Array>;
1321
+ readonly index: ContentTypeIndex;
1319
1322
  } | {
1320
1323
  readonly ok: false;
1321
- readonly reason: ZipRejection;
1322
- readonly detail?: string;
1323
- readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
1324
+ readonly error: ContentTypeError;
1324
1325
  };
1325
1326
  /**
1326
- * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count,
1327
- * compression-ratio, and total-uncompressed-size limits are enforced BEFORE each
1328
- * entry is decompressed (via fflate's pre-inflation filter), so a zip bomb or a
1329
- * traversal name is rejected without ever being inflated. Keys are canonical part
1330
- * names.
1331
- */
1332
- declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
1333
- /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
1334
- * is re-validated through the OPC normalization profile before writing, so a
1335
- * traversal/encoded/normalized-alias name from an untrusted serialized model can
1336
- * never be smuggled into a ZIP entry (write-side path-traversal guard). */
1337
- declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
1338
-
1339
- /** Only generated, escaped SVG and relationship slots; never authored markup. */
1340
- type LegacyGraphicFragment = string | Readonly<{
1341
- relationshipId: string;
1342
- before: string;
1343
- after: string;
1344
- nativeCrop?: SourceCrop;
1345
- }>;
1346
- interface LegacyGraphicProjection {
1347
- readonly width: number;
1348
- readonly height: number;
1349
- readonly fragments: readonly LegacyGraphicFragment[];
1350
- }
1351
-
1352
- /** Picture color adjustments shared by projection, layout, and paint.
1353
- * @public
1354
- */
1355
- interface DrawingImageEffects {
1356
- /** Fixed alpha multiplier for raster painting; omitted means opaque. */
1357
- readonly opacity?: number;
1358
- readonly grayscale: boolean;
1359
- readonly brightness: number;
1360
- readonly contrast: number;
1361
- readonly bilevel?: number;
1362
- }
1363
-
1364
- /** The relationship namespace `r:id` lives in. */
1365
- declare const OFFICE_RELATIONSHIP_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
1366
- /** The `Type` a hyperlink relationship declares. */
1367
- declare const HYPERLINK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
1368
- /**
1369
- * What a part's relationships answer for one `r:id`: the authored target and whether the
1370
- * package declared it external. `null` for an id the part does not declare — a DANGLING
1371
- * relationship, which is a real thing in real documents.
1372
- */
1373
- type RelationshipTargetResolver = (relationshipId: string) => {
1374
- readonly target: string;
1375
- readonly external: boolean;
1376
- /**
1377
- * The PACKAGE's own verdict on this target (`validateExternalTarget`): whether it is an
1378
- * absolute URI with a safe scheme.
1379
- *
1380
- * Carried separately because `sanitizeHref` cannot answer it. That function is a SCHEME
1381
- * allowlist and deliberately admits relative URLs — the right rule for a value the host
1382
- * authored, and the wrong one for a value a `.docx` did. A file-supplied
1383
- * `Target="/admin/delete-account"` has no scheme to refuse, so it would pass the
1384
- * allowlist and resolve against the EMBEDDING APPLICATION'S origin: a link reading
1385
- * "Company policy" that issues an authenticated same-origin request to whatever host
1386
- * app the editor is mounted in. Absent, a target is treated as unverified.
1387
- */
1388
- readonly sinkSafe?: boolean;
1389
- } | null;
1390
- /**
1391
- * What a hyperlink points at, which decides what activating it may do.
1392
- *
1393
- * The security-relevant split: an `external` link goes through `sanitizeHref` and opens only on
1394
- * explicit user action, while an anchor merely scrolls and never navigates.
1395
- */
1396
- type HyperlinkKind =
1397
- /** `r:id` → a relationship with `TargetMode="External"`. Opens somewhere else. */
1398
- 'external'
1399
- /** `w:anchor` → a bookmark in this document. Scrolls, never navigates. */
1400
- | 'internal'
1401
- /**
1402
- * `r:id` naming a relationship the part does not declare, or one that is not external.
1403
- *
1404
- * The link keeps its runs — the text is never lost twice — but there is nothing to
1405
- * activate, so it paints inert exactly like a refused scheme.
1327
+ * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
1328
+ * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
1406
1329
  */
1407
- | 'unresolved';
1408
- /** A resolved hyperlink: its kind, its target, and the tooltip Word shows on hover. */
1409
- interface HyperlinkTarget {
1410
- readonly kind: HyperlinkKind;
1411
- /**
1412
- * The authored target, verbatim: the relationship's `Target` for an `r:id` link, the
1413
- * anchor name for an internal one. Save re-emits from the tree, never from this — it is
1414
- * here so a UI can show what the document actually says.
1415
- */
1416
- readonly authored: string;
1417
- /**
1418
- * The sanitized runtime projection, or `null` when there is nothing safe to navigate to.
1419
- * The ONLY value permitted in a DOM `href`, `window.open`, or a copied link.
1420
- */
1421
- readonly href: string | null;
1422
- /** `w:anchor`, for an internal link. */
1423
- readonly anchor?: string;
1424
- /** `w:tooltip` — Word's hover text; paint puts it on the anchor's `title`. */
1425
- readonly tooltip?: string;
1426
- /** The authored `r:id`, so an edit can rewrite the relationship it names. */
1427
- readonly relationshipId?: string;
1428
- }
1429
- /** Whether a node is a typed `w:hyperlink`. */
1430
- declare function isHyperlinkNode(node: OoxmlNode): boolean;
1431
- /** A typed hyperlink's `w:anchor`, or undefined. */
1432
- declare function hyperlinkAnchorOf(link: OoxmlNode): string | undefined;
1433
- /** A typed hyperlink's `r:id`, or undefined. */
1434
- declare function hyperlinkRelationshipIdOf(link: OoxmlNode): string | undefined;
1330
+ declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
1435
1331
  /**
1436
- * Read a typed `w:hyperlink` into its target record.
1437
- *
1438
- * `r:id` wins over `w:anchor` when a link carries both, matching Word: the relationship
1439
- * names the document and the anchor names a place inside it, so the pair is a link to a
1440
- * bookmark in ANOTHER file — which this engine will not follow, but whose external half is
1441
- * the part that decides where it points.
1332
+ * A part's content type, or why it has none.
1442
1333
  *
1443
- * A link with neither is `unresolved`: it paints its runs and does nothing.
1334
+ * An orphan record never determines a part's type — a Default with no matching part is preserved
1335
+ * inertly rather than applied.
1444
1336
  */
1445
- declare function hyperlinkTargetOf(link: OoxmlNode, resolve: RelationshipTargetResolver): HyperlinkTarget;
1446
-
1447
- interface DrawingProjectionLimits {
1448
- readonly maxCompatibilityBranches: number;
1449
- readonly maxVisitedElements: number;
1450
- readonly maxDrawingDepth: number;
1451
- }
1452
- interface DrawingDiagnostic {
1453
- readonly code: 'malformed-drawing' | 'unsupported-graphic' | 'unresolvable-frame' | 'invalid-geometry' | 'resource-refused' | 'wrap-polygon-over-limit' | 'wrap-polygon-malformed';
1454
- readonly nodeId: string;
1455
- readonly detail: string | null;
1456
- }
1337
+ type ResolveResult = {
1338
+ readonly ok: true;
1339
+ readonly contentType: string;
1340
+ readonly source: 'override' | 'default';
1341
+ } | {
1342
+ readonly ok: false;
1343
+ readonly reason: 'unknown';
1344
+ };
1345
+ /** Resolve a part's content type: Override wins over Default; else unknown. */
1346
+ declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
1457
1347
 
1458
1348
  type ShapeSchemeColorResolver = (scheme: string) => string | null;
1459
1349
  type ShapeStyleMatrixResolver = (kind: 'fill' | 'line', index: number) => OoxmlElement | null;
@@ -1542,6 +1432,11 @@ interface TextboxStoryProjection {
1542
1432
  readonly verticalAnchor: 'top' | 'center' | 'bottom';
1543
1433
  /** Autofit child of `wps:bodyPr`; extent stays authoritative either way (diagnostic only). */
1544
1434
  readonly autofit: 'none' | 'shape' | 'normal';
1435
+ /**
1436
+ * `wps:bodyPr/@wrap="none"` (VML `mso-wrap-style:none`): lines never wrap at the box edge,
1437
+ * and the box takes the width of its widest line plus the insets. Absent for wrapped text.
1438
+ */
1439
+ readonly noWrap?: true;
1545
1440
  /** Solid fill of the hosting shape, painted behind the story; null for no fill. */
1546
1441
  readonly fillHex: string | null;
1547
1442
  /** Solid outline of the hosting shape; null for no outline. */
@@ -1550,6 +1445,145 @@ interface TextboxStoryProjection {
1550
1445
  readonly strokeWidthEmu: number;
1551
1446
  }
1552
1447
 
1448
+ /** Only generated, escaped SVG and relationship slots; never authored markup. */
1449
+ type LegacyGraphicFragment = string | Readonly<{
1450
+ relationshipId: string;
1451
+ before: string;
1452
+ after: string;
1453
+ nativeCrop?: SourceCrop;
1454
+ }>;
1455
+ interface LegacyGraphicProjection {
1456
+ readonly width: number;
1457
+ readonly height: number;
1458
+ readonly fragments: readonly LegacyGraphicFragment[];
1459
+ }
1460
+
1461
+ /** Picture color adjustments shared by projection, layout, and paint.
1462
+ * @public
1463
+ */
1464
+ interface DrawingImageEffects {
1465
+ /** Fixed alpha multiplier for raster painting; omitted means opaque. */
1466
+ readonly opacity?: number;
1467
+ readonly grayscale: boolean;
1468
+ readonly brightness: number;
1469
+ readonly contrast: number;
1470
+ readonly bilevel?: number;
1471
+ }
1472
+
1473
+ /** One text box member of a drawing group. */
1474
+ interface GroupTextboxProjection {
1475
+ /** Canonical node id of the member `wps:wsp`; namespaces the story's line ids. */
1476
+ readonly memberNodeId: string;
1477
+ /** The member box in the group's extent space, in EMU (origin at the extent's top-left). */
1478
+ readonly frameEmu: Readonly<{
1479
+ x: number;
1480
+ y: number;
1481
+ cx: number;
1482
+ cy: number;
1483
+ }>;
1484
+ /** The member's story, projected at the scaled member size. */
1485
+ readonly story: TextboxStoryProjection;
1486
+ /**
1487
+ * Clockwise turn of the member's text about the member box center, in degrees [0, 360):
1488
+ * the member's `rot`, plus 180 for `flipV`. `flipH` never mirrors the text.
1489
+ */
1490
+ readonly rotationDegrees: number;
1491
+ }
1492
+
1493
+ /** The relationship namespace `r:id` lives in. */
1494
+ declare const OFFICE_RELATIONSHIP_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
1495
+ /** The `Type` a hyperlink relationship declares. */
1496
+ declare const HYPERLINK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
1497
+ /**
1498
+ * What a part's relationships answer for one `r:id`: the authored target and whether the
1499
+ * package declared it external. `null` for an id the part does not declare — a DANGLING
1500
+ * relationship, which is a real thing in real documents.
1501
+ */
1502
+ type RelationshipTargetResolver = (relationshipId: string) => {
1503
+ readonly target: string;
1504
+ readonly external: boolean;
1505
+ /**
1506
+ * The PACKAGE's own verdict on this target (`validateExternalTarget`): whether it is an
1507
+ * absolute URI with a safe scheme.
1508
+ *
1509
+ * Carried separately because `sanitizeHref` cannot answer it. That function is a SCHEME
1510
+ * allowlist and deliberately admits relative URLs — the right rule for a value the host
1511
+ * authored, and the wrong one for a value a `.docx` did. A file-supplied
1512
+ * `Target="/admin/delete-account"` has no scheme to refuse, so it would pass the
1513
+ * allowlist and resolve against the EMBEDDING APPLICATION'S origin: a link reading
1514
+ * "Company policy" that issues an authenticated same-origin request to whatever host
1515
+ * app the editor is mounted in. Absent, a target is treated as unverified.
1516
+ */
1517
+ readonly sinkSafe?: boolean;
1518
+ } | null;
1519
+ /**
1520
+ * What a hyperlink points at, which decides what activating it may do.
1521
+ *
1522
+ * The security-relevant split: an `external` link goes through `sanitizeHref` and opens only on
1523
+ * explicit user action, while an anchor merely scrolls and never navigates.
1524
+ */
1525
+ type HyperlinkKind =
1526
+ /** `r:id` → a relationship with `TargetMode="External"`. Opens somewhere else. */
1527
+ 'external'
1528
+ /** `w:anchor` → a bookmark in this document. Scrolls, never navigates. */
1529
+ | 'internal'
1530
+ /**
1531
+ * `r:id` naming a relationship the part does not declare, or one that is not external.
1532
+ *
1533
+ * The link keeps its runs — the text is never lost twice — but there is nothing to
1534
+ * activate, so it paints inert exactly like a refused scheme.
1535
+ */
1536
+ | 'unresolved';
1537
+ /** A resolved hyperlink: its kind, its target, and the tooltip Word shows on hover. */
1538
+ interface HyperlinkTarget {
1539
+ readonly kind: HyperlinkKind;
1540
+ /**
1541
+ * The authored target, verbatim: the relationship's `Target` for an `r:id` link, the
1542
+ * anchor name for an internal one. Save re-emits from the tree, never from this — it is
1543
+ * here so a UI can show what the document actually says.
1544
+ */
1545
+ readonly authored: string;
1546
+ /**
1547
+ * The sanitized runtime projection, or `null` when there is nothing safe to navigate to.
1548
+ * The ONLY value permitted in a DOM `href`, `window.open`, or a copied link.
1549
+ */
1550
+ readonly href: string | null;
1551
+ /** `w:anchor`, for an internal link. */
1552
+ readonly anchor?: string;
1553
+ /** `w:tooltip` — Word's hover text; paint puts it on the anchor's `title`. */
1554
+ readonly tooltip?: string;
1555
+ /** The authored `r:id`, so an edit can rewrite the relationship it names. */
1556
+ readonly relationshipId?: string;
1557
+ }
1558
+ /** Whether a node is a typed `w:hyperlink`. */
1559
+ declare function isHyperlinkNode(node: OoxmlNode): boolean;
1560
+ /** A typed hyperlink's `w:anchor`, or undefined. */
1561
+ declare function hyperlinkAnchorOf(link: OoxmlNode): string | undefined;
1562
+ /** A typed hyperlink's `r:id`, or undefined. */
1563
+ declare function hyperlinkRelationshipIdOf(link: OoxmlNode): string | undefined;
1564
+ /**
1565
+ * Read a typed `w:hyperlink` into its target record.
1566
+ *
1567
+ * `r:id` wins over `w:anchor` when a link carries both, matching Word: the relationship
1568
+ * names the document and the anchor names a place inside it, so the pair is a link to a
1569
+ * bookmark in ANOTHER file — which this engine will not follow, but whose external half is
1570
+ * the part that decides where it points.
1571
+ *
1572
+ * A link with neither is `unresolved`: it paints its runs and does nothing.
1573
+ */
1574
+ declare function hyperlinkTargetOf(link: OoxmlNode, resolve: RelationshipTargetResolver): HyperlinkTarget;
1575
+
1576
+ interface DrawingProjectionLimits {
1577
+ readonly maxCompatibilityBranches: number;
1578
+ readonly maxVisitedElements: number;
1579
+ readonly maxDrawingDepth: number;
1580
+ }
1581
+ interface DrawingDiagnostic {
1582
+ readonly code: 'malformed-drawing' | 'unsupported-graphic' | 'unresolvable-frame' | 'invalid-geometry' | 'resource-refused' | 'wrap-polygon-over-limit' | 'wrap-polygon-malformed';
1583
+ readonly nodeId: string;
1584
+ readonly detail: string | null;
1585
+ }
1586
+
1553
1587
  /** One picture painted as a member of a drawing group. */
1554
1588
  interface GroupPictureProjection {
1555
1589
  readonly embeddedRelationshipId: string | null;
@@ -1690,6 +1724,8 @@ interface DrawingProjection {
1690
1724
  /** The picture member of a `wpg:wgp` group; `picture` stays null for a group. */
1691
1725
  readonly groupPicture: GroupPictureProjection | null;
1692
1726
  readonly textboxStory: TextboxStoryProjection | null;
1727
+ /** Text box members of a `wpg:wgp` group, laid out read-only; absent when none has text. */
1728
+ readonly groupTextboxes?: readonly GroupTextboxProjection[];
1693
1729
  /** Read-only preview of the supported native VML subset; the canonical XML is untouched. */
1694
1730
  readonly legacyGraphic?: LegacyGraphicProjection;
1695
1731
  readonly locks: DrawingLocks;
@@ -1816,6 +1852,20 @@ type OoxmlPackageResult = {
1816
1852
  readonly detail?: string;
1817
1853
  readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
1818
1854
  };
1855
+ /**
1856
+ * Load DOCX bytes into canonical typed/generic OOXML trees, bounded at every step.
1857
+ *
1858
+ * THE trust boundary for a document. Composes the hardened primitives — zip limits and OPC name
1859
+ * normalization, content-type indexing, relationship validation, entity-free XML — into one
1860
+ * loader, and returns a typed rejection rather than throwing from inside a decoder.
1861
+ *
1862
+ * Fails closed on every limit, malformed name, unresolvable internal target, duplicate
1863
+ * relationship id, and XML rejection. An external relationship never causes a failure and
1864
+ * never causes a fetch: it is recorded with its sink-safety verdict for a later, explicitly
1865
+ * user-gated lane. A content-type record with an invalid MIME type is treated as absent,
1866
+ * unless it decides the type of the main document part, a relationships part, or a
1867
+ * non-payload part that the package root or the main document relates to.
1868
+ */
1819
1869
  declare function readOoxmlPackage(bytes: Uint8Array, limits?: OoxmlPackageLimits): OoxmlPackageResult;
1820
1870
  /**
1821
1871
  * Serialize a canonical package back to DOCX bytes.
@@ -1909,234 +1959,10 @@ declare function threadStateOfPart(part: OoxmlPart): Map<string, CommentThreadSt
1909
1959
  /**
1910
1960
  * Whether the package holds any `w:comment` record — the cheap gate before a reap.
1911
1961
  *
1912
- * Overflow cannot prove the package is comment-free, so it returns true and the reap still
1913
- * runs rather than skipping cleanup.
1914
- */
1915
- declare function hasAnyComment(pkg: OoxmlPackage): boolean;
1916
-
1917
- /** How deep controls may nest before a walk stops descending. Shared by every lane. */
1918
- declare const MAX_CONTENT_CONTROL_NESTING = 32;
1919
- /** Cap on controls one walk reports, so a hostile file cannot make a read unbounded. */
1920
- declare const MAX_CONTENT_CONTROLS_PER_PART = 10000;
1921
- /** `CT_SdtPr/w:id` is `ST_DecimalNumber`; Word treats it as a signed 32-bit integer. */
1922
- declare const CONTENT_CONTROL_ID_MAX = 2147483647;
1923
- /** `ST_Lock` (§17.5.2.24). An absent `w:lock` is `unlocked`. */
1924
- /**
1925
- * `w:lock` — what a control refuses.
1926
- *
1927
- * `sdtLocked` protects the wrapper, `contentLocked` the text inside it, and `sdtContentLocked`
1928
- * both. A control inside a locked one is locked in effect regardless of its own value.
1929
- */
1930
- type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
1931
- /**
1932
- * What kind of control this is.
1933
- *
1934
- * `checkbox` is the Microsoft `w14:checkbox` extension rather than an ECMA-376 type
1935
- * element, and the two are not mutually exclusive with "declares no type": four controls
1936
- * in the comprehensive fixture declare the extension and no `w:`-prefixed type, so a scan
1937
- * that read only the ECMA-376 choice reported them untyped. `untyped` means the control
1938
- * declares neither — a rich-text container, which is what Word treats it as.
1939
- */
1940
- /** Which kind of control a `w:sdt` is, and therefore what a written value must look like. */
1941
- type ContentControlKind = 'richText' | 'plainText' | 'checkbox' | 'dropDownList' | 'comboBox' | 'date' | 'picture' | 'docPartObj' | 'docPartList' | 'group' | 'citation' | 'bibliography' | 'equation' | 'untyped';
1942
- /** One declared option of a dropdown or combo box: its display text and its stored value. */
1943
- interface ContentControlListItem {
1944
- readonly displayText: string;
1945
- readonly value: string;
1946
- }
1947
- /** A date picker's authored format and locale, for rendering and for parsing what it stores. */
1948
- interface ContentControlDateFormat {
1949
- readonly fullDate?: string;
1950
- readonly dateFormat?: string;
1951
- readonly lid?: string;
1952
- readonly storeMappedDataAs?: string;
1953
- readonly calendar?: string;
1954
- }
1955
- /** One of a checkbox's two glyphs: the font and code point it is drawn with. */
1956
- interface ContentControlCheckboxState {
1957
- /** The `w14:val` hex code point of the glyph, exactly as the control declares it. */
1958
- readonly value: string;
1959
- readonly font?: string;
1960
- }
1961
- /**
1962
- * A checkbox's state and the two glyphs it chooses between.
1963
- *
1964
- * Both glyphs matter on a write: setting the value has to update `w14:checked` AND the run's
1965
- * character, or the document's glyph and its recorded state disagree.
1966
- */
1967
- interface ContentControlCheckbox {
1968
- readonly checked: boolean;
1969
- readonly checkedState?: ContentControlCheckboxState;
1970
- readonly uncheckedState?: ContentControlCheckboxState;
1971
- }
1972
- /** `CT_DataBinding` — preserved metadata. Never resolved, never fetched. */
1973
- /** `w:dataBinding` — the custom-XML part and XPath a control's value is bound to. */
1974
- interface ContentControlDataBinding {
1975
- readonly xpath?: string;
1976
- readonly storeItemID?: string;
1977
- readonly prefixMappings?: string;
1978
- }
1979
- /**
1980
- * A control's whole `w:sdtPr`, projected into one typed shape.
1981
- *
1982
- * What every other lane reads instead of walking `localName` strings — which also means a Word
1983
- * re-save that demotes the properties node to generic does not break the projection.
1984
- */
1985
- interface ContentControlProperties {
1986
- readonly type: ContentControlKind;
1987
- readonly alias?: string;
1988
- readonly tag?: string;
1989
- /** `@w:val` of `w:id` when the file declares a parseable one. Never fabricated. */
1990
- readonly id?: number;
1991
- readonly lock: ContentControlLock;
1992
- /** The glossary entry named by `w:placeholder/w:docPart`. Preserved, never loaded. */
1993
- readonly placeholderDocPart?: string;
1994
- readonly temporary: boolean;
1995
- readonly showingPlaceholder: boolean;
1996
- readonly dataBinding?: ContentControlDataBinding;
1997
- readonly label?: string;
1998
- readonly tabIndex?: number;
1999
- /** Items a dropdown or combo box offers. Empty for every other type. */
2000
- readonly listItems: readonly ContentControlListItem[];
2001
- readonly lastValue?: string;
2002
- readonly date?: ContentControlDateFormat;
2003
- readonly multiLine?: boolean;
2004
- readonly checkbox?: ContentControlCheckbox;
2005
- }
2006
- /** Whether a node is a `w:sdt` wrapper. */
2007
- declare function isContentControlNode(node: OoxmlNode): node is OoxmlContentControlNode;
2008
- /** Whether a node is a `w:sdtContent` — the container holding a control's actual content. */
2009
- declare function isContentControlContentNode(node: OoxmlNode): node is OoxmlContentControlContentNode;
2010
- /**
2011
- * A `w:sdt` wrapper, TYPED or DEMOTED.
2012
- *
2013
- * Flattening predates typing and must not stop at a control the reader refused to type: a
2014
- * demoted wrapper still renders its content in place in Word, so a walk that only saw the
2015
- * typed kind would drop every paragraph inside a malformed control out of the story.
2016
- */
2017
- declare function isContentControlWrapper(node: OoxmlNode): boolean;
2018
- /**
2019
- * The children of a wrapper's `w:sdtContent`, typed or demoted, in order.
2020
- *
2021
- * The one place that knows a control's content is reached through an intermediate element,
2022
- * so the four flattening walks (story blocks, layout, header/footer references, list
2023
- * resolution) ask the same question rather than each re-deriving it.
2024
- */
2025
- declare function contentControlContentChildren(wrapper: OoxmlNode): readonly OoxmlNode[];
2026
- /**
2027
- * A container's children with every content-control wrapper flattened away, bounded in depth.
2028
- *
2029
- * ONE unwrap rule, for the places where a control sits between a container and the children that
2030
- * container is defined in terms of. `CT_SdtRow` puts it between `w:tbl` and `w:tr`, `CT_SdtCell`
2031
- * between `w:tr` and `w:tc`, and a walk that filtered on the child's kind dropped the row or cell
2032
- * entirely: not measured, not painted, not addressable. Flattening at the point of the filter
2033
- * means a controlled row is the same row to the grid pass, the pagination pass and the story walk.
2034
- *
2035
- * Returns the SAME array identity when there is nothing to unwrap, so the tables that carry no
2036
- * controls — nearly all of them — allocate nothing and the incremental layout cache still sees
2037
- * its own inputs.
2038
- */
2039
- declare function flattenContentControls(children: readonly OoxmlNode[], maxDepth?: number): readonly OoxmlNode[];
2040
- /** A control's `w:sdtPr`, or null. Matches structurally, so a Word-demoted node still resolves. */
2041
- declare function contentControlPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlPropertiesNode | undefined;
2042
- /** A control's `w:sdtEndPr` — the run properties applied to its closing marker. */
2043
- declare function contentControlEndPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlEndPropertiesNode | undefined;
2044
- /** A control's `w:sdtContent`, or null when the wrapper has none. */
2045
- declare function contentControlContentNodeOf(control: OoxmlNode): OoxmlContentControlContentNode | undefined;
2046
- /** A signed 32-bit `ST_DecimalNumber`, or undefined when the file wrote something else. */
2047
- declare function parseContentControlId(raw: string | undefined): number | undefined;
2048
- /**
2049
- * Read a control's properties.
2050
- *
2051
- * Total: a control with no `w:sdtPr` at all answers the same shape with the defaults an
2052
- * absent property means, so no caller has to branch on the container's existence.
2053
- */
2054
- declare function contentControlPropertiesOf(control: OoxmlNode): ContentControlProperties;
2055
- /** Where a control sits, read off what its content holds. */
2056
- type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell' | 'empty';
2057
- /**
2058
- * How deeply a control is nested inside other controls.
2059
- *
2060
- * Bounded by {@link MAX_CONTENT_CONTROL_NESTING}: nesting depth comes from a file and is a
2061
- * recursion bound.
2062
- */
2063
- declare function contentControlLevelOf(control: OoxmlNode): ContentControlLevel;
2064
- /** One control, plus how deeply it is nested and the controls that enclose it. */
2065
- interface ContentControlEntry {
2066
- readonly node: OoxmlContentControlNode;
2067
- /** 0 for a top-level control; the nesting depth otherwise. */
2068
- readonly depth: number;
2069
- /** Enclosing controls, outermost first. Empty at depth 0. */
2070
- readonly ancestors: readonly OoxmlContentControlNode[];
2071
- }
2072
- /**
2073
- * Every control under a node, in document order, bounded in depth and in count.
2074
- *
2075
- * ONE walk, shared. The nesting bound is the same one layout flattens with, so a control
2076
- * a lane can address is a control every lane can address — and a file that nests past it
2077
- * keeps its content in the tree (the serializer never stops) while no walk recurses
2078
- * further.
2079
- */
2080
- declare function contentControlsIn(root: OoxmlNode, options?: {
2081
- readonly maxDepth?: number;
2082
- readonly limit?: number;
2083
- }): readonly ContentControlEntry[];
2084
- /** Find one control by canonical node id, with the same bounded walk. */
2085
- declare function findContentControl(root: OoxmlNode, nodeId: string): ContentControlEntry | null;
2086
- /**
2087
- * The plain text a control's content holds, in reading order.
2088
- *
2089
- * `w:delText` is excluded: struck text is not the control's value, and a dropdown whose
2090
- * old item is still present as a tracked deletion would otherwise report both.
2091
- */
2092
- declare function contentControlTextOf(control: OoxmlNode): string;
2093
- /**
2094
- * Resolve the lock a position inherits from the controls enclosing it.
2095
- *
2096
- * CONSERVATIVE, because a template that says a field cannot be edited and sits inside a
2097
- * section that says it cannot be removed means both. Each half of `ST_Lock` is taken
2098
- * independently and the strongest wins, so an unlocked control inside a `contentLocked`
2099
- * one is still content-locked — a nested control cannot grant a permission its parent
2100
- * withheld, which is the only reading under which a lock is a lock.
2101
- */
2102
- declare function resolveContentControlLock(chain: readonly ContentControlLock[]): ContentControlLock;
2103
- /** Whether a resolved lock forbids editing the content it covers. */
2104
- declare function lockForbidsEdit(lock: ContentControlLock): boolean;
2105
- /** Whether a resolved lock forbids removing the control itself. */
2106
- declare function lockForbidsRemoval(lock: ContentControlLock): boolean;
2107
- /**
2108
- * `CT_SdtPr`'s declared child order (§17.5.2.38), followed by the type choice.
2109
- *
2110
- * Serialization re-emits children in tree order, so the ONLY way a write keeps the
2111
- * sequence valid is to place the child it authors at its schema position — which is what
2112
- * {@link orderedContentControlProperties} does.
2113
- */
2114
- declare const CONTENT_CONTROL_PROPERTY_ORDER: readonly string[];
2115
- /**
2116
- * Rebuild a `w:sdtPr`'s children in schema order.
2117
- *
2118
- * Modelled children sort to their declared position and the type element follows them,
2119
- * as the sequence requires. Everything else — a `w15:repeatingSection`, a vendor
2120
- * extension, the `w14:checkbox` that is not part of the ECMA-376 choice — keeps the order
2121
- * it was authored in and follows the modelled block, so a write that touches one property
2122
- * neither drops nor reorders anything it does not name.
2123
- */
2124
- declare function orderedContentControlProperties(children: readonly OoxmlNode[]): readonly OoxmlNode[];
2125
- /**
2126
- * The next `w:id` to write.
2127
- *
2128
- * Solo: one past the document's own maximum. Never a clock, a timestamp, a random source
2129
- * or a hash: those collide with ids already in the file and produce values Word rejects.
2130
- * Null when the document already reaches the signed 32-bit bound, so the caller refuses
2131
- * rather than wrapping into a negative id. Hostile or out-of-range existing values are
2132
- * ignored for seeding rather than counted past.
2133
- *
2134
- * When a collaboration actor is bound (explicit argument or the open store transaction),
2135
- * the next id is the next unused value in that actor's stripe. Two peers inserting a
2136
- * generic content control — including a custom node authored as `w:sdt` — from the same
2137
- * snapshot then cannot share a `w:id`.
1962
+ * Overflow cannot prove the package is comment-free, so it returns true and the reap still
1963
+ * runs rather than skipping cleanup.
2138
1964
  */
2139
- declare function allocateContentControlId(root: OoxmlNode, actorId?: string): number | null;
1965
+ declare function hasAnyComment(pkg: OoxmlPackage): boolean;
2140
1966
 
2141
1967
  /** A position in the model offset space of one story. */
2142
1968
  interface ReviewPosition {
@@ -2160,11 +1986,8 @@ interface ReviewRange {
2160
1986
  */
2161
1987
  type ReviewRevisionKind = 'insert' | 'delete'
2162
1988
  /**
2163
- * A deletion and an insertion that are one edit: text typed over a selection.
2164
- *
2165
- * Word shows these as a single `Replaced "x" with "y"` card, and resolving one half
2166
- * without the other is never what the reviewer meant — accepting the deletion alone
2167
- * leaves the replacement text unproposed, rejecting it alone leaves both.
1989
+ * A combined deletion and insertion decision. The built-in reader lists them separately,
1990
+ * unless a review query asks to pair replacements or a custom review provider combines them.
2168
1991
  */
2169
1992
  | 'replace' | 'moveFrom' | 'moveTo'
2170
1993
  /** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
@@ -2181,14 +2004,14 @@ type ReviewRevisionKind = 'insert' | 'delete'
2181
2004
  */
2182
2005
  interface ReviewRevisionItem {
2183
2006
  readonly kind: 'revision';
2184
- /** Stable across renders and unique per DECISION, not per site. */
2007
+ /** Stable across renders and unique per decision within this editor instance. */
2185
2008
  readonly id: string;
2186
2009
  /** The payload `acceptRevision` / `rejectRevision` take. */
2187
2010
  readonly address: RevisionAddress;
2188
2011
  /**
2189
2012
  * EVERY address this decision covers, `address` first.
2190
2013
  *
2191
- * Replacements, table fragments, and adjacent formatting changes can combine multiple
2014
+ * Adjacent text fragments, table fragments, and formatting changes can combine multiple
2192
2015
  * original revisions into one decision. Review commands resolve the complete decision
2193
2016
  * in one transaction while preserving independent changes outside the group.
2194
2017
  */
@@ -2202,8 +2025,11 @@ interface ReviewRevisionItem {
2202
2025
  readonly structuralChanges?: readonly ('rowInsert' | 'rowDelete' | 'cellInsert' | 'cellDelete' | 'cellMerge' | 'numberingInsert')[];
2203
2026
  /** Changed direct formatting values, ready for localized review summaries. */
2204
2027
  readonly formattingChanges?: readonly {
2205
- readonly property: 'bold' | 'italic' | 'underline' | 'strike' | 'fontFamily' | 'fontSize' | 'color' | 'alignment' | 'leftIndent' | 'rightIndent' | 'firstLineIndent' | 'hangingIndent' | 'spaceBefore' | 'spaceAfter';
2206
- /** New direct value; null means inherit. Sizes and distances are in points. */
2028
+ readonly property: 'bold' | 'italic' | 'underline' | 'strike' | 'fontFamily' | 'fontSize' | 'color' | 'alignment' | 'leftIndent' | 'rightIndent' | 'firstLineIndent' | 'hangingIndent' | 'spaceBefore' | 'spaceAfter' | 'direction';
2029
+ /**
2030
+ * New direct value; null means inherit. Sizes and distances are in points. A direction is
2031
+ * `rtl` or `ltr`.
2032
+ */
2207
2033
  readonly value: string | null;
2208
2034
  }[];
2209
2035
  /** Newly applied proofing language codes in a tracked formatting change. */
@@ -2310,7 +2136,8 @@ interface ReviewCustomItem {
2310
2136
  *
2311
2137
  * False for a definition with no `reviewCard`: the item exists so the chip's own surfaces can
2312
2138
  * read `attrs`, `text` and `data` off it, and the rail leaves it out. A surface listing cards
2313
- * filters on this rather than on an empty `title`.
2139
+ * filters on this rather than on an empty `title`. An uncarded node never becomes the active
2140
+ * review item, so it never shows the active highlight.
2314
2141
  */
2315
2142
  readonly carded: boolean;
2316
2143
  /** Card title, from the definition's `reviewCard` hook. Empty when `carded` is false. */
@@ -2432,6 +2259,233 @@ declare function activeReviewItem(items: readonly ReviewItem[], position: Review
2432
2259
  */
2433
2260
  declare function reviewThreadRootOf(items: readonly ReviewItem[], comment: ReviewCommentItem): ReviewItem;
2434
2261
 
2262
+ /** How deep controls may nest before a walk stops descending. Shared by every lane. */
2263
+ declare const MAX_CONTENT_CONTROL_NESTING = 32;
2264
+ /** Cap on controls one walk reports, so a hostile file cannot make a read unbounded. */
2265
+ declare const MAX_CONTENT_CONTROLS_PER_PART = 10000;
2266
+ /** `CT_SdtPr/w:id` is `ST_DecimalNumber`; Word treats it as a signed 32-bit integer. */
2267
+ declare const CONTENT_CONTROL_ID_MAX = 2147483647;
2268
+ /** `ST_Lock` (§17.5.2.24). An absent `w:lock` is `unlocked`. */
2269
+ /**
2270
+ * `w:lock` — what a control refuses.
2271
+ *
2272
+ * `sdtLocked` protects the wrapper, `contentLocked` the text inside it, and `sdtContentLocked`
2273
+ * both. A control inside a locked one is locked in effect regardless of its own value.
2274
+ */
2275
+ type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
2276
+ /**
2277
+ * What kind of control this is.
2278
+ *
2279
+ * `checkbox` is the Microsoft `w14:checkbox` extension rather than an ECMA-376 type
2280
+ * element, and the two are not mutually exclusive with "declares no type": four controls
2281
+ * in the comprehensive fixture declare the extension and no `w:`-prefixed type, so a scan
2282
+ * that read only the ECMA-376 choice reported them untyped. `untyped` means the control
2283
+ * declares neither — a rich-text container, which is what Word treats it as.
2284
+ */
2285
+ /** Which kind of control a `w:sdt` is, and therefore what a written value must look like. */
2286
+ type ContentControlKind = 'richText' | 'plainText' | 'checkbox' | 'dropDownList' | 'comboBox' | 'date' | 'picture' | 'docPartObj' | 'docPartList' | 'group' | 'citation' | 'bibliography' | 'equation' | 'untyped';
2287
+ /** One declared option of a dropdown or combo box: its display text and its stored value. */
2288
+ interface ContentControlListItem {
2289
+ readonly displayText: string;
2290
+ readonly value: string;
2291
+ }
2292
+ /** A date picker's authored format and locale, for rendering and for parsing what it stores. */
2293
+ interface ContentControlDateFormat {
2294
+ readonly fullDate?: string;
2295
+ readonly dateFormat?: string;
2296
+ readonly lid?: string;
2297
+ readonly storeMappedDataAs?: string;
2298
+ readonly calendar?: string;
2299
+ }
2300
+ /** One of a checkbox's two glyphs: the font and code point it is drawn with. */
2301
+ interface ContentControlCheckboxState {
2302
+ /** The `w14:val` hex code point of the glyph, exactly as the control declares it. */
2303
+ readonly value: string;
2304
+ readonly font?: string;
2305
+ }
2306
+ /**
2307
+ * A checkbox's state and the two glyphs it chooses between.
2308
+ *
2309
+ * Both glyphs matter on a write: setting the value has to update `w14:checked` AND the run's
2310
+ * character, or the document's glyph and its recorded state disagree.
2311
+ */
2312
+ interface ContentControlCheckbox {
2313
+ readonly checked: boolean;
2314
+ readonly checkedState?: ContentControlCheckboxState;
2315
+ readonly uncheckedState?: ContentControlCheckboxState;
2316
+ }
2317
+ /** `CT_DataBinding` — preserved metadata. Never resolved, never fetched. */
2318
+ /** `w:dataBinding` — the custom-XML part and XPath a control's value is bound to. */
2319
+ interface ContentControlDataBinding {
2320
+ readonly xpath?: string;
2321
+ readonly storeItemID?: string;
2322
+ readonly prefixMappings?: string;
2323
+ }
2324
+ /**
2325
+ * A control's whole `w:sdtPr`, projected into one typed shape.
2326
+ *
2327
+ * What every other lane reads instead of walking `localName` strings — which also means a Word
2328
+ * re-save that demotes the properties node to generic does not break the projection.
2329
+ */
2330
+ interface ContentControlProperties {
2331
+ readonly type: ContentControlKind;
2332
+ readonly alias?: string;
2333
+ readonly tag?: string;
2334
+ /** `@w:val` of `w:id` when the file declares a parseable one. Never fabricated. */
2335
+ readonly id?: number;
2336
+ readonly lock: ContentControlLock;
2337
+ /** The glossary entry named by `w:placeholder/w:docPart`. Preserved, never loaded. */
2338
+ readonly placeholderDocPart?: string;
2339
+ readonly temporary: boolean;
2340
+ readonly showingPlaceholder: boolean;
2341
+ readonly dataBinding?: ContentControlDataBinding;
2342
+ readonly label?: string;
2343
+ readonly tabIndex?: number;
2344
+ /** Items a dropdown or combo box offers. Empty for every other type. */
2345
+ readonly listItems: readonly ContentControlListItem[];
2346
+ readonly lastValue?: string;
2347
+ readonly date?: ContentControlDateFormat;
2348
+ readonly multiLine?: boolean;
2349
+ readonly checkbox?: ContentControlCheckbox;
2350
+ }
2351
+ /** Whether a node is a `w:sdt` wrapper. */
2352
+ declare function isContentControlNode(node: OoxmlNode): node is OoxmlContentControlNode;
2353
+ /** Whether a node is a `w:sdtContent` — the container holding a control's actual content. */
2354
+ declare function isContentControlContentNode(node: OoxmlNode): node is OoxmlContentControlContentNode;
2355
+ /**
2356
+ * A `w:sdt` wrapper, TYPED or DEMOTED.
2357
+ *
2358
+ * Flattening predates typing and must not stop at a control the reader refused to type: a
2359
+ * demoted wrapper still renders its content in place in Word, so a walk that only saw the
2360
+ * typed kind would drop every paragraph inside a malformed control out of the story.
2361
+ */
2362
+ declare function isContentControlWrapper(node: OoxmlNode): boolean;
2363
+ /**
2364
+ * The children of a wrapper's `w:sdtContent`, typed or demoted, in order.
2365
+ *
2366
+ * The one place that knows a control's content is reached through an intermediate element,
2367
+ * so the four flattening walks (story blocks, layout, header/footer references, list
2368
+ * resolution) ask the same question rather than each re-deriving it.
2369
+ */
2370
+ declare function contentControlContentChildren(wrapper: OoxmlNode): readonly OoxmlNode[];
2371
+ /**
2372
+ * A container's children with every content-control wrapper flattened away, bounded in depth.
2373
+ *
2374
+ * ONE unwrap rule, for the places where a control sits between a container and the children that
2375
+ * container is defined in terms of. `CT_SdtRow` puts it between `w:tbl` and `w:tr`, `CT_SdtCell`
2376
+ * between `w:tr` and `w:tc`, and a walk that filtered on the child's kind dropped the row or cell
2377
+ * entirely: not measured, not painted, not addressable. Flattening at the point of the filter
2378
+ * means a controlled row is the same row to the grid pass, the pagination pass and the story walk.
2379
+ *
2380
+ * Returns the SAME array identity when there is nothing to unwrap, so the tables that carry no
2381
+ * controls — nearly all of them — allocate nothing and the incremental layout cache still sees
2382
+ * its own inputs.
2383
+ */
2384
+ declare function flattenContentControls(children: readonly OoxmlNode[], maxDepth?: number): readonly OoxmlNode[];
2385
+ /** A control's `w:sdtPr`, or null. Matches structurally, so a Word-demoted node still resolves. */
2386
+ declare function contentControlPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlPropertiesNode | undefined;
2387
+ /** A control's `w:sdtEndPr` — the run properties applied to its closing marker. */
2388
+ declare function contentControlEndPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlEndPropertiesNode | undefined;
2389
+ /** A control's `w:sdtContent`, or null when the wrapper has none. */
2390
+ declare function contentControlContentNodeOf(control: OoxmlNode): OoxmlContentControlContentNode | undefined;
2391
+ /** A signed 32-bit `ST_DecimalNumber`, or undefined when the file wrote something else. */
2392
+ declare function parseContentControlId(raw: string | undefined): number | undefined;
2393
+ /**
2394
+ * Read a control's properties.
2395
+ *
2396
+ * Total: a control with no `w:sdtPr` at all answers the same shape with the defaults an
2397
+ * absent property means, so no caller has to branch on the container's existence.
2398
+ */
2399
+ declare function contentControlPropertiesOf(control: OoxmlNode): ContentControlProperties;
2400
+ /** Where a control sits, read off what its content holds. */
2401
+ type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell' | 'empty';
2402
+ /**
2403
+ * How deeply a control is nested inside other controls.
2404
+ *
2405
+ * Bounded by {@link MAX_CONTENT_CONTROL_NESTING}: nesting depth comes from a file and is a
2406
+ * recursion bound.
2407
+ */
2408
+ declare function contentControlLevelOf(control: OoxmlNode): ContentControlLevel;
2409
+ /** One control, plus how deeply it is nested and the controls that enclose it. */
2410
+ interface ContentControlEntry {
2411
+ readonly node: OoxmlContentControlNode;
2412
+ /** 0 for a top-level control; the nesting depth otherwise. */
2413
+ readonly depth: number;
2414
+ /** Enclosing controls, outermost first. Empty at depth 0. */
2415
+ readonly ancestors: readonly OoxmlContentControlNode[];
2416
+ }
2417
+ /**
2418
+ * Every control under a node, in document order, bounded in depth and in count.
2419
+ *
2420
+ * ONE walk, shared. The nesting bound is the same one layout flattens with, so a control
2421
+ * a lane can address is a control every lane can address — and a file that nests past it
2422
+ * keeps its content in the tree (the serializer never stops) while no walk recurses
2423
+ * further.
2424
+ */
2425
+ declare function contentControlsIn(root: OoxmlNode, options?: {
2426
+ readonly maxDepth?: number;
2427
+ readonly limit?: number;
2428
+ }): readonly ContentControlEntry[];
2429
+ /** Find one control by canonical node id, with the same bounded walk. */
2430
+ declare function findContentControl(root: OoxmlNode, nodeId: string): ContentControlEntry | null;
2431
+ /**
2432
+ * The plain text a control's content holds, in reading order.
2433
+ *
2434
+ * `w:delText` is excluded: struck text is not the control's value, and a dropdown whose
2435
+ * old item is still present as a tracked deletion would otherwise report both.
2436
+ *
2437
+ * A manual line break is left out unless `lineBreak` names the text to report it as.
2438
+ * With that option, column breaks report U+000E so callers cannot silently discard them.
2439
+ */
2440
+ declare function contentControlTextOf(control: OoxmlNode, lineBreak?: string): string;
2441
+ /**
2442
+ * Resolve the lock a position inherits from the controls enclosing it.
2443
+ *
2444
+ * CONSERVATIVE, because a template that says a field cannot be edited and sits inside a
2445
+ * section that says it cannot be removed means both. Each half of `ST_Lock` is taken
2446
+ * independently and the strongest wins, so an unlocked control inside a `contentLocked`
2447
+ * one is still content-locked — a nested control cannot grant a permission its parent
2448
+ * withheld, which is the only reading under which a lock is a lock.
2449
+ */
2450
+ declare function resolveContentControlLock(chain: readonly ContentControlLock[]): ContentControlLock;
2451
+ /** Whether a resolved lock forbids editing the content it covers. */
2452
+ declare function lockForbidsEdit(lock: ContentControlLock): boolean;
2453
+ /** Whether a resolved lock forbids removing the control itself. */
2454
+ declare function lockForbidsRemoval(lock: ContentControlLock): boolean;
2455
+ /**
2456
+ * `CT_SdtPr`'s declared child order (§17.5.2.38), followed by the type choice.
2457
+ *
2458
+ * Serialization re-emits children in tree order, so the ONLY way a write keeps the
2459
+ * sequence valid is to place the child it authors at its schema position — which is what
2460
+ * {@link orderedContentControlProperties} does.
2461
+ */
2462
+ declare const CONTENT_CONTROL_PROPERTY_ORDER: readonly string[];
2463
+ /**
2464
+ * Rebuild a `w:sdtPr`'s children in schema order.
2465
+ *
2466
+ * Modelled children sort to their declared position and the type element follows them,
2467
+ * as the sequence requires. Everything else — a `w15:repeatingSection`, a vendor
2468
+ * extension, the `w14:checkbox` that is not part of the ECMA-376 choice — keeps the order
2469
+ * it was authored in and follows the modelled block, so a write that touches one property
2470
+ * neither drops nor reorders anything it does not name.
2471
+ */
2472
+ declare function orderedContentControlProperties(children: readonly OoxmlNode[]): readonly OoxmlNode[];
2473
+ /**
2474
+ * The next `w:id` to write.
2475
+ *
2476
+ * Solo: one past the document's own maximum. Never a clock, a timestamp, a random source
2477
+ * or a hash: those collide with ids already in the file and produce values Word rejects.
2478
+ * Null when the document already reaches the signed 32-bit bound, so the caller refuses
2479
+ * rather than wrapping into a negative id. Hostile or out-of-range existing values are
2480
+ * ignored for seeding rather than counted past.
2481
+ *
2482
+ * When a collaboration actor is bound (explicit argument or the open store transaction),
2483
+ * the next id is the next unused value in that actor's stripe. Two peers inserting a
2484
+ * generic content control — including a custom node authored as `w:sdt` — from the same
2485
+ * snapshot then cannot share a `w:id`.
2486
+ */
2487
+ declare function allocateContentControlId(root: OoxmlNode, actorId?: string): number | null;
2488
+
2435
2489
  /** The value a control accepts, by what kind of control it is. */
2436
2490
  type ContentControlValueInput = {
2437
2491
  readonly kind: 'text';
@@ -2485,6 +2539,48 @@ declare function planRevisionBatch(part: OoxmlPart, action: 'accept' | 'reject',
2485
2539
  result: RevisionBatchResult;
2486
2540
  };
2487
2541
 
2542
+ /** Why a requested change keeps its attribution. @public */
2543
+ type RevisionAuthorSkipReason = 'unknown-revision' | 'unsupported-revision';
2544
+ /**
2545
+ * One reattributed change. `key` and `author` describe the change after the update, because
2546
+ * review keys include the author. @public
2547
+ */
2548
+ interface RevisionAuthorEntry extends RevisionBatchEntry {
2549
+ /**
2550
+ * The key the caller selected the change by. It differs from `key` when the attribution
2551
+ * changed, because review keys include the author and date.
2552
+ */
2553
+ readonly previousKey: string;
2554
+ /** The author the change had before the update. */
2555
+ readonly previousAuthor: string;
2556
+ }
2557
+ /** Outcome of one attribution change. Counts refer to review decisions, not XML markers. @public */
2558
+ interface RevisionAuthorResult {
2559
+ /** Changes that now carry the requested attribution, in selection order. */
2560
+ readonly updated: readonly RevisionAuthorEntry[];
2561
+ /** Requested changes that kept their attribution. */
2562
+ readonly skipped: readonly {
2563
+ readonly key: string;
2564
+ readonly reason: RevisionAuthorSkipReason;
2565
+ readonly revision?: RevisionBatchEntry;
2566
+ }[];
2567
+ }
2568
+ /** A planned attribution change: its ops, and how to name the result once they commit. */
2569
+ interface RevisionAuthorPlan {
2570
+ readonly ops: readonly TreeDocOp[];
2571
+ /** The outcome before commit. Updated entries still carry their previous keys. */
2572
+ readonly result: RevisionAuthorResult;
2573
+ /** The outcome against the committed part, with each updated change under its new key. */
2574
+ finish(after: OoxmlPart): RevisionAuthorResult;
2575
+ }
2576
+ /**
2577
+ * Plan an attribution change for selected review keys. Omitted keys select every change.
2578
+ * `authors` keeps only the changes those authors made.
2579
+ * Callers validate `revision` with `invalidRevisionAuthorInput` first.
2580
+ * @internal
2581
+ */
2582
+ declare function planRevisionAuthorChange(part: OoxmlPart, revision: RevisionAttributionInput, keys?: readonly string[], scopeRoot?: OoxmlNode, authors?: readonly string[]): RevisionAuthorPlan;
2583
+
2488
2584
  /** Allowlisted OOXML table border line styles — store/layout authority. */
2489
2585
  declare const TABLE_BORDER_STYLES: readonly ['single', 'dashed', 'dotted', 'double', 'triple', 'thick'];
2490
2586
  /**
@@ -2630,8 +2726,11 @@ interface DocRange {
2630
2726
  */
2631
2727
  type ExecResult = {
2632
2728
  ok: true;
2729
+ /** Whether the DOCUMENT changed; view-only calls (pane, activation, mode) always report `false`. */
2633
2730
  changed: boolean;
2634
2731
  revisions?: RevisionBatchResult;
2732
+ /** Present on `setReviewChangesAuthor`: the changes it updated and the ones it skipped. */
2733
+ revisionAuthors?: RevisionAuthorResult;
2635
2734
  history?: HistoryGroupOutcome;
2636
2735
  } | {
2637
2736
  ok: false;
@@ -2639,6 +2738,7 @@ type ExecResult = {
2639
2738
  reason: string;
2640
2739
  target?: DocTarget;
2641
2740
  revisions?: RevisionBatchResult;
2741
+ revisionAuthors?: RevisionAuthorResult;
2642
2742
  };
2643
2743
  /**
2644
2744
  * Why a write was refused, as a value to branch on.
@@ -3244,6 +3344,18 @@ type TreeDocOp = SetFieldCodeOp | {
3244
3344
  readonly siteNodeIds?: readonly string[];
3245
3345
  /** Internal shared-notes scope. When present, this must be the canonical id of a note root. */
3246
3346
  readonly scopeRootId?: string;
3347
+ } | {
3348
+ /**
3349
+ * Attribute pending revisions to another author, and optionally another date, without
3350
+ * deciding them. `sites` name revision elements and move range starts. Sites sharing a
3351
+ * `renumber` label take one fresh `w:id`, so the change cannot merge with another one.
3352
+ */
3353
+ readonly op: 'setRevisionAttribution';
3354
+ readonly revision: RevisionAttributionInput;
3355
+ readonly sites: readonly {
3356
+ readonly nodeId: string;
3357
+ readonly renumber?: string;
3358
+ }[];
3247
3359
  } | {
3248
3360
  readonly op: 'rejectAllRevisions';
3249
3361
  /** Exact canonical sites selected by bulk preflight. */
@@ -4057,7 +4169,19 @@ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' |
4057
4169
  * a real offset that is not a PLACE — refused rather than resolved to the nearest one, so a
4058
4170
  * caller learns the node would not have landed where they asked.
4059
4171
  */
4060
- | 'indivisible-content' | 'unknown-block' | 'not-a-block' | 'block-required' | 'carries-section-mark'
4172
+ | 'indivisible-content'
4173
+ /**
4174
+ * The range has one end inside a field's editable saved result and the other outside it.
4175
+ * Deleting it would leave the field's begin, separate, and end markers unbalanced, so it is
4176
+ * refused. A range that covers the whole field removes the field.
4177
+ */
4178
+ | 'field-structure'
4179
+ /**
4180
+ * In the editable field-result mode, an op other than typing, deletion, or run formatting
4181
+ * addresses a position inside a field's saved result. Splits, tabs, links, notes, and
4182
+ * fragments there are not supported yet.
4183
+ */
4184
+ | 'field-result-unsupported' | 'unknown-block' | 'not-a-block' | 'block-required' | 'carries-section-mark'
4061
4185
  /** The transaction named a part the package does not hold. */
4062
4186
  | 'unknown-part'
4063
4187
  /**
@@ -4141,5 +4265,5 @@ type TreeOpResult = {
4141
4265
  readonly detail?: string;
4142
4266
  };
4143
4267
 
4144
- export { IMAGE_WRAP_TARGETS as aE, TEXT_FORM_FORMATS as aF, ACCEPTED_PARAGRAPH_PROPERTIES as aW, ACCEPTED_RUN_PROPERTIES as aX, CONTENT_CONTROL_ID_MAX as aY, CONTENT_CONTROL_PROPERTY_ORDER as aZ, DEFAULT_OOXML_PACKAGE_LIMITS as be, DEFAULT_ZIP_LIMITS as bf, HYPERLINK_RELATIONSHIP_TYPE as bi, IMAGE_RELATIONSHIP_TYPE as bl, MAX_CONTENT_CONTROLS_PER_PART as br, MAX_CONTENT_CONTROL_NESTING as bs, OFFICE_RELATIONSHIP_NAMESPACE_URI as bv, OOXML_NODE_IDENTITY_RULES as bw, isContentControlWrapper as c$, allocateContentControlId as cA, asciiFold as cB, buildContentTypeIndex as cC, buildRelationshipSet as cD, childElements as cE, commentAnchorsOfStory as cF, commentsOfPart as cG, contentControlContentChildren as cH, contentControlContentNodeOf as cI, contentControlEndPropertiesNodeOf as cJ, contentControlLevelOf as cK, contentControlPropertiesNodeOf as cL, contentControlPropertiesOf as cM, contentControlTextOf as cN, contentControlsIn as cO, detectDuplicateNames as cP, extensionKey as cQ, findContentControl as cR, findElement as cS, firstReviewRange as cT, flattenContentControls as cU, hasAnyComment as cV, hyperlinkAnchorOf as cW, hyperlinkRelationshipIdOf as cX, hyperlinkTargetOf as cY, isContentControlContentNode as cZ, isContentControlNode as c_, TABLE_BORDER_STYLES as ch, W15_NAMESPACE_URI as cp, WML_NAMESPACE_URI as cq, XMLNS_NAMESPACE_URI as cr, XML_NAMESPACE_URI as cs, isContentRevisionKind as d0, isHyperlinkNode as d1, isRangeMarkerKind as d2, isValidMime as d3, legacyCheckboxFieldsOf as d4, lockForbidsEdit as d5, lockForbidsRemoval as d6, normalizePartName as d7, orderedContentControlProperties as d8, parseContentControlId as d9, reviewItemsAt as dA, reviewThreadRootOf as dB, partNameKey as da, planRevisionBatch as db, projectDrawing as dc, readOnOffChild as dd, readOoxmlPackage as de, readOoxmlPart as df, readXml as dg, readZip as dh, resolveContentControlLock as di, resolveContentType as dj, resolveImageRelationship as dk, resolveInternalTarget as dl, resolveRelationship as dm, reviewItemKey as dn, reviewItemRanges as dp, textContent as dq, textFormFieldsOf as dr, threadStateOfPart as ds, validateExternalTarget as dt, withPart as du, writeOoxmlPackage as dv, writeZip as dw, activeReviewItem as dy, reviewItemPositionRank as dz };
4145
- export type { OoxmlContentControlContentNode as $, ParagraphTabStop as A, Block as B, CommentRecord as C, DocxDocument as D, ExecResult as E, RevisionType as F, Section as G, HeaderFooterSet as H, InsertableContentControlType as I, SectionProperties as J, StyleDefinition as K, Theme as L, ThemeColorScheme as M, OoxmlNode as N, OoxmlPart as O, Paragraph as P, OoxmlPackage as Q, ReviewModelInput as R, StyleDefinitions as S, Table as T, OoxmlNodeId as U, OoxmlGenericElementNode as V, TreeDocOp as W, OoxmlProperty as X, OoxmlPackageRejection as Y, OoxmlElement as Z, OoxmlContentControlNode as _, ReviewItem as a, CommentPosition as a$, DrawingProjection as a0, OoxmlPackageLimits as a1, RevisionBatchEntry as a2, RevisionBatchResult as a3, RevisionBatchSkipReason as a4, TreeOpRejection as a5, AutomationTableMutation as a6, RevisionAttributionInput as a7, SourceCrop as a8, DrawingKind as a9, OoxmlSeparatorNode as aA, DrawingTreeDocOp as aB, ImpactClass as aC, TreeDocColorValue as aD, TableBorderStyle as aG, DrawingAccessibility as aH, DrawingImageEffects as aI, DrawingTransform as aJ, VectorShapeProjection as aK, OoxmlDrawingNode as aL, OoxmlInvariantResult as aM, OoxmlFldCharNode as aN, OoxmlFldSimpleNode as aO, OoxmlInstrTextNode as aP, OoxmlInvariantIssue as aQ, TreeOpResult as aR, RelationshipRecord as aS, OoxmlHardBreakNode as aT, OoxmlAttribute as aU, CommentThreadState as aV, CommentAnchor as a_, ImageWrapTarget as aa, DrawingPositionInput as ab, DrawingLocks as ac, ParagraphFormatCommand as ad, Watermark as ae, Rect as af, SelectionPin as ag, Unsubscribe as ah, DocxDocumentJSON as ai, DrawingHorizontalReferenceFrame as aj, DrawingVerticalReferenceFrame as ak, FontDefinition as al, NumberingRef as am, PageMargins as an, ParagraphDisagreements as ao, Point as ap, Run as aq, TableCell as ar, TableRow as as, OoxmlParagraphNode as at, OoxmlNoteNode as au, OoxmlContinuationSeparatorNode as av, OoxmlEndnotesNode as aw, OoxmlFootnotesNode as ax, OoxmlNoteRefNode as ay, OoxmlNoteReferenceNode as az, ReviewRevisionItem as b, OoxmlReadRejection as b$, CommitTextFormFieldOp as b0, ContentControlCheckbox as b1, ContentControlCheckboxState as b2, ContentControlDataBinding as b3, ContentControlDateFormat as b4, ContentControlEntry as b5, ContentControlKind as b6, ContentControlLevel as b7, ContentControlListItem as b8, ContentControlLock as b9, OoxmlContentControlCalendarNode as bA, OoxmlContentControlCheckboxNode as bB, OoxmlContentControlCheckedNode as bC, OoxmlContentControlCheckedStateNode as bD, OoxmlContentControlComboBoxNode as bE, OoxmlContentControlDataBindingNode as bF, OoxmlContentControlDateFormatNode as bG, OoxmlContentControlDateNode as bH, OoxmlContentControlDropDownListNode as bI, OoxmlContentControlEndPropertiesNode as bJ, OoxmlContentControlLidNode as bK, OoxmlContentControlListItemNode as bL, OoxmlContentControlPropertiesNode as bM, OoxmlContentControlStoreMappedDataAsNode as bN, OoxmlContentControlTextNode as bO, OoxmlContentControlUncheckedStateNode as bP, OoxmlDocumentNode as bQ, OoxmlExternalTarget as bR, OoxmlGenericExtensionAttribute as bS, OoxmlHyperlinkNode as bT, OoxmlInvariantIssueCode as bU, OoxmlKnownNodeAttribute as bV, OoxmlNamespaceBinding as bW, OoxmlNodeIdentityRules as bX, OoxmlPackageResult as bY, OoxmlParagraphPropertiesNode as bZ, OoxmlPartMetadata as b_, ContentControlProperties as ba, ContentTypeError as bb, ContentTypeIndex as bc, ContentTypeRecords as bd, DefaultRecord as bg, DeleteTextOp as bh, HyperlinkKind as bj, HyperlinkTarget as bk, ImageRelationshipResolution as bm, IndexResult as bn, InsertBuildingBlockOp as bo, InsertTextOp as bp, LegacyCheckboxFieldRange as bq, NameRejection as bt, NameResult as bu, OoxmlBodyNode as bx, OoxmlBookmarkEndNode as by, OoxmlBookmarkStartNode as bz, ReviewCommentItem as c, OoxmlReadResult as c0, OoxmlRunNode as c1, OoxmlRunPropertiesNode as c2, OoxmlTabNode as c3, OoxmlTextElementNode as c4, OoxmlTextNode as c5, OoxmlWmlValAttribute as c6, OoxmlXmlSpaceAttribute as c7, OverrideRecord as c8, RelationshipError as c9, RelationshipSetResult as ca, RelationshipTargetResolver as cb, ResolveResult as cc, ResolvedRelationship as cd, SetLegacyCheckboxOp as ce, SetLegacyDropdownOp as cf, SetTextFormFieldDefaultOp as cg, TabStopWrite as ci, TargetMode as cj, TextFormFieldOptions as ck, TextFormFieldRange as cl, TextFormFieldType as cm, TreeDocOpKind as cn, TreeOpEffect as co, XmlLimits as ct, XmlNode as cu, XmlRejection as cv, XmlResult as cw, ZipLimits as cx, ZipReadResult as cy, ZipRejection as cz, ReviewCustomItem as d, VectorShapeComponent as dx, ReviewPosition as e, ReviewRange as f, ReviewRevisionKind as g, RevisionAddress as h, ContentControlType as i, DocTarget as j, RunFormatting as k, Extent as l, ContainerRef as m, ContentControlFilter as n, DocRange as o, Revision as p, DocComment as q, ColorValue as r, ContentControl as s, DocAnchor as t, DocAnchorRange as u, DocLocation as v, DocumentBody as w, ExecErrorCode as x, IndentFormatting as y, ParagraphFlags as z };
4268
+ export { CONTENT_CONTROL_ID_MAX as a$, IMAGE_WRAP_TARGETS as aH, TEXT_FORM_FORMATS as aI, ACCEPTED_PARAGRAPH_PROPERTIES as aZ, ACCEPTED_RUN_PROPERTIES as a_, CONTENT_CONTROL_PROPERTY_ORDER as b0, DEFAULT_OOXML_PACKAGE_LIMITS as bh, DEFAULT_ZIP_LIMITS as bi, HYPERLINK_RELATIONSHIP_TYPE as bl, IMAGE_RELATIONSHIP_TYPE as bo, MAX_CONTENT_CONTROLS_PER_PART as bu, MAX_CONTENT_CONTROL_NESTING as bv, OFFICE_RELATIONSHIP_NAMESPACE_URI as by, OOXML_NODE_IDENTITY_RULES as bz, hyperlinkTargetOf as c$, allocateContentControlId as cD, asciiFold as cE, buildContentTypeIndex as cF, buildRelationshipSet as cG, childElements as cH, commentAnchorsOfStory as cI, commentsOfPart as cJ, contentControlContentChildren as cK, contentControlContentNodeOf as cL, contentControlEndPropertiesNodeOf as cM, contentControlLevelOf as cN, contentControlPropertiesNodeOf as cO, contentControlPropertiesOf as cP, contentControlTextOf as cQ, contentControlsIn as cR, detectDuplicateNames as cS, extensionKey as cT, findContentControl as cU, findElement as cV, firstReviewRange as cW, flattenContentControls as cX, hasAnyComment as cY, hyperlinkAnchorOf as cZ, hyperlinkRelationshipIdOf as c_, TABLE_BORDER_STYLES as ck, W15_NAMESPACE_URI as cs, WML_NAMESPACE_URI as ct, XMLNS_NAMESPACE_URI as cu, XML_NAMESPACE_URI as cv, isContentControlContentNode as d0, isContentControlNode as d1, isContentControlWrapper as d2, isContentRevisionKind as d3, isHyperlinkNode as d4, isRangeMarkerKind as d5, isValidMime as d6, legacyCheckboxFieldsOf as d7, lockForbidsEdit as d8, lockForbidsRemoval as d9, writeZip as dA, activeReviewItem as dC, reviewItemPositionRank as dD, reviewItemsAt as dE, reviewThreadRootOf as dF, normalizePartName as da, orderedContentControlProperties as db, parseContentControlId as dc, partNameKey as dd, planRevisionAuthorChange as de, planRevisionBatch as df, projectDrawing as dg, readOnOffChild as dh, readOoxmlPackage as di, readOoxmlPart as dj, readXml as dk, readZip as dl, resolveContentControlLock as dm, resolveContentType as dn, resolveImageRelationship as dp, resolveInternalTarget as dq, resolveRelationship as dr, reviewItemKey as ds, reviewItemRanges as dt, textContent as du, textFormFieldsOf as dv, threadStateOfPart as dw, validateExternalTarget as dx, withPart as dy, writeOoxmlPackage as dz };
4269
+ export type { OoxmlContentControlContentNode as $, ParagraphTabStop as A, Block as B, CommentRecord as C, DocxDocument as D, ExecResult as E, RevisionType as F, Section as G, HeaderFooterSet as H, InsertableContentControlType as I, SectionProperties as J, StyleDefinition as K, Theme as L, ThemeColorScheme as M, OoxmlNode as N, OoxmlPart as O, Paragraph as P, OoxmlPackage as Q, ReviewModelInput as R, StyleDefinitions as S, Table as T, OoxmlNodeId as U, OoxmlGenericElementNode as V, TreeDocOp as W, OoxmlProperty as X, OoxmlPackageRejection as Y, OoxmlElement as Z, OoxmlContentControlNode as _, ReviewItem as a, DrawingProjection as a0, OoxmlPackageLimits as a1, RevisionAuthorEntry as a2, RevisionAuthorResult as a3, RevisionAuthorSkipReason as a4, RevisionBatchEntry as a5, RevisionBatchResult as a6, RevisionBatchSkipReason as a7, TreeOpRejection as a8, AutomationTableMutation as a9, PageMargins as aA, ParagraphDisagreements as aB, Point as aC, Run as aD, TableCell as aE, TableRow as aF, TreeDocColorValue as aG, TableBorderStyle as aJ, DrawingAccessibility as aK, DrawingImageEffects as aL, DrawingTransform as aM, VectorShapeProjection as aN, OoxmlDrawingNode as aO, OoxmlInvariantResult as aP, OoxmlInvariantIssue as aQ, OoxmlFldCharNode as aR, OoxmlFldSimpleNode as aS, OoxmlInstrTextNode as aT, TreeOpResult as aU, RelationshipRecord as aV, OoxmlHardBreakNode as aW, OoxmlAttribute as aX, CommentThreadState as aY, RevisionAttributionInput as aa, OoxmlParagraphNode as ab, OoxmlNoteNode as ac, OoxmlContinuationSeparatorNode as ad, OoxmlEndnotesNode as ae, OoxmlFootnotesNode as af, OoxmlNoteRefNode as ag, OoxmlNoteReferenceNode as ah, OoxmlSeparatorNode as ai, DrawingTreeDocOp as aj, ImpactClass as ak, SourceCrop as al, DrawingKind as am, ImageWrapTarget as an, DrawingPositionInput as ao, DrawingLocks as ap, ParagraphFormatCommand as aq, Watermark as ar, Rect as as, SelectionPin as at, Unsubscribe as au, DocxDocumentJSON as av, DrawingHorizontalReferenceFrame as aw, DrawingVerticalReferenceFrame as ax, FontDefinition as ay, NumberingRef as az, ReviewRevisionItem as b, OoxmlPackageResult as b$, CommentAnchor as b1, CommentPosition as b2, CommitTextFormFieldOp as b3, ContentControlCheckbox as b4, ContentControlCheckboxState as b5, ContentControlDataBinding as b6, ContentControlDateFormat as b7, ContentControlEntry as b8, ContentControlKind as b9, OoxmlBodyNode as bA, OoxmlBookmarkEndNode as bB, OoxmlBookmarkStartNode as bC, OoxmlContentControlCalendarNode as bD, OoxmlContentControlCheckboxNode as bE, OoxmlContentControlCheckedNode as bF, OoxmlContentControlCheckedStateNode as bG, OoxmlContentControlComboBoxNode as bH, OoxmlContentControlDataBindingNode as bI, OoxmlContentControlDateFormatNode as bJ, OoxmlContentControlDateNode as bK, OoxmlContentControlDropDownListNode as bL, OoxmlContentControlEndPropertiesNode as bM, OoxmlContentControlLidNode as bN, OoxmlContentControlListItemNode as bO, OoxmlContentControlPropertiesNode as bP, OoxmlContentControlStoreMappedDataAsNode as bQ, OoxmlContentControlTextNode as bR, OoxmlContentControlUncheckedStateNode as bS, OoxmlDocumentNode as bT, OoxmlExternalTarget as bU, OoxmlGenericExtensionAttribute as bV, OoxmlHyperlinkNode as bW, OoxmlInvariantIssueCode as bX, OoxmlKnownNodeAttribute as bY, OoxmlNamespaceBinding as bZ, OoxmlNodeIdentityRules as b_, ContentControlLevel as ba, ContentControlListItem as bb, ContentControlLock as bc, ContentControlProperties as bd, ContentTypeError as be, ContentTypeIndex as bf, ContentTypeRecords as bg, DefaultRecord as bj, DeleteTextOp as bk, HyperlinkKind as bm, HyperlinkTarget as bn, ImageRelationshipResolution as bp, IndexResult as bq, InsertBuildingBlockOp as br, InsertTextOp as bs, LegacyCheckboxFieldRange as bt, NameRejection as bw, NameResult as bx, ReviewCommentItem as c, OoxmlParagraphPropertiesNode as c0, OoxmlPartMetadata as c1, OoxmlReadRejection as c2, OoxmlReadResult as c3, OoxmlRunNode as c4, OoxmlRunPropertiesNode as c5, OoxmlTabNode as c6, OoxmlTextElementNode as c7, OoxmlTextNode as c8, OoxmlWmlValAttribute as c9, ZipLimits as cA, ZipReadResult as cB, ZipRejection as cC, OoxmlXmlSpaceAttribute as ca, OverrideRecord as cb, RelationshipError as cc, RelationshipSetResult as cd, RelationshipTargetResolver as ce, ResolveResult as cf, ResolvedRelationship as cg, SetLegacyCheckboxOp as ch, SetLegacyDropdownOp as ci, SetTextFormFieldDefaultOp as cj, TabStopWrite as cl, TargetMode as cm, TextFormFieldOptions as cn, TextFormFieldRange as co, TextFormFieldType as cp, TreeDocOpKind as cq, TreeOpEffect as cr, XmlLimits as cw, XmlNode as cx, XmlRejection as cy, XmlResult as cz, ReviewCustomItem as d, VectorShapeComponent as dB, ReviewPosition as e, ReviewRange as f, ReviewRevisionKind as g, RevisionAddress as h, ContentControlType as i, DocTarget as j, RunFormatting as k, Extent as l, ContainerRef as m, ContentControlFilter as n, DocRange as o, Revision as p, DocComment as q, ColorValue as r, ContentControl as s, DocAnchor as t, DocAnchorRange as u, DocLocation as v, DocumentBody as w, ExecErrorCode as x, IndentFormatting as y, ParagraphFlags as z };