@superdoc/mcp 1.2.1-next.2 → 1.2.1-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1019 -791
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -31314,7 +31314,7 @@ var init_host = __esm(() => {
|
|
|
31314
31314
|
});
|
|
31315
31315
|
|
|
31316
31316
|
// ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
|
|
31317
|
-
var SDK_VERSION = "2.15.1-next.
|
|
31317
|
+
var SDK_VERSION = "2.15.1-next.4";
|
|
31318
31318
|
|
|
31319
31319
|
// ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
|
|
31320
31320
|
import { chmodSync, existsSync } from "node:fs";
|
|
@@ -118889,6 +118889,11 @@ function validateId(id, operationName) {
|
|
|
118889
118889
|
});
|
|
118890
118890
|
}
|
|
118891
118891
|
}
|
|
118892
|
+
function validateContentControlId(id, operationName) {
|
|
118893
|
+
if (id !== undefined && (typeof id !== "string" || id.length === 0)) {
|
|
118894
|
+
throw new DocumentApiValidationError("INVALID_INPUT", `${operationName} requires a non-empty 'contentControlId' string when provided.`);
|
|
118895
|
+
}
|
|
118896
|
+
}
|
|
118892
118897
|
function validateNamespace(namespace, operationName) {
|
|
118893
118898
|
if (typeof namespace !== "string" || namespace.length === 0) {
|
|
118894
118899
|
throw new DocumentApiValidationError("INVALID_INPUT", `${operationName} requires a non-empty 'namespace' string.`, {
|
|
@@ -118956,6 +118961,14 @@ function executeAnchoredMetadataList(adapter, query2) {
|
|
|
118956
118961
|
}
|
|
118957
118962
|
function executeAnchoredMetadataGet(adapter, input) {
|
|
118958
118963
|
validateId(input.id, "metadata.get");
|
|
118964
|
+
validateContentControlId(input.contentControlId, "metadata.get");
|
|
118965
|
+
if (input.contentControlId !== undefined) {
|
|
118966
|
+
if (input.story === undefined)
|
|
118967
|
+
return null;
|
|
118968
|
+
validateStoryLocator(input.story, "metadata.get.story");
|
|
118969
|
+
if (input.story.storyType !== "body")
|
|
118970
|
+
return null;
|
|
118971
|
+
}
|
|
118959
118972
|
return adapter.get(input);
|
|
118960
118973
|
}
|
|
118961
118974
|
function executeAnchoredMetadataUpdate(adapter, input, options) {
|
|
@@ -118969,6 +118982,14 @@ function executeAnchoredMetadataRemove(adapter, input, options) {
|
|
|
118969
118982
|
}
|
|
118970
118983
|
function executeAnchoredMetadataResolve(adapter, input) {
|
|
118971
118984
|
validateId(input.id, "metadata.resolve");
|
|
118985
|
+
validateContentControlId(input.contentControlId, "metadata.resolve");
|
|
118986
|
+
if (input.contentControlId !== undefined) {
|
|
118987
|
+
if (input.story === undefined)
|
|
118988
|
+
return null;
|
|
118989
|
+
validateStoryLocator(input.story, "metadata.resolve.story");
|
|
118990
|
+
if (input.story.storyType !== "body")
|
|
118991
|
+
return null;
|
|
118992
|
+
}
|
|
118972
118993
|
return adapter.resolve(input);
|
|
118973
118994
|
}
|
|
118974
118995
|
var init_anchored_metadata = __esm(() => {
|
|
@@ -118976,6 +118997,7 @@ var init_anchored_metadata = __esm(() => {
|
|
|
118976
118997
|
init_errors5();
|
|
118977
118998
|
init_selection_target_validator();
|
|
118978
118999
|
init_validation_primitives();
|
|
119000
|
+
init_story_validator();
|
|
118979
119001
|
});
|
|
118980
119002
|
|
|
118981
119003
|
// ../../packages/document-api/dist/protection/protection.js
|
|
@@ -162777,7 +162799,7 @@ var init_collapsed_inline_insertion_site = __esm(() => {
|
|
|
162777
162799
|
});
|
|
162778
162800
|
|
|
162779
162801
|
// ../../../v2/editor-core/dist/document/transactions/compile-edit-text-inline-plan.js
|
|
162780
|
-
function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, collapsedObjectBoundary, collapsedInlineAffinity, inheritedNamespaceBindings = {}) {
|
|
162802
|
+
function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, collapsedObjectBoundary, collapsedInlineAffinity, inheritedNamespaceBindings = {}, collapsedOutsideContentControl = false) {
|
|
162781
162803
|
const xml = TD21.decode(paragraphBytes);
|
|
162782
162804
|
const model = parseParagraphInlineMap(xml, inheritedNamespaceBindings);
|
|
162783
162805
|
const leaves = model.leaves();
|
|
@@ -162820,7 +162842,7 @@ function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, c
|
|
|
162820
162842
|
if (beside)
|
|
162821
162843
|
return beside;
|
|
162822
162844
|
}
|
|
162823
|
-
const scope = resolveEditScope(model.pieces, startOffset, endOffset, collapsedInlineAffinity);
|
|
162845
|
+
const scope = resolveEditScope(model.pieces, startOffset, endOffset, collapsedInlineAffinity, collapsedOutsideContentControl);
|
|
162824
162846
|
if (!scope.ok)
|
|
162825
162847
|
return { ok: false, reason: scope.reason };
|
|
162826
162848
|
const pieces = scope.pieces;
|
|
@@ -162832,7 +162854,7 @@ function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, c
|
|
|
162832
162854
|
return { ok: false, reason: "invalid-range" };
|
|
162833
162855
|
}
|
|
162834
162856
|
const hasEditableLeaf = pieces.some((piece) => isVisibleText(piece) || isLiveControl(piece) || startOffset !== endOffset && isLiveNoteReference(piece));
|
|
162835
|
-
if (!hasEditableLeaf) {
|
|
162857
|
+
if (!hasEditableLeaf && !(collapsedOutsideContentControl && startOffset === endOffset && newText.length > 0)) {
|
|
162836
162858
|
if (newText.length === 0 && scope.wrapperRemovalOps.length > 0) {
|
|
162837
162859
|
return {
|
|
162838
162860
|
ok: true,
|
|
@@ -162849,7 +162871,7 @@ function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, c
|
|
|
162849
162871
|
}
|
|
162850
162872
|
if (startOffset === endOffset) {
|
|
162851
162873
|
const plan2 = planCollapsedInsert(paragraphBytes, xml, pieces, leaves, startOffset, newText, visibleLength === 0, inlineContext, collapsedInlineAffinity);
|
|
162852
|
-
return plan2.ok && scope.requiresCollaborationSessionSync ? { ...plan2, requiresCollaborationSessionSync: true } : plan2;
|
|
162874
|
+
return plan2.ok && (scope.requiresCollaborationSessionSync || collapsedOutsideContentControl) ? { ...plan2, requiresCollaborationSessionSync: true } : plan2;
|
|
162853
162875
|
}
|
|
162854
162876
|
const plan = planReplace(paragraphBytes, pieces, leaves, startOffset, endOffset, newText, scope.wrapperRemovalOps);
|
|
162855
162877
|
return plan.ok && (scope.requiresCollaborationSessionSync || preservesCrossedBookmarks) ? { ...plan, requiresCollaborationSessionSync: true } : plan;
|
|
@@ -163441,13 +163463,13 @@ function hasNonWordMarkerAtCollapsedMoveBoundary(pieces, at, coordinateSpace = "
|
|
|
163441
163463
|
function firstNonFieldRangeStartMarker(markers) {
|
|
163442
163464
|
return markers.find((piece) => piece.role === "range-start" && !isFieldMarker(piece.markerKind)) ?? null;
|
|
163443
163465
|
}
|
|
163444
|
-
function resolveEditScope(pieces, start, end, collapsedInlineAffinity) {
|
|
163466
|
+
function resolveEditScope(pieces, start, end, collapsedInlineAffinity, collapsedOutsideContentControl = false) {
|
|
163445
163467
|
let current = pieces;
|
|
163446
163468
|
let descended = false;
|
|
163447
163469
|
let emptySdt;
|
|
163448
163470
|
let requiresCollaborationSessionSync = false;
|
|
163449
163471
|
for (;; ) {
|
|
163450
|
-
const container = current.find((piece) => piece.kind === "container" && containerContainsRange(piece, start, end)) ?? (start === end ? findCollapsedEdgeContainer(current, start, collapsedInlineAffinity
|
|
163472
|
+
const container = current.find((piece) => piece.kind === "container" && containerContainsRange(piece, start, end)) ?? (start === end ? findCollapsedEdgeContainer(current, start, collapsedInlineAffinity, collapsedOutsideContentControl) : undefined);
|
|
163451
163473
|
if (!container) {
|
|
163452
163474
|
if (start === end) {
|
|
163453
163475
|
return {
|
|
@@ -163550,9 +163572,24 @@ function containerContainsRange(piece, start, end) {
|
|
|
163550
163572
|
return piece.visibleStart < start && start < piece.visibleEnd;
|
|
163551
163573
|
return piece.visibleStart <= start && end <= piece.visibleEnd;
|
|
163552
163574
|
}
|
|
163553
|
-
function findCollapsedEdgeContainer(pieces, at,
|
|
163575
|
+
function findCollapsedEdgeContainer(pieces, at, collapsedInlineAffinity, collapsedOutsideContentControl = false) {
|
|
163554
163576
|
const emptySdtsAtPoint = pieces.filter((piece) => piece.kind === "container" && piece.containerKind === "sdt" && piece.visibleStart === at && piece.visibleEnd === at);
|
|
163555
|
-
return pieces.find((piece) =>
|
|
163577
|
+
return pieces.find((piece) => {
|
|
163578
|
+
if (piece.kind !== "container")
|
|
163579
|
+
return false;
|
|
163580
|
+
if (collapsedOutsideContentControl && piece.containerKind === "sdt")
|
|
163581
|
+
return false;
|
|
163582
|
+
if (piece.visibleStart === piece.visibleEnd) {
|
|
163583
|
+
return collapsedInlineAffinity == null && emptySdtsAtPoint.length === 1 && piece.containerKind === "sdt" && piece.visibleStart === at;
|
|
163584
|
+
}
|
|
163585
|
+
if (piece.visibleStart === at) {
|
|
163586
|
+
return piece.containerKind === "sdt" ? collapsedInlineAffinity !== "upstream" : !hasVisibleSiblingEndingAt(pieces, at);
|
|
163587
|
+
}
|
|
163588
|
+
if (piece.visibleEnd === at) {
|
|
163589
|
+
return piece.containerKind === "sdt" ? collapsedInlineAffinity !== "downstream" && !hasVisibleSiblingStartingAt(pieces, at, "sdt") : !hasVisibleSiblingStartingAt(pieces, at);
|
|
163590
|
+
}
|
|
163591
|
+
return false;
|
|
163592
|
+
});
|
|
163556
163593
|
}
|
|
163557
163594
|
function planEmptySdtInsert(paragraphBytes, piece, newText) {
|
|
163558
163595
|
const raw = piece.rawXml;
|
|
@@ -196194,7 +196231,7 @@ function rewriteLocalizedDirect(bytes, window2, op, inheritedNamespaceBindings =
|
|
|
196194
196231
|
return rewritten;
|
|
196195
196232
|
return { ok: true, bytes: TE16.encode(rewritten.xml), runPropertiesXml: "" };
|
|
196196
196233
|
}
|
|
196197
|
-
const plan = planDirectInlineEdit(paragraphBytes, op.on.startOffset, op.on.endOffset, op.newText, op.on.collapsedObjectBoundary, op.on.collapsedInlineAffinity, inheritedNamespaceBindings);
|
|
196234
|
+
const plan = planDirectInlineEdit(paragraphBytes, op.on.startOffset, op.on.endOffset, op.newText, op.on.collapsedObjectBoundary, op.on.collapsedInlineAffinity, inheritedNamespaceBindings, op.on.collapsedOutsideContentControl);
|
|
196198
196235
|
if (plan.ok) {
|
|
196199
196236
|
return {
|
|
196200
196237
|
ok: true,
|
|
@@ -209787,7 +209824,7 @@ function planCut(pieces, levelStart, input, rootPieces, chain = []) {
|
|
|
209787
209824
|
if (strict.kind === "container" && strict.containerKind === "sdt" && input.allowMetadataAnchorSplit) {
|
|
209788
209825
|
if (input.space === "tracked")
|
|
209789
209826
|
return { kind: "reject", reason: "paragraph-split-point-unsupported" };
|
|
209790
|
-
const chunks = anchoredMetadataChunks(strict, input.allocateWId);
|
|
209827
|
+
const chunks = anchoredMetadataChunks(strict, input.allocateWId, input.knownMetadataAnchorIds, input.onMetadataAnchorClone);
|
|
209791
209828
|
if (!chunks)
|
|
209792
209829
|
return { kind: "reject", reason: "paragraph-split-point-unsupported" };
|
|
209793
209830
|
return planCut(strict.children, chunks.contentStart, input, rootPieces, [
|
|
@@ -209843,7 +209880,7 @@ function wrapperChunks(piece) {
|
|
|
209843
209880
|
contentStart: piece.charStart + openEnd
|
|
209844
209881
|
};
|
|
209845
209882
|
}
|
|
209846
|
-
function anchoredMetadataChunks(piece, allocateWId) {
|
|
209883
|
+
function anchoredMetadataChunks(piece, allocateWId, knownMetadataAnchorIds, onMetadataAnchorClone) {
|
|
209847
209884
|
if (piece.children.length === 0)
|
|
209848
209885
|
return null;
|
|
209849
209886
|
const raw = piece.rawXml;
|
|
@@ -209857,16 +209894,23 @@ function anchoredMetadataChunks(piece, allocateWId) {
|
|
|
209857
209894
|
const originalId = /<w:id w:val="\d+"\s*\/>/.exec(properties)?.[0];
|
|
209858
209895
|
const alias = '<w:alias w:val="Anchored metadata"/>';
|
|
209859
209896
|
const tag = /<w:tag w:val="[^"]+"\/>/.exec(normalizedProperties)?.[0];
|
|
209897
|
+
const tagValue = tag ? /w:val="([^"]+)"/.exec(tag)?.[1] : null;
|
|
209860
209898
|
const appearance = '<w15:appearance w15:val="hidden"/>';
|
|
209861
209899
|
const plainText = "<w:text/>";
|
|
209862
|
-
|
|
209900
|
+
const canonical = `<w:sdtPr>${id}${alias}${tag}${appearance}${plainText}</w:sdtPr>`;
|
|
209901
|
+
const legacy = `<w:sdtPr>${id}${tag}${appearance}${plainText}</w:sdtPr>`;
|
|
209902
|
+
if (!id || !originalId || !tag || !tagValue || !knownMetadataAnchorIds?.has(decodeXmlAttributeValue(tagValue)) || !normalizedProperties.includes(appearance) || !normalizedProperties.includes(plainText) || normalizedProperties !== canonical && !(normalizedProperties === legacy && knownMetadataAnchorIds?.has(decodeXmlAttributeValue(tagValue)))) {
|
|
209863
209903
|
return null;
|
|
209864
209904
|
}
|
|
209865
209905
|
const originalPrefix = prefix[0];
|
|
209866
209906
|
return {
|
|
209867
209907
|
contentStart: piece.charStart + originalPrefix.length,
|
|
209868
209908
|
close,
|
|
209869
|
-
reopen: () =>
|
|
209909
|
+
reopen: () => {
|
|
209910
|
+
const cloneId = String(allocateWId());
|
|
209911
|
+
onMetadataAnchorClone?.(decodeXmlAttributeValue(tagValue), /\d+/.exec(originalId)[0], cloneId);
|
|
209912
|
+
return originalPrefix.replace(originalId, originalId.replace(/(w:val=")\d+/, (_match, attribute) => `${attribute}${cloneId}`));
|
|
209913
|
+
}
|
|
209870
209914
|
};
|
|
209871
209915
|
}
|
|
209872
209916
|
function openTagEnd(raw) {
|
|
@@ -214161,7 +214205,9 @@ function prepareParagraphSplit(input) {
|
|
|
214161
214205
|
space: input.coordinateSpace,
|
|
214162
214206
|
allocateWId: input.allocateWId,
|
|
214163
214207
|
atomicObjectsAsCaretSlots: true,
|
|
214164
|
-
allowMetadataAnchorSplit: true
|
|
214208
|
+
allowMetadataAnchorSplit: true,
|
|
214209
|
+
knownMetadataAnchorIds: new Set(input.knownMetadataAnchorIds),
|
|
214210
|
+
onMetadataAnchorClone: input.onMetadataAnchorClone
|
|
214165
214211
|
});
|
|
214166
214212
|
if (!slice.ok)
|
|
214167
214213
|
return slice;
|
|
@@ -214196,6 +214242,64 @@ function renderPreparedParagraphSplit(split, trackedStamp) {
|
|
|
214196
214242
|
const head = trackedStamp ? injectParagraphMarkTrackedMarker(split.headXml, "ins", trackedStamp) : split.headXml;
|
|
214197
214243
|
return head + split.tailXml;
|
|
214198
214244
|
}
|
|
214245
|
+
function prepareMetadataSplitStorage(state, bindings, clones) {
|
|
214246
|
+
const perPart = {};
|
|
214247
|
+
const preconditions = [];
|
|
214248
|
+
const parts = new Map;
|
|
214249
|
+
for (const clone3 of clones) {
|
|
214250
|
+
const binding = bindings?.find((candidate2) => candidate2.id === clone3.id);
|
|
214251
|
+
if (!binding || binding.physicalIds && !binding.physicalIds.includes(clone3.originalId))
|
|
214252
|
+
return { ok: false };
|
|
214253
|
+
const entries = parts.get(binding.partUri) ?? [];
|
|
214254
|
+
entries.push({ ...clone3, physicalIds: binding.physicalIds });
|
|
214255
|
+
parts.set(binding.partUri, entries);
|
|
214256
|
+
}
|
|
214257
|
+
for (const [partUri, entries] of parts) {
|
|
214258
|
+
const bytes = state.packageBytes.get(partUri);
|
|
214259
|
+
if (!bytes)
|
|
214260
|
+
return { ok: false };
|
|
214261
|
+
let xml = TD51.decode(bytes);
|
|
214262
|
+
const updatedIds = new Map;
|
|
214263
|
+
for (const entry of entries) {
|
|
214264
|
+
let matched = 0;
|
|
214265
|
+
let updated = 0;
|
|
214266
|
+
xml = xml.replace(/<ref\b[^>]*>/g, (tag) => {
|
|
214267
|
+
const rawId = /\bid="([^"]*)"/.exec(tag)?.[1];
|
|
214268
|
+
if (rawId === undefined || decodeXmlAttributeValue(rawId) !== entry.id)
|
|
214269
|
+
return tag;
|
|
214270
|
+
matched += 1;
|
|
214271
|
+
const bindingAttributes = [...tag.matchAll(/\bsdAnchorIdsV1\s*=\s*(['"])(.*?)\1/g)];
|
|
214272
|
+
const currentIds = updatedIds.get(entry.id);
|
|
214273
|
+
if (bindingAttributes.length > 1 || bindingAttributes.length === 0 && /\bsdAnchorIdsV1\b/.test(tag))
|
|
214274
|
+
return tag;
|
|
214275
|
+
const rawIds = bindingAttributes[0]?.[2];
|
|
214276
|
+
if (rawIds !== undefined && decodeXmlAttributeValue(rawIds) !== (currentIds ?? entry.physicalIds)?.join(","))
|
|
214277
|
+
return tag;
|
|
214278
|
+
if (rawIds === undefined && (entry.physicalIds || currentIds))
|
|
214279
|
+
return tag;
|
|
214280
|
+
const ids = currentIds ?? entry.physicalIds ?? [entry.originalId];
|
|
214281
|
+
if (ids.includes(entry.cloneId))
|
|
214282
|
+
return tag;
|
|
214283
|
+
const attribute = `sdAnchorIdsV1="${[...ids, entry.cloneId].join(",")}"`;
|
|
214284
|
+
updatedIds.set(entry.id, [...ids, entry.cloneId]);
|
|
214285
|
+
updated += 1;
|
|
214286
|
+
return rawIds === undefined ? tag.replace(/>$/, ` ${attribute}>`) : tag.replace(bindingAttributes[0][0], attribute);
|
|
214287
|
+
});
|
|
214288
|
+
if (matched !== 1 || updated !== 1)
|
|
214289
|
+
return { ok: false };
|
|
214290
|
+
}
|
|
214291
|
+
const patches = [{
|
|
214292
|
+
kind: "replaceBytes",
|
|
214293
|
+
order: 0,
|
|
214294
|
+
startByte: 0,
|
|
214295
|
+
endByte: bytes.length,
|
|
214296
|
+
bytes: TE24.encode(xml)
|
|
214297
|
+
}];
|
|
214298
|
+
perPart[partUri] = { kind: "modify", patches };
|
|
214299
|
+
preconditions.push(localizedByteWindowPrecondition2(partUri, bytes, patches));
|
|
214300
|
+
}
|
|
214301
|
+
return { ok: true, perPart, preconditions };
|
|
214302
|
+
}
|
|
214199
214303
|
function runParagraphSplitCommit(input) {
|
|
214200
214304
|
const op = input.op;
|
|
214201
214305
|
if (input.options.expectedPackageRevision && input.options.expectedPackageRevision !== input.state.packageRevision) {
|
|
@@ -214211,12 +214315,15 @@ function runParagraphSplitCommit(input) {
|
|
|
214211
214315
|
const provisionalParaId = op.provisionalParaId ?? mintParaId(input.state, input.state.packageRevision, target.entry.ordinal + 1);
|
|
214212
214316
|
const tailParaId = provisionalParaId;
|
|
214213
214317
|
const splitAllocatedWIds = [];
|
|
214318
|
+
const metadataClones = [];
|
|
214214
214319
|
const primarySplit = prepareParagraphSplit({
|
|
214215
214320
|
paragraphXml: paraXml,
|
|
214216
214321
|
partBytes: bytes,
|
|
214217
214322
|
paragraphByteStart: target.entry.byteStart,
|
|
214218
214323
|
offset: op.offset,
|
|
214219
214324
|
coordinateSpace: op.coordinateSpace ?? "visible",
|
|
214325
|
+
knownMetadataAnchorIds: op.knownMetadataAnchorIds,
|
|
214326
|
+
onMetadataAnchorClone: (id, originalId, cloneId) => metadataClones.push({ id, originalId, cloneId }),
|
|
214220
214327
|
tailParaId,
|
|
214221
214328
|
allocateWId: () => {
|
|
214222
214329
|
const wId = allocateRevisionWId(input.state);
|
|
@@ -214252,6 +214359,7 @@ function runParagraphSplitCommit(input) {
|
|
|
214252
214359
|
paragraphByteStart: context.byteStart,
|
|
214253
214360
|
offset: op.offset,
|
|
214254
214361
|
coordinateSpace: op.coordinateSpace ?? "visible",
|
|
214362
|
+
knownMetadataAnchorIds: op.knownMetadataAnchorIds,
|
|
214255
214363
|
tailParaId,
|
|
214256
214364
|
allocateWId: () => {
|
|
214257
214365
|
const wId = splitAllocatedWIds[replayIndex++];
|
|
@@ -214278,6 +214386,9 @@ function runParagraphSplitCommit(input) {
|
|
|
214278
214386
|
});
|
|
214279
214387
|
if (!counterpartRewrite.ok)
|
|
214280
214388
|
return rejected8(input.txId, counterpartRewrite.reason);
|
|
214389
|
+
const metadataStorage = prepareMetadataSplitStorage(input.state, op.metadataAnchorBindings, metadataClones);
|
|
214390
|
+
if (!metadataStorage.ok)
|
|
214391
|
+
return rejected8(input.txId, "paragraph-split-point-unsupported");
|
|
214281
214392
|
const patch = counterpartRewrite.plan?.patch ?? {
|
|
214282
214393
|
kind: "replaceBytes",
|
|
214283
214394
|
order: 0,
|
|
@@ -214291,6 +214402,8 @@ function runParagraphSplitCommit(input) {
|
|
|
214291
214402
|
partUri: target.entry.partUri,
|
|
214292
214403
|
partBytes: bytes,
|
|
214293
214404
|
patches: [patch],
|
|
214405
|
+
extraPerPart: metadataStorage.perPart,
|
|
214406
|
+
extraPreconditions: metadataStorage.preconditions,
|
|
214294
214407
|
textRangeShifts: [],
|
|
214295
214408
|
createdRefs: [
|
|
214296
214409
|
{ kind: "block", nodeId: tailParaId, storyId: op.target.storyId },
|
|
@@ -271814,7 +271927,7 @@ function ensureCustomXmlPartForNamespace(context, namespace) {
|
|
|
271814
271927
|
return listCustomXmlRecords(context).find((record3) => record3.rootNamespace === namespace) ?? null;
|
|
271815
271928
|
}
|
|
271816
271929
|
function buildMetadataStorageXml(namespace, refs) {
|
|
271817
|
-
const body = refs.map((ref5) => `<ref id="${xmlEscapeAttr(ref5.id)}" encoding="json">${xmlEscapeAttr(ref5.payloadJson)}</ref>`).join("");
|
|
271930
|
+
const body = refs.map((ref5) => `<ref id="${xmlEscapeAttr(ref5.id)}" encoding="json"${ref5.physicalIds === undefined ? "" : ` sdAnchorIdsV1="${xmlEscapeAttr(ref5.physicalIds?.join(",") ?? "")}"`}>${xmlEscapeAttr(ref5.payloadJson)}</ref>`).join("");
|
|
271818
271931
|
return `<refs xmlns="${xmlEscapeAttr(namespace)}">${body}</refs>`;
|
|
271819
271932
|
}
|
|
271820
271933
|
function buildCustomXmlCreateUpdates(context, input) {
|
|
@@ -292203,8 +292316,13 @@ class V2SelectionMutationAdapter {
|
|
|
292203
292316
|
const tx = begun.tx;
|
|
292204
292317
|
const editTextStartedAt = nowMs6();
|
|
292205
292318
|
const collapsedInlineAffinity = selectionCollapsedInlineAffinity(options);
|
|
292319
|
+
const collapsedOutsideContentControl = options?.collapsedOutsideContentControl === true;
|
|
292206
292320
|
const kernelEdits = edits.map((edit, index2) => ({
|
|
292207
|
-
on:
|
|
292321
|
+
on: edit.on.startOffset === edit.on.endOffset ? {
|
|
292322
|
+
...edit.on,
|
|
292323
|
+
...collapsedInlineAffinity ? { collapsedInlineAffinity } : {},
|
|
292324
|
+
...collapsedOutsideContentControl ? { collapsedOutsideContentControl: true } : {}
|
|
292325
|
+
} : edit.on,
|
|
292208
292326
|
newText: edit.newText,
|
|
292209
292327
|
...options?.changeMode === "tracked" && (isRewrite || edits.length > 1) && !typingHistoryMetadata(options) && story.storyKind !== "textbox" ? {
|
|
292210
292328
|
rewriteGroupId: `${tx.txId}:0`,
|
|
@@ -295198,6 +295316,737 @@ var init_context = __esm(() => {
|
|
|
295198
295316
|
init_story_surface();
|
|
295199
295317
|
});
|
|
295200
295318
|
|
|
295319
|
+
// ../../../v2/document-api-v2-adapter/dist/metadata/adapter.js
|
|
295320
|
+
class V2AnchoredMetadataAdapter {
|
|
295321
|
+
constructor(context) {
|
|
295322
|
+
this.context = context;
|
|
295323
|
+
}
|
|
295324
|
+
attach(input, options) {
|
|
295325
|
+
const mutationGuard = guardDirectOnlyMutation(this.context, input, options);
|
|
295326
|
+
if (mutationGuard)
|
|
295327
|
+
return mutationGuard;
|
|
295328
|
+
const id = input.id ?? newOpaqueId("metadata");
|
|
295329
|
+
const existingRecords = listMetadataRecords(this.context);
|
|
295330
|
+
if (existingRecords.some((record3) => record3.id === id)) {
|
|
295331
|
+
throw operationError("INVALID_INPUT", `metadata id ${id} already exists.`);
|
|
295332
|
+
}
|
|
295333
|
+
const payloadJson = JSON.stringify(input.payload);
|
|
295334
|
+
if (payloadJson === undefined)
|
|
295335
|
+
throw operationError("INVALID_INPUT", "metadata payload must be JSON serializable.");
|
|
295336
|
+
const documentXml = readDocumentXml(this.context);
|
|
295337
|
+
if (findMetadataAnchor(documentXml, id)) {
|
|
295338
|
+
throw operationError("INVALID_INPUT", `metadata id ${id} already exists.`);
|
|
295339
|
+
}
|
|
295340
|
+
const resolvedSegments = input.target.kind === "text" ? resolveMultiSegmentTarget(documentXml, input.target) : resolveSingleSegmentTarget(this.context, documentXml, input.target);
|
|
295341
|
+
if ("error" in resolvedSegments)
|
|
295342
|
+
throw operationError(resolvedSegments.error, resolvedSegments.message);
|
|
295343
|
+
const knownIds = new Set(existingRecords.map((record3) => record3.id));
|
|
295344
|
+
if (hasOverlappingMetadataAnchor(documentXml, resolvedSegments.segments, knownIds)) {
|
|
295345
|
+
return failure2("INVALID_TARGET", "metadata.attach target overlaps an existing metadata anchor.");
|
|
295346
|
+
}
|
|
295347
|
+
const existingPart = ensureCustomXmlPartForNamespace(this.context, input.namespace);
|
|
295348
|
+
const allocatedPart = existingPart ? null : allocateCustomXmlPartNames(this.context);
|
|
295349
|
+
const partName = existingPart?.partName ?? allocatedPart.partName;
|
|
295350
|
+
const partUri = existingPart?.partUri ?? allocatedPart.partUri;
|
|
295351
|
+
const storageXml = existingPart?.content ?? buildMetadataStorageXml(input.namespace, []);
|
|
295352
|
+
const sdtIds = allocateMetadataSdtIds(documentXml, resolvedSegments.segments.length);
|
|
295353
|
+
const refs = readMetadataRefs(storageXml, input.namespace);
|
|
295354
|
+
refs.push({ id, payloadJson, physicalIds: sdtIds.map(String) });
|
|
295355
|
+
const nextStorageXml = buildMetadataStorageXml(input.namespace, refs);
|
|
295356
|
+
const bySegmentPosition = resolvedSegments.segments.map((segment, index) => ({ segment, sdtId: sdtIds[index] })).sort((a, b) => b.segment.para.start - a.segment.para.start);
|
|
295357
|
+
let nextDocumentXml = documentXml;
|
|
295358
|
+
for (const { segment, sdtId } of bySegmentPosition) {
|
|
295359
|
+
const wrapped = wrapTextRangeWithMetadataSdt(segment.para.xml, segment.startOffset, segment.endOffset, id, sdtId);
|
|
295360
|
+
if (!wrapped.ok)
|
|
295361
|
+
throw metadataWrapRejectError(wrapped.reason);
|
|
295362
|
+
nextDocumentXml = replaceRange2(nextDocumentXml, segment.para.start, segment.para.end, wrapped.xml);
|
|
295363
|
+
}
|
|
295364
|
+
if (!dryRunRequested(input, options)) {
|
|
295365
|
+
nextDocumentXml = ensureW15Namespace(nextDocumentXml);
|
|
295366
|
+
const updates = existingPart ? { [partUri]: encodeXml(nextStorageXml) } : buildCustomXmlCreateUpdates(this.context, {
|
|
295367
|
+
id: newGuid(),
|
|
295368
|
+
content: nextStorageXml,
|
|
295369
|
+
partUri,
|
|
295370
|
+
propsPartUri: allocatedPart.propsPartUri,
|
|
295371
|
+
relsPartUri: allocatedPart.relsPartUri
|
|
295372
|
+
});
|
|
295373
|
+
updates[DOCUMENT_PART_URI5] = encodeXml(nextDocumentXml);
|
|
295374
|
+
const committed = commitWholePartUpdates(this.context, "metadata-attach", updates, {
|
|
295375
|
+
expectedRevision: expectedRevisionFrom(input, options),
|
|
295376
|
+
storySurface: {
|
|
295377
|
+
family: "storyAnchor",
|
|
295378
|
+
targetBlockIds: resolvedSegments.segments.map((segment) => segment.blockId)
|
|
295379
|
+
}
|
|
295380
|
+
});
|
|
295381
|
+
if (!committed.ok)
|
|
295382
|
+
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
295383
|
+
}
|
|
295384
|
+
return { success: true, id, namespace: input.namespace, partName };
|
|
295385
|
+
}
|
|
295386
|
+
list(query3) {
|
|
295387
|
+
let records = listMetadataRecords(this.context);
|
|
295388
|
+
const recordCounts = new Map;
|
|
295389
|
+
for (const record3 of records)
|
|
295390
|
+
recordCounts.set(record3.id, (recordCounts.get(record3.id) ?? 0) + 1);
|
|
295391
|
+
if (query3?.namespace !== undefined)
|
|
295392
|
+
records = records.filter((record3) => record3.namespace === query3.namespace);
|
|
295393
|
+
const documentXml = readDocumentXml(this.context);
|
|
295394
|
+
if (query3?.resolvedOnly === true) {
|
|
295395
|
+
records = records.filter((record3) => recordCounts.get(record3.id) === 1 && groupMetadataAnchor(documentXml, record3.id, new Set([record3.id]), record3.physicalIds) !== null);
|
|
295396
|
+
}
|
|
295397
|
+
if (query3?.within !== undefined) {
|
|
295398
|
+
records = records.filter((record3) => {
|
|
295399
|
+
const resolved = this.resolve({ id: record3.id });
|
|
295400
|
+
return resolved ? overlaps(query3.within, resolved.target) : false;
|
|
295401
|
+
});
|
|
295402
|
+
}
|
|
295403
|
+
const page = pageSlice(records, query3);
|
|
295404
|
+
return buildDiscoveryResult({
|
|
295405
|
+
evaluatedRevision: this.context.currentPublicRevision(),
|
|
295406
|
+
total: records.length,
|
|
295407
|
+
items: page.items.map((record3) => buildDiscoveryItem(record3.id, buildResolvedHandle(`metadata:${record3.id}`, "stable", "ext:metadata"), metadataSummary(record3, documentXml))),
|
|
295408
|
+
page: { offset: page.offset, limit: page.limit, returned: page.items.length }
|
|
295409
|
+
});
|
|
295410
|
+
}
|
|
295411
|
+
get(input) {
|
|
295412
|
+
if (input.contentControlId !== undefined && input.story?.storyType !== "body")
|
|
295413
|
+
return null;
|
|
295414
|
+
const record3 = findMetadataRecord(this.context, input.id);
|
|
295415
|
+
if (record3 && input.contentControlId !== undefined && !matchesPhysicalMetadataAnchor(readDocumentXml(this.context), record3, input.contentControlId))
|
|
295416
|
+
return null;
|
|
295417
|
+
return record3 ? { ...metadataSummary(record3, readDocumentXml(this.context)), payload: record3.payload } : null;
|
|
295418
|
+
}
|
|
295419
|
+
update(input, options) {
|
|
295420
|
+
const mutationGuard = guardDirectOnlyMutation(this.context, input, options);
|
|
295421
|
+
if (mutationGuard)
|
|
295422
|
+
return mutationGuard;
|
|
295423
|
+
if (listMetadataRecords(this.context).filter((candidate2) => candidate2.id === input.id).length > 1) {
|
|
295424
|
+
return failure2("INVALID_TARGET", `metadata ${input.id} has ambiguous payload records.`);
|
|
295425
|
+
}
|
|
295426
|
+
const record3 = findMetadataRecord(this.context, input.id);
|
|
295427
|
+
if (!record3)
|
|
295428
|
+
throw operationError("TARGET_NOT_FOUND", `metadata ${input.id} not found.`);
|
|
295429
|
+
const payloadJson = JSON.stringify(input.payload);
|
|
295430
|
+
if (payloadJson === undefined)
|
|
295431
|
+
throw operationError("INVALID_INPUT", "metadata payload must be JSON serializable.");
|
|
295432
|
+
if (dryRunRequested(input, options))
|
|
295433
|
+
return { success: true, id: input.id };
|
|
295434
|
+
const records = listMetadataRecords(this.context).filter((candidate2) => candidate2.partUri === record3.partUri);
|
|
295435
|
+
const refs = records.map((candidate2) => ({
|
|
295436
|
+
id: candidate2.id,
|
|
295437
|
+
payloadJson: candidate2.id === input.id ? payloadJson : JSON.stringify(candidate2.payload),
|
|
295438
|
+
physicalIds: candidate2.physicalIds
|
|
295439
|
+
}));
|
|
295440
|
+
const committed = commitWholePartUpdates(this.context, "metadata-update", { [record3.partUri]: encodeXml(buildMetadataStorageXml(record3.namespace, refs)) }, { expectedRevision: expectedRevisionFrom(input, options) });
|
|
295441
|
+
if (!committed.ok)
|
|
295442
|
+
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
295443
|
+
return { success: true, id: input.id };
|
|
295444
|
+
}
|
|
295445
|
+
remove(input, options) {
|
|
295446
|
+
const mutationGuard = guardDirectOnlyMutation(this.context, input, options);
|
|
295447
|
+
if (mutationGuard)
|
|
295448
|
+
return mutationGuard;
|
|
295449
|
+
if (listMetadataRecords(this.context).filter((candidate2) => candidate2.id === input.id).length > 1) {
|
|
295450
|
+
return failure2("INVALID_TARGET", `metadata ${input.id} has ambiguous payload records.`);
|
|
295451
|
+
}
|
|
295452
|
+
const record3 = findMetadataRecord(this.context, input.id);
|
|
295453
|
+
if (!record3)
|
|
295454
|
+
throw operationError("TARGET_NOT_FOUND", `metadata ${input.id} not found.`);
|
|
295455
|
+
const documentXml = readDocumentXml(this.context);
|
|
295456
|
+
const knownIds = new Set(listMetadataRecords(this.context).map((candidate2) => candidate2.id));
|
|
295457
|
+
const matchingAnchors = listMetadataAnchors(documentXml, knownIds).filter((anchor) => anchor.id === input.id);
|
|
295458
|
+
const grouped = groupMetadataAnchor(documentXml, input.id, knownIds, record3.physicalIds);
|
|
295459
|
+
const malformedLegacyAnchor = record3.physicalIds === undefined && matchingAnchors.length === 1 && (matchingAnchors[0].unmatched || unwrapSdt(matchingAnchors[0].xml) === null);
|
|
295460
|
+
if ((matchingAnchors.length > 0 || record3.physicalIds !== undefined) && !grouped && !malformedLegacyAnchor) {
|
|
295461
|
+
return { success: false, failure: { code: "INVALID_TARGET", message: `metadata ${input.id} has ambiguous anchors.` } };
|
|
295462
|
+
}
|
|
295463
|
+
if (dryRunRequested(input, options))
|
|
295464
|
+
return { success: true, id: input.id };
|
|
295465
|
+
const updates = {};
|
|
295466
|
+
if (grouped) {
|
|
295467
|
+
const bySegmentPosition = [...grouped.segments].sort((a, b) => b.start - a.start);
|
|
295468
|
+
let nextDocumentXml = documentXml;
|
|
295469
|
+
for (const anchor of bySegmentPosition) {
|
|
295470
|
+
if (anchor.unmatched)
|
|
295471
|
+
continue;
|
|
295472
|
+
const unwrapped = unwrapSdt(anchor.xml);
|
|
295473
|
+
if (unwrapped === null)
|
|
295474
|
+
continue;
|
|
295475
|
+
nextDocumentXml = replaceRange2(nextDocumentXml, anchor.start, anchor.end, unwrapped);
|
|
295476
|
+
}
|
|
295477
|
+
if (nextDocumentXml !== documentXml)
|
|
295478
|
+
updates[DOCUMENT_PART_URI5] = encodeXml(nextDocumentXml);
|
|
295479
|
+
}
|
|
295480
|
+
const remaining = listMetadataRecords(this.context).filter((candidate2) => candidate2.partUri === record3.partUri && candidate2.id !== input.id).map((candidate2) => ({ id: candidate2.id, payloadJson: JSON.stringify(candidate2.payload), physicalIds: candidate2.physicalIds }));
|
|
295481
|
+
const targetBlockIds2 = grouped ? grouped.segments.map((anchor) => anchor.blockId) : undefined;
|
|
295482
|
+
if (remaining.length > 0) {
|
|
295483
|
+
updates[record3.partUri] = encodeXml(buildMetadataStorageXml(record3.namespace, remaining));
|
|
295484
|
+
const committed = commitWholePartUpdates(this.context, "metadata-remove", updates, {
|
|
295485
|
+
expectedRevision: expectedRevisionFrom(input, options),
|
|
295486
|
+
...targetBlockIds2 ? { storySurface: { family: "storyAnchor", targetBlockIds: targetBlockIds2 } } : {}
|
|
295487
|
+
});
|
|
295488
|
+
if (!committed.ok)
|
|
295489
|
+
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
295490
|
+
} else {
|
|
295491
|
+
Object.assign(updates, buildCustomXmlRemoveUpdates(this.context, record3));
|
|
295492
|
+
const committed = commitWholePartUpdates(this.context, "metadata-remove", updates, {
|
|
295493
|
+
expectedRevision: expectedRevisionFrom(input, options),
|
|
295494
|
+
...targetBlockIds2 ? { storySurface: { family: "storyAnchor", targetBlockIds: targetBlockIds2 } } : {}
|
|
295495
|
+
});
|
|
295496
|
+
if (!committed.ok)
|
|
295497
|
+
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
295498
|
+
}
|
|
295499
|
+
return { success: true, id: input.id };
|
|
295500
|
+
}
|
|
295501
|
+
resolve(input) {
|
|
295502
|
+
if (input.contentControlId !== undefined && input.story?.storyType !== "body")
|
|
295503
|
+
return null;
|
|
295504
|
+
const record3 = findMetadataRecord(this.context, input.id);
|
|
295505
|
+
if (!record3)
|
|
295506
|
+
return null;
|
|
295507
|
+
const knownIds = new Set(listMetadataRecords(this.context).map((candidate2) => candidate2.id));
|
|
295508
|
+
const grouped = groupMetadataAnchor(readDocumentXml(this.context), input.id, knownIds, record3.physicalIds);
|
|
295509
|
+
if (!grouped)
|
|
295510
|
+
return null;
|
|
295511
|
+
if (input.contentControlId !== undefined && !grouped.segments.some((anchor) => metadataAnchorPhysicalId(anchor) === input.contentControlId))
|
|
295512
|
+
return null;
|
|
295513
|
+
return { id: input.id, target: grouped.target };
|
|
295514
|
+
}
|
|
295515
|
+
}
|
|
295516
|
+
function matchesPhysicalMetadataAnchor(documentXml, record3, contentControlId) {
|
|
295517
|
+
const grouped = groupMetadataAnchor(documentXml, record3.id, new Set([record3.id]), record3.physicalIds);
|
|
295518
|
+
return grouped !== null && grouped.segments.some((anchor) => metadataAnchorPhysicalId(anchor) === contentControlId);
|
|
295519
|
+
}
|
|
295520
|
+
function listMetadataSplitBindings(context, paragraphXml) {
|
|
295521
|
+
const candidateIds = new Set([...paragraphXml.matchAll(/<w:tag\b[^>]*\/>/g)].map((match) => attrValue(match[0], "val")).filter((id) => id !== null));
|
|
295522
|
+
if (candidateIds.size === 0)
|
|
295523
|
+
return [];
|
|
295524
|
+
const records = listMetadataRecords(context);
|
|
295525
|
+
const counts = new Map;
|
|
295526
|
+
for (const record3 of records)
|
|
295527
|
+
counts.set(record3.id, (counts.get(record3.id) ?? 0) + 1);
|
|
295528
|
+
const documentXml = readDocumentXml(context);
|
|
295529
|
+
return records.filter((record3) => candidateIds.has(record3.id) && counts.get(record3.id) === 1 && groupMetadataAnchor(documentXml, record3.id, new Set([record3.id]), record3.physicalIds) !== null).map((record3) => ({
|
|
295530
|
+
id: record3.id,
|
|
295531
|
+
partUri: record3.partUri,
|
|
295532
|
+
...record3.physicalIds ? { physicalIds: record3.physicalIds } : {}
|
|
295533
|
+
}));
|
|
295534
|
+
}
|
|
295535
|
+
function listMetadataRecords(context) {
|
|
295536
|
+
const out = [];
|
|
295537
|
+
for (const part of listCustomXmlRecords(context)) {
|
|
295538
|
+
if (!part.rootNamespace || !/^<refs\b/.test(part.content.replace(/^<\?xml[^>]*>/, "").trim()))
|
|
295539
|
+
continue;
|
|
295540
|
+
for (const ref5 of readMetadataRefs(part.content, part.rootNamespace)) {
|
|
295541
|
+
let payload = null;
|
|
295542
|
+
try {
|
|
295543
|
+
payload = JSON.parse(ref5.payloadJson);
|
|
295544
|
+
} catch {
|
|
295545
|
+
payload = null;
|
|
295546
|
+
}
|
|
295547
|
+
out.push({
|
|
295548
|
+
id: ref5.id,
|
|
295549
|
+
namespace: part.rootNamespace,
|
|
295550
|
+
partName: part.partName,
|
|
295551
|
+
partUri: part.partUri,
|
|
295552
|
+
...part.propsPartUri ? { propsPartUri: part.propsPartUri } : {},
|
|
295553
|
+
payload,
|
|
295554
|
+
...ref5.physicalIds !== undefined ? { physicalIds: ref5.physicalIds } : {}
|
|
295555
|
+
});
|
|
295556
|
+
}
|
|
295557
|
+
}
|
|
295558
|
+
return out;
|
|
295559
|
+
}
|
|
295560
|
+
function findMetadataRecord(context, id) {
|
|
295561
|
+
const matches = listMetadataRecords(context).filter((record3) => record3.id === id);
|
|
295562
|
+
return matches.length === 1 ? matches[0] : null;
|
|
295563
|
+
}
|
|
295564
|
+
function metadataSummary(record3, documentXml) {
|
|
295565
|
+
return {
|
|
295566
|
+
id: record3.id,
|
|
295567
|
+
namespace: record3.namespace,
|
|
295568
|
+
partName: record3.partName,
|
|
295569
|
+
anchorStatus: groupMetadataAnchor(documentXml, record3.id, new Set([record3.id]), record3.physicalIds) ? "resolved" : "orphan"
|
|
295570
|
+
};
|
|
295571
|
+
}
|
|
295572
|
+
function readMetadataRefs(xml, _namespace) {
|
|
295573
|
+
const refs = [];
|
|
295574
|
+
const re = /(<ref\b[^>]*\bid="([^"]*)"[^>]*>)([\s\S]*?)<\/ref>/g;
|
|
295575
|
+
for (let match = re.exec(xml);match; match = re.exec(xml)) {
|
|
295576
|
+
const bindingAttributes = [...match[1].matchAll(/\bsdAnchorIdsV1\s*=\s*(['"])(.*?)\1/g)];
|
|
295577
|
+
const ids = bindingAttributes.length === 0 && !/\bsdAnchorIdsV1\b/.test(match[1]) ? undefined : bindingAttributes.length === 1 ? decodeXmlEntities(bindingAttributes[0][2]).split(",") : [];
|
|
295578
|
+
const validIds = ids && ids.length > 0 && ids.every((value2) => /^(?:0|[1-9]\d*)$/.test(value2)) && new Set(ids).size === ids.length;
|
|
295579
|
+
refs.push({
|
|
295580
|
+
id: decodeXmlEntities(match[2]),
|
|
295581
|
+
payloadJson: decodeXmlEntities(match[3]),
|
|
295582
|
+
...ids !== undefined ? { physicalIds: validIds ? ids : null } : {}
|
|
295583
|
+
});
|
|
295584
|
+
}
|
|
295585
|
+
return refs;
|
|
295586
|
+
}
|
|
295587
|
+
function findMetadataAnchor(documentXml, id) {
|
|
295588
|
+
return listMetadataAnchors(documentXml, new Set([id])).find((anchor) => anchor.id === id) ?? null;
|
|
295589
|
+
}
|
|
295590
|
+
function listMetadataAnchors(documentXml, knownIds) {
|
|
295591
|
+
const anchors = [];
|
|
295592
|
+
for (const sdt of listSdtRanges(documentXml)) {
|
|
295593
|
+
const pr = ownSdtPr(sdt.xml);
|
|
295594
|
+
const tag = attrValue(/<w:tag\b[^>]*\/>/.exec(pr)?.[0] ?? "", "val");
|
|
295595
|
+
if (!tag || !isMetadataAnchorPr(pr, tag, knownIds))
|
|
295596
|
+
continue;
|
|
295597
|
+
const anchor = materializeMetadataAnchor(documentXml, sdt, tag);
|
|
295598
|
+
if (anchor)
|
|
295599
|
+
anchors.push(anchor);
|
|
295600
|
+
}
|
|
295601
|
+
return anchors.sort((left, right) => left.start - right.start);
|
|
295602
|
+
}
|
|
295603
|
+
function ownSdtPr(sdtXml) {
|
|
295604
|
+
const openTag = /<w:sdt\b[^>]*>/.exec(sdtXml);
|
|
295605
|
+
if (!openTag)
|
|
295606
|
+
return "";
|
|
295607
|
+
const headStart = openTag.index + openTag[0].length;
|
|
295608
|
+
const contentOrNested = /<w:sdtContent\b[^>]*>|<w:sdt\b[^>]*>/.exec(sdtXml.slice(headStart));
|
|
295609
|
+
const head = contentOrNested ? sdtXml.slice(headStart, headStart + contentOrNested.index) : sdtXml.slice(headStart);
|
|
295610
|
+
return /<w:sdtPr\b[^>]*>[\s\S]*?<\/w:sdtPr>/.exec(head)?.[0] ?? "";
|
|
295611
|
+
}
|
|
295612
|
+
function listSdtRanges(documentXml) {
|
|
295613
|
+
const ranges = [];
|
|
295614
|
+
const stack = [];
|
|
295615
|
+
const tokenRe = /<w:sdt\b[^>]*>|<\/w:sdt>/g;
|
|
295616
|
+
for (let match = tokenRe.exec(documentXml);match; match = tokenRe.exec(documentXml)) {
|
|
295617
|
+
if (match[0].startsWith("</")) {
|
|
295618
|
+
const start = stack.pop();
|
|
295619
|
+
if (start === undefined)
|
|
295620
|
+
continue;
|
|
295621
|
+
const end = tokenRe.lastIndex;
|
|
295622
|
+
ranges.push({ start, end, xml: documentXml.slice(start, end) });
|
|
295623
|
+
} else if (/\/\s*>$/.test(match[0])) {
|
|
295624
|
+
ranges.push({ start: match.index, end: tokenRe.lastIndex, xml: match[0] });
|
|
295625
|
+
} else {
|
|
295626
|
+
stack.push(match.index);
|
|
295627
|
+
}
|
|
295628
|
+
}
|
|
295629
|
+
for (const start of stack) {
|
|
295630
|
+
const end = unmatchedSdtExtent(documentXml, start);
|
|
295631
|
+
ranges.push({ start, end, xml: documentXml.slice(start, end), unmatched: true });
|
|
295632
|
+
}
|
|
295633
|
+
return ranges.sort((left, right) => left.start - right.start);
|
|
295634
|
+
}
|
|
295635
|
+
function unmatchedSdtExtent(documentXml, start) {
|
|
295636
|
+
const paraClose = documentXml.indexOf("</w:p>", start);
|
|
295637
|
+
return paraClose === -1 ? documentXml.length : paraClose;
|
|
295638
|
+
}
|
|
295639
|
+
function isMetadataAnchorPr(pr, tag, knownIds) {
|
|
295640
|
+
const alias = attrValue(/<w:alias\b[^>]*\/>/.exec(pr)?.[0] ?? "", "val");
|
|
295641
|
+
if (alias !== null && alias !== METADATA_ANCHOR_ALIAS)
|
|
295642
|
+
return false;
|
|
295643
|
+
const hasHiddenAppearance = attrValue(/<w15:appearance\b[^>]*\/>/.exec(pr)?.[0] ?? "", "val") === "hidden";
|
|
295644
|
+
const hasPlainTextPr = /<w:text\b/.test(pr);
|
|
295645
|
+
return knownIds.has(tag) && hasHiddenAppearance && hasPlainTextPr;
|
|
295646
|
+
}
|
|
295647
|
+
function materializeMetadataAnchor(documentXml, sdt, id) {
|
|
295648
|
+
const para = findParagraphContaining2(documentXml, sdt.start);
|
|
295649
|
+
if (!para)
|
|
295650
|
+
return null;
|
|
295651
|
+
const startOffset = extractVisibleTextFromXml2(para.xml.slice(0, sdt.start - para.start)).length;
|
|
295652
|
+
const length = extractVisibleTextFromXml2(unwrapSdt(sdt.xml) ?? sdt.xml).length;
|
|
295653
|
+
const endOffset = startOffset + length;
|
|
295654
|
+
return {
|
|
295655
|
+
id,
|
|
295656
|
+
start: sdt.start,
|
|
295657
|
+
end: sdt.end,
|
|
295658
|
+
xml: sdt.xml,
|
|
295659
|
+
blockId: para.blockId,
|
|
295660
|
+
startOffset,
|
|
295661
|
+
endOffset,
|
|
295662
|
+
unmatched: sdt.unmatched === true,
|
|
295663
|
+
target: {
|
|
295664
|
+
kind: "selection",
|
|
295665
|
+
start: { kind: "text", blockId: para.blockId, offset: startOffset, story: bodyStoryLocator2() },
|
|
295666
|
+
end: { kind: "text", blockId: para.blockId, offset: endOffset, story: bodyStoryLocator2() }
|
|
295667
|
+
}
|
|
295668
|
+
};
|
|
295669
|
+
}
|
|
295670
|
+
function groupMetadataAnchor(documentXml, id, knownIds, physicalIds) {
|
|
295671
|
+
const matches = listMetadataAnchors(documentXml, knownIds).filter((anchor) => anchor.id === id);
|
|
295672
|
+
if (matches.length === 0)
|
|
295673
|
+
return null;
|
|
295674
|
+
if (physicalIds === null)
|
|
295675
|
+
return null;
|
|
295676
|
+
if (physicalIds === undefined && matches.length !== 1)
|
|
295677
|
+
return null;
|
|
295678
|
+
if (physicalIds !== undefined && (matches.length !== physicalIds.length || matches.some((anchor) => {
|
|
295679
|
+
const physicalId = metadataAnchorPhysicalId(anchor);
|
|
295680
|
+
return physicalId === null || !physicalIds.includes(physicalId);
|
|
295681
|
+
}) || new Set(matches.map(metadataAnchorPhysicalId)).size !== matches.length))
|
|
295682
|
+
return null;
|
|
295683
|
+
const controlIdCounts = countBodyControlIds(documentXml);
|
|
295684
|
+
if (!controlIdCounts)
|
|
295685
|
+
return null;
|
|
295686
|
+
if (matches.some((anchor) => controlIdCounts.get(metadataAnchorPhysicalId(anchor) ?? "") !== 1))
|
|
295687
|
+
return null;
|
|
295688
|
+
const kept = contiguousAnchorPrefix(documentXml, matches);
|
|
295689
|
+
if (kept.length !== matches.length)
|
|
295690
|
+
return null;
|
|
295691
|
+
if (kept.some((anchor) => anchor.unmatched || unwrapSdt(anchor.xml) === null))
|
|
295692
|
+
return null;
|
|
295693
|
+
if (kept.length === 1)
|
|
295694
|
+
return { id, segments: kept, target: kept[0].target };
|
|
295695
|
+
const textSegments = [];
|
|
295696
|
+
for (const anchor of kept) {
|
|
295697
|
+
const previous = textSegments.at(-1);
|
|
295698
|
+
if (previous?.blockId === anchor.blockId && previous.range.end === anchor.startOffset) {
|
|
295699
|
+
previous.range.end = anchor.endOffset;
|
|
295700
|
+
} else {
|
|
295701
|
+
textSegments.push({ blockId: anchor.blockId, range: { start: anchor.startOffset, end: anchor.endOffset } });
|
|
295702
|
+
}
|
|
295703
|
+
}
|
|
295704
|
+
if (textSegments.length === 1) {
|
|
295705
|
+
const range = textSegments[0];
|
|
295706
|
+
return {
|
|
295707
|
+
id,
|
|
295708
|
+
segments: kept,
|
|
295709
|
+
target: {
|
|
295710
|
+
kind: "selection",
|
|
295711
|
+
start: { kind: "text", blockId: range.blockId, offset: range.range.start, story: bodyStoryLocator2() },
|
|
295712
|
+
end: { kind: "text", blockId: range.blockId, offset: range.range.end, story: bodyStoryLocator2() }
|
|
295713
|
+
}
|
|
295714
|
+
};
|
|
295715
|
+
}
|
|
295716
|
+
return {
|
|
295717
|
+
id,
|
|
295718
|
+
segments: kept,
|
|
295719
|
+
target: { kind: "text", segments: [textSegments[0], ...textSegments.slice(1)] }
|
|
295720
|
+
};
|
|
295721
|
+
}
|
|
295722
|
+
function metadataAnchorPhysicalId(anchor) {
|
|
295723
|
+
const idTag = /<w:id\b[^>]*\/>/.exec(ownSdtPr(anchor.xml))?.[0];
|
|
295724
|
+
const value2 = idTag && /\bw:val\s*=\s*(['"])(.*?)\1/.exec(idTag)?.[2];
|
|
295725
|
+
return value2 === undefined ? null : decodeXmlEntities(value2);
|
|
295726
|
+
}
|
|
295727
|
+
function countBodyControlIds(documentXml) {
|
|
295728
|
+
const counts = new Map;
|
|
295729
|
+
const stack = [];
|
|
295730
|
+
const parser = createXmlSaxParser({ namespaceAware: true });
|
|
295731
|
+
let parseFailed = false;
|
|
295732
|
+
parser.on("error", () => {
|
|
295733
|
+
parseFailed = true;
|
|
295734
|
+
});
|
|
295735
|
+
parser.on("opentag", (tag) => {
|
|
295736
|
+
const parent = stack.at(-1);
|
|
295737
|
+
const owner = stack.at(-2);
|
|
295738
|
+
if (tag.namespaceUri === WORD_NAMESPACE5 && tag.localName === "id" && parent?.namespaceUri === WORD_NAMESPACE5 && parent.localName === "sdtPr" && owner?.namespaceUri === WORD_NAMESPACE5 && owner.localName === "sdt") {
|
|
295739
|
+
const value2 = tag.attributes.find((attribute) => attribute.namespaceUri === WORD_NAMESPACE5 && attribute.localName === "val")?.value;
|
|
295740
|
+
if (value2 !== undefined)
|
|
295741
|
+
counts.set(value2, (counts.get(value2) ?? 0) + 1);
|
|
295742
|
+
}
|
|
295743
|
+
stack.push(tag);
|
|
295744
|
+
});
|
|
295745
|
+
parser.on("closetag", () => {
|
|
295746
|
+
stack.pop();
|
|
295747
|
+
});
|
|
295748
|
+
try {
|
|
295749
|
+
parser.write(documentXml).close();
|
|
295750
|
+
} catch {
|
|
295751
|
+
return null;
|
|
295752
|
+
}
|
|
295753
|
+
return parseFailed ? null : counts;
|
|
295754
|
+
}
|
|
295755
|
+
function contiguousAnchorPrefix(documentXml, matches) {
|
|
295756
|
+
if (matches.length <= 1)
|
|
295757
|
+
return [...matches];
|
|
295758
|
+
const map3 = buildStructuralBoundaryMap(TEXT_ENCODER.encode(documentXml));
|
|
295759
|
+
const first = map3.byBlockId(matches[0].blockId);
|
|
295760
|
+
if (!first)
|
|
295761
|
+
return [matches[0]];
|
|
295762
|
+
const kept = [matches[0]];
|
|
295763
|
+
let prev = first;
|
|
295764
|
+
for (let i2 = 1;i2 < matches.length; i2 += 1) {
|
|
295765
|
+
const context = map3.byBlockId(matches[i2].blockId);
|
|
295766
|
+
if (!context)
|
|
295767
|
+
break;
|
|
295768
|
+
const sameParagraph = context.ordinal === prev.ordinal;
|
|
295769
|
+
if (sameParagraph) {
|
|
295770
|
+
const previousAnchor = kept.at(-1);
|
|
295771
|
+
if (context.blockId !== previousAnchor.blockId || matches[i2].startOffset !== previousAnchor.endOffset || !isMetadataCarrierGap(documentXml.slice(previousAnchor.end, matches[i2].start)))
|
|
295772
|
+
break;
|
|
295773
|
+
} else if (context.ordinal !== prev.ordinal + 1)
|
|
295774
|
+
break;
|
|
295775
|
+
if (!sameTableCellPath(context.tableCellPath, first.tableCellPath))
|
|
295776
|
+
break;
|
|
295777
|
+
if (!sameOrdinalPath2(context.blockSdtPath, first.blockSdtPath))
|
|
295778
|
+
break;
|
|
295779
|
+
if (!sameOrdinalPath2(context.blockCustomXmlPath, first.blockCustomXmlPath))
|
|
295780
|
+
break;
|
|
295781
|
+
if (context.sectionIndex !== first.sectionIndex)
|
|
295782
|
+
break;
|
|
295783
|
+
if (prev.carriesSectionBreak)
|
|
295784
|
+
break;
|
|
295785
|
+
kept.push(matches[i2]);
|
|
295786
|
+
prev = context;
|
|
295787
|
+
}
|
|
295788
|
+
return kept;
|
|
295789
|
+
}
|
|
295790
|
+
function isMetadataCarrierGap(xml) {
|
|
295791
|
+
return /^(?:\s*<w:proofErr\s+w:type="(?:spellStart|spellEnd|gramStart|gramEnd)"\s*\/>)*\s*$/.test(xml);
|
|
295792
|
+
}
|
|
295793
|
+
function sameOrdinalPath2(left, right) {
|
|
295794
|
+
return left.length === right.length && left.every((value2, index) => value2 === right[index]);
|
|
295795
|
+
}
|
|
295796
|
+
function resolveSingleSegmentTarget(context, documentXml, target) {
|
|
295797
|
+
const resolved = resolveBodySelectionTarget(context, target);
|
|
295798
|
+
if ("error" in resolved)
|
|
295799
|
+
return resolved;
|
|
295800
|
+
if (resolved.startBlockId !== resolved.endBlockId) {
|
|
295801
|
+
return { error: "INVALID_TARGET", message: "metadata.attach requires a same-paragraph text selection." };
|
|
295802
|
+
}
|
|
295803
|
+
if (resolved.startOffset >= resolved.endOffset) {
|
|
295804
|
+
return { error: "INVALID_TARGET", message: "metadata.attach requires a non-empty text range." };
|
|
295805
|
+
}
|
|
295806
|
+
const para = findParagraphById2(documentXml, resolved.startBlockId);
|
|
295807
|
+
if (!para)
|
|
295808
|
+
return { error: "TARGET_NOT_FOUND", message: `paragraph ${resolved.startBlockId} not found.` };
|
|
295809
|
+
return {
|
|
295810
|
+
segments: [{ blockId: para.blockId, startOffset: resolved.startOffset, endOffset: resolved.endOffset, para }]
|
|
295811
|
+
};
|
|
295812
|
+
}
|
|
295813
|
+
function resolveMultiSegmentTarget(documentXml, target) {
|
|
295814
|
+
if (target.story !== undefined && target.story.storyType !== "body") {
|
|
295815
|
+
return {
|
|
295816
|
+
error: "TARGET_NOT_FOUND",
|
|
295817
|
+
message: "metadata.attach resolves paragraphs against the main document body only."
|
|
295818
|
+
};
|
|
295819
|
+
}
|
|
295820
|
+
if (target.coordinateSpace === "tracked") {
|
|
295821
|
+
return {
|
|
295822
|
+
error: "INVALID_TARGET",
|
|
295823
|
+
message: "metadata.attach does not support a tracked-coordinate-space TextTarget."
|
|
295824
|
+
};
|
|
295825
|
+
}
|
|
295826
|
+
const segments = [];
|
|
295827
|
+
for (const segment of target.segments) {
|
|
295828
|
+
if (segment.range.start >= segment.range.end) {
|
|
295829
|
+
return {
|
|
295830
|
+
error: "INVALID_TARGET",
|
|
295831
|
+
message: "metadata.attach requires a non-empty text range in every TextTarget segment."
|
|
295832
|
+
};
|
|
295833
|
+
}
|
|
295834
|
+
const para = findParagraphById2(documentXml, segment.blockId);
|
|
295835
|
+
if (!para)
|
|
295836
|
+
return { error: "TARGET_NOT_FOUND", message: `paragraph ${segment.blockId} not found.` };
|
|
295837
|
+
segments.push({ blockId: segment.blockId, startOffset: segment.range.start, endOffset: segment.range.end, para });
|
|
295838
|
+
}
|
|
295839
|
+
const boundaryError = validateContiguousStructuralRun(documentXml, segments.map((segment) => segment.blockId));
|
|
295840
|
+
if (boundaryError)
|
|
295841
|
+
return boundaryError;
|
|
295842
|
+
return { segments };
|
|
295843
|
+
}
|
|
295844
|
+
function validateContiguousStructuralRun(documentXml, blockIds) {
|
|
295845
|
+
if (blockIds.length <= 1)
|
|
295846
|
+
return null;
|
|
295847
|
+
const map3 = buildStructuralBoundaryMap(TEXT_ENCODER.encode(documentXml));
|
|
295848
|
+
const contexts = blockIds.map((blockId) => map3.byBlockId(blockId));
|
|
295849
|
+
const first = contexts[0];
|
|
295850
|
+
if (!first) {
|
|
295851
|
+
return { error: "INVALID_TARGET", message: `paragraph "${blockIds[0]}" is not visible to the structural map.` };
|
|
295852
|
+
}
|
|
295853
|
+
for (let i2 = 1;i2 < contexts.length; i2 += 1) {
|
|
295854
|
+
const context = contexts[i2];
|
|
295855
|
+
const prev = contexts[i2 - 1];
|
|
295856
|
+
if (!context) {
|
|
295857
|
+
return { error: "INVALID_TARGET", message: `paragraph "${blockIds[i2]}" is not visible to the structural map.` };
|
|
295858
|
+
}
|
|
295859
|
+
if (context.ordinal !== prev.ordinal + 1) {
|
|
295860
|
+
return {
|
|
295861
|
+
error: "INVALID_TARGET",
|
|
295862
|
+
message: "metadata.attach TextTarget segments must be contiguous paragraphs in document order."
|
|
295863
|
+
};
|
|
295864
|
+
}
|
|
295865
|
+
if (!sameTableCellPath(context.tableCellPath, first.tableCellPath)) {
|
|
295866
|
+
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a table-cell boundary." };
|
|
295867
|
+
}
|
|
295868
|
+
if (!sameOrdinalPath2(context.blockSdtPath, first.blockSdtPath)) {
|
|
295869
|
+
return {
|
|
295870
|
+
error: "INVALID_TARGET",
|
|
295871
|
+
message: "metadata.attach TextTarget cannot cross a block content-control boundary."
|
|
295872
|
+
};
|
|
295873
|
+
}
|
|
295874
|
+
if (!sameOrdinalPath2(context.blockCustomXmlPath, first.blockCustomXmlPath)) {
|
|
295875
|
+
return {
|
|
295876
|
+
error: "INVALID_TARGET",
|
|
295877
|
+
message: "metadata.attach TextTarget cannot cross a block custom-XML boundary."
|
|
295878
|
+
};
|
|
295879
|
+
}
|
|
295880
|
+
if (context.sectionIndex !== first.sectionIndex) {
|
|
295881
|
+
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a section boundary." };
|
|
295882
|
+
}
|
|
295883
|
+
if (prev.carriesSectionBreak) {
|
|
295884
|
+
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a section boundary." };
|
|
295885
|
+
}
|
|
295886
|
+
}
|
|
295887
|
+
if (contexts[contexts.length - 1].carriesSectionBreak) {
|
|
295888
|
+
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a section boundary." };
|
|
295889
|
+
}
|
|
295890
|
+
return null;
|
|
295891
|
+
}
|
|
295892
|
+
function hasOverlappingMetadataAnchor(documentXml, segments, knownIds) {
|
|
295893
|
+
const anchors = listMetadataAnchors(documentXml, knownIds);
|
|
295894
|
+
return segments.some((segment) => anchors.some((anchor) => anchor.blockId === segment.blockId && rangesStrictlyOverlap(segment.startOffset, segment.endOffset, anchor.startOffset, anchor.endOffset)));
|
|
295895
|
+
}
|
|
295896
|
+
function rangesStrictlyOverlap(leftStart, leftEnd, rightStart, rightEnd) {
|
|
295897
|
+
return leftStart < rightEnd && rightStart < leftEnd;
|
|
295898
|
+
}
|
|
295899
|
+
function bodyStoryLocator2() {
|
|
295900
|
+
return { kind: "story", storyType: "body" };
|
|
295901
|
+
}
|
|
295902
|
+
function wrapTextRangeWithMetadataSdt(paragraphXml, start, end, id, sdtId) {
|
|
295903
|
+
return wrapRangeWithMarkupInParagraphXml({
|
|
295904
|
+
paragraphXml,
|
|
295905
|
+
rangeStart: start,
|
|
295906
|
+
rangeEnd: end,
|
|
295907
|
+
open: metadataSdtOpenXml(id, sdtId),
|
|
295908
|
+
close: "</w:sdtContent></w:sdt>"
|
|
295909
|
+
});
|
|
295910
|
+
}
|
|
295911
|
+
function metadataSdtOpenXml(id, sdtId) {
|
|
295912
|
+
return [
|
|
295913
|
+
`<w:sdt xmlns:w15="${W15_NS}"><w:sdtPr>`,
|
|
295914
|
+
`<w:id w:val="${sdtId}"/>`,
|
|
295915
|
+
`<w:alias w:val="${xmlEscapeAttr(METADATA_ANCHOR_ALIAS)}"/>`,
|
|
295916
|
+
`<w:tag w:val="${xmlEscapeAttr(id)}"/>`,
|
|
295917
|
+
'<w15:appearance w15:val="hidden"/>',
|
|
295918
|
+
"<w:text/>",
|
|
295919
|
+
"</w:sdtPr><w:sdtContent>"
|
|
295920
|
+
].join("");
|
|
295921
|
+
}
|
|
295922
|
+
function metadataWrapRejectError(reason) {
|
|
295923
|
+
if (reason === "invalid-range") {
|
|
295924
|
+
return operationError("TARGET_NOT_FOUND", "metadata target text range not found.");
|
|
295925
|
+
}
|
|
295926
|
+
return operationError("INVALID_TARGET", `metadata.attach target overlaps unsupported content (${reason}).`);
|
|
295927
|
+
}
|
|
295928
|
+
function allocateMetadataSdtIds(documentXml, count) {
|
|
295929
|
+
const used = new Set;
|
|
295930
|
+
const idRe = /<w:id\b[^>]*(?:\/>|>)/g;
|
|
295931
|
+
for (let match = idRe.exec(documentXml);match; match = idRe.exec(documentXml)) {
|
|
295932
|
+
const value2 = Number.parseInt(attrValue(match[0], "val") ?? "", 10);
|
|
295933
|
+
if (Number.isInteger(value2))
|
|
295934
|
+
used.add(value2);
|
|
295935
|
+
}
|
|
295936
|
+
const ids = [];
|
|
295937
|
+
for (let i2 = 0;i2 < count; i2 += 1) {
|
|
295938
|
+
let candidate2 = Math.max(1, Math.floor(Math.random() * MAX_SDT_ID));
|
|
295939
|
+
while (used.has(candidate2))
|
|
295940
|
+
candidate2 = candidate2 >= MAX_SDT_ID ? 1 : candidate2 + 1;
|
|
295941
|
+
used.add(candidate2);
|
|
295942
|
+
ids.push(candidate2);
|
|
295943
|
+
}
|
|
295944
|
+
return ids;
|
|
295945
|
+
}
|
|
295946
|
+
function ensureW15Namespace(documentXml) {
|
|
295947
|
+
return documentXml.replace(/<w:document\b[^>]*>/, (openTag) => {
|
|
295948
|
+
let next = openTag;
|
|
295949
|
+
if (!/\sxmlns:w15\s*=/.test(next))
|
|
295950
|
+
next = next.replace(/>$/, ` xmlns:w15="${W15_NS}">`);
|
|
295951
|
+
const ignorable = /\smc:Ignorable\s*=\s*(["'])([^"']*)\1/.exec(next);
|
|
295952
|
+
if (!ignorable)
|
|
295953
|
+
return next;
|
|
295954
|
+
const prefixes = ignorable[2].split(/\s+/).filter(Boolean);
|
|
295955
|
+
if (prefixes.includes("w15"))
|
|
295956
|
+
return next;
|
|
295957
|
+
return next.replace(ignorable[0], ` mc:Ignorable="${[...prefixes, "w15"].join(" ")}"`);
|
|
295958
|
+
});
|
|
295959
|
+
}
|
|
295960
|
+
function readDocumentXml(context) {
|
|
295961
|
+
const xml = readPartXml(context, DOCUMENT_PART_URI5);
|
|
295962
|
+
if (!xml)
|
|
295963
|
+
throw operationError("PRECONDITION_FAILED", "document.xml bytes are unavailable.");
|
|
295964
|
+
return xml;
|
|
295965
|
+
}
|
|
295966
|
+
function findParagraphById2(documentXml, blockId) {
|
|
295967
|
+
const paraRe = /<w:p\b[^>]*>[\s\S]*?<\/w:p>/g;
|
|
295968
|
+
for (let match = paraRe.exec(documentXml);match; match = paraRe.exec(documentXml)) {
|
|
295969
|
+
if (match[0].includes(`w14:paraId="${blockId}"`))
|
|
295970
|
+
return { start: match.index, end: paraRe.lastIndex, xml: match[0], blockId };
|
|
295971
|
+
}
|
|
295972
|
+
return null;
|
|
295973
|
+
}
|
|
295974
|
+
function findParagraphContaining2(documentXml, index) {
|
|
295975
|
+
const paraRe = /<w:p\b[^>]*>[\s\S]*?<\/w:p>/g;
|
|
295976
|
+
for (let match = paraRe.exec(documentXml);match; match = paraRe.exec(documentXml)) {
|
|
295977
|
+
if (match.index <= index && paraRe.lastIndex >= index) {
|
|
295978
|
+
const open = /^<w:p\b[^>]*>/.exec(match[0])?.[0] ?? "";
|
|
295979
|
+
return {
|
|
295980
|
+
start: match.index,
|
|
295981
|
+
end: paraRe.lastIndex,
|
|
295982
|
+
xml: match[0],
|
|
295983
|
+
blockId: attrValue(open, "paraId") ?? "unknown"
|
|
295984
|
+
};
|
|
295985
|
+
}
|
|
295986
|
+
}
|
|
295987
|
+
return null;
|
|
295988
|
+
}
|
|
295989
|
+
function unwrapSdt(sdtXml) {
|
|
295990
|
+
const open = /<w:sdtContent\b[^>]*>/.exec(sdtXml);
|
|
295991
|
+
if (!open)
|
|
295992
|
+
return null;
|
|
295993
|
+
if (/\/\s*>$/.test(open[0]))
|
|
295994
|
+
return "";
|
|
295995
|
+
const contentStart = open.index + open[0].length;
|
|
295996
|
+
const tokenRe = /<w:sdtContent\b[^>]*>|<\/w:sdtContent>/g;
|
|
295997
|
+
tokenRe.lastIndex = contentStart;
|
|
295998
|
+
let depth = 0;
|
|
295999
|
+
for (let match = tokenRe.exec(sdtXml);match; match = tokenRe.exec(sdtXml)) {
|
|
296000
|
+
if (match[0].startsWith("</")) {
|
|
296001
|
+
if (depth === 0)
|
|
296002
|
+
return sdtXml.slice(contentStart, match.index);
|
|
296003
|
+
depth -= 1;
|
|
296004
|
+
} else if (!/\/\s*>$/.test(match[0])) {
|
|
296005
|
+
depth += 1;
|
|
296006
|
+
}
|
|
296007
|
+
}
|
|
296008
|
+
return null;
|
|
296009
|
+
}
|
|
296010
|
+
function replaceRange2(xml, start, end, replacement) {
|
|
296011
|
+
return `${xml.slice(0, start)}${replacement}${xml.slice(end)}`;
|
|
296012
|
+
}
|
|
296013
|
+
function toFlatSegments(target) {
|
|
296014
|
+
if (target.story !== undefined && target.story.storyType !== "body")
|
|
296015
|
+
return null;
|
|
296016
|
+
if (target.coordinateSpace === "tracked")
|
|
296017
|
+
return null;
|
|
296018
|
+
if (target.kind === "text") {
|
|
296019
|
+
return target.segments.map((segment) => ({
|
|
296020
|
+
blockId: segment.blockId,
|
|
296021
|
+
start: segment.range.start,
|
|
296022
|
+
end: segment.range.end
|
|
296023
|
+
}));
|
|
296024
|
+
}
|
|
296025
|
+
if (target.start.kind !== "text" || target.end.kind !== "text")
|
|
296026
|
+
return null;
|
|
296027
|
+
if (target.start.blockId !== target.end.blockId)
|
|
296028
|
+
return null;
|
|
296029
|
+
return [{ blockId: target.start.blockId, start: target.start.offset, end: target.end.offset }];
|
|
296030
|
+
}
|
|
296031
|
+
function overlaps(left, right) {
|
|
296032
|
+
const leftSegments = toFlatSegments(left);
|
|
296033
|
+
const rightSegments = toFlatSegments(right);
|
|
296034
|
+
if (!leftSegments || !rightSegments)
|
|
296035
|
+
return false;
|
|
296036
|
+
return leftSegments.some((leftSegment) => rightSegments.some((rightSegment) => leftSegment.blockId === rightSegment.blockId && rangesStrictlyOverlap(leftSegment.start, leftSegment.end, rightSegment.start, rightSegment.end)));
|
|
296037
|
+
}
|
|
296038
|
+
var TEXT_ENCODER, WORD_NAMESPACE5 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", METADATA_ANCHOR_ALIAS = "Anchored metadata", W15_NS = "http://schemas.microsoft.com/office/word/2012/wordml", MAX_SDT_ID = 2147483646;
|
|
296039
|
+
var init_adapter9 = __esm(() => {
|
|
296040
|
+
init_src3();
|
|
296041
|
+
init_sd_document_session_internal();
|
|
296042
|
+
init_visible_text();
|
|
296043
|
+
init_inline();
|
|
296044
|
+
init_adapter2();
|
|
296045
|
+
init_shared();
|
|
296046
|
+
init_xml();
|
|
296047
|
+
TEXT_ENCODER = new TextEncoder;
|
|
296048
|
+
});
|
|
296049
|
+
|
|
295201
296050
|
// ../../../v2/document-api-v2-adapter/dist/core/cooperative-slices.js
|
|
295202
296051
|
function createCooperativeSliceGate(yieldPoint, sliceTargetMs = COOPERATIVE_SLICE_TARGET_MS) {
|
|
295203
296052
|
let sliceStartedAt = now();
|
|
@@ -295585,11 +296434,14 @@ function prepareNativeCellSplit(resolved, original, columnInsertIndex) {
|
|
|
295585
296434
|
if (grids.length !== 1 || rows.length !== original.rows.length)
|
|
295586
296435
|
return null;
|
|
295587
296436
|
const grid = grids[0];
|
|
295588
|
-
|
|
296437
|
+
const originalGridChangeXml = original.tblGrid.changeXml;
|
|
296438
|
+
const gridChildren = children2(grid);
|
|
296439
|
+
const gridChanges = gridChildren.filter((range) => owns(range, "tblGridChange"));
|
|
296440
|
+
if (gridChanges.length > 1 || gridChildren.some((range) => !owns(range, "gridCol") && !owns(range, "tblGridChange")) || gridChanges[0] && source.slice(gridChanges[0].start, gridChanges[0].end) !== originalGridChangeXml)
|
|
295589
296441
|
return null;
|
|
295590
296442
|
const originalGridXml = source.slice(grid.start, grid.end);
|
|
295591
296443
|
const originalGridColumns = [...original.tblGrid.gridColXmls];
|
|
295592
|
-
const gridColumns =
|
|
296444
|
+
const gridColumns = gridChildren.filter((range) => owns(range, "gridCol"));
|
|
295593
296445
|
if (gridColumns.length !== originalGridColumns.length || columnInsertIndex < 0 || columnInsertIndex > gridColumns.length)
|
|
295594
296446
|
return null;
|
|
295595
296447
|
const rowFacts = new Map;
|
|
@@ -295692,7 +296544,7 @@ function prepareNativeCellSplit(resolved, original, columnInsertIndex) {
|
|
|
295692
296544
|
const addedColumns = model.tblGrid.gridColXmls.length - originalGridColumns.length;
|
|
295693
296545
|
if (addedColumns < 0 || originalGridColumns.some((column, index) => model.tblGrid.gridColXmls[index < columnInsertIndex ? index : index + addedColumns] !== column))
|
|
295694
296546
|
return null;
|
|
295695
|
-
if (model.tblGrid.changeXml || addedColumns) {
|
|
296547
|
+
if (model.tblGrid.changeXml !== originalGridChangeXml || addedColumns) {
|
|
295696
296548
|
const gridPatches = [];
|
|
295697
296549
|
if (addedColumns) {
|
|
295698
296550
|
const at = columnInsertIndex > 0 ? gridColumns[columnInsertIndex - 1].end : grid.openEnd;
|
|
@@ -295702,12 +296554,15 @@ function prepareNativeCellSplit(resolved, original, columnInsertIndex) {
|
|
|
295702
296554
|
xml: model.tblGrid.gridColXmls.slice(columnInsertIndex, columnInsertIndex + addedColumns).join("")
|
|
295703
296555
|
});
|
|
295704
296556
|
}
|
|
295705
|
-
if (model.tblGrid.changeXml)
|
|
296557
|
+
if (model.tblGrid.changeXml !== originalGridChangeXml) {
|
|
296558
|
+
const previousChange = gridChanges[0];
|
|
296559
|
+
const at = previousChange?.start ?? grid.closeStart;
|
|
295706
296560
|
gridPatches.push({
|
|
295707
|
-
start:
|
|
295708
|
-
end:
|
|
295709
|
-
xml: model.tblGrid.changeXml
|
|
296561
|
+
start: at,
|
|
296562
|
+
end: previousChange?.end ?? at,
|
|
296563
|
+
xml: model.tblGrid.changeXml ?? ""
|
|
295710
296564
|
});
|
|
296565
|
+
}
|
|
295711
296566
|
patches.push({ start: grid.start, end: grid.end, xml: apply(grid, gridPatches) });
|
|
295712
296567
|
}
|
|
295713
296568
|
return apply(table, patches);
|
|
@@ -301392,7 +302247,7 @@ function writeAfterPropertyXml(model, spec, wrappedXml) {
|
|
|
301392
302247
|
}
|
|
301393
302248
|
}
|
|
301394
302249
|
var COLLABORATIVE_TABLE_REWRITE_PREFIXES, TD89, EMPTY_TABLE_CONTEXT_AT_SELECTION, TRACKED_TABLE_COLUMN_RESTORE_NS2 = "urn:superdoc:tracked-table-column", DEFAULT_PAGE_WIDTH_TWIPS = 12240, DEFAULT_PAGE_MARGIN_TWIPS = 1440;
|
|
301395
|
-
var
|
|
302250
|
+
var init_adapter10 = __esm(() => {
|
|
301396
302251
|
init_src3();
|
|
301397
302252
|
init_sd_document_session_internal();
|
|
301398
302253
|
init_tracked_paragraph_body();
|
|
@@ -304158,6 +305013,8 @@ class V2BlocksAdapter {
|
|
|
304158
305013
|
const paraXml = partBytes ? TD90.decode(partBytes.subarray(resolved.entry.byteStart, resolved.entry.byteEnd)) : "";
|
|
304159
305014
|
const objectSlack = (paraXml.match(/<[\w.-]+:(?:drawing|pict|object)\b/g) ?? []).length;
|
|
304160
305015
|
const coordinateSpace = input.coordinateSpace ?? "visible";
|
|
305016
|
+
const metadataAnchorBindings = storyPartUriFromId5(resolved.storyId) === "/word/document.xml" ? listMetadataSplitBindings(this.context, paraXml) : [];
|
|
305017
|
+
const knownMetadataAnchorIds = metadataAnchorBindings.map((binding) => binding.id);
|
|
304161
305018
|
const offset = coordinateSpace === "tracked" ? Math.max(0, Math.trunc(Number.isFinite(input.offset) ? input.offset : 0)) : clampStructuralOffset(input.offset, resolved.entry.textLength + objectSlack);
|
|
304162
305019
|
if (options?.dryRun) {
|
|
304163
305020
|
const policy = this.context.validateMutation(options);
|
|
@@ -304170,7 +305027,8 @@ class V2BlocksAdapter {
|
|
|
304170
305027
|
partBytes,
|
|
304171
305028
|
paragraphByteStart: resolved.entry.byteStart,
|
|
304172
305029
|
offset,
|
|
304173
|
-
coordinateSpace
|
|
305030
|
+
coordinateSpace,
|
|
305031
|
+
knownMetadataAnchorIds
|
|
304174
305032
|
});
|
|
304175
305033
|
if (!planned.ok)
|
|
304176
305034
|
return failure4(mapRejectionReason(planned.reason), planned.reason);
|
|
@@ -304184,6 +305042,8 @@ class V2BlocksAdapter {
|
|
|
304184
305042
|
target: { storyId: resolved.storyId, paraId: input.target.nodeId },
|
|
304185
305043
|
offset,
|
|
304186
305044
|
coordinateSpace,
|
|
305045
|
+
knownMetadataAnchorIds,
|
|
305046
|
+
metadataAnchorBindings,
|
|
304187
305047
|
changeMode: options?.changeMode ?? "direct"
|
|
304188
305048
|
});
|
|
304189
305049
|
const txPerf = createSDTxPerfProbe();
|
|
@@ -305373,13 +306233,14 @@ function readTailParaId(provisionalToFinal, createdRefs) {
|
|
|
305373
306233
|
return null;
|
|
305374
306234
|
}
|
|
305375
306235
|
var TD90, PARAGRAPH_TYPES, TOP_LEVEL_LIST_ROWS_CACHE;
|
|
305376
|
-
var
|
|
306236
|
+
var init_adapter11 = __esm(() => {
|
|
305377
306237
|
init_sd_document_session_internal();
|
|
306238
|
+
init_adapter9();
|
|
305378
306239
|
init_materialize_slot();
|
|
305379
306240
|
init_adapter();
|
|
305380
306241
|
init_stories();
|
|
305381
306242
|
init_text_range_shifts();
|
|
305382
|
-
|
|
306243
|
+
init_adapter10();
|
|
305383
306244
|
init_tracked_pr_change();
|
|
305384
306245
|
init_note_story();
|
|
305385
306246
|
init_textbox_story();
|
|
@@ -305563,7 +306424,7 @@ function operationError4(code, message) {
|
|
|
305563
306424
|
error48.code = code;
|
|
305564
306425
|
return error48;
|
|
305565
306426
|
}
|
|
305566
|
-
var
|
|
306427
|
+
var init_adapter12 = __esm(() => {
|
|
305567
306428
|
init_src3();
|
|
305568
306429
|
init_sd_document_session_internal();
|
|
305569
306430
|
init_runtime2();
|
|
@@ -329428,7 +330289,7 @@ class V2ContentControlsAdapter {
|
|
|
329428
330289
|
}
|
|
329429
330290
|
}
|
|
329430
330291
|
if (input.at) {
|
|
329431
|
-
const anchor = input.at.start.kind === "text" ?
|
|
330292
|
+
const anchor = input.at.start.kind === "text" ? findParagraphById3(part.xml, input.at.start.blockId) : null;
|
|
329432
330293
|
if (anchor && /<(?:[\w.-]+:)?(?:ins|del|moveFrom|moveTo)\b/.test(anchor.xml)) {
|
|
329433
330294
|
this.requireDirectControlStructure(input, options);
|
|
329434
330295
|
}
|
|
@@ -329439,7 +330300,7 @@ class V2ContentControlsAdapter {
|
|
|
329439
330300
|
let beforeXml = "";
|
|
329440
330301
|
let namespaceBindings = new Map(Object.entries(collectXmlElementRanges(part.xml).ranges[0]?.namespaceBindings ?? {}));
|
|
329441
330302
|
if (input.at?.start.kind === "text") {
|
|
329442
|
-
const anchor =
|
|
330303
|
+
const anchor = findParagraphById3(part.xml, input.at.start.blockId);
|
|
329443
330304
|
if (anchor) {
|
|
329444
330305
|
namespaceBindings = new Map(contentControlNamespaceBindings(part.xml, anchor.start, true));
|
|
329445
330306
|
if (input.kind === "block" && extractVisibleTextFromXml2(anchor.xml).trim().length === 0) {
|
|
@@ -329481,11 +330342,11 @@ class V2ContentControlsAdapter {
|
|
|
329481
330342
|
if (wholeBlocks.kind === "failure") {
|
|
329482
330343
|
return { success: false, failure: { code: wholeBlocks.code, message: wholeBlocks.message } };
|
|
329483
330344
|
}
|
|
329484
|
-
const anchor = at.start.kind === "text" ?
|
|
330345
|
+
const anchor = at.start.kind === "text" ? findParagraphById3(part.xml, at.start.blockId) : null;
|
|
329485
330346
|
if (wholeBlocks.kind === "ok") {
|
|
329486
330347
|
const selectedXml = part.xml.slice(wholeBlocks.start, wholeBlocks.end);
|
|
329487
330348
|
const wrapped = replaceSdtContentInTemplate(sdtXml, buildInnerXml(selectedXml));
|
|
329488
|
-
nextXml =
|
|
330349
|
+
nextXml = replaceRange3(part.xml, wholeBlocks.start, wholeBlocks.end, wrapped);
|
|
329489
330350
|
targetBlockIds2 = wholeBlocks.blockIds;
|
|
329490
330351
|
} else if (anchor && at.start.kind === "text" && at.end.kind === "text" && at.start.offset !== at.end.offset && input.content === undefined && input.html === undefined && input.json === undefined) {
|
|
329491
330352
|
const splitMarker = "<sd-content-control-split/>";
|
|
@@ -329526,7 +330387,7 @@ class V2ContentControlsAdapter {
|
|
|
329526
330387
|
});
|
|
329527
330388
|
if (!prepared.ok)
|
|
329528
330389
|
return { success: false, failure: prepared.failure };
|
|
329529
|
-
nextXml =
|
|
330390
|
+
nextXml = replaceRange3(part.xml, anchor.start, anchor.end, prepared.xml);
|
|
329530
330391
|
createRefOptions = {
|
|
329531
330392
|
createdRefs: prepared.wordIds.map((entityId) => ({
|
|
329532
330393
|
kind: "trackedChange",
|
|
@@ -329535,7 +330396,7 @@ class V2ContentControlsAdapter {
|
|
|
329535
330396
|
}))
|
|
329536
330397
|
};
|
|
329537
330398
|
} else {
|
|
329538
|
-
nextXml =
|
|
330399
|
+
nextXml = replaceRange3(part.xml, anchor.start, anchor.end, replacementXml);
|
|
329539
330400
|
}
|
|
329540
330401
|
targetBlockIds2 = [at.start.blockId];
|
|
329541
330402
|
} else {
|
|
@@ -329680,7 +330541,7 @@ class V2ContentControlsAdapter {
|
|
|
329680
330541
|
const preview = this.validateDryRun(input, options, control.target);
|
|
329681
330542
|
return preview.success ? { ...preview, updatedRef } : preview;
|
|
329682
330543
|
}
|
|
329683
|
-
const nextXml =
|
|
330544
|
+
const nextXml = replaceRange3(loaded.documentXml, control.start, control.end, wrapper);
|
|
329684
330545
|
return this.commitDocument(nextXml, "content-control-wrap", input, options, control.target, {
|
|
329685
330546
|
updatedRef,
|
|
329686
330547
|
createdRefs,
|
|
@@ -329797,7 +330658,7 @@ class V2ContentControlsAdapter {
|
|
|
329797
330658
|
const updatedRef = { ...source.target, nodeId: clone3.rootId };
|
|
329798
330659
|
if (dryRunRequested(input, options))
|
|
329799
330660
|
return { success: true, contentControl: source.target, updatedRef };
|
|
329800
|
-
const withSource =
|
|
330661
|
+
const withSource = replaceRange3(loaded.documentXml, source.start, source.end, prepared.sourceXml);
|
|
329801
330662
|
const offset = destination.offset >= source.end ? destination.offset + prepared.sourceXml.length - source.xml.length : destination.offset;
|
|
329802
330663
|
const xml2 = withSource.slice(0, offset) + prepared.destinationXml + withSource.slice(offset);
|
|
329803
330664
|
return this.commitDocument(xml2, "content-control-move", input, options, source.target, {
|
|
@@ -329807,7 +330668,7 @@ class V2ContentControlsAdapter {
|
|
|
329807
330668
|
}
|
|
329808
330669
|
if (dryRunRequested(input, options))
|
|
329809
330670
|
return { success: true, contentControl: source.target };
|
|
329810
|
-
let xml =
|
|
330671
|
+
let xml = replaceRange3(loaded.documentXml, source.start, source.end, "");
|
|
329811
330672
|
const adjustedOffset = destination.offset >= source.end ? destination.offset - (source.end - source.start) : destination.offset;
|
|
329812
330673
|
const movedXml = destination.wrapInlineInParagraph && source.info.kind === "inline" ? buildParaIdParagraphXml(createParaIdAllocator(this.context)(), source.xml) : source.xml;
|
|
329813
330674
|
xml = `${xml.slice(0, adjustedOffset)}${movedXml}${xml.slice(adjustedOffset)}`;
|
|
@@ -329833,7 +330694,7 @@ class V2ContentControlsAdapter {
|
|
|
329833
330694
|
const destinationXml = rewriteContentControlMoveDestinationXml(source.xml, destinationId, createParaIdAllocator(this.context));
|
|
329834
330695
|
const sourceSideXml = wrapMoveSourceBlock(source.xml, stamp);
|
|
329835
330696
|
const destinationSideXml = wrapMoveDestinationBlock(destinationXml, stamp);
|
|
329836
|
-
const withSource =
|
|
330697
|
+
const withSource = replaceRange3(loaded.documentXml, source.start, source.end, sourceSideXml);
|
|
329837
330698
|
const inserted = insertAfterExactlyOnce(withSource, destination.xml, destinationSideXml);
|
|
329838
330699
|
if (!inserted.ok) {
|
|
329839
330700
|
return { success: false, failure: { code: "INTERNAL_ERROR", message: inserted.message } };
|
|
@@ -329860,7 +330721,7 @@ class V2ContentControlsAdapter {
|
|
|
329860
330721
|
}
|
|
329861
330722
|
moveToParagraphCaret(input, options, loaded, source) {
|
|
329862
330723
|
const blockId = typeof input.destination?.target?.nodeId === "string" ? input.destination.target.nodeId : "";
|
|
329863
|
-
const anchor =
|
|
330724
|
+
const anchor = findParagraphById3(loaded.documentXml, blockId);
|
|
329864
330725
|
if (!anchor) {
|
|
329865
330726
|
return {
|
|
329866
330727
|
success: false,
|
|
@@ -329885,7 +330746,7 @@ class V2ContentControlsAdapter {
|
|
|
329885
330746
|
requestedOffset = Math.max(beforeSource, requestedOffset - sourceVisible);
|
|
329886
330747
|
}
|
|
329887
330748
|
if (source.info.kind === "inline") {
|
|
329888
|
-
const preview =
|
|
330749
|
+
const preview = findParagraphById3(replaceRange3(loaded.documentXml, source.start, source.end, ""), blockId);
|
|
329889
330750
|
if (!preview || spliceXmlAtVisibleOffset(preview.xml, requestedOffset, source.xml).kind === "shared-run") {
|
|
329890
330751
|
return { success: false, failure: {
|
|
329891
330752
|
code: "CAPABILITY_UNAVAILABLE",
|
|
@@ -329926,8 +330787,8 @@ class V2ContentControlsAdapter {
|
|
|
329926
330787
|
}
|
|
329927
330788
|
if (dryRunRequested(input, options))
|
|
329928
330789
|
return { success: true, contentControl: source.target, updatedRef: commitOptions.updatedRef };
|
|
329929
|
-
const withoutSource =
|
|
329930
|
-
const para =
|
|
330790
|
+
const withoutSource = replaceRange3(loaded.documentXml, source.start, source.end, sourceReplacement);
|
|
330791
|
+
const para = findParagraphById3(withoutSource, blockId);
|
|
329931
330792
|
if (!para) {
|
|
329932
330793
|
return {
|
|
329933
330794
|
success: false,
|
|
@@ -329947,7 +330808,7 @@ class V2ContentControlsAdapter {
|
|
|
329947
330808
|
};
|
|
329948
330809
|
}
|
|
329949
330810
|
const updatedPara = spliced.kind === "ok" ? spliced.xml : insertXmlIntoParagraphContent(para.xml, destinationXml);
|
|
329950
|
-
nextXml =
|
|
330811
|
+
nextXml = replaceRange3(withoutSource, para.start, para.end, updatedPara);
|
|
329951
330812
|
} else {
|
|
329952
330813
|
const insertBefore = requestedOffset === 0 && extractVisibleTextFromXml2(para.xml).trim().length > 0;
|
|
329953
330814
|
nextXml = insertBefore ? `${withoutSource.slice(0, para.start)}${destinationXml}${withoutSource.slice(para.start)}` : `${withoutSource.slice(0, para.end)}${destinationXml}${withoutSource.slice(para.end)}`;
|
|
@@ -330037,7 +330898,7 @@ class V2ContentControlsAdapter {
|
|
|
330037
330898
|
return { success: false, failure: replacement.failure };
|
|
330038
330899
|
if (dryRunRequested(input, options))
|
|
330039
330900
|
return this.validateDryRun(input, options, control.target);
|
|
330040
|
-
const nextXml2 =
|
|
330901
|
+
const nextXml2 = replaceRange3(part.xml, control.start, control.end, replaceSdtContentXml(control, replacement.xml));
|
|
330041
330902
|
return this.commitDocument(nextXml2, "content-control-replace-content", input, options, control.target, {
|
|
330042
330903
|
partUri: part.partUri,
|
|
330043
330904
|
storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] },
|
|
@@ -330051,7 +330912,7 @@ class V2ContentControlsAdapter {
|
|
|
330051
330912
|
}
|
|
330052
330913
|
if (dryRunRequested(input, options))
|
|
330053
330914
|
return this.validateDryRun(input, options, control.target);
|
|
330054
|
-
const nextXml =
|
|
330915
|
+
const nextXml = replaceRange3(part.xml, control.start, control.end, replaceSdtContentXml(control, contentXml));
|
|
330055
330916
|
return this.commitDocument(nextXml, "content-control-replace-content", input, options, control.target, {
|
|
330056
330917
|
partUri: part.partUri,
|
|
330057
330918
|
storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] },
|
|
@@ -330109,7 +330970,7 @@ class V2ContentControlsAdapter {
|
|
|
330109
330970
|
if (at.start.kind !== "text" || at.end.kind !== "text" || at.start.blockId !== at.end.blockId) {
|
|
330110
330971
|
throw operationError("CAPABILITY_UNAVAILABLE", "Content-control creation requires a selection within one paragraph.");
|
|
330111
330972
|
}
|
|
330112
|
-
const paragraph4 =
|
|
330973
|
+
const paragraph4 = findParagraphById3(part.xml, at.start.blockId);
|
|
330113
330974
|
if (!paragraph4)
|
|
330114
330975
|
throw operationError("TARGET_NOT_FOUND", `Paragraph ${at.start.blockId} was not found in the target story.`);
|
|
330115
330976
|
if (![at.start.offset, at.end.offset].every((offset) => Number.isInteger(offset) && offset >= 0 && offset <= parseParagraphInlineMap(paragraph4.xml).visibleLength) || at.start.offset > at.end.offset) {
|
|
@@ -330142,7 +331003,7 @@ class V2ContentControlsAdapter {
|
|
|
330142
331003
|
return this.validateDryRun(input, options, control.target);
|
|
330143
331004
|
const part = loaded.parts.find((candidate2) => candidate2.storyId === control.storyId);
|
|
330144
331005
|
const replacement = replaceSdtContentXml(control, buildTextReplacementContentXml(value2, control.info.kind, createParaIdAllocator(this.context), control.contentXml, false));
|
|
330145
|
-
const nextXml =
|
|
331006
|
+
const nextXml = replaceRange3(part.xml, control.start, control.end, replacement);
|
|
330146
331007
|
return this.commitDocument(nextXml, "content-control-replace-content", input, options, control.target, {
|
|
330147
331008
|
partUri: part.partUri,
|
|
330148
331009
|
storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] },
|
|
@@ -330182,7 +331043,7 @@ class V2ContentControlsAdapter {
|
|
|
330182
331043
|
createdRefs: [{ kind: "trackedChange", entityId: String(stamp.revisionId), storyId: body.storyId }]
|
|
330183
331044
|
};
|
|
330184
331045
|
}
|
|
330185
|
-
const nextXml =
|
|
331046
|
+
const nextXml = replaceRange3(loaded.documentXml, control.start, control.end, replacement);
|
|
330186
331047
|
return this.commitDocument(nextXml, "content-control-pr", input, options, control.target, commitOptions);
|
|
330187
331048
|
}
|
|
330188
331049
|
setChoiceListItems(input, options) {
|
|
@@ -330404,7 +331265,7 @@ class V2ContentControlsAdapter {
|
|
|
330404
331265
|
replacement = prepared.xml;
|
|
330405
331266
|
createdRefs = prepared.wordIds.map((entityId) => ({ kind: "trackedChange", entityId, storyId: control.storyId }));
|
|
330406
331267
|
}
|
|
330407
|
-
const nextXml =
|
|
331268
|
+
const nextXml = replaceRange3(part.xml, control.start, control.end, replacement);
|
|
330408
331269
|
return this.commitDocument(nextXml, prefix, input, options, control.target, {
|
|
330409
331270
|
partUri: part.partUri,
|
|
330410
331271
|
storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] },
|
|
@@ -330451,7 +331312,7 @@ class V2ContentControlsAdapter {
|
|
|
330451
331312
|
const replacement = !anchor || insertIndex <= 0 ? replaceSdtContentXml(control, `${item}${control.contentXml}`) : `${control.xml.slice(0, anchor.end - control.start)}${item}${control.xml.slice(anchor.end - control.start)}`;
|
|
330452
331313
|
if (dryRunRequested(input, options))
|
|
330453
331314
|
return { success: true, contentControl: target };
|
|
330454
|
-
const nextXml =
|
|
331315
|
+
const nextXml = replaceRange3(loaded.documentXml, control.start, control.end, replacement);
|
|
330455
331316
|
return this.commitDocument(nextXml, "content-control-repeat-insert", input, options, target, { createdRefs });
|
|
330456
331317
|
}
|
|
330457
331318
|
cloneRepeatingItem(input, options) {
|
|
@@ -330495,13 +331356,13 @@ class V2ContentControlsAdapter {
|
|
|
330495
331356
|
return this.validateDryRun(input, options, control.target);
|
|
330496
331357
|
const localEnd = item.end - control.start;
|
|
330497
331358
|
const replacement = `${control.xml.slice(0, localEnd)}${clone3}${control.xml.slice(localEnd)}`;
|
|
330498
|
-
const nextXml =
|
|
331359
|
+
const nextXml = replaceRange3(loaded.documentXml, control.start, control.end, replacement);
|
|
330499
331360
|
return this.commitDocument(nextXml, "content-control-repeat-clone", input, options, control.target, { createdRefs });
|
|
330500
331361
|
}
|
|
330501
331362
|
deleteRepeatingItem(input, options) {
|
|
330502
331363
|
return this.mutateControl(input.target, input, options, (control, loaded) => {
|
|
330503
331364
|
const item = this.repeatingItems(control, loaded)[input.index];
|
|
330504
|
-
return
|
|
331365
|
+
return replaceRange3(control.xml, item.start - control.start, item.end - control.start, "");
|
|
330505
331366
|
}, "content-control-repeat-delete", (control, loaded) => {
|
|
330506
331367
|
if (control.info.controlType !== "repeatingSection") {
|
|
330507
331368
|
throw operationError("INVALID_TARGET", "contentControls.repeatingSection operation requires control type repeatingSection.");
|
|
@@ -331770,7 +332631,7 @@ function unwrapSdtXml(sdtXml) {
|
|
|
331770
332631
|
const contentRange = findDirectSdtChildRange(sdtXml, "sdtContent");
|
|
331771
332632
|
return contentRange ? sdtXml.slice(contentRange.openEnd, contentRange.closeStart) : "";
|
|
331772
332633
|
}
|
|
331773
|
-
function
|
|
332634
|
+
function replaceRange3(xml, start, end, replacement) {
|
|
331774
332635
|
return `${xml.slice(0, start)}${replacement}${xml.slice(end)}`;
|
|
331775
332636
|
}
|
|
331776
332637
|
function resolveContentControlMoveDestination(loaded, destination) {
|
|
@@ -332312,7 +333173,7 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
|
|
|
332312
333173
|
if (target?.kind !== "selection" || target.start?.kind !== "text" || target.end?.kind !== "text") {
|
|
332313
333174
|
return { ok: false, failure: { code: "INVALID_TARGET", message: "A text selection is required." } };
|
|
332314
333175
|
}
|
|
332315
|
-
const para =
|
|
333176
|
+
const para = findParagraphById3(documentXml, target.start.blockId);
|
|
332316
333177
|
if (!para)
|
|
332317
333178
|
return { ok: false, failure: { code: "TARGET_NOT_FOUND", message: "Target paragraph was not found." } };
|
|
332318
333179
|
if (kind === "inline" && target.start.offset === target.end.offset) {
|
|
@@ -332329,12 +333190,12 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
|
|
|
332329
333190
|
const insertXml = replaceSdtContentInTemplate(sdtXml, buildReplacementContentXml2(hasReplacementContent ? replacementContent : ""));
|
|
332330
333191
|
const spliced = spliceXmlAtVisibleOffset(para.xml, target.start.offset, insertXml);
|
|
332331
333192
|
if (spliced.kind === "ok") {
|
|
332332
|
-
return { ok: true, xml:
|
|
333193
|
+
return { ok: true, xml: replaceRange3(documentXml, para.start, para.end, spliced.xml) };
|
|
332333
333194
|
}
|
|
332334
333195
|
if (spliced.kind === "empty") {
|
|
332335
333196
|
return {
|
|
332336
333197
|
ok: true,
|
|
332337
|
-
xml:
|
|
333198
|
+
xml: replaceRange3(documentXml, para.start, para.end, insertXmlIntoParagraphContent(para.xml, insertXml))
|
|
332338
333199
|
};
|
|
332339
333200
|
}
|
|
332340
333201
|
return {
|
|
@@ -332364,7 +333225,7 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
|
|
|
332364
333225
|
close: template.close
|
|
332365
333226
|
});
|
|
332366
333227
|
if (wrappedRuns.ok) {
|
|
332367
|
-
return { ok: true, xml:
|
|
333228
|
+
return { ok: true, xml: replaceRange3(documentXml, para.start, para.end, wrappedRuns.xml) };
|
|
332368
333229
|
}
|
|
332369
333230
|
return { ok: false, failure: { code: "CAPABILITY_UNAVAILABLE", message: "Content-control selection spans unsupported inline structures." } };
|
|
332370
333231
|
}
|
|
@@ -332376,7 +333237,7 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
|
|
|
332376
333237
|
replacementXml: replaceSdtContentInTemplate(sdtXml, buildReplacementContentXml2(replacementContent))
|
|
332377
333238
|
});
|
|
332378
333239
|
if (replaced.ok) {
|
|
332379
|
-
return { ok: true, xml:
|
|
333240
|
+
return { ok: true, xml: replaceRange3(documentXml, para.start, para.end, replaced.xml) };
|
|
332380
333241
|
}
|
|
332381
333242
|
return {
|
|
332382
333243
|
ok: false,
|
|
@@ -332392,7 +333253,7 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
|
|
|
332392
333253
|
});
|
|
332393
333254
|
if (wrapped === para.xml)
|
|
332394
333255
|
return { ok: false, failure: { code: "CAPABILITY_UNAVAILABLE", message: "Content-control selection spans unsupported inline structures." } };
|
|
332395
|
-
return { ok: true, xml:
|
|
333256
|
+
return { ok: true, xml: replaceRange3(documentXml, para.start, para.end, wrapped) };
|
|
332396
333257
|
}
|
|
332397
333258
|
function splitSdtTemplateAroundContent(sdtXml) {
|
|
332398
333259
|
const sdtRange = findFirstSdtElementRange(sdtXml);
|
|
@@ -332416,7 +333277,7 @@ function insertBlockContentControlAtSelection(documentXml, paragraphs, target, s
|
|
|
332416
333277
|
throw operationError("TARGET_NOT_FOUND", "Target paragraph was not found.");
|
|
332417
333278
|
const collapsed = target.start.blockId === target.end.blockId && target.start.offset === target.end.offset;
|
|
332418
333279
|
if (collapsed && extractVisibleTextFromXml2(anchor.xml).trim().length === 0) {
|
|
332419
|
-
return
|
|
333280
|
+
return replaceRange3(documentXml, anchor.start, anchor.end, sdtXml);
|
|
332420
333281
|
}
|
|
332421
333282
|
return `${documentXml.slice(0, anchor.end)}${sdtXml}${documentXml.slice(anchor.end)}`;
|
|
332422
333283
|
}
|
|
@@ -332545,7 +333406,7 @@ function findFirstSdtElementRange(xml) {
|
|
|
332545
333406
|
}
|
|
332546
333407
|
return null;
|
|
332547
333408
|
}
|
|
332548
|
-
function
|
|
333409
|
+
function findParagraphById3(documentXml, blockId) {
|
|
332549
333410
|
const paraRe = /<w:p\b[^>]*?(?:\/>|>[\s\S]*?<\/w:p>)/g;
|
|
332550
333411
|
for (let match = paraRe.exec(documentXml);match; match = paraRe.exec(documentXml)) {
|
|
332551
333412
|
if (match[0].includes(`w14:paraId="${blockId}"`)) {
|
|
@@ -332659,7 +333520,7 @@ function replaceTextRangeInParagraph2(paragraphXml, start, end, replacement) {
|
|
|
332659
333520
|
return paragraphXml;
|
|
332660
333521
|
}
|
|
332661
333522
|
var DEFAULT_CHECKED, DEFAULT_UNCHECKED, SECONDARY_STORY_MUTATION_MESSAGE = "Content control mutations outside the document body are not supported by this adapter.", TYPE_TAGS, COOPERATIVE_PARSE_SLICE_PARAGRAPHS = 128, COOPERATIVE_PARSE_SLICE_CONTROLS = 16, RAW_ATTRIBUTE_PATTERN;
|
|
332662
|
-
var
|
|
333523
|
+
var init_adapter13 = __esm(() => {
|
|
332663
333524
|
init_sd_document_session_internal();
|
|
332664
333525
|
init_src6();
|
|
332665
333526
|
init_part();
|
|
@@ -332836,7 +333697,7 @@ var init_tracked_regeneration = __esm(() => {
|
|
|
332836
333697
|
init_tracked_pr_change();
|
|
332837
333698
|
init_runtime2();
|
|
332838
333699
|
init_xml();
|
|
332839
|
-
|
|
333700
|
+
init_adapter14();
|
|
332840
333701
|
});
|
|
332841
333702
|
|
|
332842
333703
|
// ../../../v2/document-api-v2-adapter/dist/captions/tracked-commit.js
|
|
@@ -333136,8 +333997,8 @@ var nativeStamp = (stamp) => ({
|
|
|
333136
333997
|
});
|
|
333137
333998
|
var init_tracked_generated_paragraph = __esm(() => {
|
|
333138
333999
|
init_sd_document_session_internal();
|
|
333139
|
-
init_adapter15();
|
|
333140
334000
|
init_adapter16();
|
|
334001
|
+
init_adapter17();
|
|
333141
334002
|
init_tracked_commit();
|
|
333142
334003
|
init_tracked_paragraph();
|
|
333143
334004
|
init_paragraph_ids();
|
|
@@ -334028,7 +334889,7 @@ function operationError5(code2, message) {
|
|
|
334028
334889
|
return error48;
|
|
334029
334890
|
}
|
|
334030
334891
|
var EMPTY_TOC_CONTEXT_AT_SELECTION, TOC_CONFIGURABLE_SWITCH_FLAGS, TOC_SWITCH_FRAGMENT_RE;
|
|
334031
|
-
var
|
|
334892
|
+
var init_adapter14 = __esm(() => {
|
|
334032
334893
|
init_tracked_regeneration();
|
|
334033
334894
|
init_removal();
|
|
334034
334895
|
init_deletion_locks();
|
|
@@ -334205,7 +335066,7 @@ var init_tracked_creation = __esm(() => {
|
|
|
334205
335066
|
init_tracked_pr_change();
|
|
334206
335067
|
init_runtime2();
|
|
334207
335068
|
init_xml();
|
|
334208
|
-
|
|
335069
|
+
init_adapter14();
|
|
334209
335070
|
});
|
|
334210
335071
|
|
|
334211
335072
|
// ../../../v2/document-api-v2-adapter/dist/sections/adapter.js
|
|
@@ -334719,7 +335580,7 @@ function documentFailure(message, code2 = "CAPABILITY_UNAVAILABLE") {
|
|
|
334719
335580
|
return { success: false, failure: { code: code2, message } };
|
|
334720
335581
|
}
|
|
334721
335582
|
var VALID_BREAK_TYPES, VALID_PAGE_NUMBER_FORMATS, VALID_LINE_NUMBER_RESTARTS, VALID_VERTICAL_ALIGNS, VALID_PAGE_BORDER_DISPLAYS, VALID_PAGE_BORDER_OFFSETS, VALID_PAGE_BORDER_Z_ORDERS;
|
|
334722
|
-
var
|
|
335583
|
+
var init_adapter15 = __esm(() => {
|
|
334723
335584
|
init_src3();
|
|
334724
335585
|
init_sd_document_session_internal();
|
|
334725
335586
|
init_document_reader();
|
|
@@ -335849,20 +336710,20 @@ function storyErrorMessage3(error48) {
|
|
|
335849
336710
|
}
|
|
335850
336711
|
}
|
|
335851
336712
|
var VALUED_TOC_SWITCHES;
|
|
335852
|
-
var
|
|
336713
|
+
var init_adapter16 = __esm(() => {
|
|
335853
336714
|
init_sd_document_session_internal();
|
|
335854
336715
|
init_sd_document_session_internal();
|
|
335855
336716
|
init_materialize_slot();
|
|
335856
|
-
|
|
336717
|
+
init_adapter13();
|
|
335857
336718
|
init_adapter();
|
|
335858
336719
|
init_runtime2();
|
|
335859
336720
|
init_xml();
|
|
335860
336721
|
init_section_xml();
|
|
335861
|
-
|
|
336722
|
+
init_adapter10();
|
|
335862
336723
|
init_xml3();
|
|
335863
|
-
init_adapter13();
|
|
335864
|
-
init_tracked_creation();
|
|
335865
336724
|
init_adapter14();
|
|
336725
|
+
init_tracked_creation();
|
|
336726
|
+
init_adapter15();
|
|
335866
336727
|
init_note_story();
|
|
335867
336728
|
init_textbox_story();
|
|
335868
336729
|
init_src6();
|
|
@@ -336522,11 +337383,11 @@ function operationError6(code2, message) {
|
|
|
336522
337383
|
error48.code = code2;
|
|
336523
337384
|
return error48;
|
|
336524
337385
|
}
|
|
336525
|
-
var
|
|
337386
|
+
var init_adapter17 = __esm(() => {
|
|
336526
337387
|
init_src3();
|
|
336527
337388
|
init_sd_document_session_internal();
|
|
336528
337389
|
init_document_reader();
|
|
336529
|
-
|
|
337390
|
+
init_adapter16();
|
|
336530
337391
|
init_composite();
|
|
336531
337392
|
init_paragraph_ids();
|
|
336532
337393
|
init_xml();
|
|
@@ -346236,7 +347097,7 @@ function commitTrackedImageCaption(context, change, options) {
|
|
|
346236
347097
|
});
|
|
346237
347098
|
}
|
|
346238
347099
|
var init_tracked_caption = __esm(() => {
|
|
346239
|
-
|
|
347100
|
+
init_adapter17();
|
|
346240
347101
|
init_tracked_commit();
|
|
346241
347102
|
init_tracked_paragraph();
|
|
346242
347103
|
init_paragraph_ids();
|
|
@@ -350148,7 +351009,7 @@ function escapeRegExp17(value2) {
|
|
|
350148
351009
|
return value2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
350149
351010
|
}
|
|
350150
351011
|
var IMAGE_HYPERLINK_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", EMU_PER_PX5 = 9525, CROP_SCALE2 = 1000, DEFAULT_FLOATING_RELATIVE_HEIGHT = 251659264, DECORATIVE_EXT_URI = "{C183D7F6-B498-43B3-948B-1728B52AA6E4}", DECORATIVE_NAMESPACE = "http://schemas.microsoft.com/office/drawing/2017/decorative", DRAWING_NAMESPACE = "http://schemas.openxmlformats.org/drawingml/2006/main", RELATIONSHIP_NAMESPACE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", CONVERTED_INLINE_ANCHORS, DEFAULT_PAGE_WIDTH_TWIPS2 = 12240, DEFAULT_PAGE_MARGIN_TWIPS2 = 1440, TWIPS_PER_PX = 15;
|
|
350151
|
-
var
|
|
351012
|
+
var init_adapter18 = __esm(() => {
|
|
350152
351013
|
init_pending_image_insertion();
|
|
350153
351014
|
init_src3();
|
|
350154
351015
|
init_sd_document_session_internal();
|
|
@@ -350165,7 +351026,7 @@ var init_adapter17 = __esm(() => {
|
|
|
350165
351026
|
init_receipt_entities();
|
|
350166
351027
|
init_xml_rewrite();
|
|
350167
351028
|
init_public_model();
|
|
350168
|
-
|
|
351029
|
+
init_adapter16();
|
|
350169
351030
|
init_adapter3();
|
|
350170
351031
|
init_runtime2();
|
|
350171
351032
|
init_tracked_caption();
|
|
@@ -350439,7 +351300,7 @@ function projectOperationCapabilities(context) {
|
|
|
350439
351300
|
return out;
|
|
350440
351301
|
}
|
|
350441
351302
|
var V2_SUPPORTED_STEP_OPS, V2_SUPPORTED_NON_UNIFORM_STRATEGIES, V2_SUPPORTED_SET_MARKS, V2_REGEX_LIMITS;
|
|
350442
|
-
var
|
|
351303
|
+
var init_adapter19 = __esm(() => {
|
|
350443
351304
|
init_src3();
|
|
350444
351305
|
init_search();
|
|
350445
351306
|
init_support_contract();
|
|
@@ -350448,8 +351309,8 @@ var init_adapter18 = __esm(() => {
|
|
|
350448
351309
|
init_rich_fragment_apply();
|
|
350449
351310
|
init_digest();
|
|
350450
351311
|
init_registry3();
|
|
350451
|
-
|
|
350452
|
-
|
|
351312
|
+
init_adapter18();
|
|
351313
|
+
init_adapter10();
|
|
350453
351314
|
V2_SUPPORTED_STEP_OPS = MUTATION_PLAN_SUPPORTED_STEP_OPS;
|
|
350454
351315
|
V2_SUPPORTED_NON_UNIFORM_STRATEGIES = Object.freeze([]);
|
|
350455
351316
|
V2_SUPPORTED_SET_MARKS = Object.freeze([]);
|
|
@@ -351072,10 +351933,10 @@ function operationError8(code2, message) {
|
|
|
351072
351933
|
error48.code = code2;
|
|
351073
351934
|
return error48;
|
|
351074
351935
|
}
|
|
351075
|
-
var
|
|
351936
|
+
var init_adapter20 = __esm(() => {
|
|
351076
351937
|
init_src3();
|
|
351077
351938
|
init_sd_document_session_internal();
|
|
351078
|
-
|
|
351939
|
+
init_adapter16();
|
|
351079
351940
|
init_adapter8();
|
|
351080
351941
|
init_tracked_generated_paragraph();
|
|
351081
351942
|
init_tracked_pr_change();
|
|
@@ -353371,7 +354232,7 @@ class V2CommentsAdapter {
|
|
|
353371
354232
|
function notImplemented(message) {
|
|
353372
354233
|
return { success: false, failure: { code: "CAPABILITY_UNAVAILABLE", message } };
|
|
353373
354234
|
}
|
|
353374
|
-
var
|
|
354235
|
+
var init_adapter21 = __esm(() => {
|
|
353375
354236
|
init_create2();
|
|
353376
354237
|
init_edit();
|
|
353377
354238
|
init_move();
|
|
@@ -353660,7 +354521,7 @@ function operationError9(code2, message) {
|
|
|
353660
354521
|
error48.code = code2;
|
|
353661
354522
|
return error48;
|
|
353662
354523
|
}
|
|
353663
|
-
var
|
|
354524
|
+
var init_adapter22 = __esm(() => {
|
|
353664
354525
|
init_src3();
|
|
353665
354526
|
init_adapter8();
|
|
353666
354527
|
init_inline();
|
|
@@ -354402,7 +355263,7 @@ var TD99, TE56, SETTINGS_PART_URI4 = "/word/settings.xml", WORDPROCESSINGML_NS3
|
|
|
354402
355263
|
var init_definitions = __esm(() => {
|
|
354403
355264
|
init_src2();
|
|
354404
355265
|
init_sd_document_session_internal();
|
|
354405
|
-
|
|
355266
|
+
init_adapter15();
|
|
354406
355267
|
init_part();
|
|
354407
355268
|
TD99 = new TextDecoder("utf-8", { fatal: false });
|
|
354408
355269
|
TE56 = new TextEncoder;
|
|
@@ -356265,13 +357126,13 @@ function recordWhole(overlapsByFragment, entry, logical) {
|
|
|
356265
357126
|
});
|
|
356266
357127
|
}
|
|
356267
357128
|
function normalizeNestedOverlaps(overlapsByFragment, rangeByFragment) {
|
|
356268
|
-
const
|
|
357129
|
+
const overlaps2 = Array.from(overlapsByFragment.values());
|
|
356269
357130
|
const remove = new Set;
|
|
356270
|
-
for (const parent of
|
|
357131
|
+
for (const parent of overlaps2) {
|
|
356271
357132
|
const parentRange = rangeByFragment.get(fragmentKey(parent.fragment));
|
|
356272
357133
|
if (!parentRange || parent.coverage !== "partial")
|
|
356273
357134
|
continue;
|
|
356274
|
-
for (const child of
|
|
357135
|
+
for (const child of overlaps2) {
|
|
356275
357136
|
if (child === parent)
|
|
356276
357137
|
continue;
|
|
356277
357138
|
const childRange = rangeByFragment.get(fragmentKey(child.fragment));
|
|
@@ -356296,7 +357157,7 @@ function normalizeNestedOverlaps(overlapsByFragment, rangeByFragment) {
|
|
|
356296
357157
|
}
|
|
356297
357158
|
return {
|
|
356298
357159
|
ok: true,
|
|
356299
|
-
overlaps:
|
|
357160
|
+
overlaps: overlaps2.filter((overlap) => !remove.has(fragmentKey(overlap.fragment)))
|
|
356300
357161
|
};
|
|
356301
357162
|
}
|
|
356302
357163
|
function fragmentKey(fragment3) {
|
|
@@ -357399,12 +358260,12 @@ function pushTextTarget(targets, seen, target) {
|
|
|
357399
358260
|
seen.add(key2);
|
|
357400
358261
|
targets.push(target);
|
|
357401
358262
|
}
|
|
357402
|
-
function shouldExpandWholePairedReplacementSide(overlap,
|
|
358263
|
+
function shouldExpandWholePairedReplacementSide(overlap, overlaps2) {
|
|
357403
358264
|
const logical = overlap.logical;
|
|
357404
358265
|
if (overlap.coverage !== "whole" || !logical || logical.type !== "replacement" || !logical.sides?.inserted || !logical.sides.deleted) {
|
|
357405
358266
|
return false;
|
|
357406
358267
|
}
|
|
357407
|
-
const sameLogicalOverlaps =
|
|
358268
|
+
const sameLogicalOverlaps = overlaps2.filter((candidate2) => candidate2.logical?.id === logical.id);
|
|
357408
358269
|
return !sameLogicalOverlaps.some((candidate2) => candidate2.coverage === "partial");
|
|
357409
358270
|
}
|
|
357410
358271
|
function isLogicalRangeDecideTarget(target) {
|
|
@@ -358159,7 +359020,7 @@ function extractStructuralCellTexts(xml, side) {
|
|
|
358159
359020
|
}
|
|
358160
359021
|
function extractStructuralText(xml, side) {
|
|
358161
359022
|
const readText = side === "deleted" ? extractTrackedTextFromXml : extractVisibleTextFromXml2;
|
|
358162
|
-
const paragraphs = scanParagraphXmlSpans({ bytes:
|
|
359023
|
+
const paragraphs = scanParagraphXmlSpans({ bytes: TEXT_ENCODER2.encode(xml) });
|
|
358163
359024
|
if (paragraphs.length === 0)
|
|
358164
359025
|
return readText(xml);
|
|
358165
359026
|
return paragraphs.map((paragraph4) => readText(paragraph4.xml).trim()).filter(Boolean).join(`
|
|
@@ -358734,8 +359595,8 @@ function structuralFieldSemanticSubtype(entry, context, resolveSession) {
|
|
|
358734
359595
|
if (!partBytes)
|
|
358735
359596
|
return null;
|
|
358736
359597
|
const partXml = decodeTrackedChangePartXml(partBytes, entry.partUri, resolveSession);
|
|
358737
|
-
const entryByteStart =
|
|
358738
|
-
const entryByteEnd =
|
|
359598
|
+
const entryByteStart = TEXT_ENCODER2.encode(partXml.slice(0, entry.documentOrderStart)).byteLength;
|
|
359599
|
+
const entryByteEnd = TEXT_ENCODER2.encode(partXml.slice(0, entry.documentOrderEnd)).byteLength;
|
|
358739
359600
|
const fields = catalog.fields.filter((candidate2) => candidate2.complete && candidate2.byteStart >= entryByteStart && candidate2.byteEnd <= entryByteEnd);
|
|
358740
359601
|
const field = fields.length === 1 ? fields[0] : undefined;
|
|
358741
359602
|
const subtype = field && field.classification !== "unknown" ? field.classification : null;
|
|
@@ -359070,8 +359931,8 @@ function createSuccessorRsidAllocator(raw) {
|
|
|
359070
359931
|
return counter.toString(16).toUpperCase().padStart(8, "0");
|
|
359071
359932
|
};
|
|
359072
359933
|
}
|
|
359073
|
-
var resolvedTrackedChangeIdsBySession,
|
|
359074
|
-
var
|
|
359934
|
+
var resolvedTrackedChangeIdsBySession, TEXT_ENCODER2, EMUS_PER_CSS_PIXEL = 9525, BROWSER_RENDERABLE_IMAGE_CONTENT_TYPES, DocumentApiAdapterError, STRUCTURAL_DESCRIPTOR_OPERATIONS;
|
|
359935
|
+
var init_adapter23 = __esm(() => {
|
|
359075
359936
|
init_review_read_model();
|
|
359076
359937
|
init_review_read_model();
|
|
359077
359938
|
init_src3();
|
|
@@ -359087,7 +359948,7 @@ var init_adapter22 = __esm(() => {
|
|
|
359087
359948
|
init_logical_view_cache();
|
|
359088
359949
|
init_local_text_projection();
|
|
359089
359950
|
resolvedTrackedChangeIdsBySession = new WeakMap;
|
|
359090
|
-
|
|
359951
|
+
TEXT_ENCODER2 = new TextEncoder;
|
|
359091
359952
|
BROWSER_RENDERABLE_IMAGE_CONTENT_TYPES = new Map([
|
|
359092
359953
|
["png", "image/png"],
|
|
359093
359954
|
["jpg", "image/jpeg"],
|
|
@@ -361940,7 +362801,7 @@ var init_legacy_body = __esm(() => {
|
|
|
361940
362801
|
init_src3();
|
|
361941
362802
|
init_document_reader();
|
|
361942
362803
|
init_adapter();
|
|
361943
|
-
|
|
362804
|
+
init_adapter23();
|
|
361944
362805
|
init_sd_document_session_internal();
|
|
361945
362806
|
init_payloads();
|
|
361946
362807
|
});
|
|
@@ -364798,13 +365659,13 @@ function stripRootReplayNamespaceDeclarations(xml) {
|
|
|
364798
365659
|
return stripReplayNamespaceDeclarations(xml.slice(0, openEnd)) + xml.slice(openEnd);
|
|
364799
365660
|
}
|
|
364800
365661
|
var FULL_DIFF_APPLY_SUPPORTED_FAMILIES, TE65, TD109, DOCUMENT_PART_URI6 = "/word/document.xml", NUMBERING_PART_URI4 = "/word/numbering.xml", EMPTY_MAIN_DOCUMENT_SOURCE, WORDPROCESSINGML_NS7 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", WORDPROCESSINGML_2010_NS2 = "http://schemas.microsoft.com/office/word/2010/wordml", WORDPROCESSING_MATH_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math", MARKUP_COMPATIBILITY_NS3 = "http://schemas.openxmlformats.org/markup-compatibility/2006", VML_NS = "urn:schemas-microsoft-com:vml", STRUCTURAL_PARA_EDIT_DELETE_WML_NAMES, STRUCTURAL_PARA_EDIT_DELETE_MATH_NAMES, STRUCTURAL_PARA_FORMAT_EDIT_WML_NAMES;
|
|
364801
|
-
var
|
|
365662
|
+
var init_adapter24 = __esm(() => {
|
|
364802
365663
|
init_tracked_table_property_replay();
|
|
364803
365664
|
init_src2();
|
|
364804
365665
|
init_compare();
|
|
364805
365666
|
init_sd_document_session_internal();
|
|
364806
365667
|
init_section_xml();
|
|
364807
|
-
|
|
365668
|
+
init_adapter23();
|
|
364808
365669
|
init_header_footer_lifecycle();
|
|
364809
365670
|
init_errors8();
|
|
364810
365671
|
init_main_document_revision_closure();
|
|
@@ -364912,7 +365773,7 @@ class V2ExportAdapter {
|
|
|
364912
365773
|
};
|
|
364913
365774
|
}
|
|
364914
365775
|
}
|
|
364915
|
-
var
|
|
365776
|
+
var init_adapter25 = __esm(() => {
|
|
364916
365777
|
init_src3();
|
|
364917
365778
|
init_sd_document_session_internal();
|
|
364918
365779
|
});
|
|
@@ -365373,9 +366234,9 @@ function operationError10(code2, message) {
|
|
|
365373
366234
|
error48.code = code2;
|
|
365374
366235
|
return error48;
|
|
365375
366236
|
}
|
|
365376
|
-
var
|
|
366237
|
+
var init_adapter26 = __esm(() => {
|
|
365377
366238
|
init_src3();
|
|
365378
|
-
|
|
366239
|
+
init_adapter16();
|
|
365379
366240
|
init_adapter8();
|
|
365380
366241
|
init_tracked_field_prefix();
|
|
365381
366242
|
init_tracked_generated_paragraph();
|
|
@@ -370422,7 +371283,7 @@ function readCreatedParagraphRefId(createdRefs, provisionalToFinal) {
|
|
|
370422
371283
|
return null;
|
|
370423
371284
|
}
|
|
370424
371285
|
var LISTS_XML_DECODER, BULLET_GLYPH_BY_LEVEL;
|
|
370425
|
-
var
|
|
371286
|
+
var init_adapter27 = __esm(() => {
|
|
370426
371287
|
init_src3();
|
|
370427
371288
|
init_sd_document_session_internal();
|
|
370428
371289
|
init_adapter();
|
|
@@ -370430,7 +371291,7 @@ var init_adapter26 = __esm(() => {
|
|
|
370430
371291
|
init_stories();
|
|
370431
371292
|
init_text_range_shifts();
|
|
370432
371293
|
init_adapter7();
|
|
370433
|
-
|
|
371294
|
+
init_adapter23();
|
|
370434
371295
|
init_tracked_pr_change();
|
|
370435
371296
|
init_receipt_entities();
|
|
370436
371297
|
init_runtime3();
|
|
@@ -370462,7 +371323,7 @@ class V2GetTextAdapter {
|
|
|
370462
371323
|
}
|
|
370463
371324
|
}
|
|
370464
371325
|
var TD111, extractVisibleTextFromXml4;
|
|
370465
|
-
var
|
|
371326
|
+
var init_adapter28 = __esm(() => {
|
|
370466
371327
|
init_sd_document_session_internal();
|
|
370467
371328
|
init_story_identity();
|
|
370468
371329
|
init_story_surface();
|
|
@@ -370770,7 +371631,7 @@ var init_node_discovery = __esm(() => {
|
|
|
370770
371631
|
init_sd_document_session_internal();
|
|
370771
371632
|
init_document_reader();
|
|
370772
371633
|
init_paragraph();
|
|
370773
|
-
|
|
371634
|
+
init_adapter28();
|
|
370774
371635
|
init_note_story();
|
|
370775
371636
|
init_textbox_story();
|
|
370776
371637
|
init_within();
|
|
@@ -371809,7 +372670,7 @@ function txIdPrefixToOperation(prefix) {
|
|
|
371809
372670
|
}
|
|
371810
372671
|
}
|
|
371811
372672
|
var TD113, TE67;
|
|
371812
|
-
var
|
|
372673
|
+
var init_adapter29 = __esm(() => {
|
|
371813
372674
|
init_sd_document_session_internal();
|
|
371814
372675
|
init_src6();
|
|
371815
372676
|
init_materialize_slot();
|
|
@@ -373606,7 +374467,7 @@ var init_engine3 = __esm(() => {
|
|
|
373606
374467
|
init_tracked_text_search();
|
|
373607
374468
|
init_structural_rewrite_span();
|
|
373608
374469
|
init_adapter7();
|
|
373609
|
-
|
|
374470
|
+
init_adapter29();
|
|
373610
374471
|
init_adapter6();
|
|
373611
374472
|
init_composite();
|
|
373612
374473
|
init_stories();
|
|
@@ -373628,7 +374489,7 @@ class V2MutationsAdapter {
|
|
|
373628
374489
|
return applyPlan(this.context, input);
|
|
373629
374490
|
}
|
|
373630
374491
|
}
|
|
373631
|
-
var
|
|
374492
|
+
var init_adapter30 = __esm(() => {
|
|
373632
374493
|
init_engine3();
|
|
373633
374494
|
});
|
|
373634
374495
|
|
|
@@ -373762,7 +374623,7 @@ function deleteFailure(code2, message) {
|
|
|
373762
374623
|
return { success: false, failure: { code: code2, message } };
|
|
373763
374624
|
}
|
|
373764
374625
|
var OPERATION_ID = "v2-textbox-geometry";
|
|
373765
|
-
var
|
|
374626
|
+
var init_adapter31 = __esm(() => {
|
|
373766
374627
|
init_sd_document_session_internal();
|
|
373767
374628
|
init_adapter();
|
|
373768
374629
|
init_stories();
|
|
@@ -374299,7 +375160,7 @@ function containsOnlyZeroWidthReferenceTail(xml) {
|
|
|
374299
375160
|
return normalized.length === 0;
|
|
374300
375161
|
}
|
|
374301
375162
|
var TD115;
|
|
374302
|
-
var
|
|
375163
|
+
var init_adapter32 = __esm(() => {
|
|
374303
375164
|
init_sd_document_session_internal();
|
|
374304
375165
|
init_materialize_slot();
|
|
374305
375166
|
init_story_surface();
|
|
@@ -374855,9 +375716,9 @@ function operationError11(code2, message) {
|
|
|
374855
375716
|
error48.code = code2;
|
|
374856
375717
|
return error48;
|
|
374857
375718
|
}
|
|
374858
|
-
var
|
|
375719
|
+
var init_adapter33 = __esm(() => {
|
|
374859
375720
|
init_src3();
|
|
374860
|
-
|
|
375721
|
+
init_adapter16();
|
|
374861
375722
|
init_adapter8();
|
|
374862
375723
|
init_tracked_field_prefix();
|
|
374863
375724
|
init_tracked_generated_paragraph();
|
|
@@ -376195,7 +377056,7 @@ function defaultRelationshipsXml3() {
|
|
|
376195
377056
|
return '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>';
|
|
376196
377057
|
}
|
|
376197
377058
|
var HYPERLINK_REL_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", TD116, TE68;
|
|
376198
|
-
var
|
|
377059
|
+
var init_adapter34 = __esm(() => {
|
|
376199
377060
|
init_sd_document_session_internal();
|
|
376200
377061
|
init_inline();
|
|
376201
377062
|
init_adapter();
|
|
@@ -376954,12 +377815,12 @@ function failure22(code2, message) {
|
|
|
376954
377815
|
return { success: false, failure: { code: code2, message } };
|
|
376955
377816
|
}
|
|
376956
377817
|
var IMAGE_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", RELATIONSHIPS_CT2 = "application/vnd.openxmlformats-package.relationships+xml", EMPTY_RELATIONSHIPS_XML4, TD117;
|
|
376957
|
-
var
|
|
377818
|
+
var init_adapter35 = __esm(() => {
|
|
376958
377819
|
init_src3();
|
|
376959
377820
|
init_sd_document_session_internal();
|
|
376960
377821
|
init_document_reader();
|
|
376961
377822
|
init_adapter3();
|
|
376962
|
-
|
|
377823
|
+
init_adapter18();
|
|
376963
377824
|
init_public_model();
|
|
376964
377825
|
init_section_xml();
|
|
376965
377826
|
init_xml();
|
|
@@ -378037,7 +378898,7 @@ function structuredError4(code2, message) {
|
|
|
378037
378898
|
return error48;
|
|
378038
378899
|
}
|
|
378039
378900
|
var W14_NS4 = "http://schemas.microsoft.com/office/word/2010/wordml", FOOTNOTES_PART_URI4 = "/word/footnotes.xml", ENDNOTES_PART_URI4 = "/word/endnotes.xml", FOOTNOTES_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml", ENDNOTES_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml", FOOTNOTES_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes", ENDNOTES_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes";
|
|
378040
|
-
var
|
|
378901
|
+
var init_adapter36 = __esm(() => {
|
|
378041
378902
|
init_src3();
|
|
378042
378903
|
init_tracked_pr_change();
|
|
378043
378904
|
init_tracked_structural_wrapper();
|
|
@@ -382013,7 +382874,7 @@ function isPasteReason(reason) {
|
|
|
382013
382874
|
return !!reason && reason.startsWith("paste-");
|
|
382014
382875
|
}
|
|
382015
382876
|
var CLIPBOARD_TD;
|
|
382016
|
-
var
|
|
382877
|
+
var init_adapter37 = __esm(() => {
|
|
382017
382878
|
init_src3();
|
|
382018
382879
|
init_sd_document_session_internal();
|
|
382019
382880
|
init_note_story();
|
|
@@ -382065,7 +382926,7 @@ class V2SelectionAdapter {
|
|
|
382065
382926
|
};
|
|
382066
382927
|
}
|
|
382067
382928
|
}
|
|
382068
|
-
var
|
|
382929
|
+
var init_adapter38 = __esm(() => {
|
|
382069
382930
|
init_sd_document_session_internal();
|
|
382070
382931
|
});
|
|
382071
382932
|
|
|
@@ -382213,651 +383074,6 @@ var init_clear_content_adapter = __esm(() => {
|
|
|
382213
383074
|
TE69 = new TextEncoder;
|
|
382214
383075
|
});
|
|
382215
383076
|
|
|
382216
|
-
// ../../../v2/document-api-v2-adapter/dist/metadata/adapter.js
|
|
382217
|
-
class V2AnchoredMetadataAdapter {
|
|
382218
|
-
constructor(context) {
|
|
382219
|
-
this.context = context;
|
|
382220
|
-
}
|
|
382221
|
-
attach(input, options) {
|
|
382222
|
-
const mutationGuard = guardDirectOnlyMutation(this.context, input, options);
|
|
382223
|
-
if (mutationGuard)
|
|
382224
|
-
return mutationGuard;
|
|
382225
|
-
const id = input.id ?? newOpaqueId("metadata");
|
|
382226
|
-
const existingRecords = listMetadataRecords(this.context);
|
|
382227
|
-
if (existingRecords.some((record3) => record3.id === id)) {
|
|
382228
|
-
throw operationError("INVALID_INPUT", `metadata id ${id} already exists.`);
|
|
382229
|
-
}
|
|
382230
|
-
const payloadJson = JSON.stringify(input.payload);
|
|
382231
|
-
if (payloadJson === undefined)
|
|
382232
|
-
throw operationError("INVALID_INPUT", "metadata payload must be JSON serializable.");
|
|
382233
|
-
const documentXml = readDocumentXml(this.context);
|
|
382234
|
-
if (findMetadataAnchor(documentXml, id)) {
|
|
382235
|
-
throw operationError("INVALID_INPUT", `metadata id ${id} already exists.`);
|
|
382236
|
-
}
|
|
382237
|
-
const resolvedSegments = input.target.kind === "text" ? resolveMultiSegmentTarget(documentXml, input.target) : resolveSingleSegmentTarget(this.context, documentXml, input.target);
|
|
382238
|
-
if ("error" in resolvedSegments)
|
|
382239
|
-
throw operationError(resolvedSegments.error, resolvedSegments.message);
|
|
382240
|
-
const knownIds = new Set(existingRecords.map((record3) => record3.id));
|
|
382241
|
-
if (hasOverlappingMetadataAnchor(documentXml, resolvedSegments.segments, knownIds)) {
|
|
382242
|
-
return failure2("INVALID_TARGET", "metadata.attach target overlaps an existing metadata anchor.");
|
|
382243
|
-
}
|
|
382244
|
-
const existingPart = ensureCustomXmlPartForNamespace(this.context, input.namespace);
|
|
382245
|
-
const allocatedPart = existingPart ? null : allocateCustomXmlPartNames(this.context);
|
|
382246
|
-
const partName = existingPart?.partName ?? allocatedPart.partName;
|
|
382247
|
-
const partUri = existingPart?.partUri ?? allocatedPart.partUri;
|
|
382248
|
-
const storageXml = existingPart?.content ?? buildMetadataStorageXml(input.namespace, []);
|
|
382249
|
-
const refs = readMetadataRefs(storageXml, input.namespace);
|
|
382250
|
-
refs.push({ id, payloadJson });
|
|
382251
|
-
const nextStorageXml = buildMetadataStorageXml(input.namespace, refs);
|
|
382252
|
-
const sdtIds = allocateMetadataSdtIds(documentXml, resolvedSegments.segments.length);
|
|
382253
|
-
const bySegmentPosition = resolvedSegments.segments.map((segment, index2) => ({ segment, sdtId: sdtIds[index2] })).sort((a, b) => b.segment.para.start - a.segment.para.start);
|
|
382254
|
-
let nextDocumentXml = documentXml;
|
|
382255
|
-
for (const { segment, sdtId } of bySegmentPosition) {
|
|
382256
|
-
const wrapped = wrapTextRangeWithMetadataSdt(segment.para.xml, segment.startOffset, segment.endOffset, id, sdtId);
|
|
382257
|
-
if (!wrapped.ok)
|
|
382258
|
-
throw metadataWrapRejectError(wrapped.reason);
|
|
382259
|
-
nextDocumentXml = replaceRange3(nextDocumentXml, segment.para.start, segment.para.end, wrapped.xml);
|
|
382260
|
-
}
|
|
382261
|
-
if (!dryRunRequested(input, options)) {
|
|
382262
|
-
nextDocumentXml = ensureW15Namespace(nextDocumentXml);
|
|
382263
|
-
const updates = existingPart ? { [partUri]: encodeXml(nextStorageXml) } : buildCustomXmlCreateUpdates(this.context, {
|
|
382264
|
-
id: newGuid(),
|
|
382265
|
-
content: nextStorageXml,
|
|
382266
|
-
partUri,
|
|
382267
|
-
propsPartUri: allocatedPart.propsPartUri,
|
|
382268
|
-
relsPartUri: allocatedPart.relsPartUri
|
|
382269
|
-
});
|
|
382270
|
-
updates[DOCUMENT_PART_URI5] = encodeXml(nextDocumentXml);
|
|
382271
|
-
const committed = commitWholePartUpdates(this.context, "metadata-attach", updates, {
|
|
382272
|
-
expectedRevision: expectedRevisionFrom(input, options),
|
|
382273
|
-
storySurface: {
|
|
382274
|
-
family: "storyAnchor",
|
|
382275
|
-
targetBlockIds: resolvedSegments.segments.map((segment) => segment.blockId)
|
|
382276
|
-
}
|
|
382277
|
-
});
|
|
382278
|
-
if (!committed.ok)
|
|
382279
|
-
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
382280
|
-
}
|
|
382281
|
-
return { success: true, id, namespace: input.namespace, partName };
|
|
382282
|
-
}
|
|
382283
|
-
list(query3) {
|
|
382284
|
-
let records = listMetadataRecords(this.context);
|
|
382285
|
-
const recordCounts = new Map;
|
|
382286
|
-
for (const record3 of records)
|
|
382287
|
-
recordCounts.set(record3.id, (recordCounts.get(record3.id) ?? 0) + 1);
|
|
382288
|
-
if (query3?.namespace !== undefined)
|
|
382289
|
-
records = records.filter((record3) => record3.namespace === query3.namespace);
|
|
382290
|
-
const documentXml = readDocumentXml(this.context);
|
|
382291
|
-
if (query3?.resolvedOnly === true) {
|
|
382292
|
-
records = records.filter((record3) => recordCounts.get(record3.id) === 1 && groupMetadataAnchor(documentXml, record3.id, new Set([record3.id])) !== null);
|
|
382293
|
-
}
|
|
382294
|
-
if (query3?.within !== undefined) {
|
|
382295
|
-
records = records.filter((record3) => {
|
|
382296
|
-
const resolved = this.resolve({ id: record3.id });
|
|
382297
|
-
return resolved ? overlaps(query3.within, resolved.target) : false;
|
|
382298
|
-
});
|
|
382299
|
-
}
|
|
382300
|
-
const page = pageSlice(records, query3);
|
|
382301
|
-
return buildDiscoveryResult({
|
|
382302
|
-
evaluatedRevision: this.context.currentPublicRevision(),
|
|
382303
|
-
total: records.length,
|
|
382304
|
-
items: page.items.map((record3) => buildDiscoveryItem(record3.id, buildResolvedHandle(`metadata:${record3.id}`, "stable", "ext:metadata"), metadataSummary(record3, documentXml))),
|
|
382305
|
-
page: { offset: page.offset, limit: page.limit, returned: page.items.length }
|
|
382306
|
-
});
|
|
382307
|
-
}
|
|
382308
|
-
get(input) {
|
|
382309
|
-
const record3 = findMetadataRecord(this.context, input.id);
|
|
382310
|
-
return record3 ? { ...metadataSummary(record3, readDocumentXml(this.context)), payload: record3.payload } : null;
|
|
382311
|
-
}
|
|
382312
|
-
update(input, options) {
|
|
382313
|
-
const mutationGuard = guardDirectOnlyMutation(this.context, input, options);
|
|
382314
|
-
if (mutationGuard)
|
|
382315
|
-
return mutationGuard;
|
|
382316
|
-
if (listMetadataRecords(this.context).filter((candidate2) => candidate2.id === input.id).length > 1) {
|
|
382317
|
-
return failure2("INVALID_TARGET", `metadata ${input.id} has ambiguous payload records.`);
|
|
382318
|
-
}
|
|
382319
|
-
const record3 = findMetadataRecord(this.context, input.id);
|
|
382320
|
-
if (!record3)
|
|
382321
|
-
throw operationError("TARGET_NOT_FOUND", `metadata ${input.id} not found.`);
|
|
382322
|
-
const payloadJson = JSON.stringify(input.payload);
|
|
382323
|
-
if (payloadJson === undefined)
|
|
382324
|
-
throw operationError("INVALID_INPUT", "metadata payload must be JSON serializable.");
|
|
382325
|
-
if (dryRunRequested(input, options))
|
|
382326
|
-
return { success: true, id: input.id };
|
|
382327
|
-
const records = listMetadataRecords(this.context).filter((candidate2) => candidate2.partUri === record3.partUri);
|
|
382328
|
-
const refs = records.map((candidate2) => ({
|
|
382329
|
-
id: candidate2.id,
|
|
382330
|
-
payloadJson: candidate2.id === input.id ? payloadJson : JSON.stringify(candidate2.payload)
|
|
382331
|
-
}));
|
|
382332
|
-
const committed = commitWholePartUpdates(this.context, "metadata-update", { [record3.partUri]: encodeXml(buildMetadataStorageXml(record3.namespace, refs)) }, { expectedRevision: expectedRevisionFrom(input, options) });
|
|
382333
|
-
if (!committed.ok)
|
|
382334
|
-
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
382335
|
-
return { success: true, id: input.id };
|
|
382336
|
-
}
|
|
382337
|
-
remove(input, options) {
|
|
382338
|
-
const mutationGuard = guardDirectOnlyMutation(this.context, input, options);
|
|
382339
|
-
if (mutationGuard)
|
|
382340
|
-
return mutationGuard;
|
|
382341
|
-
if (listMetadataRecords(this.context).filter((candidate2) => candidate2.id === input.id).length > 1) {
|
|
382342
|
-
return failure2("INVALID_TARGET", `metadata ${input.id} has ambiguous payload records.`);
|
|
382343
|
-
}
|
|
382344
|
-
const record3 = findMetadataRecord(this.context, input.id);
|
|
382345
|
-
if (!record3)
|
|
382346
|
-
throw operationError("TARGET_NOT_FOUND", `metadata ${input.id} not found.`);
|
|
382347
|
-
const documentXml = readDocumentXml(this.context);
|
|
382348
|
-
const knownIds = new Set(listMetadataRecords(this.context).map((candidate2) => candidate2.id));
|
|
382349
|
-
const matchingAnchors = listMetadataAnchors(documentXml, knownIds).filter((anchor) => anchor.id === input.id);
|
|
382350
|
-
const grouped = groupMetadataAnchor(documentXml, input.id, knownIds);
|
|
382351
|
-
if (matchingAnchors.length > 0 && !grouped) {
|
|
382352
|
-
return { success: false, failure: { code: "INVALID_TARGET", message: `metadata ${input.id} has ambiguous anchors.` } };
|
|
382353
|
-
}
|
|
382354
|
-
if (dryRunRequested(input, options))
|
|
382355
|
-
return { success: true, id: input.id };
|
|
382356
|
-
const updates = {};
|
|
382357
|
-
if (grouped) {
|
|
382358
|
-
const bySegmentPosition = [...grouped.segments].sort((a, b) => b.start - a.start);
|
|
382359
|
-
let nextDocumentXml = documentXml;
|
|
382360
|
-
for (const anchor of bySegmentPosition) {
|
|
382361
|
-
if (anchor.unmatched)
|
|
382362
|
-
continue;
|
|
382363
|
-
const unwrapped = unwrapSdt(anchor.xml);
|
|
382364
|
-
if (unwrapped === null)
|
|
382365
|
-
continue;
|
|
382366
|
-
nextDocumentXml = replaceRange3(nextDocumentXml, anchor.start, anchor.end, unwrapped);
|
|
382367
|
-
}
|
|
382368
|
-
if (nextDocumentXml !== documentXml)
|
|
382369
|
-
updates[DOCUMENT_PART_URI5] = encodeXml(nextDocumentXml);
|
|
382370
|
-
}
|
|
382371
|
-
const remaining = listMetadataRecords(this.context).filter((candidate2) => candidate2.partUri === record3.partUri && candidate2.id !== input.id).map((candidate2) => ({ id: candidate2.id, payloadJson: JSON.stringify(candidate2.payload) }));
|
|
382372
|
-
const targetBlockIds2 = grouped ? grouped.segments.map((anchor) => anchor.blockId) : undefined;
|
|
382373
|
-
if (remaining.length > 0) {
|
|
382374
|
-
updates[record3.partUri] = encodeXml(buildMetadataStorageXml(record3.namespace, remaining));
|
|
382375
|
-
const committed = commitWholePartUpdates(this.context, "metadata-remove", updates, {
|
|
382376
|
-
expectedRevision: expectedRevisionFrom(input, options),
|
|
382377
|
-
...targetBlockIds2 ? { storySurface: { family: "storyAnchor", targetBlockIds: targetBlockIds2 } } : {}
|
|
382378
|
-
});
|
|
382379
|
-
if (!committed.ok)
|
|
382380
|
-
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
382381
|
-
} else {
|
|
382382
|
-
Object.assign(updates, buildCustomXmlRemoveUpdates(this.context, record3));
|
|
382383
|
-
const committed = commitWholePartUpdates(this.context, "metadata-remove", updates, {
|
|
382384
|
-
expectedRevision: expectedRevisionFrom(input, options),
|
|
382385
|
-
...targetBlockIds2 ? { storySurface: { family: "storyAnchor", targetBlockIds: targetBlockIds2 } } : {}
|
|
382386
|
-
});
|
|
382387
|
-
if (!committed.ok)
|
|
382388
|
-
return { success: false, failure: { code: committed.code, message: committed.message } };
|
|
382389
|
-
}
|
|
382390
|
-
return { success: true, id: input.id };
|
|
382391
|
-
}
|
|
382392
|
-
resolve(input) {
|
|
382393
|
-
const record3 = findMetadataRecord(this.context, input.id);
|
|
382394
|
-
if (!record3)
|
|
382395
|
-
return null;
|
|
382396
|
-
const knownIds = new Set(listMetadataRecords(this.context).map((candidate2) => candidate2.id));
|
|
382397
|
-
const grouped = groupMetadataAnchor(readDocumentXml(this.context), input.id, knownIds);
|
|
382398
|
-
if (!grouped)
|
|
382399
|
-
return null;
|
|
382400
|
-
return { id: input.id, target: grouped.target };
|
|
382401
|
-
}
|
|
382402
|
-
}
|
|
382403
|
-
function listMetadataRecords(context) {
|
|
382404
|
-
const out = [];
|
|
382405
|
-
for (const part of listCustomXmlRecords(context)) {
|
|
382406
|
-
if (!part.rootNamespace || !/^<refs\b/.test(part.content.replace(/^<\?xml[^>]*>/, "").trim()))
|
|
382407
|
-
continue;
|
|
382408
|
-
for (const ref5 of readMetadataRefs(part.content, part.rootNamespace)) {
|
|
382409
|
-
let payload = null;
|
|
382410
|
-
try {
|
|
382411
|
-
payload = JSON.parse(ref5.payloadJson);
|
|
382412
|
-
} catch {
|
|
382413
|
-
payload = null;
|
|
382414
|
-
}
|
|
382415
|
-
out.push({
|
|
382416
|
-
id: ref5.id,
|
|
382417
|
-
namespace: part.rootNamespace,
|
|
382418
|
-
partName: part.partName,
|
|
382419
|
-
partUri: part.partUri,
|
|
382420
|
-
...part.propsPartUri ? { propsPartUri: part.propsPartUri } : {},
|
|
382421
|
-
payload
|
|
382422
|
-
});
|
|
382423
|
-
}
|
|
382424
|
-
}
|
|
382425
|
-
return out;
|
|
382426
|
-
}
|
|
382427
|
-
function findMetadataRecord(context, id) {
|
|
382428
|
-
const matches = listMetadataRecords(context).filter((record3) => record3.id === id);
|
|
382429
|
-
return matches.length === 1 ? matches[0] : null;
|
|
382430
|
-
}
|
|
382431
|
-
function metadataSummary(record3, documentXml) {
|
|
382432
|
-
return {
|
|
382433
|
-
id: record3.id,
|
|
382434
|
-
namespace: record3.namespace,
|
|
382435
|
-
partName: record3.partName,
|
|
382436
|
-
anchorStatus: groupMetadataAnchor(documentXml, record3.id, new Set([record3.id])) ? "resolved" : "orphan"
|
|
382437
|
-
};
|
|
382438
|
-
}
|
|
382439
|
-
function readMetadataRefs(xml, _namespace) {
|
|
382440
|
-
const refs = [];
|
|
382441
|
-
const re = /<ref\b[^>]*\bid="([^"]*)"[^>]*>([\s\S]*?)<\/ref>/g;
|
|
382442
|
-
for (let match = re.exec(xml);match; match = re.exec(xml)) {
|
|
382443
|
-
refs.push({ id: decodeXmlEntities(match[1]), payloadJson: decodeXmlEntities(match[2]) });
|
|
382444
|
-
}
|
|
382445
|
-
return refs;
|
|
382446
|
-
}
|
|
382447
|
-
function findMetadataAnchor(documentXml, id) {
|
|
382448
|
-
return listMetadataAnchors(documentXml, new Set([id])).find((anchor) => anchor.id === id) ?? null;
|
|
382449
|
-
}
|
|
382450
|
-
function listMetadataAnchors(documentXml, knownIds) {
|
|
382451
|
-
const anchors = [];
|
|
382452
|
-
for (const sdt of listSdtRanges(documentXml)) {
|
|
382453
|
-
const pr = ownSdtPr(sdt.xml);
|
|
382454
|
-
const tag = attrValue(/<w:tag\b[^>]*\/>/.exec(pr)?.[0] ?? "", "val");
|
|
382455
|
-
if (!tag || !isMetadataAnchorPr(pr, tag, knownIds))
|
|
382456
|
-
continue;
|
|
382457
|
-
const anchor = materializeMetadataAnchor(documentXml, sdt, tag);
|
|
382458
|
-
if (anchor)
|
|
382459
|
-
anchors.push(anchor);
|
|
382460
|
-
}
|
|
382461
|
-
return anchors.sort((left, right) => left.start - right.start);
|
|
382462
|
-
}
|
|
382463
|
-
function ownSdtPr(sdtXml) {
|
|
382464
|
-
const openTag = /<w:sdt\b[^>]*>/.exec(sdtXml);
|
|
382465
|
-
if (!openTag)
|
|
382466
|
-
return "";
|
|
382467
|
-
const headStart = openTag.index + openTag[0].length;
|
|
382468
|
-
const contentOrNested = /<w:sdtContent\b[^>]*>|<w:sdt\b[^>]*>/.exec(sdtXml.slice(headStart));
|
|
382469
|
-
const head = contentOrNested ? sdtXml.slice(headStart, headStart + contentOrNested.index) : sdtXml.slice(headStart);
|
|
382470
|
-
return /<w:sdtPr\b[^>]*>[\s\S]*?<\/w:sdtPr>/.exec(head)?.[0] ?? "";
|
|
382471
|
-
}
|
|
382472
|
-
function listSdtRanges(documentXml) {
|
|
382473
|
-
const ranges = [];
|
|
382474
|
-
const stack = [];
|
|
382475
|
-
const tokenRe = /<w:sdt\b[^>]*>|<\/w:sdt>/g;
|
|
382476
|
-
for (let match = tokenRe.exec(documentXml);match; match = tokenRe.exec(documentXml)) {
|
|
382477
|
-
if (match[0].startsWith("</")) {
|
|
382478
|
-
const start = stack.pop();
|
|
382479
|
-
if (start === undefined)
|
|
382480
|
-
continue;
|
|
382481
|
-
const end = tokenRe.lastIndex;
|
|
382482
|
-
ranges.push({ start, end, xml: documentXml.slice(start, end) });
|
|
382483
|
-
} else if (/\/\s*>$/.test(match[0])) {
|
|
382484
|
-
ranges.push({ start: match.index, end: tokenRe.lastIndex, xml: match[0] });
|
|
382485
|
-
} else {
|
|
382486
|
-
stack.push(match.index);
|
|
382487
|
-
}
|
|
382488
|
-
}
|
|
382489
|
-
for (const start of stack) {
|
|
382490
|
-
const end = unmatchedSdtExtent(documentXml, start);
|
|
382491
|
-
ranges.push({ start, end, xml: documentXml.slice(start, end), unmatched: true });
|
|
382492
|
-
}
|
|
382493
|
-
return ranges.sort((left, right) => left.start - right.start);
|
|
382494
|
-
}
|
|
382495
|
-
function unmatchedSdtExtent(documentXml, start) {
|
|
382496
|
-
const paraClose = documentXml.indexOf("</w:p>", start);
|
|
382497
|
-
return paraClose === -1 ? documentXml.length : paraClose;
|
|
382498
|
-
}
|
|
382499
|
-
function isMetadataAnchorPr(pr, tag, knownIds) {
|
|
382500
|
-
const alias = attrValue(/<w:alias\b[^>]*\/>/.exec(pr)?.[0] ?? "", "val");
|
|
382501
|
-
if (alias !== null && alias !== METADATA_ANCHOR_ALIAS)
|
|
382502
|
-
return false;
|
|
382503
|
-
const hasHiddenAppearance = attrValue(/<w15:appearance\b[^>]*\/>/.exec(pr)?.[0] ?? "", "val") === "hidden";
|
|
382504
|
-
const hasPlainTextPr = /<w:text\b/.test(pr);
|
|
382505
|
-
return knownIds.has(tag) && hasHiddenAppearance && hasPlainTextPr;
|
|
382506
|
-
}
|
|
382507
|
-
function materializeMetadataAnchor(documentXml, sdt, id) {
|
|
382508
|
-
const para = findParagraphContaining2(documentXml, sdt.start);
|
|
382509
|
-
if (!para)
|
|
382510
|
-
return null;
|
|
382511
|
-
const startOffset = extractVisibleTextFromXml2(para.xml.slice(0, sdt.start - para.start)).length;
|
|
382512
|
-
const length = extractVisibleTextFromXml2(unwrapSdt(sdt.xml) ?? sdt.xml).length;
|
|
382513
|
-
const endOffset = startOffset + length;
|
|
382514
|
-
return {
|
|
382515
|
-
id,
|
|
382516
|
-
start: sdt.start,
|
|
382517
|
-
end: sdt.end,
|
|
382518
|
-
xml: sdt.xml,
|
|
382519
|
-
blockId: para.blockId,
|
|
382520
|
-
startOffset,
|
|
382521
|
-
endOffset,
|
|
382522
|
-
unmatched: sdt.unmatched === true,
|
|
382523
|
-
target: {
|
|
382524
|
-
kind: "selection",
|
|
382525
|
-
start: { kind: "text", blockId: para.blockId, offset: startOffset, story: bodyStoryLocator2() },
|
|
382526
|
-
end: { kind: "text", blockId: para.blockId, offset: endOffset, story: bodyStoryLocator2() }
|
|
382527
|
-
}
|
|
382528
|
-
};
|
|
382529
|
-
}
|
|
382530
|
-
function groupMetadataAnchor(documentXml, id, knownIds) {
|
|
382531
|
-
const matches = listMetadataAnchors(documentXml, knownIds).filter((anchor) => anchor.id === id);
|
|
382532
|
-
if (matches.length === 0)
|
|
382533
|
-
return null;
|
|
382534
|
-
const kept = contiguousAnchorPrefix(documentXml, matches);
|
|
382535
|
-
if (kept.length !== matches.length)
|
|
382536
|
-
return null;
|
|
382537
|
-
if (kept.length === 1)
|
|
382538
|
-
return { id, segments: kept, target: kept[0].target };
|
|
382539
|
-
const textSegments = [];
|
|
382540
|
-
for (const anchor of kept) {
|
|
382541
|
-
const previous3 = textSegments.at(-1);
|
|
382542
|
-
if (previous3?.blockId === anchor.blockId && previous3.range.end === anchor.startOffset) {
|
|
382543
|
-
previous3.range.end = anchor.endOffset;
|
|
382544
|
-
} else {
|
|
382545
|
-
textSegments.push({ blockId: anchor.blockId, range: { start: anchor.startOffset, end: anchor.endOffset } });
|
|
382546
|
-
}
|
|
382547
|
-
}
|
|
382548
|
-
if (textSegments.length === 1) {
|
|
382549
|
-
const range = textSegments[0];
|
|
382550
|
-
return {
|
|
382551
|
-
id,
|
|
382552
|
-
segments: kept,
|
|
382553
|
-
target: {
|
|
382554
|
-
kind: "selection",
|
|
382555
|
-
start: { kind: "text", blockId: range.blockId, offset: range.range.start, story: bodyStoryLocator2() },
|
|
382556
|
-
end: { kind: "text", blockId: range.blockId, offset: range.range.end, story: bodyStoryLocator2() }
|
|
382557
|
-
}
|
|
382558
|
-
};
|
|
382559
|
-
}
|
|
382560
|
-
return {
|
|
382561
|
-
id,
|
|
382562
|
-
segments: kept,
|
|
382563
|
-
target: { kind: "text", segments: [textSegments[0], ...textSegments.slice(1)] }
|
|
382564
|
-
};
|
|
382565
|
-
}
|
|
382566
|
-
function contiguousAnchorPrefix(documentXml, matches) {
|
|
382567
|
-
if (matches.length <= 1)
|
|
382568
|
-
return [...matches];
|
|
382569
|
-
const map3 = buildStructuralBoundaryMap(TEXT_ENCODER2.encode(documentXml));
|
|
382570
|
-
const first = map3.byBlockId(matches[0].blockId);
|
|
382571
|
-
if (!first)
|
|
382572
|
-
return [matches[0]];
|
|
382573
|
-
const kept = [matches[0]];
|
|
382574
|
-
let prev = first;
|
|
382575
|
-
for (let i2 = 1;i2 < matches.length; i2 += 1) {
|
|
382576
|
-
const context = map3.byBlockId(matches[i2].blockId);
|
|
382577
|
-
if (!context)
|
|
382578
|
-
break;
|
|
382579
|
-
const sameParagraph = context.ordinal === prev.ordinal;
|
|
382580
|
-
if (sameParagraph) {
|
|
382581
|
-
const previousAnchor = kept.at(-1);
|
|
382582
|
-
if (context.blockId !== previousAnchor.blockId || matches[i2].startOffset !== previousAnchor.endOffset || !isMetadataCarrierGap(documentXml.slice(previousAnchor.end, matches[i2].start)))
|
|
382583
|
-
break;
|
|
382584
|
-
} else if (context.ordinal !== prev.ordinal + 1)
|
|
382585
|
-
break;
|
|
382586
|
-
if (!sameTableCellPath(context.tableCellPath, first.tableCellPath))
|
|
382587
|
-
break;
|
|
382588
|
-
if (!sameOrdinalPath2(context.blockSdtPath, first.blockSdtPath))
|
|
382589
|
-
break;
|
|
382590
|
-
if (!sameOrdinalPath2(context.blockCustomXmlPath, first.blockCustomXmlPath))
|
|
382591
|
-
break;
|
|
382592
|
-
if (context.sectionIndex !== first.sectionIndex)
|
|
382593
|
-
break;
|
|
382594
|
-
if (prev.carriesSectionBreak)
|
|
382595
|
-
break;
|
|
382596
|
-
kept.push(matches[i2]);
|
|
382597
|
-
prev = context;
|
|
382598
|
-
}
|
|
382599
|
-
return kept;
|
|
382600
|
-
}
|
|
382601
|
-
function isMetadataCarrierGap(xml) {
|
|
382602
|
-
return /^(?:\s*<w:proofErr\s+w:type="(?:spellStart|spellEnd|gramStart|gramEnd)"\s*\/>)*\s*$/.test(xml);
|
|
382603
|
-
}
|
|
382604
|
-
function sameOrdinalPath2(left, right) {
|
|
382605
|
-
return left.length === right.length && left.every((value2, index2) => value2 === right[index2]);
|
|
382606
|
-
}
|
|
382607
|
-
function resolveSingleSegmentTarget(context, documentXml, target) {
|
|
382608
|
-
const resolved = resolveBodySelectionTarget(context, target);
|
|
382609
|
-
if ("error" in resolved)
|
|
382610
|
-
return resolved;
|
|
382611
|
-
if (resolved.startBlockId !== resolved.endBlockId) {
|
|
382612
|
-
return { error: "INVALID_TARGET", message: "metadata.attach requires a same-paragraph text selection." };
|
|
382613
|
-
}
|
|
382614
|
-
if (resolved.startOffset >= resolved.endOffset) {
|
|
382615
|
-
return { error: "INVALID_TARGET", message: "metadata.attach requires a non-empty text range." };
|
|
382616
|
-
}
|
|
382617
|
-
const para = findParagraphById3(documentXml, resolved.startBlockId);
|
|
382618
|
-
if (!para)
|
|
382619
|
-
return { error: "TARGET_NOT_FOUND", message: `paragraph ${resolved.startBlockId} not found.` };
|
|
382620
|
-
return {
|
|
382621
|
-
segments: [{ blockId: para.blockId, startOffset: resolved.startOffset, endOffset: resolved.endOffset, para }]
|
|
382622
|
-
};
|
|
382623
|
-
}
|
|
382624
|
-
function resolveMultiSegmentTarget(documentXml, target) {
|
|
382625
|
-
if (target.story !== undefined && target.story.storyType !== "body") {
|
|
382626
|
-
return {
|
|
382627
|
-
error: "TARGET_NOT_FOUND",
|
|
382628
|
-
message: "metadata.attach resolves paragraphs against the main document body only."
|
|
382629
|
-
};
|
|
382630
|
-
}
|
|
382631
|
-
if (target.coordinateSpace === "tracked") {
|
|
382632
|
-
return {
|
|
382633
|
-
error: "INVALID_TARGET",
|
|
382634
|
-
message: "metadata.attach does not support a tracked-coordinate-space TextTarget."
|
|
382635
|
-
};
|
|
382636
|
-
}
|
|
382637
|
-
const segments = [];
|
|
382638
|
-
for (const segment of target.segments) {
|
|
382639
|
-
if (segment.range.start >= segment.range.end) {
|
|
382640
|
-
return {
|
|
382641
|
-
error: "INVALID_TARGET",
|
|
382642
|
-
message: "metadata.attach requires a non-empty text range in every TextTarget segment."
|
|
382643
|
-
};
|
|
382644
|
-
}
|
|
382645
|
-
const para = findParagraphById3(documentXml, segment.blockId);
|
|
382646
|
-
if (!para)
|
|
382647
|
-
return { error: "TARGET_NOT_FOUND", message: `paragraph ${segment.blockId} not found.` };
|
|
382648
|
-
segments.push({ blockId: segment.blockId, startOffset: segment.range.start, endOffset: segment.range.end, para });
|
|
382649
|
-
}
|
|
382650
|
-
const boundaryError = validateContiguousStructuralRun(documentXml, segments.map((segment) => segment.blockId));
|
|
382651
|
-
if (boundaryError)
|
|
382652
|
-
return boundaryError;
|
|
382653
|
-
return { segments };
|
|
382654
|
-
}
|
|
382655
|
-
function validateContiguousStructuralRun(documentXml, blockIds) {
|
|
382656
|
-
if (blockIds.length <= 1)
|
|
382657
|
-
return null;
|
|
382658
|
-
const map3 = buildStructuralBoundaryMap(TEXT_ENCODER2.encode(documentXml));
|
|
382659
|
-
const contexts = blockIds.map((blockId) => map3.byBlockId(blockId));
|
|
382660
|
-
const first = contexts[0];
|
|
382661
|
-
if (!first) {
|
|
382662
|
-
return { error: "INVALID_TARGET", message: `paragraph "${blockIds[0]}" is not visible to the structural map.` };
|
|
382663
|
-
}
|
|
382664
|
-
for (let i2 = 1;i2 < contexts.length; i2 += 1) {
|
|
382665
|
-
const context = contexts[i2];
|
|
382666
|
-
const prev = contexts[i2 - 1];
|
|
382667
|
-
if (!context) {
|
|
382668
|
-
return { error: "INVALID_TARGET", message: `paragraph "${blockIds[i2]}" is not visible to the structural map.` };
|
|
382669
|
-
}
|
|
382670
|
-
if (context.ordinal !== prev.ordinal + 1) {
|
|
382671
|
-
return {
|
|
382672
|
-
error: "INVALID_TARGET",
|
|
382673
|
-
message: "metadata.attach TextTarget segments must be contiguous paragraphs in document order."
|
|
382674
|
-
};
|
|
382675
|
-
}
|
|
382676
|
-
if (!sameTableCellPath(context.tableCellPath, first.tableCellPath)) {
|
|
382677
|
-
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a table-cell boundary." };
|
|
382678
|
-
}
|
|
382679
|
-
if (!sameOrdinalPath2(context.blockSdtPath, first.blockSdtPath)) {
|
|
382680
|
-
return {
|
|
382681
|
-
error: "INVALID_TARGET",
|
|
382682
|
-
message: "metadata.attach TextTarget cannot cross a block content-control boundary."
|
|
382683
|
-
};
|
|
382684
|
-
}
|
|
382685
|
-
if (!sameOrdinalPath2(context.blockCustomXmlPath, first.blockCustomXmlPath)) {
|
|
382686
|
-
return {
|
|
382687
|
-
error: "INVALID_TARGET",
|
|
382688
|
-
message: "metadata.attach TextTarget cannot cross a block custom-XML boundary."
|
|
382689
|
-
};
|
|
382690
|
-
}
|
|
382691
|
-
if (context.sectionIndex !== first.sectionIndex) {
|
|
382692
|
-
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a section boundary." };
|
|
382693
|
-
}
|
|
382694
|
-
if (prev.carriesSectionBreak) {
|
|
382695
|
-
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a section boundary." };
|
|
382696
|
-
}
|
|
382697
|
-
}
|
|
382698
|
-
if (contexts[contexts.length - 1].carriesSectionBreak) {
|
|
382699
|
-
return { error: "INVALID_TARGET", message: "metadata.attach TextTarget cannot cross a section boundary." };
|
|
382700
|
-
}
|
|
382701
|
-
return null;
|
|
382702
|
-
}
|
|
382703
|
-
function hasOverlappingMetadataAnchor(documentXml, segments, knownIds) {
|
|
382704
|
-
const anchors = listMetadataAnchors(documentXml, knownIds);
|
|
382705
|
-
return segments.some((segment) => anchors.some((anchor) => anchor.blockId === segment.blockId && rangesStrictlyOverlap(segment.startOffset, segment.endOffset, anchor.startOffset, anchor.endOffset)));
|
|
382706
|
-
}
|
|
382707
|
-
function rangesStrictlyOverlap(leftStart, leftEnd, rightStart, rightEnd) {
|
|
382708
|
-
return leftStart < rightEnd && rightStart < leftEnd;
|
|
382709
|
-
}
|
|
382710
|
-
function bodyStoryLocator2() {
|
|
382711
|
-
return { kind: "story", storyType: "body" };
|
|
382712
|
-
}
|
|
382713
|
-
function wrapTextRangeWithMetadataSdt(paragraphXml, start, end, id, sdtId) {
|
|
382714
|
-
return wrapRangeWithMarkupInParagraphXml({
|
|
382715
|
-
paragraphXml,
|
|
382716
|
-
rangeStart: start,
|
|
382717
|
-
rangeEnd: end,
|
|
382718
|
-
open: metadataSdtOpenXml(id, sdtId),
|
|
382719
|
-
close: "</w:sdtContent></w:sdt>"
|
|
382720
|
-
});
|
|
382721
|
-
}
|
|
382722
|
-
function metadataSdtOpenXml(id, sdtId) {
|
|
382723
|
-
return [
|
|
382724
|
-
`<w:sdt xmlns:w15="${W15_NS}"><w:sdtPr>`,
|
|
382725
|
-
`<w:id w:val="${sdtId}"/>`,
|
|
382726
|
-
`<w:alias w:val="${xmlEscapeAttr(METADATA_ANCHOR_ALIAS)}"/>`,
|
|
382727
|
-
`<w:tag w:val="${xmlEscapeAttr(id)}"/>`,
|
|
382728
|
-
'<w15:appearance w15:val="hidden"/>',
|
|
382729
|
-
"<w:text/>",
|
|
382730
|
-
"</w:sdtPr><w:sdtContent>"
|
|
382731
|
-
].join("");
|
|
382732
|
-
}
|
|
382733
|
-
function metadataWrapRejectError(reason) {
|
|
382734
|
-
if (reason === "invalid-range") {
|
|
382735
|
-
return operationError("TARGET_NOT_FOUND", "metadata target text range not found.");
|
|
382736
|
-
}
|
|
382737
|
-
return operationError("INVALID_TARGET", `metadata.attach target overlaps unsupported content (${reason}).`);
|
|
382738
|
-
}
|
|
382739
|
-
function allocateMetadataSdtIds(documentXml, count) {
|
|
382740
|
-
const used = new Set;
|
|
382741
|
-
const idRe = /<w:id\b[^>]*(?:\/>|>)/g;
|
|
382742
|
-
for (let match = idRe.exec(documentXml);match; match = idRe.exec(documentXml)) {
|
|
382743
|
-
const value2 = Number.parseInt(attrValue(match[0], "val") ?? "", 10);
|
|
382744
|
-
if (Number.isInteger(value2))
|
|
382745
|
-
used.add(value2);
|
|
382746
|
-
}
|
|
382747
|
-
const ids = [];
|
|
382748
|
-
for (let i2 = 0;i2 < count; i2 += 1) {
|
|
382749
|
-
let candidate2 = Math.max(1, Math.floor(Math.random() * MAX_SDT_ID));
|
|
382750
|
-
while (used.has(candidate2))
|
|
382751
|
-
candidate2 = candidate2 >= MAX_SDT_ID ? 1 : candidate2 + 1;
|
|
382752
|
-
used.add(candidate2);
|
|
382753
|
-
ids.push(candidate2);
|
|
382754
|
-
}
|
|
382755
|
-
return ids;
|
|
382756
|
-
}
|
|
382757
|
-
function ensureW15Namespace(documentXml) {
|
|
382758
|
-
return documentXml.replace(/<w:document\b[^>]*>/, (openTag) => {
|
|
382759
|
-
let next = openTag;
|
|
382760
|
-
if (!/\sxmlns:w15\s*=/.test(next))
|
|
382761
|
-
next = next.replace(/>$/, ` xmlns:w15="${W15_NS}">`);
|
|
382762
|
-
const ignorable = /\smc:Ignorable\s*=\s*(["'])([^"']*)\1/.exec(next);
|
|
382763
|
-
if (!ignorable)
|
|
382764
|
-
return next;
|
|
382765
|
-
const prefixes = ignorable[2].split(/\s+/).filter(Boolean);
|
|
382766
|
-
if (prefixes.includes("w15"))
|
|
382767
|
-
return next;
|
|
382768
|
-
return next.replace(ignorable[0], ` mc:Ignorable="${[...prefixes, "w15"].join(" ")}"`);
|
|
382769
|
-
});
|
|
382770
|
-
}
|
|
382771
|
-
function readDocumentXml(context) {
|
|
382772
|
-
const xml = readPartXml(context, DOCUMENT_PART_URI5);
|
|
382773
|
-
if (!xml)
|
|
382774
|
-
throw operationError("PRECONDITION_FAILED", "document.xml bytes are unavailable.");
|
|
382775
|
-
return xml;
|
|
382776
|
-
}
|
|
382777
|
-
function findParagraphById3(documentXml, blockId) {
|
|
382778
|
-
const paraRe = /<w:p\b[^>]*>[\s\S]*?<\/w:p>/g;
|
|
382779
|
-
for (let match = paraRe.exec(documentXml);match; match = paraRe.exec(documentXml)) {
|
|
382780
|
-
if (match[0].includes(`w14:paraId="${blockId}"`))
|
|
382781
|
-
return { start: match.index, end: paraRe.lastIndex, xml: match[0], blockId };
|
|
382782
|
-
}
|
|
382783
|
-
return null;
|
|
382784
|
-
}
|
|
382785
|
-
function findParagraphContaining2(documentXml, index2) {
|
|
382786
|
-
const paraRe = /<w:p\b[^>]*>[\s\S]*?<\/w:p>/g;
|
|
382787
|
-
for (let match = paraRe.exec(documentXml);match; match = paraRe.exec(documentXml)) {
|
|
382788
|
-
if (match.index <= index2 && paraRe.lastIndex >= index2) {
|
|
382789
|
-
const open = /^<w:p\b[^>]*>/.exec(match[0])?.[0] ?? "";
|
|
382790
|
-
return {
|
|
382791
|
-
start: match.index,
|
|
382792
|
-
end: paraRe.lastIndex,
|
|
382793
|
-
xml: match[0],
|
|
382794
|
-
blockId: attrValue(open, "paraId") ?? "unknown"
|
|
382795
|
-
};
|
|
382796
|
-
}
|
|
382797
|
-
}
|
|
382798
|
-
return null;
|
|
382799
|
-
}
|
|
382800
|
-
function unwrapSdt(sdtXml) {
|
|
382801
|
-
const open = /<w:sdtContent\b[^>]*>/.exec(sdtXml);
|
|
382802
|
-
if (!open)
|
|
382803
|
-
return null;
|
|
382804
|
-
if (/\/\s*>$/.test(open[0]))
|
|
382805
|
-
return "";
|
|
382806
|
-
const contentStart = open.index + open[0].length;
|
|
382807
|
-
const tokenRe = /<w:sdtContent\b[^>]*>|<\/w:sdtContent>/g;
|
|
382808
|
-
tokenRe.lastIndex = contentStart;
|
|
382809
|
-
let depth = 0;
|
|
382810
|
-
for (let match = tokenRe.exec(sdtXml);match; match = tokenRe.exec(sdtXml)) {
|
|
382811
|
-
if (match[0].startsWith("</")) {
|
|
382812
|
-
if (depth === 0)
|
|
382813
|
-
return sdtXml.slice(contentStart, match.index);
|
|
382814
|
-
depth -= 1;
|
|
382815
|
-
} else if (!/\/\s*>$/.test(match[0])) {
|
|
382816
|
-
depth += 1;
|
|
382817
|
-
}
|
|
382818
|
-
}
|
|
382819
|
-
return null;
|
|
382820
|
-
}
|
|
382821
|
-
function replaceRange3(xml, start, end, replacement) {
|
|
382822
|
-
return `${xml.slice(0, start)}${replacement}${xml.slice(end)}`;
|
|
382823
|
-
}
|
|
382824
|
-
function toFlatSegments(target) {
|
|
382825
|
-
if (target.story !== undefined && target.story.storyType !== "body")
|
|
382826
|
-
return null;
|
|
382827
|
-
if (target.coordinateSpace === "tracked")
|
|
382828
|
-
return null;
|
|
382829
|
-
if (target.kind === "text") {
|
|
382830
|
-
return target.segments.map((segment) => ({
|
|
382831
|
-
blockId: segment.blockId,
|
|
382832
|
-
start: segment.range.start,
|
|
382833
|
-
end: segment.range.end
|
|
382834
|
-
}));
|
|
382835
|
-
}
|
|
382836
|
-
if (target.start.kind !== "text" || target.end.kind !== "text")
|
|
382837
|
-
return null;
|
|
382838
|
-
if (target.start.blockId !== target.end.blockId)
|
|
382839
|
-
return null;
|
|
382840
|
-
return [{ blockId: target.start.blockId, start: target.start.offset, end: target.end.offset }];
|
|
382841
|
-
}
|
|
382842
|
-
function overlaps(left, right) {
|
|
382843
|
-
const leftSegments = toFlatSegments(left);
|
|
382844
|
-
const rightSegments = toFlatSegments(right);
|
|
382845
|
-
if (!leftSegments || !rightSegments)
|
|
382846
|
-
return false;
|
|
382847
|
-
return leftSegments.some((leftSegment) => rightSegments.some((rightSegment) => leftSegment.blockId === rightSegment.blockId && rangesStrictlyOverlap(leftSegment.start, leftSegment.end, rightSegment.start, rightSegment.end)));
|
|
382848
|
-
}
|
|
382849
|
-
var TEXT_ENCODER2, METADATA_ANCHOR_ALIAS = "Anchored metadata", W15_NS = "http://schemas.microsoft.com/office/word/2012/wordml", MAX_SDT_ID = 2147483646;
|
|
382850
|
-
var init_adapter38 = __esm(() => {
|
|
382851
|
-
init_src3();
|
|
382852
|
-
init_sd_document_session_internal();
|
|
382853
|
-
init_visible_text();
|
|
382854
|
-
init_inline();
|
|
382855
|
-
init_adapter2();
|
|
382856
|
-
init_shared();
|
|
382857
|
-
init_xml();
|
|
382858
|
-
TEXT_ENCODER2 = new TextEncoder;
|
|
382859
|
-
});
|
|
382860
|
-
|
|
382861
383077
|
// ../../../v2/document-api-v2-adapter/dist/formatting/styles.js
|
|
382862
383078
|
function applyStylesDocDefaultsPatch(stylesXml, input) {
|
|
382863
383079
|
const normalized = normalizeStylesWordprocessingMlQNames(stylesXml);
|
|
@@ -386012,47 +386228,47 @@ function createV2DocumentApiAdapter(session, options = {}) {
|
|
|
386012
386228
|
}
|
|
386013
386229
|
var init_factory = __esm(() => {
|
|
386014
386230
|
init_context();
|
|
386015
|
-
init_adapter10();
|
|
386016
386231
|
init_adapter11();
|
|
386017
|
-
|
|
386018
|
-
|
|
386232
|
+
init_adapter12();
|
|
386233
|
+
init_adapter17();
|
|
386019
386234
|
init_adapter19();
|
|
386020
386235
|
init_adapter20();
|
|
386021
|
-
init_adapter12();
|
|
386022
|
-
init_adapter15();
|
|
386023
386236
|
init_adapter21();
|
|
386237
|
+
init_adapter13();
|
|
386238
|
+
init_adapter16();
|
|
386239
|
+
init_adapter22();
|
|
386024
386240
|
init_adapter2();
|
|
386025
|
-
init_adapter23();
|
|
386026
386241
|
init_adapter24();
|
|
386027
|
-
init_adapter();
|
|
386028
386242
|
init_adapter25();
|
|
386243
|
+
init_adapter();
|
|
386029
386244
|
init_adapter26();
|
|
386030
|
-
|
|
386245
|
+
init_adapter27();
|
|
386246
|
+
init_adapter30();
|
|
386031
386247
|
init_adapter6();
|
|
386032
386248
|
init_adapter7();
|
|
386033
|
-
|
|
386034
|
-
init_adapter30();
|
|
386035
|
-
init_adapter13();
|
|
386036
|
-
init_adapter22();
|
|
386037
|
-
init_reader();
|
|
386249
|
+
init_adapter10();
|
|
386038
386250
|
init_adapter31();
|
|
386039
|
-
|
|
386251
|
+
init_adapter14();
|
|
386252
|
+
init_adapter23();
|
|
386253
|
+
init_reader();
|
|
386040
386254
|
init_adapter32();
|
|
386255
|
+
init_search2();
|
|
386041
386256
|
init_adapter33();
|
|
386257
|
+
init_adapter34();
|
|
386042
386258
|
init_adapter8();
|
|
386043
|
-
|
|
386259
|
+
init_adapter18();
|
|
386044
386260
|
init_adapter3();
|
|
386045
|
-
init_adapter34();
|
|
386046
386261
|
init_adapter35();
|
|
386047
386262
|
init_adapter36();
|
|
386048
|
-
init_adapter27();
|
|
386049
386263
|
init_adapter37();
|
|
386050
|
-
init_clear_content_adapter();
|
|
386051
386264
|
init_adapter28();
|
|
386265
|
+
init_adapter38();
|
|
386266
|
+
init_clear_content_adapter();
|
|
386267
|
+
init_adapter29();
|
|
386052
386268
|
init_adapter4();
|
|
386053
386269
|
init_adapter5();
|
|
386054
|
-
|
|
386055
|
-
|
|
386270
|
+
init_adapter9();
|
|
386271
|
+
init_adapter15();
|
|
386056
386272
|
init_adapter39();
|
|
386057
386273
|
init_adapter40();
|
|
386058
386274
|
init_read_adapters();
|
|
@@ -419956,7 +420172,7 @@ class XmlEmissionContext {
|
|
|
419956
420172
|
stack.push(namespaceBindings);
|
|
419957
420173
|
if (namespaceBindings !== inherited)
|
|
419958
420174
|
events.push({ offset: end, bindings: namespaceBindings });
|
|
419959
|
-
if (tag.localName !== "p" || tag.namespaceUri !==
|
|
420175
|
+
if (tag.localName !== "p" || tag.namespaceUri !== WORD_NAMESPACE6)
|
|
419960
420176
|
return;
|
|
419961
420177
|
if (paragraphDepth++ > 0)
|
|
419962
420178
|
return;
|
|
@@ -419966,7 +420182,7 @@ class XmlEmissionContext {
|
|
|
419966
420182
|
this.paragraphs.set(blockIdForParagraphXmlSpan({ paraId: id2 ?? null, ordinal: paragraphOrdinal++ }), context);
|
|
419967
420183
|
},
|
|
419968
420184
|
onCloseTag: ({ tag, end }) => {
|
|
419969
|
-
if (tag.localName === "p" && tag.namespaceUri ===
|
|
420185
|
+
if (tag.localName === "p" && tag.namespaceUri === WORD_NAMESPACE6)
|
|
419970
420186
|
paragraphDepth -= 1;
|
|
419971
420187
|
const previous3 = stack.pop();
|
|
419972
420188
|
const bindings = stack[stack.length - 1] ?? this.initial;
|
|
@@ -419991,17 +420207,17 @@ function paragraphEmissionNames(context, preservedXml) {
|
|
|
419991
420207
|
bindings[prefix] = namespace;
|
|
419992
420208
|
return prefix;
|
|
419993
420209
|
};
|
|
419994
|
-
const word3 = choose("w",
|
|
420210
|
+
const word3 = choose("w", WORD_NAMESPACE6);
|
|
419995
420211
|
const word2010 = choose("w14", WORD_2010_NAMESPACE3);
|
|
419996
420212
|
const declarations = Object.entries({ "": "", ...bindings }).filter(([prefix, uri]) => prefix !== "xml" && (context.inherited[prefix] ?? "") !== uri).sort(([left], [right]) => left.localeCompare(right)).map(([prefix, uri]) => ` xmlns${prefix ? `:${prefix}` : ""}="${xmlEscape(uri)}"`).join("");
|
|
419997
420213
|
return { word: word3, word2010, declarations };
|
|
419998
420214
|
}
|
|
419999
|
-
var
|
|
420215
|
+
var WORD_NAMESPACE6 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", WORD_2010_NAMESPACE3 = "http://schemas.microsoft.com/office/word/2010/wordml", CANONICAL_NAMESPACES;
|
|
420000
420216
|
var init_xml_emission_context = __esm(() => {
|
|
420001
420217
|
init_sd_document_session_internal();
|
|
420002
420218
|
init_canonical();
|
|
420003
420219
|
CANONICAL_NAMESPACES = {
|
|
420004
|
-
w:
|
|
420220
|
+
w: WORD_NAMESPACE6,
|
|
420005
420221
|
w14: WORD_2010_NAMESPACE3
|
|
420006
420222
|
};
|
|
420007
420223
|
});
|
|
@@ -426505,6 +426721,7 @@ function syncTrackedDecisionTableOverlaysFromSession(session, prepared, storyId,
|
|
|
426505
426721
|
partUri,
|
|
426506
426722
|
preparedTxId: prepared.txId,
|
|
426507
426723
|
lastDeltaKind: "tracked-change.decision.sync",
|
|
426724
|
+
reversibleReviewDecision: prepared.backendExtensions.storySurface?.historyReplay != null,
|
|
426508
426725
|
tableXml,
|
|
426509
426726
|
sourceXmlStart,
|
|
426510
426727
|
sourceXmlEnd: sourceXmlStart + tableXml.length,
|
|
@@ -426559,6 +426776,16 @@ function writeTableOverlayState(input) {
|
|
|
426559
426776
|
input.tableMap.set(overlayTableNodeId, tableValue);
|
|
426560
426777
|
}
|
|
426561
426778
|
const tableState = tableValue;
|
|
426779
|
+
if (input.lastDeltaKind === "tracked-change.decision.sync") {
|
|
426780
|
+
const previousTableXml = tableState.get("xml");
|
|
426781
|
+
const previousGridXml = typeof previousTableXml === "string" ? readDirectChildPropertyXml3(previousTableXml, "tbl", "tblGrid") : "";
|
|
426782
|
+
const nextGridXml = readDirectChildPropertyXml3(input.tableXml, "tbl", "tblGrid");
|
|
426783
|
+
writeTableRevisionDecisionDiff(tableState, "grid", overlayTableNodeId, previousGridXml, nextGridXml, input.reversibleReviewDecision === true);
|
|
426784
|
+
const nextGridChangeXml = readDirectChildPropertyXml3(nextGridXml, "tblGrid", "tblGridChange");
|
|
426785
|
+
if (nextGridChangeXml || tableState.has("gridChange")) {
|
|
426786
|
+
tableState.set("gridChange", nextGridChangeXml || null);
|
|
426787
|
+
}
|
|
426788
|
+
}
|
|
426562
426789
|
tableState.set("tableNodeId", overlayTableNodeId);
|
|
426563
426790
|
if (overlayTableNodeId === input.table.tableNodeId)
|
|
426564
426791
|
tableState.delete("currentTableNodeId");
|
|
@@ -426948,6 +427175,7 @@ var init_story_surface_session_sync = __esm(() => {
|
|
|
426948
427175
|
init_table_structural_refs();
|
|
426949
427176
|
init_schema4();
|
|
426950
427177
|
init_seed();
|
|
427178
|
+
init_table_revision_decisions();
|
|
426951
427179
|
init_story_surface_origin();
|
|
426952
427180
|
init_paragraph_inline_sync();
|
|
426953
427181
|
init_story_surface_origin();
|