@superdoc/mcp 1.9.0-next.4 → 1.9.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +785 -165
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31620,7 +31620,7 @@ var init_host = __esm(() => {
31620
31620
  });
31621
31621
 
31622
31622
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31623
- var SDK_VERSION = "2.22.0-next.4";
31623
+ var SDK_VERSION = "2.22.0-next.6";
31624
31624
 
31625
31625
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31626
31626
  import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
@@ -150138,7 +150138,11 @@ function captureParagraphLocalCommentMarkersUncached(xml, namespaceBindings) {
150138
150138
  start: event.start,
150139
150139
  end: event.end,
150140
150140
  rawTag: xml.slice(event.start, event.end),
150141
- namespaces: JSON.stringify(Object.entries(event.namespaceBindings).sort(([left], [right]) => left.localeCompare(right)))
150141
+ namespaces: JSON.stringify([...new Set([
150142
+ event.tag.prefix,
150143
+ ...event.tag.attributes.filter((attribute) => attribute.prefix && attribute.prefix !== "xmlns").map((attribute) => attribute.prefix),
150144
+ ...event.tag.attributes.flatMap((attribute) => [...attribute.value.matchAll(/\b([\w.-]+):[\w.-]+/g)].map((match) => match[1]))
150145
+ ])].sort().map((prefix) => [prefix, event.namespaceBindings[prefix] ?? ""]))
150142
150146
  });
150143
150147
  }
150144
150148
  });
@@ -165522,6 +165526,7 @@ function createParagraphSemanticOwnershipCollector(xml) {
165522
165526
  paragraphOwner = { start: event.start, ancestors: [...stack], hasSemanticRange: false, ownership: Object.freeze({
165523
165527
  containerKind: parent.local === "body" ? "body" : "cell",
165524
165528
  containerId: parent.containerId,
165529
+ containerPath: Object.freeze(stack.filter((frame) => frame.plain && (frame.local === "body" || frame.local === "tc")).map((frame) => frame.containerId)),
165525
165530
  namespaceBindings: createCanonicalXmlNamespaceBindings(Object.entries(event.namespaceBindings)),
165526
165531
  parentNamespaceBindings: parent.namespaceBindings
165527
165532
  }) };
@@ -166044,6 +166049,17 @@ function relatedLogicalIds(entry) {
166044
166049
  ...entry.subsumption?.role === "parent" ? entry.subsumption.ownedChildIds : []
166045
166050
  ];
166046
166051
  }
166052
+ function paragraphEndsCertifiedContainer(state, review, paragraph) {
166053
+ const ownership = readResidentParagraphOwnership(state, paragraph.blockId);
166054
+ if (!ownership)
166055
+ return false;
166056
+ const end = Math.min(payloadLength(review.payload), paragraph.byteEnd + 256);
166057
+ const bytes = readResidentPartRangeFromStateSync(state, review.partUri, paragraph.byteEnd, end);
166058
+ if (!bytes)
166059
+ return false;
166060
+ const close = /^[ \t\r\n]*<\/(?:([A-Za-z_][\w.-]*):)?(body|tc)[ \t\r\n]*>/.exec(decoder4.decode(bytes));
166061
+ return close?.[2] === (ownership.containerKind === "cell" ? "tc" : "body") && ownership.parentNamespaceBindings[close[1] ?? ""] === NS_W;
166062
+ }
166047
166063
  function readResidentReviewComponent(state, mode, sourceIds, includeCoordinates = true) {
166048
166064
  const review = reviews.get(state);
166049
166065
  if (!review || review.payload !== state.packageBytes.getPayload(review.partUri) || sourceIds.size === 0)
@@ -166069,25 +166085,33 @@ function readResidentReviewComponent(state, mode, sourceIds, includeCoordinates
166069
166085
  const ownership = readResidentParagraphOwnership(state, index.entries[first]?.blockId ?? "");
166070
166086
  if (!ownership || ownership.parentNamespaceBindings.w !== NS_W)
166071
166087
  return null;
166088
+ const hasParagraphBridge = (owner2) => (owner2.xml.match(/<w:pPr\b[\s\S]*?<\/w:pPr>/g) ?? []).some((xml) => /<w:pPrChange\b|<w:rPr\b[\s\S]*?<w:(?:ins|del)\b/.test(xml));
166089
+ const topologyBoundaryOwners = new Set;
166072
166090
  const neighbor = (ordinal, delta) => {
166073
166091
  const paragraph2 = index.entries[ordinal], adjacent = index.entries[ordinal + delta];
166074
166092
  if (!paragraph2 || !adjacent)
166075
166093
  return ordinal;
166076
166094
  const adjacentOwnership = readResidentParagraphOwnership(state, adjacent.blockId);
166077
166095
  if (!adjacentOwnership) {
166078
- const current = review.owners.get(paragraph2.blockId), other = review.owners.get(adjacent.blockId);
166079
- if (current && other && !/<(?:[\w.-]+:)?pPr\b/.test(current.xml) && !/<(?:[\w.-]+:)?(?:ins|del|moveFrom|moveTo|pPrChange|rPrChange)\b/.test(other.xml))
166096
+ const current2 = review.owners.get(paragraph2.blockId), other = review.owners.get(adjacent.blockId);
166097
+ if (current2 && other && !/<(?:[\w.-]+:)?pPr\b/.test(current2.xml) && !/<(?:[\w.-]+:)?(?:ins|del|moveFrom|moveTo|pPrChange|rPrChange)\b/.test(other.xml)) {
166098
+ topologyBoundaryOwners.add(paragraph2.blockId);
166080
166099
  return ordinal;
166100
+ }
166081
166101
  return null;
166082
166102
  }
166083
- return adjacentOwnership.containerId === ownership.containerId ? ordinal + delta : ordinal;
166103
+ if (adjacentOwnership.containerId === ownership.containerId)
166104
+ return ordinal + delta;
166105
+ const current = review.owners.get(paragraph2.blockId);
166106
+ if (adjacentOwnership.containerPath.includes(ownership.containerId))
166107
+ topologyBoundaryOwners.add(paragraph2.blockId);
166108
+ return current && hasParagraphBridge(current) ? null : ordinal;
166084
166109
  };
166085
166110
  const previous = neighbor(first, -1), next = neighbor(last, 1);
166086
166111
  if (previous == null || next == null)
166087
166112
  return null;
166088
166113
  first = previous;
166089
166114
  last = next;
166090
- const hasParagraphBridge = (owner2) => (owner2.xml.match(/<w:pPr\b[\s\S]*?<\/w:pPr>/g) ?? []).some((xml) => /<w:pPrChange\b|<w:rPr\b[\s\S]*?<w:(?:ins|del)\b/.test(xml));
166091
166115
  let owners = [];
166092
166116
  for (;; ) {
166093
166117
  if (last - first >= 64)
@@ -166146,13 +166170,13 @@ function readResidentReviewComponent(state, mode, sourceIds, includeCoordinates
166146
166170
  return null;
166147
166171
  const wrapped = prefix + xml + suffix;
166148
166172
  const prefixBytes = new TextEncoder().encode(prefix).length;
166149
- const firstChar = owners[0].charStart + review.charDeltas.at(owners[0].ordinal);
166173
+ const firstChar2 = owners[0].charStart + review.charDeltas.at(owners[0].ordinal);
166150
166174
  const firstTracked = owners[0].trackedStart + review.trackedDeltas.at(owners[0].ordinal);
166151
166175
  const analyses = [];
166152
166176
  let complete = true;
166153
166177
  for (const owner2 of owners) {
166154
166178
  const paragraph2 = index.entries[owner2.ordinal];
166155
- const charStart = prefix.length + owner2.charStart + review.charDeltas.at(owner2.ordinal) - firstChar;
166179
+ const charStart = prefix.length + owner2.charStart + review.charDeltas.at(owner2.ordinal) - firstChar2;
166156
166180
  if (wrapped.slice(charStart, charStart + owner2.xml.length) !== owner2.xml)
166157
166181
  return null;
166158
166182
  let physical = owner2.physical;
@@ -166207,6 +166231,20 @@ function readResidentReviewComponent(state, mode, sourceIds, includeCoordinates
166207
166231
  lookupContext: createStructuralLookupContext()
166208
166232
  };
166209
166233
  }
166234
+ const firstChar = owners[0].charStart + review.charDeltas.at(owners[0].ordinal);
166235
+ for (const owner2 of owners) {
166236
+ if (!topologyBoundaryOwners.has(owner2.blockId))
166237
+ continue;
166238
+ const charStart = prefix.length + owner2.charStart + review.charDeltas.at(owner2.ordinal) - firstChar;
166239
+ for (const fragments2 of component.raw.byRsid.values())
166240
+ for (const fragment3 of fragments2) {
166241
+ if (fragment3.kind === "ins" && fragment3.byteStart >= charStart && fragment3.byteEnd <= charStart + owner2.xml.length && isEmptyTableSplitParagraph(owner2.xml, fragment3.byteStart - charStart, fragment3.byteEnd - charStart) && !paragraphEndsCertifiedContainer(state, review, index.entries[owner2.ordinal])) {
166242
+ if (component !== cached2)
166243
+ component.lookupContext.dispose();
166244
+ return null;
166245
+ }
166246
+ }
166247
+ }
166210
166248
  const modeCached = component.logicalByMode.get(mode);
166211
166249
  const dependencies = componentDependencies(state, component.dependencyIds);
166212
166250
  let logical = modeCached && componentDependenciesMatch(modeCached.dependencies, dependencies) ? modeCached.logical : null;
@@ -166899,6 +166937,7 @@ var init_resident_review = __esm(() => {
166899
166937
  init_resident_paragraphs();
166900
166938
  init_comment_anchor_index();
166901
166939
  init_sd_document_state();
166940
+ init_part_payload();
166902
166941
  init_paragraph_index();
166903
166942
  init_wml_paragraph_spans();
166904
166943
  init_paragraph_inline_model();
@@ -166909,6 +166948,7 @@ var init_resident_review = __esm(() => {
166909
166948
  init_source_inventory();
166910
166949
  init_export_projection();
166911
166950
  init_resident_paragraph_ownership();
166951
+ init_table_split_paragraph();
166912
166952
  init_effective_list_reference();
166913
166953
  init_canonical_xml_analysis_frame();
166914
166954
  reviews = new WeakMap;
@@ -173786,6 +173826,54 @@ function refreshTextboxExecutionBackendCapabilities(state, geometryMutationBacke
173786
173826
  };
173787
173827
  }
173788
173828
  }
173829
+ function captureSourceSignalPackage(state) {
173830
+ const parts = new Map(state.partOrder.flatMap((id) => {
173831
+ const descriptor = state.parts.get(id)?.descriptor;
173832
+ return descriptor ? [[id, {
173833
+ uri: descriptor.partUri,
173834
+ contentType: descriptor.contentType,
173835
+ kind: descriptor.kind,
173836
+ uncompressedSize: descriptor.size.uncompressedBytes ?? 0
173837
+ }]] : [];
173838
+ }));
173839
+ const payloads = state.packageBytes.detached();
173840
+ const source = state.lazyPackagePayloadSource;
173841
+ const sourceParts = new Set([...state.parts].flatMap(([uri, { descriptor }]) => state.sourcePartRevisions.get(uri) === descriptor.revision ? [uri] : []));
173842
+ const fencedMain = state.mainStorySourceRangeReader?.partUri;
173843
+ const read = (name) => {
173844
+ const uri = normalizePartUri(name);
173845
+ if (!parts.has(uri) || uri === fencedMain)
173846
+ return;
173847
+ const retained = payloads.get(uri);
173848
+ if (retained)
173849
+ return retained;
173850
+ const bytes = sourceParts.has(uri) ? source?.readPayload(uri) : undefined;
173851
+ if (bytes)
173852
+ payloads.set(uri, bytes);
173853
+ return bytes ?? undefined;
173854
+ };
173855
+ const mainDocumentPartUri = state.mainStoryId ? state.stories.get(state.mainStoryId)?.descriptor.ownerPartUri ?? null : null;
173856
+ const relsParts = new Map;
173857
+ const mainRelsUri = mainDocumentPartUri ? relsUriFor(mainDocumentPartUri) : null;
173858
+ const mainRelsBytes = mainRelsUri ? read(mainRelsUri) : undefined;
173859
+ const mainDocumentRelationships = mainDocumentPartUri && mainRelsUri && mainRelsBytes ? parseRelationshipsXml(new TextDecoder().decode(mainRelsBytes), {
173860
+ ownerPartUri: mainDocumentPartUri,
173861
+ relsUri: mainRelsUri,
173862
+ resolveTarget: (target, mode) => resolveTargetUri(mainDocumentPartUri, target, mode, parts)
173863
+ }) : null;
173864
+ if (mainDocumentRelationships && mainRelsUri)
173865
+ relsParts.set(mainRelsUri, mainDocumentRelationships);
173866
+ return {
173867
+ parts,
173868
+ mainDocumentPartUri,
173869
+ mainDocumentRelationships,
173870
+ relsParts,
173871
+ zip: { payloads: { get: read, has: (name) => {
173872
+ const uri = normalizePartUri(name);
173873
+ return parts.has(uri) && uri !== fencedMain && payloads.has(uri);
173874
+ } } }
173875
+ };
173876
+ }
173789
173877
  function ensurePackagePartBytes(state, partUri) {
173790
173878
  const normalizedPartUri = partUri.startsWith("/") ? partUri : `/${partUri}`;
173791
173879
  const cached2 = state.packageBytes.get(normalizedPartUri);
@@ -179652,6 +179740,10 @@ var init_textbox_atom_replacement = __esm(() => {
179652
179740
  function clearTrackedChangeLogicalCatalogCache(state) {
179653
179741
  state.partRegistries.delete(LOGICAL_CATALOG_CACHE_KEY);
179654
179742
  }
179743
+ function readCurrentTrackedChangeLogicalCatalog(state, replacementMode) {
179744
+ const cached2 = state.partRegistries.get(LOGICAL_CATALOG_CACHE_KEY);
179745
+ return cached2?.key === logicalCatalogGuardKey(state, replacementMode) ? cached2.view : null;
179746
+ }
179655
179747
  function accessTrackedChangeLogicalCatalog(state, replacementMode) {
179656
179748
  const key3 = logicalCatalogGuardKey(state, replacementMode);
179657
179749
  const cached2 = state.partRegistries.get(LOGICAL_CATALOG_CACHE_KEY);
@@ -182404,7 +182496,14 @@ function compileParsedOverlapEdit(input, tokens, descendedEditableContainers) {
182404
182496
  }
182405
182497
  const paragraphContainsMoveWrapper = tokens.some((token) => token.kind === "unsupported" && token.foreignTrackedWrapper !== true && (token.trackedKind === "moveFrom" || token.trackedKind === "moveTo"));
182406
182498
  const trackedPlainCaret = (input.coordinateSpace ?? "visible") === "tracked" && tokenOwningCollapsedCaret(input, tokens)?.kind === "plain";
182407
- const deletedControlBoundary = input.collapsedInlineAffinity != null && tokens.some((token) => token.kind === "unsupported" && token.deletedInlineControl === true && token.visibleStart === input.rangeStart && token.visibleEnd === input.rangeStart);
182499
+ const deletedControlBoundary = tokens.some((token) => {
182500
+ if (token.kind !== "unsupported" || token.deletedInlineControl !== true)
182501
+ return false;
182502
+ if ((input.coordinateSpace ?? "visible") !== "tracked") {
182503
+ return input.collapsedInlineAffinity != null && token.visibleStart === input.rangeStart && token.visibleEnd === input.rangeStart;
182504
+ }
182505
+ return token.visibleStart === input.rangeStart && input.collapsedInlineAffinity !== "downstream" || token.visibleEnd === input.rangeStart && input.collapsedInlineAffinity !== "upstream";
182506
+ });
182408
182507
  if ((paragraphContainsMoveWrapper || trackedPlainCaret || deletedControlBoundary) && input.rangeStart === input.rangeEnd && input.newText.length > 0) {
182409
182508
  const defersExplicitUpstreamMoveBoundary = input.changeMode === "direct" && input.collapsedInlineAffinity === "upstream" && !tokens.some((token) => token.kind === "plain" && token.visibleEnd === input.rangeStart) && tokens.some((token) => token.kind === "unsupported" && token.foreignTrackedWrapper !== true && token.trackedKind === "moveFrom" && token.visibleStart === input.rangeStart && token.visibleEnd === input.rangeStart);
182410
182509
  if (defersExplicitUpstreamMoveBoundary) {
@@ -193147,6 +193246,92 @@ var init_closed_history_group = __esm(() => {
193147
193246
  preparedGroups = new WeakMap;
193148
193247
  });
193149
193248
 
193249
+ // ../../../v2/editor-core/dist/document/transactions/tracked-annotation-reconstruction.js
193250
+ function hasTrackedRemap(refs) {
193251
+ return refs.some((remap) => remap.from.kind === "trackedChange" || remap.to.kind === "trackedChange");
193252
+ }
193253
+ function decisionKey(prepared) {
193254
+ return JSON.stringify({
193255
+ txId: prepared.txId,
193256
+ source: prepared.source,
193257
+ base: prepared.baseRevisions,
193258
+ created: prepared.semanticDelta.createdRefs,
193259
+ updated: prepared.semanticDelta.updatedRefs,
193260
+ invalidated: prepared.semanticDelta.invalidatedRefs,
193261
+ remapped: prepared.semanticDelta.remappedRefs
193262
+ });
193263
+ }
193264
+ function captureTrackedDecisionAnnotationReconstruction(state, prepared) {
193265
+ if (prepared.source.kind !== "trackedChangeDecide" || prepared.source !== prepared.localApplyBundle.source || !hasTrackedRemap(prepared.semanticDelta.remappedRefs))
193266
+ return;
193267
+ preparedDecisions.set(prepared, {
193268
+ state,
193269
+ documentEpoch: state.documentRef.documentId,
193270
+ packageRevision: state.packageRevision,
193271
+ commitSequence: state.renderCommitSequence,
193272
+ source: prepared.source,
193273
+ bundle: prepared.localApplyBundle,
193274
+ key: decisionKey(prepared)
193275
+ });
193276
+ }
193277
+ function sourceKey(commit) {
193278
+ return JSON.stringify({
193279
+ documentEpoch: commit.documentEpoch,
193280
+ commitSequence: commit.commitSequence,
193281
+ coveredCommitSequenceStart: commit.coveredCommitSequenceStart,
193282
+ txId: commit.txId,
193283
+ package: commit.revisions.package,
193284
+ historyReplay: commit.historyReplay,
193285
+ created: commit.facts.createdRefs,
193286
+ updated: commit.facts.updatedRefs,
193287
+ invalidated: commit.facts.invalidatedRefs,
193288
+ remapped: commit.facts.remappedRefs
193289
+ });
193290
+ }
193291
+ function requiresCanonicalAnnotations(commit) {
193292
+ return commit.classification.kind === "broad" && !commit.remote && commit.trackedAnnotations == null && commit.trackedAnnotationHistory == null && commit.trackedAnnotationHistoryGroup == null && commit.trackedAnnotationSteps == null && commit.trackedAnnotationRemovals == null && commit.sourceProjectionEffect == null && commit.sourceProjectionSteps == null && (hasTrackedRemap(commit.facts.remappedRefs) || commit.historyReplay === true && commit.facts.createdRefs.some((ref3) => ref3.kind === "trackedChange"));
193293
+ }
193294
+ function issue2(state, commit) {
193295
+ const token = Object.freeze({});
193296
+ issued2.set(token, { state, key: sourceKey(commit) });
193297
+ return token;
193298
+ }
193299
+ function sealTrackedDecisionAnnotationReconstruction(state, prepared, entry, result, commit) {
193300
+ const captured = preparedDecisions.get(prepared);
193301
+ preparedDecisions.delete(prepared);
193302
+ if (!captured || captured.state !== state || captured.documentEpoch !== state.documentRef.documentId || captured.source !== prepared.source || captured.bundle !== prepared.localApplyBundle || captured.key !== decisionKey(prepared) || commit.historyReplay || captured.commitSequence + 1 !== result.commitSequence || captured.packageRevision !== result.previousPackageRevision || state.history.entries.get(entry.txId) !== entry || entry.txId !== prepared.txId || commit.txId !== prepared.txId || entry.forwardPatchGroup !== result.forwardPatchGroup || entry.inversePatchGroup !== result.inversePatchGroup || result.forwardPatchGroup?.source !== captured.source || result.status !== "committed" || result.documentEpoch !== captured.documentEpoch || result.documentEpoch !== commit.documentEpoch || result.commitSequence !== state.renderCommitSequence || result.commitSequence !== commit.commitSequence || result.previousPackageRevision !== commit.revisions.package.previous || result.packageRevision !== state.packageRevision || result.packageRevision !== commit.revisions.package.next || JSON.stringify({
193303
+ created: commit.facts.createdRefs,
193304
+ updated: commit.facts.updatedRefs,
193305
+ invalidated: commit.facts.invalidatedRefs,
193306
+ remapped: commit.facts.remappedRefs
193307
+ }) !== JSON.stringify({
193308
+ created: prepared.semanticDelta.createdRefs,
193309
+ updated: prepared.semanticDelta.updatedRefs,
193310
+ invalidated: prepared.semanticDelta.invalidatedRefs,
193311
+ remapped: prepared.semanticDelta.remappedRefs
193312
+ }) || !requiresCanonicalAnnotations(commit))
193313
+ return null;
193314
+ return issue2(state, commit);
193315
+ }
193316
+ function issueTrackedAnnotationReconstruction(state, entry, result, commit) {
193317
+ if (state.history.entries.get(entry.txId) !== entry || entry.forwardPatchGroup.source.kind !== "trackedChangeDecide" || result.status !== "committed" || result.documentEpoch !== state.documentRef.documentId || result.commitSequence !== state.renderCommitSequence || result.documentEpoch !== commit.documentEpoch || result.commitSequence !== commit.commitSequence || result.previousPackageRevision !== commit.revisions.package.previous || result.packageRevision !== state.packageRevision || result.packageRevision !== commit.revisions.package.next || commit.historyReplay !== true || !requiresCanonicalAnnotations(commit))
193318
+ return null;
193319
+ return issue2(state, commit);
193320
+ }
193321
+ function isIssuedTrackedAnnotationReconstruction(value) {
193322
+ return Object.isFrozen(value) && issued2.has(value);
193323
+ }
193324
+ function readIssuedTrackedAnnotationReconstruction(commit) {
193325
+ const token = commit.trackedAnnotationReconstruction;
193326
+ const binding = token && issued2.get(token);
193327
+ return !!binding && Object.isFrozen(token) && binding.key === sourceKey(commit) && commit.documentEpoch === binding.state.documentRef.documentId && commit.commitSequence <= binding.state.renderCommitSequence && requiresCanonicalAnnotations(commit);
193328
+ }
193329
+ var issued2, preparedDecisions;
193330
+ var init_tracked_annotation_reconstruction = __esm(() => {
193331
+ issued2 = new WeakMap;
193332
+ preparedDecisions = new WeakMap;
193333
+ });
193334
+
193150
193335
  // ../../../v2/editor-core/dist/document/transactions/render-commit-annotation-effect.js
193151
193336
  function proveAnnotationSourceEffect(input) {
193152
193337
  const { before, after, commentId, operation, beforeNamespaces, afterNamespaces } = input;
@@ -193253,7 +193438,7 @@ var init_comment_tracked_change_metadata = __esm(() => {
193253
193438
 
193254
193439
  // ../../../v2/editor-core/dist/document/transactions/tracked-decision-comment-metadata.js
193255
193440
  function readIssuedTrackedDecisionCommentMetadata(state, prepared) {
193256
- const group = prepared.localApplyBundle, proof = issued2.get(group.perPart);
193441
+ const group = prepared.localApplyBundle, proof = issued3.get(group.perPart);
193257
193442
  if (!proof || proof.state !== state || prepared.source.kind !== "trackedChangeDecide" || prepared.baseRevisions.package !== proof.packageRevision || prepared.baseRevisions.perPart[COMMENTS_PART_URI] !== proof.commentsRevision)
193258
193443
  return null;
193259
193444
  const parts = Object.keys(group.perPart), bodyPartUri = parts.find((uri) => uri !== COMMENTS_PART_URI);
@@ -193370,7 +193555,7 @@ function applyRetiredTrackedChangeCommentMetadataCleanup(args) {
193370
193555
  });
193371
193556
  const commentsRevision = args.state.parts.get(COMMENTS_PART_URI)?.descriptor.revision;
193372
193557
  if (!pendingPatch && commentsRevision && updatedRefs.length)
193373
- issued2.set(args.perPart, {
193558
+ issued3.set(args.perPart, {
193374
193559
  state: args.state,
193375
193560
  packageRevision: args.state.packageRevision,
193376
193561
  commentsRevision,
@@ -193380,14 +193565,14 @@ function applyRetiredTrackedChangeCommentMetadataCleanup(args) {
193380
193565
  });
193381
193566
  return updatedRefs;
193382
193567
  }
193383
- var TD34, TE13, issued2;
193568
+ var TD34, TE13, issued3;
193384
193569
  var init_tracked_decision_comment_metadata = __esm(() => {
193385
193570
  init_comments_catalog();
193386
193571
  init_comment_tracked_change_metadata();
193387
193572
  init_patch_substrate();
193388
193573
  TD34 = new TextDecoder;
193389
193574
  TE13 = new TextEncoder;
193390
- issued2 = new WeakMap;
193575
+ issued3 = new WeakMap;
193391
193576
  });
193392
193577
 
193393
193578
  // ../../../v2/editor-core/dist/document/transactions/tracked-decision-comment-cascade.js
@@ -193401,7 +193586,7 @@ function fingerprint2(group, updatedRefs, invalidatedRefs) {
193401
193586
  ], (_key, value) => value instanceof Uint8Array ? { byteLength: value.length } : value);
193402
193587
  }
193403
193588
  function readIssuedTrackedDecisionCommentCascade(state, prepared) {
193404
- const group = prepared.localApplyBundle, proof = issued3.get(group.perPart);
193589
+ const group = prepared.localApplyBundle, proof = issued4.get(group.perPart);
193405
193590
  if (!proof || proof.state !== state || prepared.source.kind !== "trackedChangeDecide" || prepared.baseRevisions.package !== proof.packageRevision || proof.patches.some(({ partUri, index, patch, bytes }) => {
193406
193591
  const entry = group.perPart[partUri];
193407
193592
  return entry?.kind !== "modify" || entry.patches[index] !== patch || patch.bytes.length !== bytes.length || !bytes.every((byte, index2) => patch.bytes[index2] === byte);
@@ -193554,7 +193739,7 @@ function prepareBoundedTrackedDecisionCommentCascade(input) {
193554
193739
  patchMaps: group.patchMaps,
193555
193740
  retiredSourceIds: input.retiredSourceIds
193556
193741
  }).filter((ref3) => ref3.kind !== "comment" || !removed.has(ref3.commentId));
193557
- issued3.set(group.perPart, {
193742
+ issued4.set(group.perPart, {
193558
193743
  state,
193559
193744
  packageRevision: group.baseRevisions.package,
193560
193745
  bodyPartUri: paragraph.partUri,
@@ -193568,7 +193753,7 @@ function prepareBoundedTrackedDecisionCommentCascade(input) {
193568
193753
  }
193569
193754
  };
193570
193755
  }
193571
- var TD35, TE14, issued3;
193756
+ var TD35, TE14, issued4;
193572
193757
  var init_tracked_decision_comment_cascade = __esm(() => {
193573
193758
  init_resident_review();
193574
193759
  init_body_comment_anchors();
@@ -193578,7 +193763,7 @@ var init_tracked_decision_comment_cascade = __esm(() => {
193578
193763
  init_patch_substrate();
193579
193764
  TD35 = new TextDecoder;
193580
193765
  TE14 = new TextEncoder;
193581
- issued3 = new WeakMap;
193766
+ issued4 = new WeakMap;
193582
193767
  });
193583
193768
 
193584
193769
  // ../../../v2/editor-core/dist/document/transactions/render-commit-inline-effect.js
@@ -194313,6 +194498,71 @@ var init_preserved_structural_sdt = __esm(() => {
194313
194498
  INLINE_SDT_DEPENDENCY_RE = /<(?:[\w.-]+:)?sdt\b/;
194314
194499
  });
194315
194500
 
194501
+ // ../../../v2/editor-core/dist/document/transactions/tracked-changes/paragraph-mark-markers.js
194502
+ function paragraphMarkTrackedMarkers(paragraphXml) {
194503
+ const rPr = paragraphMarkRPrSpan(paragraphXml);
194504
+ if (!rPr)
194505
+ return [];
194506
+ const markers = [];
194507
+ for (const child of childElements(paragraphXml, rPr.contentStart, rPr.contentEnd)) {
194508
+ const localName2 = xmlLocalName(child.qname);
194509
+ if (!child.selfClosing || !MARK_KINDS.has(localName2))
194510
+ continue;
194511
+ markers.push({ kind: localName2, start: child.start, end: child.end });
194512
+ }
194513
+ return markers;
194514
+ }
194515
+ function paragraphMarkHasTrackedMarker(paragraphXml, kind) {
194516
+ return paragraphMarkTrackedMarkers(paragraphXml).some((marker) => marker.kind === kind);
194517
+ }
194518
+ function paragraphMarkRPrSpan(paragraphXml) {
194519
+ const paragraph = readXmlNodeAt(paragraphXml, 0);
194520
+ if (!paragraph || paragraph.kind !== "element" || paragraph.selfClosing)
194521
+ return null;
194522
+ if (xmlLocalName(paragraph.qname) !== "p")
194523
+ return null;
194524
+ const [pPr] = childElements(paragraphXml, paragraph.openEnd, paragraph.closeStart);
194525
+ if (!pPr || pPr.selfClosing || xmlLocalName(pPr.qname) !== "pPr")
194526
+ return null;
194527
+ for (const child of childElements(paragraphXml, pPr.openEnd, pPr.closeStart)) {
194528
+ const localName2 = xmlLocalName(child.qname);
194529
+ if (localName2 === "pPrChange")
194530
+ return null;
194531
+ if (localName2 !== "rPr")
194532
+ continue;
194533
+ return child.selfClosing ? null : { contentStart: child.openEnd, contentEnd: child.closeStart };
194534
+ }
194535
+ return null;
194536
+ }
194537
+ function childElements(xml, from, to) {
194538
+ const children = [];
194539
+ let cursor = from;
194540
+ while (cursor < to) {
194541
+ const next = xml.indexOf("<", cursor);
194542
+ if (next < 0 || next >= to)
194543
+ break;
194544
+ const node2 = readXmlNodeAt(xml, next);
194545
+ if (!node2 || node2.end > to)
194546
+ break;
194547
+ if (node2.kind === "element") {
194548
+ children.push({
194549
+ qname: node2.qname,
194550
+ selfClosing: node2.selfClosing,
194551
+ start: next,
194552
+ openEnd: node2.openEnd,
194553
+ closeStart: node2.closeStart,
194554
+ end: node2.end
194555
+ });
194556
+ }
194557
+ cursor = node2.end;
194558
+ }
194559
+ return children;
194560
+ }
194561
+ var MARK_KINDS;
194562
+ var init_paragraph_mark_markers = __esm(() => {
194563
+ MARK_KINDS = new Set(["ins", "del", "moveFrom", "moveTo"]);
194564
+ });
194565
+
194316
194566
  // ../../../v2/editor-core/dist/document/transactions/structural-tracked-carrier-partition.js
194317
194567
  function issueStructuralTrackedCarrierPartition(state, input) {
194318
194568
  const paragraph = input.paragraph;
@@ -194344,7 +194594,7 @@ function issueStructuralTrackedCarrierPartition(state, input) {
194344
194594
  }
194345
194595
  if (renderedParagraphs.length !== 2)
194346
194596
  return null;
194347
- const renderedPayloads = renderedParagraphs.map((xml) => inlinePayload(xml, ownership.namespaceBindings, readInline, lineage));
194597
+ const renderedPayloads = renderedParagraphs.map((xml) => inlinePayload(xml, ownership.namespaceBindings, readInline, lineage, input.authoredMarkWordId));
194348
194598
  if (!before || resultPayloads.some((payload) => !payload) || JSON.stringify(compactPayload(before)) !== JSON.stringify(compactPayload(resultPayloads.flatMap((payload) => payload))) || renderedPayloads.some((payload) => !payload) || JSON.stringify(compactPayload(renderedPayloads.flatMap((payload) => payload))) !== JSON.stringify(compactPayload(before)) || !proveClosedCommentAnchorPreservation(input.beforeXml, input.afterXml, ownership.namespaceBindings))
194349
194599
  return null;
194350
194600
  const local = buildTrackedChangeCatalogFromPartXml({
@@ -194371,7 +194621,7 @@ function issueStructuralTrackedCarrierPartition(state, input) {
194371
194621
  });
194372
194622
  const afterSourceKeys = [...new Set([...sourceKeys2, ...afterCatalog.byRsid.keys()])];
194373
194623
  const proof = Object.freeze({ kind: "structural-tracked-carrier-partition" });
194374
- issued4.set(proof, {
194624
+ issued5.set(proof, {
194375
194625
  state,
194376
194626
  txId: input.txId,
194377
194627
  storyId: paragraph.storyId,
@@ -194388,7 +194638,7 @@ function issueStructuralTrackedCarrierPartition(state, input) {
194388
194638
  }
194389
194639
  function proveStructuralTrackedCarrierPartition(state, prepared, originXml, resultXml) {
194390
194640
  const proof = prepared.backendExtensions.storySurface?.structuralTrackedCarrierPartition;
194391
- const record3 = proof && issued4.get(proof);
194641
+ const record3 = proof && issued5.get(proof);
194392
194642
  const source = prepared.source;
194393
194643
  if (!record3 || record3.state !== state || record3.txId !== prepared.txId || source.kind !== "paragraphSplit" || source.target.storyId !== record3.storyId || source.target.paraId !== record3.blockId || originXml.length !== 1 || originXml[0] !== record3.beforeXml || resultXml.length !== 2 || resultXml.join("") !== record3.afterXml)
194394
194644
  return false;
@@ -194447,8 +194697,18 @@ function metadataKeys(fragments) {
194447
194697
  customAttributes: fragment3.customAttributes
194448
194698
  })))].sort();
194449
194699
  }
194450
- function inlinePayload(xml, namespaces, readInline, lineage = new Map) {
194451
- if (/\bxmlns(?:\s|:)/.test(xml.slice(xml.indexOf(">") + 1)))
194700
+ function inlinePayload(xml, namespaces, readInline, lineage = new Map, authoredMarkWordId) {
194701
+ let payloadXml = xml;
194702
+ if (authoredMarkWordId != null)
194703
+ for (const marker of paragraphMarkTrackedMarkers(xml).reverse()) {
194704
+ const raw = xml.slice(marker.start, marker.end);
194705
+ const node2 = readXmlNodeAt(raw, 0);
194706
+ const prefix = node2?.kind === "element" ? node2.qname.split(":").slice(0, -1).join(":") : "";
194707
+ const ids = [...scanRawXmlAttributes(raw)].filter((attribute2) => attribute2.localName === "id" && namespaces[attribute2.prefix] === NS_W);
194708
+ if (marker.kind === "ins" && namespaces[prefix] === NS_W && ids.length === 1 && ids[0].value === authoredMarkWordId)
194709
+ payloadXml = payloadXml.slice(0, marker.start) + payloadXml.slice(marker.end);
194710
+ }
194711
+ if (/\bxmlns(?:\s|:)/.test(payloadXml.slice(payloadXml.indexOf(">") + 1)))
194452
194712
  return null;
194453
194713
  const result = [];
194454
194714
  const visit = (pieces, wrappers) => {
@@ -194540,7 +194800,7 @@ function compactPayload(payload) {
194540
194800
  }
194541
194801
  return result;
194542
194802
  }
194543
- var issued4;
194803
+ var issued5;
194544
194804
  var init_structural_tracked_carrier_partition = __esm(() => {
194545
194805
  init_paragraph_inline_model();
194546
194806
  init_resident_paragraph_ownership();
@@ -194548,7 +194808,8 @@ var init_structural_tracked_carrier_partition = __esm(() => {
194548
194808
  init_catalog3();
194549
194809
  init_comment_range_invariance();
194550
194810
  init_xml_sax();
194551
- issued4 = new WeakMap;
194811
+ init_paragraph_mark_markers();
194812
+ issued5 = new WeakMap;
194552
194813
  });
194553
194814
 
194554
194815
  // ../../../v2/editor-core/dist/document/transactions/tracked-annotation-history.js
@@ -194845,71 +195106,6 @@ var init_tracked_annotation_history = __esm(() => {
194845
195106
  groupCapsules = new WeakMap;
194846
195107
  });
194847
195108
 
194848
- // ../../../v2/editor-core/dist/document/transactions/tracked-changes/paragraph-mark-markers.js
194849
- function paragraphMarkTrackedMarkers(paragraphXml) {
194850
- const rPr = paragraphMarkRPrSpan(paragraphXml);
194851
- if (!rPr)
194852
- return [];
194853
- const markers = [];
194854
- for (const child of childElements(paragraphXml, rPr.contentStart, rPr.contentEnd)) {
194855
- const localName2 = xmlLocalName(child.qname);
194856
- if (!child.selfClosing || !MARK_KINDS.has(localName2))
194857
- continue;
194858
- markers.push({ kind: localName2, start: child.start, end: child.end });
194859
- }
194860
- return markers;
194861
- }
194862
- function paragraphMarkHasTrackedMarker(paragraphXml, kind) {
194863
- return paragraphMarkTrackedMarkers(paragraphXml).some((marker) => marker.kind === kind);
194864
- }
194865
- function paragraphMarkRPrSpan(paragraphXml) {
194866
- const paragraph = readXmlNodeAt(paragraphXml, 0);
194867
- if (!paragraph || paragraph.kind !== "element" || paragraph.selfClosing)
194868
- return null;
194869
- if (xmlLocalName(paragraph.qname) !== "p")
194870
- return null;
194871
- const [pPr] = childElements(paragraphXml, paragraph.openEnd, paragraph.closeStart);
194872
- if (!pPr || pPr.selfClosing || xmlLocalName(pPr.qname) !== "pPr")
194873
- return null;
194874
- for (const child of childElements(paragraphXml, pPr.openEnd, pPr.closeStart)) {
194875
- const localName2 = xmlLocalName(child.qname);
194876
- if (localName2 === "pPrChange")
194877
- return null;
194878
- if (localName2 !== "rPr")
194879
- continue;
194880
- return child.selfClosing ? null : { contentStart: child.openEnd, contentEnd: child.closeStart };
194881
- }
194882
- return null;
194883
- }
194884
- function childElements(xml, from, to) {
194885
- const children = [];
194886
- let cursor = from;
194887
- while (cursor < to) {
194888
- const next = xml.indexOf("<", cursor);
194889
- if (next < 0 || next >= to)
194890
- break;
194891
- const node2 = readXmlNodeAt(xml, next);
194892
- if (!node2 || node2.end > to)
194893
- break;
194894
- if (node2.kind === "element") {
194895
- children.push({
194896
- qname: node2.qname,
194897
- selfClosing: node2.selfClosing,
194898
- start: next,
194899
- openEnd: node2.openEnd,
194900
- closeStart: node2.closeStart,
194901
- end: node2.end
194902
- });
194903
- }
194904
- cursor = node2.end;
194905
- }
194906
- return children;
194907
- }
194908
- var MARK_KINDS;
194909
- var init_paragraph_mark_markers = __esm(() => {
194910
- MARK_KINDS = new Set(["ins", "del", "moveFrom", "moveTo"]);
194911
- });
194912
-
194913
195109
  // ../../../v2/editor-core/dist/document/transactions/render-commit-envelope.js
194914
195110
  function isParagraphRangeRestore(prepared) {
194915
195111
  return prepared.source.kind === "paragraphRangeCollapse" && prepared.source.changeMode === "direct" && prepared.backendExtensions.storySurface?.historyReplay?.direction === "undo";
@@ -194963,7 +195159,7 @@ function cloneEnvelopeValue(value) {
194963
195159
  return value.map((entry) => cloneEnvelopeValue(entry));
194964
195160
  if (value == null || typeof value !== "object")
194965
195161
  return value;
194966
- if (isIssuedTrackedAnnotationHistoryOwner(value) || isIssuedTrackedAnnotationHistoryCapsule(value) || isIssuedTrackedAnnotationHistoryGroupCapsule(value))
195162
+ if (isIssuedTrackedAnnotationHistoryOwner(value) || isIssuedTrackedAnnotationHistoryCapsule(value) || isIssuedTrackedAnnotationHistoryGroupCapsule(value) || isIssuedTrackedAnnotationReconstruction(value))
194967
195163
  return value;
194968
195164
  const clone2 = {};
194969
195165
  for (const [key3, entry] of Object.entries(value)) {
@@ -197374,6 +197570,8 @@ function collapseSDRenderCommitEnvelopes(commits) {
197374
197570
  const last = commits[commits.length - 1];
197375
197571
  if (commits.some((commit) => commit.documentEpoch !== last.documentEpoch))
197376
197572
  return null;
197573
+ if (commits.some((commit) => commit.trackedAnnotationReconstruction != null && !readIssuedTrackedAnnotationReconstruction(commit) || commit.trackedAnnotationSteps?.some((step2) => step2.trackedAnnotationReconstruction != null) && (commit.classification.kind !== "broad" || commit.sourceProjectionEffect != null || commit.sourceProjectionSteps != null)))
197574
+ return null;
197377
197575
  const reviewReplicaCommits = collapseReviewReplicaCommitsForAggregate(commits, first, last);
197378
197576
  const localHistory = collapseNarrowTextHistoryCommits(commits) ?? collapseSecondaryTextHistoryCommits(commits);
197379
197577
  const trackedAnnotations = collapseTrackedAnnotationsForAggregate(commits);
@@ -197467,7 +197665,8 @@ function collapseTrackedAnnotationSteps(commits) {
197467
197665
  ...commit.trackedAnnotationRemovals != null ? { trackedAnnotationRemovals: commit.trackedAnnotationRemovals } : {},
197468
197666
  ...commit.trackedAnnotationHistory ? { trackedAnnotationHistory: commit.trackedAnnotationHistory } : {},
197469
197667
  ...commit.trackedAnnotationHistoryGroup ? { trackedAnnotationHistoryGroup: commit.trackedAnnotationHistoryGroup } : {},
197470
- ...commit.trackedAnnotationHistoryGroup ? { updatedRefs: commit.facts.updatedRefs } : {},
197668
+ ...commit.trackedAnnotationReconstruction ? { trackedAnnotationReconstruction: commit.trackedAnnotationReconstruction } : {},
197669
+ ...commit.trackedAnnotationHistoryGroup || commit.trackedAnnotationReconstruction ? { updatedRefs: commit.facts.updatedRefs } : {},
197471
197670
  ...commit.classification.kind === "broad" && commit.classification.reason === "tracked-annotation-unproved" && trackedAnnotations == null ? { unproved: true } : {}
197472
197671
  });
197473
197672
  }
@@ -199571,7 +199770,7 @@ function locateExactResidentBodyChild(state, storyId, partUri, byteStart, byteEn
199571
199770
  const matches = [];
199572
199771
  for (const chunk of chunks) {
199573
199772
  const revision = state.stories.get(storyId)?.descriptor.revision;
199574
- const issued5 = revision && readIssuedSourceChunkBodyChild({
199773
+ const issued6 = revision && readIssuedSourceChunkBodyChild({
199575
199774
  chunk: captureSourceChunkReadSnapshot(chunk).descriptor,
199576
199775
  storyId,
199577
199776
  storyRevision: revision,
@@ -199579,8 +199778,8 @@ function locateExactResidentBodyChild(state, storyId, partUri, byteStart, byteEn
199579
199778
  byteStart,
199580
199779
  byteEnd
199581
199780
  });
199582
- if (issued5) {
199583
- matches.push(issued5);
199781
+ if (issued6) {
199782
+ matches.push(issued6);
199584
199783
  continue;
199585
199784
  }
199586
199785
  const cached2 = cache?.get(chunk);
@@ -199919,6 +200118,7 @@ var init_render_commit_envelope = __esm(() => {
199919
200118
  init_resident_paragraph_ownership();
199920
200119
  init_structural_tracked_carrier_partition();
199921
200120
  init_tracked_annotation_history();
200121
+ init_tracked_annotation_reconstruction();
199922
200122
  init_paragraph_mark_markers();
199923
200123
  init_body_boundary_scan();
199924
200124
  init_comment_range_invariance();
@@ -200067,8 +200267,12 @@ function commitPreparedMutationInFrame(state, prepared, options) {
200067
200267
  historyEntry.renderReplay = renderCommit;
200068
200268
  if (historyEntry && backend.kind === "local")
200069
200269
  sealClosedHistoryGroupEntry(state, historyEntry);
200070
- if (historyEntry)
200270
+ if (historyEntry) {
200071
200271
  options.pushHistory(historyEntry);
200272
+ const authority = sealTrackedDecisionAnnotationReconstruction(state, prepared, historyEntry, applyResult, renderCommit);
200273
+ if (authority)
200274
+ renderCommit.trackedAnnotationReconstruction = authority;
200275
+ }
200072
200276
  if (historyEntry?.renderReplay)
200073
200277
  rememberResidentParagraphSplit(state, renderCommit);
200074
200278
  attachSDRenderCommitEnvelope(receipt2, renderCommit);
@@ -200080,6 +200284,7 @@ var init_commit_prepared_mutation = __esm(() => {
200080
200284
  init_execution_backend();
200081
200285
  init_history_text_replay();
200082
200286
  init_closed_history_group();
200287
+ init_tracked_annotation_reconstruction();
200083
200288
  init_render_commit_envelope();
200084
200289
  });
200085
200290
 
@@ -202660,7 +202865,7 @@ function commitTracked(input, view) {
202660
202865
  overlapEmittedRsids = [op.rsid];
202661
202866
  overlapTrackedTextAnnotations = spanningDeleteWIds.map((segmentWId) => ({
202662
202867
  changeId: op.rsid,
202663
- wId: String(segmentWId),
202868
+ wId: String(segmentWId + 1),
202664
202869
  kind: "delete",
202665
202870
  author: {
202666
202871
  name: stamping.author.name,
@@ -235954,14 +236159,18 @@ function captureRenderSourceSnapshot(state, snapshotId, currentSections) {
235954
236159
  const mainCoverage = mainStoryId ? coverage.get(mainStoryId) : null;
235955
236160
  const mainStory = mainStoryId ? storiesById.get(mainStoryId) : null;
235956
236161
  const signalSnapshot = state.sourceSignals.snapshot;
235957
- const sections = structuredClone(currentSections ?? (signalSnapshot?.packageRevision === binding.packageRevision && mainSignals?.storyRevision === mainStory?.revision && mainSignals?.completeness.sections === "complete" && mainCoverage?.facts.status === "source-complete" && signalSnapshot.sourceCoverageRevision === mainCoverage.facts.sourceCoverageRevision ? {
236162
+ const sectionCandidate = currentSections ?? (signalSnapshot?.packageRevision === binding.packageRevision && mainSignals?.storyRevision === mainStory?.revision && mainSignals?.completeness.sections === "complete" && mainCoverage?.facts.status === "source-complete" && signalSnapshot.sourceCoverageRevision === mainCoverage.facts.sourceCoverageRevision ? {
235958
236163
  packageRevision: binding.packageRevision,
235959
236164
  sourceCoverageRevision: signalSnapshot.sourceCoverageRevision,
235960
236165
  signalsRevision: signalSnapshot.signalsRevision,
235961
236166
  storyId: mainSignals.storyId,
235962
236167
  storyRevision: mainSignals.storyRevision,
235963
236168
  sections: mainSignals.sections
235964
- } : null));
236169
+ } : null);
236170
+ const sections = sectionCandidate && mainStory && mainCoverage && sectionCandidate.packageRevision === binding.packageRevision && sectionCandidate.storyId === mainStory.storyId && sectionCandidate.storyRevision === mainStory.revision && sectionCandidate.sourceCoverageRevision === mainCoverage.facts.sourceCoverageRevision && sectionCandidate.sections.every((section) => {
236171
+ const anchor = section.sourceAnchor;
236172
+ return anchor.stability === "byte-span" && section.storyId === mainStory.storyId && section.storyRevision === mainStory.revision && anchor.storyId === mainStory.storyId && anchor.storyRevision === mainStory.revision && anchor.partId === mainStory.ownerPartUri && anchor.partRevision === partsById.get(anchor.partId)?.revision;
236173
+ }) ? structuredClone(sectionCandidate) : null;
235965
236174
  const lazyReads = new Map;
235966
236175
  const lifetime = new AbortController;
235967
236176
  let pendingSections = null;
@@ -238209,7 +238418,7 @@ function applyDecisionToFragment(input) {
238209
238418
  return { ok: false, reason: "invalid-input" };
238210
238419
  const inner = xml.slice(wrapper.openEnd, wrapper.closeStart);
238211
238420
  const visible = visibleTextLengthInWrapper(inner, fragment3.kind);
238212
- switch (decisionKey(decision, fragment3.kind)) {
238421
+ switch (decisionKey2(decision, fragment3.kind)) {
238213
238422
  case "accept-ins":
238214
238423
  return {
238215
238424
  ok: true,
@@ -238272,7 +238481,7 @@ function applyDecisionToFragment(input) {
238272
238481
  return { ok: false, reason: "unsupported-context" };
238273
238482
  }
238274
238483
  }
238275
- function decisionKey(decision, kind) {
238484
+ function decisionKey2(decision, kind) {
238276
238485
  return `${decision}-${kind}`;
238277
238486
  }
238278
238487
  function visibleTextLengthInWrapper(inner, _kind) {
@@ -238357,7 +238566,7 @@ function applyPartialDecisionToFragment(input) {
238357
238566
  postChunk = `${postOpen}${post}${wrapperClose}`;
238358
238567
  emittedPost = true;
238359
238568
  }
238360
- switch (decisionKey(decision, fragment3.kind)) {
238569
+ switch (decisionKey2(decision, fragment3.kind)) {
238361
238570
  case "accept-ins":
238362
238571
  selChunk = sel;
238363
238572
  visibleTextDelta = 0;
@@ -244377,6 +244586,8 @@ function runTrackedChangeDecideCommitWithLookupContext(lookupContext, input, xml
244377
244586
  actorAttribution: { actorType: input.options.actorTag ?? "code" }
244378
244587
  }
244379
244588
  };
244589
+ if (restoredInsertion)
244590
+ captureTrackedDecisionAnnotationReconstruction(state, prepared);
244380
244591
  const receipt2 = commitPreparedMutation(state, prepared, { pushHistory: input.pushHistory });
244381
244592
  if (receipt2.status === "committed") {
244382
244593
  for (const [rsid, lineage] of pendingSplitLineage) {
@@ -247449,6 +247660,7 @@ var init_compile_tracked_change_decide = __esm(() => {
247449
247660
  init_revision_wid_allocator();
247450
247661
  init_semantic_style_dependencies();
247451
247662
  init_commit_prepared_mutation();
247663
+ init_tracked_annotation_reconstruction();
247452
247664
  init_review_comment_dependencies();
247453
247665
  init_review_resource_dependencies();
247454
247666
  init_compile_tracked_change_decide_local();
@@ -254065,7 +254277,7 @@ function compareTrackedStampPair(input, includeParagraphProperties = false) {
254065
254277
  function makeCompareHunkStampSource(primary, input) {
254066
254278
  const usedPairs = [];
254067
254279
  const reservedRsids = new Set([primary.del.rsid]);
254068
- let issued5 = false;
254280
+ let issued6 = false;
254069
254281
  let pendingRsids = [];
254070
254282
  let batchOrdinal = 0;
254071
254283
  const nextRsid = () => {
@@ -254082,8 +254294,8 @@ function makeCompareHunkStampSource(primary, input) {
254082
254294
  }
254083
254295
  };
254084
254296
  const next = () => {
254085
- if (!issued5) {
254086
- issued5 = true;
254297
+ if (!issued6) {
254298
+ issued6 = true;
254087
254299
  usedPairs.push(primary);
254088
254300
  return primary;
254089
254301
  }
@@ -265424,36 +265636,59 @@ var init_list_summary = __esm(() => {
265424
265636
 
265425
265637
  // ../../../v2/editor-core/dist/document/internal/review-projection-overlay.js
265426
265638
  function buildSDReviewProjectionOverlay(input) {
265639
+ return drainCatalogWork(buildReviewProjectionOverlaySteps(input));
265640
+ }
265641
+ function buildSDReviewProjectionOverlayCooperatively(input, options) {
265642
+ return runCatalogWork(buildReviewProjectionOverlaySteps(input), options);
265643
+ }
265644
+ function* buildReviewProjectionOverlaySteps(input) {
265427
265645
  const tableCatalogs = input.tableCatalogs ?? [];
265428
- const facts = Array.from(input.catalog.logical.byId.values(), (change) => buildProjectionFact(change, tableCatalogs));
265429
- const factsByLogicalId = new Map(facts.map((fact) => [fact.logicalId, fact]));
265430
- const unsupported2 = Array.from(input.catalog.raw.unsupportedByStory.values()).flat().map((fact) => ({
265431
- kind: "unsupported",
265432
- storyId: fact.storyId,
265433
- partUri: fact.partUri,
265434
- sourceStart: fact.byteStart,
265435
- sourceEnd: fact.byteEnd,
265436
- reason: fact.reason
265437
- }));
265646
+ const facts = [];
265647
+ const factsByLogicalId = new Map;
265648
+ for (const change of input.catalog.logical.byId.values()) {
265649
+ const fact = buildProjectionFact(change, tableCatalogs);
265650
+ facts.push(fact);
265651
+ factsByLogicalId.set(fact.logicalId, fact);
265652
+ yield;
265653
+ }
265654
+ const unsupported2 = [];
265655
+ for (const entries2 of input.catalog.raw.unsupportedByStory.values()) {
265656
+ for (const fact of entries2) {
265657
+ unsupported2.push({
265658
+ kind: "unsupported",
265659
+ storyId: fact.storyId,
265660
+ partUri: fact.partUri,
265661
+ sourceStart: fact.byteStart,
265662
+ sourceEnd: fact.byteEnd,
265663
+ reason: fact.reason
265664
+ });
265665
+ yield;
265666
+ }
265667
+ }
265668
+ const tableIdentities = [];
265669
+ for (const { storyId, tables } of tableCatalogs) {
265670
+ for (const table of tables) {
265671
+ const rows = [];
265672
+ for (const row of table.rows) {
265673
+ const cells = [];
265674
+ for (const cell of row.cells) {
265675
+ cells.push({ cellNodeId: cell.cellNodeId, identityProvenance: cell.identityProvenance });
265676
+ yield;
265677
+ }
265678
+ rows.push({ rowNodeId: row.rowNodeId, identityProvenance: row.identityProvenance, cells });
265679
+ yield;
265680
+ }
265681
+ tableIdentities.push({ storyId, tableNodeId: table.tableNodeId, identityProvenance: table.identityProvenance, rows });
265682
+ yield;
265683
+ }
265684
+ }
265438
265685
  return {
265439
265686
  replacementMode: input.catalog.logical.replacementMode,
265440
265687
  revision: { ...input.revision },
265441
265688
  facts,
265442
265689
  factsByLogicalId,
265443
265690
  unsupported: unsupported2,
265444
- tableIdentities: tableCatalogs.flatMap(({ storyId, tables }) => tables.map((table) => ({
265445
- storyId,
265446
- tableNodeId: table.tableNodeId,
265447
- identityProvenance: table.identityProvenance,
265448
- rows: table.rows.map((row) => ({
265449
- rowNodeId: row.rowNodeId,
265450
- identityProvenance: row.identityProvenance,
265451
- cells: row.cells.map((cell) => ({
265452
- cellNodeId: cell.cellNodeId,
265453
- identityProvenance: cell.identityProvenance
265454
- }))
265455
- }))
265456
- })))
265691
+ tableIdentities
265457
265692
  };
265458
265693
  }
265459
265694
  function reviewProjectionRevisionMatches(overlay, revision) {
@@ -270924,6 +271159,69 @@ function readSDDocumentSessionInternalReviewProjectionOverlay(session, options =
270924
271159
  })
270925
271160
  };
270926
271161
  }
271162
+ async function readSDDocumentSessionInternalReviewProjectionOverlayCooperatively(session, yieldPoint) {
271163
+ const internal = INTERNALS.get(session);
271164
+ if (!internal)
271165
+ throw new Error("internal: unknown SDDocumentSession instance");
271166
+ internal.assertNotDisposed();
271167
+ const state = internal.state;
271168
+ const revision = captureReviewProjectionRevision(state);
271169
+ const stale = () => ({
271170
+ status: "stale",
271171
+ expectedPackageRevision: revision.packageRevision,
271172
+ actualPackageRevision: state.packageRevision,
271173
+ expectedRevision: revision,
271174
+ actualRevision: captureReviewProjectionRevision(state)
271175
+ });
271176
+ if (hasFencedMainStory(state) && !hasCurrentTrackedChangeSourceInventory(state)) {
271177
+ return { status: "source-incomplete", revision, reason: "tracked-change-source-inventory-unavailable" };
271178
+ }
271179
+ const superseded = Symbol("review-source-superseded");
271180
+ const replacementMode = internal.trackedChangesReplacementMode;
271181
+ let borrowed = null;
271182
+ const current = () => revisionsEqual(revision, captureReviewProjectionRevision(state)) && (!borrowed || readCurrentTrackedChangeLogicalCatalog(state, replacementMode) === borrowed);
271183
+ const guardedYield = async () => {
271184
+ await yieldPoint();
271185
+ internal.assertNotDisposed();
271186
+ if (!current())
271187
+ throw superseded;
271188
+ };
271189
+ let captured = null;
271190
+ try {
271191
+ await guardedYield();
271192
+ borrowed = readCurrentTrackedChangeLogicalCatalog(state, replacementMode);
271193
+ if (!borrowed)
271194
+ captured = captureCooperativeTrackedCatalogRead(state, replacementMode, internal.assertNotDisposed);
271195
+ let catalog;
271196
+ if (borrowed)
271197
+ catalog = borrowed;
271198
+ else if (captured) {
271199
+ const result = await captured.build({ yieldPoint: guardedYield, sliceTargetMs: 8 });
271200
+ if (!result.promoted)
271201
+ return stale();
271202
+ catalog = result;
271203
+ } else
271204
+ catalog = accessTrackedChangeLogicalCatalog(state, replacementMode);
271205
+ if (!current())
271206
+ return stale();
271207
+ const tableCatalogs = [];
271208
+ for (const storyId of state.storyOrder) {
271209
+ const tables = await getOrBuildTableCatalogForStoryCooperatively(state, storyId, guardedYield);
271210
+ if (!current())
271211
+ return stale();
271212
+ if (tables)
271213
+ tableCatalogs.push({ storyId, tables: tables.tables });
271214
+ }
271215
+ const overlay = await buildSDReviewProjectionOverlayCooperatively({ catalog, tableCatalogs, revision }, { yieldPoint: guardedYield, sliceTargetMs: 8 });
271216
+ return current() ? { status: "success", overlay } : stale();
271217
+ } catch (error48) {
271218
+ if (error48 === superseded)
271219
+ return stale();
271220
+ throw error48;
271221
+ } finally {
271222
+ captured?.release();
271223
+ }
271224
+ }
270927
271225
  function captureReviewProjectionRevision(state) {
270928
271226
  const inventory = state.trackedChangeSourceInventory;
270929
271227
  const currentInventory = inventory && trackedChangeSourceInventoryMatchesState(state, inventory) ? inventory : null;
@@ -272767,11 +273065,22 @@ function attachHistoryRenderCommit(state, entry, direction, result, exactRender,
272767
273065
  ensureSDRenderCommitVersion(state, result);
272768
273066
  const renderCommit = replayCommit ?? (exactRender ? buildSDRenderCommitEnvelope(state, exactRender.prepared, result, exactRender.origin, { dirtyBlock: exactRender.dirtyBlock, historyReplay: true }) : buildSDBroadRenderCommitEnvelope(state, `${entry.txId}:${direction}`, result, "history-replay"));
272769
273067
  if (renderCommit) {
272770
- attachSDRenderCommitEnvelope(result, {
273068
+ const reconstructAnnotations = entry.forwardPatchGroup.source.kind === "trackedChangeDecide" && !renderCommit.trackedAnnotationHistory && !renderCommit.trackedAnnotationHistoryGroup && renderCommit.trackedAnnotations == null && (renderCommit.facts.createdRefs.some((ref3) => ref3.kind === "trackedChange") || renderCommit.facts.remappedRefs.some((remap) => remap.from.kind === "trackedChange" || remap.to.kind === "trackedChange"));
273069
+ const replay = {
272771
273070
  ...renderCommit,
272772
- ...sourceProjectionEffect ? { sourceProjectionEffect } : {},
273071
+ ...reconstructAnnotations ? {
273072
+ classification: renderCommit.classification.kind === "broad" && renderCommit.classification.reason !== "history-replay" ? renderCommit.classification : { kind: "broad", reason: "tracked-annotation-unproved" },
273073
+ sourceProjectionEffect: undefined,
273074
+ sourceProjectionSteps: undefined
273075
+ } : sourceProjectionEffect ? { sourceProjectionEffect } : {},
272773
273076
  historyReplay: true
272774
- });
273077
+ };
273078
+ if (reconstructAnnotations) {
273079
+ const authority = issueTrackedAnnotationReconstruction(state, entry, result, replay);
273080
+ if (authority)
273081
+ replay.trackedAnnotationReconstruction = authority;
273082
+ }
273083
+ attachSDRenderCommitEnvelope(result, replay);
272775
273084
  }
272776
273085
  return result;
272777
273086
  }
@@ -274056,7 +274365,7 @@ async function openSDDocumentSession(options) {
274056
274365
  function buildReadyPartial() {
274057
274366
  const signalsRevision = state.revisions.signalsRevision();
274058
274367
  const snapshot2 = buildReadySignals({
274059
- pkg: openResult.packageOpen.pkg,
274368
+ pkg: captureSourceSignalPackage(state),
274060
274369
  scan: openResult.bodyBoundaryScan,
274061
274370
  buffer: mainDocumentBuffer(openResult) ?? new Uint8Array(0),
274062
274371
  mainStoryId,
@@ -274424,7 +274733,7 @@ async function openSDDocumentSession(options) {
274424
274733
  chunkBytesProvider: fencedChunkBytesProvider,
274425
274734
  scan: signalsScan,
274426
274735
  spine: liveSourceSpine,
274427
- pkg: openResult.packageOpen.pkg,
274736
+ pkg: captureSourceSignalPackage(state),
274428
274737
  mainStoryId,
274429
274738
  mainOwnerPartId: mainPartId,
274430
274739
  sourceCoverageRevision: revisionGuard.sourceCoverageRevision,
@@ -274644,7 +274953,7 @@ async function openSDDocumentSession(options) {
274644
274953
  findings: preScanned.sectFindings,
274645
274954
  scan: bodyBoundaryScan,
274646
274955
  totalBodyChildren: sourceCompleteResult.spine.bodyChildCount,
274647
- pkg: openResult.packageOpen.pkg,
274956
+ pkg: captureSourceSignalPackage(state),
274648
274957
  mainStoryId,
274649
274958
  mainOwnerPartId: mainPartId,
274650
274959
  storyRevision: guard.storyRevision,
@@ -275195,6 +275504,7 @@ var init_sd_document_session = __esm(() => {
275195
275504
  init_sd_document_state();
275196
275505
  init_adopted_fenced_source_completion();
275197
275506
  init_render_commit_envelope();
275507
+ init_tracked_annotation_reconstruction();
275198
275508
  init_semantic_style_dependencies();
275199
275509
  init_revision_wid_scan();
275200
275510
  init_document_background();
@@ -318200,7 +318510,7 @@ function buildVisibleSelectionTarget(story, start, end) {
318200
318510
  ...distinctFootnotes(start.story ?? story, end.story ?? story) ? {} : { story }
318201
318511
  };
318202
318512
  }
318203
- function buildSelectionTarget(session, story, start, end, entries2) {
318513
+ function buildSelectionTarget(session, story, start, end, entries2, collapsed = false) {
318204
318514
  const hasTrackedEndpoint = start.trackedOffset != null || end.trackedOffset != null;
318205
318515
  if (!hasTrackedEndpoint)
318206
318516
  return buildVisibleSelectionTarget(story, start, end);
@@ -318217,6 +318527,9 @@ function buildSelectionTarget(session, story, start, end, entries2) {
318217
318527
  if (resolvedStart == null || resolvedEnd == null) {
318218
318528
  return null;
318219
318529
  }
318530
+ if (collapsed && startEntry === endEntry && start.offset === end.offset && resolvedStart === resolvedEnd && projectsOnlyDeletedControls(startMap, resolvedStart, start.offset)) {
318531
+ return buildVisibleSelectionTarget(story, start, end);
318532
+ }
318220
318533
  const [orderedStart, orderedEnd] = start.blockId === end.blockId && resolvedEnd < resolvedStart ? [resolvedEnd, resolvedStart] : [resolvedStart, resolvedEnd];
318221
318534
  return {
318222
318535
  kind: "selection",
@@ -318226,6 +318539,24 @@ function buildSelectionTarget(session, story, start, end, entries2) {
318226
318539
  coordinateSpace: "tracked"
318227
318540
  };
318228
318541
  }
318542
+ function projectsOnlyDeletedControls(map3, trackedOffset, visibleOffset) {
318543
+ let tracked = 0, visible = 0, deletedControl = false;
318544
+ for (const leaf of map3.leaves()) {
318545
+ if (leaf.trackedStart >= trackedOffset)
318546
+ break;
318547
+ const width = Math.min(leaf.trackedEnd, trackedOffset) - leaf.trackedStart;
318548
+ if (width <= 0)
318549
+ continue;
318550
+ if (leaf.trackedEnd - leaf.trackedStart === leaf.visibleEnd - leaf.visibleStart) {
318551
+ visible += width;
318552
+ } else if (leaf.kind === "control" && leaf.deleted && (leaf.control === "tab" || leaf.control === "br" || leaf.control === "cr") && leaf.trackedEnd <= trackedOffset && leaf.visibleStart === leaf.visibleEnd) {
318553
+ deletedControl = true;
318554
+ } else
318555
+ return false;
318556
+ tracked += width;
318557
+ }
318558
+ return deletedControl && tracked === trackedOffset && visible === visibleOffset;
318559
+ }
318229
318560
  function readParagraphInlineMap(session, entry) {
318230
318561
  const bytes = getSDDocumentSessionInternalPartRange(session, entry.partUri, entry.byteStart, entry.byteEnd);
318231
318562
  if (!bytes)
@@ -318292,9 +318623,25 @@ function resolveTableCellSelectionEntries(session, story, anchorBlockId, focusBl
318292
318623
  if (!index || !anchorEntry || index.duplicateParaIds.has(anchorBlockId) || index.duplicateParaIds.has(focusBlockId))
318293
318624
  return null;
318294
318625
  const catalog = readTableCatalogForSession(session, anchorEntry.storyId);
318295
- const anchor = catalog?.byParagraphId.get(anchorBlockId);
318296
- const focus = catalog?.byParagraphId.get(focusBlockId);
318297
- if (!anchor || !focus || anchor.table !== focus.table || anchor.cell === focus.cell)
318626
+ const owner = (blockId) => {
318627
+ const entry = index.byParaId(blockId), enclosing = catalog?.byParagraphId.get(blockId);
318628
+ if (!entry || !enclosing)
318629
+ return null;
318630
+ const table = tableForParagraph({ session }, anchorEntry.storyId, enclosing.table, entry);
318631
+ if (table === enclosing.table)
318632
+ return enclosing;
318633
+ for (const row of table.rows)
318634
+ for (const cell of row.cells) {
318635
+ if (entry.byteStart < cell.bodyByteStart || entry.byteEnd > cell.bodyByteEnd)
318636
+ continue;
318637
+ const paragraph2 = cell.paragraphs.find((candidate2) => candidate2.paragraphId === blockId && candidate2.byteStart === entry.byteStart && candidate2.byteEnd === entry.byteEnd);
318638
+ if (paragraph2)
318639
+ return { table, row, cell, paragraph: paragraph2 };
318640
+ }
318641
+ return null;
318642
+ };
318643
+ const anchor = owner(anchorBlockId), focus = owner(focusBlockId);
318644
+ if (!anchor || !focus || anchor.table.tableNodeId !== focus.table.tableNodeId || anchor.table.tableByteStart !== focus.table.tableByteStart || anchor.table.tableByteEnd !== focus.table.tableByteEnd || anchor.cell.cellNodeId === focus.cell.cellNodeId)
318298
318645
  return null;
318299
318646
  for (const endpoint of [anchor, focus]) {
318300
318647
  if (endpoint.paragraph.isDirectCellChild)
@@ -318404,7 +318751,7 @@ function resolveBrowserLiveSelectionForSession(session, input, options = {}) {
318404
318751
  const resolved = resolveEntries(session, input);
318405
318752
  if (!resolved)
318406
318753
  return null;
318407
- const selectionTarget = buildSelectionTarget(session, input.story, resolved.start, resolved.end, resolved.entries);
318754
+ const selectionTarget = buildSelectionTarget(session, input.story, resolved.start, resolved.end, resolved.entries, input.collapsed === true);
318408
318755
  if (!selectionTarget)
318409
318756
  return null;
318410
318757
  const contiguous = resolved.entries.every((entry, i2) => i2 === 0 || entry.ordinal === resolved.entries[i2 - 1].ordinal + 1);
@@ -318433,7 +318780,7 @@ function resolveBrowserLiveSelectionForSession(session, input, options = {}) {
318433
318780
  }
318434
318781
  function resolveBrowserSelectionReviewIdsForSession(session, input, options = {}) {
318435
318782
  const resolved = resolveEntries(session, input);
318436
- if (!resolved || !buildSelectionTarget(session, input.story, resolved.start, resolved.end, resolved.entries))
318783
+ if (!resolved || !buildSelectionTarget(session, input.story, resolved.start, resolved.end, resolved.entries, input.collapsed === true))
318437
318784
  return null;
318438
318785
  return readActiveReviewIds(session, resolved.entries, resolved.target.segments, options);
318439
318786
  }
@@ -318834,6 +319181,7 @@ var TEXT_DECODER7, ACTIVE_MARK_ORDER;
318834
319181
  var init_live_selection = __esm(() => {
318835
319182
  init_sd_document_session_internal();
318836
319183
  init_sd_document_session_internal();
319184
+ init_xml3();
318837
319185
  init_footnote_range();
318838
319186
  TEXT_DECODER7 = new TextDecoder;
318839
319187
  ACTIVE_MARK_ORDER = ["bold", "italic", "underline", "strikethrough"];
@@ -361020,6 +361368,15 @@ var init_numbering2 = __esm(() => {
361020
361368
  // ../../../v2/document-api-v2-adapter/dist/content-projection/block-numbering.js
361021
361369
  function createReviewAwareBlockNumberingProjector(context, storyId, reviewMode) {
361022
361370
  const overlayRead = readSDDocumentSessionInternalReviewProjectionOverlay(context.session);
361371
+ return blockNumberingProjector(context, storyId, reviewMode, overlayRead);
361372
+ }
361373
+ async function createReviewAwareBlockNumberingProjectorCooperatively(context, storyId, reviewMode, yieldPoint) {
361374
+ const overlayRead = await readSDDocumentSessionInternalReviewProjectionOverlayCooperatively(context.session, yieldPoint);
361375
+ if (overlayRead.status === "stale")
361376
+ return null;
361377
+ return blockNumberingProjector(context, storyId, reviewMode, overlayRead);
361378
+ }
361379
+ function blockNumberingProjector(context, storyId, reviewMode, overlayRead) {
361023
361380
  const boundedEmptyOverlay = overlayRead.status === "source-incomplete";
361024
361381
  const overlay = overlayRead.status === "success" ? overlayRead.overlay : emptyReviewProjectionOverlay(getSDDocumentSessionInternalReviewProjectionRevision(context.session));
361025
361382
  const model = projectionStyleModel(context);
@@ -361432,7 +361789,9 @@ async function buildReviewAwareBlockNumberingCooperatively(context, storyId, ind
361432
361789
  return null;
361433
361790
  tableContexts.set(story.storyId, tableContext);
361434
361791
  }
361435
- const projector = createReviewAwareBlockNumberingProjector(context, storyId, reviewMode);
361792
+ const projector = await createReviewAwareBlockNumberingProjectorCooperatively(context, storyId, reviewMode, yieldPoint);
361793
+ if (!projector || !current())
361794
+ return null;
361436
361795
  const partUriBytes = new Map;
361437
361796
  let ordinal = 0;
361438
361797
  for (const source of blockNumberingParagraphs(stories)) {
@@ -361690,6 +362049,7 @@ class V2BlocksAdapter {
361690
362049
  this.lastBlocksListStructuralProbe = streamed.probe;
361691
362050
  return;
361692
362051
  }
362052
+ throw new Error("Block list could not stabilize after cooperative source changes.");
361693
362053
  }
361694
362054
  list(input) {
361695
362055
  const inlineModelDiagnosticsBefore = getParagraphInlineModelAllocationDiagnostics();
@@ -376587,6 +376947,15 @@ class V2TrackedChangesAdapter {
376587
376947
  const residentViews = new Map;
376588
376948
  let fullView;
376589
376949
  const storyFilter = story ? resolveStoryFilter(story, this.context.session) : undefined;
376950
+ const structuralScope = source?.structuralOwner ? resolveReviewSnapshotStructuralScope(this.context, source, storyFilter) : undefined;
376951
+ if (source?.structuralOwner && !structuralScope)
376952
+ return {
376953
+ requestedIds: [...new Set(requestedIds)],
376954
+ canonicalIds: [],
376955
+ items: [],
376956
+ unresolvedTrackedChangeIds: [...new Set(requestedIds)]
376957
+ };
376958
+ const sourceFilter = source && { ...source, structuralScope: structuralScope ?? undefined };
376590
376959
  const resolveSession = createTrackedChangeFragmentResolveSession();
376591
376960
  const seenInput = new Set;
376592
376961
  const seenCanonical = new Set;
@@ -376605,7 +376974,7 @@ class V2TrackedChangesAdapter {
376605
376974
  if (resident) {
376606
376975
  view = resident;
376607
376976
  for (const requested of requestedIds) {
376608
- if (resolveReviewSnapshotTrackedChangeId(resident, requested, storyFilter, source))
376977
+ if (resolveReviewSnapshotTrackedChangeId(resident, requested, storyFilter, sourceFilter))
376609
376978
  residentViews.set(requested, resident);
376610
376979
  }
376611
376980
  } else
@@ -376613,7 +376982,7 @@ class V2TrackedChangesAdapter {
376613
376982
  }
376614
376983
  const { logical } = view;
376615
376984
  const localEntry = getLocalTrackedTextEntry(this.context, id);
376616
- const entry = localEntry && (!storyFilter || logicalEntryMatchesStoryFilter(localEntry, storyFilter)) && reviewSnapshotEntryMatchesSource(localEntry, source) ? localEntry : resolveReviewSnapshotTrackedChangeId(view, id, storyFilter, source);
376985
+ const entry = localEntry && (!storyFilter || logicalEntryMatchesStoryFilter(localEntry, storyFilter)) && reviewSnapshotEntryMatchesSource(localEntry, sourceFilter, id) ? localEntry : resolveReviewSnapshotTrackedChangeId(view, id, storyFilter, sourceFilter);
376617
376986
  if (!entry) {
376618
376987
  unresolvedTrackedChangeIds.push(id);
376619
376988
  continue;
@@ -376624,6 +376993,13 @@ class V2TrackedChangesAdapter {
376624
376993
  seenCanonical.add(entry.id);
376625
376994
  items.push(buildDiscoveryItem2(entry, this.context, logical, undefined, resolveSession));
376626
376995
  }
376996
+ if (source?.structuralOwner && !reviewSnapshotSourceIsCurrent(this.context, source.structuralOwner))
376997
+ return {
376998
+ requestedIds: orderedRequestedIds,
376999
+ canonicalIds: [],
377000
+ items: [],
377001
+ unresolvedTrackedChangeIds: orderedRequestedIds
377002
+ };
376627
377003
  return { requestedIds: orderedRequestedIds, canonicalIds, items, unresolvedTrackedChangeIds };
376628
377004
  }
376629
377005
  moveFragmentWordIds(requestedIds) {
@@ -379335,6 +379711,26 @@ function addReviewGroupChildRefs(args) {
379335
379711
  function projectFormattingDeltaSummary(entry) {
379336
379712
  if (entry.type !== "formatting")
379337
379713
  return null;
379714
+ const delta = entry.formattingDelta;
379715
+ if (entry.subtype === "run-formatting" && delta) {
379716
+ const value2 = (input) => {
379717
+ if (input === undefined)
379718
+ return "∅";
379719
+ if (input === true)
379720
+ return "on";
379721
+ if (input === false || input === null)
379722
+ return "off";
379723
+ return typeof input === "object" ? JSON.stringify(input) : String(input);
379724
+ };
379725
+ const keys = new Set([...Object.keys(delta.beforeProperties), ...Object.keys(delta.afterProperties)]);
379726
+ const differences = [];
379727
+ for (const key3 of keys) {
379728
+ const before = delta.beforeProperties[key3], after = delta.afterProperties[key3];
379729
+ if (JSON.stringify(before) !== JSON.stringify(after))
379730
+ differences.push(`${key3}: ${value2(before)} → ${value2(after)}`);
379731
+ }
379732
+ return differences.length ? `run formatting revision: ${differences.join(", ")}` : "run formatting revision";
379733
+ }
379338
379734
  return entry.excerpt || null;
379339
379735
  }
379340
379736
  function projectSourceIds(entry) {
@@ -379486,7 +379882,7 @@ function logicalEntriesForSourceAlias(logical, alias) {
379486
379882
  function resolveReviewSnapshotTrackedChangeId(view, requestedId, storyFilter, source) {
379487
379883
  const matches = new Map;
379488
379884
  const add = (entry) => {
379489
- if (!reviewSnapshotEntryMatchesSource(entry, source))
379885
+ if (!reviewSnapshotEntryMatchesSource(entry, source, requestedId))
379490
379886
  return;
379491
379887
  const canonical = resolveReviewSnapshotOwner(view.logical, entry);
379492
379888
  if (!canonical)
@@ -379519,16 +379915,51 @@ function resolveReviewSnapshotOwner(logical, entry) {
379519
379915
  let current = entry;
379520
379916
  while (!seen.has(current.id)) {
379521
379917
  seen.add(current.id);
379522
- const parent = resolveSubsumedLogicalChange(logical, current);
379918
+ const reviewParentId = reviewGroupDisplayParentId(current);
379919
+ const parent = reviewParentId ? logical.byId.get(reviewParentId) : resolveSubsumedLogicalChange(logical, current);
379920
+ if (!parent)
379921
+ return null;
379523
379922
  if (parent.id === current.id)
379524
- return current;
379923
+ return isVisibleLogicalTrackedChange(current) ? current : null;
379924
+ if (parent.storyId !== current.storyId || parent.partUri !== current.partUri)
379925
+ return null;
379926
+ if (reviewParentId && (parent.reviewGroup?.role !== "parent" || parent.reviewGroup.kind !== current.reviewGroup?.kind || !parent.reviewGroup.ownedChildIds.includes(current.id)))
379927
+ return null;
379525
379928
  current = parent;
379526
379929
  }
379527
379930
  return null;
379528
379931
  }
379529
- function reviewSnapshotEntryMatchesSource(entry, source) {
379932
+ function reviewSnapshotEntryMatchesSource(entry, source, requestedId) {
379530
379933
  if (source?.partUri && entry.partUri !== source.partUri)
379531
379934
  return false;
379935
+ if (source?.structuralScope) {
379936
+ const scope = source.structuralScope;
379937
+ const aliases = requestedId ? reviewSnapshotRequestedIdAliases(requestedId) : [];
379938
+ const structural = entry.structuralFragments.some((fragment4) => {
379939
+ if (fragment4.partUri !== scope.partUri || fragment4.storyId !== scope.storyId || requestedId !== entry.id && ![fragment4.wId, fragment4.entityKey, fragment4.rsid, fragment4.enclosingParagraphRsid].some((alias) => alias != null && aliases.includes(alias)))
379940
+ return false;
379941
+ if (source.structuralOwner?.author != null && fragment4.author.name !== source.structuralOwner.author || source.structuralOwner?.date != null && fragment4.date !== source.structuralOwner.date)
379942
+ return false;
379943
+ if (!fragment4.structuralKind.startsWith(`${scope.kind}-`))
379944
+ return false;
379945
+ if (source.kind === "insert" && !fragment4.structuralKind.endsWith("-insertion") || source.kind === "delete" && !fragment4.structuralKind.endsWith("-deletion") || source.kind === "format" && /-(?:insertion|deletion)$/.test(fragment4.structuralKind))
379946
+ return false;
379947
+ const { sourceByteStart: start, sourceByteEnd: end } = fragment4;
379948
+ if (start == null || end == null || !Number.isSafeInteger(start) || !Number.isSafeInteger(end) || end <= start)
379949
+ return false;
379950
+ return start >= scope.start && end <= scope.propertiesEnd || start <= scope.start && end >= scope.end;
379951
+ });
379952
+ const properties2 = scope.kind === "cell" && source.kind !== "insert" && source.kind !== "delete" && entry.formattingFragments.some((fragment4) => {
379953
+ if (fragment4.subtype !== "cell" || fragment4.partUri !== scope.partUri || fragment4.storyId !== scope.storyId || requestedId !== entry.id && ![fragment4.wId, fragment4.entityKey].some((alias) => alias != null && aliases.includes(alias)))
379954
+ return false;
379955
+ if (source.structuralOwner?.author != null && fragment4.author.name !== source.structuralOwner.author || source.structuralOwner?.date != null && fragment4.date !== source.structuralOwner.date)
379956
+ return false;
379957
+ const { sourceByteStart: start, sourceByteEnd: end } = fragment4;
379958
+ return start != null && end != null && Number.isSafeInteger(start) && Number.isSafeInteger(end) && start >= scope.start && end > start && end <= scope.propertiesEnd;
379959
+ });
379960
+ if (entry.storyId !== scope.storyId || entry.partUri !== scope.partUri || !structural && !properties2)
379961
+ return false;
379962
+ }
379532
379963
  if (!source?.kind)
379533
379964
  return true;
379534
379965
  if (source.kind === "format")
@@ -379536,6 +379967,31 @@ function reviewSnapshotEntryMatchesSource(entry, source) {
379536
379967
  const insertion = source.kind === "insert";
379537
379968
  return entry.fragments.some((fragment4) => insertion ? fragment4.kind === "ins" || fragment4.kind === "moveTo" : fragment4.kind === "del" || fragment4.kind === "moveFrom") || entry.structuralFragments.some((fragment4) => fragment4.structuralKind.endsWith(insertion ? "-insertion" : "-deletion"));
379538
379969
  }
379970
+ function reviewSnapshotSourceIsCurrent(context, owner) {
379971
+ const current = getSDDocumentSessionInternalSourceCommit(context.session);
379972
+ return current.documentEpoch === owner.documentEpoch && current.commitSequence === owner.commitSequence && String(getSDDocumentSessionInternalPackageRevision(context.session)) === owner.packageRevision;
379973
+ }
379974
+ function resolveReviewSnapshotStructuralScope(context, source, story) {
379975
+ const owner = source.structuralOwner;
379976
+ if (!owner || !source.partUri || !reviewSnapshotSourceIsCurrent(context, owner) || !owner.tableNodeId || !Number.isSafeInteger(owner.commitSequence) || owner.commitSequence < 0 || !Number.isSafeInteger(owner.rowIndex) || owner.rowIndex < 0 || owner.cellIndex != null && (!Number.isSafeInteger(owner.cellIndex) || owner.cellIndex < 0))
379977
+ return null;
379978
+ const matches = listSDDocumentSessionInternalStories(context.session).flatMap((candidate2) => {
379979
+ const { storyId, partUri: partUri2 } = candidate2;
379980
+ if (partUri2 !== source.partUri || story?.kind === "body-only" && !isBodyStoryId2(storyId) || story?.kind === "specific" && !story.storyIds?.has(storyId))
379981
+ return [];
379982
+ const catalog = readTableCatalogForSession(context.session, storyId);
379983
+ return (catalog?.tables ?? []).filter((table2) => table2.tableNodeId === owner.tableNodeId).map((table2) => ({ table: table2, partUri: partUri2 }));
379984
+ });
379985
+ if (matches.length !== 1)
379986
+ return null;
379987
+ const { table, partUri } = matches[0];
379988
+ const row = table.rows[owner.rowIndex];
379989
+ const cell = owner.cellIndex != null ? row?.cells[owner.cellIndex] : undefined;
379990
+ if (!row || owner.cellIndex != null && !cell)
379991
+ return null;
379992
+ const common = { storyId: table.storyId, partUri };
379993
+ return cell ? { ...common, kind: "cell", start: cell.cellByteStart, end: cell.cellByteEnd, propertiesEnd: cell.bodyByteStart } : { ...common, kind: "row", start: row.rowByteStart, end: row.rowByteEnd, propertiesEnd: row.cells[0]?.cellByteStart ?? row.rowBodyByteEnd };
379994
+ }
379539
379995
  function resolveWordSourceTrackedChangeId(view, requestedId) {
379540
379996
  const matches = new Map;
379541
379997
  for (const alias of reviewSnapshotRequestedIdAliases(requestedId)) {
@@ -386713,7 +387169,7 @@ function allocateHeaderFooterUri(context, kind) {
386713
387169
  }
386714
387170
  function emptyHeaderFooterXml(kind, paraId) {
386715
387171
  const root = kind === "header" ? "w:hdr" : "w:ftr";
386716
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>` + `<${root}${renderRootNamespaceDeclarations()}>` + `<w:p w14:paraId="${paraId}"/>` + `</${root}>`;
387172
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>` + `<${root}${renderRootNamespaceDeclarations()}>` + `<w:p w14:paraId="${paraId}"></w:p>` + `</${root}>`;
386717
387173
  }
386718
387174
  function unsupportedTrackedHeaderFooterMutation() {
386719
387175
  return { success: false, failure: {
@@ -452032,7 +452488,7 @@ function hasPendingOrderChanges(scope) {
452032
452488
  return true;
452033
452489
  if (Object.is(type, scope.meta) && [...keys3].some((key3) => key3?.startsWith(GROUP_PREFIX)))
452034
452490
  return true;
452035
- if (type instanceof YMap && type.parent === scope.blocks && keys3.has(BLOCK_KEY.blockId))
452491
+ if (type instanceof YMap && type.parent === scope.blocks && (keys3.has(BLOCK_KEY.blockId) || keys3.has(BLOCK_KEY.mergedIntoBlockId)))
452036
452492
  return true;
452037
452493
  }
452038
452494
  return false;
@@ -452059,7 +452515,7 @@ function readRetainedOrder(scope) {
452059
452515
  retained.byId = null;
452060
452516
  };
452061
452517
  const blocksChanged = (events) => {
452062
- if (events.some((event) => event.target === scope.blocks || event.target instanceof YMap && event.keysChanged.has(BLOCK_KEY.blockId)))
452518
+ if (events.some((event) => event.target === scope.blocks || event.target instanceof YMap && (event.keysChanged.has(BLOCK_KEY.blockId) || event.keysChanged.has(BLOCK_KEY.mergedIntoBlockId))))
452063
452519
  invalidate();
452064
452520
  };
452065
452521
  const metadataChanged = (event) => {
@@ -462588,6 +463044,33 @@ function emissionContext(owner, xml) {
462588
463044
  return cached2.context;
462589
463045
  }
462590
463046
  function materializeProjection(input) {
463047
+ return materializeProjectionInternal(input);
463048
+ }
463049
+ function materializeDeletedTableSourceProjection(input) {
463050
+ const manifest = readRoomManifest(input.rootDoc);
463051
+ if (!manifest.snapshot || manifest.diagnostics.length)
463052
+ throw new Error("deleted-table source requires its valid room manifest");
463053
+ for (const handle of input.shardRegistry.listStories()) {
463054
+ if (handle.rootDoc !== input.rootDoc || input.rootDoc.getMap("content").get(handle.shardId) !== handle.scope || handle.bootstrap?.sourcePackageSha256 !== manifest.snapshot.meta.createdFrom.sha256Zip) {
463055
+ throw new Error("deleted-table source does not belong to this room and original package");
463056
+ }
463057
+ }
463058
+ const recovery = { count: 0 };
463059
+ const output = materializeProjectionInternal({ ...input, previousRecord: null }, recovery);
463060
+ if (recovery.count === 0)
463061
+ throw new Error("no recoverable deleted-table source");
463062
+ for (const story of output.record.stories) {
463063
+ const parsed = collectXmlElementRanges(story.xml);
463064
+ const handle = input.shardRegistry.listStories().find((handle2) => snapshotStoryShard(shardReadTarget(handle2)).meta.storyId === story.storyId);
463065
+ const live = handle ? snapshotStoryShard(shardReadTarget(handle)).blocks.map((block) => block.blockId) : [];
463066
+ const ids = parsed.ranges.filter((range) => range.tag.namespaceUri === WORD_NAMESPACE10 && range.tag.localName === "p").map((range) => range.tag.attributes.find((attribute3) => attribute3.namespaceUri === "http://schemas.microsoft.com/office/word/2010/wordml" && attribute3.localName === "paraId")?.value);
463067
+ if (parsed.errors.length || ids.length !== live.length || ids.some((id2, index2) => id2 !== live[index2])) {
463068
+ throw new Error("deleted-table source does not preserve the complete current paragraph order");
463069
+ }
463070
+ }
463071
+ return output;
463072
+ }
463073
+ function materializeProjectionInternal(input, recovery) {
462591
463074
  const readStorySnapshot = input.readStorySnapshot ?? snapshotStoryShard;
462592
463075
  const previousById = new Map;
462593
463076
  const previousByPartUri = new Map;
@@ -462716,7 +463199,11 @@ function materializeProjection(input) {
462716
463199
  continue;
462717
463200
  }
462718
463201
  const sourceXmlByteAligned = isByteAlignedSourceXml(bootstrap);
462719
- const tableReplacements = readTableStructuralReplacements(readTarget);
463202
+ let tableReplacements = readTableStructuralReplacements(readTarget);
463203
+ if (recovery && tableReplacements.some((table) => table.tableNodeId !== table.entryKey)) {
463204
+ tableReplacements = recoverDeletedTableReplacements(handle, bootstrap, tableReplacements);
463205
+ recovery.count += 1;
463206
+ }
462720
463207
  const previousBlockIndex = previous3 ? blockDigestIndex(previous3.blockDigests) : null;
462721
463208
  const insertedBlockHint = previousBlockIndex && [...dirtyStoryBlocks.get(handle.shardId) ?? []].some((blockId) => !previousBlockIndex.has(blockId));
462722
463209
  const structuralSnapshot = previous3 && (wholeStoryDirtyShardIds.has(handle.shardId) || insertedBlockHint || tableReplacements.length === 0 && input.dirty.some((record4) => record4.shardId === handle.shardId && record4.kind === PROJECTION_DIRTY_KIND.storyBlocks)) ? readStorySnapshot(readTarget) : null;
@@ -463990,6 +464477,73 @@ function remapTableStructuralOverlaysAfterStoryXmlPatch(input) {
463990
464477
  };
463991
464478
  });
463992
464479
  }
464480
+ function recoverDeletedTableReplacements(handle, bootstrap, replacements) {
464481
+ const source = bootstrap?.sourceXml;
464482
+ if (!source)
464483
+ throw new Error("deleted-table source requires its original package");
464484
+ const parsed = collectXmlElementRanges(source);
464485
+ if (parsed.errors.length)
464486
+ throw new Error("deleted-table source has invalid original XML");
464487
+ const target = shardReadTarget(handle);
464488
+ const snapshot3 = snapshotStoryShard(target);
464489
+ const live = new Set(snapshot3.blocks.map((block) => block.blockId));
464490
+ const tables2 = getStoryTablesMap(target);
464491
+ if (tables2.size !== replacements.length || live.size !== snapshot3.blocks.length) {
464492
+ throw new Error("deleted-table source has ambiguous owners");
464493
+ }
464494
+ const allowedKeys = new Set([
464495
+ "tableNodeId",
464496
+ "storyId",
464497
+ "partUri",
464498
+ "lastPreparedTxId",
464499
+ "lastDeltaKind",
464500
+ "xml",
464501
+ "sourceXmlStart",
464502
+ "sourceXmlEnd",
464503
+ "sourceByteStart",
464504
+ "sourceByteEnd",
464505
+ "affectedRows",
464506
+ "affectedCells",
464507
+ "affectedBlocks",
464508
+ "tableBlocks",
464509
+ "nonTableAffectedBlocks"
464510
+ ]);
464511
+ const entries4 = replacements.map((table) => {
464512
+ const raw = tables2.get(table.entryKey);
464513
+ const span = findUniqueTableSpanFromTableNodeId(source, table.entryKey);
464514
+ if (!isYMap(raw) || !span || [...raw.keys()].some((key3) => !allowedKeys.has(key3)) || raw.get("storyId") !== snapshot3.meta.storyId || raw.get("partUri") !== snapshot3.meta.sourcePartUri || table.deltaKind !== "table.rewrite" || table.xml !== "" || !table.lastPreparedTxId || table.tableBlockIds.length || table.nonTableAffectedBlockIds.length) {
464515
+ throw new Error("deleted-table source has an unsupported tombstone");
464516
+ }
464517
+ for (const key3 of ["affectedRows", "affectedCells", "affectedBlocks", "tableBlocks", "nonTableAffectedBlocks"]) {
464518
+ const membership = raw.get(key3);
464519
+ if (!(membership instanceof YArray))
464520
+ throw new Error("deleted-table source has malformed membership");
464521
+ const values2 = membership.toArray();
464522
+ if (values2.some((value2) => typeof value2 !== "string" || value2.length === 0) || new Set(values2).size !== values2.length) {
464523
+ throw new Error("deleted-table source has malformed membership");
464524
+ }
464525
+ }
464526
+ const paragraphs2 = parsed.ranges.filter((range) => range.tag.namespaceUri === WORD_NAMESPACE10 && range.tag.localName === "p" && range.start > span.start && range.end < span.end);
464527
+ const ids = paragraphs2.map((paragraph4) => paragraph4.tag.attributes.find((attribute3) => attribute3.namespaceUri === "http://schemas.microsoft.com/office/word/2010/wordml" && attribute3.localName === "paraId")?.value);
464528
+ const affected = new Set(table.affectedBlockIds);
464529
+ if (!ids.length || ids.some((id2) => !id2 || !affected.has(id2) || live.has(id2)) || new Set(ids).size !== ids.length || affected.size !== ids.length || affected.size !== table.affectedBlockIds.length || snapshot3.blocks.some((block) => block.structuralRefs.tableNodeId === table.entryKey)) {
464530
+ throw new Error("deleted-table source does not prove complete removed membership");
464531
+ }
464532
+ return { table, raw, span };
464533
+ }).sort((a, b) => a.span.start - b.span.start);
464534
+ let removedBytes = 0;
464535
+ let previousEnd = 0;
464536
+ return entries4.map(({ table, raw, span }) => {
464537
+ const start = UTF8_ENCODER3.encode(source.slice(0, span.start)).length - removedBytes;
464538
+ const length3 = UTF8_ENCODER3.encode(source.slice(span.start, span.end)).length;
464539
+ if (span.start < previousEnd || raw.get("sourceByteStart") !== start || raw.get("sourceByteEnd") !== start + length3) {
464540
+ throw new Error("deleted-table source byte ownership does not match its serial deletions");
464541
+ }
464542
+ previousEnd = span.end;
464543
+ removedBytes += length3;
464544
+ return { ...table, tableNodeId: table.entryKey, sourceXmlStart: span.start, sourceXmlEnd: span.end };
464545
+ });
464546
+ }
463993
464547
  function removeRedundantSplitSeparators(projection, redundantBlockIds) {
463994
464548
  const entries4 = [...projection.blockDigests];
463995
464549
  const changedIndices = [];
@@ -465458,7 +466012,7 @@ function readTableSplitChildren(table) {
465458
466012
  function readTableStructuralReplacements(target) {
465459
466013
  const out = [];
465460
466014
  let liveBlockIds;
465461
- getStoryTablesMap(target).forEach((value2) => {
466015
+ getStoryTablesMap(target).forEach((value2, entryKey2) => {
465462
466016
  if (!isYMap(value2))
465463
466017
  return;
465464
466018
  const tableNodeId = value2.get("tableNodeId");
@@ -465508,6 +466062,7 @@ function readTableStructuralReplacements(target) {
465508
466062
  return;
465509
466063
  }
465510
466064
  out.push({
466065
+ entryKey: entryKey2,
465511
466066
  tableNodeId,
465512
466067
  lastPreparedTxId,
465513
466068
  sourceXmlStart: start,
@@ -466747,6 +467302,7 @@ var init_materialize = __esm(() => {
466747
467302
  init_content_control_groups();
466748
467303
  init_scope3();
466749
467304
  init_safety();
467305
+ init_read2();
466750
467306
  init_canonical();
466751
467307
  init_package_xml();
466752
467308
  init_reorder_story_owners();
@@ -467052,6 +467608,7 @@ var init_freshness = __esm(() => {
467052
467608
  "selection.extractOoxml",
467053
467609
  "search",
467054
467610
  "blocks.list",
467611
+ "render.source",
467055
467612
  "lists.getState",
467056
467613
  "tables.list",
467057
467614
  "tables.get",
@@ -467348,6 +467905,24 @@ function createCollabV2ProjectionRuntime(options) {
467348
467905
  diagnostics = [];
467349
467906
  return snapshot3();
467350
467907
  }
467908
+ function recoverDeletedTableSource() {
467909
+ ensureNotDisposed();
467910
+ const token = captureProjectionSnapshot({
467911
+ rootDoc: options.rootDoc,
467912
+ shardRegistry: options.shardRegistry,
467913
+ journalAcceptsMinor: options.journalAcceptsMinor,
467914
+ blobCompletenessProbe: options.blobCompletenessProbe
467915
+ });
467916
+ if (token.journalCompleteness !== "ok" || options.shardRegistry.requiredShardIds().some((id2) => !options.shardRegistry.get(id2))) {
467917
+ throw new Error("deleted-table source requires complete current collaboration owners");
467918
+ }
467919
+ return materializeDeletedTableSourceProjection({
467920
+ snapshotToken: token,
467921
+ rootDoc: options.rootDoc,
467922
+ shardRegistry: options.shardRegistry,
467923
+ dirty: pendingDirty
467924
+ }).record;
467925
+ }
467351
467926
  async function runBarrier(request) {
467352
467927
  ensureNotDisposed();
467353
467928
  const capturedToken = captureProjectionSnapshot({
@@ -467553,6 +468128,7 @@ function createCollabV2ProjectionRuntime(options) {
467553
468128
  addDirty(dirtyScopesFromPackageBatch(batch2));
467554
468129
  },
467555
468130
  refresh,
468131
+ recoverDeletedTableSource,
467556
468132
  runBarrier,
467557
468133
  markCollabMutation() {
467558
468134
  hasCollabMutation = true;
@@ -470356,12 +470932,7 @@ function trackedStoryTextRequiresMergedCarrierSync(validation) {
470356
470932
  const authorsText = validation.trackedInsert != null || validation.trackedInsertContinuation === true || (validation.trackedRefinement?.metadata.insertedText.length ?? 0) > 0;
470357
470933
  if (!authorsText && validation.trackedRefinement?.usesMergedCarrier !== true)
470358
470934
  return false;
470359
- const ordered = listOrderedBlocks(validation.target.scope);
470360
- const index2 = ordered.findIndex((entry) => entry.blockId === validation.target.blockId);
470361
- const head = ordered[index2]?.block;
470362
- if (!head || head.get(BLOCK_KEY.mergedIntoBlockId))
470363
- return false;
470364
- return ordered[index2 + 1]?.block.get(BLOCK_KEY.mergedIntoBlockId) === validation.target.blockId;
470935
+ return readLogicalBlockChain(validation.target.scope, validation.target.blockId).length > 1;
470365
470936
  }
470366
470937
  function createStorySurfaceExecutionBackend(options) {
470367
470938
  const delegate = options.delegate;
@@ -471825,12 +472396,26 @@ function tryMirrorStoryText(prepared, extension2, options, admitted) {
471825
472396
  const trackedInsert = validation.trackedInsert;
471826
472397
  if (!trackedInsert) {
471827
472398
  if (validation.trackedInsertContinuation) {
472399
+ const span = validation.trackedInsertContinuationSpan;
472400
+ if (!span)
472401
+ throw new Error("tracked continuation is missing its owning insertion");
472402
+ const start = getBlockAtoms(target.block).toArray().find((atom) => atom.get(ATOM_KEY.id) === span.startAtomId);
472403
+ if (!start)
472404
+ throw new Error("tracked continuation lost its owning insertion");
472405
+ const offset = validation.trackedInsertOffset ?? source.on.startOffset;
471828
472406
  insertTextAtResolvedTarget({
471829
472407
  target,
471830
- offset: validation.trackedInsertOffset ?? source.on.startOffset,
472408
+ offset,
471831
472409
  text: source.newText,
471832
472410
  origin: STORY_SURFACE_BACKEND_ORIGIN
471833
472411
  });
472412
+ if (offset === span.startOffset) {
472413
+ start.set(ATOM_KEY.visibleOffset, offset);
472414
+ getBlockAnchors(target.block).forEach((anchor) => {
472415
+ if (anchor.get(ANCHOR_KEY.id) === span.startAtomId)
472416
+ anchor.set(ANCHOR_KEY.visibleOffset, offset);
472417
+ });
472418
+ }
471834
472419
  return;
471835
472420
  }
471836
472421
  throw new Error("tracked storyText mirror missing typed insert metadata");
@@ -472130,7 +472715,7 @@ function validateDirectStoryText(prepared, extension2, options) {
472130
472715
  return { ok: false, failureReason: atomFailureReason };
472131
472716
  }
472132
472717
  }
472133
- return {
472718
+ const validation = {
472134
472719
  ok: true,
472135
472720
  source,
472136
472721
  doc: doc2,
@@ -472144,6 +472729,19 @@ function validateDirectStoryText(prepared, extension2, options) {
472144
472729
  ...validatedTrackedRefinement ? { trackedRefinement: validatedTrackedRefinement } : {},
472145
472730
  ...trackedEdit?.ok ? { trackedEdit: trackedEdit.trackedEdit } : {}
472146
472731
  };
472732
+ if (trackedInsertContinuation && !trackedStoryTextRequiresMergedCarrierSync(validation)) {
472733
+ const updated = prepared.semanticDelta.updatedRefs.filter((ref5) => ref5.kind === "trackedChange");
472734
+ if (updated.length !== 1 || String(updated[0].storyId) !== sourceStoryId) {
472735
+ return { ok: false, failureReason: "tracked continuation requires one updated insertion identity" };
472736
+ }
472737
+ const offset = trackedInsertOffset ?? source.on.startOffset;
472738
+ const spans = collectLiveTrackedTextSpansInBlock(hydratedBlock, updated[0].entityId, "ins").filter((span) => span.startOffset <= offset && offset <= span.endOffset);
472739
+ if (spans.length !== 1) {
472740
+ return { ok: false, failureReason: "tracked continuation could not resolve its owning insertion" };
472741
+ }
472742
+ return { ...validation, trackedInsertContinuationSpan: spans[0] };
472743
+ }
472744
+ return validation;
472147
472745
  }
472148
472746
  function storyIdsRequiringShards(prepared, extension2, resolveStoryShard) {
472149
472747
  if (extension2.family === "storyText" && prepared.source.kind === "editText") {
@@ -473563,8 +474161,18 @@ function createCollabV2SessionProjectionController(options) {
473563
474161
  return backend.preflight ? backend.preflight(prepared) : "unsupported-context";
473564
474162
  },
473565
474163
  apply(prepared) {
473566
- if (prepared.source.kind !== "packageReplace")
473567
- return storyBackend.apply(prepared);
474164
+ if (prepared.source.kind !== "packageReplace") {
474165
+ let result2 = { status: "rejected", rejectedReason: "internal-error" };
474166
+ localBackendSyncDepth += 1;
474167
+ try {
474168
+ options.rootDoc.transact(() => {
474169
+ result2 = storyBackend.apply(prepared);
474170
+ }, STORY_SURFACE_BACKEND_ORIGIN);
474171
+ } finally {
474172
+ localBackendSyncDepth -= 1;
474173
+ }
474174
+ return result2;
474175
+ }
473568
474176
  const publish3 = options.preparePackageReplacementPublication?.(prepared);
473569
474177
  if (!publish3)
473570
474178
  return { status: "rejected", rejectedReason: "unsupported-context" };
@@ -473885,7 +474493,14 @@ function createCollabV2SessionProjectionController(options) {
473885
474493
  return { ok: true };
473886
474494
  return remoteProjectionPending ? refreshCleanRecord() : synchronizeSessionFromRuntime();
473887
474495
  }
473888
- return refreshCleanRecord();
474496
+ const result = refreshCleanRecord();
474497
+ if (result.ok || operationId !== "render.source")
474498
+ return result;
474499
+ try {
474500
+ return synchronizeSessionFromRuntime({ sourceRecord: runtime.recoverDeletedTableSource() });
474501
+ } catch {
474502
+ return result;
474503
+ }
473889
474504
  }
473890
474505
  function ingestRoomAuthoritativeInitialDirty() {
473891
474506
  for (const handle of options.projectionRegistry.listStories()) {
@@ -473910,10 +474525,10 @@ function createCollabV2SessionProjectionController(options) {
473910
474525
  };
473911
474526
  }
473912
474527
  const state = runtime.state;
473913
- if (state.freshness !== "clean") {
474528
+ if (!input.sourceRecord && state.freshness !== "clean") {
473914
474529
  return projectionStateFailure(state.blockingReason);
473915
474530
  }
473916
- const record3 = runtime.lastCleanRecord();
474531
+ const record3 = input.sourceRecord ?? runtime.lastCleanRecord();
473917
474532
  if (!record3) {
473918
474533
  return {
473919
474534
  ok: false,
@@ -474577,6 +475192,10 @@ function findAnyPackagePartHandleByUri(projectionRegistry, partUri) {
474577
475192
  const ownerPartUri2 = String(meta3.get(PACKAGE_PART_META_KEY.ownerPartUri) ?? "");
474578
475193
  if (ownerPartUri2 === partUri)
474579
475194
  return handle;
475195
+ const paired = meta3.get(PACKAGE_PART_META_KEY.pairedPartKeys);
475196
+ const partKey2 = partUri.replace(/^\/+/, "").replace(/\//g, "_");
475197
+ if (Array.isArray(paired) && paired.some((key3) => typeof key3 === "string" && key3.replace(/^\/+/, "").replace(/\//g, "_") === partKey2))
475198
+ return handle;
474580
475199
  }
474581
475200
  return null;
474582
475201
  }
@@ -480118,6 +480737,7 @@ async function buildCanonicalShardGraph(input) {
480118
480737
  shardId: storyShardId2(input.runtime.rootId, story.storyKind, story.partUri),
480119
480738
  bytes: readCompletePartBytes(input.session, sourceOpen, story.partUri)
480120
480739
  }));
480740
+ const sourcePackageSha256 = sha256Hex2(input.sourceBuffer);
480121
480741
  for (const { story, shardId, bytes } of stories) {
480122
480742
  let unit;
480123
480743
  if (maySeedStoryShardsFromLocalSource && bytes) {
@@ -480149,7 +480769,7 @@ async function buildCanonicalShardGraph(input) {
480149
480769
  doc: rootDoc,
480150
480770
  rootDoc,
480151
480771
  scope: unit.scope,
480152
- ...storyBootstrap ? { bootstrap: storyBootstrap } : {}
480772
+ ...storyBootstrap ? { bootstrap: { ...storyBootstrap, sourcePackageSha256 } } : {}
480153
480773
  };
480154
480774
  storyHandles.set(shardId, handle);
480155
480775
  storyHandlesByStoryId.set(story.storyId, handle);