@superdoc/mcp 1.10.0-next.4 → 1.10.0-next.5

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 (2) hide show
  1. package/dist/index.js +1311 -566
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31630,7 +31630,7 @@ var init_host = __esm(() => {
31630
31630
  });
31631
31631
 
31632
31632
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31633
- var SDK_VERSION = "2.23.0-next.4";
31633
+ var SDK_VERSION = "2.23.0-next.5";
31634
31634
 
31635
31635
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31636
31636
  import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
@@ -132643,6 +132643,259 @@ var init_part_payload = __esm(() => {
132643
132643
  EMPTY_CHUNK = new Uint8Array(0);
132644
132644
  });
132645
132645
 
132646
+ // ../../../v2/editor-core/dist/util/sha256-sync.js
132647
+ function rightRotate(value, amount) {
132648
+ return value >>> amount | value << 32 - amount;
132649
+ }
132650
+ function sha256HexSync(bytes) {
132651
+ const bitLength = BigInt(bytes.length) * 8n;
132652
+ const paddedLength = Math.ceil((bytes.length + 1 + 8) / 64) * 64;
132653
+ const padded = new Uint8Array(paddedLength);
132654
+ padded.set(bytes);
132655
+ padded[bytes.length] = 128;
132656
+ const paddedView = new DataView(padded.buffer);
132657
+ paddedView.setUint32(paddedLength - 8, Number(bitLength >> 32n & 0xffffffffn));
132658
+ paddedView.setUint32(paddedLength - 4, Number(bitLength & 0xffffffffn));
132659
+ const hash2 = [...INITIAL_HASH];
132660
+ const words = new Uint32Array(64);
132661
+ for (let offset = 0;offset < paddedLength; offset += 64) {
132662
+ for (let index = 0;index < 16; index += 1) {
132663
+ words[index] = paddedView.getUint32(offset + index * 4);
132664
+ }
132665
+ for (let index = 16;index < 64; index += 1) {
132666
+ const s0 = rightRotate(words[index - 15], 7) ^ rightRotate(words[index - 15], 18) ^ words[index - 15] >>> 3;
132667
+ const s1 = rightRotate(words[index - 2], 17) ^ rightRotate(words[index - 2], 19) ^ words[index - 2] >>> 10;
132668
+ words[index] = words[index - 16] + s0 + words[index - 7] + s1 >>> 0;
132669
+ }
132670
+ let [a, b, c, d, e, f, g, h] = hash2;
132671
+ for (let index = 0;index < 64; index += 1) {
132672
+ const s1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
132673
+ const ch = e & f ^ ~e & g;
132674
+ const temp1 = h + s1 + ch + ROUND_CONSTANTS[index] + words[index] >>> 0;
132675
+ const s0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
132676
+ const maj = a & b ^ a & c ^ b & c;
132677
+ const temp2 = s0 + maj >>> 0;
132678
+ h = g;
132679
+ g = f;
132680
+ f = e;
132681
+ e = d + temp1 >>> 0;
132682
+ d = c;
132683
+ c = b;
132684
+ b = a;
132685
+ a = temp1 + temp2 >>> 0;
132686
+ }
132687
+ hash2[0] = hash2[0] + a >>> 0;
132688
+ hash2[1] = hash2[1] + b >>> 0;
132689
+ hash2[2] = hash2[2] + c >>> 0;
132690
+ hash2[3] = hash2[3] + d >>> 0;
132691
+ hash2[4] = hash2[4] + e >>> 0;
132692
+ hash2[5] = hash2[5] + f >>> 0;
132693
+ hash2[6] = hash2[6] + g >>> 0;
132694
+ hash2[7] = hash2[7] + h >>> 0;
132695
+ }
132696
+ return hash2.map((value) => value.toString(16).padStart(8, "0")).join("");
132697
+ }
132698
+ var INITIAL_HASH, ROUND_CONSTANTS;
132699
+ var init_sha256_sync = __esm(() => {
132700
+ INITIAL_HASH = [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225];
132701
+ ROUND_CONSTANTS = [
132702
+ 1116352408,
132703
+ 1899447441,
132704
+ 3049323471,
132705
+ 3921009573,
132706
+ 961987163,
132707
+ 1508970993,
132708
+ 2453635748,
132709
+ 2870763221,
132710
+ 3624381080,
132711
+ 310598401,
132712
+ 607225278,
132713
+ 1426881987,
132714
+ 1925078388,
132715
+ 2162078206,
132716
+ 2614888103,
132717
+ 3248222580,
132718
+ 3835390401,
132719
+ 4022224774,
132720
+ 264347078,
132721
+ 604807628,
132722
+ 770255983,
132723
+ 1249150122,
132724
+ 1555081692,
132725
+ 1996064986,
132726
+ 2554220882,
132727
+ 2821834349,
132728
+ 2952996808,
132729
+ 3210313671,
132730
+ 3336571891,
132731
+ 3584528711,
132732
+ 113926993,
132733
+ 338241895,
132734
+ 666307205,
132735
+ 773529912,
132736
+ 1294757372,
132737
+ 1396182291,
132738
+ 1695183700,
132739
+ 1986661051,
132740
+ 2177026350,
132741
+ 2456956037,
132742
+ 2730485921,
132743
+ 2820302411,
132744
+ 3259730800,
132745
+ 3345764771,
132746
+ 3516065817,
132747
+ 3600352804,
132748
+ 4094571909,
132749
+ 275423344,
132750
+ 430227734,
132751
+ 506948616,
132752
+ 659060556,
132753
+ 883997877,
132754
+ 958139571,
132755
+ 1322822218,
132756
+ 1537002063,
132757
+ 1747873779,
132758
+ 1955562222,
132759
+ 2024104815,
132760
+ 2227730452,
132761
+ 2361852424,
132762
+ 2428436474,
132763
+ 2756734187,
132764
+ 3204031479,
132765
+ 3329325298
132766
+ ];
132767
+ });
132768
+
132769
+ // ../../../v2/editor-core/dist/document/internal/xml-text.js
132770
+ function decodeXmlText(text) {
132771
+ return decodeXmlTextEntities(text, false);
132772
+ }
132773
+ function decodeXmlTextPreservingInvalidNumericEntities(text) {
132774
+ return decodeXmlTextEntities(text, true);
132775
+ }
132776
+ function decodeXmlTextEntities(text, preserveInvalidNumericEntities) {
132777
+ return text.replace(ENTITY_RE, (_, entity) => {
132778
+ switch (entity) {
132779
+ case "lt":
132780
+ return "<";
132781
+ case "gt":
132782
+ return ">";
132783
+ case "amp":
132784
+ return "&";
132785
+ case "quot":
132786
+ return '"';
132787
+ case "apos":
132788
+ return "'";
132789
+ default: {
132790
+ const cp = entity.startsWith("#x") ? Number.parseInt(entity.slice(2), 16) : Number.parseInt(entity.slice(1), 10);
132791
+ if (!Number.isFinite(cp))
132792
+ return `&${entity};`;
132793
+ if (preserveInvalidNumericEntities && (cp <= 0 || cp > 1114111 || cp >= 55296 && cp <= 57343))
132794
+ return `&${entity};`;
132795
+ return String.fromCodePoint(cp);
132796
+ }
132797
+ }
132798
+ });
132799
+ }
132800
+ function decodeXmlAttributeValue(value) {
132801
+ return decodeXmlText(value.replace(/[\t\n\r]/g, " "));
132802
+ }
132803
+ function semanticXmlAttributeValueSpace(value) {
132804
+ return value.replace(/[\t\n\r]/g, " ");
132805
+ }
132806
+ function escapeXmlText(text) {
132807
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
132808
+ }
132809
+ function escapedXmlTextCodePointUtf8Width(codePoint) {
132810
+ if (codePoint === 38)
132811
+ return 5;
132812
+ if (codePoint === 60 || codePoint === 62)
132813
+ return 4;
132814
+ if (codePoint <= 127)
132815
+ return 1;
132816
+ if (codePoint <= 2047)
132817
+ return 2;
132818
+ if (codePoint <= 65535)
132819
+ return 3;
132820
+ return 4;
132821
+ }
132822
+ function escapeXmlAttribute(text) {
132823
+ return escapeXmlText(text).replace(/"/g, "&quot;").replace(/'/g, "&apos;");
132824
+ }
132825
+ function needsXmlSpacePreserve(text) {
132826
+ return /^\s|\s$/.test(text);
132827
+ }
132828
+ function isUtf16Boundary(text, offset) {
132829
+ if (offset <= 0 || offset >= text.length)
132830
+ return true;
132831
+ const previous = text.charCodeAt(offset - 1);
132832
+ const next = text.charCodeAt(offset);
132833
+ return !(previous >= 55296 && previous <= 56319 && next >= 56320 && next <= 57343);
132834
+ }
132835
+ var ENTITY_RE;
132836
+ var init_xml_text = __esm(() => {
132837
+ ENTITY_RE = /&(lt|gt|amp|quot|apos|#\d+|#x[0-9a-fA-F]+);/g;
132838
+ });
132839
+
132840
+ // ../../../v2/editor-core/dist/document/transactions/tracked-changes/revision-id-identity.js
132841
+ function revisionIdentityBinding(partUri, namespaceUri, kind, portableId, originalId, author, date6) {
132842
+ return sha256HexSync(ENCODER.encode(JSON.stringify([
132843
+ partUri,
132844
+ namespaceUri,
132845
+ kind,
132846
+ portableId,
132847
+ originalId,
132848
+ author,
132849
+ date6
132850
+ ])));
132851
+ }
132852
+ function* readRevisionIdentityAliasesWork(xml, partUri, elements, namespaceBindingsByTagStart) {
132853
+ const result = new Map;
132854
+ if (!xml.includes("binding"))
132855
+ return result;
132856
+ for (const element of elements) {
132857
+ yield;
132858
+ const bindings2 = namespaceBindingsByTagStart.get(element.start) ?? {};
132859
+ const attributes = [...scanRawXmlAttributes(xml.slice(element.start, element.openEnd))].map((a) => ({
132860
+ namespaceUri: bindings2[a.prefix] ?? "",
132861
+ localName: a.localName,
132862
+ value: decodeXmlAttributeValue(a.value)
132863
+ }));
132864
+ const word = (name) => attributes.find((a) => a.localName === name && (a.namespaceUri === NS_W || a.namespaceUri === NS_WSTRICT))?.value ?? "";
132865
+ const physical = word("id");
132866
+ const metadata = attributes.filter((a) => a.namespaceUri === REVISION_IDENTITY_NAMESPACE && (a.localName === "id" || a.localName === "binding" || a.localName === "lexical"));
132867
+ if (!metadata.length)
132868
+ continue;
132869
+ const reservedId = metadata.find((a) => a.localName === "id")?.value;
132870
+ const lexical = metadata.find((a) => a.localName === "lexical")?.value;
132871
+ const original = lexical ?? reservedId;
132872
+ const binding = metadata.find((a) => a.localName === "binding")?.value;
132873
+ const decodedOriginal = original ? decodeXmlAttributeValue(original) : "";
132874
+ if (metadata.length !== (lexical === undefined ? 2 : 3) || !original || !binding || !physical || !reservedId || !/^[+-]?\d{1,128}$/.test(reservedId) || !/^[\x20\t\r\n]*[+-]?\d{1,128}[\x20\t\r\n]*$/.test(decodedOriginal) || !/^[\x20\t\r\n]*[+-]?\d{1,128}[\x20\t\r\n]*$/.test(physical))
132875
+ continue;
132876
+ const originalInteger = BigInt(decodedOriginal.trim()), portableInteger = BigInt(physical.trim());
132877
+ if (BigInt(reservedId) !== originalInteger)
132878
+ continue;
132879
+ if (originalInteger >= -2147483648n && originalInteger <= 2147483647n || portableInteger < -2147483648n || portableInteger > 2147483647n)
132880
+ continue;
132881
+ const portable = String(portableInteger);
132882
+ if (binding !== revisionIdentityBinding(partUri, element.namespaceUri, element.localName, portable, original, word("author"), word("date")))
132883
+ continue;
132884
+ result.set(element.start, original);
132885
+ }
132886
+ return result;
132887
+ }
132888
+ function logicalRevisionWId(fragment2) {
132889
+ return fragment2.logicalWId ?? fragment2.wId;
132890
+ }
132891
+ var REVISION_IDENTITY_NAMESPACE = "urn:superdoc:revision-identity:1", ENCODER;
132892
+ var init_revision_id_identity = __esm(() => {
132893
+ init_sha256_sync();
132894
+ init_xml_sax();
132895
+ init_xml_text();
132896
+ ENCODER = new TextEncoder;
132897
+ });
132898
+
132646
132899
  // ../../../v2/editor-core/dist/document/internal/xml-element-slice.js
132647
132900
  function matchLeadingElement(xml, localName) {
132648
132901
  const name = escapeRegExp2(localName);
@@ -132855,6 +133108,180 @@ var init_metadata_projection = __esm(() => {
132855
133108
  };
132856
133109
  });
132857
133110
 
133111
+ // ../../../v2/editor-core/dist/document/internal/xml-ignorable.js
133112
+ function appendXmlIgnorablePrefix(openTag, namespaceBindings, prefix, mcPrefix) {
133113
+ for (const attribute of scanRawXmlAttributes(openTag)) {
133114
+ if (attribute.localName === "Ignorable" && attribute.prefix && namespaceBindings[attribute.prefix] === NS_MC) {
133115
+ return openTag.slice(0, attribute.valueEnd) + ` ${prefix}` + openTag.slice(attribute.valueEnd);
133116
+ }
133117
+ }
133118
+ return openTag.slice(0, -1) + ` xmlns:${mcPrefix}="${NS_MC}" ${mcPrefix}:Ignorable="${prefix}">`;
133119
+ }
133120
+ var init_xml_ignorable = __esm(() => {
133121
+ init_xml_sax();
133122
+ });
133123
+
133124
+ // ../../../v2/editor-core/dist/document/transactions/tracked-changes/revision-id-export.js
133125
+ function integer2(value) {
133126
+ const collapsed = value.replace(/^[\x20\t\r\n]+|[\x20\t\r\n]+$/g, "");
133127
+ return /^[+-]?\d+$/.test(collapsed) ? BigInt(collapsed) : null;
133128
+ }
133129
+ function normalizeRevisionIdsForWordExport(parts, excludedPartUris) {
133130
+ if (![...parts.values()].some((xml) => /\d{10,}|&#/.test(xml)))
133131
+ return new Map;
133132
+ const reserved = new Set;
133133
+ const edits = [];
133134
+ const errors4 = [];
133135
+ for (const [partUri, xml] of [...parts].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
133136
+ const result = walkXmlElements(xml, {
133137
+ onOpenTag: ({ tag, start, end, namespaceBindings }) => {
133138
+ for (const attribute2 of tag.attributes) {
133139
+ if (attribute2.localName !== "id")
133140
+ continue;
133141
+ const value2 = integer2(attribute2.value);
133142
+ if (value2 !== null && value2 >= MIN_WORD_ID && value2 <= MAX_WORD_ID)
133143
+ reserved.add(value2);
133144
+ }
133145
+ const wordElement = tag.namespaceUri === NS_W || tag.namespaceUri === NS_WSTRICT;
133146
+ if (!(wordElement && WORD_CARRIERS.has(tag.localName)) && !(tag.namespaceUri === NS_W14 && EXTENDED_CARRIERS.has(tag.localName)))
133147
+ return;
133148
+ const attribute = tag.attributes.find((a) => a.localName === "id" && (a.namespaceUri === NS_W || a.namespaceUri === NS_WSTRICT));
133149
+ if (!attribute)
133150
+ return;
133151
+ const value = integer2(attribute.value);
133152
+ if (value === null || value >= MIN_WORD_ID && value <= MAX_WORD_ID)
133153
+ return;
133154
+ const raw = [...scanRawXmlAttributes(xml.slice(start, end))].find((a) => a.name === attribute.name);
133155
+ if (!raw)
133156
+ throw new Error("Revision ID source value could not be located.");
133157
+ const word = (name) => tag.attributes.find((a) => a.localName === name && (a.namespaceUri === NS_W || a.namespaceUri === NS_WSTRICT))?.value ?? "";
133158
+ edits.push({
133159
+ partUri,
133160
+ start: start + raw.valueStart,
133161
+ end: start + raw.valueEnd,
133162
+ integer: value,
133163
+ originalValue: raw.value,
133164
+ tagStart: start,
133165
+ tagEnd: end,
133166
+ namespaceBindings,
133167
+ namespaceUri: tag.namespaceUri,
133168
+ kind: tag.localName,
133169
+ author: word("author"),
133170
+ date: word("date")
133171
+ });
133172
+ }
133173
+ });
133174
+ errors4.push(...result.errors);
133175
+ }
133176
+ if (!edits.length)
133177
+ return new Map;
133178
+ if (excludedPartUris?.size)
133179
+ throw new RevisionIdExportCoverageError([...excludedPartUris].sort()[0]);
133180
+ if (errors4.length)
133181
+ throw new Error("Revision ID normalization cannot certify malformed Word XML.");
133182
+ const mapping = new Map;
133183
+ let candidate = 0n;
133184
+ for (const edit of edits) {
133185
+ if (mapping.has(edit.integer))
133186
+ continue;
133187
+ while (reserved.has(candidate) && candidate <= MAX_WORD_ID)
133188
+ candidate += 1n;
133189
+ if (candidate > MAX_WORD_ID)
133190
+ throw new Error("No unused Word revision ID remains.");
133191
+ mapping.set(edit.integer, String(candidate));
133192
+ reserved.add(candidate);
133193
+ }
133194
+ const byPart = new Map;
133195
+ for (const edit of edits) {
133196
+ const list = byPart.get(edit.partUri) ?? [];
133197
+ list.push(edit);
133198
+ byPart.set(edit.partUri, list);
133199
+ }
133200
+ const output = new Map;
133201
+ for (const [partUri, replacements] of byPart) {
133202
+ let xml = parts.get(partUri);
133203
+ for (const edit of replacements.sort((a, b) => b.start - a.start)) {
133204
+ const portable = mapping.get(edit.integer);
133205
+ let openTag = xml.slice(edit.tagStart, edit.start) + portable + xml.slice(edit.end, edit.tagEnd);
133206
+ const staleMetadata = [...scanRawXmlAttributes(openTag)].filter((a) => edit.namespaceBindings[a.prefix] === REVISION_IDENTITY_NAMESPACE && (a.localName === "id" || a.localName === "binding" || a.localName === "lexical"));
133207
+ for (const attribute of staleMetadata.sort((a, b) => b.sourceStart - a.sourceStart)) {
133208
+ openTag = openTag.slice(0, attribute.sourceStart) + openTag.slice(attribute.sourceEnd);
133209
+ }
133210
+ const availablePrefix = (seed) => {
133211
+ let prefix2 = seed;
133212
+ for (let index = 1;edit.namespaceBindings[prefix2]; index += 1)
133213
+ prefix2 = `${seed}${index}`;
133214
+ return prefix2;
133215
+ };
133216
+ const prefix = availablePrefix("sdRevision"), mc = availablePrefix("sdRevisionMc");
133217
+ const selfClosing = openTag.endsWith("/>");
133218
+ if (selfClosing)
133219
+ openTag = openTag.slice(0, -2) + ">";
133220
+ openTag = appendXmlIgnorablePrefix(openTag, edit.namespaceBindings, prefix, mc);
133221
+ const binding = revisionIdentityBinding(partUri, edit.namespaceUri, edit.kind, portable, edit.originalValue, edit.author, edit.date);
133222
+ const escapedOriginal = edit.originalValue.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/\t/g, "&#9;").replace(/\r/g, "&#13;").replace(/\n/g, "&#10;");
133223
+ const lexical = edit.originalValue === String(edit.integer) ? "" : ` ${prefix}:lexical="${escapedOriginal}"`;
133224
+ openTag = openTag.slice(0, -1) + ` xmlns:${prefix}="${REVISION_IDENTITY_NAMESPACE}" ${prefix}:id="${edit.integer}"${lexical} ${prefix}:binding="${binding}"${selfClosing ? "/>" : ">"}`;
133225
+ xml = xml.slice(0, edit.tagStart) + openTag + xml.slice(edit.tagEnd);
133226
+ }
133227
+ output.set(partUri, xml);
133228
+ }
133229
+ return output;
133230
+ }
133231
+ var MIN_WORD_ID, MAX_WORD_ID = 2147483647n, WORD_CARRIERS, EXTENDED_CARRIERS, RevisionIdExportCoverageError;
133232
+ var init_revision_id_export = __esm(() => {
133233
+ init_xml_sax();
133234
+ init_xml_ignorable();
133235
+ init_revision_id_identity();
133236
+ MIN_WORD_ID = -2147483648n;
133237
+ WORD_CARRIERS = new Set([
133238
+ "ins",
133239
+ "del",
133240
+ "moveFrom",
133241
+ "moveTo",
133242
+ "cellIns",
133243
+ "cellDel",
133244
+ "cellMerge",
133245
+ "rPrChange",
133246
+ "pPrChange",
133247
+ "tblPrChange",
133248
+ "tblPrExChange",
133249
+ "tblGridChange",
133250
+ "trPrChange",
133251
+ "tcPrChange",
133252
+ "sectPrChange",
133253
+ "sdtPrChange",
133254
+ "numberingChange",
133255
+ "moveFromRangeStart",
133256
+ "moveFromRangeEnd",
133257
+ "moveToRangeStart",
133258
+ "moveToRangeEnd",
133259
+ "customXmlInsRangeStart",
133260
+ "customXmlInsRangeEnd",
133261
+ "customXmlDelRangeStart",
133262
+ "customXmlDelRangeEnd",
133263
+ "customXmlMoveFromRangeStart",
133264
+ "customXmlMoveFromRangeEnd",
133265
+ "customXmlMoveToRangeStart",
133266
+ "customXmlMoveToRangeEnd"
133267
+ ]);
133268
+ EXTENDED_CARRIERS = new Set([
133269
+ "conflictIns",
133270
+ "conflictDel",
133271
+ "customXmlConflictInsRangeStart",
133272
+ "customXmlConflictInsRangeEnd",
133273
+ "customXmlConflictDelRangeStart",
133274
+ "customXmlConflictDelRangeEnd"
133275
+ ]);
133276
+ RevisionIdExportCoverageError = class RevisionIdExportCoverageError extends Error {
133277
+ constructor(partUri) {
133278
+ super("Normalizing revision IDs requires the complete package ID inventory.");
133279
+ this.partUri = partUri;
133280
+ this.name = "RevisionIdExportCoverageError";
133281
+ }
133282
+ };
133283
+ });
133284
+
132858
133285
  // ../../../v2/editor-core/dist/document/transactions/tracked-changes/pairing-markers.js
132859
133286
  function containsOnlyAllowedPairingMarkers(xml) {
132860
133287
  let remaining = xml.replace(/<!--[\s\S]*?-->/g, "").replace(/<\?xml[\s\S]*?\?>/g, "");
@@ -134626,77 +135053,6 @@ var init_native_sdt_groups = __esm(() => {
134626
135053
  MATERIAL_LEAVES = new Set(["t", "delText", "instrText", "delInstrText", "tab", "br", "cr", "drawing", "pict", "object", "fldChar", "footnoteReference", "endnoteReference", "sym"]);
134627
135054
  });
134628
135055
 
134629
- // ../../../v2/editor-core/dist/document/internal/xml-text.js
134630
- function decodeXmlText(text) {
134631
- return decodeXmlTextEntities(text, false);
134632
- }
134633
- function decodeXmlTextPreservingInvalidNumericEntities(text) {
134634
- return decodeXmlTextEntities(text, true);
134635
- }
134636
- function decodeXmlTextEntities(text, preserveInvalidNumericEntities) {
134637
- return text.replace(ENTITY_RE, (_, entity) => {
134638
- switch (entity) {
134639
- case "lt":
134640
- return "<";
134641
- case "gt":
134642
- return ">";
134643
- case "amp":
134644
- return "&";
134645
- case "quot":
134646
- return '"';
134647
- case "apos":
134648
- return "'";
134649
- default: {
134650
- const cp = entity.startsWith("#x") ? Number.parseInt(entity.slice(2), 16) : Number.parseInt(entity.slice(1), 10);
134651
- if (!Number.isFinite(cp))
134652
- return `&${entity};`;
134653
- if (preserveInvalidNumericEntities && (cp <= 0 || cp > 1114111 || cp >= 55296 && cp <= 57343))
134654
- return `&${entity};`;
134655
- return String.fromCodePoint(cp);
134656
- }
134657
- }
134658
- });
134659
- }
134660
- function decodeXmlAttributeValue(value) {
134661
- return decodeXmlText(value.replace(/[\t\n\r]/g, " "));
134662
- }
134663
- function semanticXmlAttributeValueSpace(value) {
134664
- return value.replace(/[\t\n\r]/g, " ");
134665
- }
134666
- function escapeXmlText(text) {
134667
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
134668
- }
134669
- function escapedXmlTextCodePointUtf8Width(codePoint) {
134670
- if (codePoint === 38)
134671
- return 5;
134672
- if (codePoint === 60 || codePoint === 62)
134673
- return 4;
134674
- if (codePoint <= 127)
134675
- return 1;
134676
- if (codePoint <= 2047)
134677
- return 2;
134678
- if (codePoint <= 65535)
134679
- return 3;
134680
- return 4;
134681
- }
134682
- function escapeXmlAttribute(text) {
134683
- return escapeXmlText(text).replace(/"/g, "&quot;").replace(/'/g, "&apos;");
134684
- }
134685
- function needsXmlSpacePreserve(text) {
134686
- return /^\s|\s$/.test(text);
134687
- }
134688
- function isUtf16Boundary(text, offset) {
134689
- if (offset <= 0 || offset >= text.length)
134690
- return true;
134691
- const previous = text.charCodeAt(offset - 1);
134692
- const next = text.charCodeAt(offset);
134693
- return !(previous >= 55296 && previous <= 56319 && next >= 56320 && next <= 57343);
134694
- }
134695
- var ENTITY_RE;
134696
- var init_xml_text = __esm(() => {
134697
- ENTITY_RE = /&(lt|gt|amp|quot|apos|#\d+|#x[0-9a-fA-F]+);/g;
134698
- });
134699
-
134700
135056
  // ../../../v2/editor-core/dist/document/internal/tracked-change-email.js
134701
135057
  function serializeTrackedChangeEmail(email3, wordPrefix, protectedXml = "") {
134702
135058
  if (!email3)
@@ -138817,129 +139173,6 @@ var init_paragraph_index = __esm(() => {
138817
139173
  _SDCompactParagraphRecordStore_storyIds = new WeakMap, _SDCompactParagraphRecordStore_storyRevisions = new WeakMap, _SDCompactParagraphRecordStore_partUris = new WeakMap, _SDCompactParagraphRecordStore_partRevisions = new WeakMap, _SDCompactParagraphRecordStore_blockIds = new WeakMap, _SDCompactParagraphRecordStore_baseTextStarts = new WeakMap, _SDCompactParagraphRecordStore_baseByteStarts = new WeakMap, _SDCompactParagraphRecordStore_baseByteEnds = new WeakMap, _SDCompactParagraphRecordStore_textLengths = new WeakMap, _SDCompactParagraphRecordStore_directBodyChildOrdinals = new WeakMap, _SDCompactParagraphRecordStore_containingBodyChildOrdinals = new WeakMap, _SDCompactParagraphRecordStore_flags = new WeakMap, _SDCompactParagraphRecordStore_stringPayloadBytes = new WeakMap, _SDCompactParagraphRecordStore_generation = new WeakMap;
138818
139174
  });
138819
139175
 
138820
- // ../../../v2/editor-core/dist/util/sha256-sync.js
138821
- function rightRotate(value, amount) {
138822
- return value >>> amount | value << 32 - amount;
138823
- }
138824
- function sha256HexSync(bytes) {
138825
- const bitLength = BigInt(bytes.length) * 8n;
138826
- const paddedLength = Math.ceil((bytes.length + 1 + 8) / 64) * 64;
138827
- const padded = new Uint8Array(paddedLength);
138828
- padded.set(bytes);
138829
- padded[bytes.length] = 128;
138830
- const paddedView = new DataView(padded.buffer);
138831
- paddedView.setUint32(paddedLength - 8, Number(bitLength >> 32n & 0xffffffffn));
138832
- paddedView.setUint32(paddedLength - 4, Number(bitLength & 0xffffffffn));
138833
- const hash2 = [...INITIAL_HASH];
138834
- const words = new Uint32Array(64);
138835
- for (let offset = 0;offset < paddedLength; offset += 64) {
138836
- for (let index = 0;index < 16; index += 1) {
138837
- words[index] = paddedView.getUint32(offset + index * 4);
138838
- }
138839
- for (let index = 16;index < 64; index += 1) {
138840
- const s0 = rightRotate(words[index - 15], 7) ^ rightRotate(words[index - 15], 18) ^ words[index - 15] >>> 3;
138841
- const s1 = rightRotate(words[index - 2], 17) ^ rightRotate(words[index - 2], 19) ^ words[index - 2] >>> 10;
138842
- words[index] = words[index - 16] + s0 + words[index - 7] + s1 >>> 0;
138843
- }
138844
- let [a, b, c, d, e, f, g, h] = hash2;
138845
- for (let index = 0;index < 64; index += 1) {
138846
- const s1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
138847
- const ch = e & f ^ ~e & g;
138848
- const temp1 = h + s1 + ch + ROUND_CONSTANTS[index] + words[index] >>> 0;
138849
- const s0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
138850
- const maj = a & b ^ a & c ^ b & c;
138851
- const temp2 = s0 + maj >>> 0;
138852
- h = g;
138853
- g = f;
138854
- f = e;
138855
- e = d + temp1 >>> 0;
138856
- d = c;
138857
- c = b;
138858
- b = a;
138859
- a = temp1 + temp2 >>> 0;
138860
- }
138861
- hash2[0] = hash2[0] + a >>> 0;
138862
- hash2[1] = hash2[1] + b >>> 0;
138863
- hash2[2] = hash2[2] + c >>> 0;
138864
- hash2[3] = hash2[3] + d >>> 0;
138865
- hash2[4] = hash2[4] + e >>> 0;
138866
- hash2[5] = hash2[5] + f >>> 0;
138867
- hash2[6] = hash2[6] + g >>> 0;
138868
- hash2[7] = hash2[7] + h >>> 0;
138869
- }
138870
- return hash2.map((value) => value.toString(16).padStart(8, "0")).join("");
138871
- }
138872
- var INITIAL_HASH, ROUND_CONSTANTS;
138873
- var init_sha256_sync = __esm(() => {
138874
- INITIAL_HASH = [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225];
138875
- ROUND_CONSTANTS = [
138876
- 1116352408,
138877
- 1899447441,
138878
- 3049323471,
138879
- 3921009573,
138880
- 961987163,
138881
- 1508970993,
138882
- 2453635748,
138883
- 2870763221,
138884
- 3624381080,
138885
- 310598401,
138886
- 607225278,
138887
- 1426881987,
138888
- 1925078388,
138889
- 2162078206,
138890
- 2614888103,
138891
- 3248222580,
138892
- 3835390401,
138893
- 4022224774,
138894
- 264347078,
138895
- 604807628,
138896
- 770255983,
138897
- 1249150122,
138898
- 1555081692,
138899
- 1996064986,
138900
- 2554220882,
138901
- 2821834349,
138902
- 2952996808,
138903
- 3210313671,
138904
- 3336571891,
138905
- 3584528711,
138906
- 113926993,
138907
- 338241895,
138908
- 666307205,
138909
- 773529912,
138910
- 1294757372,
138911
- 1396182291,
138912
- 1695183700,
138913
- 1986661051,
138914
- 2177026350,
138915
- 2456956037,
138916
- 2730485921,
138917
- 2820302411,
138918
- 3259730800,
138919
- 3345764771,
138920
- 3516065817,
138921
- 3600352804,
138922
- 4094571909,
138923
- 275423344,
138924
- 430227734,
138925
- 506948616,
138926
- 659060556,
138927
- 883997877,
138928
- 958139571,
138929
- 1322822218,
138930
- 1537002063,
138931
- 1747873779,
138932
- 1955562222,
138933
- 2024104815,
138934
- 2227730452,
138935
- 2361852424,
138936
- 2428436474,
138937
- 2756734187,
138938
- 3204031479,
138939
- 3329325298
138940
- ];
138941
- });
138942
-
138943
139176
  // ../../../v2/editor-core/dist/document/transactions/patch-substrate.js
138944
139177
  function normalizePartPatches(patches) {
138945
139178
  const sorted = [...patches].sort((a, b) => startOf(a) - startOf(b) || a.order - b.order);
@@ -168927,6 +169160,161 @@ var init_field_paragraph_range_deletion_groups = __esm(() => {
168927
169160
  init_logical_catalog();
168928
169161
  });
168929
169162
 
169163
+ // ../../../v2/editor-core/dist/document/transactions/tracked-changes/row-height-review-geometry.js
169164
+ function readRowHeightReviewCohorts(xml, options = {}) {
169165
+ if (!["tblGridChange", "trPrChange", "tcPrChange"].every((name) => xml.includes(name)))
169166
+ return [];
169167
+ const parsed = collectXmlElementRanges(xml, { additionalNamespaces: options.additionalNamespaces });
169168
+ if (parsed.errors.length)
169169
+ return [];
169170
+ const ranges = [...parsed.ranges].sort((a, b) => a.start - b.start || b.end - a.end);
169171
+ const parents = new Map;
169172
+ const children = new Map;
169173
+ const stack = [];
169174
+ for (const range of ranges) {
169175
+ while (stack.length && range.start >= stack.at(-1).end)
169176
+ stack.pop();
169177
+ const parent = stack.at(-1);
169178
+ if (parent) {
169179
+ parents.set(range, parent);
169180
+ const list = children.get(parent) ?? [];
169181
+ list.push(range);
169182
+ children.set(parent, list);
169183
+ }
169184
+ if (!range.tag.isSelfClosing)
169185
+ stack.push(range);
169186
+ }
169187
+ const direct = (range, name) => (children.get(range) ?? []).filter((child) => word2(child, name));
169188
+ const ancestor = (range, name) => {
169189
+ let parent = parents.get(range);
169190
+ while (parent) {
169191
+ if (word2(parent, name))
169192
+ return parent;
169193
+ parent = parents.get(parent);
169194
+ }
169195
+ return;
169196
+ };
169197
+ const inSnapshot = (range) => {
169198
+ let parent = parents.get(range);
169199
+ while (parent) {
169200
+ if (word2(parent) && parent.tag.localName.endsWith("Change"))
169201
+ return true;
169202
+ parent = parents.get(parent);
169203
+ }
169204
+ return false;
169205
+ };
169206
+ const signature2 = (range, omit2 = new Set) => {
169207
+ const attributes = range.tag.attributes.filter((attribute) => attribute.namespaceUri !== "http://www.w3.org/2000/xmlns/").map((attribute) => [attribute.namespaceUri, attribute.localName, attribute.value]).sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
169208
+ const content = [];
169209
+ let cursor = range.openEnd;
169210
+ for (const child of children.get(range) ?? []) {
169211
+ const text = xml.slice(cursor, child.start);
169212
+ if (text.trim())
169213
+ content.push(text);
169214
+ if (!omit2.has(child))
169215
+ content.push(signature2(child, omit2));
169216
+ cursor = child.end;
169217
+ }
169218
+ const tail = xml.slice(cursor, range.closeStart);
169219
+ if (tail.trim())
169220
+ content.push(tail);
169221
+ return JSON.stringify([range.tag.namespaceUri, range.tag.localName, attributes, content]);
169222
+ };
169223
+ const snapshot = (change, name) => {
169224
+ const inner = children.get(change) ?? [];
169225
+ return inner.length === 1 && word2(inner[0], name) ? inner[0] : undefined;
169226
+ };
169227
+ const identity = (change) => buildReviewIdentity({ name: attr2(change, "author"), initials: attr2(change, "initials") });
169228
+ const cohorts = [];
169229
+ for (const table of ranges.filter((range) => word2(range, "tbl") && !inSnapshot(range))) {
169230
+ const grids = direct(table, "tblGrid");
169231
+ if (grids.length !== 1)
169232
+ continue;
169233
+ const grid = grids[0], gridChanges = direct(grid, "tblGridChange");
169234
+ if (gridChanges.length !== 1)
169235
+ continue;
169236
+ const gridChange = gridChanges[0], oldGrid = snapshot(gridChange, "tblGrid");
169237
+ if (!oldGrid || signature2(grid, new Set([gridChange])) !== signature2(oldGrid))
169238
+ continue;
169239
+ const rows = ranges.filter((range) => word2(range, "tr") && ancestor(range, "tbl") === table && !inSnapshot(range));
169240
+ const rowChanges = [], cellChanges = [];
169241
+ let actor;
169242
+ let material = false, valid = true;
169243
+ const acceptActor = (change) => {
169244
+ const next = identity(change);
169245
+ if (!next.hasName || actor && (!isSameReviewGroupIdentity(actor, next) || actor.initials !== next.initials))
169246
+ return false;
169247
+ actor ?? (actor = next);
169248
+ return true;
169249
+ };
169250
+ for (const row of rows) {
169251
+ const properties2 = direct(row, "trPr");
169252
+ const property = properties2[0];
169253
+ if (properties2.length > 1) {
169254
+ valid = false;
169255
+ break;
169256
+ }
169257
+ const changes = property ? direct(property, "trPrChange") : [];
169258
+ if (!changes.length)
169259
+ continue;
169260
+ const change = changes[0], before = snapshot(change, "trPr");
169261
+ if (changes.length !== 1 || !before || !acceptActor(change)) {
169262
+ valid = false;
169263
+ break;
169264
+ }
169265
+ const currentHeights = direct(property, "trHeight"), oldHeights = direct(before, "trHeight");
169266
+ if (currentHeights.length > 1 || oldHeights.length > 1) {
169267
+ valid = false;
169268
+ break;
169269
+ }
169270
+ const afterOmit = new Set([change, ...currentHeights]), beforeOmit = new Set(oldHeights);
169271
+ if (signature2(property, afterOmit) !== signature2(before, beforeOmit)) {
169272
+ valid = false;
169273
+ break;
169274
+ }
169275
+ const heightSignature = (height) => !height || attr2(height, "hRule") === "auto" ? "auto" : signature2(height);
169276
+ material || (material = heightSignature(currentHeights[0]) !== heightSignature(oldHeights[0]));
169277
+ const cells = ranges.filter((range) => word2(range, "tc") && ancestor(range, "tr") === row && ancestor(range, "tbl") === table && !inSnapshot(range));
169278
+ if (!cells.length) {
169279
+ valid = false;
169280
+ break;
169281
+ }
169282
+ for (const cell of cells) {
169283
+ const cellProperties = direct(cell, "tcPr");
169284
+ if (cellProperties.length !== 1) {
169285
+ valid = false;
169286
+ break;
169287
+ }
169288
+ const cellProperty = cellProperties[0], changes2 = direct(cellProperty, "tcPrChange");
169289
+ const cellChange = changes2[0], beforeCell = cellChange && snapshot(cellChange, "tcPr");
169290
+ if (changes2.length !== 1 || !beforeCell || !acceptActor(cellChange) || signature2(cellProperty, new Set([cellChange])) !== signature2(beforeCell)) {
169291
+ valid = false;
169292
+ break;
169293
+ }
169294
+ cellChanges.push(cellChange);
169295
+ }
169296
+ if (!valid)
169297
+ break;
169298
+ rowChanges.push(change);
169299
+ }
169300
+ if (!valid || !actor || !rowChanges.length || !material && !options.allowAllNoop)
169301
+ continue;
169302
+ const owned = new Set([gridChange, ...rowChanges, ...cellChanges]);
169303
+ const ids = [...owned].map((change) => attr2(change, "id")?.trim());
169304
+ if (ids.some((id) => id === undefined || !/^[+-]?\d+$/.test(id)) || new Set(ids.map((id) => BigInt(id).toString())).size !== owned.size)
169305
+ continue;
169306
+ const otherProperties = ranges.some((range) => word2(range) && (["tblPrChange", "tblPrExChange", "tblGridChange", "trPrChange", "tcPrChange"].includes(range.tag.localName) || ["ins", "del", "cellIns", "cellDel", "cellMerge"].includes(range.tag.localName) && ["trPr", "tcPr"].some((name) => parents.get(range) && word2(parents.get(range), name))) && ancestor(range, "tbl") === table && !inSnapshot(range) && !owned.has(range));
169307
+ if (otherProperties)
169308
+ continue;
169309
+ cohorts.push({ table, grid, gridChange, rowChanges, cellChanges, author: actor.name, initials: actor.initials, material });
169310
+ }
169311
+ return cohorts;
169312
+ }
169313
+ var word2 = (range, name) => (range.tag.namespaceUri === NS_W || range.tag.namespaceUri === NS_WSTRICT) && (name === undefined || range.tag.localName === name), attr2 = (range, name) => range.tag.attributes.find((attribute) => (attribute.namespaceUri === NS_W || attribute.namespaceUri === NS_WSTRICT) && attribute.localName === name)?.value;
169314
+ var init_row_height_review_geometry = __esm(() => {
169315
+ init_xml_sax();
169316
+ });
169317
+
168930
169318
  // ../../../v2/editor-core/dist/document/transactions/tracked-changes/image-paragraph-deletion-groups.js
168931
169319
  function projectDeletedImageParagraphGroups(input) {
168932
169320
  for (const [storyId, entries] of input.byStory) {
@@ -170692,6 +171080,17 @@ function projectStoryTableFormattingGroups(lookupContext, storyId, entries, inpu
170692
171080
  }
170693
171081
  if (candidates.length < 2)
170694
171082
  return;
171083
+ for (const cohort of readRowHeightReviewCohorts(partXml)) {
171084
+ const grid = candidates.find((candidate2) => candidate2.fragment.byteStart === cohort.gridChange.start);
171085
+ const starts = new Set([...cohort.rowChanges, ...cohort.cellChanges].map((change) => change.start));
171086
+ const members = candidates.filter((candidate2) => starts.has(candidate2.fragment.byteStart));
171087
+ const head = members[0];
171088
+ if (!grid || !head || members.length !== starts.size || members.some((member) => !isSameReviewGroupIdentity(head.identity, member.identity) || buildGroupIdentityKey(head.identity) !== buildGroupIdentityKey(member.identity) || head.initials !== member.initials))
171089
+ continue;
171090
+ grid.identity = head.identity;
171091
+ grid.initials = head.initials;
171092
+ grid.dependencyGrid = true;
171093
+ }
170695
171094
  const grouped = new Map;
170696
171095
  for (const candidate2 of candidates) {
170697
171096
  const key2 = [
@@ -170714,7 +171113,7 @@ function materializeTableFormattingGroup(storyId, partUri, partXml, run, input)
170714
171113
  const childEntries = run.map((member) => member.entry);
170715
171114
  if (childEntries.some((entry) => entry.reviewGroup))
170716
171115
  return;
170717
- const head = run[0];
171116
+ const head = run.find((member) => !member.dependencyGrid) ?? run[0];
170718
171117
  const carrierOrdinals = run.map((member) => member.carrierOrdinal).sort((a, b) => a - b);
170719
171118
  const tableParaId = findFirstParagraphIdInRange(partXml, head.table.start, head.table.end);
170720
171119
  const groupKeyBody = tableParaId ? `tbl:p:${tableParaId}|id:${buildGroupIdentityKey(head.identity)}|ini:${head.initials ?? ""}` : `to:${carrierOrdinals.join(",")}`;
@@ -171100,12 +171499,12 @@ function parsePropertyChildElements(innerXml) {
171100
171499
  }
171101
171500
  const attrs = new Map;
171102
171501
  const attrRe = /([\w.-]+):([\w.-]+)="([^"]*)"/g;
171103
- let attr2;
171104
- while (attr2 = attrRe.exec(match[4] ?? "")) {
171105
- const attrLocal2 = attr2[2];
171502
+ let attr3;
171503
+ while (attr3 = attrRe.exec(match[4] ?? "")) {
171504
+ const attrLocal2 = attr3[2];
171106
171505
  if (attrLocal2.startsWith("rsid"))
171107
171506
  continue;
171108
- attrs.set(attrLocal2, attr2[3] ?? "");
171507
+ attrs.set(attrLocal2, attr3[3] ?? "");
171109
171508
  }
171110
171509
  const element = { localName: localName2, attrs, children: [] };
171111
171510
  (stack.length > 0 ? stack[stack.length - 1].children : roots).push(element);
@@ -171715,22 +172114,10 @@ var init_review_groups = __esm(() => {
171715
172114
  init_field_paragraph_deletion_groups();
171716
172115
  init_bookmark_revision_groups();
171717
172116
  init_field_paragraph_range_deletion_groups();
172117
+ init_row_height_review_geometry();
171718
172118
  init_image_paragraph_deletion_groups();
171719
172119
  });
171720
172120
 
171721
- // ../../../v2/editor-core/dist/document/internal/xml-ignorable.js
171722
- function appendXmlIgnorablePrefix(openTag, namespaceBindings, prefix, mcPrefix) {
171723
- for (const attribute of scanRawXmlAttributes(openTag)) {
171724
- if (attribute.localName === "Ignorable" && attribute.prefix && namespaceBindings[attribute.prefix] === NS_MC) {
171725
- return openTag.slice(0, attribute.valueEnd) + ` ${prefix}` + openTag.slice(attribute.valueEnd);
171726
- }
171727
- }
171728
- return openTag.slice(0, -1) + ` xmlns:${mcPrefix}="${NS_MC}" ${mcPrefix}:Ignorable="${prefix}">`;
171729
- }
171730
- var init_xml_ignorable = __esm(() => {
171731
- init_xml_sax();
171732
- });
171733
-
171734
172121
  // ../../../v2/editor-core/dist/document/transactions/tracked-changes/rewrite-groups.js
171735
172122
  function readRewriteGroupId(carrier) {
171736
172123
  const values = carrier.customAttributes?.filter((attribute) => attribute.namespaceUri === REWRITE_NAMESPACE && attribute.localName === "id");
@@ -175036,7 +175423,7 @@ function resolveMoveRangeMarkersForFragment(lookupContext, fragment3, partXml, m
175036
175423
  return bounds.startAfter <= fragment3.byteStart && bounds.endBefore >= fragment3.byteEnd;
175037
175424
  });
175038
175425
  if (containing.length === 1) {
175039
- matched.push({ id: containing[0].id, name: containing[0].name });
175426
+ matched.push({ id: containing[0].id, logicalId: containing[0].logicalId, name: containing[0].name });
175040
175427
  }
175041
175428
  }
175042
175429
  matched.sort((a, b) => a.id.localeCompare(b.id));
@@ -175212,7 +175599,7 @@ function isSameRevisionFragment(head, candidate2, headNoteId, candidateNoteId) {
175212
175599
  return false;
175213
175600
  if (headNoteId !== candidateNoteId)
175214
175601
  return false;
175215
- if (!head.wId || revisionWIdIdentity(head.wId) !== revisionWIdIdentity(candidate2.wId))
175602
+ if (!head.wId || revisionWIdIdentity(logicalRevisionWId(head)) !== revisionWIdIdentity(logicalRevisionWId(candidate2)))
175216
175603
  return false;
175217
175604
  if ((head.author.name || "") !== (candidate2.author.name || ""))
175218
175605
  return false;
@@ -175352,8 +175739,9 @@ function buildCoalescedSameRevisionLogical(lookupContext, fragments, noteId, par
175352
175739
  wordIdOther: extraWordIds,
175353
175740
  rsids
175354
175741
  };
175355
- if (contributingWordIds.length > 1) {
175356
- const coalescedId = buildLogicalId(head.storyId, head.kind, groupKind, ...contributingWordIds);
175742
+ const identityWordIds = [...new Set(fragments.map(logicalRevisionWId).filter(Boolean))].sort();
175743
+ if (identityWordIds.length > 1) {
175744
+ const coalescedId = buildLogicalId(head.storyId, head.kind, groupKind, ...identityWordIds);
175357
175745
  mutable.id = coalescedId;
175358
175746
  mutable.revisionGroupId = coalescedId;
175359
175747
  }
@@ -175766,8 +176154,8 @@ function isGeneratedMoveApproximationPair(del, ins, partXml, splitLineage) {
175766
176154
  return false;
175767
176155
  if (splitLineage?.has(del.rsid) || splitLineage?.has(ins.rsid))
175768
176156
  return false;
175769
- const delId = numericWordId(del.wId);
175770
- const insId = numericWordId(ins.wId);
176157
+ const delId = numericWordId(logicalRevisionWId(del));
176158
+ const insId = numericWordId(logicalRevisionWId(ins));
175771
176159
  if (delId != null && insId != null && insId - delId >= 100)
175772
176160
  return true;
175773
176161
  const delDrawing = extractFirstDrawingXml(extractTrackedWrapperInnerXml(partXml.slice(del.byteStart, del.byteEnd), "del") ?? "");
@@ -175780,8 +176168,8 @@ function numericWordId(value) {
175780
176168
  return Number(value);
175781
176169
  }
175782
176170
  function deriveGeneratedMoveApproximationPairId(source, destination) {
175783
- const left = source.wId || source.rsid;
175784
- const right = destination.wId || destination.rsid;
176171
+ const left = logicalRevisionWId(source) || source.rsid;
176172
+ const right = logicalRevisionWId(destination) || destination.rsid;
175785
176173
  return `${left}|${right}`;
175786
176174
  }
175787
176175
  function publicMoveSourceIdsRsids(source, destination) {
@@ -176063,8 +176451,10 @@ function paragraphCarriesSoleInlineImage(paragraphXml) {
176063
176451
  return !/<[\w.-]+:t\b[^>]*>[\s\S]*?<\/[\w.-]+:t>/.test(withoutDrawingRuns);
176064
176452
  }
176065
176453
  function derivePairId(source, destination, sourceMoveRangeMarkers, destinationMoveRangeMarkers) {
176066
- const sourceMoveRangeIds = sourceMoveRangeMarkers.map((marker) => marker.id);
176067
- const destinationMoveRangeIds = destinationMoveRangeMarkers.map((marker) => marker.id);
176454
+ sourceMoveRangeMarkers = sourceMoveRangeMarkers.filter((marker) => marker.logicalId !== null);
176455
+ destinationMoveRangeMarkers = destinationMoveRangeMarkers.filter((marker) => marker.logicalId !== null);
176456
+ const sourceMoveRangeIds = sourceMoveRangeMarkers.map((marker) => marker.logicalId ?? marker.id);
176457
+ const destinationMoveRangeIds = destinationMoveRangeMarkers.map((marker) => marker.logicalId ?? marker.id);
176068
176458
  const sharedMoveRangeId = firstSharedMoveRangeId(sourceMoveRangeIds, destinationMoveRangeIds);
176069
176459
  if (sharedMoveRangeId) {
176070
176460
  return sharedMoveRangeId;
@@ -176073,11 +176463,11 @@ function derivePairId(source, destination, sourceMoveRangeMarkers, destinationMo
176073
176463
  if (sharedMoveRangeName) {
176074
176464
  return sharedMoveRangeName;
176075
176465
  }
176076
- if (source.wId && destination.wId && source.wId === destination.wId) {
176077
- return source.wId;
176466
+ if (source.wId && destination.wId && logicalRevisionWId(source) === logicalRevisionWId(destination)) {
176467
+ return logicalRevisionWId(source);
176078
176468
  }
176079
- const left = source.wId || source.rsid;
176080
- const right = destination.wId || destination.rsid;
176469
+ const left = logicalRevisionWId(source) || source.rsid;
176470
+ const right = logicalRevisionWId(destination) || destination.rsid;
176081
176471
  return `${left}|${right}`;
176082
176472
  }
176083
176473
  function buildImagePairLogical(del, ins, noteId, partXml) {
@@ -176252,10 +176642,10 @@ function buildPairedImageMoveLogical(deleteEntityKey, a, insertEntityKey, b, not
176252
176642
  };
176253
176643
  }
176254
176644
  function deriveStructuralMovePairId(source, destination, sourceKey, destinationKey) {
176255
- if (source.wId && destination.wId && source.wId === destination.wId)
176256
- return source.wId;
176257
- const left = source.wId || sourceKey;
176258
- const right = destination.wId || destinationKey;
176645
+ if (source.wId && destination.wId && logicalRevisionWId(source) === logicalRevisionWId(destination))
176646
+ return logicalRevisionWId(source);
176647
+ const left = logicalRevisionWId(source) || sourceKey;
176648
+ const right = logicalRevisionWId(destination) || destinationKey;
176259
176649
  return `${left}|${right}`;
176260
176650
  }
176261
176651
  function buildPairedImageStructuralLogical(deleteEntityKey, a, insertEntityKey, b, noteId, partXml) {
@@ -177712,6 +178102,7 @@ function decodeXmlText4(escaped) {
177712
178102
  }
177713
178103
  var TE5, PARAGRAPH_SEMANTIC_KEYS, LIST_INDENT_KEYS, RUN_SEMANTIC_KEYS, FORMATTING_CARRIER_ELEMENTS, TD22;
177714
178104
  var init_logical_catalog = __esm(() => {
178105
+ init_revision_id_identity();
177715
178106
  init_enclosed_table_groups();
177716
178107
  init_catalog_xml_analysis();
177717
178108
  init_pairing_markers();
@@ -177822,7 +178213,7 @@ function collectMoveRangeNamesFromXml(xml, names) {
177822
178213
  onOpenTag: ({ tag }) => {
177823
178214
  if (tag.namespaceUri !== NS_W || tag.localName !== "moveFromRangeStart" && tag.localName !== "moveToRangeStart")
177824
178215
  return;
177825
- const name = tag.attributes.find((attr2) => attr2.namespaceUri === NS_W && attr2.localName === "name")?.value;
178216
+ const name = tag.attributes.find((attr3) => attr3.namespaceUri === NS_W && attr3.localName === "name")?.value;
177826
178217
  if (name !== undefined)
177827
178218
  names.add(name);
177828
178219
  }
@@ -177890,7 +178281,7 @@ function projectTrackedChangesForExport(state, options) {
177890
178281
  for (const [partUri, xml] of projected) {
177891
178282
  const original = partXmlByUri.get(partUri);
177892
178283
  if (original !== undefined && xml !== original) {
177893
- overrides.set(partUri, ENCODER.encode(xml));
178284
+ overrides.set(partUri, ENCODER2.encode(xml));
177894
178285
  }
177895
178286
  }
177896
178287
  } else {
@@ -177900,10 +178291,24 @@ function projectTrackedChangesForExport(state, options) {
177900
178291
  if (partUri === "/word/document.xml") {
177901
178292
  assertMetadataProjectionPreserved(state, xml, projected, options.mode);
177902
178293
  }
177903
- overrides.set(partUri, ENCODER.encode(projected));
178294
+ overrides.set(partUri, ENCODER2.encode(projected));
177904
178295
  }
177905
178296
  }
177906
178297
  }
178298
+ const effectiveParts = new Map(partXmlByUri);
178299
+ for (const [partUri, bytes] of overrides)
178300
+ effectiveParts.set(partUri, DECODER.decode(bytes));
178301
+ for (const [partUri, xml] of normalizeRevisionIdsForWordExport(effectiveParts, options.excludedPartUris)) {
178302
+ overrides.set(partUri, ENCODER2.encode(xml));
178303
+ warnings.push({
178304
+ code: "revision-id-normalized",
178305
+ message: "Revision IDs outside Word’s integer range were normalized in the exported document. SuperDoc review identities are retained in ignorable metadata.",
178306
+ feature: "trackedChanges",
178307
+ severity: "warning",
178308
+ affectedPartUri: partUri,
178309
+ canProceed: true
178310
+ });
178311
+ }
177907
178312
  return { overrides, warnings };
177908
178313
  }
177909
178314
  function readTrackedChangeCatalogForExport(state, excludedPartUris, baseOverrides) {
@@ -177917,6 +178322,10 @@ function readWordXmlParts(state, baseOverrides) {
177917
178322
  const effectiveBytes = baseOverrides?.get(partUri) ?? bytes;
177918
178323
  parts.set(partUri, DECODER.decode(effectiveBytes));
177919
178324
  }
178325
+ for (const [partUri, bytes] of baseOverrides ?? []) {
178326
+ if (isWordXmlPart(partUri) && !parts.has(partUri))
178327
+ parts.set(partUri, DECODER.decode(bytes));
178328
+ }
177920
178329
  return parts;
177921
178330
  }
177922
178331
  function isWordXmlPart(partUri) {
@@ -178321,15 +178730,16 @@ function convertDeletedTextToVisibleText(xml) {
178321
178730
  function escapeRegExp6(value) {
178322
178731
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
178323
178732
  }
178324
- var DECODER, ENCODER;
178733
+ var DECODER, ENCODER2;
178325
178734
  var init_export_projection = __esm(() => {
178326
178735
  init_xml_sax();
178327
178736
  init_metadata_projection();
178737
+ init_revision_id_export();
178328
178738
  init_catalog3();
178329
178739
  init_logical_catalog();
178330
178740
  init_move_stamps();
178331
178741
  DECODER = new TextDecoder;
178332
- ENCODER = new TextEncoder;
178742
+ ENCODER2 = new TextEncoder;
178333
178743
  });
178334
178744
 
178335
178745
  // ../../../v2/editor-core/dist/document/transactions/word-text-payload.js
@@ -178876,7 +179286,7 @@ function closeTableCellBodyNamespaces(xml, source, destination) {
178876
179286
  let attributes = "";
178877
179287
  for (const [prefix, uri] of Object.entries(source)) {
178878
179288
  const name = prefix ? `xmlns:${prefix}` : "xmlns";
178879
- if (prefix === "xml" || prefix === "xmlns" || destination[prefix] === uri || root.tag.attributes.some((attr2) => attr2.name === name))
179289
+ if (prefix === "xml" || prefix === "xmlns" || destination[prefix] === uri || root.tag.attributes.some((attr3) => attr3.name === name))
178880
179290
  continue;
178881
179291
  attributes += ` ${name}="${escapeXmlAttribute(uri)}"`;
178882
179292
  }
@@ -178947,8 +179357,8 @@ function collectOwnershipElements(xml, namespaceBindings, work) {
178947
179357
  if (work)
178948
179358
  work.visitedElements++;
178949
179359
  const parent = ancestors.at(-1)?.event.tag;
178950
- const word2 = event.tag.namespaceUri === NS_W;
178951
- const retain = parent?.namespaceUri === NS_W && parent.localName === "sdt" || word2 && (["sdt", "sdtContent", "sdtPr", "sdtEndPr", "customXml"].includes(event.tag.localName) || event.tag.localName === "id" && parent?.namespaceUri === NS_W && parent.localName === "sdtPr" || /^customXml(?:Ins|Del|MoveFrom|MoveTo)Range(?:Start|End)$/.test(event.tag.localName));
179360
+ const word3 = event.tag.namespaceUri === NS_W;
179361
+ const retain = parent?.namespaceUri === NS_W && parent.localName === "sdt" || word3 && (["sdt", "sdtContent", "sdtPr", "sdtEndPr", "customXml"].includes(event.tag.localName) || event.tag.localName === "id" && parent?.namespaceUri === NS_W && parent.localName === "sdtPr" || /^customXml(?:Ins|Del|MoveFrom|MoveTo)Range(?:Start|End)$/.test(event.tag.localName));
178952
179362
  if (retain && work)
178953
179363
  work.retainedElements++;
178954
179364
  if (event.tag.isSelfClosing) {
@@ -180345,8 +180755,8 @@ function assembleTrackedChangeParagraphAnalyses(input) {
180345
180755
  fragment3.logicalIdHint = mintTrackedTextLogicalIdHint({
180346
180756
  owners: textOwners,
180347
180757
  kind: fragment3.kind,
180348
- rsid: fragment3.rsid,
180349
- wId: fragment3.wId,
180758
+ rsid: fragment3.logicalRsid ?? fragment3.rsid,
180759
+ wId: logicalRevisionWId(fragment3),
180350
180760
  occurrence: 0,
180351
180761
  author: fragment3.author.name,
180352
180762
  date: fragment3.date,
@@ -180354,7 +180764,7 @@ function assembleTrackedChangeParagraphAnalyses(input) {
180354
180764
  });
180355
180765
  for (const fragment3 of structural) {
180356
180766
  const source = fragment3.sourceMetadata;
180357
- const identity = `${fragment3.structuralKind}|${rawStructuralRevisionIdentityKey({ ...source, wId: fragment3.wId })}`;
180767
+ const identity = `${fragment3.structuralKind}|${rawStructuralRevisionIdentityKey({ ...source, wId: logicalRevisionWId(fragment3) })}`;
180358
180768
  const occurrence = (structuralOccurrences.get(identity) ?? 0) + 1;
180359
180769
  structuralOccurrences.set(identity, occurrence);
180360
180770
  fragment3.identityOccurrence = occurrence;
@@ -180363,7 +180773,7 @@ function assembleTrackedChangeParagraphAnalyses(input) {
180363
180773
  locatorOccurrences.set(identity, locator);
180364
180774
  fragment3.locatorOccurrence = locator;
180365
180775
  }
180366
- fragment3.entityKey = structuralOccurrenceEntityKey(input.storyId, fragment3.structuralKind, { ...source, wId: fragment3.wId }, occurrence);
180776
+ fragment3.entityKey = structuralOccurrenceEntityKey(input.storyId, fragment3.structuralKind, { ...source, wId: logicalRevisionWId(fragment3) }, occurrence);
180367
180777
  }
180368
180778
  return catalogFromScan({
180369
180779
  fragments,
@@ -180433,6 +180843,27 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180433
180843
  const structuralScan = yield* buildElementRangeIndexWork(xml, initialNamespaceBindings, shared?.analysis?.ranges, shared?.analysis ? readTrackedCatalogXmlTopology(shared.analysis, xml) : null);
180434
180844
  endElementIndex();
180435
180845
  const elementIndex = structuralScan.elementIndex;
180846
+ const logicalWIds = yield* readRevisionIdentityAliasesWork(xml, partUri, structuralScan.revisionIdentityElements, structuralScan.namespaceBindingsByTagStart);
180847
+ if (logicalWIds.size) {
180848
+ const aliasesByOpenEnd = new Map;
180849
+ for (const element of structuralScan.revisionIdentityElements) {
180850
+ yield;
180851
+ const alias = logicalWIds.get(element.start);
180852
+ if (alias)
180853
+ aliasesByOpenEnd.set(element.openEnd, alias);
180854
+ }
180855
+ for (const side of [structuralScan.moveRangeMarkers.moveFrom, structuralScan.moveRangeMarkers.moveTo]) {
180856
+ for (const ranges of side.values())
180857
+ for (const range of ranges) {
180858
+ yield;
180859
+ const start = range.startAfter == null ? undefined : aliasesByOpenEnd.get(range.startAfter);
180860
+ const end = range.endBefore == null ? undefined : logicalWIds.get(range.endBefore);
180861
+ if (start && end && canonicalTrackedTextRevisionWId(start) === canonicalTrackedTextRevisionWId(end)) {
180862
+ range.logicalId = parseRevisionWId(normalizeXmlRevisionId(start)) === null ? null : canonicalTrackedTextRevisionWId(start);
180863
+ }
180864
+ }
180865
+ }
180866
+ }
180436
180867
  const wordTrackedMarkupTagStarts = structuralScan.wordTrackedMarkupTagStarts;
180437
180868
  const wordTrackedMarkupTags = structuralScan.wordTrackedMarkupTags;
180438
180869
  const namespaceBindingsByTagStart = structuralScan.namespaceBindingsByTagStart;
@@ -180482,12 +180913,13 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180482
180913
  const pushStructural = (kind, markerStart, markerEnd, attrs, sourceWrapperKind, tagPrefix, enclosing, innerRange, containerMeta) => {
180483
180914
  const namespaceBindings = namespaceBindingsByTagStart.get(markerStart);
180484
180915
  const wId = readNamespacedAttr(attrs, namespaceBindings, "id") ?? "";
180916
+ const logicalWId = logicalWIds.get(markerStart);
180485
180917
  const sourceAuthor = readNamespacedAttr(attrs, namespaceBindings, "author") ?? "";
180486
180918
  const sourceInitials = readNamespacedAttr(attrs, namespaceBindings, "initials");
180487
180919
  const sourceAuthorEmail = readRawTrackedChangeEmail(attrs, namespaceBindings);
180488
180920
  const sourceDate = readNamespacedAttr(attrs, namespaceBindings, "date") ?? "";
180489
180921
  const structuralIdentity = rawStructuralRevisionIdentity({
180490
- wId,
180922
+ wId: logicalWId ?? wId,
180491
180923
  author: sourceAuthor,
180492
180924
  date: sourceDate
180493
180925
  });
@@ -180498,7 +180930,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180498
180930
  date: sourceDate
180499
180931
  });
180500
180932
  const rsid = sourceWrapperKind === "del" ? readNamespacedAttr(attrs, namespaceBindings, "rsidDel") : sourceWrapperKind === "ins" ? readNamespacedAttr(attrs, namespaceBindings, "rsidR") : null;
180501
- const identityOccurrence = nextStructuralIdentityOccurrence(kind, sourceAuthor, sourceDate, wId);
180933
+ const identityOccurrence = nextStructuralIdentityOccurrence(kind, sourceAuthor, sourceDate, logicalWId ?? wId);
180502
180934
  const tableStart = containerMeta?.enclosingTableStart;
180503
180935
  const rowGroupedByTable = tableStart != null && (kind === "row-insertion" || kind === "row-deletion");
180504
180936
  const cellGroupedByTable = wId.length > 0 && tableStart != null && (kind === "cell-insertion" || kind === "cell-deletion" || kind === "cell-merge" || kind === "cell-split");
@@ -180509,7 +180941,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180509
180941
  author: structuralIdentity.author,
180510
180942
  date: structuralIdentity.date,
180511
180943
  tableToken
180512
- }) : cellGroupedByTable ? `struct:${storyId}|${kind}|${structuralIdentity.author}|${structuralIdentity.date}|${structuralIdentity.wId}|tbl:${tableToken}` : structuralOccurrenceEntityKey(storyId, kind, { wId, author: sourceAuthor, date: sourceDate }, identityOccurrence);
180944
+ }) : cellGroupedByTable ? `struct:${storyId}|${kind}|${structuralIdentity.author}|${structuralIdentity.date}|${structuralIdentity.wId}|tbl:${tableToken}` : structuralOccurrenceEntityKey(storyId, kind, { wId: logicalWId ?? wId, author: sourceAuthor, date: sourceDate }, identityOccurrence);
180513
180945
  const fragment3 = {
180514
180946
  entityKey,
180515
180947
  identityOccurrence,
@@ -180522,6 +180954,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180522
180954
  authorEmail,
180523
180955
  date: date6,
180524
180956
  wId,
180957
+ ...logicalWId ? { logicalWId } : {},
180525
180958
  sourceMetadata: {
180526
180959
  author: sourceAuthor,
180527
180960
  initials: sourceInitials,
@@ -180696,6 +181129,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180696
181129
  continue;
180697
181130
  }
180698
181131
  const wId = readNamespacedAttr(wrapperAttrs, namespaceBindings, "id") ?? "";
181132
+ const logicalWId = logicalWIds.get(tag.start);
180699
181133
  const sourceAuthor = readNamespacedAttr(wrapperAttrs, namespaceBindings, "author") ?? "";
180700
181134
  const sourceInitials = readNamespacedAttr(wrapperAttrs, namespaceBindings, "initials");
180701
181135
  const sourceAuthorEmail = readRawTrackedChangeEmail(wrapperAttrs, namespaceBindings);
@@ -180714,7 +181148,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180714
181148
  const subtype = formattingSubtypeForWrapper(wrapperLocal, beforeInnerXml, afterInnerXml, namespaceBindings, namespaceBindingsByTagStart.get(outer.start));
180715
181149
  occurrencesBySubtype[subtype] += 1;
180716
181150
  const occurrenceIndex = occurrencesBySubtype[subtype];
180717
- const entityKey = wId.length > 0 ? buildFormattingRevisionEntityKey({ storyId, subtype, author, date: date6, wId }) : `fmt:${storyId}|${subtype}|${author}|${date6}|#${occurrenceIndex}`;
181151
+ const entityKey = wId.length > 0 ? buildFormattingRevisionEntityKey({ storyId, subtype, author, date: date6, wId: logicalWId ?? wId }) : `fmt:${storyId}|${subtype}|${author}|${date6}|#${occurrenceIndex}`;
180718
181152
  formatting.push({
180719
181153
  entityKey,
180720
181154
  partUri,
@@ -180740,6 +181174,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180740
181174
  authorEmail,
180741
181175
  date: date6,
180742
181176
  wId,
181177
+ ...logicalWId ? { logicalWId } : {},
180743
181178
  sourceMetadata: {
180744
181179
  author: sourceAuthor,
180745
181180
  initials: sourceInitials,
@@ -180816,6 +181251,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180816
181251
  const sourceAuthorEmail2 = readRawTrackedChangeEmail(attrs, namespaceBindings);
180817
181252
  const sourceDate2 = readNamespacedAttr(attrs, namespaceBindings, "date") ?? "";
180818
181253
  const wId2 = readNamespacedAttr(attrs, namespaceBindings, "id") ?? "";
181254
+ const logicalWId2 = logicalWIds.get(byteStart);
180819
181255
  const { author: author2, initials: initials2, authorEmail: authorEmail2, date: date7 } = semanticTrackedChangeMetadata({
180820
181256
  author: sourceAuthor2,
180821
181257
  initials: sourceInitials2,
@@ -180823,9 +181259,9 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180823
181259
  date: sourceDate2
180824
181260
  });
180825
181261
  const rsid2 = kind === "del" ? readNamespacedAttr(attrs, namespaceBindings, "rsidDel") : readNamespacedAttr(attrs, namespaceBindings, "rsidR");
180826
- const identityOccurrence = nextStructuralIdentityOccurrence(structuralKind, sourceAuthor2, sourceDate2, wId2);
181262
+ const identityOccurrence = nextStructuralIdentityOccurrence(structuralKind, sourceAuthor2, sourceDate2, logicalWId2 ?? wId2);
180827
181263
  const locatorOccurrence = nextBlockStructuralLocatorOccurrence(structuralKind, sourceAuthor2, sourceDate2, wId2);
180828
- const entityKey = structuralOccurrenceEntityKey(storyId, structuralKind, { wId: wId2, author: sourceAuthor2, date: sourceDate2 }, identityOccurrence);
181264
+ const entityKey = structuralOccurrenceEntityKey(storyId, structuralKind, { wId: logicalWId2 ?? wId2, author: sourceAuthor2, date: sourceDate2 }, identityOccurrence);
180829
181265
  structural.push({
180830
181266
  entityKey,
180831
181267
  identityOccurrence,
@@ -180841,6 +181277,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180841
181277
  authorEmail: authorEmail2,
180842
181278
  date: date7,
180843
181279
  wId: wId2,
181280
+ ...logicalWId2 ? { logicalWId: logicalWId2 } : {},
180844
181281
  sourceMetadata: {
180845
181282
  author: sourceAuthor2,
180846
181283
  initials: sourceInitials2,
@@ -180878,6 +181315,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180878
181315
  date: sourceDate
180879
181316
  });
180880
181317
  const wId = readNamespacedAttr(attrs, namespaceBindings, "id") ?? "";
181318
+ const logicalWId = logicalWIds.get(byteStart);
180881
181319
  const rawExplicitRsid = readNamespacedAttr(attrs, namespaceBindings, "rsidR") ?? readNamespacedAttr(attrs, namespaceBindings, "rsidDel");
180882
181320
  const explicitRsid = rawExplicitRsid ? normalizeTrackedChangeRsid({ storyId, kind, rsid: rawExplicitRsid }) : null;
180883
181321
  const rsid = explicitRsid && explicitRsid.length > 0 ? explicitRsid : synthesizeTrackedChangeRsidFromRawMetadata({
@@ -180888,11 +181326,19 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180888
181326
  wId,
180889
181327
  occurrence
180890
181328
  });
181329
+ const logicalRsid = logicalWId && !explicitRsid ? synthesizeTrackedChangeRsidFromRawMetadata({
181330
+ storyId,
181331
+ kind,
181332
+ author: sourceAuthor,
181333
+ date: sourceDate,
181334
+ wId: logicalWId,
181335
+ occurrence
181336
+ }) : rsid;
180891
181337
  const logicalIdHint = mintTrackedTextLogicalIdHint({
180892
181338
  owners: textLogicalIdHintOwners,
180893
181339
  kind,
180894
- rsid,
180895
- wId,
181340
+ rsid: logicalRsid,
181341
+ wId: logicalWId ?? wId,
180896
181342
  occurrence,
180897
181343
  author,
180898
181344
  date: date6,
@@ -180901,6 +181347,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180901
181347
  fragments.push({
180902
181348
  rsid,
180903
181349
  logicalIdHint,
181350
+ ...logicalWId ? { logicalRsid } : {},
180904
181351
  partUri,
180905
181352
  storyId,
180906
181353
  byteStart,
@@ -180918,6 +181365,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180918
181365
  authorEmail,
180919
181366
  date: date6,
180920
181367
  wId,
181368
+ ...logicalWId ? { logicalWId } : {},
180921
181369
  sourceMetadata: {
180922
181370
  author: sourceAuthor,
180923
181371
  initials: sourceInitials,
@@ -180944,6 +181392,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180944
181392
  continue;
180945
181393
  const nestedNamespaceBindings = namespaceBindingsByTagStart.get(nestedByteStart);
180946
181394
  const nestedWId = readNamespacedAttr(nestedAttrs, nestedNamespaceBindings, "id") ?? "";
181395
+ const nestedLogicalWId = logicalWIds.get(nestedByteStart);
180947
181396
  const nestedSourceAuthor = readNamespacedAttr(nestedAttrs, nestedNamespaceBindings, "author") ?? "";
180948
181397
  const nestedSourceInitials = readNamespacedAttr(nestedAttrs, nestedNamespaceBindings, "initials");
180949
181398
  const nestedSourceAuthorEmail = readRawTrackedChangeEmail(nestedAttrs, nestedNamespaceBindings);
@@ -180964,11 +181413,19 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180964
181413
  wId: nestedWId,
180965
181414
  occurrence
180966
181415
  });
181416
+ const nestedLogicalRsid = nestedLogicalWId && !nestedExplicitRsid ? synthesizeTrackedChangeRsidFromRawMetadata({
181417
+ storyId,
181418
+ kind: nestedKind,
181419
+ author: nestedSourceAuthor,
181420
+ date: nestedSourceDate,
181421
+ wId: nestedLogicalWId,
181422
+ occurrence
181423
+ }) : nestedRsid;
180967
181424
  const nestedLogicalIdHint = mintTrackedTextLogicalIdHint({
180968
181425
  owners: textLogicalIdHintOwners,
180969
181426
  kind: nestedKind,
180970
- rsid: nestedRsid,
180971
- wId: nestedWId,
181427
+ rsid: nestedLogicalRsid,
181428
+ wId: nestedLogicalWId ?? nestedWId,
180972
181429
  occurrence,
180973
181430
  author: nestedAuthor,
180974
181431
  date: nestedDate,
@@ -180977,6 +181434,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180977
181434
  fragments.push({
180978
181435
  rsid: nestedRsid,
180979
181436
  logicalIdHint: nestedLogicalIdHint,
181437
+ ...nestedLogicalWId ? { logicalRsid: nestedLogicalRsid } : {},
180980
181438
  partUri,
180981
181439
  storyId,
180982
181440
  byteStart: nestedByteStart,
@@ -180994,6 +181452,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
180994
181452
  authorEmail: nestedAuthorEmail,
180995
181453
  date: nestedDate,
180996
181454
  wId: nestedWId,
181455
+ ...nestedLogicalWId ? { logicalWId: nestedLogicalWId } : {},
180997
181456
  sourceMetadata: {
180998
181457
  author: nestedSourceAuthor,
180999
181458
  initials: nestedSourceInitials,
@@ -181010,8 +181469,9 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
181010
181469
  yield;
181011
181470
  const insertion = group.kind === "ins" || group.kind === "moveTo";
181012
181471
  const structuralKind = insertion ? "content-control-insertion" : "content-control-deletion";
181472
+ const logicalWordIds = group.ranges.map((range) => logicalWIds.get(range.startMarker.start) ?? range.wId);
181013
181473
  structural.push({
181014
- entityKey: `native-sdt:${storyId}|${group.kind}|${group.wordIds.join(",")}|${group.author}|${group.date}`,
181474
+ entityKey: `native-sdt:${storyId}|${group.kind}|${logicalWordIds.join(",")}|${group.author}|${group.date}`,
181015
181475
  partUri,
181016
181476
  storyId,
181017
181477
  structuralKind,
@@ -181020,6 +181480,7 @@ function* scanFragmentsWork(xml, partUri, storyId, sourceByteBase = 0, initialNa
181020
181480
  author: { name: group.author, initials: null },
181021
181481
  date: group.date,
181022
181482
  wId: group.wordIds[0],
181483
+ ...logicalWordIds[0] !== group.wordIds[0] ? { logicalWId: logicalWordIds[0] } : {},
181023
181484
  sourceWrapperKind: insertion ? "ins" : "del",
181024
181485
  tagPrefix: group.tagPrefix,
181025
181486
  nativeSdtOwnership: group
@@ -181575,6 +182036,8 @@ function* buildElementRangeIndexWork(xml, initialNamespaceBindings = {}, sharedR
181575
182036
  const trackedTextTokens = [];
181576
182037
  const emptyPropertyRevisionEnds = new Map;
181577
182038
  const bookmarkBoundaries = [];
182039
+ const revisionIdentityElements = [];
182040
+ const hasRevisionIdentity = xml.includes("binding");
181578
182041
  const namespaceBindingsByTagStart = new Map;
181579
182042
  const stack = [];
181580
182043
  const accumulators = {
@@ -181604,6 +182067,10 @@ function* buildElementRangeIndexWork(xml, initialNamespaceBindings = {}, sharedR
181604
182067
  const declarations = isClose || tag.namespaceBindings ? null : readNamespaceDeclarations2(attrs);
181605
182068
  const namespaceBindings = tag.namespaceBindings ?? (!declarations || Object.keys(declarations).length === 0 ? parentBindings : createNamespaceBindings(parentBindings, declarations));
181606
182069
  const wordTrackedMarkup = !isClose && TRACKED_CHANGE_MARKUP_LOCAL_NAMES.has(localName2) && namespaceBindings[prefix] === NS_W;
182070
+ if (hasRevisionIdentity && !isClose && namespaceBindings[prefix] === NS_W) {
182071
+ revisionIdentityElements.push({ start: tag.start, openEnd: tag.end, namespaceUri: NS_W, localName: localName2 });
182072
+ namespaceBindingsByTagStart.set(tag.start, namespaceBindings);
182073
+ }
181607
182074
  if (!isClose && (wordTrackedMarkup || localName2 === "p" || localName2 === "hyperlink")) {
181608
182075
  namespaceBindingsByTagStart.set(tag.start, namespaceBindings);
181609
182076
  }
@@ -181710,6 +182177,7 @@ function* buildElementRangeIndexWork(xml, initialNamespaceBindings = {}, sharedR
181710
182177
  }
181711
182178
  }
181712
182179
  return {
182180
+ revisionIdentityElements,
181713
182181
  elementIndex: {
181714
182182
  entries,
181715
182183
  starts: entries.map((entry) => entry.start),
@@ -181758,6 +182226,8 @@ function* projectCanonicalElementRangesWork(xml, ranges, sharedTopology) {
181758
182226
  const trackedTextTokens = [];
181759
182227
  const emptyPropertyRevisionEnds = new Map;
181760
182228
  const bookmarkBoundaries = [];
182229
+ const revisionIdentityElements = [];
182230
+ const hasRevisionIdentity = xml.includes("binding");
181761
182231
  const namespaceBindingsByTagStart = new Map;
181762
182232
  const ancestors = [];
181763
182233
  const markerEvents = [];
@@ -181778,6 +182248,10 @@ function* projectCanonicalElementRangesWork(xml, ranges, sharedTopology) {
181778
182248
  const { tag, namespaceBindings, start, openEnd, closeStart, end } = range;
181779
182249
  const { localName: localName2, prefix, namespaceUri, isSelfClosing } = tag;
181780
182250
  const wordTrackedMarkup = namespaceUri === NS_W && TRACKED_CHANGE_MARKUP_LOCAL_NAMES.has(localName2);
182251
+ if (hasRevisionIdentity && namespaceUri === NS_W) {
182252
+ revisionIdentityElements.push({ start, openEnd, namespaceUri, localName: localName2 });
182253
+ namespaceBindingsByTagStart.set(start, namespaceBindings);
182254
+ }
181781
182255
  if (wordTrackedMarkup || localName2 === "p" || localName2 === "hyperlink") {
181782
182256
  namespaceBindingsByTagStart.set(start, namespaceBindings);
181783
182257
  }
@@ -181865,6 +182339,7 @@ function* projectCanonicalElementRangesWork(xml, ranges, sharedTopology) {
181865
182339
  }
181866
182340
  recordSDTxPerf("trackedCatalogSharedXmlReuses", 1);
181867
182341
  return {
182342
+ revisionIdentityElements,
181868
182343
  elementIndex: { entries, starts, byStart, textContainers: { entries: containers, starts: containerStarts, maxEnds } },
181869
182344
  moveRangeMarkers,
181870
182345
  bookmarkBoundaries,
@@ -181918,6 +182393,8 @@ function customAttributesField(attrs, namespaceBindings) {
181918
182393
  const namespaceUri = namespaceBindings[attribute.prefix];
181919
182394
  if (!namespaceUri || !isUnknownExtensionNamespace(namespaceUri))
181920
182395
  continue;
182396
+ if (namespaceUri === REVISION_IDENTITY_NAMESPACE && (attribute.localName === "id" || attribute.localName === "binding" || attribute.localName === "lexical"))
182397
+ continue;
181921
182398
  if (namespaceUri === TRACKED_CHANGE_NAMESPACE && (attribute.localName === "rsidR" || attribute.localName === "rsidDel"))
181922
182399
  continue;
181923
182400
  customAttributes.push({
@@ -182065,6 +182542,7 @@ function normalizeTrackedChangeRsid(input) {
182065
182542
  }
182066
182543
  var TD25, TE6, TRACKED_CHANGE_CATALOG_REGISTRY_KEY = "__sd:tracked-change-rsid-catalog", TRACKED_CHANGE_PART_SCAN_REGISTRY_KEY = "__sd:tracked-change-part-scan-cache", TRACKED_CHANGE_CATALOG_TAG, TRACKED_CHANGE_PART_SCAN_TAG, paragraphAnalyses, paragraphAnalysisSuffix = "</w:body></w:document>", TRACKED_CHANGE_MARKUP_LOCAL_NAMES, TRACKED_CHANGE_ELEMENT_CANDIDATE, RAW_CATALOG_CHECKPOINT_BATCH = 16;
182067
182544
  var init_catalog3 = __esm(() => {
182545
+ init_revision_id_identity();
182068
182546
  init_xml_range_topology();
182069
182547
  init_resident_paragraphs();
182070
182548
  init_resident_paragraph_ownership();
@@ -183952,21 +184430,21 @@ function measureTrackedLength(xml, namespaceBindings) {
183952
184430
  function sourceKeys(xml, storyId, inheritedNamespaces = {}) {
183953
184431
  const keys = new Set;
183954
184432
  for (const match of xml.matchAll(/<(?:[^<>\s/:]+:)?(?:rPrChange|pPrChange|tblPrChange|tblPrExChange|trPrChange|tcPrChange|sectPrChange)\b[^>]*>/g)) {
183955
- for (const attr2 of scanRawXmlAttributes(match[0]))
183956
- if (attr2.localName === "id" && attr2.value) {
183957
- const id = decodeXmlText(attr2.value);
184433
+ for (const attr3 of scanRawXmlAttributes(match[0]))
184434
+ if (attr3.localName === "id" && attr3.value) {
184435
+ const id = decodeXmlText(attr3.value);
183958
184436
  keys.add(id);
183959
184437
  keys.add(canonicalTrackedTextRevisionWId(id));
183960
184438
  }
183961
184439
  }
183962
184440
  for (const match of xml.matchAll(/<w:(ins|del|moveFrom|moveTo|rPrChange|pPrChange|tblPrChange|trPrChange|tcPrChange)\b[^>]*>/g)) {
183963
- const attr2 = (name) => new RegExp(`\\bw:${name}=["']([^"']*)["']`).exec(match[0])?.[1] ?? "";
183964
- const wId = attr2("id");
184441
+ const attr3 = (name) => new RegExp(`\\bw:${name}=["']([^"']*)["']`).exec(match[0])?.[1] ?? "";
184442
+ const wId = attr3("id");
183965
184443
  if (wId)
183966
184444
  keys.add(canonicalTrackedTextRevisionWId(wId));
183967
184445
  if (match[1] === "ins" || match[1] === "del") {
183968
184446
  const localName2 = match[1] === "ins" ? "rsidR" : "rsidDel";
183969
- let rsid = attr2(localName2);
184447
+ let rsid = attr3(localName2);
183970
184448
  if (!rsid) {
183971
184449
  const namespaces = { ...inheritedNamespaces, ...Object.fromEntries([...match[0].matchAll(/xmlns:([\w.-]+)=["']([^"']*)["']/g)].map((binding) => [binding[1], binding[2]])) };
183972
184450
  rsid = readXmlAttributeValueByNamespace(match[0], namespaces, "urn:superdoc:tracked-change:1", localName2) ?? "";
@@ -183978,8 +184456,8 @@ function sourceKeys(xml, storyId, inheritedNamespaces = {}) {
183978
184456
  storyId,
183979
184457
  kind: match[1],
183980
184458
  wId,
183981
- author: attr2("author"),
183982
- date: attr2("date"),
184459
+ author: attr3("author"),
184460
+ date: attr3("date"),
183983
184461
  occurrence: 0
183984
184462
  }));
183985
184463
  }
@@ -184356,12 +184834,12 @@ function readResidentReviewComponent(state, mode, sourceIds, includeCoordinates
184356
184834
  return all;
184357
184835
  let found = false;
184358
184836
  for (const wrapper of owner2.xml.matchAll(/<w:(ins|del)\b([^>]*)>/g)) {
184359
- const attr2 = (name) => new RegExp(`\\bw:${name}=["']([^"']*)["']`).exec(wrapper[2])?.[1] ?? "";
184360
- const rsid = attr2(wrapper[1] === "ins" ? "rsidR" : "rsidDel");
184837
+ const attr3 = (name) => new RegExp(`\\bw:${name}=["']([^"']*)["']`).exec(wrapper[2])?.[1] ?? "";
184838
+ const rsid = attr3(wrapper[1] === "ins" ? "rsidR" : "rsidDel");
184361
184839
  const normalized = rsid && normalizeTrackedChangeRsid({ storyId: review.storyId, kind: wrapper[1], rsid });
184362
184840
  if (normalized === key3)
184363
184841
  return all;
184364
- if (canonicalTrackedTextRevisionWId(attr2("id")) !== key3)
184842
+ if (canonicalTrackedTextRevisionWId(attr3("id")) !== key3)
184365
184843
  continue;
184366
184844
  if (!rsid || hasParagraphBridge(owner2))
184367
184845
  return all;
@@ -196651,7 +197129,7 @@ function buildCommentMarkerIndex(partXml, original) {
196651
197129
  return { allByWId, ordered: [...allByWId.values()].flat().sort((left, right) => left.byteStart - right.byteStart) };
196652
197130
  }
196653
197131
  function buildStagedCommentMarkerFact(input) {
196654
- const word2 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
197132
+ const word3 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
196655
197133
  const kinds = new Set(["commentRangeStart", "commentRangeEnd", "commentReference"]);
196656
197134
  if (input.original.errors.length || !/^\uFEFF?\s*<\?xml\b/.test(input.sourceXml))
196657
197135
  return null;
@@ -196664,20 +197142,20 @@ function buildStagedCommentMarkerFact(input) {
196664
197142
  const { tag } = range;
196665
197143
  if (!root || range.start < root.start)
196666
197144
  root = range;
196667
- if (tag.namespaceUri === word2 && tag.prefix !== "w")
197145
+ if (tag.namespaceUri === word3 && tag.prefix !== "w")
196668
197146
  return null;
196669
- if (tag.prefix === "w" && tag.namespaceUri !== word2)
197147
+ if (tag.prefix === "w" && tag.namespaceUri !== word3)
196670
197148
  return null;
196671
197149
  if (byStart.has(range.start))
196672
197150
  owners.set(range.start, range);
196673
- if (tag.namespaceUri !== word2 || !kinds.has(tag.localName))
197151
+ if (tag.namespaceUri !== word3 || !kinds.has(tag.localName))
196674
197152
  continue;
196675
- const id = tag.attributes.find((attr2) => attr2.namespaceUri === word2 && attr2.localName === "id");
197153
+ const id = tag.attributes.find((attr3) => attr3.namespaceUri === word3 && attr3.localName === "id");
196676
197154
  if (tag.prefix !== "w" || !tag.isSelfClosing || !id?.value || id.prefix !== "w")
196677
197155
  return null;
196678
197156
  originalMarkers.push({ commentWId: id.value, kind: tag.localName, byteStart: range.start, byteEnd: range.end });
196679
197157
  }
196680
- if (!root || root.tag.prefix !== "w" || root.tag.namespaceUri !== word2 || root.namespaceBindings.w !== word2)
197158
+ if (!root || root.tag.prefix !== "w" || root.tag.namespaceUri !== word3 || root.namespaceBindings.w !== word3)
196681
197159
  return null;
196682
197160
  originalMarkers.sort((left, right) => left.byteStart - right.byteStart);
196683
197161
  if (originalMarkers.length !== input.markerIndex.ordered.length || originalMarkers.some((hit, index) => {
@@ -196691,7 +197169,7 @@ function buildStagedCommentMarkerFact(input) {
196691
197169
  let previousEnd = 0;
196692
197170
  for (const edit of edits) {
196693
197171
  const owner = owners.get(edit.start);
196694
- if (!owner || owner.end !== edit.end || owner.tag.namespaceUri !== word2 || owner.tag.prefix !== "w" || !["ins", "del"].includes(owner.tag.localName) || owner.namespaceBindings.w !== word2 || edit.start < previousEnd || edit.end <= edit.start || edit.end > input.sourceXml.length || /\bxmlns(?::[\w.-]+)?\s*=/.test(input.sourceXml.slice(edit.start, edit.end)) || /\bxmlns(?::[\w.-]+)?\s*=/.test(edit.replacement))
197172
+ if (!owner || owner.end !== edit.end || owner.tag.namespaceUri !== word3 || owner.tag.prefix !== "w" || !["ins", "del"].includes(owner.tag.localName) || owner.namespaceBindings.w !== word3 || edit.start < previousEnd || edit.end <= edit.start || edit.end > input.sourceXml.length || /\bxmlns(?::[\w.-]+)?\s*=/.test(input.sourceXml.slice(edit.start, edit.end)) || /\bxmlns(?::[\w.-]+)?\s*=/.test(edit.replacement))
196695
197173
  return null;
196696
197174
  while (cursor < originalMarkers.length && originalMarkers[cursor].byteStart < edit.start) {
196697
197175
  const hit = originalMarkers[cursor++];
@@ -196711,9 +197189,9 @@ function buildStagedCommentMarkerFact(input) {
196711
197189
  fragment: true,
196712
197190
  additionalNamespaces: owner.namespaceBindings,
196713
197191
  onOpenTag({ tag, start, end }) {
196714
- if (tag.namespaceUri !== word2 || !kinds.has(tag.localName))
197192
+ if (tag.namespaceUri !== word3 || !kinds.has(tag.localName))
196715
197193
  return;
196716
- const id = tag.attributes.find((attr2) => attr2.namespaceUri === word2 && attr2.localName === "id");
197194
+ const id = tag.attributes.find((attr3) => attr3.namespaceUri === word3 && attr3.localName === "id");
196717
197195
  if (tag.prefix !== "w" || !tag.isSelfClosing || !id?.value || id.prefix !== "w") {
196718
197196
  unsupported2 = true;
196719
197197
  return;
@@ -196919,14 +197397,14 @@ function collectAllCommentMarkers(partXml, original) {
196919
197397
  return out;
196920
197398
  }
196921
197399
  function readCommentMarkerHits(xml, original) {
196922
- const word2 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
197400
+ const word3 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
196923
197401
  if (original && /^\uFEFF?\s*<\?xml\b/.test(xml)) {
196924
197402
  const parsed2 = original.analysis.original(original.partUri, xml);
196925
197403
  if (parsed2.errors.length === 0) {
196926
- const markers = parsed2.ranges.filter(({ tag }) => tag.namespaceUri === word2 && ["commentRangeStart", "commentRangeEnd", "commentReference"].includes(tag.localName));
197404
+ const markers = parsed2.ranges.filter(({ tag }) => tag.namespaceUri === word3 && ["commentRangeStart", "commentRangeEnd", "commentReference"].includes(tag.localName));
196927
197405
  if (markers.every(({ tag }) => tag.isSelfClosing)) {
196928
197406
  return markers.flatMap(({ tag, start, end }) => {
196929
- const id = tag.attributes.find((attr2) => attr2.namespaceUri === word2 && attr2.localName === "id")?.value;
197407
+ const id = tag.attributes.find((attr3) => attr3.namespaceUri === word3 && attr3.localName === "id")?.value;
196930
197408
  return id ? [{ commentWId: id, kind: tag.localName, byteStart: start, byteEnd: end }] : [];
196931
197409
  });
196932
197410
  }
@@ -196936,11 +197414,11 @@ function readCommentMarkerHits(xml, original) {
196936
197414
  const pending2 = [];
196937
197415
  const parsed = walkXmlElements(xml, {
196938
197416
  fragment: !/^\uFEFF?\s*<\?xml\b/.test(xml),
196939
- additionalNamespaces: xmlFragmentAdditionalNamespaces(xml, new Map, { w: word2 }),
197417
+ additionalNamespaces: xmlFragmentAdditionalNamespaces(xml, new Map, { w: word3 }),
196940
197418
  onOpenTag({ tag, start, end }) {
196941
- if (tag.namespaceUri !== word2 || !["commentRangeStart", "commentRangeEnd", "commentReference"].includes(tag.localName))
197419
+ if (tag.namespaceUri !== word3 || !["commentRangeStart", "commentRangeEnd", "commentReference"].includes(tag.localName))
196942
197420
  return;
196943
- const id = tag.attributes.find((attr2) => attr2.namespaceUri === word2 && attr2.localName === "id")?.value;
197421
+ const id = tag.attributes.find((attr3) => attr3.namespaceUri === word3 && attr3.localName === "id")?.value;
196944
197422
  if (!id)
196945
197423
  return;
196946
197424
  const hit = { commentWId: id, kind: tag.localName, byteStart: start, byteEnd: end };
@@ -196949,7 +197427,7 @@ function readCommentMarkerHits(xml, original) {
196949
197427
  pending2.push(hit);
196950
197428
  },
196951
197429
  onCloseTag({ tag, end }) {
196952
- if (tag.isSelfClosing || tag.namespaceUri !== word2)
197430
+ if (tag.isSelfClosing || tag.namespaceUri !== word3)
196953
197431
  return;
196954
197432
  const hit = pending2[pending2.length - 1];
196955
197433
  if (hit?.kind === tag.localName) {
@@ -196976,7 +197454,7 @@ var init_comment_cascade = __esm(() => {
196976
197454
 
196977
197455
  // ../../../v2/editor-core/dist/document/transactions/tracked-changes/insertion-restoration.js
196978
197456
  function attribute(element, namespace, name) {
196979
- const attrs = element.tag.attributes.filter((attr2) => attr2.namespaceUri === namespace && attr2.localName === name);
197457
+ const attrs = element.tag.attributes.filter((attr3) => attr3.namespaceUri === namespace && attr3.localName === name);
196980
197458
  return attrs.length === 1 ? attrs[0].value : null;
196981
197459
  }
196982
197460
  function originId(element) {
@@ -196985,7 +197463,7 @@ function originId(element) {
196985
197463
  return id == null ? null : String(id);
196986
197464
  }
196987
197465
  function hasRestorationOrigin(element) {
196988
- return element.tag.attributes.some((attr2) => attr2.namespaceUri === RESTORE_NS && attr2.localName === RESTORE_ATTR);
197466
+ return element.tag.attributes.some((attr3) => attr3.namespaceUri === RESTORE_NS && attr3.localName === RESTORE_ATTR);
196989
197467
  }
196990
197468
  function stampInsertionRestoration(openTag, namespaceBindings, originalWId, originalCarrierXml, paragraphXml) {
196991
197469
  const raw = parseRawXmlElementTag(openTag);
@@ -197000,7 +197478,7 @@ function stampInsertionRestoration(openTag, namespaceBindings, originalWId, orig
197000
197478
  const element = parsed.ranges[0];
197001
197479
  if (parsed.errors.length > 0 || !element || element.tag.namespaceUri !== NS_W || element.tag.localName !== "ins")
197002
197480
  return null;
197003
- const existing = element.tag.attributes.filter((attr2) => attr2.namespaceUri === RESTORE_NS && attr2.localName === RESTORE_ATTR);
197481
+ const existing = element.tag.attributes.filter((attr3) => attr3.namespaceUri === RESTORE_NS && attr3.localName === RESTORE_ATTR);
197004
197482
  if (existing.length > 0) {
197005
197483
  return originId(element) == null || restorationProof(element) == null ? null : openTag;
197006
197484
  }
@@ -197037,11 +197515,11 @@ function stampInsertionRestoration(openTag, namespaceBindings, originalWId, orig
197037
197515
  return prefix3;
197038
197516
  };
197039
197517
  const prefix2 = availablePrefix("sdRewrite");
197040
- const ignorable = element.tag.attributes.find((attr2) => attr2.namespaceUri === MC_NS2 && attr2.localName === "Ignorable");
197518
+ const ignorable = element.tag.attributes.find((attr3) => attr3.namespaceUri === MC_NS2 && attr3.localName === "Ignorable");
197041
197519
  let result = openTag;
197042
197520
  let declarations = ` xmlns:${prefix2}="${RESTORE_NS}"`;
197043
197521
  if (ignorable) {
197044
- const sourceAttr = [...scanRawXmlAttributes(openTag)].find((attr2) => attr2.name === ignorable.name);
197522
+ const sourceAttr = [...scanRawXmlAttributes(openTag)].find((attr3) => attr3.name === ignorable.name);
197045
197523
  result = result.slice(0, sourceAttr.valueStart) + escapeXmlAttribute(`${ignorable.value} ${prefix2}`.trim()) + result.slice(sourceAttr.valueEnd);
197046
197524
  } else {
197047
197525
  const mc = availablePrefix("sdRewriteMc");
@@ -197055,7 +197533,7 @@ function insertionId(element) {
197055
197533
  return id == null ? null : String(id);
197056
197534
  }
197057
197535
  function metadata2(element) {
197058
- return JSON.stringify(element.tag.attributes.filter((attr2) => attr2.namespaceUri !== "http://www.w3.org/2000/xmlns/" && !(attr2.namespaceUri === NS_W && attr2.localName === "id") && !(attr2.namespaceUri === RESTORE_NS && (attr2.localName === RESTORE_ATTR || attr2.localName === PROOF_ATTR)) && !(attr2.namespaceUri === MC_NS2 && attr2.localName === "Ignorable")).map((attr2) => [attr2.namespaceUri === "urn:superdoc:tracked-change:1" && ["rsidR", "rsidDel"].includes(attr2.localName) ? NS_W : attr2.namespaceUri, attr2.localName, attr2.value]).sort());
197536
+ return JSON.stringify(element.tag.attributes.filter((attr3) => attr3.namespaceUri !== "http://www.w3.org/2000/xmlns/" && !(attr3.namespaceUri === NS_W && attr3.localName === "id") && !(attr3.namespaceUri === RESTORE_NS && (attr3.localName === RESTORE_ATTR || attr3.localName === PROOF_ATTR)) && !(attr3.namespaceUri === MC_NS2 && attr3.localName === "Ignorable")).map((attr3) => [attr3.namespaceUri === "urn:superdoc:tracked-change:1" && ["rsidR", "rsidDel"].includes(attr3.localName) ? NS_W : attr3.namespaceUri, attr3.localName, attr3.value]).sort());
197059
197537
  }
197060
197538
  function restorationProof(element) {
197061
197539
  const value = attribute(element, RESTORE_NS, PROOF_ATTR);
@@ -200896,12 +201374,12 @@ function renderTrackedChangeMarker(kind, id, stamp, includeRsid, wordPrefix = "w
200896
201374
  return renderTrackedChangeOpen(kind, id, stamp, includeRsid, wordPrefix, declareWordPrefix).replace(/>$/, "/>");
200897
201375
  }
200898
201376
  function renderTrackedChangeOpen(kind, id, stamp, includeRsid, wordPrefix = "w", declareWordPrefix = false, protectedXml = "") {
200899
- const attr2 = (name) => xmlQName(wordPrefix, name);
201377
+ const attr3 = (name) => xmlQName(wordPrefix, name);
200900
201378
  const namespace = declareWordPrefix ? ` xmlns:${wordPrefix}="${WORDPROCESSINGML_NAMESPACE3}"` : "";
200901
- const initials = stamp.author.initials ? ` ${attr2("initials")}="${escapeXmlAttribute(stamp.author.initials)}"` : "";
201379
+ const initials = stamp.author.initials ? ` ${attr3("initials")}="${escapeXmlAttribute(stamp.author.initials)}"` : "";
200902
201380
  const email3 = serializeTrackedChangeEmail(stamp.author.email, wordPrefix, protectedXml);
200903
- const rsid = includeRsid ? ` ${attr2(kind === "del" ? "rsidDel" : "rsidR")}="${escapeXmlAttribute(stamp.rsid)}"` : "";
200904
- return `<${xmlQName(wordPrefix, kind)}${namespace} ${attr2("id")}="${id}" ${attr2("author")}="${escapeXmlAttribute(stamp.author.name)}"${initials}${email3}` + ` ${attr2("date")}="${escapeXmlAttribute(stamp.date)}"${rsid}>`;
201381
+ const rsid = includeRsid ? ` ${attr3(kind === "del" ? "rsidDel" : "rsidR")}="${escapeXmlAttribute(stamp.rsid)}"` : "";
201382
+ return `<${xmlQName(wordPrefix, kind)}${namespace} ${attr3("id")}="${id}" ${attr3("author")}="${escapeXmlAttribute(stamp.author.name)}"${initials}${email3}` + ` ${attr3("date")}="${escapeXmlAttribute(stamp.date)}"${rsid}>`;
200905
201383
  }
200906
201384
  function tableColumnCount(spec) {
200907
201385
  return Math.max(1, ...spec.rows.map((row) => row.cells.reduce((sum, cell) => sum + Math.max(1, cell.gridSpan ?? 1), 0)));
@@ -201499,14 +201977,14 @@ function prepareEnclosedTrackedTables(bytes, startByte, endByte, stamp) {
201499
201977
  function stampTrackedRangeParagraph(xml, rsid, partBytes, paragraphStartByte) {
201500
201978
  return xml.replace(new RegExp(`^<([\\w.-]+):p\\b${RAW_XML_TAG_ATTRIBUTES_PATTERN}>`), (open2) => {
201501
201979
  const prefix2 = /^<([\w.-]+):/.exec(open2)[1];
201502
- const attr2 = `${prefix2}:rsidR`;
201980
+ const attr3 = `${prefix2}:rsidR`;
201503
201981
  const namespaces = namespaceBindingsAtPosition(partBytes, paragraphStartByte, open2);
201504
201982
  for (const attribute2 of scanRawXmlAttributes(open2)) {
201505
201983
  if (attribute2.localName === "rsidR" && attribute2.prefix && namespaces[attribute2.prefix] === NS_W) {
201506
201984
  return open2.slice(0, attribute2.valueStart) + rsid + open2.slice(attribute2.valueEnd);
201507
201985
  }
201508
201986
  }
201509
- return open2.replace(/>$/, ` ${attr2}="${rsid}">`);
201987
+ return open2.replace(/>$/, ` ${attr3}="${rsid}">`);
201510
201988
  });
201511
201989
  }
201512
201990
  var TE10, TD37;
@@ -231734,9 +232212,9 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231734
232212
  fragment: true,
231735
232213
  additionalNamespaces: { ...source.namespaces }
231736
232214
  });
231737
- if (parsed.ranges.some((r) => word2(r) && ["document", "body", "hdr", "ftr", "sectPr", "altChunk", "dataBinding"].includes(r.tag.localName)))
232215
+ if (parsed.ranges.some((r) => word3(r) && ["document", "body", "hdr", "ftr", "sectPr", "altChunk", "dataBinding"].includes(r.tag.localName)))
231738
232216
  return fail4();
231739
- const inline = roots.value.every((r) => word2(r) && [
232217
+ const inline = roots.value.every((r) => word3(r) && [
231740
232218
  "r",
231741
232219
  "hyperlink",
231742
232220
  "ins",
@@ -231747,20 +232225,20 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231747
232225
  "commentRangeEnd",
231748
232226
  "fldSimple"
231749
232227
  ].includes(r.tag.localName));
231750
- if (!inline && !roots.value.every((r) => word2(r) && ["p", "tbl"].includes(r.tag.localName)))
232228
+ if (!inline && !roots.value.every((r) => word3(r) && ["p", "tbl"].includes(r.tag.localName)))
231751
232229
  return fail4();
231752
232230
  if (inline && !validateRetainableParagraphXml(`<w:p xmlns:w="${NS_W}">${source.xml}</w:p>`, source.namespaces).ok)
231753
232231
  return fail4();
231754
232232
  if (!inline && !validNativeBlockPlacement(source.xml, parsed.ranges))
231755
232233
  return fail4();
231756
- for (const range of parsed.ranges.filter((r) => word2(r) && r.tag.localName === "p")) {
232234
+ for (const range of parsed.ranges.filter((r) => word3(r) && r.tag.localName === "p")) {
231757
232235
  const check2 = validateRetainableParagraphXml(source.xml.slice(range.start, range.end), range.namespaceBindings);
231758
232236
  if (!check2.ok)
231759
232237
  return fail4();
231760
232238
  }
231761
232239
  const sourceParagraphIds = new Set;
231762
232240
  for (const range of parsed.ranges) {
231763
- if (!word2(range) || range.tag.localName !== "p")
232241
+ if (!word3(range) || range.tag.localName !== "p")
231764
232242
  continue;
231765
232243
  const id = range.tag.attributes.find((a) => a.namespaceUri === W14 && a.localName === "paraId")?.value;
231766
232244
  if (id && sourceParagraphIds.has(id))
@@ -231807,7 +232285,7 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231807
232285
  occupiedHex.add(id.toUpperCase());
231808
232286
  for (const r of collectXmlElementRanges(xml2).ranges)
231809
232287
  if (r.tag.localName === "docPr" && r.tag.namespaceUri === "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") {
231810
- const id = attr2(r, "id");
232288
+ const id = attr3(r, "id");
231811
232289
  if (id)
231812
232290
  occupiedDrawingIds.add(id);
231813
232291
  }
@@ -231893,8 +232371,8 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231893
232371
  if (ranges.errors.length || ranges.ranges.length > 50000 || /<!DOCTYPE|<!ENTITY/i.test(xml2))
231894
232372
  return fail4();
231895
232373
  for (const range of ranges.ranges) {
231896
- if (word2(range) && range.tag.localName === "comment") {
231897
- const id = attr2(range, "id");
232374
+ if (word3(range) && range.tag.localName === "comment") {
232375
+ const id = attr3(range, "id");
231898
232376
  if (!id || commentIds.has(id))
231899
232377
  return fail4();
231900
232378
  mintNumeric(commentIds, id);
@@ -231905,25 +232383,25 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231905
232383
  if (a.localName === "durableId")
231906
232384
  mintHex(durableIds, a.value.toUpperCase());
231907
232385
  }
231908
- if (word2(range) && range.tag.localName === "style") {
231909
- const id = attr2(range, "styleId");
232386
+ if (word3(range) && range.tag.localName === "style") {
232387
+ const id = attr3(range, "styleId");
231910
232388
  if (!id || styleIds.has(id))
231911
232389
  return fail4();
231912
232390
  const destinationBytes = read(sourceToDest.get(uri));
231913
232391
  const destinationXml = destinationBytes ? TD57.decode(destinationBytes) : "";
231914
232392
  const destinationRanges = collectXmlElementRanges(destinationXml).ranges;
231915
- const found = destinationRanges.find((r) => word2(r) && r.tag.localName === "style" && attr2(r, "styleId") === id);
232393
+ const found = destinationRanges.find((r) => word3(r) && r.tag.localName === "style" && attr3(r, "styleId") === id);
231916
232394
  const same = found && destinationXml.slice(found.start, found.end) === xml2.slice(range.start, range.end);
231917
232395
  styleIds.set(id, !found || same ? id : `SD_${mintHex(new Map, id)}`);
231918
232396
  }
231919
- if (word2(range) && range.tag.localName === "num") {
231920
- const id = attr2(range, "numId");
232397
+ if (word3(range) && range.tag.localName === "num") {
232398
+ const id = attr3(range, "numId");
231921
232399
  if (!id)
231922
232400
  return fail4();
231923
232401
  mintNumeric(numIds, id);
231924
232402
  }
231925
- if (word2(range) && range.tag.localName === "abstractNum") {
231926
- const id = attr2(range, "abstractNumId");
232403
+ if (word3(range) && range.tag.localName === "abstractNum") {
232404
+ const id = attr3(range, "abstractNumId");
231927
232405
  if (!id)
231928
232406
  return fail4();
231929
232407
  mintNumeric(abstractIds, id);
@@ -231968,7 +232446,7 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231968
232446
  next = mintHex(paraIds, a.value);
231969
232447
  else if (a.localName === "durableId")
231970
232448
  next = mintHex(durableIds, a.value.toUpperCase());
231971
- else if (word2(range) && a.localName === "id") {
232449
+ else if (word3(range) && a.localName === "id") {
231972
232450
  if (/^(comment|commentRangeStart|commentRangeEnd|commentReference)$/.test(range.tag.localName)) {
231973
232451
  next = commentIds.get(a.value);
231974
232452
  if (!next)
@@ -231979,13 +232457,13 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
231979
232457
  next = mintNumeric(revisions2, a.value);
231980
232458
  else if (["footnoteReference", "endnoteReference", "footnote", "endnote"].includes(range.tag.localName))
231981
232459
  return null;
231982
- } else if (word2(range) && a.localName === "styleId")
232460
+ } else if (word3(range) && a.localName === "styleId")
231983
232461
  next = styleIds.get(a.value);
231984
- else if (word2(range) && a.localName === "numId" && range.tag.localName === "num")
232462
+ else if (word3(range) && a.localName === "numId" && range.tag.localName === "num")
231985
232463
  next = numIds.get(a.value);
231986
- else if (word2(range) && a.localName === "abstractNumId" && range.tag.localName === "abstractNum")
232464
+ else if (word3(range) && a.localName === "abstractNumId" && range.tag.localName === "abstractNum")
231987
232465
  next = abstractIds.get(a.value);
231988
- else if (word2(range) && a.localName === "val") {
232466
+ else if (word3(range) && a.localName === "val") {
231989
232467
  if (["pStyle", "rStyle", "tblStyle", "basedOn", "link", "next"].includes(range.tag.localName))
231990
232468
  next = styleIds.get(a.value);
231991
232469
  if (range.tag.localName === "numId")
@@ -232084,13 +232562,13 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
232084
232562
  return relation ? read(resolveTargetUri("/word/document.xml", relation.target, "Internal")) : undefined;
232085
232563
  };
232086
232564
  const destinationStyles = sharedPart("styles");
232087
- const availableStyles = new Set(destinationStyles ? collectXmlElementRanges(TD57.decode(destinationStyles)).ranges.filter((r) => word2(r) && r.tag.localName === "style").map((r) => attr2(r, "styleId")) : []);
232565
+ const availableStyles = new Set(destinationStyles ? collectXmlElementRanges(TD57.decode(destinationStyles)).ranges.filter((r) => word3(r) && r.tag.localName === "style").map((r) => attr3(r, "styleId")) : []);
232088
232566
  const destinationNumbering = sharedPart("numbering");
232089
- const availableNumbers = new Set(destinationNumbering ? collectXmlElementRanges(TD57.decode(destinationNumbering)).ranges.filter((r) => word2(r) && r.tag.localName === "num").map((r) => attr2(r, "numId")) : []);
232567
+ const availableNumbers = new Set(destinationNumbering ? collectXmlElementRanges(TD57.decode(destinationNumbering)).ranges.filter((r) => word3(r) && r.tag.localName === "num").map((r) => attr3(r, "numId")) : []);
232090
232568
  for (const r of nativeRefs.ranges) {
232091
- if (!word2(r))
232569
+ if (!word3(r))
232092
232570
  continue;
232093
- const value = attr2(r, "val");
232571
+ const value = attr3(r, "val");
232094
232572
  if (["pStyle", "rStyle", "tblStyle"].includes(r.tag.localName) && value !== "CommentReference" && !availableStyles.has(value))
232095
232573
  return fail4();
232096
232574
  if (r.tag.localName === "numId" && value !== "0" && !availableNumbers.has(value))
@@ -232108,7 +232586,7 @@ function planNativeOoxmlImport(state, source, txId, basePerPart = {}) {
232108
232586
  else {
232109
232587
  const all = collectXmlElementRanges(xml, { fragment: true });
232110
232588
  for (const range of [...all.ranges].reverse())
232111
- if (word2(range) && range.tag.localName === "p" && !range.tag.attributes.some((a) => a.namespaceUri === W14 && a.localName === "paraId")) {
232589
+ if (word3(range) && range.tag.localName === "p" && !range.tag.attributes.some((a) => a.namespaceUri === W14 && a.localName === "paraId")) {
232112
232590
  const open2 = xml.slice(range.start, range.openEnd);
232113
232591
  xml = xml.slice(0, range.start) + open2.replace(/\/?\s*>$/, (tail) => `${range.namespaceBindings.w14 === W14 ? "" : ` xmlns:w14="${W14}"`} w14:paraId="${mintHex(paraIds, "paragraph-" + range.start)}"` + tail) + xml.slice(range.openEnd);
232114
232592
  }
@@ -232178,11 +232656,11 @@ function validNativeDependency(bytes, contentType, kind) {
232178
232656
  const catalog = catalogs[kind];
232179
232657
  if (!catalog) {
232180
232658
  if (kind === "theme")
232181
- return contentType === "application/vnd.openxmlformats-officedocument.theme+xml" && root.tag.localName === "theme" && root.tag.namespaceUri === "http://schemas.openxmlformats.org/drawingml/2006/main" && !parsed.ranges.some(word2);
232659
+ return contentType === "application/vnd.openxmlformats-officedocument.theme+xml" && root.tag.localName === "theme" && root.tag.namespaceUri === "http://schemas.openxmlformats.org/drawingml/2006/main" && !parsed.ranges.some(word3);
232182
232660
  if (kind === "customXml")
232183
- return contentType === "application/xml" && !parsed.ranges.some(word2);
232661
+ return contentType === "application/xml" && !parsed.ranges.some(word3);
232184
232662
  if (kind === "customXmlProps")
232185
- return contentType === "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" && root.tag.localName === "datastoreItem" && root.tag.namespaceUri === "http://schemas.openxmlformats.org/officeDocument/2006/customXml" && !!attr2(root, "itemID") && direct.every((r) => r.tag.localName === "schemaRefs" && r.tag.namespaceUri === root.tag.namespaceUri) && parsed.ranges.every((r) => r === root || ["schemaRefs", "schemaRef"].includes(r.tag.localName) && r.tag.namespaceUri === root.tag.namespaceUri);
232663
+ return contentType === "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" && root.tag.localName === "datastoreItem" && root.tag.namespaceUri === "http://schemas.openxmlformats.org/officeDocument/2006/customXml" && !!attr3(root, "itemID") && direct.every((r) => r.tag.localName === "schemaRefs" && r.tag.namespaceUri === root.tag.namespaceUri) && parsed.ranges.every((r) => r === root || ["schemaRefs", "schemaRef"].includes(r.tag.localName) && r.tag.namespaceUri === root.tag.namespaceUri);
232186
232664
  return false;
232187
232665
  }
232188
232666
  if (contentType !== wordCt + kind + "+xml" || root.tag.localName !== catalog.root || root.tag.namespaceUri !== catalog.namespace)
@@ -232195,7 +232673,7 @@ function validNativeDependency(bytes, contentType, kind) {
232195
232673
  offset = child.end;
232196
232674
  const keyName = kind === "numbering" ? child.tag.localName === "num" ? "numId" : "abstractNumId" : catalog.key;
232197
232675
  if (keyName && !(kind === "styles" && child.tag.localName !== "style")) {
232198
- const key3 = attr2(child, keyName);
232676
+ const key3 = attr3(child, keyName);
232199
232677
  if (!key3 || keys.has(child.tag.localName + ":" + key3))
232200
232678
  return false;
232201
232679
  keys.add(child.tag.localName + ":" + key3);
@@ -232204,10 +232682,10 @@ function validNativeDependency(bytes, contentType, kind) {
232204
232682
  if (kind.startsWith("comments") && kind !== "comments") {
232205
232683
  if (descendants.length || xml.slice(child.openEnd, child.closeStart).trim())
232206
232684
  return false;
232207
- if (kind === "commentsIds" && !attr2(child, "durableId"))
232685
+ if (kind === "commentsIds" && !attr3(child, "durableId"))
232208
232686
  return false;
232209
232687
  } else if (kind === "comments") {
232210
- if (!descendants.some((r) => word2(r) && r.tag.localName === "p"))
232688
+ if (!descendants.some((r) => word3(r) && r.tag.localName === "p"))
232211
232689
  return false;
232212
232690
  const body = xml.slice(child.openEnd, child.closeStart);
232213
232691
  const blocks = collectXmlElementRanges(body, {
@@ -232216,15 +232694,15 @@ function validNativeDependency(bytes, contentType, kind) {
232216
232694
  });
232217
232695
  if (blocks.errors.length || !validNativeBlockPlacement(body, blocks.ranges))
232218
232696
  return false;
232219
- for (const paragraph of blocks.ranges.filter((r) => word2(r) && r.tag.localName === "p"))
232697
+ for (const paragraph of blocks.ranges.filter((r) => word3(r) && r.tag.localName === "p"))
232220
232698
  if (!validateRetainableParagraphXml(body.slice(paragraph.start, paragraph.end), paragraph.namespaceBindings).ok)
232221
232699
  return false;
232222
232700
  } else {
232223
- if (descendants.some((r) => !word2(r) || ["p", "r", "t", "delText", "tbl", "comment", "style", "num", "abstractNum"].includes(r.tag.localName)))
232701
+ if (descendants.some((r) => !word3(r) || ["p", "r", "t", "delText", "tbl", "comment", "style", "num", "abstractNum"].includes(r.tag.localName)))
232224
232702
  return false;
232225
232703
  if (kind === "numbering" && child.tag.localName === "num") {
232226
232704
  const abstract = descendants.filter((r) => r.tag.localName === "abstractNumId");
232227
- if (abstract.length !== 1 || !attr2(abstract[0], "val"))
232705
+ if (abstract.length !== 1 || !attr3(abstract[0], "val"))
232228
232706
  return false;
232229
232707
  }
232230
232708
  }
@@ -232243,30 +232721,30 @@ function validDependencyReferences(payloads, state, mainRanges) {
232243
232721
  const collect = (bytes, kind) => {
232244
232722
  const ranges = collectXmlElementRanges(TD57.decode(bytes)).ranges;
232245
232723
  for (const r of ranges) {
232246
- if (word2(r) && r.tag.localName === "style")
232247
- styleIds.add(attr2(r, "styleId"));
232248
- if (word2(r) && r.tag.localName === "abstractNum")
232249
- abstractIds.add(attr2(r, "abstractNumId"));
232250
- if (word2(r) && r.tag.localName === "num")
232251
- numIds.add(attr2(r, "numId"));
232252
- if (kind === "comments" && word2(r) && r.tag.localName === "comment") {
232253
- const lastParagraph = ranges.filter((p) => r.start < p.start && r.end > p.end && word2(p) && p.tag.localName === "p").at(-1);
232254
- const paraId = lastParagraph && attr2(lastParagraph, "paraId");
232255
- const id = attr2(r, "id");
232724
+ if (word3(r) && r.tag.localName === "style")
232725
+ styleIds.add(attr3(r, "styleId"));
232726
+ if (word3(r) && r.tag.localName === "abstractNum")
232727
+ abstractIds.add(attr3(r, "abstractNumId"));
232728
+ if (word3(r) && r.tag.localName === "num")
232729
+ numIds.add(attr3(r, "numId"));
232730
+ if (kind === "comments" && word3(r) && r.tag.localName === "comment") {
232731
+ const lastParagraph = ranges.filter((p) => r.start < p.start && r.end > p.end && word3(p) && p.tag.localName === "p").at(-1);
232732
+ const paraId = lastParagraph && attr3(lastParagraph, "paraId");
232733
+ const id = attr3(r, "id");
232256
232734
  if (importedComments.has(id) || paraId && commentParas.has(paraId))
232257
232735
  validIdentities = false;
232258
232736
  importedComments.set(id, paraId);
232259
232737
  if (paraId)
232260
232738
  commentParas.add(paraId);
232261
232739
  }
232262
- if (kind === "commentsIds" && attr2(r, "durableId")) {
232263
- const id = attr2(r, "durableId").toUpperCase();
232740
+ if (kind === "commentsIds" && attr3(r, "durableId")) {
232741
+ const id = attr3(r, "durableId").toUpperCase();
232264
232742
  if (durableIds.has(id))
232265
232743
  validIdentities = false;
232266
232744
  durableIds.add(id);
232267
232745
  }
232268
- if (kind === "commentsExtended" && r.tag.localName === "commentEx" && attr2(r, "paraIdParent"))
232269
- parents.set(attr2(r, "paraId"), attr2(r, "paraIdParent"));
232746
+ if (kind === "commentsExtended" && r.tag.localName === "commentEx" && attr3(r, "paraIdParent"))
232747
+ parents.set(attr3(r, "paraId"), attr3(r, "paraIdParent"));
232270
232748
  }
232271
232749
  return ranges;
232272
232750
  };
@@ -232290,24 +232768,24 @@ function validDependencyReferences(payloads, state, mainRanges) {
232290
232768
  return false;
232291
232769
  for (const { kind, ranges } of catalogs)
232292
232770
  for (const r of ranges) {
232293
- const value = attr2(r, "val");
232294
- if (word2(r) && ["pStyle", "rStyle", "tblStyle", "basedOn", "link", "next"].includes(r.tag.localName) && value !== "CommentReference" && !styleIds.has(value))
232771
+ const value = attr3(r, "val");
232772
+ if (word3(r) && ["pStyle", "rStyle", "tblStyle", "basedOn", "link", "next"].includes(r.tag.localName) && value !== "CommentReference" && !styleIds.has(value))
232295
232773
  return false;
232296
- if (word2(r) && r.tag.localName === "abstractNumId" && !abstractIds.has(value))
232774
+ if (word3(r) && r.tag.localName === "abstractNumId" && !abstractIds.has(value))
232297
232775
  return false;
232298
- if (word2(r) && r.tag.localName === "numId" && value !== "0" && !numIds.has(value))
232776
+ if (word3(r) && r.tag.localName === "numId" && value !== "0" && !numIds.has(value))
232299
232777
  return false;
232300
232778
  if (["commentsExtended", "commentsIds"].includes(kind) && ["commentEx", "commentId"].includes(r.tag.localName)) {
232301
- if (!commentParas.has(attr2(r, "paraId")))
232779
+ if (!commentParas.has(attr3(r, "paraId")))
232302
232780
  return false;
232303
- const parent = attr2(r, "paraIdParent");
232781
+ const parent = attr3(r, "paraIdParent");
232304
232782
  if (parent && !commentParas.has(parent))
232305
232783
  return false;
232306
232784
  }
232307
- if (kind === "commentsExtensible" && r.tag.localName === "commentExtensible" && !durableIds.has(attr2(r, "durableId").toUpperCase()))
232785
+ if (kind === "commentsExtensible" && r.tag.localName === "commentExtensible" && !durableIds.has(attr3(r, "durableId").toUpperCase()))
232308
232786
  return false;
232309
232787
  }
232310
- const referenced = new Set(mainRanges.filter((r) => word2(r) && r.tag.localName === "commentReference").map((r) => attr2(r, "id")));
232788
+ const referenced = new Set(mainRanges.filter((r) => word3(r) && r.tag.localName === "commentReference").map((r) => attr3(r, "id")));
232311
232789
  const byPara = new Map([...importedComments].filter(([, para]) => !!para).map(([id, para]) => [para, id]));
232312
232790
  for (const [id, para] of importedComments) {
232313
232791
  if (referenced.has(id) && para && parents.has(para))
@@ -232382,9 +232860,9 @@ function validNativeBlockPlacement(xml, ranges) {
232382
232860
  while (stack.length && range.start >= stack.at(-1).end)
232383
232861
  stack.pop();
232384
232862
  const parent = stack.at(-1);
232385
- const inParagraph = stack.some((r) => word2(r) && r.tag.localName === "p");
232863
+ const inParagraph = stack.some((r) => word3(r) && r.tag.localName === "p");
232386
232864
  if (!inParagraph) {
232387
- if (!word2(range))
232865
+ if (!word3(range))
232388
232866
  return false;
232389
232867
  const name = range.tag.localName;
232390
232868
  if (!parent) {
@@ -232410,7 +232888,7 @@ function validNativeBlockPlacement(xml, ranges) {
232410
232888
  stack.push(range);
232411
232889
  }
232412
232890
  for (const range of ranges) {
232413
- if (!word2(range) || !["tbl", "tr", "tc", "tblGrid"].includes(range.tag.localName))
232891
+ if (!word3(range) || !["tbl", "tr", "tc", "tblGrid"].includes(range.tag.localName))
232414
232892
  continue;
232415
232893
  const direct = children.get(range) ?? [];
232416
232894
  const required2 = range.tag.localName === "tbl" ? ["tr"] : range.tag.localName === "tr" ? ["tc"] : range.tag.localName === "tc" ? ["p", "tbl"] : ["gridCol"];
@@ -232435,8 +232913,8 @@ function mergeDefinitions(destination, source, kind) {
232435
232913
  return null;
232436
232914
  if (kind === "styles") {
232437
232915
  for (const name of ["docDefaults", "latentStyles"]) {
232438
- const sourceDefault = s.ranges.find((r) => word2(r) && r.tag.localName === name);
232439
- const destinationDefault = d.ranges.find((r) => word2(r) && r.tag.localName === name);
232916
+ const sourceDefault = s.ranges.find((r) => word3(r) && r.tag.localName === name);
232917
+ const destinationDefault = d.ranges.find((r) => word3(r) && r.tag.localName === name);
232440
232918
  if (sourceDefault && (!destinationDefault || source.slice(sourceDefault.start, sourceDefault.end) !== destination.slice(destinationDefault.start, destinationDefault.end)))
232441
232919
  return null;
232442
232920
  }
@@ -232446,10 +232924,10 @@ function mergeDefinitions(destination, source, kind) {
232446
232924
  if (kind === "styles" && !["style"].includes(child.tag.localName))
232447
232925
  continue;
232448
232926
  const keyName = kind === "styles" ? "styleId" : kind === "numbering" ? child.tag.localName === "num" ? "numId" : "abstractNumId" : kind === "comments" ? "id" : kind === "commentsExtensible" ? "durableId" : "paraId";
232449
- const key3 = attr2(child, keyName);
232927
+ const key3 = attr3(child, keyName);
232450
232928
  if (!key3)
232451
232929
  return null;
232452
- const found = d.ranges.find((r) => r.tag.namespaceUri === child.tag.namespaceUri && r.tag.localName === child.tag.localName && attr2(r, keyName) === key3);
232930
+ const found = d.ranges.find((r) => r.tag.namespaceUri === child.tag.namespaceUri && r.tag.localName === child.tag.localName && attr3(r, keyName) === key3);
232453
232931
  const raw = source.slice(child.start, child.end);
232454
232932
  if (found) {
232455
232933
  if (destination.slice(found.start, found.end) !== raw)
@@ -232516,7 +232994,7 @@ function canonicalWordMarkup(xml, namespaces) {
232516
232994
  return null;
232517
232995
  const patches = [];
232518
232996
  for (const r of parsed.ranges) {
232519
- if (!word2(r))
232997
+ if (!word3(r))
232520
232998
  continue;
232521
232999
  let open2 = xml.slice(r.start, r.openEnd).replace(new RegExp(`^<${r.tag.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?=[\\s/>])`), `<w:${r.tag.localName}`);
232522
233000
  for (const a of r.tag.attributes)
@@ -232533,7 +233011,7 @@ function canonicalWordMarkup(xml, namespaces) {
232533
233011
  var TE28, TD57, W14 = "http://schemas.microsoft.com/office/word/2010/wordml", CT_URI = "/[Content_Types].xml", REL_CT = "application/vnd.openxmlformats-package.relationships+xml", fail4 = () => ({
232534
233012
  ok: false,
232535
233013
  reason: "paste-structure-unsupported"
232536
- }), word2 = (r) => r.tag.namespaceUri === NS_W || r.tag.namespaceUri === NS_WSTRICT, attr2 = (r, name) => r.tag.attributes.find((a) => a.localName === name)?.value;
233014
+ }), word3 = (r) => r.tag.namespaceUri === NS_W || r.tag.namespaceUri === NS_WSTRICT, attr3 = (r, name) => r.tag.attributes.find((a) => a.localName === name)?.value;
232537
233015
  var init_native_ooxml_import = __esm(() => {
232538
233016
  init_xml_sax();
232539
233017
  init_sha256_sync();
@@ -232647,7 +233125,7 @@ function readContentControlBlockGroups(bytes) {
232647
233125
  while (ancestors.length && ancestors.at(-1).range.end < control2.end)
232648
233126
  ancestors.pop();
232649
233127
  const idRange = parsed.ranges.find((range) => range.start > control2.start && range.end < headerEnd && range.tag.namespaceUri === W2 && range.tag.localName === "id");
232650
- const id = idRange?.tag.attributes.find((attr3) => attr3.namespaceUri === W2 && attr3.localName === "val")?.value ?? `paragraph:${first.id}:${ancestors.length}`;
233128
+ const id = idRange?.tag.attributes.find((attr4) => attr4.namespaceUri === W2 && attr4.localName === "val")?.value ?? `paragraph:${first.id}:${ancestors.length}`;
232651
233129
  const parentId = ancestors.at(-1)?.id ?? null;
232652
233130
  const candidate2 = { id, parentId, range: control2, members };
232653
233131
  candidates.push(candidate2);
@@ -232730,7 +233208,7 @@ function snapshot(xml, parsed = collectXmlElementRanges(xml)) {
232730
233208
  continue;
232731
233209
  if (range.start < cursor || range.end > container.closeStart)
232732
233210
  return null;
232733
- const id = range.tag.attributes.find((attr3) => attr3.namespaceUri === W142 && attr3.localName === "paraId")?.value ?? syntheticParagraphBlockId(ordinal);
233211
+ const id = range.tag.attributes.find((attr4) => attr4.namespaceUri === W142 && attr4.localName === "paraId")?.value ?? syntheticParagraphBlockId(ordinal);
232734
233212
  if (!id || ids.has(id))
232735
233213
  return null;
232736
233214
  ids.add(id);
@@ -232869,7 +233347,7 @@ function applyEntry(current, entry) {
232869
233347
  return applied.ok ? applied.value : undefined;
232870
233348
  }
232871
233349
  function paragraphId(range) {
232872
- return range.tag.attributes.find((attr3) => attr3.namespaceUri === W143 && attr3.localName === "paraId")?.value ?? null;
233350
+ return range.tag.attributes.find((attr4) => attr4.namespaceUri === W143 && attr4.localName === "paraId")?.value ?? null;
232873
233351
  }
232874
233352
  function readHeader(bytes) {
232875
233353
  const xml = TD59.decode(bytes);
@@ -232997,7 +233475,7 @@ function readMarginCarriers(xml, allowed) {
232997
233475
  if (!parent || parent.tag.namespaceUri !== W4 || !["body", "pPr"].includes(parent.tag.localName))
232998
233476
  return null;
232999
233477
  const paragraph = parent.tag.localName === "pPr" ? parentOf(parent, parsed.ranges) : null;
233000
- const blockId = paragraph?.tag.attributes.find((attr3) => attr3.namespaceUri === W144 && attr3.localName === "paraId")?.value ?? null;
233478
+ const blockId = paragraph?.tag.attributes.find((attr4) => attr4.namespaceUri === W144 && attr4.localName === "paraId")?.value ?? null;
233001
233479
  if (parent.tag.localName === "pPr" && (!paragraph || paragraph.tag.namespaceUri !== W4 || paragraph.tag.localName !== "p" || !blockId || sections.some((section) => section.blockId === blockId)))
233002
233480
  return null;
233003
233481
  const margins = parsed.ranges.filter((candidate2) => candidate2.tag.namespaceUri === W4 && candidate2.tag.localName === "pgMar" && candidate2.start > range.start && candidate2.end <= range.closeStart);
@@ -233006,9 +233484,9 @@ function readMarginCarriers(xml, allowed) {
233006
233484
  const margin = margins[0];
233007
233485
  if (margin && (parentOf(margin, parsed.ranges) !== range || !margin.tag.isSelfClosing && xml.slice(margin.openEnd, margin.closeStart).trim()))
233008
233486
  return null;
233009
- if (margin?.tag.attributes.some((attr3) => attr3.namespaceUri === W4 && allowed.includes(attr3.localName) && !/^\d+$/.test(attr3.value)))
233487
+ if (margin?.tag.attributes.some((attr4) => attr4.namespaceUri === W4 && allowed.includes(attr4.localName) && !/^\d+$/.test(attr4.value)))
233010
233488
  return null;
233011
- const otherAttributes = JSON.stringify((margin?.tag.attributes ?? []).filter((attr3) => attr3.namespaceUri !== W4 || !allowed.includes(attr3.localName)).map((attr3) => [attr3.name, attr3.namespaceUri, attr3.value]).sort((a, b) => a[0].localeCompare(b[0])));
233489
+ const otherAttributes = JSON.stringify((margin?.tag.attributes ?? []).filter((attr4) => attr4.namespaceUri !== W4 || !allowed.includes(attr4.localName)).map((attr4) => [attr4.name, attr4.namespaceUri, attr4.value]).sort((a, b) => a[0].localeCompare(b[0])));
233012
233490
  const inner = range.tag.isSelfClosing ? "" : margin ? xml.slice(range.openEnd, margin.start) + xml.slice(margin.end, range.closeStart) : xml.slice(range.openEnd, range.closeStart);
233013
233491
  const opening = xml.slice(range.start, range.openEnd).replace(/\s*\/>$/, ">");
233014
233492
  shell += xml.slice(cursor, range.start) + opening + inner + `</${range.tag.name}>`;
@@ -237675,10 +238153,10 @@ function scanXmlChunks(chunks, partUri, bytesScanned) {
237675
238153
  } else if (local === "Fallback")
237676
238154
  counts.mceFallback += 1;
237677
238155
  }
237678
- for (const attr3 of tag.attributes) {
237679
- if (attr3.namespaceUri === "http://schemas.openxmlformats.org/markup-compatibility/2006") {
237680
- const lname = attr3.localName;
237681
- const val = attr3.value;
238156
+ for (const attr4 of tag.attributes) {
238157
+ if (attr4.namespaceUri === "http://schemas.openxmlformats.org/markup-compatibility/2006") {
238158
+ const lname = attr4.localName;
238159
+ const val = attr4.value;
237682
238160
  if (lname === "Ignorable")
237683
238161
  for (const t of val.split(/\s+/).filter(Boolean))
237684
238162
  bump(mceIgnorable, t, anchor);
@@ -237692,8 +238170,8 @@ function scanXmlChunks(chunks, partUri, bytesScanned) {
237692
238170
  for (const t of val.split(/\s+/).filter(Boolean))
237693
238171
  bump(mceProcessContent, t, anchor);
237694
238172
  }
237695
- if (attr3.namespaceUri && isUnknownAttributeNamespace(attr3.namespaceUri)) {
237696
- bump(unknownAttributeCounts, `${attr3.localName}@${attr3.namespaceUri}`, anchor);
238173
+ if (attr4.namespaceUri && isUnknownAttributeNamespace(attr4.namespaceUri)) {
238174
+ bump(unknownAttributeCounts, `${attr4.localName}@${attr4.namespaceUri}`, anchor);
237697
238175
  }
237698
238176
  }
237699
238177
  if (ns === "http://schemas.openxmlformats.org/wordprocessingml/2006/main") {
@@ -237978,15 +238456,15 @@ function currentAnchor(parser) {
237978
238456
  };
237979
238457
  }
237980
238458
  function findAttrValue(tag, localName2) {
237981
- for (const attr3 of tag.attributes) {
237982
- if (attr3.localName === localName2)
237983
- return attr3.value;
238459
+ for (const attr4 of tag.attributes) {
238460
+ if (attr4.localName === localName2)
238461
+ return attr4.value;
237984
238462
  }
237985
238463
  return null;
237986
238464
  }
237987
238465
  function readXmlSpace2(tag) {
237988
- const attr3 = readXmlAttribute(tag, "http://www.w3.org/XML/1998/namespace", "space");
237989
- return attr3?.value === "preserve" || attr3?.value === "default" ? attr3.value : null;
238466
+ const attr4 = readXmlAttribute(tag, "http://www.w3.org/XML/1998/namespace", "space");
238467
+ return attr4?.value === "preserve" || attr4?.value === "default" ? attr4.value : null;
237990
238468
  }
237991
238469
  function bump(map3, key3, anchor) {
237992
238470
  if (!key3)
@@ -238700,12 +239178,12 @@ function colorFromBackgroundAttrs(attrs) {
238700
239178
  const wColor = readXmlAttribute({ attributes: [...attrs] }, NS_W, "color");
238701
239179
  if (wColor)
238702
239180
  return normalizeDocumentBackgroundColor(wColor.value);
238703
- for (const attr3 of attrs) {
238704
- if (attr3.localName === "color" && (!attr3.namespaceUri || attr3.namespaceUri === NS_W)) {
238705
- return normalizeDocumentBackgroundColor(attr3.value);
239181
+ for (const attr4 of attrs) {
239182
+ if (attr4.localName === "color" && (!attr4.namespaceUri || attr4.namespaceUri === NS_W)) {
239183
+ return normalizeDocumentBackgroundColor(attr4.value);
238706
239184
  }
238707
- if (attr3.name === "color" || attr3.name === "w:color") {
238708
- return normalizeDocumentBackgroundColor(attr3.value);
239185
+ if (attr4.name === "color" || attr4.name === "w:color") {
239186
+ return normalizeDocumentBackgroundColor(attr4.value);
238709
239187
  }
238710
239188
  }
238711
239189
  return null;
@@ -243265,8 +243743,8 @@ function applyOneProperty(inner, key3, value, emit) {
243265
243743
  if (v === null)
243266
243744
  return null;
243267
243745
  if (typeof v === "string") {
243268
- const attr3 = escapeXmlAttribute(v);
243269
- return `<${w}:rFonts ${w}:ascii="${attr3}" ${w}:hAnsi="${attr3}"/>`;
243746
+ const attr4 = escapeXmlAttribute(v);
243747
+ return `<${w}:rFonts ${w}:ascii="${attr4}" ${w}:hAnsi="${attr4}"/>`;
243270
243748
  }
243271
243749
  if (v && typeof v === "object") {
243272
243750
  const obj = v;
@@ -243282,11 +243760,11 @@ function applyOneProperty(inner, key3, value, emit) {
243282
243760
  csTheme: `${w}:csTheme`,
243283
243761
  hint: `${w}:hint`
243284
243762
  };
243285
- for (const [k, attr3] of Object.entries(keyToAttr)) {
243763
+ for (const [k, attr4] of Object.entries(keyToAttr)) {
243286
243764
  const raw = obj[k];
243287
243765
  if (raw === undefined || raw === null)
243288
243766
  continue;
243289
- attrs.push(`${attr3}="${escapeXmlAttribute(String(raw))}"`);
243767
+ attrs.push(`${attr4}="${escapeXmlAttribute(String(raw))}"`);
243290
243768
  }
243291
243769
  if (attrs.length === 0)
243292
243770
  return null;
@@ -244300,7 +244778,7 @@ function restoreParagraphMarkFormattingSnapshot(beforeXml, liveXml, namespaceBin
244300
244778
  if (before.markers.length === 0 && live.markers.length === 0)
244301
244779
  return beforeXml;
244302
244780
  for (const marker of live.markers) {
244303
- const prefixes = new Set([marker.tag.prefix ?? "", ...marker.tag.attributes.map((attr3) => attr3.prefix).filter((prefix3) => !!prefix3 && prefix3 !== "xml" && prefix3 !== "xmlns")]);
244781
+ const prefixes = new Set([marker.tag.prefix ?? "", ...marker.tag.attributes.map((attr4) => attr4.prefix).filter((prefix3) => !!prefix3 && prefix3 !== "xml" && prefix3 !== "xmlns")]);
244304
244782
  for (const prefix3 of prefixes) {
244305
244783
  if (marker.namespaceBindings[prefix3] !== before.root.namespaceBindings[prefix3])
244306
244784
  return null;
@@ -247147,7 +247625,7 @@ function localDependencyInventory(xml, namespaceBindings, removedCommentRoots) {
247147
247625
  const inventory = [];
247148
247626
  for (const range of [...parsed.ranges].sort((left, right) => left.start - right.start)) {
247149
247627
  const name = range.tag.localName;
247150
- if (["commentRangeStart", "commentRangeEnd", "commentReference"].includes(name) && range.tag.attributes.some((attr3) => attr3.localName === "id" && removedCommentRoots.has(attr3.value)))
247628
+ if (["commentRangeStart", "commentRangeEnd", "commentReference"].includes(name) && range.tag.attributes.some((attr4) => attr4.localName === "id" && removedCommentRoots.has(attr4.value)))
247151
247629
  continue;
247152
247630
  if (!resources.has(name) && name !== "hyperlink")
247153
247631
  continue;
@@ -256590,7 +257068,7 @@ function propertySurface(xml, namespaceBindings) {
256590
257068
  for (const range of ranges) {
256591
257069
  while (stack.length && range.start >= stack[stack.length - 1].closeStart)
256592
257070
  stack.pop();
256593
- if (range.tag.attributes.some((attr3) => attr3.namespaceUri.includes("/relationships")) && [...stack, range].some((ancestor) => ancestor.tag.namespaceUri === NS_W && Object.values(PROPERTY_BLOCKS).some((names) => names.includes(ancestor.tag.localName))))
257071
+ if (range.tag.attributes.some((attr4) => attr4.namespaceUri.includes("/relationships")) && [...stack, range].some((ancestor) => ancestor.tag.namespaceUri === NS_W && Object.values(PROPERTY_BLOCKS).some((names) => names.includes(ancestor.tag.localName))))
256594
257072
  return null;
256595
257073
  const parent = stack[stack.length - 1];
256596
257074
  if (parent) {
@@ -257093,14 +257571,14 @@ function linearSpaceDiff(oldSeq, newSeq, isEqual, keyOf) {
257093
257571
  x2[column >>> 5] |= 1 << (column & 31);
257094
257572
  let carry = 1;
257095
257573
  let borrow = 0;
257096
- for (let word3 = 0;word3 < bits2.length; word3 += 1) {
257097
- const previous = bits2[word3];
257574
+ for (let word4 = 0;word4 < bits2.length; word4 += 1) {
257575
+ const previous = bits2[word4];
257098
257576
  const shifted = (previous << 1 | carry) >>> 0;
257099
257577
  carry = previous >>> 31;
257100
257578
  const subtrahend = shifted + borrow;
257101
- const difference = x2[word3] - subtrahend >>> 0;
257102
- borrow = x2[word3] < subtrahend ? 1 : 0;
257103
- bits2[word3] = x2[word3] & ~difference;
257579
+ const difference = x2[word4] - subtrahend >>> 0;
257580
+ borrow = x2[word4] < subtrahend ? 1 : 0;
257581
+ bits2[word4] = x2[word4] & ~difference;
257104
257582
  }
257105
257583
  }
257106
257584
  const row2 = new Uint32Array(newLength + 1);
@@ -257339,7 +257817,7 @@ function prepareCompareTableBlockReplay(bytes, step2) {
257339
257817
  cursor = range.end;
257340
257818
  }
257341
257819
  const namespaceBindings = new Map(Object.entries(body.namespaceBindings));
257342
- const occupiedIds = ranges.flatMap((range) => range.tag.namespaceUri === NS_W && ["p", "tr"].includes(range.tag.localName) ? range.tag.attributes.filter((attr3) => attr3.namespaceUri === W146 && attr3.localName === "paraId").map((attr3) => attr3.value.toUpperCase()) : []);
257820
+ const occupiedIds = ranges.flatMap((range) => range.tag.namespaceUri === NS_W && ["p", "tr"].includes(range.tag.localName) ? range.tag.attributes.filter((attr4) => attr4.namespaceUri === W146 && attr4.localName === "paraId").map((attr4) => attr4.value.toUpperCase()) : []);
257343
257821
  const ids = safeTableParagraphIds(step2.tableXml, step2.storyId, body.namespaceBindings);
257344
257822
  if (!ids)
257345
257823
  return null;
@@ -257359,9 +257837,9 @@ function prepareCompareTableBlockReplay(bytes, step2) {
257359
257837
  }
257360
257838
  if (step2.kind !== "insertTable" || !["before", "after"].includes(step2.placement))
257361
257839
  return null;
257362
- const anchors = children.filter((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "p" && range.tag.attributes.some((attr3) => attr3.namespaceUri === W146 && attr3.localName === "paraId" && attr3.value === step2.anchorBlockId));
257840
+ const anchors = children.filter((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "p" && range.tag.attributes.some((attr4) => attr4.namespaceUri === W146 && attr4.localName === "paraId" && attr4.value === step2.anchorBlockId));
257363
257841
  const normalizedIds = ids.map((id) => id.toUpperCase());
257364
- if (anchors.length !== 1 || ranges.some((range) => range.tag.attributes.some((attr3) => attr3.namespaceUri === W146 && attr3.localName === "paraId" && normalizedIds.includes(attr3.value.toUpperCase()))))
257842
+ if (anchors.length !== 1 || ranges.some((range) => range.tag.attributes.some((attr4) => attr4.namespaceUri === W146 && attr4.localName === "paraId" && normalizedIds.includes(attr4.value.toUpperCase()))))
257365
257843
  return null;
257366
257844
  const at = byteOffsets[step2.placement === "before" ? anchors[0].start : anchors[0].end];
257367
257845
  return { startByte: at, endByte: at, namespaceBindings, paragraphIds: ids, occupiedIds };
@@ -257374,7 +257852,7 @@ function safeTableParagraphIds(tableXml, storyId, namespaceBindings) {
257374
257852
  const root = payload.ranges.find((range) => range.start === 0 && range.end === tableXml.length);
257375
257853
  if (payload.errors.length || root?.tag.namespaceUri !== NS_W || root.tag.localName !== "tbl")
257376
257854
  return null;
257377
- if (payload.ranges.some((range) => range.tag.namespaceUri === NS_W && (UNSAFE.has(range.tag.localName) || range.tag.localName.endsWith("PrChange")) || range.tag.attributes.some((attr3) => attr3.namespaceUri.includes("/relationships"))))
257855
+ if (payload.ranges.some((range) => range.tag.namespaceUri === NS_W && (UNSAFE.has(range.tag.localName) || range.tag.localName.endsWith("PrChange")) || range.tag.attributes.some((attr4) => attr4.namespaceUri.includes("/relationships"))))
257378
257856
  return null;
257379
257857
  const tableCatalog = buildTableCatalog({
257380
257858
  bytes: TE42.encode(tableXml),
@@ -257384,8 +257862,8 @@ function safeTableParagraphIds(tableXml, storyId, namespaceBindings) {
257384
257862
  if (tableCatalog.tables.length !== 1 || tableCatalog.tables.some((table) => table.containsNestedTable || !table.isRectangular || table.hasGridSpan || table.hasVMerge))
257385
257863
  return null;
257386
257864
  const paragraphs2 = payload.ranges.filter((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "p");
257387
- const paragraphIds = paragraphs2.map((range) => range.tag.attributes.find((attr3) => attr3.namespaceUri === W146 && attr3.localName === "paraId")?.value);
257388
- const rowIds = payload.ranges.filter((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "tr").flatMap((range) => range.tag.attributes.filter((attr3) => attr3.namespaceUri === W146 && attr3.localName === "paraId").map((attr3) => attr3.value));
257865
+ const paragraphIds = paragraphs2.map((range) => range.tag.attributes.find((attr4) => attr4.namespaceUri === W146 && attr4.localName === "paraId")?.value);
257866
+ const rowIds = payload.ranges.filter((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "tr").flatMap((range) => range.tag.attributes.filter((attr4) => attr4.namespaceUri === W146 && attr4.localName === "paraId").map((attr4) => attr4.value));
257389
257867
  const normalizedIds = [...paragraphIds, ...rowIds].map((id) => id?.toUpperCase());
257390
257868
  if (!paragraphs2.length || normalizedIds.some((id) => !id || !/^[0-7][0-9A-F]{7}$/.test(id) || id === "00000000") || new Set(normalizedIds).size !== normalizedIds.length)
257391
257869
  return null;
@@ -257398,10 +257876,10 @@ function remapReplacementTableParagraphIds(xml, namespaceBindings, nextId) {
257398
257876
  });
257399
257877
  const paragraphIds = [];
257400
257878
  for (const range of parsed.ranges.filter((range2) => range2.tag.namespaceUri === NS_W && ["p", "tr"].includes(range2.tag.localName)).sort((a, b) => b.start - a.start)) {
257401
- const attr3 = range.tag.attributes.find((attr4) => attr4.namespaceUri === W146 && attr4.localName === "paraId");
257402
- if (!attr3)
257879
+ const attr4 = range.tag.attributes.find((attr5) => attr5.namespaceUri === W146 && attr5.localName === "paraId");
257880
+ if (!attr4)
257403
257881
  continue;
257404
- const raw = [...scanRawXmlAttributes(xml.slice(range.start, range.openEnd))].find((raw2) => raw2.name === attr3.name);
257882
+ const raw = [...scanRawXmlAttributes(xml.slice(range.start, range.openEnd))].find((raw2) => raw2.name === attr4.name);
257405
257883
  const id = nextId();
257406
257884
  if (range.tag.localName === "p")
257407
257885
  paragraphIds.unshift(id);
@@ -260378,11 +260856,11 @@ function splitCompareManualBreakSegments(xml, prefix2) {
260378
260856
  const childXml = xml.slice(child.start, child.end);
260379
260857
  const carrier = children.length === 1 ? xml.slice(run.start, run.end) : `${openTag}${childXml}</${prefix2}:r>`;
260380
260858
  if (child.tag.localName === "t") {
260381
- if (child.tag.isSelfClosing || xml.slice(child.openEnd, child.closeStart).includes("<") || child.tag.attributes.some((attr3) => !(attr3.namespaceUri === "http://www.w3.org/XML/1998/namespace" && attr3.localName === "space")))
260859
+ if (child.tag.isSelfClosing || xml.slice(child.openEnd, child.closeStart).includes("<") || child.tag.attributes.some((attr4) => !(attr4.namespaceUri === "http://www.w3.org/XML/1998/namespace" && attr4.localName === "space")))
260382
260860
  return null;
260383
260861
  spans[spans.length - 1] += carrier;
260384
260862
  } else if (child.tag.localName === "br") {
260385
- if (xml.slice(child.openEnd, child.closeStart).trim() || child.tag.attributes.some((attr3) => attr3.namespaceUri !== NS_W || (attr3.localName === "type" ? attr3.value !== "textWrapping" : attr3.localName !== "clear" || !["none", "left", "right", "all"].includes(attr3.value))))
260863
+ if (xml.slice(child.openEnd, child.closeStart).trim() || child.tag.attributes.some((attr4) => attr4.namespaceUri !== NS_W || (attr4.localName === "type" ? attr4.value !== "textWrapping" : attr4.localName !== "clear" || !["none", "left", "right", "all"].includes(attr4.value))))
260386
260864
  return null;
260387
260865
  breaks.push(carrier);
260388
260866
  spans.push("");
@@ -261212,8 +261690,8 @@ function renderTrackedSectionReplay(step2, stamp, context) {
261212
261690
  const before = step2.beforeXml;
261213
261691
  const names = replayNames(context.after.namespaceBindings, context.after.tag.prefix);
261214
261692
  const markerName = qualifiedName(names.elementPrefix, "sectPrChange");
261215
- const attr3 = (name) => qualifiedName(names.attributePrefix, name);
261216
- const marker = `<${markerName}${names.namespaceDeclaration} ${attr3("id")}="${stamp.wId}" ${attr3("author")}="${escapeXmlAttribute(stamp.author.name)}"` + ` ${attr3("date")}="${escapeXmlAttribute(stamp.date)}">${before}</${markerName}>`;
261693
+ const attr4 = (name) => qualifiedName(names.attributePrefix, name);
261694
+ const marker = `<${markerName}${names.namespaceDeclaration} ${attr4("id")}="${stamp.wId}" ${attr4("author")}="${escapeXmlAttribute(stamp.author.name)}"` + ` ${attr4("date")}="${escapeXmlAttribute(stamp.date)}">${before}</${markerName}>`;
261217
261695
  if (context.after.tag.isSelfClosing) {
261218
261696
  return step2.afterXml.slice(0, -2) + `>${marker}</${context.after.tag.name}>`;
261219
261697
  }
@@ -261240,10 +261718,10 @@ function renderTrackedBookmarkMarkerReplay(step2, stamp, context) {
261240
261718
  function renderTrackedWrapper(kind, inner, stamp, context) {
261241
261719
  const names = replayNames(context.parentNamespaceBindings, context.before.tag.prefix);
261242
261720
  const wrapperName = qualifiedName(names.elementPrefix, kind);
261243
- const attr3 = (name) => qualifiedName(names.attributePrefix, name);
261721
+ const attr4 = (name) => qualifiedName(names.attributePrefix, name);
261244
261722
  const rsidAttribute = kind === "del" ? "rsidDel" : "rsidR";
261245
- const initials = stamp.author.initials ? ` ${attr3("initials")}="${escapeXmlAttribute(stamp.author.initials)}"` : "";
261246
- return `<${wrapperName}${names.namespaceDeclaration} ${attr3("id")}="${stamp.wId}" ${attr3("author")}="${escapeXmlAttribute(stamp.author.name)}"${initials}` + ` ${attr3("date")}="${escapeXmlAttribute(stamp.date)}" ${attr3(rsidAttribute)}="${stamp.rsid}">${inner}</${wrapperName}>`;
261723
+ const initials = stamp.author.initials ? ` ${attr4("initials")}="${escapeXmlAttribute(stamp.author.initials)}"` : "";
261724
+ return `<${wrapperName}${names.namespaceDeclaration} ${attr4("id")}="${stamp.wId}" ${attr4("author")}="${escapeXmlAttribute(stamp.author.name)}"${initials}` + ` ${attr4("date")}="${escapeXmlAttribute(stamp.date)}" ${attr4(rsidAttribute)}="${stamp.rsid}">${inner}</${wrapperName}>`;
261247
261725
  }
261248
261726
  function readResolvedReplayAttribute(element, localName2) {
261249
261727
  return element.tag.attributes.find((attribute2) => attribute2.namespaceUri === NS_W && attribute2.localName === localName2)?.value ?? null;
@@ -271961,7 +272439,7 @@ function removeCommentsExtendedEntries3(xml, paraIds) {
271961
272439
  return { ok: true, value: next };
271962
272440
  }
271963
272441
  function removeCommentsExtendedParentRefs(xml, paraIds) {
271964
- return xml.replace(/\s+\b(?:w14|w15):(?:paraIdParent|parentId)="([^"]*)"/g, (attr3, parentParaId) => paraIds.has(parentParaId) ? "" : attr3);
272442
+ return xml.replace(/\s+\b(?:w14|w15):(?:paraIdParent|parentId)="([^"]*)"/g, (attr4, parentParaId) => paraIds.has(parentParaId) ? "" : attr4);
271965
272443
  }
271966
272444
  function removeCommentsIdsEntries3(xml, paraIds) {
271967
272445
  const re = /<[\w.-]+:commentId\b[^>]*\/?>/g;
@@ -276015,8 +276493,8 @@ function sanitizeWordNamespaces(bytes) {
276015
276493
  function sanitizeReviewMetadataOpeningTag(open2, element) {
276016
276494
  if (element.tag.namespaceUri !== WORD_NS2)
276017
276495
  return open2;
276018
- const illegal = ["ins", "del", "moveFrom", "moveTo"].includes(element.tag.localName) ? element.tag.attributes.filter((attr3) => attr3.namespaceUri === WORD_NS2 && ["rsidR", "rsidDel"].includes(attr3.localName)) : [];
276019
- const comments = element.tag.localName === "comment" ? element.tag.attributes.filter((attr3) => attr3.namespaceUri === COMMENT_META_NS) : [];
276496
+ const illegal = ["ins", "del", "moveFrom", "moveTo"].includes(element.tag.localName) ? element.tag.attributes.filter((attr4) => attr4.namespaceUri === WORD_NS2 && ["rsidR", "rsidDel"].includes(attr4.localName)) : [];
276497
+ const comments = element.tag.localName === "comment" ? element.tag.attributes.filter((attr4) => attr4.namespaceUri === COMMENT_META_NS) : [];
276020
276498
  if (!illegal.length && !comments.length)
276021
276499
  return open2;
276022
276500
  let tag = open2;
@@ -276028,7 +276506,7 @@ function sanitizeReviewMetadataOpeningTag(open2, element) {
276028
276506
  return prefix2;
276029
276507
  };
276030
276508
  const markIgnorable = (prefix2) => {
276031
- const current = [...scanRawXmlAttributes(tag)].find((attr3) => attr3.localName === "Ignorable" && bindings2[attr3.prefix ?? ""] === MC_NS3);
276509
+ const current = [...scanRawXmlAttributes(tag)].find((attr4) => attr4.localName === "Ignorable" && bindings2[attr4.prefix ?? ""] === MC_NS3);
276032
276510
  if (current) {
276033
276511
  const value = tag.slice(current.valueStart, current.valueEnd);
276034
276512
  if (!value.trim().split(/\s+/).includes(prefix2)) {
@@ -276042,37 +276520,37 @@ function sanitizeReviewMetadataOpeningTag(open2, element) {
276042
276520
  };
276043
276521
  if (illegal.length) {
276044
276522
  const prefix2 = Object.keys(bindings2).find((key3) => key3.length > 0 && bindings2[key3] === TRACKED_CHANGE_NS2) ?? freePrefix("sdtr");
276045
- const identityPrefixes = new Set([prefix2, ...element.tag.attributes.filter((attr3) => attr3.namespaceUri === TRACKED_CHANGE_NS2 && illegal.some((legacy) => legacy.localName === attr3.localName)).flatMap((attr3) => attr3.prefix ? [attr3.prefix] : [])]);
276523
+ const identityPrefixes = new Set([prefix2, ...element.tag.attributes.filter((attr4) => attr4.namespaceUri === TRACKED_CHANGE_NS2 && illegal.some((legacy) => legacy.localName === attr4.localName)).flatMap((attr4) => attr4.prefix ? [attr4.prefix] : [])]);
276046
276524
  for (const identityPrefix of identityPrefixes) {
276047
- if (![...scanRawXmlAttributes(tag)].some((attr3) => attr3.name === `xmlns:${identityPrefix}`)) {
276525
+ if (![...scanRawXmlAttributes(tag)].some((attr4) => attr4.name === `xmlns:${identityPrefix}`)) {
276048
276526
  tag = insertRootAttribute(tag, `xmlns:${identityPrefix}="${TRACKED_CHANGE_NS2}"`);
276049
276527
  bindings2[identityPrefix] = TRACKED_CHANGE_NS2;
276050
276528
  }
276051
276529
  }
276052
- const names = new Set(illegal.map((attr3) => attr3.name));
276530
+ const names = new Set(illegal.map((attr4) => attr4.name));
276053
276531
  const attributes = [...scanRawXmlAttributes(tag)];
276054
276532
  const updates = new Map;
276055
- for (const attr3 of attributes) {
276056
- if (!names.has(attr3.name))
276533
+ for (const attr4 of attributes) {
276534
+ if (!names.has(attr4.name))
276057
276535
  continue;
276058
- const existing = attributes.find((candidate2) => candidate2.localName === attr3.localName && bindings2[candidate2.prefix ?? ""] === TRACKED_CHANGE_NS2);
276536
+ const existing = attributes.find((candidate2) => candidate2.localName === attr4.localName && bindings2[candidate2.prefix ?? ""] === TRACKED_CHANGE_NS2);
276059
276537
  if (existing)
276060
- updates.set(existing.name, attr3.value);
276538
+ updates.set(existing.name, attr4.value);
276061
276539
  }
276062
- for (const attr3 of attributes.reverse()) {
276063
- if (updates.has(attr3.name)) {
276064
- tag = tag.slice(0, attr3.valueStart) + updates.get(attr3.name) + tag.slice(attr3.valueEnd);
276065
- } else if (names.has(attr3.name)) {
276066
- const localName2 = attr3.localName;
276540
+ for (const attr4 of attributes.reverse()) {
276541
+ if (updates.has(attr4.name)) {
276542
+ tag = tag.slice(0, attr4.valueStart) + updates.get(attr4.name) + tag.slice(attr4.valueEnd);
276543
+ } else if (names.has(attr4.name)) {
276544
+ const localName2 = attr4.localName;
276067
276545
  const exists = element.tag.attributes.some((candidate2) => candidate2.localName === localName2 && candidate2.namespaceUri === TRACKED_CHANGE_NS2);
276068
- const replacement2 = exists ? "" : tag.slice(attr3.sourceStart, attr3.sourceEnd).replace(attr3.name, `${prefix2}:${localName2}`);
276069
- tag = tag.slice(0, attr3.sourceStart) + replacement2 + tag.slice(attr3.sourceEnd);
276546
+ const replacement2 = exists ? "" : tag.slice(attr4.sourceStart, attr4.sourceEnd).replace(attr4.name, `${prefix2}:${localName2}`);
276547
+ tag = tag.slice(0, attr4.sourceStart) + replacement2 + tag.slice(attr4.sourceEnd);
276070
276548
  }
276071
276549
  }
276072
276550
  for (const identityPrefix of identityPrefixes)
276073
276551
  markIgnorable(identityPrefix);
276074
276552
  }
276075
- for (const prefix2 of new Set(comments.map((attr3) => attr3.prefix))) {
276553
+ for (const prefix2 of new Set(comments.map((attr4) => attr4.prefix))) {
276076
276554
  if (prefix2)
276077
276555
  markIgnorable(prefix2);
276078
276556
  }
@@ -278300,7 +278778,7 @@ function serializeSDDocumentSessionInternalPackageWithDiagnostics(session, optio
278300
278778
  continue;
278301
278779
  if (internal.state.packageBytes.has(partUri))
278302
278780
  continue;
278303
- finalizeEntry(partUri, bytes);
278781
+ finalizeEntry(partUri, trackedChangesProjection.overrides.get(partUri) ?? bytes);
278304
278782
  }
278305
278783
  for (const [partUri, bytes] of trackedChangesProjection.overrides) {
278306
278784
  if (commentRemovals.has(partUri))
@@ -278441,12 +278919,19 @@ function planSourceBackedStreamingSave(internal, mainPartUri, options) {
278441
278919
  const commentOverrides = normalization.overrides;
278442
278920
  const commentRemovals = EMPTY_PART_URI_SET;
278443
278921
  const commentWarnings = normalization.warnings;
278444
- const trackedChangesProjection = projectTrackedChangesForExport(state, {
278445
- mode,
278446
- replacementMode: internal.trackedChangesReplacementMode,
278447
- baseOverrides: commentOverrides,
278448
- excludedPartUris: hasResidentMain ? EMPTY_PART_URI_SET : new Set([mainPartUri])
278449
- });
278922
+ let trackedChangesProjection;
278923
+ try {
278924
+ trackedChangesProjection = projectTrackedChangesForExport(state, {
278925
+ mode,
278926
+ replacementMode: internal.trackedChangesReplacementMode,
278927
+ baseOverrides: commentOverrides,
278928
+ excludedPartUris: hasResidentMain ? EMPTY_PART_URI_SET : new Set([mainPartUri])
278929
+ });
278930
+ } catch (error48) {
278931
+ if (!(error48 instanceof RevisionIdExportCoverageError))
278932
+ throw error48;
278933
+ throw new SDSourceBackedSaveUnsupportedError("save-overlay-unsupported", error48.partUri, "Revision ID normalization requires a complete ID inventory; the fenced main story cannot be materialized for export.");
278934
+ }
278450
278935
  if (commentRemovals.has(mainPartUri) || !hasResidentMain && (commentOverrides.has(mainPartUri) || trackedChangesProjection.overrides.has(mainPartUri))) {
278451
278936
  throw new SDSourceBackedSaveUnsupportedError("save-overlay-unsupported", mainPartUri, `Save would rewrite the fenced source-backed main story ${mainPartUri}; the streaming overlay path cannot compose a fenced-main rewrite yet.`);
278452
278937
  }
@@ -278563,7 +279048,7 @@ function planSourceBackedStreamingSave(internal, mainPartUri, options) {
278563
279048
  continue;
278564
279049
  if (state.packageBytes.has(partUri))
278565
279050
  continue;
278566
- pushBytes(partUri, bytes);
279051
+ pushBytes(partUri, trackedChangesProjection.overrides.get(partUri) ?? bytes);
278567
279052
  }
278568
279053
  for (const [partUri, bytes] of trackedChangesProjection.overrides) {
278569
279054
  if (partUri === mainPartUri || commentRemovals.has(partUri) || emitted.has(partUri))
@@ -282611,6 +283096,7 @@ var init_sd_document_session = __esm(() => {
282611
283096
  init_hyperlink_catalog();
282612
283097
  init_field_catalog();
282613
283098
  init_remote_paragraph_publication();
283099
+ init_revision_id_export();
282614
283100
  init_resident_review();
282615
283101
  init_canonical_xml_analysis_frame();
282616
283102
  init_catalog_xml_analysis();
@@ -283010,7 +283496,7 @@ function readScalarDocumentProperty(session, name) {
283010
283496
  return missing;
283011
283497
  if (!root)
283012
283498
  return unavailable2;
283013
- const matches = children(root, CUSTOM, "property").filter((property) => property.tag.attributes.some((attr3) => attr3.namespaceUri === "" && attr3.localName === "name" && attr3.value === name));
283499
+ const matches = children(root, CUSTOM, "property").filter((property) => property.tag.attributes.some((attr4) => attr4.namespaceUri === "" && attr4.localName === "name" && attr4.value === name));
283014
283500
  if (!matches.length)
283015
283501
  return missing;
283016
283502
  if (matches.length !== 1 || matches[0].children.length !== 1)
@@ -283026,12 +283512,12 @@ function readScalarDocumentVariable(session, name) {
283026
283512
  return missing;
283027
283513
  if (!root)
283028
283514
  return unavailable2;
283029
- const matches = children(root, W6, "docVars").flatMap((vars) => children(vars, W6, "docVar")).filter((entry) => entry.tag.attributes.some((attr3) => attr3.namespaceUri === W6 && attr3.localName === "name" && attr3.value === name));
283515
+ const matches = children(root, W6, "docVars").flatMap((vars) => children(vars, W6, "docVar")).filter((entry) => entry.tag.attributes.some((attr4) => attr4.namespaceUri === W6 && attr4.localName === "name" && attr4.value === name));
283030
283516
  if (!matches.length)
283031
283517
  return missing;
283032
283518
  if (matches.length !== 1 || matches[0].children.length)
283033
283519
  return unavailable2;
283034
- const value = matches[0].tag.attributes.find((attr3) => attr3.namespaceUri === W6 && attr3.localName === "val");
283520
+ const value = matches[0].tag.attributes.find((attr4) => attr4.namespaceUri === W6 && attr4.localName === "val");
283035
283521
  return value ? { kind: "value", value: value.value } : unavailable2;
283036
283522
  }
283037
283523
  var CP = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties", DC = "http://purl.org/dc/elements/1.1/", DCTERMS = "http://purl.org/dc/terms/", APP = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties", CUSTOM = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties", VT = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", W6 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", TD88, unavailable2, missing, BUILTINS;
@@ -283986,6 +284472,8 @@ var init_sd_document_session_internal = __esm(() => {
283986
284472
  init_core_properties();
283987
284473
  init_docx_package_sanitizer();
283988
284474
  init_scalar_properties();
284475
+ init_revision_id_export();
284476
+ init_row_height_review_geometry();
283989
284477
  init_sd_document_session();
283990
284478
  init_review_projection_overlay();
283991
284479
  init_ensure_para_ids();
@@ -312627,6 +313115,7 @@ var init_registry3 = __esm(() => {
312627
313115
  "tables.applyBorderPreset",
312628
313116
  "tables.setBorders",
312629
313117
  "tables.setLayout",
313118
+ "tables.setColumnWidth",
312630
313119
  "tables.setRowHeight",
312631
313120
  "tables.setRowOptions",
312632
313121
  "tables.setCellProperties",
@@ -312765,6 +313254,13 @@ var init_source = __esm(() => {
312765
313254
  relatedV1Operation: "replace",
312766
313255
  rationale: "Host-owned cut/paste and pointer-drag move authoring primitive. It returns the text-mutation receipt used for atomic render and history finalization."
312767
313256
  },
313257
+ {
313258
+ method: "createDocumentApi(host.adapter).tables.resizeColumns",
313259
+ stability: "internal",
313260
+ workerWired: true,
313261
+ relatedV1Operation: "tables.setColumnWidth",
313262
+ rationale: "Native column-drag primitive: commit the complete width grid and fixed layout as one property revision and history entry."
313263
+ },
312768
313264
  {
312769
313265
  method: "createDocumentApi(host.adapter).tables.applyTableProperties",
312770
313266
  stability: "consumer-supported",
@@ -312960,8 +313456,8 @@ var init_source = __esm(() => {
312960
313456
  revisionBinding: "unbound",
312961
313457
  durability: "save-reopen",
312962
313458
  remapBehavior: "invalidate",
312963
- invalidationBehavior: "Tracked-change refs are stable across save/reopen while the change is pending. Accept/reject invalidates.",
312964
- refreshGuidance: "After accept/reject, drop the held tracked-change address; re-list from `trackChanges.list` for any remaining changes.",
313459
+ invalidationBehavior: "Pending tracked-change refs with Word-valid revision IDs are stable across save/reopen. DOCX export normalizes out-of-range revision IDs without changing live refs; those normalized refs must be rediscovered after reopening. Accept/reject invalidates.",
313460
+ refreshGuidance: "After accept/reject, drop the held tracked-change address; re-list from `trackChanges.list` for any remaining changes. Re-list after reopening an export that normalized out-of-range revision IDs.",
312965
313461
  lifecycleFixture: "covered"
312966
313462
  },
312967
313463
  {
@@ -319445,15 +319941,15 @@ var require_js2xml = __commonJS((exports, module) => {
319445
319941
  if ("attributesFn" in options) {
319446
319942
  attributes = options.attributesFn(attributes, currentElementName, currentElement);
319447
319943
  }
319448
- var key3, attr3, attrName, quote, result = [];
319944
+ var key3, attr4, attrName, quote, result = [];
319449
319945
  for (key3 in attributes) {
319450
319946
  if (attributes.hasOwnProperty(key3) && attributes[key3] !== null && attributes[key3] !== undefined) {
319451
319947
  quote = options.noQuotesForNativeAttributes && typeof attributes[key3] !== "string" ? "" : '"';
319452
- attr3 = "" + attributes[key3];
319453
- attr3 = attr3.replace(/"/g, "&quot;");
319454
- attrName = "attributeNameFn" in options ? options.attributeNameFn(key3, attr3, currentElementName, currentElement) : key3;
319948
+ attr4 = "" + attributes[key3];
319949
+ attr4 = attr4.replace(/"/g, "&quot;");
319950
+ attrName = "attributeNameFn" in options ? options.attributeNameFn(key3, attr4, currentElementName, currentElement) : key3;
319455
319951
  result.push(options.spaces && options.indentAttributes ? writeIndentation(options, depth + 1, false) : " ");
319456
- result.push(attrName + "=" + quote + ("attributeValueFn" in options ? options.attributeValueFn(attr3, key3, currentElementName, currentElement) : attr3) + quote);
319952
+ result.push(attrName + "=" + quote + ("attributeValueFn" in options ? options.attributeValueFn(attr4, key3, currentElementName, currentElement) : attr4) + quote);
319457
319953
  }
319458
319954
  }
319459
319955
  if (attributes && Object.keys(attributes).length && options.spaces && options.indentAttributes) {
@@ -319784,14 +320280,14 @@ function findChildren(node3, name) {
319784
320280
  return [];
319785
320281
  return node3.elements.filter((el) => el && el.name === name);
319786
320282
  }
319787
- function attr3(node3, name) {
320283
+ function attr4(node3, name) {
319788
320284
  const value = node3?.attributes?.[name];
319789
320285
  return value == null ? undefined : String(value);
319790
320286
  }
319791
320287
  function parseOnOff2(node3) {
319792
320288
  if (!node3)
319793
320289
  return;
319794
- const raw = attr3(node3, "w:val");
320290
+ const raw = attr4(node3, "w:val");
319795
320291
  if (raw == null)
319796
320292
  return true;
319797
320293
  const lower = raw.trim().toLowerCase();
@@ -319802,14 +320298,14 @@ function parseOnOff2(node3) {
319802
320298
  return true;
319803
320299
  }
319804
320300
  function parseNumberVal(node3) {
319805
- const raw = attr3(node3, "w:val");
320301
+ const raw = attr4(node3, "w:val");
319806
320302
  if (raw == null)
319807
320303
  return;
319808
320304
  const num = Number(raw);
319809
320305
  return Number.isFinite(num) ? num : undefined;
319810
320306
  }
319811
320307
  function parseStringVal(node3) {
319812
- return attr3(node3, "w:val");
320308
+ return attr4(node3, "w:val");
319813
320309
  }
319814
320310
  var import_xml_js, DECODER3, ST_ON, ST_OFF;
319815
320311
  var init_parse_xml = __esm(() => {
@@ -324863,8 +325359,8 @@ function parseContainerXml(xml, localName2) {
324863
325359
  };
324864
325360
  }
324865
325361
  function ensureNamespaceOnRoot(xml, prefix2, uri) {
324866
- const attr4 = `xmlns:${prefix2}=`;
324867
- if (xml.includes(attr4))
325362
+ const attr5 = `xmlns:${prefix2}=`;
325363
+ if (xml.includes(attr5))
324868
325364
  return xml;
324869
325365
  return xml.replace(/<([\w.-]+:[\w.-]+\b)([^>]*)>/, `<$1$2 xmlns:${prefix2}="${uri}">`);
324870
325366
  }
@@ -326580,7 +327076,7 @@ function evaluateScalarField(context, source, cachedText, snapshot2) {
326580
327076
  text = text.toLowerCase();
326581
327077
  break;
326582
327078
  case "Caps":
326583
- text = text.replace(/\p{L}[\p{L}\p{M}]*/gu, (word3) => word3[0].toUpperCase() + word3.slice(1).toLowerCase());
327079
+ text = text.replace(/\p{L}[\p{L}\p{M}]*/gu, (word4) => word4[0].toUpperCase() + word4.slice(1).toLowerCase());
326584
327080
  break;
326585
327081
  case "FirstCap":
326586
327082
  text = text.replace(/\p{L}/u, (letter) => letter.toUpperCase());
@@ -327418,18 +327914,18 @@ function readInlinePatchFromRPrXml(rPrXml) {
327418
327914
  const children2 = parsed ? parseTopLevelChildren(parsed.inner) : [];
327419
327915
  const patch = {};
327420
327916
  const child = (localName2) => children2.find((candidate2) => candidate2.localName === localName2);
327421
- const attr4 = (xml, localName2) => {
327917
+ const attr5 = (xml, localName2) => {
327422
327918
  const raw = readAttr2(xml, localName2);
327423
327919
  return raw == null ? undefined : decodeXmlText8(raw);
327424
327920
  };
327425
327921
  const scaled = (localName2, divisor) => {
327426
327922
  const node3 = child(localName2);
327427
- const raw = node3 ? Number.parseInt(attr4(node3.xml, "val") ?? "", 10) : Number.NaN;
327923
+ const raw = node3 ? Number.parseInt(attr5(node3.xml, "val") ?? "", 10) : Number.NaN;
327428
327924
  return Number.isFinite(raw) ? raw / divisor : undefined;
327429
327925
  };
327430
327926
  const stringVal = (localName2) => {
327431
327927
  const node3 = child(localName2);
327432
- return node3 ? attr4(node3.xml, "val") : undefined;
327928
+ return node3 ? attr5(node3.xml, "val") : undefined;
327433
327929
  };
327434
327930
  const objectOf = (localName2, attrMap, numeric = new Set) => {
327435
327931
  const node3 = child(localName2);
@@ -327437,7 +327933,7 @@ function readInlinePatchFromRPrXml(rPrXml) {
327437
327933
  return;
327438
327934
  const out = {};
327439
327935
  for (const [key3, attrName] of Object.entries(attrMap)) {
327440
- const raw = attr4(node3.xml, attrName);
327936
+ const raw = attr5(node3.xml, attrName);
327441
327937
  if (raw == null || raw === "")
327442
327938
  continue;
327443
327939
  out[key3] = numeric.has(key3) ? Number(raw) : raw;
@@ -327451,13 +327947,13 @@ function readInlinePatchFromRPrXml(rPrXml) {
327451
327947
  }
327452
327948
  const underline = child("u");
327453
327949
  if (underline) {
327454
- const style = attr4(underline.xml, "val");
327950
+ const style = attr5(underline.xml, "val");
327455
327951
  if (style === "none" || style === "0")
327456
327952
  patch.underline = false;
327457
327953
  else {
327458
327954
  const value2 = { style: style ?? "single" };
327459
- const color2 = attr4(underline.xml, "color");
327460
- const themeColor = attr4(underline.xml, "themeColor");
327955
+ const color2 = attr5(underline.xml, "color");
327956
+ const themeColor = attr5(underline.xml, "themeColor");
327461
327957
  if (color2)
327462
327958
  value2.color = color2;
327463
327959
  if (themeColor)
@@ -327471,7 +327967,7 @@ function readInlinePatchFromRPrXml(rPrXml) {
327471
327967
  else {
327472
327968
  const shading2 = child("shd");
327473
327969
  if (shading2 && isHighlightFallbackShdXml3(shading2.xml))
327474
- patch.highlight = attr4(shading2.xml, "fill");
327970
+ patch.highlight = attr5(shading2.xml, "fill");
327475
327971
  }
327476
327972
  const color = stringVal("color");
327477
327973
  if (color)
@@ -327552,8 +328048,8 @@ function readInlinePatchFromRPrXml(rPrXml) {
327552
328048
  const stylisticSets = child("stylisticSets");
327553
328049
  if (stylisticSets) {
327554
328050
  patch.stylisticSets = [...stylisticSets.xml.matchAll(/<[\w.-]+:ss\b[^>]*>/g)].map(([tag]) => {
327555
- const val = attr4(tag, "val");
327556
- return { id: Number(attr4(tag, "id")), val: val !== "0" && val !== "false" };
328051
+ const val = attr5(tag, "val");
328052
+ return { id: Number(attr5(tag, "id")), val: val !== "0" && val !== "false" };
327557
328053
  });
327558
328054
  }
327559
328055
  return patch;
@@ -333468,7 +333964,7 @@ function collectPermissionRanges(context, includeUnpaired) {
333468
333964
  }
333469
333965
  function collectPermissionMarkers(xml) {
333470
333966
  return collectXmlElementRanges(xml).ranges.filter(({ tag }) => tag.namespaceUri === WORD_NAMESPACE7 && (tag.localName === "permStart" || tag.localName === "permEnd")).map(({ tag, start, end }) => {
333471
- const attribute2 = (name) => tag.attributes.find((attr4) => attr4.namespaceUri === WORD_NAMESPACE7 && attr4.localName === name)?.value;
333967
+ const attribute2 = (name) => tag.attributes.find((attr5) => attr5.namespaceUri === WORD_NAMESPACE7 && attr5.localName === name)?.value;
333472
333968
  const group = attribute2("edGrp");
333473
333969
  const editor = attribute2("ed");
333474
333970
  return {
@@ -333953,7 +334449,7 @@ function parseRoot(xml, localName2, namespace) {
333953
334449
  function parseSettings(xml) {
333954
334450
  const parsed = parseRoot(xml, "settings", WORD_NAMESPACES2);
333955
334451
  const namespace = parsed.root.tag.namespaceUri;
333956
- if (parsed.ranges.some((range) => WORD_NAMESPACES2.has(range.tag.namespaceUri) && range.tag.namespaceUri !== namespace || range.tag.attributes.some((attr4) => WORD_NAMESPACES2.has(attr4.namespaceUri) && attr4.namespaceUri !== namespace))) {
334452
+ if (parsed.ranges.some((range) => WORD_NAMESPACES2.has(range.tag.namespaceUri) && range.tag.namespaceUri !== namespace || range.tag.attributes.some((attr5) => WORD_NAMESPACES2.has(attr5.namespaceUri) && attr5.namespaceUri !== namespace))) {
333957
334453
  throw operationError("PRECONDITION_FAILED", "Settings XML mixes WordprocessingML dialects.");
333958
334454
  }
333959
334455
  return {
@@ -333968,7 +334464,7 @@ function parseSettings(xml) {
333968
334464
  };
333969
334465
  }
333970
334466
  function wordAttributes(element) {
333971
- return Object.fromEntries(element.tag.attributes.filter((attr4) => attr4.namespaceUri === element.tag.namespaceUri).map((attr4) => [`w:${attr4.localName}`, attr4.value]));
334467
+ return Object.fromEntries(element.tag.attributes.filter((attr5) => attr5.namespaceUri === element.tag.namespaceUri).map((attr5) => [`w:${attr5.localName}`, attr5.value]));
333972
334468
  }
333973
334469
  function serializeAttributes2(attrs) {
333974
334470
  return Object.entries(attrs).map(([key3, value2]) => ` ${key3}="${xmlEscapeAttr(value2)}"`).join("");
@@ -333990,7 +334486,7 @@ function updateSettingsChild(xml, name, changes) {
333990
334486
  const existing = parsed.find(name);
333991
334487
  const bindings2 = existing?.namespaceBindings ?? parsed.root.namespaceBindings;
333992
334488
  let prefix2 = Object.keys(bindings2).find((key3) => key3.length > 0 && bindings2[key3] === parsed.namespace);
333993
- const attrs = Object.fromEntries((existing?.tag.attributes ?? []).filter((attr4) => !(attr4.namespaceUri === parsed.namespace && Object.prototype.hasOwnProperty.call(changes, attr4.localName))).map((attr4) => [attr4.name, attr4.value]));
334489
+ const attrs = Object.fromEntries((existing?.tag.attributes ?? []).filter((attr5) => !(attr5.namespaceUri === parsed.namespace && Object.prototype.hasOwnProperty.call(changes, attr5.localName))).map((attr5) => [attr5.name, attr5.value]));
333994
334490
  if (!prefix2) {
333995
334491
  prefix2 = "w";
333996
334492
  for (let index = 1;bindings2[prefix2] !== undefined; index++)
@@ -335739,6 +336235,86 @@ function prepareRowHeightMutation(resolved, heightTwips, rule, tracked = false)
335739
336235
  render: (propertyXml) => resolved.tableXml.slice(0, start) + open2 + propertyXml + close + resolved.tableXml.slice(end)
335740
336236
  };
335741
336237
  }
336238
+ function prepareRowHeightReviewGeometry(resolved) {
336239
+ const source = TD95.decode(resolved.bytes);
336240
+ const tableStart = TD95.decode(resolved.bytes.subarray(0, resolved.table.tableByteStart)).length;
336241
+ const rowStart = TD95.decode(resolved.bytes.subarray(0, resolved.row.rowByteStart)).length - tableStart;
336242
+ const table = collectXmlElementRanges(source).ranges.find((range) => range.start === tableStart && range.tag.localName === "tbl" && range.tag.namespaceUri === W8);
336243
+ const namespaces = { ...table.namespaceBindings };
336244
+ const inspect = (xml) => {
336245
+ const parsed = collectXmlElementRanges(xml, { fragment: true, additionalNamespaces: namespaces });
336246
+ if (parsed.errors.length)
336247
+ throw new Error("Row history requires well-formed table source.");
336248
+ const ranges = parsed.ranges;
336249
+ const direct = (parent, name) => ranges.filter((range) => range.start >= parent.openEnd && range.end <= parent.closeStart && range.tag.namespaceUri === W8 && range.tag.localName === name && !ranges.some((outer) => outer.start >= parent.openEnd && outer.end <= parent.closeStart && outer.start < range.start && outer.end > range.end));
336250
+ const root = ranges.find((range) => range.start === 0 && range.tag.namespaceUri === W8 && range.tag.localName === "tbl");
336251
+ const row = ranges.find((range) => range.start === rowStart && range.tag.namespaceUri === W8 && range.tag.localName === "tr");
336252
+ if (!root || !row)
336253
+ throw new Error("Row history target no longer matches the captured source.");
336254
+ const cellRanges = ranges.filter((range) => range.tag.namespaceUri === W8 && range.tag.localName === "tc" && range.start >= row.openEnd && range.end <= row.closeStart && !ranges.some((outer) => outer.tag.namespaceUri === W8 && ["tc", "tbl"].includes(outer.tag.localName) && outer.start >= row.openEnd && outer.start < range.start && outer.end > range.end)).sort((a, b) => a.start - b.start);
336255
+ if (cellRanges.length !== resolved.row.cells.length)
336256
+ throw new Error("Row history cell ranges are ambiguous.");
336257
+ const grid = direct(root, "tblGrid");
336258
+ if (grid.length !== 1)
336259
+ throw new Error("Row history requires one source table grid.");
336260
+ return { grid: grid[0], direct, cells: cellRanges };
336261
+ };
336262
+ const original = inspect(resolved.tableXml);
336263
+ const missingCells = original.cells.filter((cell) => {
336264
+ const property2 = original.direct(cell, "tcPr")[0];
336265
+ return !property2 || original.direct(property2, "tcPrChange").length === 0;
336266
+ }).length;
336267
+ const missingGrid = original.direct(original.grid, "tblGridChange").length === 0;
336268
+ return {
336269
+ count: missingCells + Number(missingGrid),
336270
+ namespaces,
336271
+ render(xml, ids, author, date6) {
336272
+ const facts = inspect(xml);
336273
+ const replacements = [];
336274
+ let index = 0;
336275
+ const prefixFor = (range) => {
336276
+ let prefix2 = range.tag.prefix || Object.keys(range.namespaceBindings).find((key3) => key3 && range.namespaceBindings[key3] === W8) || "rh";
336277
+ if (range.namespaceBindings[prefix2] !== undefined && range.namespaceBindings[prefix2] !== W8) {
336278
+ prefix2 = "rh";
336279
+ for (let n = 1;range.namespaceBindings[prefix2] !== undefined; n++)
336280
+ prefix2 = `rh${n}`;
336281
+ }
336282
+ return { prefix: prefix2, declaration: range.namespaceBindings[prefix2] === W8 ? "" : ` xmlns:${prefix2}="${W8}"` };
336283
+ };
336284
+ for (const cell of facts.cells) {
336285
+ const properties2 = facts.direct(cell, "tcPr");
336286
+ if (properties2.length > 1)
336287
+ throw new Error("Row history cell properties are ambiguous.");
336288
+ const property2 = properties2[0];
336289
+ if (property2 && facts.direct(property2, "tcPrChange").length)
336290
+ continue;
336291
+ const { prefix: prefix2, declaration } = prefixFor(property2 ?? cell);
336292
+ const before = property2 ? xml.slice(property2.start, property2.end) : `<${prefix2}:tcPr/>`;
336293
+ const wrapper = `<${prefix2}:tcPrChange${declaration} ${prefix2}:id="${ids[index++]}" ${prefix2}:author="${escapeXmlAttribute3(author)}" ${prefix2}:date="${escapeXmlAttribute3(date6)}">${before}</${prefix2}:tcPrChange>`;
336294
+ let next;
336295
+ if (property2 && !property2.tag.isSelfClosing)
336296
+ next = xml.slice(property2.start, property2.closeStart) + wrapper + xml.slice(property2.closeStart, property2.end);
336297
+ else if (property2)
336298
+ next = before.replace(/\/\s*>$/, ">") + wrapper + `</${property2.tag.name}>`;
336299
+ else
336300
+ next = `<${prefix2}:tcPr${declaration}>${wrapper}</${prefix2}:tcPr>`;
336301
+ replacements.push({ start: property2?.start ?? cell.openEnd, end: property2?.end ?? cell.openEnd, xml: next });
336302
+ }
336303
+ if (!facts.direct(facts.grid, "tblGridChange").length) {
336304
+ const { prefix: prefix2, declaration } = prefixFor(facts.grid);
336305
+ const before = xml.slice(facts.grid.start, facts.grid.end);
336306
+ const wrapper = `<${prefix2}:tblGridChange${declaration} ${prefix2}:id="${ids[index++]}">${before}</${prefix2}:tblGridChange>`;
336307
+ const next = facts.grid.tag.isSelfClosing ? before.replace(/\/\s*>$/, ">") + wrapper + `</${facts.grid.tag.name}>` : xml.slice(facts.grid.start, facts.grid.closeStart) + wrapper + xml.slice(facts.grid.closeStart, facts.grid.end);
336308
+ replacements.push({ start: facts.grid.start, end: facts.grid.end, xml: next });
336309
+ }
336310
+ if (index !== ids.length)
336311
+ throw new Error("Row history revision reservation does not match its source surfaces.");
336312
+ for (const replacement2 of replacements.sort((a, b) => b.start - a.start))
336313
+ xml = xml.slice(0, replacement2.start) + replacement2.xml + xml.slice(replacement2.end);
336314
+ return xml;
336315
+ }
336316
+ };
336317
+ }
335742
336318
  var W8 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", TD95;
335743
336319
  var init_native_table_properties = __esm(() => {
335744
336320
  init_sd_document_session_internal();
@@ -340774,7 +341350,7 @@ var init_default2 = __esm(() => {
340774
341350
  }
340775
341351
  },
340776
341352
  adoptAttributes(recipient, attrs) {
340777
- const recipientAttrsMap = new Set(recipient.attrs.map((attr4) => attr4.name));
341353
+ const recipientAttrsMap = new Set(recipient.attrs.map((attr5) => attr5.name));
340778
341354
  for (let j = 0;j < attrs.length; j++) {
340779
341355
  if (!recipientAttrsMap.has(attrs[j].name)) {
340780
341356
  recipient.attrs.push(attrs[j]);
@@ -341070,7 +341646,7 @@ var init_foreign_content = __esm(() => {
341070
341646
  "xChannelSelector",
341071
341647
  "yChannelSelector",
341072
341648
  "zoomAndPan"
341073
- ].map((attr4) => [attr4.toLowerCase(), attr4]));
341649
+ ].map((attr5) => [attr5.toLowerCase(), attr5]));
341074
341650
  XML_ATTRS_ADJUSTMENT_MAP = new Map([
341075
341651
  ["xlink:actuate", { prefix: "xlink", name: "actuate", namespace: NS.XLINK }],
341076
341652
  ["xlink:arcrole", { prefix: "xlink", name: "arcrole", namespace: NS.XLINK }],
@@ -345799,10 +346375,10 @@ function convertFlowChildren(children2, context, inlineContext, path6, indexOffs
345799
346375
  }
345800
346376
  if (!isElement(node3))
345801
346377
  continue;
345802
- const word3 = describeWordListParagraph(node3);
345803
- if (word3) {
346378
+ const word4 = describeWordListParagraph(node3);
346379
+ if (word4) {
345804
346380
  flushPending();
345805
- const group = [{ descriptor: word3, sourcePath: nodePath }];
346381
+ const group = [{ descriptor: word4, sourcePath: nodePath }];
345806
346382
  let lookahead = index + 1;
345807
346383
  while (lookahead < children2.length) {
345808
346384
  const next = children2[lookahead];
@@ -345813,7 +346389,7 @@ function convertFlowChildren(children2, context, inlineContext, path6, indexOffs
345813
346389
  if (!isElement(next))
345814
346390
  break;
345815
346391
  const nextWord = describeWordListParagraph(next);
345816
- if (!nextWord || nextWord.listKey !== word3.listKey)
346392
+ if (!nextWord || nextWord.listKey !== word4.listKey)
345817
346393
  break;
345818
346394
  group.push({ descriptor: nextWord, sourcePath: [...path6, lookahead + indexOffset] });
345819
346395
  lookahead += 1;
@@ -346773,8 +347349,8 @@ function hasBlockDescendant(element) {
346773
347349
  }
346774
347350
  function headingLevelForElement(element) {
346775
347351
  const semantic = /^h([1-6])$/.exec(element.tagName)?.[1];
346776
- const word3 = /(?:^|\s)MsoHeading([1-6])(?:\s|$)/i.exec(attributeValue2(element, "class") ?? "")?.[1];
346777
- const value2 = semantic ?? word3;
347352
+ const word4 = /(?:^|\s)MsoHeading([1-6])(?:\s|$)/i.exec(attributeValue2(element, "class") ?? "")?.[1];
347353
+ const value2 = semantic ?? word4;
346778
347354
  return value2 ? Number.parseInt(value2, 10) : undefined;
346779
347355
  }
346780
347356
  function orderedListStart(list, context, path6) {
@@ -367052,18 +367628,18 @@ function rewriteWholeBodySelectionText(bytes, index2, text4) {
367052
367628
  const parsed = collectXmlElementRanges(sourceXml);
367053
367629
  if (parsed.errors.length)
367054
367630
  return { ok: false, reason: "invalid-range" };
367055
- const document5 = parsed.ranges.find((range) => range.tag.namespaceUri === word3 && range.tag.localName === "document");
367631
+ const document5 = parsed.ranges.find((range) => range.tag.namespaceUri === word4 && range.tag.localName === "document");
367056
367632
  if (!document5)
367057
367633
  return { ok: false, reason: "invalid-range" };
367058
- const body = directChildren3(sourceXml, document5, parsed.ranges)?.find((range) => range.tag.namespaceUri === word3 && range.tag.localName === "body");
367634
+ const body = directChildren3(sourceXml, document5, parsed.ranges)?.find((range) => range.tag.namespaceUri === word4 && range.tag.localName === "body");
367059
367635
  if (!body || body.tag.isSelfClosing)
367060
367636
  return { ok: false, reason: "invalid-range" };
367061
367637
  const children2 = directChildren3(sourceXml, body, parsed.ranges);
367062
367638
  if (!children2?.length)
367063
367639
  return { ok: false, reason: "unsupported-context" };
367064
367640
  const section = children2.at(-1);
367065
- const contentEnd = section?.tag.namespaceUri === word3 && section.tag.localName === "sectPr" ? section.start : body.closeStart;
367066
- if (children2.some((child) => child.start < contentEnd && (child.tag.namespaceUri !== word3 || !["p", "tbl"].includes(child.tag.localName)))) {
367641
+ const contentEnd = section?.tag.namespaceUri === word4 && section.tag.localName === "sectPr" ? section.start : body.closeStart;
367642
+ if (children2.some((child) => child.start < contentEnd && (child.tag.namespaceUri !== word4 || !["p", "tbl"].includes(child.tag.localName)))) {
367067
367643
  return { ok: false, reason: "unsupported-context" };
367068
367644
  }
367069
367645
  const protection = validateSelectionTextReplacement({
@@ -367157,7 +367733,7 @@ function rewriteMixedBody(xml, body, contentEnd, ranges, firstByteStart, text4)
367157
367733
  "tcPrChange",
367158
367734
  "tblGridChange"
367159
367735
  ]);
367160
- if (ranges.some((range) => range.start >= body.openEnd && range.end <= contentEnd && range.tag.namespaceUri === word3 && unsupported5.has(range.tag.localName))) {
367736
+ if (ranges.some((range) => range.start >= body.openEnd && range.end <= contentEnd && range.tag.namespaceUri === word4 && unsupported5.has(range.tag.localName))) {
367161
367737
  return { ok: false, reason: "unsupported-context" };
367162
367738
  }
367163
367739
  const beforeXml = xml.slice(body.openEnd, contentEnd);
@@ -367169,13 +367745,13 @@ function rewriteMixedBody(xml, body, contentEnd, ranges, firstByteStart, text4)
367169
367745
  }))
367170
367746
  return { ok: false, reason: "unsupported-context" };
367171
367747
  const firstStart = decoder7.decode(encoder4.encode(xml).subarray(0, firstByteStart)).length;
367172
- const first = ranges.find((range) => range.start === firstStart && range.tag.namespaceUri === word3 && range.tag.localName === "p");
367748
+ const first = ranges.find((range) => range.start === firstStart && range.tag.namespaceUri === word4 && range.tag.localName === "p");
367173
367749
  if (!first || first.start < body.openEnd || first.end > contentEnd)
367174
367750
  return { ok: false, reason: "invalid-range" };
367175
367751
  const firstChildren = first.tag.isSelfClosing ? [] : directChildren3(xml, first, ranges);
367176
367752
  if (!firstChildren)
367177
367753
  return { ok: false, reason: "invalid-range" };
367178
- const properties2 = firstChildren[0]?.tag.namespaceUri === word3 && firstChildren[0].tag.localName === "pPr" ? xml.slice(firstChildren[0].start, firstChildren[0].end) : "";
367754
+ const properties2 = firstChildren[0]?.tag.namespaceUri === word4 && firstChildren[0].tag.localName === "pPr" ? xml.slice(firstChildren[0].start, firstChildren[0].end) : "";
367179
367755
  const prefix2 = first.tag.prefix ? first.tag.prefix + ":" : "";
367180
367756
  const escaped = text4.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
367181
367757
  const run = "<" + prefix2 + "r><" + prefix2 + 't xml:space="preserve">' + escaped + "</" + prefix2 + "t></" + prefix2 + "r>";
@@ -367188,7 +367764,7 @@ function rewriteMixedBody(xml, body, contentEnd, ranges, firstByteStart, text4)
367188
367764
  return { ok: false, reason: "invalid-range" };
367189
367765
  return { ok: true, xml: result };
367190
367766
  }
367191
- var decoder7, encoder4, word3 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
367767
+ var decoder7, encoder4, word4 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
367192
367768
  var init_whole_body_selection_text = __esm(() => {
367193
367769
  init_sd_document_session_internal();
367194
367770
  decoder7 = new TextDecoder;
@@ -371668,7 +372244,7 @@ function prepareNativeTableSplit(input) {
371668
372244
  return null;
371669
372245
  const start = decoder8.decode(input.bytes.subarray(0, input.startByte)).length;
371670
372246
  const end = decoder8.decode(input.bytes.subarray(0, input.endByte)).length;
371671
- const table = parsed.ranges.find((range) => range.start === start && range.end === end && range.tag.namespaceUri === word4 && range.tag.localName === "tbl");
372247
+ const table = parsed.ranges.find((range) => range.start === start && range.end === end && range.tag.namespaceUri === word5 && range.tag.localName === "tbl");
371672
372248
  if (!table)
371673
372249
  return null;
371674
372250
  const rows = [];
@@ -371676,7 +372252,7 @@ function prepareNativeTableSplit(input) {
371676
372252
  for (const child of [...parsed.ranges].sort((left, right) => left.start - right.start)) {
371677
372253
  if (child.start < cursor || child.end > table.closeStart)
371678
372254
  continue;
371679
- if (xml.slice(cursor, child.start).trim() || child.tag.namespaceUri !== word4)
372255
+ if (xml.slice(cursor, child.start).trim() || child.tag.namespaceUri !== word5)
371680
372256
  return null;
371681
372257
  if (child.tag.localName === "tr")
371682
372258
  rows.push(child);
@@ -371693,7 +372269,7 @@ function prepareNativeTableSplit(input) {
371693
372269
  secondXml: header + xml.slice(rows[input.rowIndex].start, rows.at(-1).end) + footer
371694
372270
  };
371695
372271
  }
371696
- var word4 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", decoder8;
372272
+ var word5 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", decoder8;
371697
372273
  var init_native_table_split = __esm(() => {
371698
372274
  init_sd_document_session_internal();
371699
372275
  decoder8 = new TextDecoder;
@@ -372122,10 +372698,16 @@ function prepareNativeCellSplit(resolved, original, columnInsertIndex) {
372122
372698
  }
372123
372699
  flushRows();
372124
372700
  const addedColumns = model.tblGrid.gridColXmls.length - originalGridColumns.length;
372125
- if (addedColumns < 0 || originalGridColumns.some((column, index2) => model.tblGrid.gridColXmls[index2 < columnInsertIndex ? index2 : index2 + addedColumns] !== column))
372701
+ const resizedColumnIndex = columnInsertIndex - 1;
372702
+ const resizedColumnChanged = resizedColumnIndex >= 0 && model.tblGrid.gridColXmls[resizedColumnIndex] !== originalGridColumns[resizedColumnIndex];
372703
+ if (addedColumns < 0 || originalGridColumns.some((column, index2) => index2 !== resizedColumnIndex && model.tblGrid.gridColXmls[index2 < columnInsertIndex ? index2 : index2 + addedColumns] !== column))
372126
372704
  return null;
372127
- if (model.tblGrid.changeXml !== originalGridChangeXml || addedColumns) {
372705
+ if (model.tblGrid.changeXml !== originalGridChangeXml || addedColumns || resizedColumnChanged) {
372128
372706
  const gridPatches = [];
372707
+ if (resizedColumnChanged) {
372708
+ const column = gridColumns[resizedColumnIndex];
372709
+ gridPatches.push({ start: column.start, end: column.end, xml: model.tblGrid.gridColXmls[resizedColumnIndex] });
372710
+ }
372129
372711
  if (addedColumns) {
372130
372712
  const at = columnInsertIndex > 0 ? gridColumns[columnInsertIndex - 1].end : grid.openEnd;
372131
372713
  gridPatches.push({
@@ -372187,7 +372769,7 @@ function prepareNativeCellMerge(resolved, model) {
372187
372769
  for (const properties2 of nativeChildren(rows[index2], "trPr")) {
372188
372770
  for (const name of ["gridBefore", "gridAfter"]) {
372189
372771
  const omissions = nativeChildren(properties2, name);
372190
- if (omissions.length > 1 || omissions.some((range) => !/^\+?0+$/.test(range.tag.attributes.find((attr4) => attr4.namespaceUri === W12 && attr4.localName === "val")?.value ?? "")))
372772
+ if (omissions.length > 1 || omissions.some((range) => !/^\+?0+$/.test(range.tag.attributes.find((attr5) => attr5.namespaceUri === W12 && attr5.localName === "val")?.value ?? "")))
372191
372773
  simpleTopology = false;
372192
372774
  }
372193
372775
  }
@@ -372204,7 +372786,7 @@ function prepareNativeCellMerge(resolved, model) {
372204
372786
  simpleTopology = false;
372205
372787
  if (property2) {
372206
372788
  const spans = nativeChildren(property2, "gridSpan");
372207
- if (spans.length > 1 || spans.some((range2) => !/^\+?0*1$/.test(range2.tag.attributes.find((attr4) => attr4.namespaceUri === W12 && attr4.localName === "val")?.value ?? "")) || nativeChildren(property2, "vMerge").length > 0)
372789
+ if (spans.length > 1 || spans.some((range2) => !/^\+?0*1$/.test(range2.tag.attributes.find((attr5) => attr5.namespaceUri === W12 && attr5.localName === "val")?.value ?? "")) || nativeChildren(property2, "vMerge").length > 0)
372208
372790
  simpleTopology = false;
372209
372791
  }
372210
372792
  const prefix2 = property2 ? source.slice(range.openEnd, property2.start) : "";
@@ -374225,12 +374807,17 @@ class V2TablesAdapter {
374225
374807
  }
374226
374808
  setRowHeight(input, options) {
374227
374809
  options = normalizeRuntimeTableMutationOptions(input, options);
374228
- const guard = this.guardMutation(input, options, { trackedOperationId: "tables.setRowHeight" });
374810
+ const guard = this.guardMutation(input, options, { trackedOperationId: "tables.setRowHeight", rowHeightPurpose: "height" });
374229
374811
  if (guard)
374230
374812
  return guard;
374231
374813
  const resolved = resolveRowLocatorForMutation(this.context, input, "tables.setRowHeight");
374232
374814
  const prepared = prepareRowHeightMutation(resolved, ptToTwips(input.heightPt), input.rule, options?.changeMode === "tracked");
374233
374815
  const dryRun = dryRunRequested2(input, options);
374816
+ if (options?.changeMode === "tracked" && resolved.row.cells.length > 0) {
374817
+ if (prepared.beforeXml === prepared.afterXml)
374818
+ return successMutation(resolved.table.tableNodeId);
374819
+ return this.commitTrackedRowHeight(resolved, prepared, { ...options, dryRun });
374820
+ }
374234
374821
  const tracked = this.applyTrackedPropertyXmlWrap(prepared.beforeXml, prepared.afterXml, "trPr", {
374235
374822
  ...options,
374236
374823
  dryRun
@@ -374252,6 +374839,52 @@ class V2TablesAdapter {
374252
374839
  trackedChangeRefs: projectTrackedStructuralEntityIds(this.context, refs.map((ref5) => ref5.entityId)).map((entityId) => ({ kind: "entity", entityType: "trackedChange", entityId }))
374253
374840
  };
374254
374841
  }
374842
+ commitTrackedRowHeight(resolved, prepared, options) {
374843
+ const author = readTrackedAuthor(this.context);
374844
+ if (!author.name)
374845
+ return mutationFailure("PRECONDITION_FAILED", "no-author-configured");
374846
+ const source = TD104.decode(resolved.bytes);
374847
+ const tableStart = TD104.decode(resolved.bytes.subarray(0, resolved.table.tableByteStart)).length;
374848
+ const prior = readRowHeightReviewCohorts(source).find((cohort) => cohort.table.start === tableStart);
374849
+ const geometry = prepareRowHeightReviewGeometry(resolved);
374850
+ const tableRanges = collectXmlElementRanges(resolved.tableXml, { fragment: true, additionalNamespaces: geometry.namespaces }).ranges;
374851
+ if (!prior && tableRanges.some((range) => range.tag.localName === "tblGridChange" && range.tag.namespaceUri === "http://schemas.openxmlformats.org/wordprocessingml/2006/main")) {
374852
+ return mutationFailure("CAPABILITY_UNAVAILABLE", "Review the existing table-grid revision before resizing this row.");
374853
+ }
374854
+ const count = 1 + geometry.count;
374855
+ const previewIds = reserveTrackedRevisionIds(this.context, count, true);
374856
+ if (!previewIds)
374857
+ return tableRevisionIdReservationFailure("tables.setRowHeight");
374858
+ const date6 = new Date().toISOString();
374859
+ const prepare = (ids2) => {
374860
+ const row = wrapAfterPropertyBlockWithChange({ nextXml: prepared.afterXml, beforeXml: prepared.beforeXml, block: "trPr", stamp: { revisionId: ids2[0], author, date: date6 } });
374861
+ if (!row)
374862
+ return null;
374863
+ const xml = geometry.render(prepared.render(row), ids2.slice(1), author.name, date6);
374864
+ const cohort = readRowHeightReviewCohorts(xml, { additionalNamespaces: geometry.namespaces, allowAllNoop: prior !== undefined }).find((value3) => value3.table.start === 0);
374865
+ return cohort ? { xml, cohort } : null;
374866
+ };
374867
+ const preview = prepare(previewIds);
374868
+ if (!preview)
374869
+ return mutationFailure("CAPABILITY_UNAVAILABLE", "Pending or unsupported table properties cannot preserve this row-height review. Review those changes first.");
374870
+ if (options.dryRun)
374871
+ return successMutation(resolved.table.tableNodeId);
374872
+ if (prior && !preview.cohort.material) {
374873
+ let xml = preview.xml;
374874
+ for (const change of [preview.cohort.gridChange, ...preview.cohort.rowChanges, ...preview.cohort.cellChanges].sort((a, b) => b.start - a.start)) {
374875
+ xml = xml.slice(0, change.start) + xml.slice(change.end);
374876
+ }
374877
+ return this.commitTableModel(resolved, null, "v2-tables-set-row-height", [], false, xml);
374878
+ }
374879
+ const ids = reserveTrackedRevisionIds(this.context, count);
374880
+ if (!ids)
374881
+ return tableRevisionIdReservationFailure("tables.setRowHeight");
374882
+ const result = prepare(ids);
374883
+ const committed = this.commitTableModel(resolved, null, "v2-tables-set-row-height", ids.map((id) => ({ kind: "trackedChange", entityId: String(id), storyId: resolved.storyId })), false, result.xml);
374884
+ if (!committed.success)
374885
+ return committed;
374886
+ return { ...committed, trackedChangeRefs: projectTrackedStructuralEntityIds(this.context, ids.map(String)).map((entityId) => ({ kind: "entity", entityType: "trackedChange", entityId })) };
374887
+ }
374255
374888
  distributeRows(input, options) {
374256
374889
  options = normalizeRuntimeTableMutationOptions(input, options);
374257
374890
  const guard = this.guardPlannedMutation(input, options);
@@ -374685,6 +375318,34 @@ class V2TablesAdapter {
374685
375318
  stabilizeTableIdentityAcrossRows(model, originalTableIdentityParaId, allocParaId);
374686
375319
  return this.commitTableModel(resolved, model, "v2-tables-move-column");
374687
375320
  }
375321
+ resizeColumns(input, options) {
375322
+ options = normalizeRuntimeTableMutationOptions(input, options);
375323
+ const guard = this.guardMutation(input, options, { trackedOperationId: "tables.setColumnWidth" });
375324
+ if (guard)
375325
+ return guard;
375326
+ const resolved = resolvePublicTableLocator(this.context, input, "tables.resizeColumns", false);
375327
+ const model = parseTableXmlModel(resolved.tableXml);
375328
+ if (!Array.isArray(input.widthsPt) || input.widthsPt.length !== model.tblGrid.gridColXmls.length || input.widthsPt.some((width) => !Number.isFinite(width) || width <= 0 || ptToTwips(width) < 1)) {
375329
+ throw operationError2("INVALID_ARGUMENT", "A column resize requires a positive width for every existing grid column.", "tables.resizeColumns");
375330
+ }
375331
+ const widths = input.widthsPt.map(ptToTwips);
375332
+ model.tblGrid.gridColXmls = widths.map((width) => singleElement2(model.prefix, "gridCol", { w: String(width) }));
375333
+ for (const row of model.rows) {
375334
+ const gridBefore = readValidatedRowGridOmission(row.trPrXml, "gridBefore");
375335
+ if (gridBefore == null)
375336
+ return mutationFailure("INVALID_CONTEXT", "Column resize requires a valid row gridBefore.");
375337
+ let column = gridBefore;
375338
+ for (const cell of row.cells) {
375339
+ const span = readValidatedGridSpan(cell.tcPrXml);
375340
+ if (span == null || column + span > widths.length)
375341
+ return mutationFailure("INVALID_CONTEXT", "Column resize requires a complete cell grid span.");
375342
+ setCellDxaWidth(cell, model.prefix, widths.slice(column, column + span).reduce((sum, width) => sum + width, 0));
375343
+ column += span;
375344
+ }
375345
+ }
375346
+ mutateTablePr(model, (children2) => setOrRemoveChild(setOrRemoveChild(children2, "tblLayout", singleElement2(model.prefix, "tblLayout", { type: "fixed" })), "tblW", buildTablePreferredWidthXml(model.prefix, { type: "dxa", value: widths.reduce((sum, width) => sum + width, 0) })));
375347
+ return this.commitTrackedPropertyChanges(resolved, model, "v2-tables-set-column-width", options);
375348
+ }
374688
375349
  setColumnWidth(input, options) {
374689
375350
  options = normalizeRuntimeTableMutationOptions(input, options);
374690
375351
  const guard = this.guardPlannedMutation(input, options);
@@ -375425,9 +376086,11 @@ class V2TablesAdapter {
375425
376086
  const originalFirstParaId = model.rows[0]?.cells[0]?.firstParaId ?? null;
375426
376087
  const beforeCellXml = targetCell.tcPrXml ?? `<${model.prefix}:tcPr></${model.prefix}:tcPr>`;
375427
376088
  const beforeGridXml = `${model.tblGrid.openTag}${model.tblGrid.gridColXmls.join("")}${model.tblGrid.closeTag}`;
376089
+ const originalWidth = readGridColumnWidth2(model.tblGrid.gridColXmls[targetColumnIndex] ?? "");
375428
376090
  for (let offset = 0;offset < input.columns - 1; offset += 1) {
375429
376091
  insertSplitColumnIntoModel(model, targetColumnIndex + 1 + offset, targetRowIndex, targetRowIndex + 1, allocParaId);
375430
376092
  }
376093
+ subdivideCellWidths(model, targetRowIndex, targetColumnIndex, input.columns, originalWidth);
375431
376094
  const splitCells = listRowCells(row).filter((entry) => entry.gridColumnStart >= targetColumnIndex).slice(0, input.columns).map((entry) => entry.cell);
375432
376095
  if (splitCells.length !== input.columns) {
375433
376096
  return mutationFailure("PRECONDITION_FAILED", "tracked-cell-split-model-incomplete");
@@ -375516,7 +376179,7 @@ class V2TablesAdapter {
375516
376179
  const result = this.setCellText({ nodeId: input.cellNodeId, text: input.text }, mutationOptions2);
375517
376180
  return projectNarrowMutation(input.tableNodeId, result);
375518
376181
  }
375519
- const guard2 = this.guardMutation(input, mutationOptions2, { deferTrackedGate: true });
376182
+ const guard2 = this.guardMutation(input, mutationOptions2, { deferTrackedGate: true, rowHeightPurpose: "cell-text" });
375520
376183
  if (guard2)
375521
376184
  return guard2;
375522
376185
  const resolved2 = resolveCellOrScopedCellLocator(this.context, { nodeId: input.cellNodeId, text: input.text }, "tables.setCellText");
@@ -375546,7 +376209,7 @@ class V2TablesAdapter {
375546
376209
  return { success: true, tableNodeId: resolved2.table.tableNodeId, txId: receipt4.txId };
375547
376210
  }
375548
376211
  const mutationOptions = options;
375549
- const guard = this.guardMutation(input, mutationOptions, { deferTrackedGate: true });
376212
+ const guard = this.guardMutation(input, mutationOptions, { deferTrackedGate: true, rowHeightPurpose: "cell-text" });
375550
376213
  if (guard)
375551
376214
  return guard;
375552
376215
  const resolved = resolveCellOrScopedCellLocator(this.context, input, "tables.setCellText");
@@ -376526,6 +377189,35 @@ class V2TablesAdapter {
376526
377189
  if (expectedRevision !== undefined && expectedRevision !== this.context.currentPublicRevision()) {
376527
377190
  return mutationFailure("REVISION_MISMATCH", `expected-revision ${expectedRevision} does not match current revision ${this.context.currentPublicRevision()}.`);
376528
377191
  }
377192
+ const records = [];
377193
+ const add = (value3) => {
377194
+ if (value3 && typeof value3 === "object")
377195
+ records.push(value3);
377196
+ };
377197
+ add(input);
377198
+ if (records[0]) {
377199
+ add(records[0].target);
377200
+ add(records[0].destination);
377201
+ }
377202
+ for (const record3 of [...records])
377203
+ add(record3.target);
377204
+ const ids = new Set(records.flatMap((record3) => ["nodeId", "tableNodeId", "rowNodeId", "cellNodeId"].flatMap((key3) => typeof record3[key3] === "string" ? [record3[key3]] : [])));
377205
+ const seen = new Set;
377206
+ for (const id of ids) {
377207
+ const resolved = findTableByNodeIdIncludingNested(this.context, id) ?? findRowByNodeId(this.context, id) ?? findCellByNodeId(this.context, id);
377208
+ if (!resolved || seen.has(resolved.table.tableNodeId))
377209
+ continue;
377210
+ seen.add(resolved.table.tableNodeId);
377211
+ const start = TD104.decode(resolved.bytes.subarray(0, resolved.table.tableByteStart)).length;
377212
+ const cohort = readRowHeightReviewCohorts(TD104.decode(resolved.bytes)).find((value3) => value3.table.start === start);
377213
+ if (!cohort)
377214
+ continue;
377215
+ if (config2?.rowHeightPurpose === "cell-text")
377216
+ continue;
377217
+ if (config2?.rowHeightPurpose === "height" && options?.changeMode === "tracked" && cohort.author.trim().toLowerCase() === readTrackedAuthorName(this.context).trim().toLowerCase())
377218
+ continue;
377219
+ return mutationFailure("CAPABILITY_UNAVAILABLE", "Review the pending row-height change before changing this table’s structure or properties.");
377220
+ }
376529
377221
  return null;
376530
377222
  }
376531
377223
  guardDocumentMutation(input, options, trackedMessage = "Document-level table mutations do not support tracked mode on v2 yet.") {
@@ -377505,11 +378197,26 @@ function createSplitCloneCell(template, paraId, prefix2, span = 1, vMerge = "non
377505
378197
  setCellVMerge(cell, prefix2, vMerge);
377506
378198
  return cell;
377507
378199
  }
378200
+ function subdivideCellWidths(model, rowIndex, columnIndex, columns, originalWidth) {
378201
+ if (originalWidth == null || columns <= 1)
378202
+ return;
378203
+ const width = Math.floor(originalWidth / columns);
378204
+ const remainder = originalWidth - width * columns;
378205
+ for (let offset = 0;offset < columns; offset += 1) {
378206
+ const cellWidth = width + (offset < remainder ? 1 : 0);
378207
+ model.tblGrid.gridColXmls[columnIndex + offset] = singleElement2(model.prefix, "gridCol", { w: String(cellWidth) });
378208
+ const cell = findRowCellAtGridColumn(model.rows[rowIndex], columnIndex + offset)?.cell;
378209
+ if (cell)
378210
+ setCellDxaWidth(cell, model.prefix, cellWidth);
378211
+ }
378212
+ }
377508
378213
  function splitSimpleCellModel(model, rowIndex, columnIndex, input, allocate) {
377509
378214
  const originalFirstId = model.rows[0]?.cells[0]?.firstParaId ?? null;
378215
+ const originalWidth = readGridColumnWidth2(model.tblGrid.gridColXmls[columnIndex] ?? "");
377510
378216
  for (let offset = 0;offset < input.columns - 1; offset += 1) {
377511
- insertSplitColumnIntoModel(model, columnIndex + 1 + offset, rowIndex, rowIndex + input.rows, allocate);
378217
+ insertSplitColumnIntoModel(model, columnIndex + 1 + offset, rowIndex, rowIndex + 1, allocate);
377512
378218
  }
378219
+ subdivideCellWidths(model, rowIndex, columnIndex, input.columns, originalWidth);
377513
378220
  for (let offset = 0;offset < input.rows - 1; offset += 1) {
377514
378221
  insertSplitRowIntoModel(model, rowIndex + 1 + offset, columnIndex, columnIndex + input.columns, allocate);
377515
378222
  }
@@ -383549,13 +384256,13 @@ function normalizeOoxml(content3, allocate) {
383549
384256
  return `${prefix2}:${name2.localName}`;
383550
384257
  };
383551
384258
  const name = qualifiedName2(range.tag);
383552
- const attrs = range.tag.attributes.filter((attr4) => !(range.tag.namespaceUri === W18 && range.tag.localName === "p" && attr4.namespaceUri === W147 && attr4.localName === "paraId")).map((attr4) => ({ name: qualifiedName2(attr4), value: attr4.value }));
384259
+ const attrs = range.tag.attributes.filter((attr5) => !(range.tag.namespaceUri === W18 && range.tag.localName === "p" && attr5.namespaceUri === W147 && attr5.localName === "paraId")).map((attr5) => ({ name: qualifiedName2(attr5), value: attr5.value }));
383553
384260
  if (range.tag.namespaceUri === W18 && range.tag.localName === "p") {
383554
384261
  attrs.push({ name: "w14:paraId", value: allocate() });
383555
384262
  if (range.namespaceBindings["w14"] !== W147)
383556
384263
  bindings2.set("w14", W147);
383557
384264
  }
383558
- const serialized = attrs.filter((attr4) => !bindings2.has(attr4.name.replace(/^xmlns:/, ""))).map((attr4) => ` ${attr4.name}="${xmlEscapeAttr(attr4.value).replaceAll(`
384265
+ const serialized = attrs.filter((attr5) => !bindings2.has(attr5.name.replace(/^xmlns:/, ""))).map((attr5) => ` ${attr5.name}="${xmlEscapeAttr(attr5.value).replaceAll(`
383559
384266
  `, "&#10;").replaceAll("\r", "&#13;").replaceAll("\t", "&#9;")}"`).join("");
383560
384267
  const declarations = [...bindings2].map(([prefix2, uri]) => ` xmlns:${prefix2}="${uri}"`).join("");
383561
384268
  edits.push({
@@ -383707,16 +384414,16 @@ function validateOoxml(input) {
383707
384414
  control2.content = true;
383708
384415
  }
383709
384416
  if (["pStyle", "rStyle", "tblStyle", "numId"].includes(name)) {
383710
- const value3 = tag.attributes.find((attr4) => attr4.namespaceUri === W18 && attr4.localName === "val")?.value;
384417
+ const value3 = tag.attributes.find((attr5) => attr5.namespaceUri === W18 && attr5.localName === "val")?.value;
383711
384418
  const part = name === "numId" ? "/word/numbering.xml" : "/word/styles.xml";
383712
384419
  const attribute2 = name === "numId" ? "numId" : "styleId";
383713
384420
  const catalog = collectXmlElementRanges(readPartXml(input.context, part) ?? "").ranges;
383714
- if (!value3 || !catalog.some((range) => range.tag.attributes.some((attr4) => attr4.namespaceUri === W18 && attr4.localName === attribute2 && attr4.value === value3))) {
384421
+ if (!value3 || !catalog.some((range) => range.tag.attributes.some((attr5) => attr5.namespaceUri === W18 && attr5.localName === attribute2 && attr5.value === value3))) {
383715
384422
  invalid4(`OOXML replacement references unavailable ${name}.`);
383716
384423
  }
383717
384424
  }
383718
384425
  if (name === "id" && parent === "sdtPr") {
383719
- const id = tag.attributes.find((attr4) => attr4.namespaceUri === W18 && attr4.localName === "val")?.value;
384426
+ const id = tag.attributes.find((attr5) => attr5.namespaceUri === W18 && attr5.localName === "val")?.value;
383720
384427
  const numeric = Number(id);
383721
384428
  const control2 = controls.at(-1);
383722
384429
  if (!id || !/^-?\d+$/.test(id) || !Number.isSafeInteger(numeric) || numeric < -2147483648 || numeric > 2147483647 || ids.has(String(numeric)) || !control2 || control2.id)
@@ -383725,9 +384432,9 @@ function validateOoxml(input) {
383725
384432
  control2.id = true;
383726
384433
  }
383727
384434
  }
383728
- for (const attr4 of tag.attributes) {
383729
- if (attr4.namespaceUri === R && !relationshipIds.has(attr4.value))
383730
- invalid4(`OOXML relationship ${attr4.value} is unavailable in the destination part.`);
384435
+ for (const attr5 of tag.attributes) {
384436
+ if (attr5.namespaceUri === R && !relationshipIds.has(attr5.value))
384437
+ invalid4(`OOXML relationship ${attr5.value} is unavailable in the destination part.`);
383731
384438
  }
383732
384439
  stack.push(name);
383733
384440
  });
@@ -383877,7 +384584,7 @@ function collectPackageControlIds(context, removed) {
383877
384584
  parser.on("opentag", (tag) => {
383878
384585
  const parent = stack.at(-1);
383879
384586
  if (tag.namespaceUri === W19 && tag.localName === "id" && parent?.namespaceUri === W19 && parent.localName === "sdtPr") {
383880
- const value3 = tag.attributes.find((attr4) => attr4.namespaceUri === W19 && attr4.localName === "val")?.value;
384587
+ const value3 = tag.attributes.find((attr5) => attr5.namespaceUri === W19 && attr5.localName === "val")?.value;
383881
384588
  if (value3 !== undefined)
383882
384589
  ids.add(String(Number(value3)));
383883
384590
  }
@@ -384171,7 +384878,7 @@ function prepareStructuralSdtReplacement(context, fragment4) {
384171
384878
  if (lowered.plan.assets?.length)
384172
384879
  throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "Structural SDT replacement cannot import package assets.");
384173
384880
  const styleBytes = readStyleDefinitionsPartBytes(context);
384174
- const styles = new Set(collectXmlElementRanges(styleBytes ? new TextDecoder().decode(styleBytes) : "").ranges.filter((range) => range.tag.namespaceUri === W21 && range.tag.localName === "style").flatMap((range) => range.tag.attributes.filter((attr4) => attr4.namespaceUri === W21 && attr4.localName === "styleId").map((attr4) => attr4.value)));
384881
+ const styles = new Set(collectXmlElementRanges(styleBytes ? new TextDecoder().decode(styleBytes) : "").ranges.filter((range) => range.tag.namespaceUri === W21 && range.tag.localName === "style").flatMap((range) => range.tag.attributes.filter((attr5) => attr5.namespaceUri === W21 && attr5.localName === "styleId").map((attr5) => attr5.value)));
384175
384882
  const allocate = createParaIdAllocator(context);
384176
384883
  const contentXml = lowered.plan.blocks.map((block) => {
384177
384884
  if (block.kind !== "paragraph" || block.numbering || block.listIntent || block.semanticStyleRole) {
@@ -385854,6 +386561,9 @@ class V2ContentControlsAdapter {
385854
386561
  if (rowSection && options?.changeMode === "tracked") {
385855
386562
  throw operationError("CAPABILITY_UNAVAILABLE", "Tracked insertion of a repeating table row is not supported.");
385856
386563
  }
386564
+ if (options?.changeMode === "tracked" && this.context.isCollaborativeSession()) {
386565
+ throw operationError("CAPABILITY_UNAVAILABLE", "Tracked repeating-item insertion is not supported in collaboration.");
386566
+ }
385857
386567
  const template = children2[Math.max(0, Math.min(insertIndex, children2.length - 1))];
385858
386568
  const innerXml = rowSection ? buildEmptyRepeatingTableRowXml(template, this.context) : buildParaIdParagraphXml(createParaIdAllocator(this.context)());
385859
386569
  const id = this.allocateId(loaded, dryRunRequested(input, options));
@@ -385888,7 +386598,10 @@ class V2ContentControlsAdapter {
385888
386598
  if (dryRunRequested(input, options))
385889
386599
  return { success: true, contentControl: target };
385890
386600
  const nextXml = replaceRange3(loaded.documentXml, control2.start, control2.end, replacement2);
385891
- return this.commitDocument(nextXml, "content-control-repeat-insert", input, options, target, { createdRefs });
386601
+ return this.commitDocument(nextXml, "content-control-repeat-insert", input, options, target, {
386602
+ createdRefs,
386603
+ storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] }
386604
+ });
385892
386605
  }
385893
386606
  cloneRepeatingItem(input, options) {
385894
386607
  this.validateTrackedControlMutation(input, options);
@@ -385904,6 +386617,9 @@ class V2ContentControlsAdapter {
385904
386617
  throw repeatingSectionCloneIndexError(input.index, children2.length);
385905
386618
  if (hasTrackedControlAncestor(loaded.documentXml, control2))
385906
386619
  this.requireDirectControlStructure(input, options);
386620
+ if (options?.changeMode === "tracked" && this.context.isCollaborativeSession()) {
386621
+ throw operationError("CAPABILITY_UNAVAILABLE", "Tracked repeating-item insertion is not supported in collaboration.");
386622
+ }
385907
386623
  if (options?.changeMode !== "tracked" && dryRunRequested(input, options))
385908
386624
  return this.validateDryRun(input, options, control2.target);
385909
386625
  const cloneRevision = expectedRevisionFrom(input, options);
@@ -385932,7 +386648,10 @@ class V2ContentControlsAdapter {
385932
386648
  const localEnd = item.end - control2.start;
385933
386649
  const replacement2 = `${control2.xml.slice(0, localEnd)}${clone3}${control2.xml.slice(localEnd)}`;
385934
386650
  const nextXml = replaceRange3(loaded.documentXml, control2.start, control2.end, replacement2);
385935
- return this.commitDocument(nextXml, "content-control-repeat-clone", input, options, control2.target, { createdRefs });
386651
+ return this.commitDocument(nextXml, "content-control-repeat-clone", input, options, control2.target, {
386652
+ createdRefs,
386653
+ storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] }
386654
+ });
385936
386655
  }
385937
386656
  deleteRepeatingItem(input, options) {
385938
386657
  return this.mutateControl(input.target, input, options, (control2, loaded) => {
@@ -392427,9 +393146,9 @@ function paragraphRangeIndentationContext(paragraphXml, namespaceBindings) {
392427
393146
  }
392428
393147
  function paragraphRangeIndentationPropertiesXml(paragraphXml, namespaceBindings) {
392429
393148
  const { indent: indent2, propertyChildren } = paragraphRangeIndentationContext(paragraphXml, namespaceBindings);
392430
- const styleId = propertyChildren.find((child) => child.tag.namespaceUri === WORD_NAMESPACE9 && child.tag.localName === "pStyle")?.tag.attributes.find((attr4) => attr4.namespaceUri === WORD_NAMESPACE9 && attr4.localName === "val")?.value;
393149
+ const styleId = propertyChildren.find((child) => child.tag.namespaceUri === WORD_NAMESPACE9 && child.tag.localName === "pStyle")?.tag.attributes.find((attr5) => attr5.namespaceUri === WORD_NAMESPACE9 && attr5.localName === "val")?.value;
392431
393150
  const style = styleId == null ? "" : `<w:pStyle w:val="${escapeXmlAttribute3(styleId)}"/>`;
392432
- const attrs = indent2?.tag.attributes.filter((attr4) => attr4.namespaceUri === WORD_NAMESPACE9).map((attr4) => `w:${attr4.localName}="${escapeXmlAttribute3(attr4.value)}"`).join(" ") ?? "";
393151
+ const attrs = indent2?.tag.attributes.filter((attr5) => attr5.namespaceUri === WORD_NAMESPACE9).map((attr5) => `w:${attr5.localName}="${escapeXmlAttribute3(attr5.value)}"`).join(" ") ?? "";
392433
393152
  return `<w:pPr>${style}<w:ind ${attrs}/></w:pPr>`;
392434
393153
  }
392435
393154
  function classifyParagraphNodeType(input) {
@@ -392572,7 +393291,7 @@ function setParagraphRangeLeftIndentation(paragraphXml, left, logicalStart, name
392572
393291
  opening = opening.replace(/\/?>$/, (end) => ` xmlns:${attributePrefix}="${WORD_NAMESPACE9}"${end}`);
392573
393292
  }
392574
393293
  for (const localName2 of logicalStart ? ["left", "start"] : ["left"]) {
392575
- const existing = indent2.tag.attributes.find((attr4) => attr4.namespaceUri === WORD_NAMESPACE9 && attr4.localName === localName2);
393294
+ const existing = indent2.tag.attributes.find((attr5) => attr5.namespaceUri === WORD_NAMESPACE9 && attr5.localName === localName2);
392576
393295
  const name = existing?.name ?? `${attributePrefix}:${localName2}`;
392577
393296
  if (existing) {
392578
393297
  opening = opening.replace(/\s+([^\s=]+)\s*=\s*(["'])[^]*?\2/g, (attribute2, qualifiedName2) => qualifiedName2 === name ? ` ${name}="${left}"` : attribute2);
@@ -392591,7 +393310,7 @@ function setParagraphRangeLeftIndentation(paragraphXml, left, logicalStart, name
392591
393310
  prefix2 += "w";
392592
393311
  }
392593
393312
  const declaration = ` xmlns:${prefix2}="${WORD_NAMESPACE9}"`;
392594
- const attrs = (logicalStart ? ["left", "start"] : ["left"]).map((attr4) => `${prefix2}:${attr4}="${left}"`).join(" ");
393313
+ const attrs = (logicalStart ? ["left", "start"] : ["left"]).map((attr5) => `${prefix2}:${attr5}="${left}"`).join(" ");
392595
393314
  const xml = `<${prefix2}:ind${declaration} ${attrs}/>`;
392596
393315
  if (!properties2) {
392597
393316
  const pPr = `<${prefix2}:pPr${declaration}>${xml}</${prefix2}:pPr>`;
@@ -393868,7 +394587,7 @@ function buildCommentMarkerEnvelopeIndex(xml) {
393868
394587
  const result = walkXmlElements(xml, { onOpenTag({ tag, start, end }) {
393869
394588
  if (!WORD_NAMESPACES4.has(tag.namespaceUri) || !["commentRangeStart", "commentRangeEnd"].includes(tag.localName))
393870
394589
  return;
393871
- const id = tag.attributes.find((attr4) => attr4.localName === "id" && WORD_NAMESPACES4.has(attr4.namespaceUri))?.value;
394590
+ const id = tag.attributes.find((attr5) => attr5.localName === "id" && WORD_NAMESPACES4.has(attr5.namespaceUri))?.value;
393872
394591
  if (id === undefined)
393873
394592
  return;
393874
394593
  const entry = markers.get(id) ?? { starts: [], ends: [] };
@@ -400024,11 +400743,11 @@ function numberingInstanceIsOwnedByRun(runtime, run) {
400024
400743
  for (const reference of parsed.ranges) {
400025
400744
  if (reference.tag.namespaceUri !== WORDPROCESSINGML_NAMESPACE7 || reference.tag.localName !== "numId")
400026
400745
  continue;
400027
- const value3 = reference.tag.attributes.find((attr4) => attr4.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && attr4.localName === "val")?.value;
400746
+ const value3 = reference.tag.attributes.find((attr5) => attr5.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && attr5.localName === "val")?.value;
400028
400747
  if (value3 !== run.definitionNumId)
400029
400748
  continue;
400030
400749
  const paragraph4 = parsed.ranges.find((range) => range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && range.tag.localName === "p" && range.start < reference.start && range.end > reference.end);
400031
- const paraId = paragraph4?.tag.attributes.find((attr4) => attr4.namespaceUri === "http://schemas.microsoft.com/office/word/2010/wordml" && attr4.localName === "paraId")?.value;
400750
+ const paraId = paragraph4?.tag.attributes.find((attr5) => attr5.namespaceUri === "http://schemas.microsoft.com/office/word/2010/wordml" && attr5.localName === "paraId")?.value;
400032
400751
  if (partUri !== runtime.partUri || !paraId || !paragraphs2.has(paraId))
400033
400752
  return false;
400034
400753
  }
@@ -400516,7 +401235,7 @@ function versionNumberingDefinition(numbering, abstractNumId) {
400516
401235
  if (parsed.ranges.some((range) => ["num", "abstractNum"].includes(range.tag.localName) && range.tag.namespaceUri !== WORDPROCESSINGML_NAMESPACE7)) {
400517
401236
  return { ok: false, code: "CAPABILITY_UNAVAILABLE", message: "Tracked shared numbering cannot version extension-owned definitions." };
400518
401237
  }
400519
- const abstract = parsed.ranges.find((range) => range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && range.tag.localName === "abstractNum" && range.tag.attributes.some((attr4) => attr4.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && attr4.localName === "abstractNumId" && attr4.value === abstractNumId));
401238
+ const abstract = parsed.ranges.find((range) => range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && range.tag.localName === "abstractNum" && range.tag.attributes.some((attr5) => attr5.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && attr5.localName === "abstractNumId" && attr5.value === abstractNumId));
400520
401239
  if (!abstract || parsed.ranges.some((range) => range.start > abstract.start && range.end < abstract.end && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && ["styleLink", "numStyleLink"].includes(range.tag.localName))) {
400521
401240
  return { ok: false, code: "CAPABILITY_UNAVAILABLE", message: "Tracked shared numbering does not yet support linked style ownership." };
400522
401241
  }
@@ -400577,7 +401296,7 @@ function commitTrackedDefinitionMutation(runtime, abstractNumId, txIdPrefix, mut
400577
401296
  for (const reference of parsed.ranges) {
400578
401297
  if (reference.tag.namespaceUri !== WORDPROCESSINGML_NAMESPACE7 || reference.tag.localName !== "numId")
400579
401298
  continue;
400580
- const id = reference.tag.attributes.find((attr4) => attr4.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && attr4.localName === "val")?.value;
401299
+ const id = reference.tag.attributes.find((attr5) => attr5.namespaceUri === WORDPROCESSINGML_NAMESPACE7 && attr5.localName === "val")?.value;
400581
401300
  if (!id || !numIds.has(id))
400582
401301
  continue;
400583
401302
  const startByte = TE62.encode(xml.slice(0, reference.start)).length;
@@ -421803,10 +422522,10 @@ function insertBeforeSectPr(documentXml, insertion) {
421803
422522
  xml: documentXml.slice(0, at) + insertion + documentXml.slice(at)
421804
422523
  };
421805
422524
  }
421806
- function ensureDocumentRootNamespace(xml, attr4, uri) {
421807
- if (xml.includes(`${attr4}=`))
422525
+ function ensureDocumentRootNamespace(xml, attr5, uri) {
422526
+ if (xml.includes(`${attr5}=`))
421808
422527
  return xml;
421809
- return xml.replace(/<w:document\b/, `<w:document ${attr4}="${escapeXmlAttribute3(uri)}"`);
422528
+ return xml.replace(/<w:document\b/, `<w:document ${attr5}="${escapeXmlAttribute3(uri)}"`);
421810
422529
  }
421811
422530
  function spliceRunIntoParagraphXml(paraXml, runXml, offset, allocateWId) {
421812
422531
  const selfClosed = /^<([\w.-]+:p)\b([^>]*?)\/>$/.exec(paraXml);
@@ -422250,10 +422969,10 @@ function insertHeaderFooterParagraph(partXml, paragraphXml, kind) {
422250
422969
  xml: withNamespace.slice(0, finalCloseIdx) + paragraphXml + withNamespace.slice(finalCloseIdx)
422251
422970
  };
422252
422971
  }
422253
- function ensureRootNamespace(xml, attr4, uri) {
422254
- if (xml.includes(`${attr4}=`))
422972
+ function ensureRootNamespace(xml, attr5, uri) {
422973
+ if (xml.includes(`${attr5}=`))
422255
422974
  return xml;
422256
- return xml.replace(/<(w:(?:hdr|ftr))\b/, `<$1 ${attr4}="${escapeXmlAttribute3(uri)}"`);
422975
+ return xml.replace(/<(w:(?:hdr|ftr))\b/, `<$1 ${attr5}="${escapeXmlAttribute3(uri)}"`);
422257
422976
  }
422258
422977
  function insertAtHeaderFooterStart(partXml, paragraphXml, kind) {
422259
422978
  const openTag = kind === "header" ? /<w:hdr\b[^>]*>/ : /<w:ftr\b[^>]*>/;
@@ -426774,9 +427493,9 @@ function normalizeSettingsXml(xml) {
426774
427493
  const ns = [];
426775
427494
  const rest = [];
426776
427495
  for (const m of attrs.matchAll(XML_ATTR_RE)) {
426777
- const attr4 = m[0];
426778
- const trimmed = attr4.trimStart();
426779
- (/^(?:xmlns(?::|=)|mc:Ignorable=)/.test(trimmed) ? ns : rest).push(attr4);
427496
+ const attr5 = m[0];
427497
+ const trimmed = attr5.trimStart();
427498
+ (/^(?:xmlns(?::|=)|mc:Ignorable=)/.test(trimmed) ? ns : rest).push(attr5);
426780
427499
  }
426781
427500
  return "<w:settings" + [...ns.sort(), ...rest].join("") + close;
426782
427501
  });
@@ -426789,19 +427508,19 @@ function normalizeSettingsXml(xml) {
426789
427508
  const ns = [];
426790
427509
  const rest = [];
426791
427510
  for (const m of attrs.matchAll(XML_ATTR_RE)) {
426792
- const attr4 = m[0];
426793
- const trimmed = attr4.trimStart();
427511
+ const attr5 = m[0];
427512
+ const trimmed = attr5.trimStart();
426794
427513
  if (trimmed.startsWith("xmlns:")) {
426795
427514
  const prefix2 = trimmed.slice("xmlns:".length, trimmed.indexOf("="));
426796
427515
  if (usedPrefixes.has(prefix2))
426797
- ns.push(attr4);
427516
+ ns.push(attr5);
426798
427517
  continue;
426799
427518
  }
426800
427519
  if (trimmed.startsWith("xmlns=")) {
426801
- ns.push(attr4);
427520
+ ns.push(attr5);
426802
427521
  continue;
426803
427522
  }
426804
- rest.push(attr4);
427523
+ rest.push(attr5);
426805
427524
  }
426806
427525
  return open2 + [...ns.sort(), ...rest].join("") + close;
426807
427526
  });
@@ -429904,7 +430623,7 @@ function buildTrackedTableBlockReplayPlan(input) {
429904
430623
  bodyOperations: input.bodyOperations.filter((operation) => !ownedIds.has(operation.blockId))
429905
430624
  };
429906
430625
  }
429907
- var W27 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", W149 = "http://schemas.microsoft.com/office/word/2010/wordml", STORY = "body:/word/document.xml", TE74, paragraphId2 = (range) => range.tag.attributes.find((attr4) => attr4.namespaceUri === W149 && attr4.localName === "paraId")?.value;
430626
+ var W27 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", W149 = "http://schemas.microsoft.com/office/word/2010/wordml", STORY = "body:/word/document.xml", TE74, paragraphId2 = (range) => range.tag.attributes.find((attr5) => attr5.namespaceUri === W149 && attr5.localName === "paraId")?.value;
429908
430627
  var init_tracked_table_block_replay = __esm(() => {
429909
430628
  init_sd_document_session_internal();
429910
430629
  init_tracked_table_row_replay();
@@ -444609,11 +445328,11 @@ function captureDependencies(context, sourcePartUri, xml, namespaces, definition
444609
445328
  const styleIds = new Set;
444610
445329
  const numberIds = new Set;
444611
445330
  for (const range of parsed.ranges) {
444612
- for (const attr4 of range.tag.attributes) {
444613
- if (attr4.namespaceUri === R2) {
444614
- ids.add(attr4.value);
445331
+ for (const attr5 of range.tag.attributes) {
445332
+ if (attr5.namespaceUri === R2) {
445333
+ ids.add(attr5.value);
444615
445334
  }
444616
- if (range.tag.namespaceUri === W28 && attr4.namespaceUri === W28 && (attr4.localName.startsWith("theme") || attr4.localName.endsWith("Theme"))) {
445335
+ if (range.tag.namespaceUri === W28 && attr5.namespaceUri === W28 && (attr5.localName.startsWith("theme") || attr5.localName.endsWith("Theme"))) {
444617
445336
  needsTheme = true;
444618
445337
  anyThemeReference = true;
444619
445338
  }
@@ -445350,13 +446069,13 @@ function captureCommentFamily(context, owner, ids) {
445350
446069
  invalid4("PRECONDITION_FAILED", "Modern comment metadata has no root.");
445351
446070
  return { rel, xml: partXml, root };
445352
446071
  });
445353
- const attr4 = (r, name) => r.tag.attributes.find((a) => a.localName === name)?.value;
446072
+ const attr5 = (r, name) => r.tag.attributes.find((a) => a.localName === name)?.value;
445354
446073
  let size = -1;
445355
446074
  while (size !== paraIds.size) {
445356
446075
  size = paraIds.size;
445357
446076
  for (const part of entries2)
445358
446077
  for (const child of part.root.children) {
445359
- const parent = attr4(child.range, "paraIdParent"), id = attr4(child.range, "paraId");
446078
+ const parent = attr5(child.range, "paraIdParent"), id = attr5(child.range, "paraId");
445360
446079
  if (parent && id && paraIds.has(parent))
445361
446080
  paraIds.add(id);
445362
446081
  }
@@ -445368,14 +446087,14 @@ function captureCommentFamily(context, owner, ids) {
445368
446087
  const durableIds = new Set;
445369
446088
  for (const part of entries2)
445370
446089
  for (const child of part.root.children) {
445371
- if (paraIds.has(attr4(child.range, "paraId") ?? "")) {
445372
- const durable = attr4(child.range, "durableId");
446090
+ if (paraIds.has(attr5(child.range, "paraId") ?? "")) {
446091
+ const durable = attr5(child.range, "durableId");
445373
446092
  if (durable)
445374
446093
  durableIds.add(durable.toUpperCase());
445375
446094
  }
445376
446095
  }
445377
446096
  for (const part of entries2) {
445378
- const children2 = part.root.children.filter((c) => paraIds.has(attr4(c.range, "paraId") ?? "") || durableIds.has((attr4(c.range, "durableId") ?? "").toUpperCase()));
446097
+ const children2 = part.root.children.filter((c) => paraIds.has(attr5(c.range, "paraId") ?? "") || durableIds.has((attr5(c.range, "durableId") ?? "").toUpperCase()));
445379
446098
  result.set(part.rel.resolvedTarget, TE79.encode(part.xml.slice(part.root.range.start, part.root.range.openEnd) + children2.map((c) => part.xml.slice(c.range.start, c.range.end)).join("") + part.xml.slice(part.root.range.closeStart, part.root.range.end)));
445380
446099
  }
445381
446100
  return result;
@@ -453449,9 +454168,9 @@ var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes,
453449
454168
  switch (currPos.right.content.constructor) {
453450
454169
  case ContentFormat: {
453451
454170
  const { key: key3, value: value3 } = currPos.right.content;
453452
- const attr4 = attributes[key3];
453453
- if (attr4 !== undefined) {
453454
- if (equalAttrs(attr4, value3)) {
454171
+ const attr5 = attributes[key3];
454172
+ if (attr5 !== undefined) {
454173
+ if (equalAttrs(attr5, value3)) {
453455
454174
  negatedAttributes.delete(key3);
453456
454175
  } else {
453457
454176
  if (length2 === 0) {
@@ -454626,9 +455345,9 @@ var init_yjs = __esm(() => {
454626
455345
  }
454627
455346
  } else if (!item.deleted) {
454628
455347
  oldAttributes.set(key3, value3);
454629
- const attr4 = attributes[key3];
454630
- if (attr4 !== undefined) {
454631
- if (!equalAttrs(attr4, value3)) {
455348
+ const attr5 = attributes[key3];
455349
+ if (attr5 !== undefined) {
455350
+ if (!equalAttrs(attr5, value3)) {
454632
455351
  if (action2 === "retain") {
454633
455352
  addOp();
454634
455353
  }
@@ -454637,7 +455356,7 @@ var init_yjs = __esm(() => {
454637
455356
  } else {
454638
455357
  attributes[key3] = value3;
454639
455358
  }
454640
- } else if (attr4 !== null) {
455359
+ } else if (attr5 !== null) {
454641
455360
  item.delete(transaction);
454642
455361
  }
454643
455362
  }
@@ -455267,8 +455986,8 @@ var init_yjs = __esm(() => {
455267
455986
  const node4 = nestedNodes[i2];
455268
455987
  str += `<${node4.nodeName}`;
455269
455988
  for (let j = 0;j < node4.attrs.length; j++) {
455270
- const attr4 = node4.attrs[j];
455271
- str += ` ${attr4.key}="${attr4.value}"`;
455989
+ const attr5 = node4.attrs[j];
455990
+ str += ` ${attr5.key}="${attr5.value}"`;
455272
455991
  }
455273
455992
  str += ">";
455274
455993
  }
@@ -468114,8 +468833,8 @@ function clean(...arrays) {
468114
468833
  function createView(arr) {
468115
468834
  return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
468116
468835
  }
468117
- function rotr(word5, shift) {
468118
- return word5 << 32 - shift | word5 >>> shift;
468836
+ function rotr(word6, shift) {
468837
+ return word6 << 32 - shift | word6 >>> shift;
468119
468838
  }
468120
468839
  function utf8ToBytes(str) {
468121
468840
  if (typeof str !== "string")
@@ -473576,6 +474295,12 @@ function publishContentControlGroups(scope, groups, blockIds) {
473576
474295
  scope.order.set(unit, index2);
473577
474296
  }
473578
474297
  }
474298
+ for (const group of groups) {
474299
+ const key3 = ORDER_PREFIX + group.id;
474300
+ const existing = group.blockIds.find((id2) => typeof scope.order.get(id2) === "number");
474301
+ if (!scope.order.has(key3) && existing)
474302
+ scope.order.set(key3, readBlockOrder(scope, existing, 0));
474303
+ }
473579
474304
  for (const group of groups) {
473580
474305
  const key3 = ORDER_PREFIX + group.id;
473581
474306
  if (scope.order.has(key3))
@@ -473586,9 +474311,8 @@ function publishContentControlGroups(scope, groups, blockIds) {
473586
474311
  const after2 = units.slice(at + 1).find((unit) => typeof scope.order.get(unit) === "number");
473587
474312
  const left = before2 ? readBlockOrder(scope, before2, at - 1) : null;
473588
474313
  const right = after2 ? readBlockOrder(scope, after2, at + 1) : null;
473589
- const existing = group.blockIds.find((id2) => typeof scope.order.get(id2) === "number");
473590
- let order = existing ? readBlockOrder(scope, existing, at) : left === null ? (right ?? 1) - 1 : right === null ? left + 1 : (left + right) / 2;
473591
- if (!existing && left !== null && right !== null && right <= left) {
474314
+ let order = left === null ? (right ?? 1) - 1 : right === null ? left + 1 : (left + right) / 2;
474315
+ if (left !== null && right !== null && right <= left) {
473592
474316
  for (const [index2, unit] of units.entries())
473593
474317
  scope.order.set(unit, index2);
473594
474318
  order = at;
@@ -473658,8 +474382,8 @@ function bindOriginalBomNoteBoundaries(input) {
473658
474382
  const last2 = source.paragraphs.at(-1);
473659
474383
  if (!first || !last2 || new Set(source.paragraphs.map((p) => p.blockId)).size !== source.paragraphs.length || source.paragraphs.some((p) => !p.paraId || p.tableNodeId))
473660
474384
  return false;
473661
- const start = first.byteStart - ENCODER2.encode(first.leadingXml).length;
473662
- const end = last2.byteEnd + ENCODER2.encode(source.trailingXml).length;
474385
+ const start = first.byteStart - ENCODER3.encode(first.leadingXml).length;
474386
+ const end = last2.byteEnd + ENCODER3.encode(source.trailingXml).length;
473663
474387
  if (start < 3 || end - 3 < last2.byteEnd)
473664
474388
  return false;
473665
474389
  const scope = resolveStoryShardScope(input.target);
@@ -473711,7 +474435,7 @@ function readBomCorrectedLeadingXml(block) {
473711
474435
  const repair = BY_FIRST_BLOCK.get(block);
473712
474436
  return repair && matches(repair) ? repair.leadingXml : String(block.get(BLOCK_KEY.leadingXml) ?? "");
473713
474437
  }
473714
- var DECODER4, ENCODER2, BY_META, BY_FIRST_BLOCK;
474438
+ var DECODER4, ENCODER3, BY_META, BY_FIRST_BLOCK;
473715
474439
  var init_bom_boundary_repair = __esm(() => {
473716
474440
  init_yjs();
473717
474441
  init_sd_document_session_internal();
@@ -473720,7 +474444,7 @@ var init_bom_boundary_repair = __esm(() => {
473720
474444
  init_content_control_groups();
473721
474445
  init_scope3();
473722
474446
  DECODER4 = new TextDecoder;
473723
- ENCODER2 = new TextEncoder;
474447
+ ENCODER3 = new TextEncoder;
473724
474448
  BY_META = new WeakMap;
473725
474449
  BY_FIRST_BLOCK = new WeakMap;
473726
474450
  });
@@ -483920,7 +484644,7 @@ function projectCommentsFamilySource(comments, source, owner) {
483920
484644
  }
483921
484645
  }
483922
484646
  const generatedRows = emitted.ranges.filter((row) => row.tag.namespaceUri === namespace && row.tag.localName === localName3);
483923
- const attribute3 = (row, name) => row.tag.attributes.find((attr4) => attr4.namespaceUri === namespace && attr4.localName === name)?.value;
484647
+ const attribute3 = (row, name) => row.tag.attributes.find((attr5) => attr5.namespaceUri === namespace && attr5.localName === name)?.value;
483924
484648
  const generatedByKey = new Map(generatedRows.map((row) => [attribute3(row, uri === BODY ? "id" : "paraId"), row]));
483925
484649
  const consumed = new Set;
483926
484650
  const patches = [];
@@ -483951,7 +484675,7 @@ function projectCommentsFamilySource(comments, source, owner) {
483951
484675
  if (changedBody)
483952
484676
  patches.push({ start: row.start, end: row.end, xml: emit(comment) });
483953
484677
  else {
483954
- const id2 = row.tag.attributes.find((attr4) => attr4.namespaceUri === W30 && attr4.localName === "id");
484678
+ const id2 = row.tag.attributes.find((attr5) => attr5.namespaceUri === W30 && attr5.localName === "id");
483955
484679
  const frame = id2 ? attributeFrame(xml, row, id2.name) : null;
483956
484680
  if (id2 && !frame)
483957
484681
  throw new Error("comment source identity attribute cannot be located");
@@ -484105,10 +484829,10 @@ function paragraphEmissionNames(context, preservedXml) {
484105
484829
  bindings2[prefix2] = namespace;
484106
484830
  return prefix2;
484107
484831
  };
484108
- const word5 = choose("w", WORD_NAMESPACE10);
484832
+ const word6 = choose("w", WORD_NAMESPACE10);
484109
484833
  const word2010 = choose("w14", WORD_2010_NAMESPACE3);
484110
484834
  const declarations = Object.entries({ "": "", ...bindings2 }).filter(([prefix2, uri]) => prefix2 !== "xml" && (context.inherited[prefix2] ?? "") !== uri).sort(([left], [right]) => left.localeCompare(right)).map(([prefix2, uri]) => ` xmlns${prefix2 ? `:${prefix2}` : ""}="${xmlEscape(uri)}"`).join("");
484111
- return { word: word5, word2010, declarations };
484835
+ return { word: word6, word2010, declarations };
484112
484836
  }
484113
484837
  var WORD_NAMESPACE10 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", WORD_2010_NAMESPACE3 = "http://schemas.microsoft.com/office/word/2010/wordml", CANONICAL_NAMESPACES;
484114
484838
  var init_xml_emission_context = __esm(() => {
@@ -487181,8 +487905,8 @@ function renderSyntheticTableCell(input) {
487181
487905
  }).slice(0, 8).toUpperCase();
487182
487906
  const prefix2 = input.tableXml.slice(input.cellSpan.start, contentStart);
487183
487907
  const inherited = new XmlEmissionContext(prefix2, input.inherited).at(prefix2.length);
487184
- const { word: word5, word2010, declarations } = paragraphEmissionNames({ inherited, source: inherited }, "");
487185
- return prefix2 + `<${word5}:p ${word2010}:paraId="${paragraphId5}"${declarations}/>` + input.tableXml.slice(contentEnd, input.cellSpan.end);
487908
+ const { word: word6, word2010, declarations } = paragraphEmissionNames({ inherited, source: inherited }, "");
487909
+ return prefix2 + `<${word6}:p ${word2010}:paraId="${paragraphId5}"${declarations}/>` + input.tableXml.slice(contentEnd, input.cellSpan.end);
487186
487910
  }
487187
487911
  function directElementSpans(xml, openEnd, closeStart, localName3) {
487188
487912
  const spans = [];
@@ -489441,7 +490165,7 @@ function createCollabV2ProjectionRuntime(options) {
489441
490165
  }
489442
490166
  let bytes;
489443
490167
  try {
489444
- bytes = await bytesEncoder.encode(record3);
490168
+ bytes = request.kind === BARRIER_KIND.save && bytesEncoder.encodeForTerminalSave ? await bytesEncoder.encodeForTerminalSave(record3) : await bytesEncoder.encode(record3);
489445
490169
  } catch (error50) {
489446
490170
  const diag = diagnosticFromThrownError(error50, "bytes encoder threw");
489447
490171
  const reason = classifyBlockingReason([diag]);
@@ -490693,7 +491417,9 @@ function mirrorStorySurfaceFromSession(input) {
490693
491417
  scope.meta.set(STORY_META_KEY.lastEditActorType, actorType);
490694
491418
  const source = input.prepared.source;
490695
491419
  const rewritesTableBoundaries = source.kind === "paragraphRangeCollapse" || source.kind === "trackedChangeDecide";
490696
- const groups = extension2.contentControlRewrite || hasContentControlGroups(scope) || rewritesTableBoundaries || extension2.family === "storyPaste" && (extension2.fragmentApply?.containsBlockControls || hasUnpublishedBlockControls(scope)) ? prepareStoryContentControlGroups(input.session, storyId, doc2) : null;
491420
+ const controlRewrite = extension2.contentControlRewrite;
491421
+ const preparesControlGroups = controlRewrite ? controlRewrite.addedBlockIds.length > 0 || controlRewrite.removedBlockIds.length > 0 || controlRewrite.leadingBlockIds.length > 0 || controlRewrite.trailingXmlChanged : hasContentControlGroups(scope) || rewritesTableBoundaries || extension2.family === "storyPaste" && (extension2.fragmentApply?.containsBlockControls || hasUnpublishedBlockControls(scope));
491422
+ const groups = preparesControlGroups ? prepareStoryContentControlGroups(input.session, storyId, doc2) : null;
490697
491423
  mirrorFamilyIntoStory({
490698
491424
  session: input.session,
490699
491425
  prepared: input.prepared,
@@ -491036,11 +491762,12 @@ function mirrorContentControlRewrite(input) {
491036
491762
  const snapshot3 = readSessionStoryPayloads(loadStorySyncContext(input.session, input.storyId));
491037
491763
  const payloadById = new Map(snapshot3.payloads.map((payload) => [payload.blockId, payload]));
491038
491764
  const changed = new Set(rewrite.contentBlockIds);
491765
+ const leadingChanged = new Set(rewrite.leadingBlockIds);
491039
491766
  const payloads = rewrite.contentBlockIds.map((id2) => {
491040
491767
  const payload = payloadById.get(id2);
491041
491768
  if (!payload)
491042
491769
  throw new Error(`Content-control rewrite paragraph ${id2} is unavailable.`);
491043
- return payload;
491770
+ return leadingChanged.has(id2) ? payload : { ...payload, leadingXml: undefined };
491044
491771
  });
491045
491772
  resolveStoryShardScope(input.doc).doc.transact(() => {
491046
491773
  for (const id2 of rewrite.removedBlockIds) {
@@ -493712,7 +494439,7 @@ function collectCommentCarriers(doc2, commentIds, session) {
493712
494439
  if (parsed.errors.length > 0)
493713
494440
  throw new Error("comment carrier XML cannot be read");
493714
494441
  const carrier = parsed.ranges.find((row) => row.tag.namespaceUri === wordNamespace && row.tag.localName === marker);
493715
- const commentId = carrier?.tag.attributes.find((attr4) => attr4.namespaceUri === wordNamespace && attr4.localName === "id")?.value;
494442
+ const commentId = carrier?.tag.attributes.find((attr5) => attr5.namespaceUri === wordNamespace && attr5.localName === "id")?.value;
493716
494443
  if (!commentId || !commentIds.has(commentId))
493717
494444
  continue;
493718
494445
  atoms.add(atom);
@@ -495854,6 +496581,12 @@ function createCollabV2SessionProjectionController(options) {
495854
496581
  record: record3,
495855
496582
  projectionRegistry: options.projectionRegistry,
495856
496583
  blobAdapter: options.blobAdapter
496584
+ }),
496585
+ encodeForTerminalSave: (record3) => encodeProjectionRecordAsDocx({
496586
+ record: record3,
496587
+ projectionRegistry: options.projectionRegistry,
496588
+ blobAdapter: options.blobAdapter,
496589
+ portableRevisionIds: true
495857
496590
  })
495858
496591
  },
495859
496592
  docxBytesValidator: {
@@ -496909,6 +497642,18 @@ async function encodeProjectionRecordAsDocx(input) {
496909
497642
  else
496910
497643
  entries4.set(zipKey(partUri), bytes);
496911
497644
  }
497645
+ if (input.portableRevisionIds) {
497646
+ const decoder13 = new TextDecoder;
497647
+ const wordParts = new Map;
497648
+ for (const [key3, bytes] of entries4) {
497649
+ if (key3.startsWith("word/") && key3.endsWith(".xml") && !key3.includes("/_rels/")) {
497650
+ wordParts.set(`/${key3}`, decoder13.decode(bytes));
497651
+ }
497652
+ }
497653
+ for (const [partUri, xml] of normalizeRevisionIdsForWordExport(wordParts)) {
497654
+ entries4.set(zipKey(partUri), encoder7.encode(xml));
497655
+ }
497656
+ }
496912
497657
  const ordered = {};
496913
497658
  for (const key3 of [...entries4.keys()].sort()) {
496914
497659
  ordered[key3] = entries4.get(key3);