docxodus 12.6.4 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +7 -3
- package/dist/canonical.js.map +1 -1
- package/dist/conversion-options.d.ts +16 -0
- package/dist/conversion-options.d.ts.map +1 -0
- package/dist/conversion-options.js +31 -0
- package/dist/conversion-options.js.map +1 -0
- package/dist/core.d.ts +17 -9
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +23 -24
- package/dist/core.js.map +1 -1
- package/dist/docxodus.worker.js +2 -1073
- package/dist/docxodus.worker.js.map +7 -1
- package/dist/editor.bundle.js +35 -14296
- package/dist/editor.bundle.js.map +7 -0
- package/dist/editor.d.ts +33 -2
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +6739 -4773
- package/dist/editor.js.map +7 -1
- package/dist/embed.bundle.js +159 -18703
- package/dist/embed.bundle.js.map +7 -0
- package/dist/embed.d.ts +1 -1
- package/dist/embed.iife.js +37 -18595
- package/dist/embed.iife.js.map +7 -0
- package/dist/embed.js +1 -1
- package/dist/export-assets.json +27 -27
- package/dist/export-browser.bundle.js +1388 -477
- package/dist/export-browser.d.ts +20 -0
- package/dist/export-browser.d.ts.map +1 -1
- package/dist/export-browser.js +132 -37
- package/dist/export-browser.js.map +1 -1
- package/dist/font-runtime.d.ts.map +1 -1
- package/dist/font-runtime.js +54 -0
- package/dist/font-runtime.js.map +1 -1
- package/dist/line-metrics.d.ts +60 -0
- package/dist/line-metrics.d.ts.map +1 -0
- package/dist/line-metrics.js +343 -0
- package/dist/line-metrics.js.map +1 -0
- package/dist/pagination.bundle.js +3 -3214
- package/dist/pagination.bundle.js.map +7 -0
- package/dist/pagination.d.ts +86 -9
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +358 -55
- package/dist/pagination.js.map +1 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +63 -12
- package/dist/react.js.map +1 -1
- package/dist/render-report-v2.schema.json +29 -0
- package/dist/session.bundle.js +2 -2013
- package/dist/session.bundle.js.map +7 -0
- package/dist/session.d.ts +14 -5
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +62 -29
- package/dist/session.js.map +1 -1
- package/dist/types.d.ts +137 -21
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -1
- package/dist/wasm/_framework/Docxodus.wasm +0 -0
- package/dist/wasm/_framework/Docxodus.wasm.br +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm.br +0 -0
- package/dist/wasm/_framework/System.Collections.wasm +0 -0
- package/dist/wasm/_framework/System.Collections.wasm.br +0 -0
- package/dist/wasm/_framework/System.IO.Compression.wasm +0 -0
- package/dist/wasm/_framework/System.IO.Compression.wasm.br +0 -0
- package/dist/wasm/_framework/System.Linq.wasm +0 -0
- package/dist/wasm/_framework/System.Linq.wasm.br +0 -0
- package/dist/wasm/_framework/System.Memory.wasm +0 -0
- package/dist/wasm/_framework/System.Memory.wasm.br +0 -0
- package/dist/wasm/_framework/System.Private.CoreLib.wasm +0 -0
- package/dist/wasm/_framework/System.Private.CoreLib.wasm.br +0 -0
- package/dist/wasm/_framework/System.Private.Xml.Linq.wasm +0 -0
- package/dist/wasm/_framework/System.Private.Xml.Linq.wasm.br +0 -0
- package/dist/wasm/_framework/System.Text.RegularExpressions.wasm +0 -0
- package/dist/wasm/_framework/System.Text.RegularExpressions.wasm.br +0 -0
- package/dist/wasm/_framework/dotnet.boot.js +11 -11
- package/dist/wasm/_framework/dotnet.boot.js.br +0 -0
- package/dist/wasm/_framework/dotnet.native.wasm +0 -0
- package/dist/wasm/_framework/dotnet.native.wasm.br +0 -0
- package/dist/word-text.d.ts +14 -0
- package/dist/word-text.d.ts.map +1 -0
- package/dist/word-text.js +377 -0
- package/dist/word-text.js.map +1 -0
- package/dist/worker-proxy.bundle.js +2 -536
- package/dist/worker-proxy.bundle.js.map +7 -0
- package/dist/worker-proxy.d.ts +14 -1
- package/dist/worker-proxy.d.ts.map +1 -1
- package/dist/worker-proxy.js +357 -339
- package/dist/worker-proxy.js.map +1 -1
- package/package.json +13 -12
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/session.ts", "../src/verification-request.ts", "../src/types.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) John Scrudato IV. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type {\n AnchorInfo,\n AnchorRef,\n AnchorTargetRef,\n AnnotationUpdate,\n BlockMetadata,\n BookmarkInfo,\n BulkEditResult,\n CharSpan,\n CommentListEntry,\n ContentControlFillOptions,\n ContentControlInfo,\n CrossBlockMatch,\n DiffEntry,\n DocumentAnnotation,\n DocumentRange,\n DeliverableVerificationResult,\n DeliverableVerificationRequest,\n DocxodusWasmExports,\n DocxSessionProjection,\n DocxSessionSettings,\n EditError,\n EditResult,\n EditSummary,\n FillOptions,\n FindOptions,\n FormatOp,\n FormattingInspection,\n HeaderFooterKind,\n HyperlinkInfo,\n HyperlinkKind,\n ImageCapabilities,\n ImageDimensions,\n ImageInsertOptions,\n ImageOccurrence,\n FloatingImageLayout,\n InlineSpan,\n NoteListEntry,\n NumberFormat,\n PageNumberField,\n PageNumberingOp,\n PageSetupOp,\n TableOfAuthoritiesOptions,\n TableOfContentsOptions,\n TableOfFiguresOptions,\n PageCitation,\n PageCitationRequest,\n PageMapRegistrationResult,\n PageMapStatus,\n PackageManifest,\n ParagraphBorderEdge,\n ParagraphFormatOp,\n TableBorderSpec,\n TableInsertOptions,\n TableMetadataResult,\n TableCellResolutionResult,\n TableMergeContent,\n TableRowOptions,\n TableShadingScope,\n ListFormat,\n GrepOptions,\n ListMembership,\n MutationBatchFailure,\n MutationBatchChangeSet,\n MutationBatchMode,\n MutationBatchPreviewOptions,\n MutationBatchPreviewStep,\n MutationBatchResult,\n MutationBatchStep,\n MutationTransaction,\n MutationTransactionIdentity,\n MutationPreviewRetention,\n DeliveryBundleResult,\n DeliveryEvidenceStatus,\n DeliveryReceiptBuildOptions,\n MutationBatchStepResult,\n MutationPreconditions,\n CrossReferenceOptions,\n ReplaceOptions,\n RevisionListEntry,\n RevisionListFilter,\n RevisionRepairProposal,\n RevisionRepairRequest,\n RevisionRepairResult,\n SectionInfo,\n SemanticChangeSet,\n StyleInfo,\n TemplatePlaceholder,\n TextMatch,\n} from \"./types.js\";\nimport { serializeVerificationRequest } from \"./verification-request.js\";\nimport type { PageMap } from \"./pagination.js\";\nimport { ContextBoundary, DiffFormat, PlaceholderKinds, ProjectionDepth, ProjectionScopes, TrackedChangeMode } from \"./types.js\";\n\nfunction mutationBatchChangeSet<T>(\n before: readonly T[],\n after: readonly T[],\n key: (value: T) => string,\n): MutationBatchChangeSet<T> {\n const beforeGroups = new Map<string, number[]>();\n const afterGroups = new Map<string, number[]>();\n const group = (items: readonly T[], target: Map<string, number[]>): void => {\n items.forEach((item, index) => {\n const identity = key(item);\n const indices = target.get(identity) ?? [];\n indices.push(index);\n target.set(identity, indices);\n });\n };\n group(before, beforeGroups);\n group(after, afterGroups);\n\n const beforeMatched = before.map(() => false);\n const afterMatched = after.map(() => false);\n const modified = after.map(() => false);\n for (const [identity, afterIndices] of afterGroups) {\n const beforeIndices = beforeGroups.get(identity) ?? [];\n for (const afterIndex of afterIndices) {\n const beforeIndex = beforeIndices.find(index =>\n !beforeMatched[index] && JSON.stringify(before[index]) === JSON.stringify(after[afterIndex]));\n if (beforeIndex === undefined) continue;\n beforeMatched[beforeIndex] = true;\n afterMatched[afterIndex] = true;\n }\n const remainingBefore = beforeIndices.filter(index => !beforeMatched[index]);\n const remainingAfter = afterIndices.filter(index => !afterMatched[index]);\n const modifiedCount = Math.min(remainingBefore.length, remainingAfter.length);\n for (let index = 0; index < modifiedCount; index++) {\n beforeMatched[remainingBefore[index]!] = true;\n afterMatched[remainingAfter[index]!] = true;\n modified[remainingAfter[index]!] = true;\n }\n }\n return {\n added: after.filter((_, index) => !afterMatched[index]),\n removed: before.filter((_, index) => !beforeMatched[index]),\n modified: after.filter((_, index) => modified[index]),\n };\n}\n\n/**\n * Stateful in-memory DOCX editing session keyed by markdown-projection anchor ids.\n * Mirror of the .NET `DocxSession` surface. See\n * `docs/architecture/docx_mutation_api.md` for the surface contract,\n * anchor lifecycle, error catalog, and supported markdown subset.\n *\n * Sessions are not eligible for JS-side garbage collection \u2014 call {@link close}\n * (or use a `using` block under TypeScript 5.2+) when done.\n */\n/**\n * Receipt warnings that say a fresh execution may regenerate ids or timestamps \u2014 the same\n * text the .NET receipt attaches. {@link DocxSession.commitPreview} removes them, because a\n * commit restores the previewed bytes rather than executing afresh.\n */\nconst BATCH_REPLAY_CAVEATS = {\n revisionDates: \"Tracked-revision date attributes may use the execution clock; compare revision ids, authors, types, text, and anchors across separate executions.\",\n commentDates: \"Comment date attributes may be generated from the execution clock; supply dates explicitly when byte-identical replay is required.\",\n annotationMetadata: \"Auto-generated annotation ids or creation timestamps are execution metadata; supply id and created explicitly when byte-identical replay is required.\",\n createdAnchors: \"Created anchors and related OOXML ids may be generated independently on replay; preview/apply equivalence is semantic and packageHash or anchor ids may differ.\",\n} as const;\nconst BATCH_REPLAY_CAVEAT_TEXTS: ReadonlySet<string> = new Set(Object.values(BATCH_REPLAY_CAVEATS));\n\ntype DeliveryBundleArtifactWire = Omit<DeliveryBundleResult[\"artifacts\"][number], \"bytes\"> & { bytes?: string };\n\n/** Mirrors the .NET retained-preview count bound, so this client-side receipt map cannot outgrow it. */\nconst RETAINED_PREVIEW_RECEIPTS = 8;\n\nexport class DocxSession {\n private readonly handle: number;\n private readonly wasm: DocxodusWasmExports[\"DocxSessionBridge\"];\n /**\n * The receipts this client composed for previews it retained, keyed by previewId. The host\n * keeps the package and the binding; the step receipts live only here, so a commit can return\n * the previewed steps and change sets without the host re-parsing a client-composed result.\n */\n private readonly retainedPreviewReceipts = new Map<string, MutationBatchResult>();\n\n /** @internal */\n constructor(handle: number, wasm: DocxodusWasmExports[\"DocxSessionBridge\"]) {\n this.handle = handle;\n this.wasm = wasm;\n }\n\n // \u2500\u2500\u2500 View \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n project(): DocxSessionProjection {\n return JSON.parse(this.wasm.Project(this.handle)) as DocxSessionProjection;\n }\n\n /** Monotonic document version (0 at open; +1 per committed mutation/undo/redo). */\n getVersion(): number {\n return (JSON.parse(this.wasm.GetVersion(this.handle)) as { version: number }).version;\n }\n\n /**\n * Verification manifest for the current logical checkpoint. Unsaved edits are included and\n * the read does not mutate package bytes, caches, history, or the document version.\n */\n getPackageManifest(): PackageManifest {\n return JSON.parse(this.wasm.GetPackageManifest(this.handle)) as PackageManifest;\n }\n\n /** Register a browser-materialized PageMap without changing the document version. */\n registerPageMap(pageMap: PageMap, expectedRendererFingerprint?: string): PageMapRegistrationResult {\n return JSON.parse(this.wasm.RegisterPageMap(\n this.handle,\n JSON.stringify(pageMap),\n expectedRendererFingerprint ?? \"\",\n )) as PageMapRegistrationResult;\n }\n\n getPageMapStatus(request?: PageCitationRequest): PageMapStatus {\n return JSON.parse(this.wasm.GetPageMapStatus(\n this.handle,\n request ? JSON.stringify(request) : \"\",\n )) as PageMapStatus;\n }\n\n getPageCitation(anchorId: string, request: PageCitationRequest): PageCitation {\n return JSON.parse(this.wasm.GetPageCitation(\n this.handle,\n anchorId,\n JSON.stringify(request),\n )) as PageCitation;\n }\n\n /** Evaluate optimistic guards without mutating or advancing the version. */\n checkPreconditions(preconditions: MutationPreconditions): EditResult {\n return JSON.parse(\n this.wasm.CheckPreconditions(this.handle, JSON.stringify(preconditions)),\n ) as EditResult;\n }\n\n /**\n * Guard any synchronous mutation. WASM calls are synchronous and single-threaded, so the\n * check and callback form one uninterrupted client-side operation. Prefer a method's native\n * `preconditions` option where it has one (notably replaceTextRange's match-count guard).\n */\n runWithPreconditions(\n preconditions: MutationPreconditions,\n mutation: () => EditResult,\n ): EditResult {\n const checked = this.checkPreconditions(preconditions);\n return checked.success ? mutation() : checked;\n }\n\n /**\n * Execute synchronous mutations atomically by default. Atomic success is one undo/version\n * unit; any failed or thrown step restores the exact package and history checkpoint.\n */\n executeBatch(\n steps: readonly MutationBatchStep[],\n mode: MutationBatchMode = \"atomic\",\n transaction?: MutationTransaction,\n ): MutationBatchResult {\n if (mode !== \"atomic\" && mode !== \"best_effort\") {\n throw new RangeError(`unknown mutation batch mode: ${String(mode)}`);\n }\n if (transaction === undefined) return this.recorded(steps, mode, undefined, () => this.runBatch(steps, mode));\n return this.runTransactional(transaction, mode,\n identity => this.recorded(steps, mode, identity, () => this.runBatch(steps, mode)));\n }\n\n /**\n * What the session's host-owned delivery evidence recorder holds (issue #748). `enabled` is\n * false, with the reason, unless the session was opened with `captureDeliveryEvidence`.\n */\n getDeliveryEvidenceStatus(): DeliveryEvidenceStatus {\n if (!this.wasm.GetDeliveryEvidenceStatus) {\n throw new Error(\"This WASM bundle predates delivery evidence; rebuild docxodus.\");\n }\n return JSON.parse(this.wasm.GetDeliveryEvidenceStatus(this.handle)) as DeliveryEvidenceStatus;\n }\n\n /**\n * Build the receipt-bearing delivery of this session through the shared bundle service: the\n * clean current package (`final-docx`), the source-to-delivered semantic delta, and the change\n * receipt (`change-receipt`) minted from the captured evidence \u2014 verifiable with\n * `verifyDeliveryReceipt` against the returned artifact bytes. A history that cannot be\n * attested yields an `incomplete` bundle whose receipt artifact carries the reason, and\n * `evidence.unavailableReason` says why.\n */\n buildDeliveryReceipt(options?: DeliveryReceiptBuildOptions): DeliveryBundleResult {\n if (!this.wasm.BuildDeliveryReceipt) {\n throw new Error(\"This WASM bundle predates delivery evidence; rebuild docxodus.\");\n }\n const wire = JSON.parse(this.wasm.BuildDeliveryReceipt(this.handle, JSON.stringify(options ?? {}))) as {\n status: DeliveryBundleResult[\"status\"];\n verified: boolean;\n manifest: Record<string, unknown>;\n manifestBytes: string;\n artifacts: readonly (Omit<DeliveryBundleArtifactWire, \"bytes\"> & { bytes?: string })[];\n evidence?: DeliveryEvidenceStatus;\n };\n const decode = (base64: string): Uint8Array => Uint8Array.from(atob(base64), c => c.charCodeAt(0));\n return {\n status: wire.status,\n verified: wire.verified,\n manifest: wire.manifest,\n manifestBytes: decode(wire.manifestBytes),\n artifacts: wire.artifacts.map(artifact => {\n const { bytes, ...rest } = artifact;\n return bytes === undefined ? rest : { ...rest, bytes: decode(bytes) };\n }),\n ...(wire.evidence ? { evidence: wire.evidence } : {}),\n };\n }\n\n /**\n * Describe a batch to the session's delivery evidence recorder before running it, and hand\n * it the step results afterwards, so the version steps the batch produced are recorded under\n * this description rather than as unlabeled mutations. A bundle without the recorder, or a\n * session not capturing evidence, simply runs the batch.\n */\n private recorded(\n steps: readonly MutationBatchStep[],\n mode: MutationBatchMode,\n identity: MutationTransactionIdentity | undefined,\n run: () => MutationBatchResult,\n ): MutationBatchResult {\n if (!this.wasm.BeginDeliveryEvidence || !this.wasm.CompleteDeliveryEvidence\n || !this.wasm.AbandonDeliveryEvidence) {\n return run();\n }\n const described = this.wasm.BeginDeliveryEvidence(\n this.handle,\n JSON.stringify(steps.map(step => step.args === undefined\n ? { tool: step.tool, action: step.action }\n : { tool: step.tool, action: step.action, args: step.args })),\n mode,\n identity ? JSON.stringify({ transactionId: identity.transactionId, requestFingerprint: identity.requestFingerprint }) : \"\",\n );\n if (!described) return run();\n let result: MutationBatchResult | undefined;\n try {\n result = run();\n return result;\n } finally {\n if (result) this.wasm.CompleteDeliveryEvidence(this.handle, JSON.stringify(result.steps));\n else this.wasm.AbandonDeliveryEvidence(this.handle);\n }\n }\n\n /**\n * Make a preview retained by {@link previewBatch} (`retain: true`) the live document exactly\n * as previewed: the previewed package is restored byte-for-byte as one undo step, so the\n * generated anchor ids, timestamps and `packageHash` are exactly those the preview reported.\n * The commit is guarded \u2014 it refuses with `preview_stale`, editing nothing, when the session's\n * version, package content, tracked-changes mode or revision author moved since the preview,\n * and with `preview_not_found` once the preview expired, was evicted, or was already\n * committed. A `transaction` makes a retry after a lost response safe, as for\n * {@link executeBatch}.\n */\n commitPreview(previewId: string, transaction?: MutationTransaction): MutationBatchResult {\n if (!this.wasm.CommitPreview) {\n throw new Error(\"This WASM bundle predates retained previews; rebuild docxodus.\");\n }\n const commit = (): MutationBatchResult => {\n const envelope = JSON.parse(this.wasm.CommitPreview!(this.handle, previewId)) as MutationBatchResult;\n if (!envelope.success) {\n if (envelope.failure?.error.code === \"preview_not_found\") this.retainedPreviewReceipts.delete(previewId);\n return envelope;\n }\n const receipt = this.retainedPreviewReceipts.get(previewId);\n this.retainedPreviewReceipts.delete(previewId);\n // No receipt means another client of this handle retained the preview; the host's\n // envelope (versions, hash, retention) is still exact, only the step receipts are unknown.\n if (!receipt) return envelope;\n return {\n ...receipt,\n preview: false,\n html: null,\n baseVersion: envelope.baseVersion,\n resultVersion: envelope.resultVersion,\n packageHash: envelope.packageHash,\n warnings: receipt.warnings.filter(warning => !BATCH_REPLAY_CAVEAT_TEXTS.has(warning)),\n retention: envelope.retention,\n };\n };\n if (transaction === undefined) return commit();\n return this.runTransactional(transaction, \"atomic\", () => commit());\n }\n\n private runTransactional(\n transaction: MutationTransaction,\n mode: MutationBatchMode,\n body: (identity: MutationTransactionIdentity) => MutationBatchResult,\n ): MutationBatchResult {\n // The batch is composed here from callbacks, so the session's journal (shared with every\n // other transport) is driven in three steps: resolve the id, run, retain the result.\n if (!this.wasm.BeginMutationTransaction\n || !this.wasm.CompleteMutationTransaction\n || !this.wasm.AbandonMutationTransaction) {\n throw new Error(\"This WASM bundle predates mutation transactions; rebuild docxodus.\");\n }\n if (typeof transaction.transactionId !== \"string\") {\n throw new RangeError(\"transactionId must be a string\");\n }\n if (transaction.request === null || typeof transaction.request !== \"object\"\n || Array.isArray(transaction.request)) {\n throw new RangeError(\"a mutation transaction needs a request object describing the batch\");\n }\n const decision = JSON.parse(this.wasm.BeginMutationTransaction(\n this.handle,\n transaction.transactionId,\n JSON.stringify({ ...transaction.request, mode }),\n )) as { kind: string; transaction: MutationTransactionIdentity; response: string | null };\n if (decision.response !== null) {\n return JSON.parse(decision.response) as MutationBatchResult;\n }\n let completed = false;\n try {\n const result: MutationBatchResult = {\n ...body(decision.transaction),\n transaction: decision.transaction,\n };\n this.wasm.CompleteMutationTransaction(\n this.handle, transaction.transactionId, JSON.stringify(result));\n completed = true;\n return result;\n } finally {\n if (!completed) this.wasm.AbandonMutationTransaction(this.handle, transaction.transactionId);\n }\n }\n\n private runBatch(\n steps: readonly MutationBatchStep[],\n mode: MutationBatchMode,\n ): MutationBatchResult {\n const baseVersion = this.getVersion();\n const observationWarnings: string[] = [];\n const inspect = <T>(label: string, read: () => T, fallback: T): T => {\n try { return read(); } catch (error) {\n observationWarnings.push(`${label} unavailable: ${error instanceof Error ? error.message : String(error)}`);\n return fallback;\n }\n };\n const beforeRevisions = inspect(\"Revision delta inspection\", () => this.listRevisions(), []);\n const beforeComments = inspect(\"Comment delta inspection\", () => this.listComments(), []);\n const beforeAnnotations = inspect(\"Annotation delta inspection\", () => this.listAnnotations(), []);\n const complete = (result: {\n mode: MutationBatchMode;\n status: \"ok\" | \"failed\" | \"partial\";\n success: boolean;\n rolledBack: boolean;\n steps: readonly MutationBatchStepResult[];\n failure?: MutationBatchFailure;\n }): MutationBatchResult => {\n try {\n const revisionChanges = mutationBatchChangeSet(\n beforeRevisions,\n inspect(\"Revision delta inspection\", () => this.listRevisions(), beforeRevisions),\n revision => revision.id,\n );\n const commentChanges = mutationBatchChangeSet(\n beforeComments,\n inspect(\"Comment delta inspection\", () => this.listComments(), beforeComments),\n comment => comment.anchorId,\n );\n const annotationChanges = mutationBatchChangeSet(\n beforeAnnotations,\n inspect(\"Annotation delta inspection\", () => this.listAnnotations(), beforeAnnotations),\n annotation => annotation.id ?? \"\",\n );\n const resultVersion = inspect(\n \"Result version inspection\", () => this.getVersion(), baseVersion,\n );\n const warnings: string[] = [...observationWarnings];\n if ([...revisionChanges.added, ...revisionChanges.modified]\n .some(revision => revision.date !== undefined && revision.date !== null)) {\n warnings.push(BATCH_REPLAY_CAVEATS.revisionDates);\n }\n if ([...commentChanges.added, ...commentChanges.modified]\n .some(comment => comment.date !== undefined && comment.date !== null)) {\n warnings.push(BATCH_REPLAY_CAVEATS.commentDates);\n }\n // Same predicate as the .NET receipt (`annotation.Created.HasValue`): the warning is\n // about an execution CLOCK, so an annotation added with no created timestamp is\n // deterministic and must not raise it on one surface and not the other.\n if (annotationChanges.added\n .some(annotation => annotation.created !== undefined && annotation.created !== null)) {\n warnings.push(BATCH_REPLAY_CAVEATS.annotationMetadata);\n }\n if (result.steps.some(step => step.results.some(edit => edit.created.length > 0))) {\n warnings.push(BATCH_REPLAY_CAVEATS.createdAnchors);\n }\n if (mode === \"best_effort\" && !result.success) {\n warnings.push(\"Best-effort execution retains every successful step despite later failures.\");\n }\n // null, never \"\": an absent hash must not compare equal to another absent hash, or a\n // naive `preview.packageHash === applied.packageHash` replay assertion passes vacuously.\n let packageHash: string | null = null;\n if (!this.wasm.GetPackageContentHash) {\n warnings.push(\"This WASM bundle predates package equivalence hashes; packageHash is unavailable.\");\n } else {\n try { packageHash = this.wasm.GetPackageContentHash(this.handle); } catch (error) {\n warnings.push(`Package equivalence hash unavailable: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n return {\n ...result,\n preview: false,\n baseVersion,\n resultVersion,\n packageHash,\n revisionChanges,\n commentChanges,\n annotationChanges,\n warnings,\n html: null,\n };\n } catch (error) {\n return {\n ...result,\n preview: false,\n baseVersion,\n resultVersion: inspect(\"Result version inspection\", () => this.getVersion(), baseVersion),\n packageHash: null,\n revisionChanges: { added: [], removed: [], modified: [] },\n commentChanges: { added: [], removed: [], modified: [] },\n annotationChanges: { added: [], removed: [], modified: [] },\n warnings: [\n ...observationWarnings,\n `Batch receipt enrichment unavailable: ${error instanceof Error ? error.message : String(error)}`,\n ],\n html: null,\n };\n }\n };\n const internalFailure = (value: unknown): EditResult => ({\n success: false,\n error: { code: \"internal_error\", message: value instanceof Error ? value.message : String(value) },\n created: [], removed: [], modified: [],\n });\n const run = (step: MutationBatchStep): readonly EditResult[] => {\n try {\n const value = step.mutation();\n const results = Array.isArray(value) ? value : [value];\n if (results.some(result =>\n result === null || typeof result !== \"object\" || typeof result.success !== \"boolean\")) {\n return [internalFailure(\"batch mutation returned invalid edit results\")];\n }\n // An empty list is a successful no-op step, matching the core contract.\n return results;\n } catch (error) {\n return [internalFailure(error)];\n }\n };\n const failureOf = (\n step: MutationBatchStepResult,\n rolledBack: boolean,\n ): MutationBatchFailure => ({\n index: step.index,\n tool: step.tool,\n action: step.action,\n error: step.results.find(result => !result.success)?.error\n ?? { code: \"internal_error\", message: \"batch step failed without an error\" },\n rolledBack,\n });\n\n const preflightOne = (step: MutationBatchStep): EditError | undefined => {\n try { return step.preflight?.(); } catch (error) { return internalFailure(error).error; }\n };\n if (mode === \"atomic\") {\n const preflight = steps.map(preflightOne);\n const failedPreflight = preflight.findIndex(error => error !== undefined);\n if (failedPreflight >= 0) {\n const source = steps[failedPreflight]!;\n const failed: MutationBatchStepResult = {\n index: failedPreflight, tool: source.tool, action: source.action,\n success: false, rolledBack: true,\n results: [{ success: false, error: preflight[failedPreflight]!, created: [], removed: [], modified: [] }],\n };\n return complete({ mode, status: \"failed\", success: false, rolledBack: true,\n steps: [failed], failure: failureOf(failed, true) });\n }\n\n const transaction = this.wasm.BeginTransaction(this.handle);\n const completed: MutationBatchStepResult[] = [];\n try {\n for (let index = 0; index < steps.length; index++) {\n const source = steps[index]!;\n const results = run(source);\n const step: MutationBatchStepResult = {\n index, tool: source.tool, action: source.action,\n success: results.every(result => result.success), rolledBack: false, results,\n };\n completed.push(step);\n if (!step.success) {\n this.wasm.RollbackTransaction(transaction);\n const rolledBack = completed.map(value => ({ ...value, rolledBack: true }));\n const failed = rolledBack[rolledBack.length - 1]!;\n return complete({ mode, status: \"failed\", success: false, rolledBack: true,\n steps: rolledBack, failure: failureOf(failed, true) });\n }\n }\n this.wasm.CommitTransaction(transaction);\n return complete({ mode, status: \"ok\", success: true, rolledBack: false, steps: completed });\n } catch (error) {\n try { this.wasm.RollbackTransaction(transaction); } catch { /* preserve the original */ }\n throw error;\n }\n }\n\n // Preserve sequential best-effort semantics: a later preflight can observe state created by\n // an earlier successful step, so run it immediately before that step rather than up front.\n const completed: MutationBatchStepResult[] = steps.map((source, index) => {\n const preflight = preflightOne(source);\n const results = preflight\n ? [{ success: false, error: preflight, created: [], removed: [], modified: [] }]\n : run(source);\n return {\n index, tool: source.tool, action: source.action,\n success: results.every(result => result.success), rolledBack: false, results,\n };\n });\n const failed = completed.find(step => !step.success);\n return complete({\n mode,\n status: failed ? (completed.some(step => step.success) ? \"partial\" : \"failed\") : \"ok\",\n success: failed === undefined,\n rolledBack: false,\n steps: completed,\n failure: failed ? failureOf(failed, false) : undefined,\n });\n }\n\n /**\n * Execute the same callback batch algorithm against a complete isolated package clone.\n * Callbacks receive the shadow session explicitly; mutate that argument. The live session's\n * package, caches, version, configuration, and undo/redo history are never execution targets.\n */\n previewBatch(\n steps: readonly MutationBatchPreviewStep[],\n mode: MutationBatchMode = \"atomic\",\n options?: MutationBatchPreviewOptions,\n ): MutationBatchResult {\n if (mode !== \"atomic\" && mode !== \"best_effort\") {\n throw new RangeError(`unknown mutation batch mode: ${String(mode)}`);\n }\n const htmlMode = options?.html ?? \"none\";\n if (htmlMode !== \"none\" && htmlMode !== \"scoped\" && htmlMode !== \"full\") {\n throw new RangeError(`unknown preview HTML mode: ${String(htmlMode)}`);\n }\n if (!this.wasm.OpenPreviewSession) {\n throw new Error(\"This WASM bundle does not support isolated mutation previews.\");\n }\n\n const shadow = new DocxSession(this.wasm.OpenPreviewSession(this.handle), this.wasm);\n try {\n const result = shadow.executeBatch(\n steps.map(step => ({\n tool: step.tool,\n action: step.action,\n mutation: () => step.mutation(shadow),\n preflight: step.preflight ? () => step.preflight!(shadow) : undefined,\n })),\n mode,\n );\n const warnings = [...result.warnings];\n let html: string | null = null;\n // A rendered document always starts with '<'; a leading '{' is the bridge's error object.\n const unwrapRendered = (rendered: string): string | null => {\n if (rendered.trimStart().startsWith(\"{\")) {\n const envelope = JSON.parse(rendered) as { error?: string };\n if (envelope.error) {\n warnings.push(`Preview HTML could not be generated: ${envelope.error}`);\n return null;\n }\n }\n return rendered;\n };\n // Preview HTML MUST come from the fa\u00E7ade's preview profile (DocxSessionOps.RenderPreview*),\n // not the editor's authoring profile: the editor render hides comments, annotations and\n // headers/footers, so routing a preview through it would show this surface a materially\n // different document than the stdio/Python/MCP surfaces show for the identical batch.\n const legacyProfileWarning =\n \"This WASM bundle predates the shared preview HTML profile; preview HTML omits comments, \" +\n \"annotations and headers/footers and may differ from other surfaces.\";\n try {\n if (htmlMode === \"scoped\") {\n if (!options?.htmlAnchorId) {\n warnings.push(\"Scoped HTML was requested without htmlAnchorId; no HTML was generated.\");\n } else if (this.wasm.RenderPreviewBlockHtml) {\n html = unwrapRendered(\n this.wasm.RenderPreviewBlockHtml(shadow.handle, options.htmlAnchorId));\n } else {\n warnings.push(legacyProfileWarning);\n html = shadow.renderBlock(options.htmlAnchorId);\n }\n } else if (htmlMode === \"full\") {\n if (this.wasm.RenderPreviewHtml) {\n html = unwrapRendered(this.wasm.RenderPreviewHtml(shadow.handle));\n } else {\n warnings.push(legacyProfileWarning);\n html = unwrapRendered(this.wasm.RenderHtmlForReview\n ? this.wasm.RenderHtmlForReview(shadow.handle, \"docx-\", false, false, 1, true)\n : this.wasm.RenderHtml(shadow.handle, \"docx-\", false, false, 1));\n }\n }\n } catch (error) {\n warnings.push(`Preview HTML could not be generated: ${error instanceof Error ? error.message : String(error)}`);\n }\n let retention: MutationPreviewRetention | undefined;\n if (options?.retain) {\n if (!this.wasm.RetainPreview) {\n throw new Error(\"This WASM bundle predates retained previews; rebuild docxodus.\");\n }\n if (!result.success) {\n warnings.push(\"The preview did not succeed, so it was not retained for commit.\");\n } else {\n const retained = JSON.parse(this.wasm.RetainPreview(shadow.handle)) as {\n retention: MutationPreviewRetention | null;\n warnings: readonly string[];\n };\n warnings.push(...retained.warnings);\n retention = retained.retention ?? undefined;\n }\n }\n const preview: MutationBatchResult = retention\n ? { ...result, preview: true, warnings, html, retention }\n : { ...result, preview: true, warnings, html };\n if (retention) {\n if (this.retainedPreviewReceipts.size >= RETAINED_PREVIEW_RECEIPTS) {\n this.retainedPreviewReceipts.delete(this.retainedPreviewReceipts.keys().next().value!);\n }\n this.retainedPreviewReceipts.set(retention.previewId, { ...preview, html: null });\n }\n return preview;\n } finally {\n shadow.close();\n }\n }\n\n /**\n * Project a slice of the document keyed off an anchor \u2014 useful for showing\n * one section to an LLM at a time without paying the cost of projecting the\n * whole document.\n *\n * - `ProjectionDepth.SelfOnly` \u2014 just the addressed block (one paragraph,\n * row, etc.).\n * - `ProjectionDepth.Subtree` \u2014 the block + descendants (e.g. a table with\n * all its rows/cells, but no following content).\n * - `ProjectionDepth.SubtreeAndFollowingSiblings` (default) \u2014 for headings\n * this returns the whole section (heading + content up to the next same-\n * or-higher heading); for non-headings it behaves like `Subtree`.\n *\n * @see docs/architecture/docx_mutation_api.md\n */\n projectAnchor(\n anchorId: string,\n depth?: ProjectionDepth,\n citation?: PageCitationRequest,\n ): DocxSessionProjection {\n // An omitted depth takes the engine's default (SubtreeAndFollowingSiblings), declared once in\n // DocxSessionOps.\n return JSON.parse(\n citation\n ? this.wasm.ProjectAnchorWithCitations(this.handle, anchorId, depth ?? null, JSON.stringify(citation))\n : this.wasm.ProjectAnchor(this.handle, anchorId, depth ?? null),\n ) as DocxSessionProjection;\n }\n\n /**\n * Render a single block to faithful HTML from the live session \u2014 the editor's\n * incremental per-block re-render after an edit. Resolves against the in-memory\n * document (no Save round-trip). `anchorId` is a block anchor (`kind:scope:unid`)\n * or the bare unid carried by a `data-anchor` attribute. Returns the block's HTML\n * element (no `<html>`/`<head>` wrapper).\n */\n renderBlock(\n anchorId: string,\n options?: { cssPrefix?: string; fabricateClasses?: boolean },\n ): string {\n // Omitted options take the engine's defaults (\"docx-\", no fabricated classes), declared once\n // in DocxSessionOps.\n const html = this.wasm.RenderBlockHtml(\n this.handle,\n anchorId,\n options?.cssPrefix ?? null,\n options?.fabricateClasses ?? null,\n );\n // Rendered HTML always begins with '<'; a leading '{' signals an error object.\n if (html.charCodeAt(0) === 0x7b /* '{' */) {\n const err = JSON.parse(html) as { error?: string };\n throw new Error(`renderBlock failed: ${err.error ?? \"unknown error\"}`);\n }\n return html;\n }\n\n // \u2500\u2500\u2500 Tier A: text CRUD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n replaceText(\n anchorId: string,\n markdown: string,\n preconditions?: MutationPreconditions,\n ): EditResult {\n const apply = () => JSON.parse(\n this.wasm.ReplaceText(this.handle, anchorId, markdown),\n ) as EditResult;\n return preconditions\n ? this.runWithPreconditions(\n { ...preconditions, anchorId: preconditions.anchorId ?? anchorId }, apply)\n : apply();\n }\n\n deleteBlock(anchorId: string, preconditions?: MutationPreconditions): EditResult {\n const apply = () => JSON.parse(this.wasm.DeleteBlock(this.handle, anchorId)) as EditResult;\n return preconditions\n ? this.runWithPreconditions(\n { ...preconditions, anchorId: preconditions.anchorId ?? anchorId }, apply)\n : apply();\n }\n\n /** Reorder one top-level paragraph/heading/list/table block relative to another. */\n moveBlock(sourceAnchorId: string, targetAnchorId: string, position: \"before\" | \"after\"): EditResult {\n return JSON.parse(\n this.wasm.MoveBlock(this.handle, sourceAnchorId, targetAnchorId, position),\n ) as EditResult;\n }\n\n /**\n * Delete every top-level block-level sibling between `fromAnchorId` (inclusive)\n * and `toAnchorIdExclusive` (exclusive). Both anchors must share a direct\n * parent and live in the same package part. Returns a single `EditResult`\n * whose `removed` lists every anchor that was deleted.\n *\n * Records ONE undo snapshot \u2014 `undo()` restores the entire range.\n *\n * @see docs/architecture/docx_mutation_api.md#deleterange\n */\n deleteRange(fromAnchorId: string, toAnchorIdExclusive: string): EditResult {\n return JSON.parse(this.wasm.DeleteRange(this.handle, fromAnchorId, toAnchorIdExclusive)) as EditResult;\n }\n\n /**\n * Delete a heading and everything below it up to (but not including) the next\n * heading at the same or higher level. The heading anchor must have `kind === \"h\"`.\n *\n * If the target is the last heading in its parent, the section extends to the\n * end of the parent (heading + everything after).\n *\n * @see docs/architecture/docx_mutation_api.md#deletesection\n */\n deleteSection(headingAnchorId: string): EditResult {\n return JSON.parse(this.wasm.DeleteSection(this.handle, headingAnchorId)) as EditResult;\n }\n\n // \u2500\u2500\u2500 Tier B: structural \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n insertParagraph(anchorId: string, position: \"before\" | \"after\", markdown: string): EditResult {\n return JSON.parse(this.wasm.InsertParagraph(this.handle, anchorId, position, markdown)) as EditResult;\n }\n\n splitParagraph(anchorId: string, characterOffset: number): EditResult {\n return JSON.parse(this.wasm.SplitParagraph(this.handle, anchorId, characterOffset)) as EditResult;\n }\n\n mergeParagraphs(firstAnchorId: string, secondAnchorId: string): EditResult {\n return JSON.parse(this.wasm.MergeParagraphs(this.handle, firstAnchorId, secondAnchorId)) as EditResult;\n }\n\n /**\n * Insert an empty paragraph carrying a bottom border \u2014 an S-1-style horizontal rule \u2014\n * before/after the block. `rule` styles the line (default: a single \u22481.5pt black rule).\n */\n insertHorizontalRule(\n anchorId: string,\n position: \"before\" | \"after\",\n rule?: ParagraphBorderEdge,\n ): EditResult {\n const ruleJson = rule ? JSON.stringify(rule) : \"\";\n return JSON.parse(\n this.wasm.InsertHorizontalRule(this.handle, anchorId, position, ruleJson),\n ) as EditResult;\n }\n\n /**\n * Insert a `rows`\u00D7`cols` table before/after the block. `options` controls borders, row-major\n * cell markdown, and cell alignment. The returned `EditResult.created` lists canonical `tc`\n * anchors (row-major), so each cell can then be addressed to fill/format.\n */\n insertTable(\n anchorId: string,\n position: \"before\" | \"after\",\n rows: number,\n cols: number,\n options?: TableInsertOptions,\n ): EditResult {\n const optionsJson = options ? JSON.stringify(options) : \"\";\n return JSON.parse(\n this.wasm.InsertTable(this.handle, anchorId, position, rows, cols, optionsJson),\n ) as EditResult;\n }\n\n /** Resolve a canonical `tbl` anchor to explicit table/row/column/cell identities. */\n getTableMetadata(tableAnchorId: string): TableMetadataResult {\n return JSON.parse(this.wasm.GetTableMetadata(this.handle, tableAnchorId)) as TableMetadataResult;\n }\n\n /** Resolve a canonical `tc` anchor to its zero-based table-grid coordinate and spans. */\n resolveTableCellAnchor(cellAnchorId: string): TableCellResolutionResult {\n return JSON.parse(\n this.wasm.ResolveTableCellAnchor(this.handle, cellAnchorId),\n ) as TableCellResolutionResult;\n }\n\n /** Resolve a zero-based table-grid coordinate to the physical `tc` covering it. */\n resolveTableCellCoordinate(\n tableAnchorId: string,\n rowIndex: number,\n columnIndex: number,\n ): TableCellResolutionResult {\n return JSON.parse(\n this.wasm.ResolveTableCellCoordinate(this.handle, tableAnchorId, rowIndex, columnIndex),\n ) as TableCellResolutionResult;\n }\n\n /**\n * Table row/column editing, addressed by the canonical `tc` anchor returned from\n * {@link insertTable}'s `created` or table metadata. Insert clones the reference row/column's\n * widths and starts empty (`created` lists new `tc` anchors); delete of the last row/column removes\n * the whole table. All four are grid-aware: inserting across a merge extends it, deleting\n * through one narrows it, and deleting a vertical merge's lead row promotes the next row to\n * carry it \u2014 the grid is never left ragged.\n */\n insertTableRow(cellAnchorId: string, position: \"before\" | \"after\"): EditResult {\n return JSON.parse(this.wasm.InsertTableRow(this.handle, cellAnchorId, position)) as EditResult;\n }\n\n insertTableColumn(cellAnchorId: string, position: \"before\" | \"after\"): EditResult {\n return JSON.parse(this.wasm.InsertTableColumn(this.handle, cellAnchorId, position)) as EditResult;\n }\n\n deleteTableRow(cellAnchorId: string): EditResult {\n return JSON.parse(this.wasm.DeleteTableRow(this.handle, cellAnchorId)) as EditResult;\n }\n\n deleteTableColumn(cellAnchorId: string): EditResult {\n return JSON.parse(this.wasm.DeleteTableColumn(this.handle, cellAnchorId)) as EditResult;\n }\n\n /**\n * Merge the rectangle of cells anchored at `cellAnchorId` running `rowSpan` rows down \u00D7\n * `colSpan` cells right (Word's *Merge Cells*): `w:gridSpan` for the horizontal extent,\n * `w:vMerge` restart/continue for the vertical one. The rectangle must tile the same whole grid\n * columns in every row it covers and must not clip a vertical merge entering from above or\n * continuing below \u2014 a partial overlap fails with `invalid_table_merge` instead of tearing the\n * grid. `content` decides what happens to the absorbed cells' content (default `\"append\"`).\n */\n mergeCells(\n cellAnchorId: string,\n rowSpan: number,\n colSpan: number,\n content: TableMergeContent = \"append\",\n ): EditResult {\n return JSON.parse(\n this.wasm.MergeCells(this.handle, cellAnchorId, rowSpan, colSpan, content),\n ) as EditResult;\n }\n\n /**\n * Split the merged cell at `cellAnchorId` back into unit cells, dropping its `w:gridSpan` and\n * `w:vMerge` markup and restoring one cell per grid column (each taking its `w:tblGrid` width).\n * Addressing a vertical-merge continuation unmerges the whole run. A cell with no merge markup\n * fails with `invalid_table_merge`.\n */\n unmergeCells(cellAnchorId: string): EditResult {\n return JSON.parse(this.wasm.UnmergeCells(this.handle, cellAnchorId)) as EditResult;\n }\n\n /**\n * Table styling, addressed by a canonical `tc` anchor \u2014 the post-insert counterpart of\n * {@link insertTable}'s options (issue #315 Stage A). `setColumnWidths` retunes `w:tblGrid` +\n * every row's cell width (one positive twip value per column) and pins the table to fixed\n * layout, exactly as inserting with explicit `columnWidths` would.\n */\n setColumnWidths(cellAnchorId: string, widthsTwips: number[]): EditResult {\n return JSON.parse(\n this.wasm.SetColumnWidths(this.handle, cellAnchorId, JSON.stringify(widthsTwips)),\n ) as EditResult;\n }\n\n /**\n * Set the table-level borders (`w:tblPr/w:tblBorders`) of the table containing the anchor.\n * Only the edges named by `spec.scope` are written; the rest are left untouched. Style\n * `\"none\"` removes the targeted edges. Omitting `spec` writes a thin single border all round.\n */\n setTableBorders(cellAnchorId: string, spec?: TableBorderSpec): EditResult {\n return JSON.parse(\n this.wasm.SetTableBorders(this.handle, cellAnchorId, spec ? JSON.stringify(spec) : \"\"),\n ) as EditResult;\n }\n\n /**\n * Shade the cell containing the anchor \u2014 or, with scope `\"row\"`, every cell of its row\n * (header-row banding). `fill` is a hex RRGGBB triplet (leading '#' tolerated) or `\"auto\"`;\n * `null` removes the shading.\n */\n setCellShading(\n cellAnchorId: string,\n fill: string | null,\n scope?: TableShadingScope,\n ): EditResult {\n // An omitted scope takes the engine's default (\"cell\"), declared once in the facade.\n return JSON.parse(\n this.wasm.SetCellShading(this.handle, cellAnchorId, fill ?? \"\", scope ?? \"\"),\n ) as EditResult;\n }\n\n /**\n * Mark (or unmark) the row containing the anchor as a repeating header row\n * (`w:trPr/w:tblHeader`), so a multi-page table re-shows it on every page. Word only honors\n * the flag on a run of rows starting at the table's first row. An omitted `repeat` marks the\n * row (the engine's default, `true`).\n */\n setRepeatHeaderRow(cellAnchorId: string, repeat?: boolean): EditResult {\n return JSON.parse(\n this.wasm.SetRepeatHeaderRow(this.handle, cellAnchorId, repeat ?? null),\n ) as EditResult;\n }\n\n /** Apply row layout options to the row containing the canonical cell anchor. */\n setTableRowOptions(cellAnchorId: string, options: TableRowOptions): EditResult {\n return JSON.parse(\n this.wasm.SetTableRowOptions(\n this.handle,\n cellAnchorId,\n options.repeatHeader ?? null,\n options.allowBreakAcrossPages ?? null,\n options.heightTwips ?? null,\n options.heightRule ?? \"atLeast\",\n ),\n ) as EditResult;\n }\n\n // \u2500\u2500\u2500 Headers / footers / page numbers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Set the running header story for the section that owns `anchorId` (any body block in that\n * section) to `markdown`. Creates the header part + `w:headerReference` if the story of `kind`\n * doesn't exist yet, else replaces its content. The created header-paragraph anchors (scope\n * `hdr{N}`) come back in `EditResult.created` \u2014 insert a page number into one with\n * {@link insertPageNumberField}. `\"first\"` sets the section's title-page flag; `\"even\"` sets the\n * document's even/odd-headers flag.\n */\n setHeaderText(anchorId: string, kind: HeaderFooterKind, markdown: string): EditResult {\n return JSON.parse(this.wasm.SetHeaderText(this.handle, anchorId, kind, markdown)) as EditResult;\n }\n\n /** Set the running footer story for the section that owns `anchorId` \u2014 see {@link setHeaderText};\n * the created footer-paragraph anchors (scope `ftr{N}`) come back in `EditResult.created`. */\n setFooterText(anchorId: string, kind: HeaderFooterKind, markdown: string): EditResult {\n return JSON.parse(this.wasm.SetFooterText(this.handle, anchorId, kind, markdown)) as EditResult;\n }\n\n /**\n * Append a page-number field to the paragraph `anchorId` \u2014 typically a header/footer paragraph\n * returned by {@link setFooterText}/{@link setHeaderText}. `\"currentPage\"` emits a PAGE field,\n * `\"totalPages\"` a NUMPAGES field (native complex field with a cached result), and\n * `\"pageOfTotal\"` Word's \"Page X of Y\" gallery entry \u2014 the text `Page `, a PAGE field, the text\n * ` of ` and a NUMPAGES field, every run inheriting the paragraph's last run formatting (the\n * pieces cannot be composed from the single-field form: text after a field cannot be appended\n * without rewriting the field's result). Center it by setting the paragraph alignment\n * ({@link setParagraphFormat}). Returns the paragraph anchor in `modified`.\n *\n * `format` writes the field's own `\\*` general-formatting switch (`PAGE \\* roman` \u2192 `i, ii, iii`).\n * Omitting it \u2014 the default \u2014 emits a plain field, which is what Word inserts and what follows the\n * SECTION's format ({@link setPageNumbering}). Prefer the section setting for ordinary page\n * numbering: a switch here overrides it for this one field and keeps overriding it if the section\n * later changes.\n */\n insertPageNumberField(\n anchorId: string,\n field?: PageNumberField,\n format?: NumberFormat\n ): EditResult {\n // An omitted field takes the engine's default (\"currentPage\"), declared once in DocxSessionOps.\n return JSON.parse(\n this.wasm.InsertPageNumberField(this.handle, anchorId, field ?? \"\", format ?? \"\")\n ) as EditResult;\n }\n\n /**\n * Set the page-numbering properties (`w:pgNumType`) of the section that owns `anchorId` (any body\n * block in that section) \u2014 Word's *Format Page Numbers\u2026* dialog: which number the section starts\n * at and which format its pages use. Omitted fields on `op` are left unchanged, so the start can\n * be set without disturbing the format and vice versa. Creates the element, and a trailing\n * `w:sectPr`, if absent.\n *\n * Applying values the section already has is a successful no-op that does NOT consume undo\n * history \u2014 safe to call from a dropdown's change handler.\n */\n setPageNumbering(anchorId: string, op: PageNumberingOp): EditResult {\n return JSON.parse(\n this.wasm.SetPageNumbering(this.handle, anchorId, JSON.stringify(op))\n ) as EditResult;\n }\n\n /**\n * Insert a **table of contents** before or after `anchorId` (issue #607). The field is written\n * dirty and the document asks for a field update on open, so Word paginates and fills the table\n * itself \u2014 nothing here ships a cached result that is stale the moment anything above it moves.\n *\n * The table is wrapped in the `w:sdt` content control Word puts around one, which is what gives\n * it the *Update Table* control in Word's UI. Word's `TOCHeading` and `TOC1` styles are\n * find-or-created; a document that already defines them keeps its own.\n *\n * Body anchors only, and refused under tracked-change recording: a generated table is regenerated\n * wholesale on every field update, so there is no reversible way to redline it.\n */\n insertTableOfContents(\n anchorId: string,\n pos?: \"before\" | \"after\",\n options?: TableOfContentsOptions\n ): EditResult {\n // An omitted position takes the engine's default for reference fields (\"before\").\n return JSON.parse(\n this.wasm.InsertTableOfContents(\n this.handle, anchorId, pos ?? \"\", options ? JSON.stringify(options) : \"\")\n ) as EditResult;\n }\n\n /**\n * Insert a **table of figures** \u2014 the captions carrying `options.captionLabel` and their page\n * numbers. Same field mechanics as {@link insertTableOfContents}; Word writes this one as a bare\n * paragraph rather than inside a content control, so this does too.\n */\n insertTableOfFigures(\n anchorId: string,\n pos?: \"before\" | \"after\",\n options?: TableOfFiguresOptions\n ): EditResult {\n // An omitted position takes the engine's default for reference fields (\"before\").\n return JSON.parse(\n this.wasm.InsertTableOfFigures(\n this.handle, anchorId, pos ?? \"\", options ? JSON.stringify(options) : \"\")\n ) as EditResult;\n }\n\n /**\n * Insert a **table of authorities** \u2014 the cases, statutes or other authorities marked in the\n * document, grouped by `options.category`. The table lists entries the document has MARKED with\n * `TA` fields; a document with no marked citations produces a table that is correct and empty.\n */\n insertTableOfAuthorities(\n anchorId: string,\n pos?: \"before\" | \"after\",\n options?: TableOfAuthoritiesOptions\n ): EditResult {\n // An omitted position takes the engine's default for reference fields (\"before\").\n return JSON.parse(\n this.wasm.InsertTableOfAuthorities(\n this.handle, anchorId, pos ?? \"\", options ? JSON.stringify(options) : \"\")\n ) as EditResult;\n }\n\n /**\n * Remove the section's page-numbering start/format: it reverts to continuing the previous\n * section's numbering in Word's default `1, 2, 3`. Chapter-numbering attributes\n * (`w:chapStyle`/`w:chapSep`) are preserved. A section with nothing to clear is a no-op.\n */\n clearPageNumbering(anchorId: string): EditResult {\n return JSON.parse(this.wasm.ClearPageNumbering(this.handle, anchorId)) as EditResult;\n }\n\n /**\n * Make the `kind` header/footer stories of the section that owns `anchorId` actually RENDER:\n * `\"first\"` sets `w:titlePg`, `\"even\"` sets the document-global `w:evenAndOddHeaders`;\n * `\"default\"` needs no flag and succeeds as a no-op. Idempotent.\n *\n * {@link setHeaderText}/{@link setFooterText} set these flags while writing content, which covers\n * authoring a story from scratch \u2014 but NOT a document that already carries a first/even reference\n * with the flag absent (Word leaves exactly that behind when \"Different first page\" is switched\n * off). Editing such a story through the text ops otherwise yields header content that is present\n * but invisible. Note the `\"even\"` caveat from {@link setHeaderText}: the flag is document-global\n * and governs footers too.\n */\n ensureHeaderFooterVisible(anchorId: string, kind: HeaderFooterKind): EditResult {\n return JSON.parse(this.wasm.EnsureHeaderFooterVisible(this.handle, anchorId, kind)) as EditResult;\n }\n\n /**\n * Word's \"Different first page\" / \"Different odd & even pages\" checkboxes as one verb: switch\n * the `kind` story of the section that owns `anchorId` (any body block in it) on or off.\n * `enabled: true` is exactly {@link ensureHeaderFooterVisible}; `enabled: false` removes the\n * flag that selects the story \u2014 `w:titlePg` from the governing `w:sectPr` for `\"first\"`, the\n * document-global `w:evenAndOddHeaders` for `\"even\"` \u2014 and leaves the story parts in place,\n * which is what Word does when the checkbox is cleared (re-enabling brings the content straight\n * back). Disabling `\"default\"` fails with `invalid_page_setup`: that story has no flag.\n *\n * A flag already in the requested state is a successful no-op that records NO undo step, so a\n * checkbox handler can call this unconditionally. Read the current state from\n * {@link SectionInfo.titlePage} / {@link SectionInfo.evenAndOddHeaders}.\n */\n setHeaderFooterKindEnabled(anchorId: string, kind: HeaderFooterKind, enabled: boolean): EditResult {\n if (!this.wasm.SetHeaderFooterKindEnabled) {\n throw new Error(\"SetHeaderFooterKindEnabled is not available in this WASM build\");\n }\n return JSON.parse(\n this.wasm.SetHeaderFooterKindEnabled(this.handle, anchorId, kind, enabled)\n ) as EditResult;\n }\n\n /**\n * Set the page geometry (`w:pgSz` / `w:pgMar`) of the section that owns `anchorId` \u2014 Word's\n * *Page Setup* dialog: page size, orientation, margins and header/footer distance. Omitted\n * fields on `op` are left unchanged; the elements are created in schema order when absent, as\n * is a trailing `w:sectPr` for a body that has none. Read the result back with\n * {@link getSectionInfo}.\n *\n * `landscape: true` without an explicit size swaps a portrait-shaped page's width and height\n * (and `false` swaps back), matching Word's orientation toggle. Invalid geometry \u2014 a\n * non-positive size, a negative margin, or opposing margins that leave no room \u2014 fails with\n * `invalid_page_setup` and touches nothing. Values the section already has are a successful\n * no-op that consumes no undo history.\n */\n setPageSetup(anchorId: string, op: PageSetupOp): EditResult {\n if (!this.wasm.SetPageSetup) {\n throw new Error(\"SetPageSetup is not available in this WASM build\");\n }\n return JSON.parse(\n this.wasm.SetPageSetup(this.handle, anchorId, JSON.stringify(op))\n ) as EditResult;\n }\n\n // \u2500\u2500\u2500 Footnotes / endnotes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Create a footnote whose body is `markdown` and cite it from the body paragraph `anchorId`, at\n * `characterOffset` characters into that paragraph's text (0 = before all text, text length =\n * after all of it). On a document with no footnotes yet this also creates the footnotes part,\n * Word's two reserved separator notes, the `FootnoteText`/`FootnoteReference` styles and the\n * `w:footnotePr` settings declaration; otherwise the existing part is reused. The note id is\n * allocated above every id already used in the package, so non-contiguous ids can't collide.\n *\n * Returns the created note anchors in `EditResult.created` \u2014 the definition (kind `fn`) and its\n * paragraphs (kind `p`, scope `fn`) \u2014 so the note can immediately be edited with\n * {@link replaceText} or removed with {@link deleteBlock} (which also drops the body reference).\n *\n * Body paragraphs only: Word does not allow a note reference inside a header/footer story or\n * inside another note, so a non-body anchor fails with `anchorWrongKind`.\n */\n insertFootnote(anchorId: string, characterOffset: number, markdown: string): EditResult {\n return JSON.parse(\n this.wasm.InsertFootnote(this.handle, anchorId, characterOffset, markdown),\n ) as EditResult;\n }\n\n /**\n * Insert a Word-faithful internal cross-reference \u2014 a `REF` field targeting an existing\n * bookmark \u2014 at a character offset (issue #545). The field carries a cached result run\n * (the bookmarked text, or the target's auto-number under `referenceNumber`), so\n * renderers that do not recompute fields show a faithful snapshot and Word updates it\n * like a hand-authored cross-reference. A missing or incoherent bookmark fails with\n * `missing_bookmark_target`.\n */\n insertCrossReference(\n anchorId: string,\n characterOffset: number,\n bookmarkName: string,\n options?: CrossReferenceOptions,\n ): EditResult {\n return JSON.parse(\n this.wasm.InsertCrossReference(\n this.handle, anchorId, characterOffset, bookmarkName,\n options ? JSON.stringify(options) : \"\",\n ),\n ) as EditResult;\n }\n\n /**\n * The document's footnotes (`endnotes` false) or endnotes (`endnotes` true) in citation order.\n * Each entry is the note's `w:id`, its definition anchor (kind `fn`/`en`, the anchor\n * {@link replaceText} and {@link deleteBlock} take) and its 1-based `ordinal`, which is the\n * number Word displays for it. Notes are found through their body references, so Word's\n * separator notes and a note nothing cites are not listed.\n */\n listNotes(endnotes: boolean): NoteListEntry[] {\n if (!this.wasm.ListNotes) {\n throw new Error(\"ListNotes is not available in this WASM build\");\n }\n return JSON.parse(this.wasm.ListNotes(this.handle, endnotes)) as NoteListEntry[];\n }\n\n /** Create an endnote \u2014 see {@link insertFootnote}; writes the endnotes part and a\n * `w:endnoteReference`, and the created definition anchor has kind `en`. */\n insertEndnote(anchorId: string, characterOffset: number, markdown: string): EditResult {\n return JSON.parse(\n this.wasm.InsertEndnote(this.handle, anchorId, characterOffset, markdown),\n ) as EditResult;\n }\n\n // \u2500\u2500\u2500 Comments (issue #300) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Add a **native Word comment** (real `w:comment` markup, visible in Word/Google\n * Docs/LibreOffice's Reviewing pane \u2014 not the {@link addAnnotation} overlay) on the body\n * paragraph `anchorId`. `span` selects the commented character range; `null` comments the\n * whole block. On a document with no comments yet this also creates the comments part and\n * the `CommentText`/`CommentReference` styles. `opts.date` (ISO-8601) is written only when\n * provided, keeping output deterministic by default.\n *\n * Returns the created definition anchor (kind `cmt`) and its paragraph anchors (kind `p`,\n * scope `cmt`) in `EditResult.created`, so the comment can immediately be edited with\n * {@link updateComment} or removed with {@link removeComment}.\n *\n * Body paragraphs only (Word has no comments-on-comments); a non-body anchor fails with\n * `anchor_wrong_kind`, a zero-length span with `empty_comment_span`.\n */\n addComment(\n anchorId: string,\n span: CharSpan | null,\n author: string,\n markdown: string,\n opts?: { initials?: string; date?: string },\n ): EditResult {\n const spanJson = span ? JSON.stringify(span) : \"\";\n return JSON.parse(\n this.wasm.AddComment(\n this.handle,\n anchorId,\n spanJson,\n author,\n opts?.initials ?? \"\",\n opts?.date ?? \"\",\n markdown,\n ),\n ) as EditResult;\n }\n\n /** Add a native Word comment around the exact live extent of a tracked revision returned by\n * {@link listRevisions}. Accepting/rejecting the revision keeps the comment and either leaves\n * its range on surviving text or collapses it to a point. */\n addCommentToRevision(\n revisionId: string,\n author: string,\n markdown: string,\n opts?: { initials?: string; date?: string },\n ): EditResult {\n return JSON.parse(\n this.wasm.AddCommentToRevision(\n this.handle,\n revisionId,\n author,\n opts?.initials ?? \"\",\n opts?.date ?? \"\",\n markdown,\n ),\n ) as EditResult;\n }\n\n /**\n * Add a native Word reply to `parentCommentAnchorId`. It adds an adjacent reference and\n * inherits the thread root's range through `w15:paraIdParent`; the required\n * `commentsExtended.xml` and `commentsIds.xml` parts are created when the parent was flat.\n */\n addCommentReply(\n parentCommentAnchorId: string,\n author: string,\n markdown: string,\n opts?: { initials?: string; date?: string },\n ): EditResult {\n return JSON.parse(\n this.wasm.AddCommentReply(\n this.handle,\n parentCommentAnchorId,\n author,\n opts?.initials ?? \"\",\n opts?.date ?? \"\",\n markdown,\n ),\n ) as EditResult;\n }\n\n /** Replace a comment's body text, addressed by its definition anchor (kind `cmt`); the\n * comment's author/initials/date are preserved, as is the last paragraph's `w14:paraId`\n * (Word's reply-threading key). */\n updateComment(commentAnchorId: string, markdown: string): EditResult {\n return JSON.parse(this.wasm.UpdateComment(this.handle, commentAnchorId, markdown)) as EditResult;\n }\n\n /** Resolve or reopen one comment (`false` reopens it). Flat comments are upgraded with the\n * paraId-keyed metadata Word uses, and the operation is undoable. */\n setCommentResolved(commentAnchorId: string, resolved: boolean): EditResult {\n return JSON.parse(\n this.wasm.SetCommentResolved(this.handle, commentAnchorId, resolved),\n ) as EditResult;\n }\n\n /** Remove a comment: the definition, its body marker triple everywhere in the package, and\n * any `commentsExtended`/`commentsIds` threading entries keyed by it. */\n removeComment(commentAnchorId: string): EditResult {\n return JSON.parse(this.wasm.RemoveComment(this.handle, commentAnchorId)) as EditResult;\n }\n\n /** The document's native Word comments in comments-part order. */\n listComments(): CommentListEntry[] {\n return JSON.parse(this.wasm.ListComments(this.handle)) as CommentListEntry[];\n }\n\n listHyperlinks(scopes: ProjectionScopes = ProjectionScopes.All): HyperlinkInfo[] {\n return JSON.parse(this.wasm.ListHyperlinks(this.handle, scopes)) as HyperlinkInfo[];\n }\n\n addHyperlink(anchorId: string, span: CharSpan, kind: HyperlinkKind, target: string): EditResult {\n return JSON.parse(this.wasm.AddHyperlink(\n this.handle, anchorId, span.start, span.length, kind, target,\n )) as EditResult;\n }\n\n updateHyperlink(hyperlinkId: string, kind: HyperlinkKind, target: string): EditResult {\n return JSON.parse(this.wasm.UpdateHyperlink(this.handle, hyperlinkId, kind, target)) as EditResult;\n }\n\n removeHyperlink(hyperlinkId: string): EditResult {\n return JSON.parse(this.wasm.RemoveHyperlink(this.handle, hyperlinkId)) as EditResult;\n }\n\n /** Versioned operational facts for native image inspection/mutation in this runtime. */\n getImageCapabilities(): ImageCapabilities {\n return JSON.parse(this.wasm.GetImageCapabilities()) as ImageCapabilities;\n }\n\n listImages(scopes: ProjectionScopes = ProjectionScopes.All): ImageOccurrence[] {\n return JSON.parse(this.wasm.ListImages(this.handle, scopes)) as ImageOccurrence[];\n }\n\n insertImage(anchorId: string, characterOffset: number, bytes: Uint8Array,\n options: ImageInsertOptions = {}): EditResult {\n return JSON.parse(this.wasm.InsertImage(this.handle, anchorId, characterOffset,\n imageBytesToBase64(bytes), JSON.stringify(options))) as EditResult;\n }\n\n replaceImage(imageId: string, bytes: Uint8Array): EditResult {\n return JSON.parse(this.wasm.ReplaceImage(\n this.handle, imageId, imageBytesToBase64(bytes))) as EditResult;\n }\n\n /**\n * Convert an external linked picture into an embedded one using bytes the caller fetched;\n * the engine never reaches the network itself. Refused for pictures that already embed\n * their media \u2014 see `ImageOccurrence.operations`.\n */\n embedLinkedImage(imageId: string, bytes: Uint8Array): EditResult {\n return JSON.parse(this.wasm.EmbedLinkedImage(\n this.handle, imageId, imageBytesToBase64(bytes))) as EditResult;\n }\n\n setImageDimensions(imageId: string, dimensions: ImageDimensions): EditResult {\n return JSON.parse(this.wasm.SetImageDimensions(\n this.handle, imageId, JSON.stringify(dimensions))) as EditResult;\n }\n\n setImageMetadata(imageId: string, altText: string | null, title: string | null): EditResult {\n return JSON.parse(this.wasm.SetImageMetadata(\n this.handle, imageId, altText, title)) as EditResult;\n }\n\n setImageFloatingLayout(imageId: string, layout: FloatingImageLayout): EditResult {\n return JSON.parse(this.wasm.SetImageFloatingLayout(\n this.handle, imageId, JSON.stringify(layout))) as EditResult;\n }\n\n removeImage(imageId: string): EditResult {\n return JSON.parse(this.wasm.RemoveImage(this.handle, imageId)) as EditResult;\n }\n\n /** Native Word structured-document tags, in outer-before-inner story order. */\n listContentControls(scopes: ProjectionScopes = ProjectionScopes.All): ContentControlInfo[] {\n return JSON.parse(this.wasm.ListContentControls(this.handle, scopes)) as ContentControlInfo[];\n }\n\n fillContentControlText(anchorId: string, text: string,\n options: ContentControlFillOptions = {}): EditResult {\n return JSON.parse(this.wasm.FillContentControlText(\n this.handle, anchorId, text, JSON.stringify(options))) as EditResult;\n }\n\n fillContentControlRichText(anchorId: string, markdown: string,\n options: ContentControlFillOptions = {}): EditResult {\n return JSON.parse(this.wasm.FillContentControlRichText(\n this.handle, anchorId, markdown, JSON.stringify(options))) as EditResult;\n }\n\n setContentControlChecked(anchorId: string, isChecked: boolean,\n options: ContentControlFillOptions = {}): EditResult {\n return JSON.parse(this.wasm.SetContentControlChecked(\n this.handle, anchorId, isChecked, JSON.stringify(options))) as EditResult;\n }\n\n setContentControlDate(anchorId: string, value: string | Date, displayText?: string,\n options: ContentControlFillOptions = {}): EditResult {\n const timestamp = value instanceof Date ? value.toISOString() : value;\n return JSON.parse(this.wasm.SetContentControlDate(\n this.handle, anchorId, timestamp, displayText ?? null, JSON.stringify(options))) as EditResult;\n }\n\n selectContentControlItem(anchorId: string, value: string,\n options: ContentControlFillOptions = {}): EditResult {\n return JSON.parse(this.wasm.SelectContentControlItem(\n this.handle, anchorId, value, JSON.stringify(options))) as EditResult;\n }\n\n fillContentControlPicture(anchorId: string, bytes: Uint8Array,\n options: ContentControlFillOptions = {}): EditResult {\n return JSON.parse(this.wasm.FillContentControlPicture(\n this.handle, anchorId, imageBytesToBase64(bytes), JSON.stringify(options))) as EditResult;\n }\n\n addRepeatingSectionItem(sectionAnchorId: string, afterItemAnchorId?: string,\n options: ContentControlFillOptions = {}): EditResult {\n return JSON.parse(this.wasm.AddRepeatingSectionItem(\n this.handle, sectionAnchorId, afterItemAnchorId ?? \"\", JSON.stringify(options))) as EditResult;\n }\n\n removeRepeatingSectionItem(itemAnchorId: string): EditResult {\n return JSON.parse(this.wasm.RemoveRepeatingSectionItem(\n this.handle, itemAnchorId)) as EditResult;\n }\n\n listBookmarks(scopes: ProjectionScopes = ProjectionScopes.All): BookmarkInfo[] {\n return JSON.parse(this.wasm.ListBookmarks(this.handle, scopes)) as BookmarkInfo[];\n }\n\n addBookmark(name: string, range: DocumentRange): EditResult {\n return JSON.parse(this.wasm.AddBookmark(this.handle, name,\n range.startAnchorId, range.startOffset, range.endAnchorId, range.endOffset)) as EditResult;\n }\n\n renameBookmark(name: string, newName: string): EditResult {\n return JSON.parse(this.wasm.RenameBookmark(this.handle, name, newName)) as EditResult;\n }\n\n moveBookmark(name: string, range: DocumentRange): EditResult {\n return JSON.parse(this.wasm.MoveBookmark(this.handle, name,\n range.startAnchorId, range.startOffset, range.endAnchorId, range.endOffset)) as EditResult;\n }\n\n removeBookmark(name: string): EditResult {\n return JSON.parse(this.wasm.RemoveBookmark(this.handle, name)) as EditResult;\n }\n\n // \u2500\u2500\u2500 Tracked revisions (issue #318) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Markup-native tracked-revision listing, in document order across body, headers,\n * footers, footnotes, and endnotes. Ids are stable while the underlying markup\n * exists and address {@link acceptRevision}/{@link rejectRevision}; authors/dates\n * are the markup's own (no accept/reject re-diff). */\n listRevisions(filter?: RevisionListFilter): RevisionListEntry[] {\n if (filter && Object.values(filter).some((v) => v != null)) {\n if (!this.wasm.ListRevisionsFiltered) {\n throw new Error(\"This WASM bundle predates filtered revision listing; rebuild docxodus.\");\n }\n return JSON.parse(\n this.wasm.ListRevisionsFiltered(this.handle, JSON.stringify(filter)),\n ) as RevisionListEntry[];\n }\n return JSON.parse(this.wasm.ListRevisions(this.handle)) as RevisionListEntry[];\n }\n\n /**\n * The explicit repairs the registry offers for entries it refuses to resolve (issues\n * #754\u2013#758): which carriers are defective, whether a unique repair exists, and what it\n * would do. Read-only; listing, accept and reject never repair.\n */\n listRevisionRepairs(): RevisionRepairProposal[] {\n if (!this.wasm.ListRevisionRepairs) {\n throw new Error(\"This WASM bundle predates revision repairs; rebuild docxodus.\");\n }\n return JSON.parse(this.wasm.ListRevisionRepairs(this.handle)) as RevisionRepairProposal[];\n }\n\n /**\n * Perform requested repairs atomically as one undo step. A kind the registry did not offer,\n * a non-repairable proposal, or a wrap-as-deletion without author and date refuses the whole\n * call (`revision_repair_rejected`) with nothing mutated. Repaired entries get new ids.\n */\n repairRevisions(repairs: readonly RevisionRepairRequest[]): RevisionRepairResult {\n if (!this.wasm.RepairRevisions) {\n throw new Error(\"This WASM bundle predates revision repairs; rebuild docxodus.\");\n }\n return JSON.parse(this.wasm.RepairRevisions(this.handle, JSON.stringify(repairs))) as RevisionRepairResult;\n }\n\n /** Accept ONE revision by the id {@link listRevisions} reported \u2014 insertions keep\n * their content, deletions are carried out, a move materializes at its destination,\n * a format change keeps the new properties. Undoable. */\n acceptRevision(revisionId: string): EditResult {\n return JSON.parse(this.wasm.AcceptRevision(this.handle, revisionId)) as EditResult;\n }\n\n /** Reject ONE revision by id \u2014 the inverse of {@link acceptRevision}: insertions are\n * removed, deleted content is restored, a move stays at its source, a format change\n * restores the stored old properties. Undoable. */\n rejectRevision(revisionId: string): EditResult {\n return JSON.parse(this.wasm.RejectRevision(this.handle, revisionId)) as EditResult;\n }\n\n /**\n * Accept every live revision as one undoable session mutation.\n *\n * Fails closed: an unsupported, malformed, or ambiguous registry entry aborts the whole\n * operation (`revisionUnsupported`/`revisionMalformed`/`revisionAmbiguous`) and nothing is\n * mutated. There is no force mode \u2014 call {@link listRevisions} and read each entry's\n * `diagnostic` to see what blocks it.\n */\n acceptAllRevisions(): EditResult {\n return JSON.parse(this.wasm.AcceptAllRevisions(this.handle)) as EditResult;\n }\n\n /** Reject every live revision as one undoable session mutation. Fails closed exactly like\n * {@link acceptAllRevisions}. */\n rejectAllRevisions(): EditResult {\n return JSON.parse(this.wasm.RejectAllRevisions(this.handle)) as EditResult;\n }\n\n // \u2500\u2500\u2500 Tier C: formatting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n applyFormat(anchorId: string, span: CharSpan | null, op: FormatOp): EditResult {\n const spanJson = span ? JSON.stringify(span) : \"\";\n return JSON.parse(this.wasm.ApplyFormat(this.handle, anchorId, spanJson, JSON.stringify(op))) as EditResult;\n }\n\n /**\n * Convenience: find `substring` in the anchor's flat text and apply `op` to the\n * first occurrence. Eliminates the offset-arithmetic trap from #138 \u2014 caller passes\n * the visible text they want formatted, the WASM-side resolves it to a CharSpan.\n */\n applyFormatBySubstring(anchorId: string, substring: string, op: FormatOp): EditResult {\n return JSON.parse(\n this.wasm.ApplyFormatBySubstring(this.handle, anchorId, substring, JSON.stringify(op))\n ) as EditResult;\n }\n\n /**\n * Convenience: apply `op` to the exact span of a {@link TextMatch} (typically from\n * {@link grep}). The match's `enclosingAnchor.id` + `span` address one specific\n * occurrence even when several identical needles share the same block.\n */\n applyFormatToMatch(match: TextMatch, op: FormatOp): EditResult {\n const span: CharSpan = { start: match.span.start, length: match.span.length };\n return this.applyFormat(match.enclosingAnchor.id, span, op);\n }\n\n setParagraphStyle(anchorId: string, styleId: string): EditResult {\n return JSON.parse(this.wasm.SetParagraphStyle(this.handle, anchorId, styleId)) as EditResult;\n }\n\n /** Set paragraph alignment / indent / page-break-before (omitted fields are left unchanged). */\n setParagraphFormat(anchorId: string, op: ParagraphFormatOp): EditResult {\n return JSON.parse(this.wasm.SetParagraphFormat(this.handle, anchorId, JSON.stringify(op))) as EditResult;\n }\n\n setListLevel(anchorId: string, levelDelta: number): EditResult {\n return JSON.parse(this.wasm.SetListLevel(this.handle, anchorId, levelDelta)) as EditResult;\n }\n\n removeListMembership(anchorId: string): EditResult {\n return JSON.parse(this.wasm.RemoveListMembership(this.handle, anchorId)) as EditResult;\n }\n\n /** Make the paragraph a bullet/numbered list item, or remove list membership (\"none\"). */\n applyListFormat(anchorId: string, kind: ListFormat): EditResult {\n return JSON.parse(this.wasm.ApplyListFormat(this.handle, anchorId, kind)) as EditResult;\n }\n\n /** Apply one list format across the contiguous sibling run from `firstAnchorId` to\n * `lastAnchorId` inclusive (either document order). Every member shares one `w:num`\n * instance so the numbering sequence stays intact; the whole range is a single undo step. */\n applyListFormatRange(firstAnchorId: string, lastAnchorId: string, kind: ListFormat): EditResult {\n return JSON.parse(\n this.wasm.ApplyListFormatRange(this.handle, firstAnchorId, lastAnchorId, kind),\n ) as EditResult;\n }\n\n /** Restart the anchored list item's numbering at `value` \u2014 Word's *Set Numbering Value\u2026*.\n * Writes a `w:startOverride` on a dedicated `w:num` instance and repoints the anchored item\n * plus every following member of its sequence, so a mid-list restart splits the sequence\n * exactly like Word (earlier items keep their numbers, the tail continues from `value`). */\n setListStartOverride(anchorId: string, value: number): EditResult {\n return JSON.parse(this.wasm.SetListStartOverride(this.handle, anchorId, value)) as EditResult;\n }\n\n /** Remove the numbering restart from the anchored item's whole sequence (the inverse of\n * {@link setListStartOverride}); the sequence reverts to the definition's own start. A\n * sequence with no override at the item's level is a successful no-op. */\n clearListStartOverride(anchorId: string): EditResult {\n return JSON.parse(this.wasm.ClearListStartOverride(this.handle, anchorId)) as EditResult;\n }\n\n // \u2500\u2500\u2500 Tier D: cell content \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n replaceCellContent(cellAnchorId: string, markdown: string): EditResult {\n return JSON.parse(this.wasm.ReplaceCellContent(this.handle, cellAnchorId, markdown)) as EditResult;\n }\n\n // \u2500\u2500\u2500 Raw escape hatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n readonly raw = {\n getXml: (anchorId: string): string => this.wasm.RawGetXml(this.handle, anchorId),\n insertXml: (anchorId: string, position: \"before\" | \"after\", xml: string): EditResult =>\n JSON.parse(this.wasm.RawInsertXml(this.handle, anchorId, position, xml)) as EditResult,\n replaceXml: (anchorId: string, xml: string): EditResult =>\n JSON.parse(this.wasm.RawReplaceXml(this.handle, anchorId, xml)) as EditResult,\n };\n\n // \u2500\u2500\u2500 Search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Searches the flat text of every paragraph/heading/list-item in scope for\n * matches of `pattern`, returning them in document order with the run\n * fragments each match spans. Lets callers rewrite a match in place while\n * preserving each fragment's formatting (bold/italic/hyperlink/etc.).\n *\n * `pattern` is a regular expression \u2014 use plain string equivalents wrapped\n * in `^` / `$` or pass literal text escaped via a helper.\n *\n * @see docs/architecture/docx_mutation_api.md#grep\n */\n grep(pattern: string, options?: GrepOptions): TextMatch[] {\n return JSON.parse(this.wasm.Grep(this.handle, pattern, options ? JSON.stringify(options) : \"\")) as TextMatch[];\n }\n\n /**\n * Like {@link grep}, but lets a single match span adjacent block-level\n * siblings (paragraphs/headings/list items) under the same parent. Block\n * boundaries appear in the matched text as `\\n`, so `^`/`$` with the\n * Multiline flag anchor at boundaries and `.` won't cross unless Singleline\n * is set.\n *\n * Matches never cross OOXML package parts, container boundaries (body \u2192\n * table cell), or non-paragraph siblings (a table between two paragraphs\n * breaks the run). Returned superset of {@link grep}: single-block matches\n * still appear with one slice. Filter `slices.length > 1` for cross-block only.\n *\n * @see docs/architecture/docx_mutation_api.md#grepcrossblock\n */\n grepCrossBlock(pattern: string, options?: GrepOptions): CrossBlockMatch[] {\n return JSON.parse(\n this.wasm.GrepCrossBlock(this.handle, pattern, options ? JSON.stringify(options) : \"\")\n ) as CrossBlockMatch[];\n }\n\n /**\n * Finds every literal occurrence of `find` in the anchor's flat text and\n * replaces it with `replace`, preserving the surrounding run formatting that\n * the match didn't touch. Returns one `EditResult` per attempted match.\n *\n * A `find` that matches nothing fails with a single `text_not_found` result\n * naming the anchor and the needle \u2014 never an empty array. Pass\n * `expectedMatchCount: 0` to assert absence as a successful no-op instead.\n *\n * Run-formatting contract: the replacement text inherits the formatting of\n * the FIRST run the match spanned. Middle/trailing runs keep their `w:rPr`\n * but lose the slice of text the match consumed.\n *\n * @see docs/architecture/docx_mutation_api.md#replacetextrange\n */\n replaceTextRange(anchorId: string, find: string, replace: string, options?: ReplaceOptions): EditResult[] {\n return JSON.parse(\n this.wasm.ReplaceTextRange(this.handle, anchorId, find, replace, options ? JSON.stringify(options) : \"\")\n ) as EditResult[];\n }\n\n /**\n * Replaces a specific Grep match in place \u2014 addresses the exact span by\n * `enclosingAnchor.id` + `span.{start,length}`, so identical needles in the\n * same paragraph (the template-fill case where five `[___]` placeholders\n * each get a different value) don't collide.\n *\n * Pass `format` to replace text and format exactly the replacement atomically, with one\n * undo/version unit. This interactive path returns an ordinary EditResult and avoids the\n * package checkpoint/hash required by executeBatch's receipt. Empty replacements only delete.\n */\n replaceMatch(match: TextMatch, replace: string, format?: FormatOp): EditResult {\n if (format !== undefined) {\n if (!this.wasm.ReplaceTextAtSpanWithFormat) {\n throw new Error(\"This WASM bundle predates atomic text-plus-format edits; rebuild docxodus.\");\n }\n return JSON.parse(this.wasm.ReplaceTextAtSpanWithFormat(\n this.handle, match.enclosingAnchor.id, match.span.start, match.span.length, replace,\n JSON.stringify(format),\n )) as EditResult;\n }\n return JSON.parse(\n this.wasm.ReplaceTextAtSpan(this.handle, match.enclosingAnchor.id, match.span.start, match.span.length, replace)\n ) as EditResult;\n }\n\n /**\n * Helper for {@link fillPlaceholders} `coalesceWhitespaceAroundEmptyFill` path \u2014\n * mirrors the .NET `ReplaceMatchCoalescingNeighbors` rules. Inspects the chars\n * immediately surrounding the match via `match.contextBefore` / `contextAfter`\n * (so the option requires `contextChars >= 1`, the default) and expands the\n * deletion span to absorb whitespace / leading-space-before-punctuation /\n * matched-brackets where the patterns match. Falls back to literal-delete\n * when no neighbor pattern applies.\n *\n * Note: with `boundary: ContextBoundary.Bracket`, neighbor brackets are not\n * captured in context, so the bracket-coalesce rule won't fire on the JS side.\n * The .NET implementation reads flat text directly and handles that case;\n * callers who care should leave `boundary` at the default `Char`.\n */\n private replaceMatchCoalescingNeighbors(match: TextMatch): EditResult {\n // Fold NBSP / narrow NBSP / thin space to ASCII space so e.g. an NBSP on\n // either side still gets treated as whitespace by the rules below.\n const fold = (c: string | undefined): string | undefined => {\n if (c === \"\u00A0\" || c === \"\u202F\" || c === \"\u2009\") return \" \";\n return c;\n };\n const l = fold(match.contextBefore.length > 0 ? match.contextBefore[match.contextBefore.length - 1] : undefined);\n const r = fold(match.contextAfter.length > 0 ? match.contextAfter[0] : undefined);\n\n const isSpace = (c: string | undefined): boolean => c === \" \" || c === \"\\t\";\n const isClauseTerm = (c: string | undefined): boolean =>\n c === \".\" || c === \",\" || c === \";\" || c === \":\" || c === \"!\" || c === \"?\";\n const isOpen = (c: string | undefined): boolean => c === \"(\" || c === \"[\" || c === \"{\";\n const isClose = (c: string | undefined): boolean => c === \")\" || c === \"]\" || c === \"}\";\n\n let extendLeft = 0;\n let extendRight = 0;\n if (isSpace(l) && isSpace(r)) {\n extendRight = 1;\n } else if (isSpace(l) && isClauseTerm(r)) {\n extendLeft = 1;\n } else if (isOpen(l) && isClose(r)) {\n extendLeft = 1;\n extendRight = 1;\n }\n\n if (extendLeft === 0 && extendRight === 0) {\n return this.replaceMatch(match, \"\");\n }\n\n return JSON.parse(\n this.wasm.ReplaceTextAtSpan(\n this.handle,\n match.enclosingAnchor.id,\n match.span.start - extendLeft,\n match.span.length + extendLeft + extendRight,\n \"\",\n ),\n ) as EditResult;\n }\n\n /**\n * Replace the bracketed portion of a `TextMatch` with `newInner`, preserving any\n * prefix or suffix outside the brackets. Designed for `findPlaceholders` matches\n * like `$[___]` where the regex `\\$?\\[\u2026\\]` captures a leading `$`:\n * `replaceInner(match, \"0.20\")` yields `$0.20`, not `0.20`.\n *\n * Returns `MalformedMarkdown` if the match text does not contain balanced brackets.\n */\n replaceInner(match: TextMatch, newInner: string): EditResult {\n return JSON.parse(this.wasm.ReplaceInner(\n this.handle,\n match.text,\n match.enclosingAnchor.id,\n match.span.start,\n match.span.length,\n newInner,\n )) as EditResult;\n }\n\n /**\n * Picker-driven template fill. For every placeholder matching `options.kinds`,\n * calls `picker`; if the picker returns a non-null string, the placeholder is\n * replaced (with optional `$`-prefix preservation). Iterates until no more\n * placeholders match (or `maxPasses` is reached, or a pass makes zero changes)\n * \u2014 handles nested brackets that surface only after the inner ones are stripped.\n *\n * The TypeScript implementation mirrors the .NET `DocxSession.FillPlaceholders`\n * exactly.\n *\n * The picker is invoked synchronously by this loop on the JS side (it does\n * NOT run inside the WASM module). Async pickers are not supported: returning\n * a `Promise` will cause a `TypeError` at runtime inside the `$`-prefix\n * preservation branch (`Promise.startsWith is not a function`). For async\n * data, pre-build a lookup map before calling and have the picker read from\n * it synchronously.\n */\n fillPlaceholders(\n picker: (p: TemplatePlaceholder) => string | null | undefined,\n options?: FillOptions,\n ): BulkEditResult {\n const opts = options ?? {};\n // Default Kinds = All so the picker is invoked for every kind the doc contains.\n // Callers that want to ignore AlternativeClause matches should narrow this to\n // `PlaceholderKinds.BlankFill | PlaceholderKinds.Instruction`.\n const kinds = opts.kinds ?? PlaceholderKinds.All;\n const scope = opts.scope ?? 1; // Body\n const maxPasses = opts.maxPasses ?? 8;\n const preserveDollarPrefix = opts.preserveDollarPrefix ?? true;\n const contextChars = opts.contextChars;\n const boundary = opts.boundary ?? ContextBoundary.Char;\n const coalesceEmpty = opts.coalesceWhitespaceAroundEmptyFill ?? false;\n\n if (maxPasses <= 0) {\n throw new RangeError(\"FillOptions.maxPasses must be > 0\");\n }\n\n let filled = 0;\n let workPasses = 0;\n const errors: EditError[] = [];\n const unfilled: TemplatePlaceholder[] = [];\n const seenSkipKeys = new Set<string>();\n\n for (let pass = 1; pass <= maxPasses; pass++) {\n const placeholders = this.findPlaceholders(kinds, scope, contextChars, boundary)\n .sort((a, b) => {\n const cmp = b.match.enclosingAnchor.id.localeCompare(a.match.enclosingAnchor.id);\n if (cmp !== 0) return cmp;\n return b.match.span.start - a.match.span.start;\n });\n if (placeholders.length === 0) break;\n\n let passChanges = 0;\n for (const p of placeholders) {\n const pick = picker(p);\n if (pick == null) {\n const key = `${p.match.enclosingAnchor.id}:${p.match.span.start}:${p.match.span.length}`;\n if (!seenSkipKeys.has(key)) {\n seenSkipKeys.add(key);\n unfilled.push(p);\n }\n continue;\n }\n\n let replacement = pick;\n if (preserveDollarPrefix && p.match.text.startsWith(\"$\") && !replacement.startsWith(\"$\")) {\n replacement = \"$\" + replacement;\n }\n\n const r = coalesceEmpty && replacement.length === 0\n ? this.replaceMatchCoalescingNeighbors(p.match)\n : this.replaceMatch(p.match, replacement);\n if (r.success) {\n filled++;\n passChanges++;\n } else if (r.error) {\n errors.push(r.error);\n }\n }\n\n if (passChanges > 0) workPasses = pass;\n if (passChanges === 0) break;\n }\n\n const stillPresent = this.findPlaceholders(kinds, scope).length;\n\n return {\n filled,\n skipped: unfilled.length,\n stillPresent,\n passes: workPasses,\n unfilled,\n errors,\n };\n }\n\n /**\n * Enumerate template placeholders in the document. Thin classifier over\n * {@link grep}: distinguishes `[___]` value blanks (`blank_fill`),\n * `[bracketed alternative clauses]` (`alternative_clause`), and\n * `[insert X]` / `[*italic hint*]` instructions (`instruction`).\n *\n * Combine kinds with bitwise OR: `PlaceholderKinds.BlankFill | PlaceholderKinds.Instruction`.\n * Default is `PlaceholderKinds.All`; default scope is body only (1).\n *\n * @see docs/architecture/docx_mutation_api.md#findplaceholders\n */\n findPlaceholders(\n kinds?: number,\n scope?: number,\n contextChars?: number,\n boundary?: number,\n citation?: PageCitationRequest,\n ): TemplatePlaceholder[] {\n // Omitted arguments take the engine's defaults (all kinds, the body, 80 characters, cut at a\n // character), declared once in DocxSessionOps and DocxSession.\n const json = citation\n ? this.wasm.FindPlaceholdersWithCitations(\n this.handle, kinds ?? null, scope ?? null, contextChars ?? null, boundary ?? null,\n JSON.stringify(citation),\n )\n : this.wasm.FindPlaceholders(\n this.handle, kinds ?? null, scope ?? null, contextChars ?? null, boundary ?? null);\n return JSON.parse(json) as TemplatePlaceholder[];\n }\n\n /**\n * Returns a snapshot of edit-state introspection signals \u2014 placeholder counts,\n * underscore-run leftovers, footnote/comment counts. Useful for \"am I done?\"\n * verification at the end of an edit pipeline.\n */\n getEditSummary(): EditSummary {\n return JSON.parse(this.wasm.GetEditSummary(this.handle)) as EditSummary;\n }\n\n /**\n * Discoverability alias for {@link findPlaceholders}. Same return shape.\n */\n remainingPlaceholders(kinds?: number): TemplatePlaceholder[] {\n return JSON.parse(this.wasm.RemainingPlaceholders(this.handle, kinds ?? null)) as TemplatePlaceholder[];\n }\n\n /**\n * Diff the document's current projection against the projection captured at\n * session construction time.\n *\n * Requires `captureInitialProjection: true` in {@link DocxSessionSettings}\n * (the default). Throws if not enabled.\n *\n * The return type depends on `format`:\n * - `DiffFormat.Json` (default) \u2014 structured anchor-keyed `DiffEntry[]`.\n * - `DiffFormat.Unified` \u2014 `patch(1)`-compatible unified-diff text;\n * empty string when nothing has changed.\n * - `DiffFormat.SideBySide` \u2014 two-column human-review text\n * (`diff -y` style).\n */\n getDiff(format?: typeof DiffFormat.Json): DiffEntry[];\n getDiff(format: typeof DiffFormat.Unified | typeof DiffFormat.SideBySide): string;\n getDiff(format?: number): DiffEntry[] | string {\n // An omitted format reaches the engine as null and takes its default (JSON, declared once in\n // DocxSessionOps); the overloads above promise the parsed form for it.\n const raw = this.wasm.GetDiff(this.handle, format ?? null);\n if (format == null || format === DiffFormat.Json) {\n return JSON.parse(raw) as DiffEntry[];\n }\n return raw;\n }\n\n /**\n * Return stable semantic changes from the package opened for this session to\n * its current state. Requires `captureInitialProjection` (enabled by default).\n */\n getSemanticChanges(): SemanticChangeSet {\n return JSON.parse(this.wasm.GetSemanticChanges(this.handle)) as SemanticChangeSet;\n }\n\n /**\n * Run the default deliverable gate on this session's normal clean-save checkpoint.\n * With initial projection capture enabled (the default), exact opening bytes are the\n * baseline used for dispositions and semantic/package deltas.\n */\n verifyDeliverable(request?: DeliverableVerificationRequest): DeliverableVerificationResult {\n if (request !== undefined) {\n // The full request (issue #747): policy/limit options, expected deltas, companions.\n if (!this.wasm.VerifyDeliverableWithRequest) {\n throw new Error(\"This WASM bundle predates full verification requests; rebuild docxodus.\");\n }\n return JSON.parse(this.wasm.VerifyDeliverableWithRequest(\n this.handle, serializeVerificationRequest(request))) as DeliverableVerificationResult;\n }\n return JSON.parse(\n this.wasm.VerifyDeliverable(this.handle),\n ) as DeliverableVerificationResult;\n }\n\n // \u2500\u2500\u2500 Annotation-based anchor discovery (#132) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolves an annotation's range to the block-level markdown anchors covering\n * it, in document order. The bridge between Docxodus' read-side annotation API\n * and the write-side session: an agent that wants to edit \"the indemnification\n * clause\" looks the annotation up by id and gets the anchors it can hand to\n * {@link replaceText} / {@link deleteBlock} / {@link raw}. Returns an empty\n * list when the id is unknown or its bookmark is missing.\n *\n * v1 returns the enclosing block anchors \u2014 every paragraph/heading/list-item/\n * cell/row/table whose subtree overlaps the bookmark range. Filter by\n * `kind === \"p\" | \"h\" | \"li\"` when you want only text-bearing blocks.\n *\n * @see docs/architecture/docx_mutation_api.md#findbyannotation\n */\n findByAnnotation(annotationId: string, citation?: PageCitationRequest): AnchorTargetRef[] {\n const json = citation\n ? this.wasm.FindByAnnotationWithCitations(this.handle, annotationId, JSON.stringify(citation))\n : this.wasm.FindByAnnotation(this.handle, annotationId);\n return JSON.parse(json) as AnchorTargetRef[];\n }\n\n /**\n * Finds every annotation whose `labelId` matches and resolves each of their\n * ranges. The result is keyed by annotation id so callers can disambiguate\n * when the same label is applied to multiple regions (three \"WARRANTY\"\n * annotations on different paragraphs become three entries). Annotations\n * whose bookmark resolves to no anchors are omitted from the result.\n */\n findByLabel(labelId: string, citation?: PageCitationRequest): Record<string, AnchorTargetRef[]> {\n const json = citation\n ? this.wasm.FindByLabelWithCitations(this.handle, labelId, JSON.stringify(citation))\n : this.wasm.FindByLabel(this.handle, labelId);\n return JSON.parse(json) as Record<string, AnchorTargetRef[]>;\n }\n\n /**\n * Resolves any bookmark in the main document part (Docxodus-managed or\n * user-authored) to the block-level anchors covering its range, in document\n * order. Empty when the bookmark name is unknown. Use this for raw bookmark\n * names that didn't come from the annotation system.\n */\n findByBookmark(bookmarkName: string, citation?: PageCitationRequest): AnchorTargetRef[] {\n const json = citation\n ? this.wasm.FindByBookmarkWithCitations(this.handle, bookmarkName, JSON.stringify(citation))\n : this.wasm.FindByBookmark(this.handle, bookmarkName);\n return JSON.parse(json) as AnchorTargetRef[];\n }\n\n // \u2500\u2500\u2500 Text/kind-based anchor discovery (#171) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * True when `anchorId` resolves to a live element in the current session.\n * Cheap existence probe \u2014 use it to guard an anchor obtained from an earlier\n * projection before handing it to a mutation (anchors can be invalidated by\n * intervening edits; see the anchor lifecycle table in the mutation docs).\n */\n exists(anchorId: string): boolean {\n return this.wasm.Exists(this.handle, anchorId);\n }\n\n /**\n * Find the first block-level anchor (in document order) whose flat text\n * contains `needle`, or `null` when nothing matches. `options` tune case /\n * whitespace handling and narrow the search by kind or scope. For all\n * matches use {@link findAllByText}.\n */\n findByText(needle: string, options?: FindOptions): AnchorTargetRef | null {\n return JSON.parse(\n this.wasm.FindByText(this.handle, needle, options ? JSON.stringify(options) : \"\"),\n ) as AnchorTargetRef | null;\n }\n\n /**\n * Like {@link findByText} but returns every matching anchor in document\n * order (empty when nothing matches).\n */\n findAllByText(needle: string, options?: FindOptions): AnchorTargetRef[] {\n return JSON.parse(\n this.wasm.FindAllByText(this.handle, needle, options ? JSON.stringify(options) : \"\"),\n ) as AnchorTargetRef[];\n }\n\n /**\n * Find every block-level anchor whose flat text matches the regular\n * expression `pattern`, in document order. `regexOptions` uses the numeric\n * layout of .NET `RegexOptions` (e.g. `1` = IgnoreCase); `options` is the\n * same shape as {@link findByText} (its `ignoreCase` composes with the regex\n * flag). Defaults to `regexOptions = 0` (none).\n */\n findByRegex(pattern: string, regexOptions?: number, options?: FindOptions): AnchorTargetRef[] {\n return JSON.parse(\n this.wasm.FindByRegex(\n this.handle, pattern, regexOptions ?? null, options ? JSON.stringify(options) : \"\"),\n ) as AnchorTargetRef[];\n }\n\n /**\n * Return every anchor of the given `kind` \u2014 one of `\"p\"`, `\"h\"`, `\"li\"`,\n * `\"tbl\"`, `\"tr\"`, `\"tc\"`, `\"col\"`, `\"sdt\"`, `\"sec\"`, `\"fn\"`, `\"en\"`,\n * `\"cmt\"`, `\"unk\"` \u2014 in document order. Matching is an exact string comparison;\n * in particular the row and cell tokens are `\"tr\"` and `\"tc\"`, never\n * `\"row\"`/`\"cell\"`. Unknown strings are not parsed or rejected: they simply\n * return an empty array. `\"img\"` and `\"drw\"` likewise return empty because the\n * projection never assigns those reserved kinds; address images through the\n * image surface instead. Reads the projection's anchor\n * index directly \u2014 no text scan. Pass `scope` (e.g. `\"body\"`) to restrict to\n * a single part; omit it to span all scopes.\n */\n findByKind(kind: string, scope?: string, citation?: PageCitationRequest): AnchorTargetRef[] {\n const json = citation\n ? this.wasm.FindByKindWithCitations(\n this.handle, kind, scope ?? \"\", JSON.stringify(citation),\n )\n : this.wasm.FindByKind(this.handle, kind, scope ?? \"\");\n return JSON.parse(json) as AnchorTargetRef[];\n }\n\n /**\n * Look up a single anchor's preview info \u2014 `{ id, kind, scope, textPreview }`.\n * Returns null when the anchor id is unknown.\n *\n * For iterating many anchors at once, prefer reading `textPreview` directly\n * off the {@link MarkdownProjection.anchorIndex} entries (cheaper \u2014 no extra\n * WASM round trip), or use {@link getAnchorInfos} for batched lookups.\n */\n getAnchorInfo(anchorId: string): AnchorInfo | null {\n const raw = this.wasm.GetAnchorInfo(this.handle, anchorId);\n return JSON.parse(raw) as AnchorInfo | null;\n }\n\n /**\n * Bulk variant of {@link getAnchorInfo}: takes an array of anchor ids,\n * returns a record where each unknown id maps to `null`.\n */\n getAnchorInfos(anchorIds: readonly string[]): Record<string, AnchorInfo | null> {\n const raw = this.wasm.GetAnchorInfos(this.handle, JSON.stringify(anchorIds));\n return JSON.parse(raw) as Record<string, AnchorInfo | null>;\n }\n\n /**\n * Resolve block-level metadata (style id+name, outline level, list membership,\n * formatting probe) for an anchor. Returns null when the anchor doesn't exist.\n */\n getBlockMetadata(anchorId: string): BlockMetadata | null {\n const raw = this.wasm.GetBlockMetadata(this.handle, anchorId);\n return JSON.parse(raw) as BlockMetadata | null;\n }\n\n /**\n * Bulk variant of {@link getBlockMetadata}. Unknown ids map to null;\n * duplicates are deduped.\n */\n getBlockMetadatas(anchorIds: readonly string[]): Record<string, BlockMetadata | null> {\n const raw = this.wasm.GetBlockMetadatas(this.handle, JSON.stringify(anchorIds));\n return JSON.parse(raw) as Record<string, BlockMetadata | null>;\n }\n\n /**\n * Resolve the numbering facts for a list-item paragraph; returns null when\n * the anchor has no w:numPr.\n */\n getListMembership(anchorId: string): ListMembership | null {\n const raw = this.wasm.GetListMembership(this.handle, anchorId);\n return JSON.parse(raw) as ListMembership | null;\n }\n\n /**\n * Resolve page-layout info for the w:sectPr that governs an anchor.\n * Returns null for anchors outside the body part.\n */\n getSectionInfo(anchorId: string): SectionInfo | null {\n const raw = this.wasm.GetSectionInfo(this.handle, anchorId);\n return JSON.parse(raw) as SectionInfo | null;\n }\n\n /** Enumerate the document's explicit style catalog with resolved high-signal properties. */\n listStyles(): StyleInfo[] {\n return JSON.parse(this.wasm.ListStyles(this.handle)) as StyleInfo[];\n }\n\n /** Inspect direct and effective paragraph/run formatting for one paragraph anchor. */\n getFormatting(anchorId: string): FormattingInspection | null {\n return JSON.parse(this.wasm.GetFormatting(this.handle, anchorId)) as FormattingInspection | null;\n }\n\n /** Enumerate text-bearing runs as mutation-compatible anchor/span pairs. */\n listInlineSpans(anchorId: string): InlineSpan[] {\n return JSON.parse(this.wasm.ListInlineSpans(this.handle, anchorId)) as InlineSpan[];\n }\n\n /**\n * Enumerates every annotation persisted in the document. Lets an agent prime\n * itself with \"here are the labeled regions you can target\" before committing\n * to a specific id.\n */\n listAnnotations(): DocumentAnnotation[] {\n return JSON.parse(this.wasm.ListAnnotations(this.handle)) as DocumentAnnotation[];\n }\n\n // \u2500\u2500\u2500 Annotation write surface \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Annotate a range inside `anchorId`. When `span` is `null`/`undefined`\n * the annotation wraps every inline run of the block. When\n * `annotation.id` is `undefined`, a 16-char hex id is auto-generated and\n * returned in `EditResult.annotationId`.\n */\n addAnnotation(\n anchorId: string,\n span: CharSpan | null,\n annotation: DocumentAnnotation,\n ): EditResult {\n const spanJson = span ? JSON.stringify(span) : \"\";\n return JSON.parse(\n this.wasm.AddAnnotation(this.handle, anchorId, spanJson, JSON.stringify(annotation)),\n ) as EditResult;\n }\n\n removeAnnotation(annotationId: string): EditResult {\n return JSON.parse(this.wasm.SessionRemoveAnnotation(this.handle, annotationId)) as EditResult;\n }\n\n updateAnnotation(annotationId: string, update: AnnotationUpdate): EditResult {\n return JSON.parse(\n this.wasm.UpdateAnnotation(this.handle, annotationId, JSON.stringify(update)),\n ) as EditResult;\n }\n\n moveAnnotation(\n annotationId: string,\n newAnchorId: string,\n newSpan: CharSpan | null,\n ): EditResult {\n const spanJson = newSpan ? JSON.stringify(newSpan) : \"\";\n return JSON.parse(\n this.wasm.MoveAnnotation(this.handle, annotationId, newAnchorId, spanJson),\n ) as EditResult;\n }\n\n // \u2500\u2500\u2500 Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Switch how subsequent mutations are recorded (issue #304). Session configuration,\n * not a document mutation: not undoable, and already-applied markup is never touched.\n */\n setTrackedChanges(mode: TrackedChangeMode): void {\n this.wasm.SetTrackedChanges(this.handle, mode);\n }\n\n /** Author stamped on subsequent tracked-change markup; `null` restores the \"docxodus\" default. */\n setRevisionAuthor(author: string | null): void {\n this.wasm.SetRevisionAuthor(this.handle, author ?? \"\");\n }\n\n undo(): boolean {\n return this.wasm.Undo(this.handle);\n }\n\n redo(): boolean {\n return this.wasm.Redo(this.handle);\n }\n\n save(): Uint8Array {\n return this.wasm.Save(this.handle);\n }\n\n close(): void {\n this.retainedPreviewReceipts.clear();\n this.wasm.CloseSession(this.handle);\n }\n\n // TypeScript 5.2+ disposable protocol\n [Symbol.dispose]?(): void {\n this.close();\n }\n}\n\nfunction imageBytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let offset = 0; offset < bytes.length; offset += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + 0x8000));\n }\n return globalThis.btoa(binary);\n}\n\n/**\n * Opens a new {@link DocxSession} over the supplied DOCX bytes.\n * The returned session holds its document in WASM memory until you call\n * {@link DocxSession.close} (or it is disposed).\n */\nexport function openDocxSession(\n bytes: Uint8Array,\n wasmExports: DocxodusWasmExports,\n settings?: DocxSessionSettings,\n): DocxSession {\n const bridge = wasmExports.DocxSessionBridge;\n const handle = bridge.OpenSession(bytes, settings ? JSON.stringify(settings) : \"\");\n return new DocxSession(handle, bridge);\n}\n\nexport type { AnchorInfo, AnchorRef, AnchorTargetRef, BlockSlice, CharSpan, CommentListEntry, CrossBlockMatch, CrossReferenceOptions, DocumentAnnotation, DocxSessionProjection, DocxSessionSettings, EditError, EditErrorCode, EditResult, FindOptions, FormatOp, FormattingInspection, GrepOptions, InlineSpan, MarkdownPatch, MarkdownPatchBlock, MutationBatchChangeSet, MutationBatchFailure, MutationBatchMode, MutationBatchPreviewOptions, MutationBatchPreviewStep, MutationBatchResult, MutationBatchStep, MutationBatchStepResult, MutationPreconditions, PageCitation, PageCitationRequest, PageMapRegistrationResult, PageMapStatus, ParagraphFormatting, PlaceholderKind, PreconditionFailure, PreconditionTarget, ReplaceOptions, RunFormatting, RunFormattingInfo, RunFragment, StyleInfo, TableStyleFormatting, TemplatePlaceholder, TextMatch, TextRangePrecondition } from \"./types.js\";\nexport { ContextBoundary, PlaceholderKinds } from \"./types.js\";\n", "import type {\n DeliverableVerificationRequest,\n DeliverableCompanionArtifactInput,\n} from \"./types.js\";\n\n/**\n * Serialize the full deliverable-verification request (issue #747) to the wire shape every\n * transport parses: companion bytes become `bytesB64`, everything else passes through. Kept\n * separate from the API modules so the direct API, the session, and the worker proxy share\n * one encoding.\n */\nexport function serializeVerificationRequest(request: DeliverableVerificationRequest): string {\n if (request === null || typeof request !== \"object\" || Array.isArray(request)) {\n throw new RangeError(\"a verification request must be an object\");\n }\n const { companionArtifacts, ...rest } = request;\n const wire: Record<string, unknown> = { ...rest };\n if (companionArtifacts !== undefined) {\n wire.companionArtifacts = companionArtifacts.map(encodeCompanion);\n }\n return JSON.stringify(wire);\n}\n\nfunction encodeCompanion(artifact: DeliverableCompanionArtifactInput): Record<string, unknown> {\n const { bytes, ...rest } = artifact;\n const wire: Record<string, unknown> = { ...rest };\n if (bytes !== undefined) wire.bytesB64 = bytesToBase64(bytes);\n return wire;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof btoa === \"function\") {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n binary += String.fromCharCode.apply(null, chunk as unknown as number[]);\n }\n return btoa(binary);\n }\n return Buffer.from(bytes).toString(\"base64\");\n}\n", "/**\n * Which parts of the OOXML package to include in the markdown projection.\n * Bitflags mirroring the .NET `Docxodus.ProjectionScopes` enum.\n */\nexport enum ProjectionScopes {\n Body = 1,\n Headers = 2,\n Footers = 4,\n Footnotes = 8,\n Endnotes = 16,\n Comments = 32,\n All = 63,\n}\n\n/**\n * How anchor markers are rendered in the markdown projection.\n * Mirrors the .NET `Docxodus.AnchorRenderMode` enum.\n */\nexport enum AnchorRenderMode {\n /** Anchor appears on its own line before each block element (default). */\n Block = 0,\n /** Block anchors plus inline `{#\u2026}` markers for spans (comments, hyperlinks). */\n BlockAndInline = 1,\n /** No anchor markers in the output (projection only, no addressing). */\n None = 2,\n}\n\n/**\n * Strategy for rendering `w:tbl` elements that don't fit GFM pipe-table constraints.\n * Mirrors the .NET `Docxodus.TableRenderMode` enum.\n */\nexport enum TableRenderMode {\n /** Emit GFM pipe tables when possible, opaque anchor blocks otherwise (default). */\n GfmWithOpaqueFallback = 0,\n /** Always emit GFM pipe tables, flattening complex structure with possible loss. */\n AlwaysGfm = 1,\n /** Always emit opaque anchor blocks. */\n AlwaysOpaque = 2,\n}\n\n/**\n * How tracked changes are handled in the markdown projection.\n * Mirrors the .NET `Docxodus.TrackedChangeMode` enum.\n */\nexport enum TrackedChangeMode {\n /** Accept all revisions before conversion (default). */\n Accept = 0,\n /** Render insertions and deletions inline as `{+ins+}` / `{-del-}`. */\n RenderInline = 1,\n /** Accept insertions, drop deletions. */\n StripDeletions = 2,\n}\n\n/**\n * How empty paragraphs are rendered. Mirrors the .NET `Docxodus.EmptyParagraphMode` enum.\n */\nexport enum EmptyParagraphMode {\n /** Default: emit the anchor on its own line (`{#p:body:UNID}\\n`). */\n AnchorOnly = 0,\n /** Tag the empty paragraph visibly so agents can pattern-match (`{#p:body:UNID} \u2205`). */\n MarkedEmpty = 1,\n /** Skip empty paragraphs entirely \u2014 they don't appear in the markdown or the anchor index. */\n Suppress = 2,\n}\n\n/**\n * How anchor ids are rendered inside `{#\u2026}` tokens (and keyed in\n * {@link MarkdownProjection.anchorIndex}). Mirrors the .NET\n * `Docxodus.AnchorIdRendering` enum.\n *\n * `Anchor.token` (and any `AnchorRef` returned by `DocxSession` mutations)\n * always carries the full Unid regardless of rendering \u2014 the choice only\n * affects the markdown text. The returned `anchorIndex` is dual-keyed so\n * lookups by either the rendered id or the full Unid work for the\n * `Abbreviated`/`Sequential` modes.\n */\nexport enum AnchorIdRendering {\n /** Full 32-char hex Unid (default; e.g. `{#h:body:a1b2c3d4e5f6789012345678901234ab}`). */\n FullUnid = 0,\n /** Shortest unique prefix per (kind, scope) bucket, 4-char floor (e.g. `{#h:body:a1b2}`).\n * Saves 5-10% of projection-token budget for LLM consumption. */\n Abbreviated = 1,\n /** Sequential numeric ids per (kind, scope) bucket in document order (e.g. `{#h:body:1}`).\n * Maximally token-efficient for one-shot LLM contexts. NOT stable across\n * `project()` calls and must NOT be persisted. */\n Sequential = 2,\n}\n\n/**\n * How far below the target anchor to include in\n * {@link DocxSession.projectAnchor}. Mirrors the .NET\n * `Docxodus.ProjectionDepth` enum.\n */\nexport enum ProjectionDepth {\n /** Just the target block itself (its anchor + its own text). For headings,\n * returns only the heading paragraph, not the section under it. */\n SelfOnly = 0,\n /** Self + descendants. Most useful for `tbl` anchors (returns the whole table);\n * for paragraphs it's the same as `SelfOnly`. */\n Subtree = 1,\n /** Self + descendants + following siblings up to (but not including) the next\n * sibling at the same or higher heading level. For non-heading anchors,\n * equivalent to `Subtree`. Dominant \"give me this section\" case; the default. */\n SubtreeAndFollowingSiblings = 2,\n}\n\n/**\n * Settings controlling the markdown projection. Mirrors the .NET\n * `WmlToMarkdownConverterSettings` class \u2014 see `docs/architecture/markdown_projection.md`.\n */\nexport interface MarkdownProjectionSettings {\n scopes?: ProjectionScopes;\n headingLevelOffset?: number;\n anchorMode?: AnchorRenderMode;\n tableMode?: TableRenderMode;\n tableInlineCellMax?: number;\n trackedChanges?: TrackedChangeMode;\n resolveNumbering?: boolean;\n emptyParagraphs?: EmptyParagraphMode;\n /**\n * How anchor ids are rendered in markdown output. Default `FullUnid`.\n * Set to `Abbreviated` for terse LLM-friendly ids; `Sequential` for\n * 1-based per-scope counters (best for replay logs / human review).\n * `Anchor.token` (and any `AnchorRef`) always reflects the full Unid\n * regardless; this only affects the markdown text. Use the returned\n * {@link MarkdownProjection.anchorIndex} (dual-keyed for Abbreviated /\n * Sequential) to translate rendered ids back to full Unids.\n */\n anchorIdRendering?: AnchorIdRendering;\n}\n\n/**\n * Resolved location of an anchor in the underlying OOXML package \u2014 sufficient to walk\n * back to the source element via the .NET API.\n */\nexport interface MarkdownAnchorTarget {\n id: string;\n kind: string;\n scope: string;\n unid: string;\n partUri: string;\n /** First ~80 characters of the element's flat text \u2014 for previewing/picking anchors. */\n textPreview: string;\n /** Resolved auto-numbering prefix (e.g. \"1.\", \"First\") for paragraphs/headings/list\n * items whose style or `w:numPr` produces numbering. Absent when the element has\n * no numbering. The prefix is NOT included in {@link textPreview} because\n * textPreview reflects only the run text; this field gives callers the value\n * Word actually renders before the element's text. */\n autoNumberPrefix?: string;\n}\n\n/**\n * Output of the markdown projection: rendered text plus the anchor index mapping\n * each `{#\u2026}` token back to a location in the OOXML package.\n */\nexport interface MarkdownProjection {\n markdown: string;\n anchorIndex: Record<string, MarkdownAnchorTarget>;\n}\n\n/**\n * Revision type enum matching the .NET `DocxDiffRevisionType`, as returned by the `docxDiff*`\n * comparison APIs. NOT the shape {@link getRevisions} returns \u2014 that reads a document's own markup\n * and reports the markup-level kind on `RevisionListEntry.type` (`ins`/`del`/`moveFrom`), with the\n * grouped classification on `family`.\n */\nexport enum RevisionType {\n /** Text or content that was added/inserted */\n Inserted = \"Inserted\",\n /** Text or content that was removed/deleted */\n Deleted = \"Deleted\",\n /** Text or content that was relocated within the document */\n Moved = \"Moved\",\n /** Text content unchanged but formatting (bold, italic, etc.) changed */\n FormatChanged = \"FormatChanged\",\n}\n\n\n/**\n * Comment render mode\n * Use -1 (Disabled) to not render comments, or a positive value to enable with that mode\n */\nexport enum CommentRenderMode {\n /** Do not render comments (default) */\n Disabled = -1,\n /** Render comments at the end of the document with bidirectional links (like footnotes) */\n EndnoteStyle = 0,\n /** Render comments as inline tooltips with data attributes */\n Inline = 1,\n /** Render comments in a margin column (CSS-positioned) */\n Margin = 2,\n}\n\n/**\n * Pagination mode for HTML output\n */\nexport enum PaginationMode {\n /** No pagination - content flows continuously (default) */\n None = 0,\n /**\n * Paginated view - outputs page containers with document dimensions\n * and content with data attributes for client-side pagination.\n * Creates a PDF.js-style page preview experience.\n */\n Paginated = 1,\n}\n\n/**\n * How rendered tracked changes look (issue #851). Only used when `renderTrackedChanges` is on.\n */\nexport enum RevisionPresentation {\n /** Docxodus's own review style (default): green/red text with light fills, purple moves, pilcrows. */\n Docxodus = 0,\n /**\n * Close to Word's All Markup print: one colour per author for both insertions (underlined) and\n * deletions (struck through), no fills or pilcrows, green double-lined moves, Word's default cell\n * shading, and one left-margin change bar per changed paragraph. Full renders only.\n */\n Word = 1,\n}\n\n/**\n * Annotation label display mode\n */\nexport enum AnnotationLabelMode {\n /** Floating label positioned above the highlight */\n Above = 0,\n /** Label displayed inline at start of highlight */\n Inline = 1,\n /** Label shown only on hover (tooltip) */\n Tooltip = 2,\n /** No labels displayed, only highlights */\n None = 3,\n}\n\n/**\n * Types of content that cannot be fully converted to HTML.\n * Used for placeholder rendering when unsupported content is encountered.\n */\nexport enum UnsupportedContentType {\n /** Windows Metafile image format (legacy vector graphics) */\n WmfImage = \"WmfImage\",\n /** Enhanced Metafile image format (legacy vector graphics) */\n EmfImage = \"EmfImage\",\n /** SVG image format (not yet supported) */\n SvgImage = \"SvgImage\",\n /** Office Math Markup Language equations */\n MathEquation = \"MathEquation\",\n /** Form field elements (checkboxes, text inputs, dropdowns) */\n FormField = \"FormField\",\n /** Ruby annotations for East Asian text */\n RubyAnnotation = \"RubyAnnotation\",\n /** Embedded OLE objects */\n OleObject = \"OleObject\",\n /** Other unsupported content */\n Other = \"Other\",\n}\n\n/**\n * Options for DOCX to HTML conversion\n */\nexport interface ConversionOptions {\n /** Title for the HTML document (default: \"Document\") */\n pageTitle?: string;\n /** CSS class prefix for generated styles (default: \"docx-\") */\n cssPrefix?: string;\n /** Whether to generate CSS classes (default: true) */\n fabricateClasses?: boolean;\n /** Additional CSS to include in the output */\n additionalCss?: string;\n /** Comment rendering mode: Disabled (-1), EndnoteStyle (0), Inline (1), or Margin (2). Default: Disabled */\n commentRenderMode?: CommentRenderMode;\n /** CSS class prefix for comment elements (default: \"comment-\") */\n commentCssClassPrefix?: string;\n /** Pagination mode: None (0) or Paginated (1). Default: None */\n paginationMode?: PaginationMode;\n /** Scale factor for page rendering in paginated mode (1.0 = 100%). Default: 1.0 */\n paginationScale?: number;\n /** CSS class prefix for pagination elements. Default: \"page-\" */\n paginationCssClassPrefix?: string;\n /** Whether to render custom annotations (default: false) */\n renderAnnotations?: boolean;\n /** How to display annotation labels (default: Above) */\n annotationLabelMode?: AnnotationLabelMode;\n /** CSS class prefix for annotation elements (default: \"annot-\") */\n annotationCssClassPrefix?: string;\n /** Whether to render footnotes and endnotes sections at the end of the document (default: false) */\n renderFootnotesAndEndnotes?: boolean;\n /** Whether to render document headers and footers (default: false) */\n renderHeadersAndFooters?: boolean;\n /** Whether to render tracked changes visually (insertions/deletions) (default: false) */\n renderTrackedChanges?: boolean;\n /** Whether to show deleted content with strikethrough (only when renderTrackedChanges=true, default: true) */\n showDeletedContent?: boolean;\n /** Whether to distinguish move operations from regular insert/delete (only when renderTrackedChanges=true, default: true) */\n renderMoveOperations?: boolean;\n /** How tracked changes look (only when renderTrackedChanges=true, default: RevisionPresentation.Docxodus) */\n revisionPresentation?: RevisionPresentation;\n /**\n * Whether to render placeholders for unsupported content (default: false)\n * When enabled, unsupported content (WMF/EMF images, math equations, form fields, etc.)\n * will display as styled placeholder spans instead of being silently dropped.\n */\n renderUnsupportedContentPlaceholders?: boolean;\n /**\n * Override the document's default language for the HTML lang attribute.\n * If not specified, the language is auto-detected from document settings\n * (w:themeFontLang or default paragraph style), falling back to \"en-US\".\n * Examples: \"en-US\", \"fr-FR\", \"de-DE\", \"ja-JP\"\n */\n documentLanguage?: string;\n /**\n * Stamp block-level elements (p, h1-h6, li, table) with a `data-anchor`\n * attribute carrying the block's stable Unid. Required for the editor to\n * address blocks in the DOM and drive incremental per-block re-render via\n * `renderBlockHtml`. Default: false.\n */\n stampAnchors?: boolean;\n /**\n * Emit Word lists as `<ol>`/`<ul>`/`<li>` instead of paragraphs (issue #895). Adjacent list\n * paragraphs of one list share a list, and a deeper level nests inside the preceding item. CSS\n * draws the marker (`list-style-type`, with `start`/`value` for restarts) only where it\n * reproduces Word's marker exactly; other lists keep the generated marker spans under\n * `list-style-type: none`. Ignored by paginated output. Default: false.\n */\n semanticLists?: boolean;\n}\n\n/**\n * Options for document comparison\n */\nexport interface CompareOptions {\n /** Author name for tracked changes (default: the engine's, \"Docxodus\") */\n authorName?: string;\n /** Whether comparison is case-insensitive (default: false) */\n caseInsensitive?: boolean;\n /**\n * Whether to render tracked changes visually in HTML output (default: true)\n * If true: insertions shown with <ins>, deletions with <del>, styled with colors\n * If false: changes are accepted, output shows final \"clean\" document\n */\n renderTrackedChanges?: boolean;\n}\n\n\n/**\n * Which property container a FormatChanged revision describes.\n * `run` (the default) is an rPr-grade report (bold/italic/fontSize/\u2026); the others are the\n * block-and-above scopes tracked by the block-format-change family: `paragraph` (pPr),\n * `tableCell`/`tableRow`/`table` (tcPr/trPr/tblPr+tblGrid), and `section` (sectPr).\n * Non-`run` scopes are only reported under Fine revision granularity.\n */\nexport type FormatChangeScope =\n | \"run\"\n | \"paragraph\"\n | \"tableCell\"\n | \"tableRow\"\n | \"table\"\n | \"section\";\n\n/**\n * Details about formatting changes for FormatChanged revisions.\n */\nexport interface FormatChangeDetails {\n /**\n * Dictionary of old property names and values.\n * Keys are friendly property names like \"bold\", \"italic\", \"fontSize\".\n */\n oldProperties?: Record<string, string>;\n /**\n * Dictionary of new property names and values.\n */\n newProperties?: Record<string, string>;\n /**\n * List of property names that changed (e.g., \"bold\", \"italic\", \"fontSize\").\n * For the table/section scopes this is a digest-grade marker (`[\"shell\"]`, `[\"grid\"]`).\n */\n changedPropertyNames?: string[];\n /**\n * Which property container this change describes (default `\"run\"`).\n */\n scope?: FormatChangeScope;\n}\n\n// \u2500\u2500\u2500 DocxDiff (IR diff engine) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// The structure-aware default comparison engine. Its specialized APIs expose\n// anchor-addressed revisions (`leftAnchor`/`rightAnchor`) and the diff-as-data\n// edit script (`docxDiffGetEditScript`).\n\n/**\n * How `docxDiffGetRevisions` projects the edit script to revisions. Integer\n * values match the .NET `DocxDiffRevisionGranularity` enum positions.\n */\nexport enum DocxDiffRevisionGranularity {\n /** The engine's native one-revision-per-token-span grain (the default). */\n Fine = 0,\n /** Coalesced to the coarser contiguous-region grain the legacy comparer reported. */\n WmlComparerCompatible = 1,\n}\n\n/**\n * How DocxDiff compares run formatting. Integer values match the .NET\n * `DocxDiffFormatComparison` enum positions.\n */\nexport enum DocxDiffFormatComparison {\n /** Compare only the modeled rPr fields (the default). */\n ModeledOnly = 0,\n /** Compare the full run format including the unmodeled rPr digest. */\n Full = 1,\n}\n\n/**\n * Settings for the `docxDiff*` functions. Mirrors the .NET `DocxDiffSettings`;\n * every field is optional and an omitted field uses the engine default.\n */\nexport interface DocxDiffSettings {\n /** Author stamped on revisions and markup (default \"Docxodus\"). */\n authorForRevisions?: string;\n /** Pin revision dates to a fixed epoch for byte-identical output (default true). */\n deterministic?: boolean;\n /** Explicit ISO-8601 revision date; overrides `deterministic` when set. */\n dateTimeForRevisions?: string;\n /**\n * Accept every pre-existing revision on both inputs before comparing (default false).\n * This flattens prior authorship; `preserveInputRevisions` takes precedence when both are set.\n * The consolidate functions (`docxDiffConsolidate` and its siblings) always pre-accept the base\n * and every reviewer, whatever this says: they compare the accepted view, as Word's Compare does.\n */\n preAcceptInputRevisions?: boolean;\n /**\n * Preserve the inputs' existing tracked revisions, as Word's Combine does (default false).\n * Word's Compare pre-accepts them instead (see `preAcceptInputRevisions`).\n * This takes precedence over `preAcceptInputRevisions` when both are set.\n */\n preserveInputRevisions?: boolean;\n /** Case-fold word match keys (default false). */\n caseInsensitive?: boolean;\n /** Culture name (e.g. \"tr-TR\") for case folding when `caseInsensitive` is true; default invariant/ordinal. */\n culture?: string;\n /** Fold NBSP (U+00A0) to ordinary space in match keys (default true). */\n conflateBreakingAndNonbreakingSpaces?: boolean;\n /** Override the word/separator split characters (default: engine's set). */\n wordSeparators?: string;\n /** Report relocations as native move pairs (default true). */\n detectMoves?: boolean;\n /** Jaccard similarity threshold for a fuzzy move 0.0-1.0 (default 0.8). */\n moveSimilarityThreshold?: number;\n /** Minimum word tokens for a fuzzy move (default 3). */\n moveMinimumWordCount?: number;\n /** Revision projection grain (default Fine). */\n revisionGranularity?: DocxDiffRevisionGranularity;\n /** Run-format comparison policy (default ModeledOnly). */\n formatComparison?: DocxDiffFormatComparison;\n /**\n * Compare header/footer stories (default true \u2014 Word Compare's own default).\n * Changed stories get native tracked-changes markup inside their parts;\n * Fine-mode revisions carry `hdr`/`ftr`-scoped anchors; the edit script\n * carries `headerFooterOps`. Set false to ignore header/footer scopes (the\n * pre-campaign behavior: left's headers/footers carried verbatim).\n */\n compareHeadersFooters?: boolean;\n\n /**\n * Track paragraph-and-above property changes (pPr/tcPr/trPr/tblPr/tblGrid/tblPrEx/sectPr) as native\n * Word markup. Default true. Set false to restore the pre-campaign untracked-right-apply behavior.\n * (Consolidate ignores block-format changes regardless.)\n */\n trackBlockFormatChanges?: boolean;\n\n /**\n * Render a run of >=2 adjacent word-matched modified paragraph pairs via a single cross-paragraph\n * word+pilcrow token-stream diff \u2014 the within-run flat-stream shape decoded from Word's compare\n * output (retained words may cross the pilcrow; paragraph marks are ins/del stream tokens; the\n * output paragraph count follows the token-level interleave). Markup (`docxDiffCompare`) only \u2014\n * the revision list and edit-script JSON are unaffected. Default false.\n */\n crossParagraphTokenDiff?: boolean;\n\n /**\n * Record a list item's previous label in `w:numberingChange` when an insertion, deletion or move\n * elsewhere in its list renumbered it. Word's own compare never writes this; set false for output\n * limited to the constructs Word writes. Default true. Consolidate honors it too.\n */\n trackNumberingChanges?: boolean;\n\n /**\n * Track a cell added to or removed from a paired table row with `w:cellIns`/`w:cellDel`. Word's own\n * compare never writes cell-level revisions; set false and such a table is tracked as a whole (the\n * original deleted, the revised inserted), in the markup and the revision list alike. Default true.\n * Consolidate keeps cell-level revisions regardless.\n */\n trackCellInsertionsAndDeletions?: boolean;\n}\n\n/**\n * One revision from `docxDiffGetRevisions`. Mirrors the consumer shape of\n * {@link Revision} and ADDS the block anchors the revision derives from \u2014 the\n * IR engine's differentiator.\n *\n * Anchor presence by `revisionType` \u2014 each type's PRIMARY anchor is ALWAYS\n * present; the opposite anchor MAY also be present for a token-level revision.\n * Inserted \u2192 `rightAnchor` always (plus `leftAnchor` when it is a token-level\n * insert inside a modified block); Deleted \u2192 `leftAnchor` always (plus\n * `rightAnchor` when token-level); FormatChanged \u2192 both; Moved is EXCLUSIVE:\n * source \u2192 `leftAnchor` only, destination \u2192 `rightAnchor` only. A token-level\n * revision (an insert/delete WITHIN a modified paragraph that exists on both\n * sides) carries both enclosing-block anchors; a whole-block insert/delete\n * carries only its primary anchor.\n */\nexport interface DocxDiffRevision {\n /** \"Inserted\" | \"Deleted\" | \"Moved\" | \"FormatChanged\". */\n revisionType: RevisionType | string;\n /** The affected text. */\n text: string;\n /** Author stamped on the revision. */\n author: string;\n /** ISO-8601 revision date. */\n date: string;\n /** For Moved revisions, links source and destination. */\n moveGroupId?: number;\n /** For Moved revisions: true = source, false = destination. */\n isMoveSource?: boolean;\n /** For FormatChanged revisions: what formatting changed. */\n formatChange?: FormatChangeDetails;\n /** The LEFT-document block anchor (`kind:scope:unid`). Always set for Deleted/FormatChanged/Moved-source;\n * also set for a token-level insert inside a modified block; undefined for a whole-block insertion. */\n leftAnchor?: string;\n /** The RIGHT-document block anchor (`kind:scope:unid`). Always set for Inserted/FormatChanged/Moved-dest;\n * also set for a token-level delete inside a modified block; undefined for a whole-block deletion. */\n rightAnchor?: string;\n}\n\n/** A data product selectable in `docxDiffCompareProducts`. */\nexport type DocxDiffProduct = \"redline\" | \"revisions\" | \"editScript\" | \"semanticChanges\";\n\n/**\n * The requested products of ONE memoized comparison pass, from\n * `docxDiffCompareProducts` (issue #594). Unrequested products are undefined.\n * Each present product equals what the corresponding standalone function\n * returns for the same inputs and settings \u2014 except `editScript`, which is\n * handed over parsed (the standalone `docxDiffGetEditScript` returns the\n * serialized string).\n */\nexport interface DocxDiffProducts {\n /** The native tracked-changes redline (what `docxDiffCompare` returns). */\n redline?: Uint8Array;\n /** The anchor-addressed revision list (what `docxDiffGetRevisions` returns). */\n revisions?: DocxDiffRevision[];\n /** The engine's edit script, parsed. */\n editScript?: Record<string, unknown>;\n /** The stable semantic-change schema (what `docxDiffGetSemanticChanges` returns). */\n semanticChanges?: SemanticChangeSet;\n}\n\n/** One candidate of a {@link docxDiffCompareBatch} run: the products of comparing the shared\n * baseline against it, or the error that comparing it produced. */\nexport interface DocxDiffBatchResult extends DocxDiffProducts {\n /** The candidate's name, echoed from the request (its index when none was given). */\n name: string;\n /** Set when this candidate failed; its products are then absent. The rest of the batch is\n * unaffected \u2014 one malformed counterparty markup must not cost the other ninety-nine. */\n error?: string;\n}\n\n/** A candidate document for {@link docxDiffCompareBatch}. */\nexport interface DocxDiffBatchCandidate {\n /** Echoed back on the matching result. Defaults to the candidate's index. */\n name?: string;\n /** The candidate document. */\n document: File | Uint8Array;\n}\n\n/** Stable v1 operation names emitted by the semantic-change schema. */\nexport type SemanticChangeOperation = \"insert\" | \"delete\" | \"move\" | \"modify\";\n\n/** Stable v1 semantic families. New schema versions may append families. */\nexport type SemanticChangeFamily =\n | \"text\"\n | \"block_structure\"\n | \"run_formatting\"\n | \"paragraph_formatting\"\n | \"style\"\n | \"numbering\"\n | \"list\"\n | \"table\"\n | \"table_row\"\n | \"table_cell\"\n | \"table_span\"\n | \"table_width\"\n | \"table_style\"\n | \"section\"\n | \"page_setup\"\n | \"header\"\n | \"footer\"\n | \"field\"\n | \"footnote\"\n | \"endnote\"\n | \"comment\"\n | \"hyperlink\"\n | \"bookmark\"\n | \"content_control\"\n | \"image\"\n | \"media\"\n | \"relationship\"\n | \"revision\"\n | \"annotation\"\n | \"opaque_package_part\";\n\n/**\n * Closed typed value used in {@link SemanticChange.before} and `after`.\n * Schema v1 integers stay within `Number.MIN_SAFE_INTEGER..Number.MAX_SAFE_INTEGER`; a document\n * value outside that range arrives as a decimal `string` rather than a rounded `integer`.\n */\nexport type SemanticValue =\n | { kind: \"absent\" }\n | { kind: \"string\"; value: string }\n | { kind: \"boolean\"; value: boolean }\n | { kind: \"integer\"; value: number }\n | { kind: \"digest\"; algorithm: string; profile: string | null; value: string }\n | { kind: \"object\"; value: Record<string, SemanticValue> }\n | { kind: \"array\"; value: SemanticValue[] };\n\n/** One deterministic, anchor-addressed semantic change. */\nexport interface SemanticChange {\n id: string;\n operation: SemanticChangeOperation;\n family: SemanticChangeFamily;\n partUri: string;\n path: string;\n leftAnchor: string | null;\n rightAnchor: string | null;\n leftScope: string | null;\n rightScope: string | null;\n moveId: string | null;\n before: SemanticValue;\n after: SemanticValue;\n}\n\n/** Public `docxodus.semantic-changes` schema returned by semantic comparison APIs. */\nexport interface SemanticChangeSet {\n schema: \"docxodus.semantic-changes\";\n schemaVersion: 1;\n changeCount: number;\n changes: SemanticChange[];\n}\n\n// \u2500\u2500\u2500 DocxDiff consolidate (composite N-way) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// The composite layer over the IR diff engine: merge several reviewers' edits\n// against one shared base DOCX. Mirrors the .NET consolidate surface\n// (`DocxDiff.Consolidate` / `GetConflicts` / `GetConsolidatedRevisions` /\n// `GetConsolidatedEditScriptJson`) \u2014 see `docs/architecture/ir_diff_engine.md`.\n\n/**\n * How overlapping reviewer edits at the same base token span are resolved.\n * Integer values match the .NET `ConflictResolution` enum positions.\n */\nexport enum ConflictResolution {\n /** Keep the base text where reviewers disagree (the default). */\n BaseWins = 0,\n /** The first reviewer (by input order) wins each contested span. */\n FirstReviewerWins = 1,\n /** Stack every reviewer's variant so a human can pick. */\n StackAll = 2,\n}\n\n/** One reviewer's edited copy of the shared base document, plus their name. */\nexport interface DocxDiffReviewer {\n /** The reviewer's edited DOCX bytes. */\n document: Uint8Array;\n /** Author name stamped on this reviewer's revisions in the consolidated output. */\n author: string;\n}\n\n/**\n * Settings for the `docxDiffConsolidate*` functions. Extends {@link DocxDiffSettings}\n * with the conflict-resolution policy; mirrors the .NET `DocxDiffConsolidateSettings`.\n */\nexport interface DocxDiffConsolidateSettings extends DocxDiffSettings {\n /** Policy for overlapping reviewer edits (default {@link ConflictResolution.BaseWins}). */\n conflictResolution?: ConflictResolution;\n}\n\n/** One reviewer's contested variant at a conflict span. */\nexport interface DocxDiffConflictCompetitor {\n /** The reviewer whose variant this is. */\n author: string;\n /** The text this reviewer would produce for the contested span. */\n resultText: string;\n}\n\n/**\n * A single conflict: two or more reviewers edited the same base token span\n * incompatibly. Returned by {@link docxDiffGetConflicts}.\n */\nexport interface DocxDiffConflict {\n /** Stable id for this conflict within the consolidation. */\n id: number;\n /** The base-document block anchor (`kind:scope:unid`) the conflict sits in. */\n baseAnchor: string;\n /** First contested base token index (inclusive). */\n tokenStart: number;\n /** Last contested base token index (exclusive). */\n tokenEnd: number;\n /** The {@link ConflictResolution} policy that was applied to this conflict. */\n policy: ConflictResolution | number;\n /** The competing reviewer variants. */\n competitors: DocxDiffConflictCompetitor[];\n}\n\n/**\n * One revision from {@link docxDiffGetConsolidatedRevisions}. A\n * {@link DocxDiffRevision} plus the id of the conflict it participates in\n * (when it sits in a contested span).\n */\nexport interface DocxDiffConsolidatedRevision extends DocxDiffRevision {\n /** The {@link DocxDiffConflict.id} this revision belongs to, if any. */\n conflictId?: number;\n}\n\n/**\n * Type guard to check if a revision is an insertion.\n * @param revision - The revision to check\n * @returns true if the revision is an insertion\n *\n * @example\n * ```typescript\n * const revisions = await getRevisions(doc);\n * const insertions = revisions.filter(isInsertion);\n * ```\n */\nexport function isInsertion(revision: RevisionListEntry): boolean {\n return revision.family === \"content_insert\";\n}\n\n/**\n * Type guard to check if a revision is a deletion.\n * @param revision - The revision to check\n * @returns true if the revision is a deletion\n *\n * @example\n * ```typescript\n * const revisions = await getRevisions(doc);\n * const deletions = revisions.filter(isDeletion);\n * ```\n */\nexport function isDeletion(revision: RevisionListEntry): boolean {\n return revision.family === \"content_delete\";\n}\n\n/**\n * Type guard to check if a revision is a move operation.\n * @param revision - The revision to check\n * @returns true if the revision is part of a move\n *\n * @example\n * ```typescript\n * const revisions = await getRevisions(doc);\n * const moves = revisions.filter(isMove);\n * ```\n */\nexport function isMove(revision: RevisionListEntry): boolean {\n return revision.family === \"move\";\n}\n\n/**\n * Type guard to check if a revision is a format change.\n * @param revision - The revision to check\n * @returns true if the revision is a format change\n *\n * @example\n * ```typescript\n * const revisions = await getRevisions(doc);\n * const formatChanges = revisions.filter(isFormatChange);\n * for (const rev of formatChanges) {\n * console.log(`Format changed: ${rev.formatChange?.changedPropertyNames?.join(\", \")}`);\n * }\n * ```\n */\nexport function isFormatChange(revision: RevisionListEntry): boolean {\n return revision.family === \"properties_change\";\n}\n\n\n\n\n/**\n * Version information for the library\n */\nexport interface VersionInfo {\n library: string;\n dotnetVersion: string;\n platform: string;\n}\n\n/**\n * Error response from WASM operations\n */\nexport interface ErrorResponse {\n error: string;\n type?: string;\n /**\n * @deprecated Never populated: the engine stopped putting stack traces on the wire (issue #961).\n */\n stackTrace?: string;\n}\n\n/**\n * Result of a comparison operation\n */\nexport interface CompareResult {\n /** The redlined document as a Uint8Array */\n document: Uint8Array;\n /** List of revisions found */\n revisions: RevisionListEntry[];\n}\n\n/** Algorithm-labelled digest in a verification artifact. */\nexport interface VerificationDigest {\n algorithm: string;\n /** Lower-case hexadecimal digest bytes. */\n value: string;\n}\n\n/** Stable package location attached to a verification finding. */\nexport interface ChangeLocation {\n entryUri: string | null;\n ownerUri: string | null;\n relationshipId: string | null;\n targetUri: string | null;\n propertyPath: string | null;\n}\n\nexport type VerificationFindingSeverity = \"info\" | \"warning\" | \"error\";\n\n/** Machine-readable package validation or safety finding. */\nexport interface VerificationFinding {\n code: string;\n severity: VerificationFindingSeverity;\n message: string;\n location: ChangeLocation | null;\n}\n\n/** One physical ZIP entry. Duplicate names remain separate occurrences. */\nexport interface PackageManifestEntry {\n uri: string;\n occurrence: number;\n contentType: string | null;\n contentTypeSource: \"override\" | \"default\" | \"implicit\" | \"unresolved\";\n /** Exact declared uncompressed byte length as a base-10 integer string. */\n size: string;\n /** Exact compressed ZIP byte length as a base-10 integer string. */\n compressedSize: string;\n rawBytesDigest: VerificationDigest | null;\n normalizedXmlDigest: VerificationDigest | null;\n isXml: boolean;\n /** null when central-directory encryption flags could not be parsed authoritatively. */\n isEncrypted: boolean | null;\n}\n\nexport interface PackageContentTypeDeclaration {\n kind: \"default\" | \"override\";\n key: string;\n contentType: string;\n occurrence: number;\n}\n\nexport interface PackageRelationship {\n ownerUri: string;\n id: string;\n type: string;\n target: string;\n targetMode: \"Internal\" | \"External\";\n resolvedTargetUri: string | null;\n isTargetPresent: boolean | null;\n}\n\nexport interface PackageRevisionCounts {\n insertions: number;\n deletions: number;\n moveFrom: number;\n moveTo: number;\n propertyChanges: number;\n /** The `rPrChange` subset of `propertyChanges`; not added into `total`. */\n runPropertyChanges: number;\n structuralChanges: number;\n otherChanges: number;\n total: number;\n}\n\nexport interface PackageAnnotationCounts {\n comments: number;\n commentReplies: number;\n threadedCommentMetadata: number;\n resolvedComments: number;\n people: number;\n docxodusAnnotations: number;\n}\n\nexport interface PackageManifestFacts {\n mainDocumentUri: string | null;\n isStrictOoxml: boolean;\n isMacroEnabled: boolean;\n hasCoreProperties: boolean;\n hasExtendedProperties: boolean;\n hasCustomProperties: boolean;\n sectionCount: number;\n paragraphCount: number;\n tableCount: number;\n headerPartCount: number;\n footerPartCount: number;\n footnoteCount: number;\n endnoteCount: number;\n styleCount: number;\n numberingDefinitionCount: number;\n themePartCount: number;\n mediaPartCount: number;\n customXmlPartCount: number;\n drawingCount: number;\n altChunkCount: number;\n fieldCount: number;\n revisions: PackageRevisionCounts;\n annotations: PackageAnnotationCounts;\n}\n\n/** Deterministic schema-v1 description of a DOCX/OPC package. */\nexport interface PackageManifest {\n schema: \"https://docxodus.dev/schemas/verification/package-manifest/v1\";\n schemaVersion: 1;\n packageKind: \"opc\" | \"zip\" | \"zip-encrypted\" | \"ole-encrypted\" | \"ole\" | \"malformed\";\n isValid: boolean;\n rawPackageBytesDigest: VerificationDigest;\n orderedOpcContentDigest: VerificationDigest | null;\n normalizedSemanticDigest: VerificationDigest | null;\n entries: readonly PackageManifestEntry[];\n contentTypes: readonly PackageContentTypeDeclaration[];\n relationships: readonly PackageRelationship[];\n facts: PackageManifestFacts;\n findings: readonly VerificationFinding[];\n}\n\n// ============================================================================\n// Deliverable verification\n// ============================================================================\n\n/** Policy preset used by the default deliverable gate. */\nexport type DeliverableVerificationMode = \"standard\" | \"strict\" | \"reportOnly\";\n\n/** Final policy decision in a deliverable-verification report. */\nexport type DeliverableVerificationDecision =\n | \"passed\"\n | \"passedWithPreExistingFindings\"\n | \"failed\"\n | \"notEvaluated\";\n\n/** How a delivered finding relates to the exact opening/baseline package. */\nexport type DeliverableFindingDisposition =\n | \"new\"\n | \"preExisting\"\n | \"resolved\"\n | \"unclassified\";\n\nexport type DeliverableFindingCategory =\n | \"package\"\n | \"openXml\"\n | \"relationship\"\n | \"structure\"\n | \"workflow\"\n | \"delta\"\n | \"render\"\n | \"artifact\";\n\nexport type DeliverableCheckStatus =\n | \"completed\"\n | \"skippedPrerequisiteFailed\"\n | \"unavailableEvidence\";\n\nexport type DeliverablePackageChangeKind =\n | \"entryAdded\"\n | \"entryRemoved\"\n | \"entryModified\"\n | \"relationshipAdded\"\n | \"relationshipRemoved\"\n | \"relationshipModified\";\n\nexport type DeliverableArtifactRole =\n | \"html\"\n | \"pdf\"\n | \"pageMap\"\n | \"pageImage\"\n | \"renderReport\"\n | \"other\";\n\nexport type DeliverableArtifactAvailability = \"available\" | \"unavailable\";\n\n/** Camel-case enum values used by the deliverable report's semantic summary. */\nexport type DeliverableSemanticChangeFamily =\n | \"text\"\n | \"blockStructure\"\n | \"runFormatting\"\n | \"paragraphFormatting\"\n | \"style\"\n | \"numbering\"\n | \"list\"\n | \"table\"\n | \"tableRow\"\n | \"tableCell\"\n | \"tableSpan\"\n | \"tableWidth\"\n | \"tableStyle\"\n | \"section\"\n | \"pageSetup\"\n | \"header\"\n | \"footer\"\n | \"field\"\n | \"footnote\"\n | \"endnote\"\n | \"comment\"\n | \"hyperlink\"\n | \"bookmark\"\n | \"contentControl\"\n | \"image\"\n | \"media\"\n | \"relationship\"\n | \"revision\"\n | \"annotation\"\n | \"opaquePackagePart\";\n\nexport interface DeliverablePackageIdentity {\n packageKind: string;\n manifestValid: boolean;\n rawPackageBytesDigest: VerificationDigest;\n orderedOpcContentDigest: VerificationDigest | null;\n normalizedSemanticDigest: VerificationDigest | null;\n}\n\nexport interface DeliverableCheckResult {\n check: string;\n status: DeliverableCheckStatus;\n findingCount: number;\n diagnostic: string | null;\n}\n\nexport interface DeliverableFinding {\n findingId: string;\n code: string;\n category: DeliverableFindingCategory;\n severity: VerificationFindingSeverity;\n disposition: DeliverableFindingDisposition;\n blocksDelivery: boolean;\n message: string;\n owningPartUri: string;\n location: ChangeLocation | null;\n anchorId: string | null;\n scope: string | null;\n xPath: string | null;\n remediation: string;\n}\n\nexport interface DeliverablePackageChange {\n changeId: string;\n kind: DeliverablePackageChangeKind;\n location: ChangeLocation;\n beforeDigest: VerificationDigest | null;\n afterDigest: VerificationDigest | null;\n beforeValue: string | null;\n afterValue: string | null;\n}\n\nexport interface DeliverableSemanticChange {\n changeId: string;\n fingerprint: string;\n operation: SemanticChangeOperation;\n family: DeliverableSemanticChangeFamily;\n partUri: string;\n path: string;\n leftAnchor: string | null;\n rightAnchor: string | null;\n}\n\nexport interface DeliverableSemanticDelta {\n schema: \"docxodus.semantic-changes\";\n schemaVersion: 1;\n changeCount: number;\n canonicalDigest: VerificationDigest;\n changes: readonly DeliverableSemanticChange[];\n}\n\nexport interface DeliverableArtifactMetadata {\n artifactId: string;\n role: DeliverableArtifactRole;\n mediaType: string;\n availability: DeliverableArtifactAvailability;\n byteLength: number | null;\n digest: VerificationDigest | null;\n unavailableReason: string | null;\n pageCount: number | null;\n rendererFingerprint: string | null;\n sourcePackageDigest: VerificationDigest | null;\n pageMapDigest: VerificationDigest | null;\n renderDiagnosticCount: number;\n}\n\n/** Canonical schema-v1 report returned by every default verification transport. */\n/** One recorded artifact's independent re-hash verdict from receipt verification. */\nexport type DeliveryArtifactVerificationStatus =\n | \"verified\"\n | \"unavailable\"\n | \"missing\"\n | \"length_mismatch\"\n | \"digest_mismatch\"\n | \"invalid_record\";\n\nexport interface DeliveryArtifactVerification {\n artifactId: string;\n status: DeliveryArtifactVerificationStatus;\n expectedLength?: number;\n actualLength?: number;\n expectedDigest?: VerificationDigest;\n actualDigest?: VerificationDigest;\n}\n\n/**\n * Portable delivery change receipt verification verdict \u2014 the shared facade wire\n * shape every transport returns (issue #520).\n */\n/** What the session's host-owned delivery evidence recorder holds (issue #748). */\nexport interface DeliveryEvidenceStatus {\n enabled: boolean;\n transactionCount: number;\n lineageEventCount: number;\n /** Version steps applied by direct calls: exact packages, unknown request. */\n unlabeledTransactionCount: number;\n retainedStateCount: number;\n retainedBytes: number;\n sourceVersion: number;\n currentVersion: number;\n /** Null when a complete receipt can be minted; otherwise the first reason it cannot. */\n unavailableReason: string | null;\n}\n\nexport type DeliveryReceiptPrivacyProfile = \"hashOnly\" | \"hashAndSummary\" | \"fullEvidence\";\n\nexport interface DeliveryReceiptBuildOptions {\n privacyProfile?: DeliveryReceiptPrivacyProfile;\n failOnUnexpectedChanges?: boolean;\n}\n\nexport interface DeliveryBundleArtifact {\n artifactId: string;\n kind: string;\n requiredness: \"required\" | \"optional\";\n availability: \"available\" | \"unavailable\";\n relativePath: string;\n mediaType: string;\n /** Present when available. */\n bytes?: Uint8Array;\n /** Present when unavailable. */\n unavailableReason?: string;\n}\n\n/**\n * A delivery bundle as every transport publishes it: the verified manifest, its canonical bytes,\n * and each artifact with its bytes or the reason it is unavailable. `evidence` is the session's\n * recorder status at delivery time.\n */\nexport interface DeliveryBundleResult {\n status: \"complete\" | \"incomplete\" | \"failed\";\n verified: boolean;\n manifest: Record<string, unknown>;\n manifestBytes: Uint8Array;\n artifacts: readonly DeliveryBundleArtifact[];\n evidence?: DeliveryEvidenceStatus;\n}\n\nexport interface DeliveryReceiptVerificationResult {\n isValid: boolean;\n receiptDigestValid: boolean;\n contractValid: boolean;\n citationBindingsValid: boolean;\n artifacts: DeliveryArtifactVerification[];\n findings: string[];\n}\n\n/** One approved package-level delta the deliverable is expected to show (issue #747). */\nexport interface DeliverablePackageChangeExpectation {\n kind: DeliverablePackageChangeKind;\n location: ChangeLocation;\n beforeDigest?: VerificationDigest;\n afterDigest?: VerificationDigest;\n beforeValue?: string;\n afterValue?: string;\n}\n\nexport type DeliverableRenderDiagnosticKind =\n | \"warning\"\n | \"unsupportedContent\"\n | \"missingFont\"\n | \"fontSubstitution\";\n\n/** One render warning or limitation reported by the companion renderer. */\nexport interface DeliverableRenderDiagnostic {\n kind: DeliverableRenderDiagnosticKind;\n message: string;\n severity?: VerificationFindingSeverity;\n code?: string;\n phase?: string;\n}\n\n/** Bytes and renderer/document binding for one companion artifact submitted for verification. */\nexport interface DeliverableCompanionArtifactInput {\n artifactId: string;\n role: DeliverableArtifactRole;\n mediaType: string;\n /** Defaults to `available`. */\n availability?: DeliverableArtifactAvailability;\n bytes?: Uint8Array;\n unavailableReason?: string;\n pageCount?: number;\n rendererFingerprint?: string;\n /** Digest of the exact package the renderer consumed; a mismatch is a stale artifact. */\n sourcePackageDigest?: VerificationDigest;\n pageMapDigest?: VerificationDigest;\n renderDiagnostics?: readonly DeliverableRenderDiagnostic[];\n}\n\n/**\n * Policy and inspection limits for verification (issue #747). Every field is optional; an\n * omitted field takes the verifier's own default. Unknown fields are rejected.\n */\nexport interface DeliverableVerificationPolicyOptions {\n mode?: DeliverableVerificationMode;\n openXmlVersion?: string;\n failOnUnexpectedChanges?: boolean;\n requireNoPlaceholders?: boolean;\n detectBracketedAlternativeClauses?: boolean;\n editorialMarkers?: readonly string[];\n placeholderTokens?: readonly string[];\n maxPackageBytes?: number;\n maxFindings?: number;\n maxDetectorNodes?: number;\n maxDetectorRelationships?: number;\n maxDetectorTextCharacters?: number;\n maxDetectorRegexMatches?: number;\n maxDetectorSteps?: number;\n maxCompanionArtifactBytes?: number;\n maxTotalCompanionArtifactBytes?: number;\n maxCompanionArtifacts?: number;\n maxRenderDiagnostics?: number;\n maxExpectedChanges?: number;\n maxReportedDeltaChanges?: number;\n packageManifest?: {\n maxEntryCount?: number;\n maxEntryUncompressedBytes?: number;\n maxTotalUncompressedBytes?: number;\n maxXmlPartBytes?: number;\n maxCompressionRatio?: number;\n maxUriLength?: number;\n };\n}\n\n/**\n * The full bounded verification request (issue #747): what the typed .NET request adds to the\n * package bytes. Package bytes are passed alongside, never inside, this object.\n */\nexport interface DeliverableVerificationRequest {\n options?: DeliverableVerificationPolicyOptions;\n /** The canonical semantic-changes object (as `getSemanticChanges` returns it). */\n expectedSemanticChanges?: SemanticChangeSet;\n expectedPackageChanges?: readonly DeliverablePackageChangeExpectation[];\n companionArtifacts?: readonly DeliverableCompanionArtifactInput[];\n}\n\nexport interface DeliverableVerificationResult {\n schema: \"https://docxodus.dev/schemas/verification/deliverable-verification/v1\";\n schemaVersion: 1;\n mode: DeliverableVerificationMode;\n decision: DeliverableVerificationDecision;\n analysisCompleted: boolean;\n baselineCompared: boolean;\n baselinePackage: DeliverablePackageIdentity | null;\n deliverablePackage: DeliverablePackageIdentity;\n checks: readonly DeliverableCheckResult[];\n findings: readonly DeliverableFinding[];\n resolvedFindings: readonly DeliverableFinding[];\n semanticDelta: DeliverableSemanticDelta | null;\n packageChanges: readonly DeliverablePackageChange[];\n companionArtifacts: readonly DeliverableArtifactMetadata[];\n}\n\n/** How a revision in a redline relates to the selected baseline. */\nexport type RedlineRevisionDisposition =\n | \"preExisting\"\n | \"intendedFinalPreExisting\"\n | \"generated\"\n | \"conflicted\";\n\n/** Which of the two proof paths a result or finding belongs to. */\nexport type RedlineProofDirection = \"acceptToFinal\" | \"rejectToBaseline\";\n\n/** How a package entry differs from a path's expected document. */\nexport type RedlinePackageDivergenceKind = \"added\" | \"removed\" | \"modified\";\n\n/** Fail-closed resolution status of one native revision \u2014 the session registry's vocabulary. */\nexport type RedlineRevisionResolutionStatus = RevisionResolutionStatus;\n\n/** Coarse family of one native revision. */\nexport type RedlineRevisionFamily =\n | \"contentInsert\"\n | \"contentDelete\"\n | \"move\"\n | \"paragraphMark\"\n | \"rowInsert\"\n | \"rowDelete\"\n | \"cellInsert\"\n | \"cellDelete\"\n | \"cellMerge\"\n | \"contentControlInsert\"\n | \"contentControlDelete\"\n | \"numberingPropertiesInsert\"\n | \"numberingChange\"\n | \"propertiesChange\"\n | \"unsupported\";\n\n/** Why a revision could not be resolved \u2014 the session registry's shape. */\nexport type RedlineRevisionDiagnostic = RevisionDiagnostic;\n\n/** Input or output package identity recorded by the proof. */\nexport interface RedlineProofPackageIdentity {\n rawPackageBytesDigest: VerificationDigest;\n orderedOpcContentDigest: VerificationDigest | null;\n normalizedWholePackageDigest: VerificationDigest | null;\n}\n\n/** A stable, part-qualified identity for one native Word revision. */\nexport interface RedlineRevisionIdentity {\n id: string;\n partUri: string;\n scope: string;\n type: string;\n family: RedlineRevisionFamily;\n constituentIds: readonly string[];\n constituentKeys: readonly string[];\n author: string;\n date: string | null;\n dateUtc: string | null;\n text: string;\n anchorId: string | null;\n affectedAnchorIds: readonly string[];\n resolutionStatus: RedlineRevisionResolutionStatus;\n diagnostic: RedlineRevisionDiagnostic | null;\n}\n\n/** Classification of a baseline/intended-final/redline revision identity triple. */\nexport interface RedlineRevisionClassification {\n disposition: RedlineRevisionDisposition;\n baseline: RedlineRevisionIdentity | null;\n intendedFinal: RedlineRevisionIdentity | null;\n redline: RedlineRevisionIdentity | null;\n reason: string;\n}\n\n/**\n * Modeled semantic comparison for one path. `available` and `changeCount` are explicit so an\n * empty modeled change set is never mistaken for complete package equality.\n */\nexport interface RedlineModeledSemanticComparison {\n available: boolean;\n equivalent: boolean | null;\n schema: string | null;\n changeCount: number | null;\n diagnostic: string | null;\n}\n\n/** One added, removed, or modified package entry on a proof path. */\nexport interface RedlinePackageDivergence {\n kind: RedlinePackageDivergenceKind;\n partUri: string;\n occurrence: number;\n anchorId: string | null;\n applicableRevisionIds: readonly string[];\n expectedRawDigest: VerificationDigest | null;\n actualRawDigest: VerificationDigest | null;\n expectedNormalizedDigest: VerificationDigest | null;\n actualNormalizedDigest: VerificationDigest | null;\n /** Whether the semantic change set reports a modeled change for this part. */\n hasModeledSemanticChange: boolean;\n /**\n * Conservatively true when the normalized difference may contain content outside the modeled\n * semantic projection. A modeled change in one part never proves every change in it was modeled.\n */\n unknownOrUnmodeled: boolean;\n}\n\n/** A structured, actionable proof finding. */\nexport interface RedlineProofFinding {\n code: string;\n severity: VerificationFindingSeverity;\n message: string;\n direction: RedlineProofDirection | null;\n location: ChangeLocation | null;\n anchorId: string | null;\n revisionIds: readonly string[];\n remediation: string | null;\n}\n\n/** Result of accepting or rejecting only the generated revision set. */\nexport interface RedlineProofPathResult {\n direction: RedlineProofDirection;\n completed: boolean;\n equivalent: boolean;\n requestedRevisionIds: readonly string[];\n resolvedRevisionIds: readonly string[];\n implicitlyResolvedRevisionIds: readonly string[];\n survivingPreExistingRevisions: readonly RedlineRevisionIdentity[];\n preExistingRevisionsPreserved: boolean;\n modeledSemantic: RedlineModeledSemanticComparison;\n normalizedWholePackageEquivalent: boolean;\n orderedOpcContentEquivalent: boolean;\n exactPackageBytesEquivalent: boolean;\n /**\n * Whether the complete bounded package delta was available. A false value never exposes a\n * potentially misleading prefix of `divergences`.\n */\n divergenceAnalysisCompleted: boolean;\n expectedPackage: RedlineProofPackageIdentity;\n actualPackage: RedlineProofPackageIdentity | null;\n firstDivergence: RedlinePackageDivergence | null;\n divergences: readonly RedlinePackageDivergence[];\n findings: readonly RedlineProofFinding[];\n}\n\n/**\n * Canonical schema-v1 proof that a redline's generated changes accept to the intended final and\n * reject to the baseline without consuming pre-existing review state.\n */\nexport interface RedlineReversibilityProof {\n schema: \"https://docxodus.dev/schemas/verification/redline-reversibility-proof/v1\";\n schemaVersion: 1;\n success: boolean;\n requireExactPackageBytes: boolean;\n baselinePackage: RedlineProofPackageIdentity;\n intendedFinalPackage: RedlineProofPackageIdentity;\n redlinePackage: RedlineProofPackageIdentity;\n revisionClassifications: readonly RedlineRevisionClassification[];\n acceptToFinal: RedlineProofPathResult | null;\n rejectToBaseline: RedlineProofPathResult | null;\n findings: readonly RedlineProofFinding[];\n}\n\n/** Effective #493 inspection limits applied while the manifest is being generated. */\nexport interface PackageManifestInspectionLimits {\n opcEntries: number;\n expandedOpcBytes: number;\n xmlPartBytes: number;\n opcUriCharacters: number;\n opcCompressionRatio: number;\n}\n\n/**\n * Internal WASM exports structure\n */\nexport interface DocxodusWasmExports {\n /** Available in builds with durable history bindings. */\n HistoryBridge?: import('./history.js').HistoryBridge;\n DocumentConverter: {\n GeneratePackageManifest: (bytes: Uint8Array) => string;\n VerifyDeliverable: (bytes: Uint8Array) => string;\n VerifyDeliverableWithRequest?: (bytes: Uint8Array, requestJson: string) => string;\n VerifyDeliverableWithBaselineAndRequest?: (\n baselineBytes: Uint8Array,\n bytes: Uint8Array,\n requestJson: string,\n ) => string;\n VerifyDeliveryReceipt: (receiptJson: string, artifactsJson: string) => string;\n VerifyDeliverableWithBaseline: (\n baselineBytes: Uint8Array,\n bytes: Uint8Array\n ) => string;\n ProveRedlineReversibility: (\n baselineBytes: Uint8Array,\n intendedFinalBytes: Uint8Array,\n redlineBytes: Uint8Array\n ) => string;\n GeneratePackageManifestWithOptions: (\n bytes: Uint8Array,\n maxEntryCount: number,\n maxTotalUncompressedBytes: number,\n maxXmlPartBytes: number,\n maxCompressionRatio: number,\n maxUriLength: number,\n ) => string;\n ConvertDocxToHtml: (bytes: Uint8Array) => string;\n RenderBlockHtml: (\n bytes: Uint8Array,\n anchorId: string,\n cssPrefix: string,\n fabricateClasses: boolean\n ) => string;\n ConvertDocxToHtmlWithOptions: (\n bytes: Uint8Array,\n pageTitle: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n additionalCss: string,\n commentRenderMode: number,\n commentCssClassPrefix: string\n ) => string;\n ConvertDocxToHtmlWithPagination: (\n bytes: Uint8Array,\n pageTitle: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n additionalCss: string,\n commentRenderMode: number,\n commentCssClassPrefix: string,\n paginationMode: number,\n paginationScale: number,\n paginationCssClassPrefix: string\n ) => string;\n ConvertDocxToHtmlFull: (\n bytes: Uint8Array,\n pageTitle: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n additionalCss: string,\n commentRenderMode: number,\n commentCssClassPrefix: string,\n paginationMode: number,\n paginationScale: number,\n paginationCssClassPrefix: string,\n renderAnnotations: boolean,\n annotationLabelMode: number,\n annotationCssClassPrefix: string\n ) => string;\n ConvertDocxToHtmlComplete: (\n bytes: Uint8Array,\n pageTitle: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n additionalCss: string,\n commentRenderMode: number,\n commentCssClassPrefix: string,\n paginationMode: number,\n paginationScale: number,\n paginationCssClassPrefix: string,\n renderAnnotations: boolean,\n annotationLabelMode: number,\n annotationCssClassPrefix: string,\n renderFootnotesAndEndnotes: boolean,\n renderHeadersAndFooters: boolean,\n renderTrackedChanges: boolean,\n showDeletedContent: boolean,\n renderMoveOperations: boolean,\n renderUnsupportedContentPlaceholders: boolean,\n documentLanguage: string | null,\n stampAnchors: boolean,\n revisionPresentation: number,\n semanticLists?: boolean\n ) => string;\n GetAnnotations: (bytes: Uint8Array) => string;\n AddAnnotation: (bytes: Uint8Array, requestJson: string) => string;\n AddAnnotationWithTarget: (bytes: Uint8Array, requestJson: string) => string;\n RemoveAnnotation: (bytes: Uint8Array, annotationId: string) => string;\n HasAnnotations: (bytes: Uint8Array) => string;\n GetDocumentStructure: (bytes: Uint8Array) => string;\n GetDocumentMetadata: (bytes: Uint8Array) => string;\n ExportToOpenContract: (bytes: Uint8Array) => string;\n ConvertWmlToMarkdown: (bytes: Uint8Array, settingsJson: string) => string;\n GetVersion: () => string;\n // Profiling methods\n ConvertDocxToHtmlProfiled: (bytes: Uint8Array) => string;\n ProfileConversionDetailed: (bytes: Uint8Array) => string;\n // External annotation methods\n ComputeDocumentHash: (bytes: Uint8Array) => string;\n CreateExternalAnnotationSet: (\n bytes: Uint8Array,\n documentId: string\n ) => string;\n ValidateExternalAnnotations: (\n bytes: Uint8Array,\n annotationSetJson: string\n ) => string;\n ConvertDocxToHtmlWithExternalAnnotations: (\n bytes: Uint8Array,\n annotationSetJson: string,\n pageTitle: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n additionalCss: string,\n extAnnotCssClassPrefix: string,\n extAnnotLabelMode: number\n ) => string;\n SearchTextOffsets: (\n bytes: Uint8Array,\n searchText: string,\n maxResults: number\n ) => string;\n // Incremental annotation overlay methods\n ProjectAnnotationsOntoHtml: (\n html: string,\n annotationSetJson: string,\n extAnnotCssClassPrefix: string,\n extAnnotLabelMode: number\n ) => string;\n AddAnnotationToHtml: (\n html: string,\n annotationJson: string,\n labelJson: string,\n extAnnotCssClassPrefix: string,\n extAnnotLabelMode: number\n ) => string;\n RemoveAnnotationFromHtml: (\n html: string,\n annotationId: string,\n extAnnotCssClassPrefix: string\n ) => string;\n GenerateAnnotationVisibilityCss: (\n hiddenLabelIdsJson: string,\n extAnnotCssClassPrefix: string\n ) => string;\n GenerateAnnotationCss: (\n labelsJson: string,\n extAnnotCssClassPrefix: string,\n extAnnotLabelMode: number\n ) => string;\n };\n DocumentComparer: {\n /**\n * Force the comparison code path hot by running a real comparison against\n * tiny in-memory seed documents. Returns \"ok\" or a JSON error object.\n * Idempotent \u2014 assemblies load only once.\n */\n Warmup: () => string;\n CompareDocuments: (\n originalBytes: Uint8Array,\n modifiedBytes: Uint8Array,\n authorName: string | null\n ) => Uint8Array;\n CompareDocumentsToHtml: (\n originalBytes: Uint8Array,\n modifiedBytes: Uint8Array,\n authorName: string | null\n ) => string;\n CompareDocumentsToHtmlWithOptions: (\n originalBytes: Uint8Array,\n modifiedBytes: Uint8Array,\n authorName: string | null,\n renderTrackedChanges: boolean\n ) => string;\n CompareDocumentsToHtmlFull: (\n originalBytes: Uint8Array,\n modifiedBytes: Uint8Array,\n authorName: string | null,\n caseInsensitive: boolean,\n renderTrackedChanges: boolean\n ) => string;\n CompareDocumentsWithOptions: (\n originalBytes: Uint8Array,\n modifiedBytes: Uint8Array,\n authorName: string | null,\n caseInsensitive: boolean\n ) => Uint8Array;\n GetRevisionsJson: (comparedDocBytes: Uint8Array) => string;\n GetCommentsJson: (docBytes: Uint8Array) => string;\n };\n DocxDiffBridge: {\n /** Redlined DOCX bytes (native markup), or empty array on error. */\n Compare: (\n leftBytes: Uint8Array,\n rightBytes: Uint8Array,\n settingsJson: string\n ) => Uint8Array;\n /** `{\"revisions\":[\u2026]}` JSON, or a JSON error object. */\n GetRevisionsJson: (\n leftBytes: Uint8Array,\n rightBytes: Uint8Array,\n settingsJson: string\n ) => string;\n /** Edit-script JSON (diff-as-data), or a JSON error object. */\n GetEditScriptJson: (\n leftBytes: Uint8Array,\n rightBytes: Uint8Array,\n settingsJson: string\n ) => string;\n /** Canonical `docxodus.semantic-changes` JSON, or a JSON error object. */\n GetSemanticChangesJson: (\n leftBytes: Uint8Array,\n rightBytes: Uint8Array,\n settingsJson: string\n ) => string;\n /** One memoized pass, every requested product: `{\"redlineB64\":\u2026, \"revisions\":[\u2026],\n * \"editScript\":\u2026, \"semanticChanges\":\u2026}` JSON (issue #594), or a JSON error object. */\n CompareProductsJson: (\n leftBytes: Uint8Array,\n rightBytes: Uint8Array,\n settingsJson: string,\n productsJson: string\n ) => string;\n /** One baseline read once, compared against many candidates:\n * `{\"results\":[{\"name\":\u2026, \u2026products\u2026}]}` JSON (issue #617), or a JSON error object. */\n CompareBatchJson: (\n baselineBytes: Uint8Array,\n candidatesJson: string,\n settingsJson: string,\n productsJson: string\n ) => string;\n /** Accept all tracked revisions in a redlined DOCX \u2192 \"right\"-side bytes, or empty array on error. */\n AcceptRevisions: (bytes: Uint8Array) => Uint8Array;\n /** Reject all tracked revisions in a redlined DOCX \u2192 \"left\"-side bytes, or empty array on error. */\n RejectRevisions: (bytes: Uint8Array) => Uint8Array;\n /** Consolidated redlined DOCX bytes (native markup), or empty array on error. */\n Consolidate: (\n baseBytes: Uint8Array,\n reviewersJson: string,\n settingsJson: string\n ) => Uint8Array;\n /** `{\"revisions\":[\u2026]}` JSON for the consolidation, or a JSON error object. */\n GetConsolidatedRevisionsJson: (\n baseBytes: Uint8Array,\n reviewersJson: string,\n settingsJson: string\n ) => string;\n /** Consolidated edit-script JSON (diff-as-data), or a JSON error object. */\n GetConsolidatedEditScriptJson: (\n baseBytes: Uint8Array,\n reviewersJson: string,\n settingsJson: string\n ) => string;\n /** `{\"conflicts\":[\u2026]}` JSON for the consolidation, or a JSON error object. */\n GetConflictsJson: (\n baseBytes: Uint8Array,\n reviewersJson: string,\n settingsJson: string\n ) => string;\n };\n DocxSessionBridge: {\n OpenSession: (bytes: Uint8Array, settingsJson: string) => number;\n OpenPreviewSession?: (liveHandle: number) => number;\n CloseSession: (handle: number) => void;\n CreateBlankDocx: () => Uint8Array;\n Project: (handle: number) => string;\n GetVersion: (handle: number) => string;\n RegisterPageMap: (handle: number, pageMapJson: string, expectedRendererFingerprint: string) => string;\n GetPageMapStatus: (handle: number, requestJson: string) => string;\n GetPageCitation: (handle: number, anchorId: string, requestJson: string) => string;\n GetPackageContentHash?: (handle: number) => string;\n BeginMutationTransaction?: (handle: number, transactionId: string, requestJson: string) => string;\n CompleteMutationTransaction?: (handle: number, transactionId: string, serializedResponse: string) => void;\n AbandonMutationTransaction?: (handle: number, transactionId: string) => void;\n RetainPreview?: (shadowHandle: number) => string;\n CommitPreview?: (handle: number, previewId: string) => string;\n GetDeliveryEvidenceStatus?: (handle: number) => string;\n BuildDeliveryReceipt?: (handle: number, optionsJson: string) => string;\n BeginDeliveryEvidence?: (handle: number, operationsJson: string, mode: string, identityJson: string) => boolean;\n CompleteDeliveryEvidence?: (handle: number, stepsJson: string) => void;\n AbandonDeliveryEvidence?: (handle: number) => void;\n GetPackageManifest: (handle: number) => string;\n RenderPreviewHtml?: (handle: number) => string;\n RenderPreviewBlockHtml?: (handle: number, anchorId: string) => string;\n CheckPreconditions: (handle: number, preconditionsJson: string) => string;\n BeginTransaction: (handle: number) => number;\n CommitTransaction: (transactionHandle: number) => void;\n RollbackTransaction: (transactionHandle: number) => void;\n ProjectAnchor: (handle: number, anchorId: string, depth: number | null) => string;\n ProjectAnchorWithCitations: (\n handle: number,\n anchorId: string,\n depth: number | null,\n requestJson: string,\n ) => string;\n /** Ordered top-level render units per scope container (JSON {@link RenderPlan}) \u2014\n * what the editor's incremental reconciler diffs its DOM against. Optional:\n * absent on older WASM bundles. */\n ListBlocks?: (handle: number) => string;\n ListRenderedBlocks?: (handle: number, renderTrackedChanges: boolean) => string;\n /** Citation-ordered footnotes/endnotes (JSON {@link NoteListEntry}[]) \u2014 the\n * id\u2194ordinal authority for renumbering rendered note chrome. Optional:\n * absent on older WASM bundles. */\n ListNotes?: (handle: number, endnotes: boolean) => string;\n /** The anchor index alone as `{\"anchorIndex\":{\u2026}}` \u2014 the editor's per-op\n * anchor-map refresh without marshaling the whole markdown projection.\n * Optional: absent on older WASM bundles. */\n ListAnchors?: (handle: number) => string;\n /** Batch block render: `anchorIdsJson` is a JSON string array; returns a JSON\n * object mapping each id to its HTML element (null when unresolvable), or\n * `{\"error\": \u2026}` on total failure \u2014 parse and check for `error`. One throwaway\n * doc + one converter run for the whole batch, with real sibling context and\n * true list-marker numbers. Optional: absent on older WASM bundles. */\n RenderBlocksHtml?: (\n handle: number,\n anchorIdsJson: string,\n cssPrefix: string,\n fabricateClasses: boolean\n ) => string;\n RenderBlocksHtmlForReview?: (\n handle: number,\n anchorIdsJson: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n renderTrackedChanges: boolean\n ) => string;\n RenderBlockHtml: (\n handle: number,\n anchorId: string,\n cssPrefix: string | null,\n fabricateClasses: boolean | null\n ) => string;\n RenderBlockHtmlForReview?: (\n handle: number,\n anchorId: string,\n cssPrefix: string,\n fabricateClasses: boolean,\n renderTrackedChanges: boolean\n ) => string;\n RenderHtml: (\n handle: number,\n cssPrefix: string,\n fabricateClasses: boolean,\n paginated: boolean,\n scale: number\n ) => string;\n RenderHtmlForReview?: (\n handle: number,\n cssPrefix: string,\n fabricateClasses: boolean,\n paginated: boolean,\n scale: number,\n renderTrackedChanges: boolean\n ) => string;\n /** The editor's comments-aware render profile: `optionsJson` is a serialized\n * {@link EditorRenderOptions}. With `comments: true` the output carries the converter's\n * Inline comment markup (`comment-highlight` spans with `data-comment-id`, `comment-marker`\n * anchors) using the `comment-` class prefix; with `comments: false` it is byte-identical to\n * `RenderHtml` / `RenderHtmlForReview`. Same error convention: HTML starts with '<', an\n * error object with '{'. Optional: absent on older WASM bundles. */\n RenderEditorHtml?: (handle: number, optionsJson: string) => string;\n /** Batch block render with the editor profile \u2014 `RenderBlocksHtml` plus comment markup;\n * same JSON-object result (`{ [anchorId]: html | null }`, or `{\"error\": \u2026}`). */\n RenderEditorBlocksHtml?: (handle: number, anchorIdsJson: string, optionsJson: string) => string;\n RenderEditorChromeHtml?: (handle: number, optionsJson: string) => string;\n RenderEditorRangeHtml?: (handle: number, anchorIdsJson: string, optionsJson: string) => string;\n /** Single-block render with the editor profile \u2014 `RenderBlockHtml` plus comment markup. */\n RenderEditorBlockHtml?: (handle: number, anchorId: string, optionsJson: string) => string;\n ReplaceText: (handle: number, anchor: string, md: string) => string;\n DeleteBlock: (handle: number, anchor: string) => string;\n MoveBlock: (handle: number, sourceAnchor: string, targetAnchor: string, pos: string) => string;\n /** JSON `{anchorId, before, after}[]` \u2014 the blocks a block may legally be moved next to and\n * on which side, which is what a drag UI gates its drop targets on. The two sides are\n * reported separately because a cross-block range or a section break between the blocks can\n * make one legal and the other not. Optional: absent on older WASM bundles. */\n ValidMoveTargets?: (handle: number, sourceAnchor: string) => string;\n DeleteRange: (handle: number, fromAnchorId: string, toAnchorIdExclusive: string) => string;\n DeleteSection: (handle: number, headingAnchorId: string) => string;\n InsertParagraph: (handle: number, anchor: string, pos: string, md: string) => string;\n SplitParagraph: (handle: number, anchor: string, offset: number) => string;\n MergeParagraphs: (handle: number, first: string, second: string) => string;\n InsertHorizontalRule: (handle: number, anchor: string, pos: string, ruleJson: string) => string;\n InsertTable: (handle: number, anchor: string, pos: string, rows: number, cols: number, optionsJson: string) => string;\n GetTableMetadata: (handle: number, tableAnchor: string) => string;\n ResolveTableCellAnchor: (handle: number, cellAnchor: string) => string;\n ResolveTableCellCoordinate: (handle: number, tableAnchor: string, rowIndex: number, columnIndex: number) => string;\n InsertTableRow: (handle: number, cellAnchor: string, pos: string) => string;\n InsertTableColumn: (handle: number, cellAnchor: string, pos: string) => string;\n DeleteTableRow: (handle: number, cellAnchor: string) => string;\n DeleteTableColumn: (handle: number, cellAnchor: string) => string;\n MergeCells: (handle: number, cellAnchor: string, rowSpan: number, colSpan: number, content: string) => string;\n UnmergeCells: (handle: number, cellAnchor: string) => string;\n SetColumnWidths: (handle: number, cellAnchor: string, widthsJson: string) => string;\n SetTableBorders: (handle: number, cellAnchor: string, specJson: string) => string;\n SetCellShading: (handle: number, cellAnchor: string, fill: string, scope: string) => string;\n SetRepeatHeaderRow: (handle: number, cellAnchor: string, repeat: boolean | null) => string;\n SetTableRowOptions: (handle: number, cellAnchor: string, repeatHeader: boolean | null,\n allowBreakAcrossPages: boolean | null, heightTwips: number | null, heightRule: string) => string;\n SetHeaderText: (handle: number, anchor: string, kind: string, markdown: string) => string;\n SetFooterText: (handle: number, anchor: string, kind: string, markdown: string) => string;\n InsertPageNumberField: (handle: number, anchor: string, field: string, format: string) => string;\n SetPageNumbering: (handle: number, anchor: string, opJson: string) => string;\n InsertTableOfContents: (handle: number, anchor: string, pos: string, optionsJson: string) => string;\n InsertTableOfFigures: (handle: number, anchor: string, pos: string, optionsJson: string) => string;\n InsertTableOfAuthorities: (handle: number, anchor: string, pos: string, optionsJson: string) => string;\n ClearPageNumbering: (handle: number, anchor: string) => string;\n EnsureHeaderFooterVisible: (handle: number, anchor: string, kind: string) => string;\n /** Word's \"Different first page\" / \"Different odd & even pages\" checkboxes. `kind` is\n * \"first\" | \"even\"; `enabled: false` removes `w:titlePg` / `w:evenAndOddHeaders` and leaves\n * the story parts in place. Optional: absent on older WASM bundles. */\n SetHeaderFooterKindEnabled?: (handle: number, anchor: string, kind: string, enabled: boolean) => string;\n /** Page size / orientation / margins / header-footer distance of the section owning\n * `anchor`; `opJson` is a serialized {@link PageSetupOp}. Optional: absent on older WASM\n * bundles. */\n SetPageSetup?: (handle: number, anchor: string, opJson: string) => string;\n InsertFootnote: (handle: number, anchor: string, characterOffset: number, markdown: string) => string;\n InsertCrossReference: (\n handle: number,\n anchor: string,\n characterOffset: number,\n bookmarkName: string,\n optionsJson: string\n ) => string;\n InsertEndnote: (handle: number, anchor: string, characterOffset: number, markdown: string) => string;\n // Native Word comment authoring (issue #300). spanJson: \"\" = whole block, else\n // {\"start\":n,\"length\":n}; initials/date: \"\" = absent (date is ISO-8601).\n AddComment: (\n handle: number,\n anchor: string,\n spanJson: string,\n author: string,\n initials: string,\n date: string,\n markdown: string,\n ) => string;\n AddCommentToRevision: (\n handle: number,\n revisionId: string,\n author: string,\n initials: string,\n date: string,\n markdown: string,\n ) => string;\n AddCommentReply: (\n handle: number,\n parentCommentAnchor: string,\n author: string,\n initials: string,\n date: string,\n markdown: string,\n ) => string;\n UpdateComment: (handle: number, commentAnchor: string, markdown: string) => string;\n SetCommentResolved: (handle: number, commentAnchor: string, resolved: boolean) => string;\n RemoveComment: (handle: number, commentAnchor: string) => string;\n ListComments: (handle: number) => string;\n ListHyperlinks: (handle: number, scopes: number) => string;\n AddHyperlink: (handle: number, anchor: string, start: number, length: number, kind: string, target: string) => string;\n UpdateHyperlink: (handle: number, hyperlinkId: string, kind: string, target: string) => string;\n RemoveHyperlink: (handle: number, hyperlinkId: string) => string;\n GetImageCapabilities: () => string;\n ListImages: (handle: number, scopes: number) => string;\n InsertImage: (handle: number, anchor: string, characterOffset: number, imageBase64: string, optionsJson: string) => string;\n ReplaceImage: (handle: number, imageId: string, imageBase64: string) => string;\n EmbedLinkedImage: (handle: number, imageId: string, imageBase64: string) => string;\n SetImageDimensions: (handle: number, imageId: string, dimensionsJson: string) => string;\n SetImageMetadata: (handle: number, imageId: string, altText: string | null, title: string | null) => string;\n SetImageFloatingLayout: (handle: number, imageId: string, layoutJson: string) => string;\n RemoveImage: (handle: number, imageId: string) => string;\n ListContentControls: (handle: number, scopes: number) => string;\n FillContentControlText: (handle: number, anchorId: string, text: string, optionsJson: string) => string;\n FillContentControlRichText: (handle: number, anchorId: string, markdown: string, optionsJson: string) => string;\n SetContentControlChecked: (handle: number, anchorId: string, isChecked: boolean, optionsJson: string) => string;\n SetContentControlDate: (handle: number, anchorId: string, value: string, displayText: string | null, optionsJson: string) => string;\n SelectContentControlItem: (handle: number, anchorId: string, value: string, optionsJson: string) => string;\n FillContentControlPicture: (handle: number, anchorId: string, imageBase64: string, optionsJson: string) => string;\n AddRepeatingSectionItem: (handle: number, sectionAnchorId: string, afterItemAnchorId: string, optionsJson: string) => string;\n RemoveRepeatingSectionItem: (handle: number, itemAnchorId: string) => string;\n ListBookmarks: (handle: number, scopes: number) => string;\n AddBookmark: (handle: number, name: string, startAnchor: string, startOffset: number, endAnchor: string, endOffset: number) => string;\n RenameBookmark: (handle: number, name: string, newName: string) => string;\n MoveBookmark: (handle: number, name: string, startAnchor: string, startOffset: number, endAnchor: string, endOffset: number) => string;\n RemoveBookmark: (handle: number, name: string) => string;\n ListRevisions: (handle: number) => string;\n ListRevisionsFiltered?: (handle: number, filterJson: string) => string;\n ListRevisionRepairs?: (handle: number) => string;\n RepairRevisions?: (handle: number, repairsJson: string) => string;\n AcceptRevision: (handle: number, revisionId: string) => string;\n RejectRevision: (handle: number, revisionId: string) => string;\n AcceptAllRevisions: (handle: number) => string;\n RejectAllRevisions: (handle: number) => string;\n ApplyFormat: (handle: number, anchor: string, spanJson: string, opJson: string) => string;\n ApplyFormatBySubstring: (handle: number, anchor: string, substring: string, opJson: string) => string;\n SetParagraphStyle: (handle: number, anchor: string, styleId: string) => string;\n SetParagraphFormat: (handle: number, anchor: string, opJson: string) => string;\n SetListLevel: (handle: number, anchor: string, delta: number) => string;\n RemoveListMembership: (handle: number, anchor: string) => string;\n ApplyListFormat: (handle: number, anchor: string, kind: string) => string;\n ApplyListFormatRange: (handle: number, firstAnchor: string, lastAnchor: string, kind: string) => string;\n SetListStartOverride: (handle: number, anchor: string, value: number) => string;\n ClearListStartOverride: (handle: number, anchor: string) => string;\n ReplaceCellContent: (handle: number, anchor: string, md: string) => string;\n RawGetXml: (handle: number, anchor: string) => string;\n RawInsertXml: (handle: number, anchor: string, pos: string, xml: string) => string;\n RawReplaceXml: (handle: number, anchor: string, xml: string) => string;\n Grep: (handle: number, pattern: string, optionsJson: string) => string;\n GrepCrossBlock: (handle: number, pattern: string, optionsJson: string) => string;\n ReplaceTextRange: (handle: number, anchor: string, find: string, replace: string, optionsJson: string) => string;\n ReplaceTextAtSpan: (handle: number, anchor: string, spanStart: number, spanLength: number, replace: string) => string;\n ReplaceTextAtSpanWithFormat?: (handle: number, anchor: string, spanStart: number, spanLength: number, replace: string, formatJson: string) => string;\n ReplaceInner: (\n handle: number,\n matchText: string,\n anchor: string,\n spanStart: number,\n spanLength: number,\n newInner: string,\n ) => string;\n FindPlaceholders: (\n handle: number,\n kinds: number | null,\n scope: number | null,\n contextChars: number | null,\n boundary: number | null,\n ) => string;\n FindPlaceholdersWithCitations: (\n handle: number,\n kinds: number | null,\n scope: number | null,\n contextChars: number | null,\n boundary: number | null,\n requestJson: string,\n ) => string;\n GetEditSummary: (handle: number) => string;\n RemainingPlaceholders: (handle: number, kinds: number | null) => string;\n GetDiff: (handle: number, format: number | null) => string;\n GetSemanticChanges: (handle: number) => string;\n VerifyDeliverable: (handle: number) => string;\n VerifyDeliverableWithRequest?: (handle: number, requestJson: string) => string;\n FindByAnnotation: (handle: number, annotationId: string) => string;\n FindByAnnotationWithCitations: (handle: number, annotationId: string, requestJson: string) => string;\n FindByLabel: (handle: number, labelId: string) => string;\n FindByLabelWithCitations: (handle: number, labelId: string, requestJson: string) => string;\n FindByBookmark: (handle: number, bookmarkName: string) => string;\n FindByBookmarkWithCitations: (handle: number, bookmarkName: string, requestJson: string) => string;\n Exists: (handle: number, anchorId: string) => boolean;\n FindByText: (handle: number, needle: string, optionsJson: string) => string;\n FindAllByText: (handle: number, needle: string, optionsJson: string) => string;\n FindByRegex: (handle: number, pattern: string, regexOptions: number | null, optionsJson: string) => string;\n FindByKind: (handle: number, kind: string, scope: string) => string;\n FindByKindWithCitations: (handle: number, kind: string, scope: string, requestJson: string) => string;\n GetAnchorInfo: (handle: number, anchorId: string) => string;\n GetAnchorInfos: (handle: number, anchorIdsJson: string) => string;\n GetBlockMetadata: (handle: number, anchorId: string) => string;\n GetBlockMetadatas: (handle: number, anchorIdsJson: string) => string;\n GetListMembership: (handle: number, anchorId: string) => string;\n GetSectionInfo: (handle: number, anchorId: string) => string;\n ListStyles: (handle: number) => string;\n GetFormatting: (handle: number, anchorId: string) => string;\n ListInlineSpans: (handle: number, anchorId: string) => string;\n ListAnnotations: (handle: number) => string;\n // Session annotation write surface\n AddAnnotation: (\n handle: number,\n anchorId: string,\n spanJson: string,\n annotationJson: string\n ) => string;\n SessionRemoveAnnotation: (handle: number, annotationId: string) => string;\n UpdateAnnotation: (\n handle: number,\n annotationId: string,\n updateJson: string\n ) => string;\n MoveAnnotation: (\n handle: number,\n annotationId: string,\n newAnchorId: string,\n newSpanJson: string\n ) => string;\n Undo: (handle: number) => boolean;\n Redo: (handle: number) => boolean;\n SetTrackedChanges: (handle: number, mode: number) => void;\n SetRevisionAuthor: (handle: number, author: string) => void;\n Save: (handle: number) => Uint8Array;\n /** Save KEEPING the projector's `PtOpenXml:Unid` bookkeeping. Exists for the in-browser\n * editor's remount, which re-renders these bytes and needs the anchors to survive the hop.\n * Roughly 6x the document's size and read by no renderer \u2014 never hand it to a user; a\n * save-to-disk wants {@link Save}. */\n SaveWithAnchorIds: (handle: number) => Uint8Array;\n };\n}\n\n// \u2500\u2500\u2500 DocxSession types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type EditErrorCode =\n | \"anchor_not_found\"\n | \"anchor_wrong_kind\"\n | \"anchors_not_adjacent\"\n | \"session_disposed\"\n | \"malformed_markdown\"\n | \"unsupported_markdown_syntax\"\n | \"table_insert_not_supported\"\n | \"footnote_ref_not_supported\"\n | \"comment_marker_not_supported\"\n | \"image_insert_not_supported\"\n | \"anchor_token_in_payload\"\n | \"offset_out_of_range\"\n | \"invalid_position\"\n | \"text_not_found\"\n | \"unknown_style\"\n | \"invalid_list_level\"\n | \"invalid_list_start_value\"\n | \"invalid_page_numbering\"\n | \"invalid_page_setup\"\n | \"invalid_reference_field\"\n | \"invalid_paragraph_format\"\n | \"invalid_table_styling\"\n | \"invalid_table_merge\"\n | \"table_anchor_migration_required\"\n | \"malformed_xml\"\n | \"disallowed_namespace\"\n | \"incompatible_element_type\"\n | \"validation_failed\"\n | \"nothing_to_undo\"\n | \"nothing_to_redo\"\n | \"duplicate_annotation_id\"\n | \"annotation_not_found\"\n | \"empty_annotation_span\"\n | \"empty_comment_span\"\n | \"revision_not_found\"\n | \"precondition_failed\"\n | \"invalid_batch_step\"\n | \"invalid_transaction\"\n | \"transaction_conflict\"\n | \"transaction_result_evicted\"\n | \"transaction_incomplete\"\n | \"preview_not_found\"\n | \"preview_stale\"\n | \"revision_repair_rejected\"\n | \"hyperlink_not_found\"\n | \"bookmark_not_found\"\n | \"duplicate_bookmark_name\"\n | \"invalid_bookmark_name\"\n | \"invalid_hyperlink_target\"\n | \"missing_bookmark_target\"\n | \"bookmark_in_use\"\n | \"managed_bookmark\"\n | \"empty_hyperlink_span\"\n | \"unsupported_inline_boundary\"\n | \"revision_unsupported\"\n | \"revision_malformed\"\n | \"revision_ambiguous\"\n | \"tracked_operation_unsupported\"\n | \"unresolved_structural_revision\"\n | \"content_control_not_found\"\n | \"content_control_malformed\"\n | \"content_control_unsupported\"\n | \"content_control_locked\"\n | \"content_control_bound\"\n | \"content_control_wrong_type\"\n | \"invalid_content_control_value\"\n | \"content_control_placement_unsupported\"\n | \"content_control_nested_fill_unsupported\"\n | \"repeating_section_constraint\"\n | \"image_not_found\"\n | \"invalid_image_data\"\n | \"unsupported_image_format\"\n | \"image_too_large\"\n | \"invalid_image_dimensions\"\n | \"unsupported_image_markup\"\n | \"linked_image_read_only\"\n | \"invalid_image_layout\"\n | \"internal_error\"\n /** A failed edit's rollback also failed, so the document may be half-changed. Every later\n * mutation is refused with this code; close the session and reopen it from known-good bytes. */\n | \"session_corrupted\";\n\nexport interface AnchorRef {\n id: string;\n kind: string;\n scope: string;\n unid: string;\n}\n\nexport interface EditError {\n code: EditErrorCode;\n message: string;\n anchorId?: string;\n precondition?: PreconditionFailure;\n}\n\nexport interface PreconditionTarget {\n exists: boolean;\n anchorId?: string;\n kind?: string;\n scope?: string;\n contentHash?: string;\n visibleText?: string;\n}\n\nexport interface PreconditionFailure {\n condition: string;\n expected: unknown;\n actual: unknown;\n currentVersion: number;\n currentTarget?: PreconditionTarget;\n}\n\nexport interface TextRangePrecondition {\n start: number;\n length: number;\n text: string;\n}\n\n/** Optimistic guards checked immediately before a mutation. */\nexport interface MutationPreconditions {\n expectedVersion?: number;\n /** Optional explicit target; target-addressed methods infer their own anchor when omitted. */\n anchorId?: string;\n expectedContentHash?: string;\n expectedText?: string;\n expectedTextRange?: TextRangePrecondition;\n expectedKind?: string;\n expectedScope?: string;\n expectedMatchCount?: number;\n}\n\nexport type MutationBatchMode = \"atomic\" | \"best_effort\";\n\n/** One synchronous npm batch step. Atomic is the default execution mode. */\nexport interface MutationBatchStep {\n tool: string;\n action: string;\n mutation: () => EditResult | readonly EditResult[];\n /** Optional read-only validation: all run up front in atomic mode, per-step in best-effort. */\n preflight?: () => EditError | undefined;\n /**\n * The step's request arguments, recorded as the normalized request in delivery evidence\n * (issue #748) when the session captures it. The callback hides them, so name them here.\n */\n args?: Record<string, unknown>;\n}\n\n/** A preview callback receives the isolated shadow session it must mutate/read. */\nexport interface MutationBatchPreviewStep {\n tool: string;\n action: string;\n mutation: (shadow: import(\"./session.js\").DocxSession) => EditResult | readonly EditResult[];\n preflight?: (shadow: import(\"./session.js\").DocxSession) => EditError | undefined;\n}\n\nexport interface MutationBatchPreviewOptions {\n html?: \"none\" | \"scoped\" | \"full\";\n /** Required for scoped HTML. */\n htmlAnchorId?: string;\n /**\n * Keep a successful preview's exact result package so {@link DocxSession.commitPreview} can\n * later make it the live document with the previewed generated ids, timestamps and\n * `packageHash`. The receipt then carries {@link MutationBatchResult.retention}. Retention\n * is bounded (count, bytes and time) and cleared when the session closes.\n */\n retain?: boolean;\n}\n\n/**\n * Identity of a preview retained for a guarded commit (issue #760). `baseVersion` and\n * `basePackageHash` describe the live state the preview was predicted from; the commit refuses\n * once either has moved. `expiresAt` is the ISO-8601 UTC instant after which the entry is gone.\n */\nexport interface MutationPreviewRetention {\n previewId: string;\n baseVersion: number;\n basePackageHash: string;\n expiresAt: string;\n}\n\nexport interface MutationBatchStepResult {\n index: number;\n tool: string;\n action: string;\n success: boolean;\n rolledBack: boolean;\n results: readonly EditResult[];\n}\n\nexport interface MutationBatchFailure {\n index: number;\n tool: string;\n action: string;\n error: EditError;\n rolledBack: boolean;\n}\n\nexport interface MutationBatchChangeSet<T> {\n added: readonly T[];\n removed: readonly T[];\n modified: readonly T[];\n}\n\nexport interface MutationBatchResult {\n mode: MutationBatchMode;\n status: \"ok\" | \"failed\" | \"partial\";\n preview: boolean;\n success: boolean;\n rolledBack: boolean;\n baseVersion: number;\n resultVersion: number;\n /**\n * Canonical SHA-256 of this result package, or `null` when it could not be computed.\n * Exact replay equality is guaranteed only for deterministic batches, so consult\n * {@link MutationBatchResult.warnings} before asserting on it \u2014 and note that `null`\n * never equals `null` for the purposes of a replay assertion: an absent hash proves\n * nothing and must be handled explicitly rather than compared.\n */\n packageHash: string | null;\n steps: readonly MutationBatchStepResult[];\n failure?: MutationBatchFailure;\n revisionChanges: MutationBatchChangeSet<RevisionListEntry>;\n commentChanges: MutationBatchChangeSet<CommentListEntry>;\n annotationChanges: MutationBatchChangeSet<DocumentAnnotation>;\n warnings: readonly string[];\n /** Shadow-only preview HTML when requested; null otherwise. */\n html: string | null;\n /**\n * Present only for a batch executed under a {@link MutationTransaction}: the identity the\n * session's journal bound the request to \u2014 the same on the original call and on a replay.\n */\n transaction?: MutationTransactionIdentity;\n /**\n * Present on a preview retained with {@link MutationBatchPreviewOptions.retain} and on the\n * result of {@link DocxSession.commitPreview}.\n */\n retention?: MutationPreviewRetention;\n}\n\n/** The versioned identity a transaction-aware batch result carries (issue #761). */\nexport interface MutationTransactionIdentity {\n schemaVersion: number;\n transactionId: string;\n /** SHA-256 over the canonical rendering of {@link MutationTransaction.request} plus the mode. */\n requestFingerprint: string;\n}\n\n/**\n * Retry deduplication for {@link DocxSession.executeBatch}. The session's journal replays the\n * original result for an identical retry under the same `transactionId` without executing the\n * steps again, and refuses the id for a different request with `transaction_conflict`. Because\n * the batch is composed from callbacks, `request` is the caller's own serializable description\n * of what the batch does and is what the fingerprint covers: pass the same descriptor on a retry.\n */\nexport interface MutationTransaction {\n /** Non-blank, at most 256 Unicode scalar values; scoped to this open session. */\n transactionId: string;\n /** A JSON object describing the batch (step kinds, targets, payloads). */\n request: Record<string, unknown>;\n}\n\n/** One changed top-level block in a {@link MarkdownPatch}. */\nexport interface MarkdownPatchBlock {\n /** The block's anchor id (`kind:scope:unid`). */\n anchorId: string;\n /** The block it now follows in its scope, or `null` when it is the scope's first block. */\n afterAnchorId: string | null;\n /** The block's own markdown, without the separators the full projection puts between blocks. */\n markdown: string;\n}\n\n/**\n * The projection change one mutation produced. Block-scoped: it carries the markdown of the\n * top-level blocks (body paragraphs/tables, header and footer blocks, note definitions, comments)\n * that changed or were added since the previous patch, and the ids of blocks that are gone.\n * A client keeping one entry per block applies it by deleting `removedAnchorIds`, then, for each\n * of `blocks` in order, deleting that id if present and re-inserting it after `afterAnchorId`.\n *\n * When a block-local patch cannot be exact, `fullDocument` is true and `markdown` is the whole\n * projection: an edit that renumbered a list, changed a style, edited a header or footer, or added,\n * removed or renumbered a story part or a note; the first patch after an op failed and rolled back\n * or a preview was committed; any non-`FullUnid` anchor rendering. `undo()` and `redo()` return no\n * patch: re-read the projection after them; the next patch covers only later changes. Call\n * `project()` for the whole document at any time.\n */\nexport interface MarkdownPatch {\n /** The anchor the op addressed. */\n scopeAnchorId: string;\n /** The changed blocks' markdown in document order, or the whole projection when `fullDocument`. */\n markdown: string;\n /** True when `markdown` is the whole projection; `blocks` and `removedAnchorIds` are then empty. */\n fullDocument: boolean;\n /** Blocks changed or added since the previous patch, in document order. */\n blocks: MarkdownPatchBlock[];\n /** Ids of blocks removed since the previous patch (or whose id changed). */\n removedAnchorIds: string[];\n}\n\nexport interface EditResult {\n success: boolean;\n error?: EditError;\n created: AnchorRef[];\n removed: AnchorRef[];\n modified: AnchorRef[];\n /** Deterministic structural identity map for table shape mutations. */\n tableAnchors?: TableAnchorMapping;\n patch?: MarkdownPatch;\n /** Set by the annotation ops (addAnnotation/removeAnnotation/updateAnnotation/\n * moveAnnotation) with the affected annotation id; absent for every other op. */\n annotationId?: string;\n hyperlinkId?: string;\n bookmarkName?: string;\n imageId?: string;\n}\n\nexport type HyperlinkKind = \"external\" | \"internal\";\n\nexport interface HyperlinkInfo {\n id: string;\n kind: HyperlinkKind;\n owningPartUri: string;\n scope: string;\n anchorId: string;\n span: CharSpan;\n text: string;\n target?: string;\n relationshipId?: string;\n relationshipIsExternal?: boolean;\n isBroken: boolean;\n}\n\nexport type ImageBinaryFormat = \"unknown\" | \"png\" | \"jpeg\" | \"gif\" | \"bmp\" | \"tiff\" | \"webp\";\nexport type ImageMarkupKind = \"modern_drawing\" | \"legacy_vml\" | \"unsupported_drawing\";\nexport type ImagePlacement = \"inline\" | \"floating\";\nexport type ImageWrapMode = \"none\" | \"square\" | \"tight\" | \"through\" | \"top_and_bottom\" | \"unknown\";\nexport type ImageWrapSide = \"both_sides\" | \"left\" | \"right\" | \"largest\" | \"unknown\";\nexport type ImageHorizontalReference = \"page\" | \"margin\" | \"column\" | \"character\" | \"unknown\";\nexport type ImageVerticalReference = \"page\" | \"margin\" | \"paragraph\" | \"line\" | \"unknown\";\nexport type ImageHorizontalAlignment = \"left\" | \"center\" | \"right\" | \"inside\" | \"outside\" | \"unknown\";\nexport type ImageVerticalAlignment = \"top\" | \"center\" | \"bottom\" | \"inside\" | \"outside\" | \"unknown\";\n\n/** One vertex of a tight/through wrap outline in DrawingML's 21600-unit picture space. */\nexport interface ImageWrapPoint { x: number; y: number; }\n\n/**\n * The outline text follows under tight/through wrap: a start vertex plus at least two line\n * segments. Omit it on write to get the picture rectangle; a layout read from the document\n * always carries the outline it holds.\n */\nexport interface ImageWrapPolygon { points: ImageWrapPoint[]; edited?: boolean; }\n\nexport interface FloatingImageLayout {\n horizontalRelativeFrom?: ImageHorizontalReference;\n horizontalOffsetEmu?: number | null;\n horizontalAlignment?: ImageHorizontalAlignment | null;\n verticalRelativeFrom?: ImageVerticalReference;\n verticalOffsetEmu?: number | null;\n verticalAlignment?: ImageVerticalAlignment | null;\n wrapMode?: ImageWrapMode;\n wrapSide?: ImageWrapSide;\n wrapPolygon?: ImageWrapPolygon | null;\n distanceTopEmu?: number;\n distanceBottomEmu?: number;\n distanceLeftEmu?: number;\n distanceRightEmu?: number;\n relativeHeight?: number;\n behindDocument?: boolean;\n locked?: boolean;\n layoutInCell?: boolean;\n allowOverlap?: boolean;\n rawHorizontalReference?: string;\n rawVerticalReference?: string;\n rawHorizontalPosition?: string;\n rawVerticalPosition?: string;\n rawWrapMode?: string;\n rawWrapSide?: string;\n rawRelativeSizeHorizontal?: string;\n rawRelativeSizeVertical?: string;\n rawFlagTokens?: Record<string, string>;\n}\n\nexport interface ImageInsertOptions {\n placement?: ImagePlacement;\n widthPoints?: number;\n heightPoints?: number;\n preserveAspect?: boolean;\n altText?: string | null;\n title?: string | null;\n floatingLayout?: FloatingImageLayout;\n}\n\nexport interface ImageDimensions {\n widthPoints?: number;\n heightPoints?: number;\n preserveAspect?: boolean;\n}\n\n/** Whether one image operation applies to one occurrence in the session's current mode. */\nexport interface ImageOperationSupport { operation: string; canMutate: boolean; reason?: string; }\n\nexport interface ImageOccurrence {\n id: string; markupKind: ImageMarkupKind; placement?: ImagePlacement; canMutate: boolean;\n unsupportedReason?: string; owningPartUri: string; scope: string; anchorId: string; span: CharSpan;\n relationshipId?: string; targetPartUri?: string; linkedRelationshipId?: string; linkedTarget?: string;\n isEmbedded: boolean; isLinked: boolean; isBroken: boolean; mediaFileName?: string; contentType?: string;\n format: ImageBinaryFormat; contentTypeMatchesBytes?: boolean; intrinsicWidthPixels?: number;\n intrinsicHeightPixels?: number; renderedWidthPoints?: number; renderedHeightPoints?: number;\n altText?: string; title?: string; floatingLayout?: FloatingImageLayout; floatingLayoutSupported: boolean;\n /** replace, embed_linked, set_dimensions, set_metadata, set_floating_layout and remove, each answered. */\n operations: ImageOperationSupport[];\n}\n\n/** Which operations one markup family accepts, independent of any occurrence. */\nexport interface ImageMarkupCapability { markup: string; operations: string[]; limitation?: string; }\n\nexport interface ImageFormatCapability {\n format: ImageBinaryFormat; contentType: string; canInspect: boolean; canInsert: boolean;\n canReplace: boolean; limitation?: string;\n}\n\nexport interface ImageCapabilities {\n schemaVersion: number; runtime: string; formats: ImageFormatCapability[]; operations: string[];\n mutableWrapModes: ImageWrapMode[]; horizontalReferences: ImageHorizontalReference[];\n verticalReferences: ImageVerticalReference[]; maxInputBytes: number; maxRenderedPoints: number;\n defaultDpi: number; usesHeaderParsingOnly: boolean; acceptsBinaryBytes: boolean;\n supportsNetworkFetch: boolean; supportsFileIo: boolean;\n markups: ImageMarkupCapability[]; trackedOperations: string[];\n}\n\nexport type ContentControlType = \"plain_text\" | \"rich_text\" | \"checkbox\" | \"date\"\n | \"drop_down_list\" | \"combo_box\" | \"picture\" | \"repeating_section\"\n | \"repeating_section_item\" | \"unsupported\";\nexport type ContentControlPlacement = \"inline\" | \"block\" | \"row\" | \"cell\" | \"unknown\";\nexport type ContentControlBindingPolicy = \"preserve\" | \"detach_target\";\n\n/** How a whole-control fill treats nested controls inside its target (issue #763). */\nexport type ContentControlNestedPolicy = \"refuse\" | \"preserve\" | \"replace\";\n\nexport interface ContentControlFillOptions {\n bindingPolicy?: ContentControlBindingPolicy;\n /**\n * Default `refuse`. `preserve` keeps every nested control in place and replaces only the\n * content outside them; `replace` discards the whole payload, nested controls included\n * (each is reported removed; a locked or data-bound nested control refuses).\n */\n nestedControls?: ContentControlNestedPolicy;\n /**\n * With `preserve`: plain-text fills for nested text/rich-text controls of the target, keyed\n * by their `sdt` anchor, applied in the same operation. A key that is not a nested textual\n * control, or a child that fails its own gates, fails the whole call without mutating.\n */\n childFills?: Record<string, string>;\n}\n\n/** Whether one operation would succeed on a control right now, by the gates the operation applies. */\nexport interface ContentControlOperationSupport {\n operation: \"fill_text\" | \"fill_rich_text\" | \"set_checked\" | \"set_date\" | \"select_item\"\n | \"fill_picture\" | \"add_repeating_item\" | \"remove_repeating_item\";\n /** The nested policy this entry describes, when the target contains nested controls. */\n nestedControls?: ContentControlNestedPolicy;\n canMutate: boolean;\n reason?: string;\n}\n\nexport interface ContentControlBindingInfo {\n storeItemId?: string;\n xpath?: string;\n prefixMappings?: string;\n}\n\nexport interface ContentControlInfo {\n anchorId: string;\n type: ContentControlType;\n placement: ContentControlPlacement;\n nativeId?: string;\n tag?: string;\n alias?: string;\n lock?: string;\n isShowingPlaceholder: boolean;\n isBound: boolean;\n binding?: ContentControlBindingInfo;\n owningPartUri: string;\n scope: string;\n parentAnchorId?: string;\n depth: number;\n hasValidNativeId: boolean;\n hasDuplicateNativeId: boolean;\n canMutate: boolean;\n canDetachTargetBinding: boolean;\n unsupportedReason?: string;\n text: string;\n itemValues: string[];\n /** Anchors of the controls nested anywhere inside this control's payload, in story order. */\n nestedControlAnchorIds: string[];\n /**\n * Per-operation support for this control's family, including nested-policy variants of a\n * fill when the target contains nested controls and the session's tracked-change mode.\n */\n operations: ContentControlOperationSupport[];\n}\n\nexport interface DocumentRange {\n startAnchorId: string;\n startOffset: number;\n endAnchorId: string;\n endOffset: number;\n}\n\nexport interface BookmarkRangeSegment {\n owningPartUri: string;\n scope: string;\n anchorId: string;\n span: CharSpan;\n text: string;\n}\n\nexport interface BookmarkInfo {\n name: string;\n bookmarkId: string;\n startPartUri: string;\n startScope: string;\n endPartUri?: string;\n endScope?: string;\n range?: DocumentRange;\n segments: BookmarkRangeSegment[];\n text: string;\n isPaired: boolean;\n isManaged: boolean;\n isValid: boolean;\n validationError?: string;\n}\n\n/**\n * One native Word comment, in comments-part order \u2014 see {@link DocxSession.listComments}.\n * `anchorId` addresses the definition (kind `cmt`) for updateComment/removeComment;\n * `date` is the raw `w:date` attribute string; `text` is the flattened body.\n * `parentAnchorId` and `resolved` are present when the comment has a\n * `commentsExtended.xml` entry; their absence distinguishes a legacy/flat comment from an\n * explicitly reopened one. `id` is the numeric `w:id` \u2014 the value rendered comment markup\n * carries as `data-comment-id`, which is how a highlight in the DOM is matched back to its\n * entry. Mutations still address comments by `anchorId`.\n */\nexport interface CommentListEntry {\n anchorId: string;\n /** The comment's numeric `w:comment/@w:id`; equals the `data-comment-id` of its rendered\n * highlight spans and marker. */\n id: number;\n author: string;\n initials?: string;\n date?: string;\n text: string;\n parentAnchorId?: string;\n resolved?: boolean;\n}\n\n/** Revision kind in a markup-native revision listing. A `move` entry is a linked\n * move pair \u2014 both sides resolve together. */\nexport type SessionRevisionType = \"insert\" | \"delete\" | \"move\" | \"format\" | \"structure\";\nexport type RevisionFamily =\n | \"content_insert\" | \"content_delete\" | \"move\" | \"paragraph_mark\"\n | \"row_insert\" | \"row_delete\" | \"cell_insert\" | \"cell_delete\" | \"cell_merge\"\n | \"content_control_insert\" | \"content_control_delete\"\n | \"numbering_properties_insert\" | \"numbering_change\" | \"properties_change\"\n | \"unsupported\";\nexport type RevisionResolutionStatus = \"supported\" | \"unsupported\" | \"malformed\" | \"ambiguous\";\n\n/** The explicit repairs the revision registry can perform on markup it refuses to resolve. */\nexport type RevisionRepairKind =\n | \"assign_identity\"\n | \"reattach_numbering_change\"\n | \"reattach_cell_marker\"\n | \"restore_orphan_text\"\n | \"wrap_orphan_text_as_deletion\";\n\n/** One repair the registry offers for one listed entry, and whether it can perform it. */\nexport interface RevisionRepairProposal {\n revisionId: string;\n kind: RevisionRepairKind;\n partUri: string;\n diagnostic: RevisionDiagnostic;\n /** Every native carrier the repair touches, as QName@element-path keys. */\n carriers: readonly string[];\n repairable: boolean;\n /** What the repair does, or why the package's evidence does not permit it. */\n reason: string;\n /** The request must supply `author` and `date`. */\n requiresAuthorship: boolean;\n}\n\nexport interface RevisionRepairRequest {\n revisionId: string;\n kind: RevisionRepairKind;\n author?: string;\n date?: string;\n}\n\n/** One carrier's identity before and after a repair; `newId` is empty when it was moved, not renumbered. */\nexport interface RevisionCarrierIdentity {\n carrier: string;\n oldId: string | null;\n newId: string;\n}\n\nexport interface RevisionRepairOutcome {\n revisionId: string;\n kind: RevisionRepairKind;\n partUri: string;\n identities: readonly RevisionCarrierIdentity[];\n}\n\n/** Atomic, one undo step; repaired entries get new ids, so re-list afterwards. */\nexport interface RevisionRepairResult {\n success: boolean;\n error?: EditError;\n repairs: readonly RevisionRepairOutcome[];\n modified: readonly AnchorRef[];\n}\n\nexport interface RevisionDiagnostic {\n code: string;\n message: string;\n}\n\n/**\n * One part-qualified atomic revision from the live registry. `id` is an opaque,\n * deterministic `rev2-\u2026` identity; `constituentIds` exposes the native Word ids.\n * `family` identifies the exact operation, while `type` is its coarse display class.\n * Unsafe native topology remains listed through `resolutionStatus` and `diagnostic`.\n */\nexport interface RevisionListEntry {\n id: string;\n type: SessionRevisionType;\n family: RevisionFamily;\n constituentIds: string[];\n /**\n * QName-qualified native carrier identities. Unlike `constituentIds`, these\n * distinguish revision roles which legally use the same numeric `w:id` value.\n */\n constituentKeys: string[];\n author: string;\n date?: string;\n /** The `w16du:dateUtc` timestamp, when the markup carries one. */\n dateUtc?: string;\n text: string;\n partUri: string;\n scope: string;\n anchorId?: string;\n affectedAnchors: AnchorRef[];\n resolutionStatus: RevisionResolutionStatus;\n diagnostic?: RevisionDiagnostic;\n}\n\nexport interface CharSpan {\n start: number;\n length: number;\n}\n\nexport interface FormatOp {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strike?: boolean;\n code?: boolean;\n color?: string;\n runStyle?: string;\n /** Vertical alignment: \"superscript\" | \"subscript\" | \"\" (clear). Omit to leave unchanged. */\n vertAlign?: string;\n /**\n * Font size in **points** (maps to `w:sz`/`w:szCs`, stored as half-points). Omit to leave\n * unchanged; a value <= 0 clears the explicit size. Fractional points round to a half-point.\n */\n fontSizePts?: number;\n /**\n * Run font family (maps to `w:rFonts` ascii/hAnsi/cs). Omit to leave unchanged; `\"\"` clears\n * the explicit font so the run inherits the style/default. Lets a run match a serif filing.\n */\n fontFamily?: string;\n /**\n * Text highlight colour (`w:highlight`) \u2014 one of Word's sixteen `ST_HighlightColor` names:\n * \"yellow\", \"green\", \"cyan\", \"magenta\", \"blue\", \"red\", \"darkBlue\", \"darkCyan\", \"darkGreen\",\n * \"darkMagenta\", \"darkRed\", \"darkYellow\", \"darkGray\", \"lightGray\", \"black\", \"white\". Omit to\n * leave unchanged; `\"\"` or `\"none\"` clears. Any other value fails the op (`internal_error`\n * with the message, like an invalid `vertAlign`) \u2014 Word has no free-form highlight.\n */\n highlight?: string;\n /** All capitals (`w:caps`). `true` sets it and removes `w:smallCaps` (Word's either/or rule);\n * `false` removes it; omit to leave unchanged. */\n caps?: boolean;\n /** Small capitals (`w:smallCaps`). `true` sets it and removes `w:caps`; `false` removes it;\n * omit to leave unchanged. */\n smallCaps?: boolean;\n}\n\n/** One edge of a paragraph border (`w:pBdr` top/bottom) \u2014 drives S-1 horizontal rules. */\nexport interface ParagraphBorderEdge {\n /** Border line style (`w:val`): \"single\",\"double\",\"thick\",\"dotted\",\"dashed\",\u2026 Default \"single\". */\n style?: string;\n /** Weight in eighths of a point (`w:sz`). Default 6 (\u22480.75pt); a heavy rule \u2248 18\u201324. */\n size?: number;\n /** Hex color without '#', or \"auto\". Default \"auto\". */\n color?: string;\n /** Padding between border and text, in points (`w:space`). Default 1. */\n space?: number;\n}\n\n/** List format for `DocxSession.applyListFormat` / `applyListFormatRange`. The plain numbered\n * formats render `1.` / `a.` / `i.` level text; the `*Parenthesis` variants render `(1)` /\n * `(a)` / `(i)` \u2014 same `w:numFmt`, different `w:lvlText` (the legal-drafting presets). */\nexport type ListFormat =\n | \"none\"\n | \"bullet\"\n | \"decimal\"\n | \"lowerLetter\"\n | \"upperLetter\"\n | \"lowerRoman\"\n | \"upperRoman\"\n | \"decimalParenthesis\"\n | \"lowerLetterParenthesis\"\n | \"upperLetterParenthesis\"\n | \"lowerRomanParenthesis\"\n | \"upperRomanParenthesis\";\n\n/** How `ParagraphFormatOp.lineSpacing` is interpreted (`w:spacing/@w:lineRule`): under `\"auto\"`\n * the value is in 240ths of a line (240 = single, 360 = 1.5\u00D7, 480 = double); under\n * `\"exact\"`/`\"atLeast\"` it is a height in twips (20 twips = 1pt). */\nexport type LineSpacingRule = \"auto\" | \"exact\" | \"atLeast\";\n\n/** Paragraph-level formatting for `DocxSession.setParagraphFormat`. Omit a field to leave it unchanged. */\nexport interface ParagraphFormatOp {\n /** Paragraph alignment. */\n alignment?: \"left\" | \"center\" | \"right\" | \"justify\";\n /** Adjust the left indent by this many twips (1440 = 1 inch); clamped at 0. */\n indentDelta?: number;\n /** First-line indent in twips (`w:ind/@w:firstLine`; 1440 = 1 inch). Absolute, not a delta;\n * 0 writes an explicit \"none\". Mutually exclusive with `hangingIndent` (Word's `w:ind` holds\n * one or the other) \u2014 setting this removes any hanging indent, and an op carrying both is\n * rejected with `invalid_paragraph_format`. Negatives are invalid. */\n firstLineIndent?: number;\n /** Hanging indent in twips (`w:ind/@w:hanging`; 1440 = 1 inch) \u2014 every line EXCEPT the first\n * starts this far right of the paragraph's left edge. Mutually exclusive with\n * `firstLineIndent`; setting this removes any first-line indent. Negatives are invalid. */\n hangingIndent?: number;\n /** Space above the paragraph in twips (`w:spacing/@w:before`; 20 twips = 1pt, so 240 = 12pt).\n * Absolute; negatives are invalid. */\n spacingBefore?: number;\n /** Space below the paragraph in twips (`w:spacing/@w:after`; 20 twips = 1pt). Absolute;\n * negatives are invalid. */\n spacingAfter?: number;\n /** Line spacing (`w:spacing/@w:line`). Units depend on `lineSpacingRule`: 240ths of a line\n * under `\"auto\"` (the default when the rule is omitted), twips under `\"exact\"`/`\"atLeast\"`.\n * Negatives are invalid. */\n lineSpacing?: number;\n /** How `lineSpacing` is interpreted. Only meaningful alongside `lineSpacing` \u2014 set without\n * it, the op is rejected with `invalid_paragraph_format`. */\n lineSpacingRule?: LineSpacingRule;\n /** Page-break-before: true to add, false to remove. */\n pageBreakBefore?: boolean;\n /** Top paragraph border (`w:pBdr/w:top`). Omit to leave unchanged. */\n topBorder?: ParagraphBorderEdge;\n /** Bottom paragraph border (`w:pBdr/w:bottom`) \u2014 what an S-1 horizontal rule is. Omit to leave unchanged. */\n bottomBorder?: ParagraphBorderEdge;\n /** Remove all paragraph borders before applying any top/bottom border in this op. */\n clearBorders?: boolean;\n}\n\n/**\n * Which header/footer story `DocxSession.setHeaderText`/`setFooterText` targets, mapping to the\n * OOXML `w:type`: `\"default\"` (all pages), `\"first\"` (first-page-only; sets `w:titlePg`),\n * `\"even\"` (even pages; sets `w:evenAndOddHeaders`).\n */\nexport type HeaderFooterKind = \"default\" | \"first\" | \"even\";\n\n/**\n * Options for {@link DocxSession.insertTableOfContents} (issue #607). Every field is a typed switch\n * on the underlying `TOC` field, so a caller never writes `\\o \"1-3\"` by hand \u2014 a malformed switch\n * string renders as nothing in Word, silently, which is the failure these exist to prevent.\n */\nexport interface TableOfContentsOptions {\n /** Heading levels to list (`\\o`): a level or a range within 1-9, e.g. `\"1-3\"`. Default `\"1-3\"`. */\n levels?: string;\n /** Make each entry a hyperlink to its heading (`\\h`). Default true. */\n hyperlinks?: boolean;\n /** Hide the leader tab and page numbers in Word's web view (`\\z`). Default true. */\n hideTabAndPageNumbersInWeb?: boolean;\n /** Include paragraphs with an outline level but no heading style (`\\u`). Default true. */\n useOutlineLevels?: boolean;\n /** Heading above the table, in Word's `TOCHeading` style. `null` or `\"\"` inserts no heading.\n * Default `\"Contents\"`. */\n title?: string | null;\n /** Right-aligned dot-leader tab stop in twips. Default 9350 (US Letter, one-inch margins). */\n rightTabPos?: number;\n}\n\n/** Options for {@link DocxSession.insertTableOfFigures}. A table of figures is a `TOC` field\n * selecting by caption label rather than outline level \u2014 Word's own encoding. */\nexport interface TableOfFiguresOptions {\n /** The caption label whose captions to list (`\\c`) \u2014 `\"Figure\"`, `\"Table\"`, `\"Exhibit\"`. */\n captionLabel?: string;\n /** Make each entry a hyperlink to its caption (`\\h`). Default true. */\n hyperlinks?: boolean;\n /** Right-aligned dot-leader tab stop in twips. Default 9350. */\n rightTabPos?: number;\n}\n\n/** Word's fixed table-of-authorities categories. */\nexport type AuthorityCategory =\n | \"cases\"\n | \"statutes\"\n | \"other_authorities\"\n | \"rules\"\n | \"treatises\"\n | \"regulations\"\n | \"constitutional_provisions\";\n\n/** Options for {@link DocxSession.insertTableOfAuthorities}. */\nexport interface TableOfAuthoritiesOptions {\n /** Which category of authority to list (`\\c`). Default `\"cases\"`. */\n category?: AuthorityCategory;\n /** Make each entry a hyperlink to its citation (`\\h`). Default true. */\n hyperlinks?: boolean;\n /** Separator between an entry and its page numbers (`\\e`), e.g. a tab. Default: Word's own. */\n entryPageSeparator?: string;\n /** Right-aligned dot-leader tab stop in twips. Default 9350. */\n rightTabPos?: number;\n}\n\n/** Which page-number field `DocxSession.insertPageNumberField` emits: `\"currentPage\"` \u2192 PAGE,\n * `\"totalPages\"` \u2192 NUMPAGES, `\"pageOfTotal\"` \u2192 Word's \"Page X of Y\" gallery entry (the text\n * `Page `, a PAGE field, ` of `, a NUMPAGES field, every run inheriting the paragraph's last run\n * formatting). */\nexport type PageNumberField = \"currentPage\" | \"totalPages\" | \"pageOfTotal\";\n\n/**\n * Section-level page-numbering setup for {@link DocxSession.setPageNumbering} \u2014 the `w:pgNumType`\n * element, which is what Word's *Format Page Numbers\u2026* dialog writes. Each field is tri-state: an\n * omitted field leaves that attribute exactly as it is. Use\n * {@link DocxSession.clearPageNumbering} to remove them.\n *\n * This governs how a **plain** PAGE field renders anywhere in the section, which is the normal way\n * to number pages: set the section once, insert unswitched fields. It is distinct from the\n * per-field `\\*` switch {@link DocxSession.insertPageNumberField} can stamp, which overrides the\n * section for that one field.\n */\nexport interface PageNumberingOp {\n /** The page number this section starts at (`w:start`) \u2014 e.g. `1` to restart at a section break.\n * Omitted leaves it unchanged; absent means the section continues the previous one. */\n start?: number;\n /** This section's page-number format (`w:fmt`) \u2014 e.g. `\"lowerRoman\"` for `i, ii, iii` front\n * matter. Omitted leaves it unchanged; absent means Word's default `1, 2, 3`. `\"bullet\"` is\n * rejected \u2014 pages cannot be bulleted. */\n format?: NumberFormat;\n}\n\n/**\n * Page geometry for {@link DocxSession.setPageSetup} \u2014 the `w:pgSz` / `w:pgMar` of the governing\n * `w:sectPr`, i.e. what Word's *Page Setup* dialog writes. Every field is tri-state: an omitted\n * field leaves that attribute exactly as it is. All values are twips (1440 = 1 inch). Read the\n * current values back from {@link SectionInfo}.\n *\n * Validation runs against the section's effective values after the op: width and height must be\n * positive, margins and header/footer distances non-negative, and `left + right < width`,\n * `top + bottom < height`; a violation fails with `invalid_page_setup` and touches nothing.\n */\nexport interface PageSetupOp {\n /** Page width (`w:pgSz/@w:w`). */\n pageWidthTwips?: number;\n /** Page height (`w:pgSz/@w:h`). */\n pageHeightTwips?: number;\n /** Orientation (`w:pgSz/@w:orient`). `true` writes `landscape` and \u2014 when no explicit size is\n * given and the page is currently taller than wide \u2014 swaps width and height; `false` removes\n * the attribute and swaps back when the page is wider than tall. With an explicit size only\n * the attribute is written. */\n landscape?: boolean;\n /** Top margin (`w:pgMar/@w:top`). */\n marginTopTwips?: number;\n /** Bottom margin (`w:pgMar/@w:bottom`). */\n marginBottomTwips?: number;\n /** Left margin (`w:pgMar/@w:left`). */\n marginLeftTwips?: number;\n /** Right margin (`w:pgMar/@w:right`). */\n marginRightTwips?: number;\n /** Header distance from the page's top edge (`w:pgMar/@w:header`). */\n headerDistanceTwips?: number;\n /** Footer distance from the page's bottom edge (`w:pgMar/@w:footer`). */\n footerDistanceTwips?: number;\n}\n\n/**\n * The browser editor's render profile, passed as one JSON object to the `RenderEditorHtml` /\n * `RenderEditorBlocksHtml` / `RenderEditorBlockHtml` bridge exports. Defaults match the editor's\n * first paint: `\"docx-\"`, no fabricated classes, continuous, scale 1, revisions and comments off.\n */\nexport interface EditorRenderOptions {\n /** CSS class prefix for the document's own classes. Default `\"docx-\"`. */\n cssPrefix?: string;\n /** Emit fabricated per-run CSS classes instead of inline styles. Default false. */\n fabricateClasses?: boolean;\n /** Paginated (page-box) output with headers/footers. Default false. Full-document render only. */\n paginated?: boolean;\n /** Pagination scale. Default 1. Full-document render only. */\n scale?: number;\n /** Render tracked changes as redlines instead of accepting them. Default false. */\n renderTrackedChanges?: boolean;\n /** Render native Word comments inline: `comment-highlight` spans carrying `data-comment-id`\n * around every run inside a comment range, `comment-marker` anchors at each reference. The\n * ids match {@link CommentListEntry.id}. Default false, which renders exactly as the\n * comment-less `RenderHtml` / `RenderBlockHtml` do. */\n comments?: boolean;\n}\n\n/** Options for `DocxSession.insertTable`. */\nexport interface TableInsertOptions {\n /** Emit an invisible layout table (explicit \"none\" borders) \u2014 the S-1 multi-column blocks. */\n borderless?: boolean;\n /** Row-major markdown for each cell (row 0 left\u2192right, then row 1, \u2026). Short/omitted \u21D2 empty cells. */\n cellContents?: string[];\n /** Alignment applied to every cell paragraph (S-1 columns are centered). */\n cellAlignment?: \"left\" | \"center\" | \"right\" | \"justify\";\n /** Per-column widths in twips (one per column, left\u2192right). Omit for equal columns; a list\n * whose length != the column count is rejected. Drives unequal layouts like the S-1's\n * wide-left / narrow-right filing-header row. */\n columnWidths?: number[];\n}\n\nexport type TableVerticalMergeRole = \"none\" | \"restart\" | \"continue\";\nexport type TableAnchorEntityKind = \"table\" | \"row\" | \"column\" | \"cell\";\n\nexport interface TableCellMetadata {\n anchor: AnchorRef;\n tableAnchorId: string;\n rowAnchorId: string;\n rowIndex: number;\n columnIndex: number;\n rowSpan: number;\n columnSpan: number;\n verticalMerge: TableVerticalMergeRole;\n /** Direct cell paragraphs only; nested-table paragraphs belong to their own cells. */\n paragraphAnchors: AnchorRef[];\n}\n\nexport interface TableRowMetadata {\n anchor: AnchorRef;\n tableAnchorId: string;\n rowIndex: number;\n gridBefore: number;\n gridAfter: number;\n cells: TableCellMetadata[];\n}\n\nexport interface TableColumnMetadata {\n anchor: AnchorRef;\n tableAnchorId: string;\n columnIndex: number;\n widthTwips: number;\n /** True when an absent/underspecified tblGrid required a read-only coordinate identity. */\n isVirtual: boolean;\n cellAnchorIds: string[];\n}\n\nexport interface TableMetadata {\n anchor: AnchorRef;\n columns: TableColumnMetadata[];\n rows: TableRowMetadata[];\n}\n\nexport interface TableMetadataResult {\n success: boolean;\n error?: EditError;\n metadata?: TableMetadata;\n}\n\nexport interface TableCellResolutionResult {\n success: boolean;\n error?: EditError;\n cell?: TableCellMetadata;\n}\n\nexport interface TableAnchorLocation {\n anchor: AnchorRef;\n entityKind: TableAnchorEntityKind;\n rowIndex?: number;\n columnIndex?: number;\n rowSpan?: number;\n columnSpan?: number;\n isVirtual?: boolean;\n}\n\nexport interface TableAnchorMapping {\n retained: { before: TableAnchorLocation; after: TableAnchorLocation }[];\n added: TableAnchorLocation[];\n invalidated: TableAnchorLocation[];\n}\n\nexport type TableRowHeightRule = \"auto\" | \"atLeast\" | \"exact\";\n\nexport interface TableRowOptions {\n repeatHeader?: boolean;\n allowBreakAcrossPages?: boolean;\n /** Zero removes an explicit height. */\n heightTwips?: number;\n heightRule?: TableRowHeightRule;\n}\n\n/** Which table edges `DocxSession.setTableBorders` targets: `\"outside\"` = top/left/bottom/right,\n * `\"inside\"` = the inner grid lines (`w:insideH`/`w:insideV`), `\"all\"` = both. */\nexport type TableBorderScope = \"all\" | \"outside\" | \"inside\";\n\n/** Shading granularity for `DocxSession.setCellShading`: the one cell the anchor sits in, or\n * every cell of its row (header-row banding). */\nexport type TableShadingScope = \"cell\" | \"row\";\n\n/** What `DocxSession.mergeCells` does with the content of the cells a merge absorbs:\n * `\"append\"` (default) moves their non-empty blocks into the surviving cell \u2014 lossless;\n * `\"discard\"` drops them; `\"reject\"` fails the merge (`invalid_table_merge`) when any absorbed\n * cell is non-empty. */\nexport type TableMergeContent = \"append\" | \"discard\" | \"reject\";\n\n/** Border specification for `DocxSession.setTableBorders`. Written as explicit `w:tblBorders`\n * edges (overriding style-inherited borders); edges outside `scope` are left untouched. */\nexport interface TableBorderSpec {\n /** Which edges to write. Default `\"all\"`. */\n scope?: TableBorderScope;\n /** Border line style (`w:val`): `\"single\"`, `\"double\"`, `\"thick\"`, `\"dotted\"`, `\"dashed\"`, \u2026 \u2014\n * or `\"none\"` to remove the targeted edges. Default `\"single\"`. */\n style?: string;\n /** Border weight in eighths of a point (`w:sz`). Default 4 (= 0.5pt). */\n size?: number;\n /** Border color as a hex RRGGBB triplet without '#', or `\"auto\"`. Default `\"auto\"`. */\n color?: string;\n}\n\nexport interface DocxSessionSettings {\n /**\n * Maximum undo steps retained. Default 20 (was 50).\n *\n * Each step is a full snapshot of every snapshot-scoped part, so this is a STEP count and not\n * a memory bound \u2014 the cost of one step scales with the document. Use `undoMemoryBudgetBytes`\n * to bound the heap.\n */\n undoDepth?: number;\n /**\n * Approximate ceiling, in bytes, on memory held by undo/redo snapshots. Default 134217728\n * (128 MiB). When exceeded the oldest history is discarded, so on a large document undo may\n * not reach the full `undoDepth`; one step is always retained. Set to 0 to bound by depth\n * alone (the pre-9.10 behavior).\n */\n undoMemoryBudgetBytes?: number;\n validateRawOps?: boolean;\n trackedChanges?: \"accept\" | \"render_inline\" | \"strip_deletions\";\n revisionAuthor?: string;\n /**\n * When false (default), `save()` strips the projector's internal `PtOpenXml:Unid`\n * attributes before serializing \u2014 they aren't OOXML schema, and persisting them\n * bloats large documents significantly (~700 KB on a 100-page DOCX). Set to true\n * only when anchor ids must survive a save/reopen round trip.\n */\n persistAnchorIds?: boolean;\n /**\n * When true, ReplaceText / ReplaceTextRange / ReplaceMatch payloads have ASCII\n * `\"` and `'` converted to typographic curly quotes (`\u201C \u201D \u2018 \u2019`) based on\n * context \u2014 open at start / after whitespace / after open-bracket, close\n * elsewhere. Avoids the cosmetic regression where a replacement lands as\n * straight-quoted text adjacent to surrounding already-curly text. Default false.\n */\n smartQuotes?: boolean;\n /**\n * When false, mutation EditResults omit the markdown patch and skip the per-op\n * scope re-projection that builds it \u2014 the fast path for clients that re-render\n * from HTML (the browser editor) rather than consuming markdown patches.\n * Default true.\n */\n emitMarkdownPatch?: boolean;\n /**\n * When `true` (default), the session projects the document at construction\n * time so {@link DocxSession.getDiff} can compare initial vs. current, and\n * retains the exact opening package for `getSemanticChanges()`.\n * Set to `false` to skip the upfront projection plus package-copy cost if you\n * do not plan to call either comparison API.\n */\n captureInitialProjection?: boolean;\n /**\n * Record the evidence a delivery change receipt needs as edits execute (issue #748): the\n * exact package before and after every version step, each batch's described request,\n * transaction ids, and undo/redo lineage. {@link DocxSession.buildDeliveryReceipt} then mints\n * a verifiable receipt. Default false: every version step serializes a clean package copy\n * and retention holds them (bounded: 256 states / 512 MiB) until delivery. Requires\n * `captureInitialProjection`.\n */\n captureDeliveryEvidence?: boolean;\n}\n\n/** One top-level render unit in a {@link RenderPlan}: a body block (`p`/`h`/`li`),\n * one whole table (`tbl`), or one footnote/endnote definition (`fn`/`en`). */\nexport interface RenderUnit {\n id: string;\n kind: string;\n /** Content signature for change detection (leaf blocks omit it). */\n sig?: string;\n /** Index of the section wrapper (`[data-section-index]`) the unit renders into. */\n section?: number;\n /** Ordinal of the border box the renderer groups adjacent bordered paragraphs into; units\n * sharing a group render inside one wrapper, so a windowed mount never splits one. */\n group?: number;\n}\n\n/** Ordered top-level render units per scope container \u2014 the authority for \"what\n * blocks exist, in what order\" that the incremental reconciler diffs against. */\nexport interface RenderPlan {\n body: RenderUnit[];\n footnotes: RenderUnit[];\n endnotes: RenderUnit[];\n}\n\n/** One footnote/endnote in citation order. `id` is the note's `w:id`; `ordinal`\n * is its 1-based citation position \u2014 which IS its displayed number. */\nexport interface NoteListEntry {\n id: string;\n defAnchorId: string;\n ordinal: number;\n}\n\nexport interface DocxSessionProjection {\n markdown: string;\n anchorIndex: Record<string, {\n partUri: string;\n unid: string;\n kind: string;\n scope: string;\n textPreview: string;\n }>;\n /** Present only when projectAnchor requested citations. */\n pageCitations?: Record<string, PageCitation>;\n}\n\nexport interface PageCitationRequest {\n documentVersion: number;\n rendererFingerprint: string;\n}\n\nexport type PageCitationUnavailableReason =\n | \"no_page_map\"\n | \"continuous_mode\"\n | \"stale_document_version\"\n | \"renderer_fingerprint_mismatch\"\n | \"anchor_not_mapped\";\n\nexport interface PageCitationFragment {\n fragmentId: string;\n anchorId: string;\n fragmentIndex: number;\n pageNumber: number;\n geometry: { x: number; y: number; width: number; height: number };\n story: \"body\" | \"header\" | \"footer\" | \"footnote\" | \"endnote\" | \"comment\";\n inTableCell: boolean;\n}\n\nexport interface PageCitationPage {\n pageNumber: number;\n pageInSection: number;\n width: number;\n height: number;\n sectionIndex?: number;\n pageName: string;\n}\n\nexport interface PageCitation {\n anchorId: string;\n availability: \"available\" | \"unavailable\";\n unavailableReason?: PageCitationUnavailableReason;\n documentVersion: number;\n rendererFingerprint: string;\n pages: PageCitationPage[];\n fragments: PageCitationFragment[];\n}\n\nexport interface PageMapRegistrationResult {\n success: boolean;\n error?: \"unsupported_schema_version\" | \"stale_document_version\" | \"renderer_fingerprint_mismatch\" | \"invalid_map\";\n message?: string;\n}\n\nexport interface PageMapStatus {\n availability: \"available\" | \"unavailable\";\n unavailableReason?: PageCitationUnavailableReason;\n documentVersion: number;\n rendererFingerprint?: string;\n mode?: \"paginated\" | \"continuous\";\n}\n\n/**\n * Per-fragment visible formatting reported by {@link DocxSession.grep}.\n */\nexport interface RunFormatting {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strike: boolean;\n code: boolean;\n color?: string;\n hyperlinkUrl?: string;\n runStyle?: string;\n}\n\n/**\n * One piece of a {@link TextMatch} that came from a single `<w:r>` run.\n */\nexport interface RunFragment {\n /** PtOpenXml:Unid of the `w:r` element this fragment came from. */\n unid: string;\n /** The text from this run that participates in the match. */\n text: string;\n /** Character offset + length of this fragment inside the run's flat text. */\n spanInElement: CharSpan;\n /** Visible formatting of the run this fragment came from. */\n formatting: RunFormatting;\n}\n\n/**\n * A single match returned by {@link DocxSession.grep}. The match always lives\n * within one block-level element.\n */\nexport interface TextMatch {\n text: string;\n enclosingAnchor: AnchorRef;\n span: CharSpan;\n fragments: RunFragment[];\n contextBefore: string;\n contextAfter: string;\n /** Regex capture groups; index 0 is always the whole match. */\n groups: string[];\n /** Present only when grep requested a citation for this exact render. */\n citation?: PageCitation;\n}\n\n/**\n * One block's contribution to a {@link CrossBlockMatch}. The slice's `fragments`\n * list is empty when the match touches an empty paragraph \u2014 the slice is still\n * recorded so callers can see the match crossed the empty block.\n */\nexport interface BlockSlice {\n anchor: AnchorRef;\n /** Character offset + length of the slice within the block's own flat text. */\n spanInBlock: CharSpan;\n /** Run fragments contributing to this slice, in document order. */\n fragments: RunFragment[];\n}\n\n/**\n * A single match returned by {@link DocxSession.grepCrossBlock}. The match may\n * span multiple adjacent block-level elements (paragraphs/headings/list items)\n * under the same parent container. `slices` is the per-block breakdown;\n * `enclosingAnchors` lists every block the match touches, in document order.\n *\n * Block boundaries appear in `text` / `contextBefore` / `contextAfter` as\n * single `\\n` characters.\n */\nexport interface CrossBlockMatch {\n text: string;\n enclosingAnchors: AnchorRef[];\n slices: BlockSlice[];\n contextBefore: string;\n contextAfter: string;\n /** Regex capture groups; index 0 is always the whole match. */\n groups: string[];\n /** One per enclosingAnchors entry when requested. */\n citations?: PageCitation[];\n}\n\n/**\n * Options for {@link DocxSession.insertCrossReference} \u2014 each flag is one of the REF\n * field's switches: `\\r` (reference the target's auto-number), `\\h` (hyperlink),\n * `\\p` (relative position, cached as \"above\"/\"below\").\n */\nexport interface CrossReferenceOptions {\n referenceNumber?: boolean;\n hyperlink?: boolean;\n includePosition?: boolean;\n}\n\n/**\n * Options for {@link DocxSession.replaceTextRange}.\n */\nexport interface ReplaceOptions {\n /** Case-insensitive matching for the literal `find` needle. */\n ignoreCase?: boolean;\n /** Cap the number of replacements; omitted = unlimited. */\n maxReplacements?: number;\n /** Require exactly this many occurrences before applying any replacement. */\n expectedMatchCount?: number;\n /** Optional document/anchor guards evaluated before searching. */\n preconditions?: MutationPreconditions;\n}\n\n/**\n * Categories of bracketed placeholders {@link DocxSession.findPlaceholders} recognizes.\n *\n * - `blank_fill` \u2014 `[___]` or `$[___]` value slots\n * - `alternative_clause` \u2014 `[entire clause text]`\n * - `instruction` \u2014 `[insert X]`, `[specify Y]`, `[*italicized hint*]`\n */\nexport type PlaceholderKind = \"blank_fill\" | \"alternative_clause\" | \"instruction\";\n\n/**\n * Numeric flag layout matching the .NET `PlaceholderKinds` enum. Combine with bitwise OR.\n */\nexport const PlaceholderKinds = {\n BlankFill: 1,\n AlternativeClause: 2,\n Instruction: 4,\n All: 7,\n} as const;\n\n/**\n * Numeric flag layout matching the .NET `DiffFormat` enum. Use with\n * {@link DocxSession.getDiff}.\n *\n * - `Json` (default) \u2014 anchor-keyed structured diff. Returns a `DiffEntry[]`.\n * - `Unified` \u2014 `patch(1)`-compatible unified diff over the markdown projection.\n * Returns a single string (`\"\"` when nothing changed).\n * - `SideBySide` \u2014 two-column human-review diff (`diff -y` style) over the\n * markdown projection. Returns a single string.\n */\nexport const DiffFormat = {\n Json: 0,\n Unified: 1,\n SideBySide: 2,\n} as const;\n\n/**\n * A single anchor-keyed change in the diff between an initial and current projection.\n */\nexport interface DiffEntry {\n op: \"delete\" | \"insert\" | \"modify\";\n anchorId: string;\n /** Pre-change text content for delete/modify; absent for insert. */\n before?: string;\n /** Post-change text content for insert/modify; absent for delete. */\n after?: string;\n}\n\n/**\n * Aggregate snapshot of edit-state introspection signals returned by\n * {@link DocxSession.getEditSummary}.\n */\nexport interface EditSummary {\n totalAnchors: number;\n remainingPlaceholders: TemplatePlaceholder[];\n bareUnderscoreRuns: TextMatch[];\n footnoteCount: number;\n inlineFootnoteRefCount: number;\n commentCount: number;\n}\n\n/**\n * Numeric flag layout matching the .NET `ContextBoundary` enum. Controls\n * how `Grep` / `GrepCrossBlock` / `FindPlaceholders` decide where to stop\n * walking outward when computing `TextMatch.contextBefore` / `contextAfter`.\n *\n * - `Char` (default) \u2014 truncate at `contextChars`. Matches legacy behavior.\n * - `Bracket` \u2014 stop at `[` or `]`. Use for template fills: each placeholder's\n * context is unambiguously its own even when multiple placeholders crowd\n * into one sentence.\n * - `Sentence` \u2014 stop at `.`, `!`, `?`, `:`, `;`.\n * - `Comma` \u2014 stop at `,`. For matches inside enumerations.\n */\nexport const ContextBoundary = {\n Char: 0,\n Bracket: 1,\n Sentence: 2,\n Comma: 3,\n} as const;\n\nexport interface TemplatePlaceholder {\n kind: PlaceholderKind;\n /** For `instruction` placeholders: the inner text with surrounding brackets/asterisks stripped. */\n hint?: string;\n match: TextMatch;\n /**\n * Additional plausible classifications when the primary `kind` is borderline.\n * Empty by default. The classic case is a long bracketed clause that happens\n * to contain a `_______` blank: primary `kind` stays `\"blank_fill\"`\n * (back-compat) and `alternativeKinds` contains `\"alternative_clause\"`.\n */\n alternativeKinds: PlaceholderKind[];\n}\n\n/**\n * Options for {@link DocxSession.fillPlaceholders}.\n */\nexport interface FillOptions {\n /** Which placeholder kinds to fill. Defaults to `PlaceholderKinds.All` so the\n * picker is invoked for every kind in the doc. Narrow with e.g.\n * `PlaceholderKinds.BlankFill | PlaceholderKinds.Instruction` to ignore\n * bracketed alternative clauses. */\n kinds?: number;\n /** Which package parts to scan. Defaults to body (1). */\n scope?: number;\n /** Max iteration passes for multi-pass nested-bracket scenarios. Default 8. */\n maxPasses?: number;\n /** When the match starts with `$` and the picker's return value doesn't,\n * preserve the `$` by prepending it. Default true. */\n preserveDollarPrefix?: boolean;\n /** Cap on `contextBefore` / `contextAfter` length on each side. Default 80. */\n contextChars?: number;\n /** Where to stop walking outward when computing context. Numeric layout\n * matching {@link ContextBoundary}. Default `Char` (0). */\n boundary?: number;\n /** When the picker returns an empty string (and after `$`-prefix preservation\n * has been applied), look at the chars immediately adjacent to the placeholder\n * span and absorb surrounding whitespace / leading-space-before-punctuation /\n * matched-brackets so the dropped placeholder doesn't leave cosmetic\n * artifacts. Default `false` (preserve the literal-delete behavior).\n *\n * Rules: whitespace on both sides collapses to one space; whitespace before\n * and clause-terminating punctuation (`. , ; : ! ?`) after drops the leading\n * space; matched open/close brackets (`()` `[]` `{}`) on either side drop\n * both. NBSP / narrow NBSP / thin space are treated as whitespace.\n *\n * Caveat: `$`-prefix preservation runs first, so a picker returning `\"\"` for\n * `$[xxx]` with `preserveDollarPrefix: true` (default) ends up replacing with\n * `\"$\"` and coalescing is skipped. Set `preserveDollarPrefix: false` when you\n * want the `$` to drop along with the brackets. */\n coalesceWhitespaceAroundEmptyFill?: boolean;\n}\n\n/**\n * Aggregate result returned by {@link DocxSession.fillPlaceholders}.\n *\n * `skipped` counts placeholders the picker returned null for in the first pass\n * that saw them \u2014 it stays > 0 even if later passes finished those same\n * placeholders. Use `stillPresent` (post-loop document state) for the\n * trustworthy \"is the template done?\" check; `skipped > 0 && stillPresent === 0`\n * means \"picker said no the first time but later passes resolved it.\"\n */\nexport interface BulkEditResult {\n filled: number;\n skipped: number;\n /** Number of placeholders matching `options.kinds` in `options.scope` that\n * remain in the document after the final pass. `0` means the template is\n * fully filled for the requested kinds/scope. */\n stillPresent: number;\n passes: number;\n unfilled: TemplatePlaceholder[];\n errors: EditError[];\n}\n\n/**\n * Options for {@link DocxSession.grep}.\n *\n * `regexOptions` and `scope` use the numeric flag layouts of the .NET\n * `System.Text.RegularExpressions.RegexOptions` and `ProjectionScopes` enums.\n * Common values:\n * - `RegexOptions.IgnoreCase = 1`\n * - `RegexOptions.Multiline = 2`\n * - `ProjectionScopes.Body = 1`, `Headers = 2`, `Footers = 4`,\n * `Footnotes = 8`, `Endnotes = 16`, `Comments = 32`, `All = 63`.\n */\nexport interface GrepOptions {\n regexOptions?: number;\n scope?: number;\n contextChars?: number;\n /**\n * Whitespace handling. Numeric layout matching the .NET `WhitespaceMode` enum:\n * - 0 = Preserve (default; match against the document's original characters)\n * - 1 = Normalize (fold NBSP / narrow-NBSP / thin-space to ASCII space before matching)\n */\n whitespace?: number;\n /**\n * Where to stop walking outward when computing `TextMatch.contextBefore` /\n * `contextAfter`. Numeric layout matching the .NET `ContextBoundary` enum;\n * use the {@link ContextBoundary} const. Default `Char` (0) \u2014 truncate at\n * `contextChars`.\n */\n boundary?: number;\n /** Attach citations only if this exact registered layout is still valid. */\n citation?: PageCitationRequest;\n /** Return at most this many matches, in document order. Omitted returns them all. */\n maxResults?: number;\n}\n\n/**\n * Narrows {@link DocxSession.listRevisions} to the entries matching every field set here.\n * `author`, `changeType` (the entry's `type`), `family` and `resolutionStatus` ignore case;\n * `partUri` is exact.\n */\nexport interface RevisionListFilter {\n author?: string;\n changeType?: string;\n family?: string;\n resolutionStatus?: string;\n partUri?: string;\n}\n\n/**\n * Options that tune the `findBy*` helpers on {@link DocxSession}. Mirrors the\n * .NET `FindOptions` record; wire keys are already camelCase, so this object is\n * serialized straight to the bridge. Omit it (or pass `{}`) for the defaults\n * (case-sensitive, whitespace-preserving, all scopes, no kind filter).\n */\nexport interface FindOptions {\n /** Case-insensitive matching. */\n ignoreCase?: boolean;\n /** Fold NBSP / narrow-NBSP / thin-space to ASCII space before matching. */\n ignoreWhitespace?: boolean;\n /** Only return anchors of this kind (e.g. `\"h\"` for headings, `\"p\"` for paragraphs). */\n kindFilter?: string;\n /**\n * Coarse-grained scope flag set (Body / Headers / Footers / Footnotes /\n * Endnotes / Comments). Numeric layout matching the .NET `ProjectionScopes`\n * flags enum; use {@link ProjectionScopes}. Defaults to all scopes.\n */\n scopes?: number;\n /**\n * Target a single named package part (e.g. `\"hdr1\"`). Prefer {@link scopes}\n * for whole-category filtering; this is for the rare single-part case.\n */\n scopeFilter?: string;\n /** Attach citations only if this exact registered layout is still valid. */\n citation?: PageCitationRequest;\n}\n\n/**\n * Resolved location of an anchor \u2014 what {@link DocxSession.findByAnnotation} and\n * the other discovery helpers return. The shape is {@link AnchorRef} plus the\n * `partUri` of the package part the element lives in (useful for callers that\n * walk the underlying OOXML directly).\n */\nexport interface AnchorTargetRef extends AnchorRef {\n partUri: string;\n /** First ~80 characters of the element's flat text \u2014 for previewing/picking anchors. */\n textPreview: string;\n /** Resolved auto-numbering prefix (e.g. \"1.\", \"First\") when the element carries\n * numbering. Absent otherwise. See {@link MarkdownAnchorTarget.autoNumberPrefix}. */\n autoNumberPrefix?: string;\n /** Present only when the discovery call requested an exact page citation. */\n citation?: PageCitation;\n}\n\n/**\n * The shape returned by {@link DocxSession.getAnchorInfo}.\n * Use {@link MarkdownAnchorTarget} when iterating a full projection \u2014 it\n * includes the same fields plus `unid` and `partUri`.\n */\nexport interface AnchorInfo {\n id: string;\n kind: string;\n scope: string;\n textPreview: string;\n /** Exact live subtree hash suitable for expectedContentHash. */\n contentHash: string;\n /** Exact (untruncated) reader-visible text suitable for expectedText. */\n visibleText: string;\n /** Resolved auto-numbering prefix (e.g. \"1.\", \"First\") when the element carries\n * numbering. Absent for un-numbered paragraphs or non-paragraph kinds. */\n autoNumberPrefix?: string;\n}\n\n/** Six list formats supported by the list write surface (decimal, upperLetter,\n * lowerLetter, upperRoman, lowerRoman, bullet). Surfaced on\n * {@link ListMembership.format} as a string union (mirrors the JSON wire format). */\nexport type NumberFormat =\n | \"decimal\"\n | \"upperLetter\"\n | \"lowerLetter\"\n | \"upperRoman\"\n | \"lowerRoman\"\n | \"bullet\";\n\n/** Numbering facts for a list-item paragraph. Returned by\n * {@link DocxSession.getListMembership} and surfaced as {@link BlockMetadata.list}. */\nexport interface ListMembership {\n /** Stable paragraph anchor accepted unchanged by every list mutation method. */\n anchorId: string;\n /** The w:numId the paragraph belongs to (the w:num instance). */\n numId: number;\n /** The w:abstractNumId the paragraph's w:num points at. */\n abstractNumId: number;\n /** The paragraph's level (w:ilvl), 0-8. */\n level: number;\n /** Resolved format for this level. */\n format: NumberFormat;\n /** Always true for a paragraph carrying w:numPr (inline or via style). */\n isAutoNumbered: boolean;\n /** True when the w:numPr is inherited from the paragraph's style chain. */\n fromStyle: boolean;\n /** Start-override from w:lvlOverride/w:startOverride for this level, if any. */\n startOverride?: number;\n /** Level definition's w:start value (1 when omitted). */\n start: number;\n /** Marker template such as \"%1.\" or \"(%2)\". */\n levelText?: string;\n leftIndentTwips?: number;\n rightIndentTwips?: number;\n firstLineIndentTwips?: number;\n hangingIndentTwips?: number;\n /** Resolved label (e.g. \"1.\", \"(a)\") \u2014 same value surfaced via AnchorInfo.autoNumberPrefix. */\n generatedLabel?: string;\n}\n\n/** Block-level structural metadata. Returned by {@link DocxSession.getBlockMetadata}. */\nexport interface BlockMetadata {\n anchorId: string;\n kind: string;\n scope: string;\n styleId?: string;\n styleName?: string;\n /** 0-based outline level (Word convention). */\n outlineLevel?: number;\n list?: ListMembership;\n /** True when any descendant w:r carries a non-empty w:rPr. */\n hasInlineFormatting: boolean;\n}\n\n/**\n * A `w:headerReference`/`w:footerReference` on a section: the story kind it supplies and the\n * URI of the part holding it. Maps a {@link HeaderFooterKind} to a part \u2014 and thence to that\n * part's projection anchors, which carry the same `partUri` \u2014 instead of guessing from\n * part-collection order, which carries no kind information.\n */\nexport interface HeaderFooterRef {\n kind: HeaderFooterKind;\n partUri: string;\n /** True when this section declares no reference of `kind` and the story is INHERITED from the\n * nearest preceding section that does (ECMA-376 \u00A717.6.17). Editing it edits the shared part. */\n inherited: boolean;\n}\n\n/** Page-layout snapshot for the w:sectPr that governs an anchor.\n * Returned by {@link DocxSession.getSectionInfo}. */\nexport interface SectionInfo {\n /** Body anchor used for the lookup; accepted unchanged by section mutation methods. */\n anchorId: string;\n sectionUnid: string;\n pageWidthTwips: number;\n pageHeightTwips: number;\n landscape: boolean;\n marginTopTwips: number;\n marginBottomTwips: number;\n marginLeftTwips: number;\n marginRightTwips: number;\n /** Header distance from the page's top edge (`w:pgMar/@w:header`); Word's default 720 when\n * the attribute is absent. */\n headerDistanceTwips: number;\n /** Footer distance from the page's bottom edge (`w:pgMar/@w:footer`); Word's default 720 when\n * the attribute is absent. */\n footerDistanceTwips: number;\n /** Word's \"Different first page\" flag \u2014 true when the governing `w:sectPr` carries an\n * on-valued `w:titlePg`, so the section's first-page stories actually render. Toggle with\n * {@link DocxSession.setHeaderFooterKindEnabled}. */\n titlePage: boolean;\n /** Word's \"Different odd & even pages\" flag \u2014 true when the settings part carries an\n * on-valued `w:evenAndOddHeaders`. Document-global, so every section reports the same\n * value. Toggle with {@link DocxSession.setHeaderFooterKindEnabled}. */\n evenAndOddHeaders: boolean;\n columns: number;\n headerPartUris: string[];\n footerPartUris: string[];\n /** Header references in declaration order, each with its `w:type`. Describes exactly the\n * parts {@link SectionInfo.headerPartUris} lists, plus the kind each supplies. */\n headerRefs: HeaderFooterRef[];\n /** Footer references in declaration order, each with its `w:type`. Describes exactly the\n * parts {@link SectionInfo.footerPartUris} lists, plus the kind each supplies. */\n footerRefs: HeaderFooterRef[];\n /** The page number this section starts at (`w:pgNumType/@w:start`). Absent when the section\n * continues the previous section's numbering. */\n pageNumberStart?: number;\n /** This section's page-number format (`w:pgNumType/@w:fmt`). Absent means Word's default\n * `1, 2, 3` \u2014 deliberately not reported as `\"decimal\"`, so a UI can tell \"inherits\" from\n * \"explicitly decimal\" and avoid writing an attribute the document never had. */\n pageNumberFormat?: NumberFormat;\n}\n\n/** High-signal paragraph properties. Optional fields are deliberately absent when a\n * direct formatting layer did not write them; effective layers include schema defaults. */\nexport interface ParagraphFormatting {\n styleId?: string;\n alignment?: \"left\" | \"center\" | \"right\" | \"justify\";\n leftIndentTwips?: number;\n rightIndentTwips?: number;\n firstLineIndentTwips?: number;\n hangingIndentTwips?: number;\n spacingBeforeTwips?: number;\n spacingAfterTwips?: number;\n lineSpacing?: number;\n lineSpacingRule?: LineSpacingRule;\n keepNext?: boolean;\n keepLines?: boolean;\n pageBreakBefore?: boolean;\n outlineLevel?: number;\n shadingFill?: string;\n topBorder?: ParagraphBorderEdge;\n bottomBorder?: ParagraphBorderEdge;\n}\n\n/** High-signal character properties. Nullable-at-source fields are optional on the wire so\n * an absent direct property remains distinguishable from an explicit false/zero. */\nexport interface RunFormattingInfo {\n styleId?: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n underlineStyle?: string;\n strike?: boolean;\n code?: boolean;\n color?: string;\n highlight?: string;\n vertAlign?: string;\n fontSizePts?: number;\n fontFamily?: string;\n caps?: boolean;\n smallCaps?: boolean;\n hidden?: boolean;\n}\n\nexport interface TableStyleFormatting {\n alignment?: string;\n widthTwips?: number;\n indentTwips?: number;\n layout?: string;\n hasBorders?: boolean;\n cellShadingFill?: string;\n}\n\n/** One explicit document style. `id` is accepted unchanged by paragraph/run style mutations. */\nexport interface StyleInfo {\n id: string;\n name: string;\n type: \"paragraph\" | \"character\" | \"table\" | \"numbering\" | string;\n basedOn?: string;\n next?: string;\n isDefault: boolean;\n isCustom: boolean;\n hasLatentException: boolean;\n uiPriority?: number;\n semiHidden?: boolean;\n unhideWhenUsed?: boolean;\n quickFormat?: boolean;\n locked?: boolean;\n resolvedParagraph?: ParagraphFormatting;\n resolvedRun?: RunFormattingInfo;\n resolvedTable?: TableStyleFormatting;\n}\n\n/** One text-bearing run. `anchorId` + `span` can be passed unchanged to applyFormat. */\nexport interface InlineSpan {\n anchorId: string;\n runUnid: string;\n span: CharSpan;\n text: string;\n direct: RunFormattingInfo;\n effective: RunFormattingInfo;\n /** Outer-to-inner native content controls containing this run. */\n contentControlAnchorIds: string[];\n}\n\n/** Explicitly separated direct and effective formatting for one paragraph anchor. */\nexport interface FormattingInspection {\n anchorId: string;\n directParagraph: ParagraphFormatting;\n effectiveParagraph: ParagraphFormatting;\n runs: InlineSpan[];\n}\n\n/**\n * A custom annotation persisted in the document via Docxodus' annotation system.\n * Returned by {@link DocxSession.listAnnotations}; mirrors the wire-relevant\n * fields of the .NET `DocumentAnnotation` type. The page-info cache fields\n * (`startPage`/`endPage`/`pageInfoStale`/`pageInfoComputedAt`) are omitted to\n * keep the JSON payload compact \u2014 callers that need them can use the .NET API\n * directly. The `metadata` bag is emitted only when non-empty.\n *\n * See `docs/architecture/custom_annotations.md` for the persistence design.\n */\nexport interface DocumentAnnotation {\n /** Unique annotation identifier (caller-supplied at add time). */\n id: string;\n /** Label category/type (e.g. `\"INDEMNIFICATION\"`, `\"CLAUSE_TYPE_A\"`). */\n labelId: string;\n /** Human-readable label text displayed in the UI. */\n label: string;\n /** Highlight color in hex (e.g. `\"#FFEB3B\"`). */\n color: string;\n /** Internal bookmark name in the DOCX (`_Docxodus_Ann_{id}` for managed annotations). */\n bookmarkName: string;\n /** Author who created the annotation, if recorded. */\n author?: string;\n /** Creation timestamp in ISO-8601 (round-trip) format, if recorded. */\n created?: string;\n /** The text content covered by the annotation's bookmark, populated when reading. */\n annotatedText?: string;\n /** Arbitrary string\u2192string metadata bag persisted with the annotation. */\n metadata?: Record<string, string>;\n}\n\n/**\n * Partial-update payload for {@link DocxSession.updateAnnotation}.\n * Null/missing fields leave the existing value unchanged. `metadataPatch`\n * is a per-key merge: a non-null value sets the key, an explicit `null`\n * removes it, a missing key leaves it unchanged.\n */\nexport interface AnnotationUpdate {\n labelId?: string;\n label?: string;\n color?: string;\n author?: string;\n metadataPatch?: Record<string, string | null>;\n}\n\n/**\n * Severity level for comparison log entries.\n */\nexport enum ComparisonLogLevel {\n /** Informational message about the comparison process */\n Info = \"Info\",\n /** Warning about a potential issue that didn't prevent comparison */\n Warning = \"Warning\",\n /** Error that may affect comparison results but didn't stop processing */\n Error = \"Error\",\n}\n\n\n\n\n/**\n * Well-known log entry codes used by the comparison engine.\n */\nexport const ComparisonLogCodes = {\n /** A footnote reference in the document body has no corresponding footnote definition */\n OrphanedFootnoteReference: \"ORPHANED_FOOTNOTE_REFERENCE\",\n /** An endnote reference in the document body has no corresponding endnote definition */\n OrphanedEndnoteReference: \"ORPHANED_ENDNOTE_REFERENCE\",\n /** A style referenced in the document is not defined in styles.xml */\n MissingStyle: \"MISSING_STYLE\",\n /** A numbering definition referenced in the document is missing */\n MissingNumberingDefinition: \"MISSING_NUMBERING_DEFINITION\",\n /** A relationship referenced in the document is missing */\n MissingRelationship: \"MISSING_RELATIONSHIP\",\n /** An image or media file referenced in the document is missing */\n MissingMedia: \"MISSING_MEDIA\",\n /** The document structure contains unexpected or malformed XML */\n MalformedXml: \"MALFORMED_XML\",\n /** A bookmark reference has no corresponding bookmark start/end */\n OrphanedBookmark: \"ORPHANED_BOOKMARK\",\n} as const;\n\n\n/**\n * A custom annotation on a document range.\n */\nexport interface Annotation {\n /** Unique annotation ID */\n id: string;\n /** Label category/type identifier (e.g., \"CLAUSE_TYPE_A\", \"DATE_REF\") */\n labelId: string;\n /** Human-readable label text */\n label: string;\n /** Highlight color in hex format (e.g., \"#FFEB3B\") */\n color: string;\n /** Author who created the annotation */\n author?: string;\n /** Creation timestamp (ISO 8601) */\n created?: string;\n /** Internal bookmark name */\n bookmarkName?: string;\n /** Start page number (if computed) */\n startPage?: number;\n /** End page number (if computed) */\n endPage?: number;\n /** The annotated text content */\n annotatedText?: string;\n /** Custom metadata key-value pairs */\n metadata?: Record<string, string>;\n}\n\n/**\n * Request to add an annotation to a document.\n */\nexport interface AddAnnotationRequest {\n /** Unique annotation ID */\n id: string;\n /** Label category/type identifier */\n labelId: string;\n /** Human-readable label text */\n label: string;\n /** Highlight color in hex format (default: \"#FFEB3B\") */\n color?: string;\n /** Author who created the annotation */\n author?: string;\n /** Text to search for and annotate */\n searchText?: string;\n /** Which occurrence to annotate (1-based, default: 1) */\n occurrence?: number;\n /** Start paragraph index (0-based) */\n startParagraphIndex?: number;\n /** End paragraph index (0-based, inclusive) */\n endParagraphIndex?: number;\n /** Custom metadata key-value pairs */\n metadata?: Record<string, string>;\n}\n\n/**\n * Response from adding an annotation.\n */\nexport interface AddAnnotationResponse {\n /** Whether the operation succeeded */\n success: boolean;\n /** The modified document as base64 string */\n documentBytes: string;\n /** The added annotation details */\n annotation?: Annotation;\n}\n\n/**\n * Response from removing an annotation.\n */\nexport interface RemoveAnnotationResponse {\n /** Whether the operation succeeded */\n success: boolean;\n /** The modified document as base64 string */\n documentBytes: string;\n}\n\n/**\n * Options for annotation rendering in HTML output.\n */\nexport interface AnnotationOptions {\n /** Whether to render annotations (default: false) */\n renderAnnotations?: boolean;\n /** How to display annotation labels (default: Above) */\n annotationLabelMode?: AnnotationLabelMode;\n /** CSS class prefix for annotation elements (default: \"annot-\") */\n annotationCssClassPrefix?: string;\n}\n\n// ============================================================================\n// Document Structure Types (for element-based annotation targeting)\n// ============================================================================\n\n/**\n * Document element types that can be annotated.\n */\nexport enum DocumentElementType {\n /** Root document element */\n Document = \"Document\",\n /** A paragraph (w:p) */\n Paragraph = \"Paragraph\",\n /** A run within a paragraph (w:r) */\n Run = \"Run\",\n /** A table (w:tbl) */\n Table = \"Table\",\n /** A table row (w:tr) */\n TableRow = \"TableRow\",\n /** A table cell (w:tc) */\n TableCell = \"TableCell\",\n /** A virtual table column (not a real OOXML element) */\n TableColumn = \"TableColumn\",\n /** A hyperlink (w:hyperlink) */\n Hyperlink = \"Hyperlink\",\n /** An image/drawing (w:drawing) */\n Image = \"Image\",\n}\n\n/**\n * A document element in the structure tree.\n */\nexport interface DocumentElement {\n /** Unique element ID (path-based, e.g., \"doc/tbl-0/tr-1/tc-2\") */\n id: string;\n /** Canonical session anchor when this element is addressable. */\n anchorId?: string;\n /** Element type */\n type: DocumentElementType | string;\n /** Preview of text content (first ~100 characters) */\n textPreview?: string;\n /** Position index within parent element */\n index: number;\n /** Child elements */\n children: DocumentElement[];\n /** For table rows/cells: the row index */\n rowIndex?: number;\n /** For table cells: the column index */\n columnIndex?: number;\n /** For table cells: number of rows this cell spans */\n rowSpan?: number;\n /** For table cells: number of columns this cell spans */\n columnSpan?: number;\n}\n\n/**\n * Information about a table column.\n */\nexport interface TableColumnInfo {\n /** ID of the table this column belongs to */\n tableId: string;\n /** Canonical `col` anchor. */\n anchorId: string;\n /** Canonical owning `tbl` anchor. */\n tableAnchorId: string;\n isVirtual: boolean;\n /** Zero-based column index */\n columnIndex: number;\n /** IDs of all cells in this column */\n cellIds: string[];\n /** Canonical `tc` anchors for cells covering this column. */\n cellAnchorIds: string[];\n /** Total number of rows in this column */\n rowCount: number;\n}\n\n/**\n * Document structure analysis result.\n */\nexport interface DocumentStructure {\n /** Root document element */\n root: DocumentElement;\n /** All elements indexed by ID for quick lookup */\n elementsById: Record<string, DocumentElement>;\n /** Table column information indexed by column ID */\n tableColumns: Record<string, TableColumnInfo>;\n}\n\n/**\n * Target specification for element-based annotation.\n * Supports multiple targeting modes: element ID, indices, or text search.\n */\nexport interface AnnotationTarget {\n /** Target by element ID (e.g., \"doc/p-0/r-1\") */\n elementId?: string;\n /** Element type for index-based targeting */\n elementType?: DocumentElementType | string;\n /** Paragraph index (0-based) */\n paragraphIndex?: number;\n /** Run index within paragraph (0-based) */\n runIndex?: number;\n /** Table index (0-based) */\n tableIndex?: number;\n /** Row index within table (0-based) */\n rowIndex?: number;\n /** Cell index within row (0-based) */\n cellIndex?: number;\n /** Column index for table column targeting (0-based) */\n columnIndex?: number;\n /** Text to search for (global or within elementId) */\n searchText?: string;\n /** Which occurrence of searchText to target (1-based, default: 1) */\n occurrence?: number;\n /** End paragraph index for range targeting */\n rangeEndParagraphIndex?: number;\n}\n\n/**\n * Request to add an annotation using flexible targeting.\n */\nexport interface AddAnnotationWithTargetRequest {\n /** Unique annotation ID */\n id: string;\n /** Label category/type identifier */\n labelId: string;\n /** Human-readable label text */\n label: string;\n /** Highlight color in hex format (default: \"#FFEB3B\") */\n color?: string;\n /** Author who created the annotation */\n author?: string;\n /** Custom metadata key-value pairs */\n metadata?: Record<string, string>;\n /** Target specification */\n target: AnnotationTarget;\n}\n\n// ============================================================================\n// Helper functions for document structure navigation\n// ============================================================================\n\n/**\n * Find an element by ID in the document structure.\n * @param structure - The document structure\n * @param elementId - The element ID to find\n * @returns The element or undefined if not found\n */\nexport function findElementById(\n structure: DocumentStructure,\n elementId: string\n): DocumentElement | undefined {\n return structure.elementsById[elementId];\n}\n\n/**\n * Find all elements of a specific type in the document structure.\n * @param structure - The document structure\n * @param type - The element type to find\n * @returns Array of matching elements\n */\nexport function findElementsByType(\n structure: DocumentStructure,\n type: DocumentElementType | string\n): DocumentElement[] {\n return Object.values(structure.elementsById).filter(\n (el) => el.type === type\n );\n}\n\n/**\n * Get all paragraphs from the document structure.\n * @param structure - The document structure\n * @returns Array of paragraph elements\n */\nexport function getParagraphs(\n structure: DocumentStructure\n): DocumentElement[] {\n return findElementsByType(structure, DocumentElementType.Paragraph);\n}\n\n/**\n * Get all tables from the document structure.\n * @param structure - The document structure\n * @returns Array of table elements\n */\nexport function getTables(structure: DocumentStructure): DocumentElement[] {\n return findElementsByType(structure, DocumentElementType.Table);\n}\n\n/**\n * Get column information for a specific table.\n * @param structure - The document structure\n * @param tableId - The table ID\n * @returns Array of column info objects sorted by column index\n */\nexport function getTableColumns(\n structure: DocumentStructure,\n tableId: string\n): TableColumnInfo[] {\n return Object.values(structure.tableColumns)\n .filter((col) => col.tableId === tableId)\n .sort((a, b) => a.columnIndex - b.columnIndex);\n}\n\n/**\n * Create an annotation target for an element by ID.\n * @param elementId - The element ID (e.g., \"doc/p-0\", \"doc/tbl-0/tr-1/tc-2\")\n * @returns AnnotationTarget object\n */\nexport function targetElement(elementId: string): AnnotationTarget {\n return { elementId };\n}\n\n/**\n * Create an annotation target for a paragraph by index.\n * @param paragraphIndex - Zero-based paragraph index\n * @returns AnnotationTarget object\n */\nexport function targetParagraph(paragraphIndex: number): AnnotationTarget {\n return {\n elementType: DocumentElementType.Paragraph,\n paragraphIndex,\n };\n}\n\n/**\n * Create an annotation target for a range of paragraphs.\n * @param startIndex - Zero-based start paragraph index\n * @param endIndex - Zero-based end paragraph index\n * @returns AnnotationTarget object\n */\nexport function targetParagraphRange(\n startIndex: number,\n endIndex: number\n): AnnotationTarget {\n return {\n elementType: DocumentElementType.Paragraph,\n paragraphIndex: startIndex,\n rangeEndParagraphIndex: endIndex,\n };\n}\n\n/**\n * Create an annotation target for a specific run within a paragraph.\n * @param paragraphIndex - Zero-based paragraph index\n * @param runIndex - Zero-based run index within the paragraph\n * @returns AnnotationTarget object\n */\nexport function targetRun(\n paragraphIndex: number,\n runIndex: number\n): AnnotationTarget {\n return {\n elementType: DocumentElementType.Run,\n paragraphIndex,\n runIndex,\n };\n}\n\n/**\n * Create an annotation target for a table by index.\n * @param tableIndex - Zero-based table index\n * @returns AnnotationTarget object\n */\nexport function targetTable(tableIndex: number): AnnotationTarget {\n return {\n elementType: DocumentElementType.Table,\n tableIndex,\n };\n}\n\n/**\n * Create an annotation target for a table row.\n * @param tableIndex - Zero-based table index\n * @param rowIndex - Zero-based row index within the table\n * @returns AnnotationTarget object\n */\nexport function targetTableRow(\n tableIndex: number,\n rowIndex: number\n): AnnotationTarget {\n return {\n elementType: DocumentElementType.TableRow,\n tableIndex,\n rowIndex,\n };\n}\n\n/**\n * Create an annotation target for a table cell.\n * @param tableIndex - Zero-based table index\n * @param rowIndex - Zero-based row index\n * @param cellIndex - Zero-based cell index within the row\n * @returns AnnotationTarget object\n */\nexport function targetTableCell(\n tableIndex: number,\n rowIndex: number,\n cellIndex: number\n): AnnotationTarget {\n return {\n elementType: DocumentElementType.TableCell,\n tableIndex,\n rowIndex,\n cellIndex,\n };\n}\n\n/**\n * Create an annotation target for a table column (all cells in that column).\n * @param tableIndex - Zero-based table index\n * @param columnIndex - Zero-based column index\n * @returns AnnotationTarget object\n */\nexport function targetTableColumn(\n tableIndex: number,\n columnIndex: number\n): AnnotationTarget {\n return {\n elementType: DocumentElementType.TableColumn,\n tableIndex,\n columnIndex,\n };\n}\n\n/**\n * Create an annotation target by text search.\n * @param searchText - Text to search for\n * @param occurrence - Which occurrence to target (1-based, default: 1)\n * @returns AnnotationTarget object\n */\nexport function targetSearch(\n searchText: string,\n occurrence: number = 1\n): AnnotationTarget {\n return { searchText, occurrence };\n}\n\n/**\n * Create an annotation target to search text within a specific element.\n * @param elementId - The element ID to search within\n * @param searchText - Text to search for\n * @param occurrence - Which occurrence to target (1-based, default: 1)\n * @returns AnnotationTarget object\n */\nexport function targetSearchInElement(\n elementId: string,\n searchText: string,\n occurrence: number = 1\n): AnnotationTarget {\n return { elementId, searchText, occurrence };\n}\n\n// ============================================================================\n// Document Metadata Types (Phase 3: Lazy Loading)\n// ============================================================================\n\n/**\n * Metadata for a single section in the document.\n *\n * ## Units\n * All dimension values are in **points** (1 point = 1/72 inch).\n *\n * Common page sizes in points:\n * - **US Letter**: 612 \u00D7 792 pt (8.5\" \u00D7 11\")\n * - **A4**: 595 \u00D7 842 pt (210mm \u00D7 297mm)\n * - **Legal**: 612 \u00D7 1008 pt (8.5\" \u00D7 14\")\n *\n * To convert points to other units:\n * - Points to inches: `pt / 72`\n * - Points to mm: `pt / 72 * 25.4`\n * - Points to pixels (96 DPI): `pt * 96 / 72` (or `pt * 1.333...`)\n *\n * @example\n * ```typescript\n * const section = metadata.sections[0];\n * // US Letter: pageWidthPt = 612, pageHeightPt = 792\n *\n * // Convert to inches\n * const widthInches = section.pageWidthPt / 72; // 8.5\n *\n * // Convert to pixels at 96 DPI\n * const widthPx = section.pageWidthPt * 96 / 72; // 816\n * ```\n */\nexport interface SectionMetadata {\n /** Section index (0-based, sequential across document) */\n sectionIndex: number;\n /** Page width in points (1 pt = 1/72 inch). US Letter = 612pt, A4 \u2248 595pt */\n pageWidthPt: number;\n /** Page height in points (1 pt = 1/72 inch). US Letter = 792pt, A4 \u2248 842pt */\n pageHeightPt: number;\n /** Top margin in points. Default is typically 72pt (1 inch) */\n marginTopPt: number;\n /** Right margin in points. Default is typically 72pt (1 inch) */\n marginRightPt: number;\n /** Bottom margin in points. Default is typically 72pt (1 inch) */\n marginBottomPt: number;\n /** Left margin in points. Default is typically 72pt (1 inch) */\n marginLeftPt: number;\n /** Content width in points (pageWidthPt - marginLeftPt - marginRightPt) */\n contentWidthPt: number;\n /** Content height in points (pageHeightPt - marginTopPt - marginBottomPt) */\n contentHeightPt: number;\n /** Header distance from page top in points. Default is typically 36pt (0.5 inch) */\n headerPt: number;\n /** Footer distance from page bottom in points. Default is typically 36pt (0.5 inch) */\n footerPt: number;\n /** Number of paragraphs in this section (includes paragraphs inside tables) */\n paragraphCount: number;\n /** Number of top-level tables in this section */\n tableCount: number;\n /** Whether this section has a default header (w:headerReference type=\"default\") */\n hasHeader: boolean;\n /** Whether this section has a default footer (w:footerReference type=\"default\") */\n hasFooter: boolean;\n /** Whether this section has a first page header (requires titlePg element) */\n hasFirstPageHeader: boolean;\n /** Whether this section has a first page footer (requires titlePg element) */\n hasFirstPageFooter: boolean;\n /** Whether this section has an even page header (for different even/odd headers) */\n hasEvenPageHeader: boolean;\n /** Whether this section has an even page footer (for different even/odd footers) */\n hasEvenPageFooter: boolean;\n /** Start paragraph index (0-based, global across document). Inclusive. */\n startParagraphIndex: number;\n /** End paragraph index (global across document). Exclusive - use `endParagraphIndex - startParagraphIndex` for count. */\n endParagraphIndex: number;\n /** Start table index (0-based, global across document). Inclusive. */\n startTableIndex: number;\n /** End table index (global across document). Exclusive - use `endTableIndex - startTableIndex` for count. */\n endTableIndex: number;\n}\n\n/**\n * Document metadata for lazy loading pagination.\n * Provides fast access to document structure without full HTML rendering.\n *\n * This is significantly faster than full HTML conversion and is designed for:\n * - Lazy loading / virtual scrolling of large documents\n * - Pre-calculating pagination layouts\n * - Document feature detection before rendering\n *\n * @example\n * ```typescript\n * const metadata = await getDocumentMetadata(docxFile);\n *\n * // Check document features before rendering\n * if (metadata.hasTrackedChanges) {\n * console.log('Document has tracked changes');\n * }\n *\n * // Calculate total content for lazy loading\n * const totalSections = metadata.sections.length;\n * const firstPageWidth = metadata.sections[0].pageWidthPt;\n *\n * // Paragraph count includes paragraphs inside tables\n * console.log(`${metadata.totalParagraphs} paragraphs, ${metadata.totalTables} tables`);\n * ```\n *\n * @remarks\n * **Limitations:**\n * - Section breaks inside tables or text boxes are not detected (see GitHub issue #51)\n * - Estimated page count is heuristic-based and may not match actual rendered pages\n * - Maximum document size is 100MB\n */\nexport interface DocumentMetadata {\n /** List of sections with their metadata. Documents always have at least one section. */\n sections: SectionMetadata[];\n /** Total number of paragraphs in the document (includes paragraphs inside tables) */\n totalParagraphs: number;\n /** Total number of top-level tables in the document */\n totalTables: number;\n /** Whether the document has any footnotes (excludes separator/continuationSeparator) */\n hasFootnotes: boolean;\n /** Whether the document has any endnotes (excludes separator/continuationSeparator) */\n hasEndnotes: boolean;\n /** Whether the document has tracked changes (w:ins, w:del, w:moveFrom, w:moveTo) */\n hasTrackedChanges: boolean;\n /** Whether the document has comments (w:comment elements with content) */\n hasComments: boolean;\n /** Estimated total page count (heuristic based on content volume and page sizes) */\n estimatedPageCount: number;\n /** Explicit provenance: always \"heuristic\"; use PageMap for authoritative pages. */\n estimatedPageCountSource: \"heuristic\";\n}\n\n// ============================================================================\n// Web Worker Types (Phase 2: Non-blocking WASM operations)\n// ============================================================================\n\n/**\n * Message types sent from main thread to worker.\n */\nexport type WorkerRequestType =\n | \"init\"\n | \"generatePackageManifest\"\n | \"verifyDeliverable\"\n | \"proveRedlineReversibility\"\n | \"projectReviewProfile\"\n | \"convertDocxToHtml\"\n | \"compareDocuments\"\n | \"compareDocumentsToHtml\"\n | \"getSemanticChanges\"\n | \"createExternalAnnotationSet\"\n | \"validateExternalAnnotations\"\n | \"projectAnnotationsOntoHtml\"\n | \"convertDocxToHtmlWithExternalAnnotations\"\n | \"exportToOpenContract\"\n | \"getRevisions\"\n | \"getComments\"\n | \"getDocumentMetadata\"\n | \"getVersion\"\n | \"prepare\"\n | \"sessionOpen\"\n | \"sessionGetPackageManifest\"\n | \"sessionGetSemanticChanges\"\n | \"sessionVerifyDeliverable\"\n | \"sessionClose\"\n | \"sessionAddAnnotation\"\n | \"sessionRemoveAnnotation\"\n | \"sessionUpdateAnnotation\"\n | \"sessionMoveAnnotation\";\n\n/**\n * Base structure for worker requests.\n */\nexport interface WorkerRequestBase {\n /** Unique request ID for correlating responses */\n id: string;\n /** The operation type */\n type: WorkerRequestType;\n}\n\n/**\n * Initialize the worker with WASM base path.\n */\nexport interface WorkerInitRequest extends WorkerRequestBase {\n type: \"init\";\n /** Base URL for loading WASM files (e.g., \"/wasm/\") */\n wasmBasePath: string;\n}\n\n/**\n * Convert DOCX to HTML request.\n */\nexport interface WorkerConvertRequest extends WorkerRequestBase {\n type: \"convertDocxToHtml\";\n /** Private exact-view copy of the caller's document bytes, transferred to the worker. */\n documentBytes: Uint8Array;\n /** Conversion options */\n options?: ConversionOptions;\n /** Optional main-thread admission ceiling for the UTF-8 response. */\n maximumOutputBytes?: number;\n}\n\n/** Generate a deterministic package manifest without opening a live session. */\nexport interface WorkerGeneratePackageManifestRequest extends WorkerRequestBase {\n type: \"generatePackageManifest\";\n documentBytes: Uint8Array;\n /** When present, these lower ceilings constrain #493 inspection itself. */\n limits?: PackageManifestInspectionLimits;\n /**\n * Which representation the caller needs. A manifest near the entry ceiling is multi-megabyte,\n * so returning both costs a parse plus a structured clone nobody reads. Defaults to `\"both\"`.\n */\n representation?: \"object\" | \"json\" | \"both\";\n}\n\n/** Derive exact final/original package bytes before conversion. */\nexport interface WorkerProjectReviewProfileRequest extends WorkerRequestBase {\n type: \"projectReviewProfile\";\n documentBytes: Uint8Array;\n profile: \"final\" | \"original\";\n /** Do not transfer a derived package larger than this many bytes. */\n maximumOutputBytes?: number;\n}\n\n/** Run the default deliverable gate directly over exact supplied bytes. */\nexport interface WorkerVerifyDeliverableRequest extends WorkerRequestBase {\n type: \"verifyDeliverable\";\n documentBytes: Uint8Array;\n baselineBytes?: Uint8Array;\n /** The serialized full request (issue #747); absent means the default policy. */\n requestJson?: string;\n}\n\n/**\n * Prove redline accept/reject reversibility off the main thread. Three packages are inspected and\n * two are rebuilt, so this is the heaviest verification request the worker serves.\n */\nexport interface WorkerProveRedlineReversibilityRequest extends WorkerRequestBase {\n type: \"proveRedlineReversibility\";\n baselineBytes: Uint8Array;\n intendedFinalBytes: Uint8Array;\n redlineBytes: Uint8Array;\n}\n\n/**\n * Compare two documents request.\n */\nexport interface WorkerCompareRequest extends WorkerRequestBase {\n type: \"compareDocuments\";\n /** Original document bytes */\n originalBytes: Uint8Array;\n /** Modified document bytes */\n modifiedBytes: Uint8Array;\n /** Comparison options */\n options?: CompareOptions;\n}\n\n/**\n * Compare documents and return HTML request.\n */\nexport interface WorkerCompareToHtmlRequest extends WorkerRequestBase {\n type: \"compareDocumentsToHtml\";\n /** Original document bytes */\n originalBytes: Uint8Array;\n /** Modified document bytes */\n modifiedBytes: Uint8Array;\n /** Comparison options */\n options?: CompareOptions;\n}\n\n/** Compare two packages into the stable, versioned semantic-change schema. */\nexport interface WorkerGetSemanticChangesRequest extends WorkerRequestBase {\n type: \"getSemanticChanges\";\n leftBytes: Uint8Array;\n rightBytes: Uint8Array;\n settings?: DocxDiffSettings;\n}\n\n/** Create an empty external annotation set bound to a document's hash (issue #775). */\nexport interface WorkerCreateExternalAnnotationSetRequest extends WorkerRequestBase {\n type: \"createExternalAnnotationSet\";\n documentBytes: Uint8Array;\n documentId: string;\n}\n\n/** Validate an external annotation set against a document. */\nexport interface WorkerValidateExternalAnnotationsRequest extends WorkerRequestBase {\n type: \"validateExternalAnnotations\";\n documentBytes: Uint8Array;\n annotationSet: ExternalAnnotationSet;\n}\n\n/** Project an annotation set onto already-rendered (XML-well-formed) HTML. */\nexport interface WorkerProjectAnnotationsOntoHtmlRequest extends WorkerRequestBase {\n type: \"projectAnnotationsOntoHtml\";\n html: string;\n annotationSet: ExternalAnnotationSet;\n projectionOptions?: ExternalAnnotationProjectionSettings;\n}\n\n/** Convert a document and project an annotation set onto it in one round trip. */\nexport interface WorkerConvertWithExternalAnnotationsRequest extends WorkerRequestBase {\n type: \"convertDocxToHtmlWithExternalAnnotations\";\n documentBytes: Uint8Array;\n annotationSet: ExternalAnnotationSet;\n conversionOptions?: ConversionOptions;\n projectionOptions?: ExternalAnnotationProjectionSettings;\n}\n\n/** Export a document to the OpenContracts format. */\nexport interface WorkerExportToOpenContractRequest extends WorkerRequestBase {\n type: \"exportToOpenContract\";\n documentBytes: Uint8Array;\n}\n\n/**\n * Get revisions from a document request.\n */\nexport interface WorkerGetRevisionsRequest extends WorkerRequestBase {\n type: \"getRevisions\";\n /** Document bytes */\n documentBytes: Uint8Array;\n}\n\n/**\n * Get comments from a document request.\n */\nexport interface WorkerGetCommentsRequest extends WorkerRequestBase {\n type: \"getComments\";\n /** Document bytes */\n documentBytes: Uint8Array;\n}\n\n/**\n * Get document metadata for lazy loading request.\n */\nexport interface WorkerGetDocumentMetadataRequest extends WorkerRequestBase {\n type: \"getDocumentMetadata\";\n /** Document bytes */\n documentBytes: Uint8Array;\n}\n\n/**\n * Get library version request.\n */\nexport interface WorkerGetVersionRequest extends WorkerRequestBase {\n type: \"getVersion\";\n}\n\n/**\n * Warm up the comparison code path so the next compare triggers no further\n * WASM assembly fetches. Carries no payload.\n */\nexport interface WorkerPrepareRequest extends WorkerRequestBase {\n type: \"prepare\";\n}\n\n/**\n * Open a DocxSession in the worker.\n */\nexport interface WorkerSessionOpenRequest extends WorkerRequestBase {\n type: \"sessionOpen\";\n /** Private exact-view copy of the caller's document bytes, transferred to the worker. */\n documentBytes: Uint8Array;\n /** Session settings as JSON */\n settingsJson?: string;\n}\n\n/** Generate a manifest from the current logical checkpoint of a worker session. */\nexport interface WorkerSessionGetPackageManifestRequest extends WorkerRequestBase {\n type: \"sessionGetPackageManifest\";\n handle: number;\n}\n\n/** Compare a worker session's current checkpoint with its opening package. */\nexport interface WorkerSessionGetSemanticChangesRequest extends WorkerRequestBase {\n type: \"sessionGetSemanticChanges\";\n handle: number;\n}\n\n/** Run the default deliverable gate over a worker session's clean-save checkpoint. */\nexport interface WorkerSessionVerifyDeliverableRequest extends WorkerRequestBase {\n type: \"sessionVerifyDeliverable\";\n handle: number;\n /** The serialized full request (issue #747); absent means the default policy. */\n requestJson?: string;\n}\n\n/**\n * Close a worker DocxSession.\n */\nexport interface WorkerSessionCloseRequest extends WorkerRequestBase {\n type: \"sessionClose\";\n /** Session handle returned by sessionOpen */\n handle: number;\n}\n\n/**\n * Add an annotation via a worker DocxSession.\n */\nexport interface WorkerSessionAddAnnotationRequest extends WorkerRequestBase {\n type: \"sessionAddAnnotation\";\n handle: number;\n anchorId: string;\n /** CharSpan as JSON, or empty string for block-level */\n spanJson: string;\n annotationJson: string;\n}\n\n/**\n * Remove an annotation via a worker DocxSession.\n */\nexport interface WorkerSessionRemoveAnnotationRequest extends WorkerRequestBase {\n type: \"sessionRemoveAnnotation\";\n handle: number;\n annotationId: string;\n}\n\n/**\n * Update an annotation via a worker DocxSession.\n */\nexport interface WorkerSessionUpdateAnnotationRequest extends WorkerRequestBase {\n type: \"sessionUpdateAnnotation\";\n handle: number;\n annotationId: string;\n updateJson: string;\n}\n\n/**\n * Move an annotation via a worker DocxSession.\n */\nexport interface WorkerSessionMoveAnnotationRequest extends WorkerRequestBase {\n type: \"sessionMoveAnnotation\";\n handle: number;\n annotationId: string;\n newAnchorId: string;\n /** CharSpan as JSON, or empty string for block-level */\n newSpanJson: string;\n}\n\n/**\n * Union type of all possible worker requests.\n */\nexport type WorkerRequest =\n | WorkerInitRequest\n | WorkerGeneratePackageManifestRequest\n | WorkerVerifyDeliverableRequest\n | WorkerProveRedlineReversibilityRequest\n | WorkerProjectReviewProfileRequest\n | WorkerConvertRequest\n | WorkerCompareRequest\n | WorkerCompareToHtmlRequest\n | WorkerGetSemanticChangesRequest\n | WorkerCreateExternalAnnotationSetRequest\n | WorkerValidateExternalAnnotationsRequest\n | WorkerProjectAnnotationsOntoHtmlRequest\n | WorkerConvertWithExternalAnnotationsRequest\n | WorkerExportToOpenContractRequest\n | WorkerGetRevisionsRequest\n | WorkerGetCommentsRequest\n | WorkerGetDocumentMetadataRequest\n | WorkerGetVersionRequest\n | WorkerPrepareRequest\n | WorkerSessionOpenRequest\n | WorkerSessionGetPackageManifestRequest\n | WorkerSessionGetSemanticChangesRequest\n | WorkerSessionVerifyDeliverableRequest\n | WorkerSessionCloseRequest\n | WorkerSessionAddAnnotationRequest\n | WorkerSessionRemoveAnnotationRequest\n | WorkerSessionUpdateAnnotationRequest\n | WorkerSessionMoveAnnotationRequest;\n\n/**\n * Base structure for worker responses.\n */\nexport interface WorkerResponseBase {\n /** Request ID this response corresponds to */\n id: string;\n /** Whether the operation succeeded */\n success: boolean;\n /** Error message if success is false */\n error?: string;\n /**\n * Machine-readable cause when success is false. Callers classify failures from this\n * rather than by matching `error`, whose wording is not a contract.\n */\n errorCode?: WorkerErrorCode;\n}\n\n/**\n * Closed set of machine-readable worker failure causes.\n *\n * - `resource_limit`: the operation exceeded a configured size or work limit.\n * - `internal_error`: the worker threw an unexpected error while handling the request.\n * - `timeout`: the request outlived its `timeoutMs` / `requestTimeoutMs` deadline.\n * - `aborted`: the request's `AbortSignal` fired.\n * - `message_error`: a worker response could not be deserialized (`messageerror`); every request\n * in flight is rejected with this code, because the lost response cannot be matched to its request.\n * - `missing_result`: the worker reported success but sent no payload.\n */\nexport type WorkerErrorCode =\n | \"resource_limit\"\n | \"internal_error\"\n | \"timeout\"\n | \"aborted\"\n | \"message_error\"\n | \"missing_result\";\n\n/**\n * Response from init request.\n */\nexport interface WorkerInitResponse extends WorkerResponseBase {\n type: \"init\";\n}\n\n/**\n * Response from convertDocxToHtml request.\n */\nexport interface WorkerConvertResponse extends WorkerResponseBase {\n type: \"convertDocxToHtml\";\n /** The converted HTML string */\n html?: string;\n}\n\nexport interface WorkerGeneratePackageManifestResponse extends WorkerResponseBase {\n type: \"generatePackageManifest\";\n manifest?: PackageManifest;\n /** Exact canonical JSON, retained for strict duplicate-property/schema validation. */\n manifestJson?: string;\n}\n\nexport interface WorkerProjectReviewProfileResponse extends WorkerResponseBase {\n type: \"projectReviewProfile\";\n documentBytes?: Uint8Array;\n}\n\nexport interface WorkerVerifyDeliverableResponse extends WorkerResponseBase {\n type: \"verifyDeliverable\";\n verification?: DeliverableVerificationResult;\n}\n\nexport interface WorkerProveRedlineReversibilityResponse extends WorkerResponseBase {\n type: \"proveRedlineReversibility\";\n proof?: RedlineReversibilityProof;\n}\n\n/**\n * Response from compareDocuments request.\n */\nexport interface WorkerCompareResponse extends WorkerResponseBase {\n type: \"compareDocuments\";\n /** The redlined document bytes */\n documentBytes?: Uint8Array;\n}\n\n/**\n * Response from compareDocumentsToHtml request.\n */\nexport interface WorkerCompareToHtmlResponse extends WorkerResponseBase {\n type: \"compareDocumentsToHtml\";\n /** The HTML string with redlines */\n html?: string;\n}\n\n/** Response containing the public semantic-change schema. */\nexport interface WorkerGetSemanticChangesResponse extends WorkerResponseBase {\n type: \"getSemanticChanges\";\n semanticChanges?: SemanticChangeSet;\n}\n\nexport interface WorkerCreateExternalAnnotationSetResponse extends WorkerResponseBase {\n type: \"createExternalAnnotationSet\";\n annotationSet?: ExternalAnnotationSet;\n}\n\nexport interface WorkerValidateExternalAnnotationsResponse extends WorkerResponseBase {\n type: \"validateExternalAnnotations\";\n validation?: ExternalAnnotationValidationResult;\n}\n\nexport interface WorkerProjectAnnotationsOntoHtmlResponse extends WorkerResponseBase {\n type: \"projectAnnotationsOntoHtml\";\n html?: string;\n}\n\nexport interface WorkerConvertWithExternalAnnotationsResponse extends WorkerResponseBase {\n type: \"convertDocxToHtmlWithExternalAnnotations\";\n html?: string;\n}\n\nexport interface WorkerExportToOpenContractResponse extends WorkerResponseBase {\n type: \"exportToOpenContract\";\n export?: OpenContractDocExport;\n}\n\n/**\n * Response from getRevisions request.\n */\nexport interface WorkerGetRevisionsResponse extends WorkerResponseBase {\n type: \"getRevisions\";\n /** Array of revisions */\n revisions?: RevisionListEntry[];\n}\n\n/**\n * Response from getComments request.\n */\nexport interface WorkerGetCommentsResponse extends WorkerResponseBase {\n type: \"getComments\";\n /** Array of comments */\n comments?: CommentListEntry[];\n}\n\n/**\n * Response from getDocumentMetadata request.\n */\nexport interface WorkerGetDocumentMetadataResponse extends WorkerResponseBase {\n type: \"getDocumentMetadata\";\n /** Document metadata */\n metadata?: DocumentMetadata;\n}\n\n/**\n * Response from getVersion request.\n */\nexport interface WorkerGetVersionResponse extends WorkerResponseBase {\n type: \"getVersion\";\n /** Version information */\n version?: VersionInfo;\n}\n\n/**\n * Response from prepare request. Carries no payload beyond success/error.\n */\nexport interface WorkerPrepareResponse extends WorkerResponseBase {\n type: \"prepare\";\n}\n\n/**\n * Response from sessionOpen request.\n */\nexport interface WorkerSessionOpenResponse extends WorkerResponseBase {\n type: \"sessionOpen\";\n /** Integer handle identifying the session in the worker */\n handle?: number;\n}\n\n/** Response containing the current worker-session package manifest. */\nexport interface WorkerSessionGetPackageManifestResponse extends WorkerResponseBase {\n type: \"sessionGetPackageManifest\";\n manifest?: PackageManifest;\n}\n\n/** Response containing a session's public semantic-change schema. */\nexport interface WorkerSessionGetSemanticChangesResponse extends WorkerResponseBase {\n type: \"sessionGetSemanticChanges\";\n semanticChanges?: SemanticChangeSet;\n}\n\nexport interface WorkerSessionVerifyDeliverableResponse extends WorkerResponseBase {\n type: \"sessionVerifyDeliverable\";\n verification?: DeliverableVerificationResult;\n}\n\n/**\n * Response from sessionClose request.\n */\nexport interface WorkerSessionCloseResponse extends WorkerResponseBase {\n type: \"sessionClose\";\n}\n\n/**\n * Response from session annotation write operations.\n * The `result` field is the serialised EditResult from the WASM bridge.\n */\nexport interface WorkerSessionEditResponse extends WorkerResponseBase {\n type:\n | \"sessionAddAnnotation\"\n | \"sessionRemoveAnnotation\"\n | \"sessionUpdateAnnotation\"\n | \"sessionMoveAnnotation\";\n /** EditResult returned by the session operation */\n result?: EditResult;\n}\n\n/**\n * Union type of all possible worker responses.\n */\nexport type WorkerResponse =\n | WorkerInitResponse\n | WorkerGeneratePackageManifestResponse\n | WorkerVerifyDeliverableResponse\n | WorkerProveRedlineReversibilityResponse\n | WorkerProjectReviewProfileResponse\n | WorkerConvertResponse\n | WorkerCompareResponse\n | WorkerCompareToHtmlResponse\n | WorkerGetSemanticChangesResponse\n | WorkerCreateExternalAnnotationSetResponse\n | WorkerValidateExternalAnnotationsResponse\n | WorkerProjectAnnotationsOntoHtmlResponse\n | WorkerConvertWithExternalAnnotationsResponse\n | WorkerExportToOpenContractResponse\n | WorkerGetRevisionsResponse\n | WorkerGetCommentsResponse\n | WorkerGetDocumentMetadataResponse\n | WorkerGetVersionResponse\n | WorkerPrepareResponse\n | WorkerSessionOpenResponse\n | WorkerSessionGetPackageManifestResponse\n | WorkerSessionGetSemanticChangesResponse\n | WorkerSessionVerifyDeliverableResponse\n | WorkerSessionCloseResponse\n | WorkerSessionEditResponse;\n\n/**\n * Options for creating a worker-based Docxodus instance.\n */\nexport interface WorkerDocxodusOptions {\n /**\n * Base URL for loading WASM files.\n * Defaults to auto-detection from module URL.\n */\n wasmBasePath?: string;\n /** Abort the owned worker, including an initialization that has not completed. */\n signal?: AbortSignal;\n /**\n * Reject any request, including initialization, that has not answered within this many\n * milliseconds, with a `timeout` {@link WorkerErrorCode}. Off by default: large documents can\n * legitimately take a long time. A timed-out initialization stops the worker. Any other\n * timed-out request is most likely still running on the worker's single thread, and later\n * requests queue behind it; call `terminate()` to stop it.\n */\n requestTimeoutMs?: number;\n}\n\n/** Per-request options for a `WorkerDocxodus.withRequestOptions` view. */\nexport interface WorkerRequestOptions {\n /** Rejects each pending request of the view with an `aborted` {@link WorkerErrorCode} when it fires. */\n signal?: AbortSignal;\n /** A deadline in milliseconds that overrides the instance's `requestTimeoutMs`. */\n timeoutMs?: number;\n}\n\n// ============================================================================\n// OpenContracts Export Types (Issue #56)\n// ============================================================================\n\n/**\n * OpenContracts document export format.\n * Compatible with the OpenContracts ecosystem for document analysis.\n *\n * @example\n * ```typescript\n * const export = await exportToOpenContract(docxFile);\n * console.log(`Title: ${export.title}`);\n * console.log(`Content length: ${export.content.length} characters`);\n * console.log(`Pages: ${export.pageCount}`);\n * console.log(`Structural annotations: ${export.labelledText.filter(a => a.structural).length}`);\n * ```\n */\nexport interface OpenContractDocExport {\n /** Document title (from core properties or filename) */\n title: string;\n /** Complete document text content - ALL text from the document */\n content: string;\n /** Optional document description */\n description?: string;\n /** Estimated page count */\n pageCount: number;\n /** PAWLS-format page layout information with token positions */\n pawlsFileContent: PawlsPage[];\n /** Document-level labels (categories applied to the whole document) */\n docLabels: string[];\n /** Annotations/labeled text spans in the document */\n labelledText: OpenContractsAnnotation[];\n /** Relationships between annotations */\n relationships?: OpenContractsRelationship[];\n}\n\n/**\n * PAWLS page containing page boundary and token information.\n * PAWLS (Page-Aware Layout Segmentation) is a format for document layout data.\n */\nexport interface PawlsPage {\n /** Page boundary information (dimensions and index) */\n page: PawlsPageBoundary;\n /** Tokens on this page with position information */\n tokens: PawlsToken[];\n}\n\n/**\n * Page boundary information for PAWLS format.\n */\nexport interface PawlsPageBoundary {\n /** Page width in points (1pt = 1/72 inch) */\n width: number;\n /** Page height in points */\n height: number;\n /** Zero-based page index */\n index: number;\n}\n\n/**\n * Token with position information for PAWLS format.\n * Each token represents a word or text fragment with its bounding box.\n */\nexport interface PawlsToken {\n /** X coordinate (left edge) in points */\n x: number;\n /** Y coordinate (top edge) in points */\n y: number;\n /** Token width in points */\n width: number;\n /** Token height in points */\n height: number;\n /** The text content of this token */\n text: string;\n}\n\n/**\n * OpenContracts annotation format.\n * Used for both user annotations and structural elements.\n */\nexport interface OpenContractsAnnotation {\n /** Unique annotation identifier */\n id?: string;\n /** Label/category for this annotation (e.g., \"SECTION\", \"PARAGRAPH\", \"CLAUSE_TYPE_A\") */\n annotationLabel: string;\n /** The raw text content of the annotation */\n rawText: string;\n /** Starting page number (0-indexed) */\n page: number;\n /**\n * Position data for the annotation. Can be either:\n * - A TextSpan with start/end character offsets\n * - A dictionary of page indices to single-page annotation data\n */\n annotationJson?: TextSpan | Record<string, OpenContractsSinglePageAnnotation>;\n /** Parent annotation ID for hierarchical annotations */\n parentId?: string;\n /** Type of annotation (e.g., \"text\", \"structural\") */\n annotationType?: string;\n /** Whether this is a structural element (section, heading, table, etc.) */\n structural: boolean;\n}\n\n/**\n * Per-page annotation position data.\n * Used when an annotation spans multiple pages.\n */\nexport interface OpenContractsSinglePageAnnotation {\n /** Bounding box for the annotation on this page */\n bounds: BoundingBox;\n /** Token indices that make up this annotation on this page */\n tokensJsons: TokenId[];\n /** Raw text content on this page */\n rawText: string;\n}\n\n/**\n * Bounding box coordinates in points.\n */\nexport interface BoundingBox {\n /** Top edge coordinate */\n top: number;\n /** Bottom edge coordinate */\n bottom: number;\n /** Left edge coordinate */\n left: number;\n /** Right edge coordinate */\n right: number;\n}\n\n/**\n * Token identifier referencing a specific token on a specific page.\n */\nexport interface TokenId {\n /** Zero-based page index */\n pageIndex: number;\n /** Zero-based token index within the page */\n tokenIndex: number;\n}\n\n/**\n * Text span with character offsets for annotation positioning.\n * This is the simpler form of annotation_json for single-page annotations.\n */\nexport interface TextSpan {\n /** Optional span identifier */\n id?: string;\n /** Start character offset (0-indexed, inclusive) */\n start: number;\n /** End character offset (exclusive) */\n end: number;\n /** The text content of this span */\n text: string;\n}\n\n/**\n * Relationship between annotations.\n * Used to express hierarchical or semantic connections between annotations.\n */\nexport interface OpenContractsRelationship {\n /** Unique relationship identifier */\n id?: string;\n /** Label describing the relationship type (e.g., \"CONTAINS\", \"REFERENCES\") */\n relationshipLabel: string;\n /** IDs of source annotations */\n sourceAnnotationIds: string[];\n /** IDs of target annotations */\n targetAnnotationIds: string[];\n /** Whether this is a structural relationship */\n structural: boolean;\n}\n\n// ============================================================================\n// External Annotation Types (Issue #57)\n// ============================================================================\n\n/**\n * Annotation label definition matching OpenContracts AnnotationLabelPythonType.\n */\nexport interface AnnotationLabel {\n /** Unique label identifier */\n id: string;\n /** Color in hex format (e.g., \"#FFEB3B\") */\n color: string;\n /** Description of what this label represents */\n description: string;\n /** Optional icon name */\n icon: string;\n /** Display name for the label */\n text: string;\n /** Type of label: \"text\", \"doc\", or \"metadata\" */\n labelType: \"text\" | \"doc\" | \"metadata\";\n}\n\n/**\n * External annotation set - extends OpenContractDocExport with binding/validation.\n * This allows storing annotations externally (in JSON/database) without modifying the DOCX.\n *\n * @example\n * ```typescript\n * // Create an annotation set from a document\n * const set = await createExternalAnnotationSet(docxFile, \"my-doc-123\");\n *\n * // Add a label definition\n * set.textLabels[\"IMPORTANT\"] = {\n * id: \"IMPORTANT\",\n * text: \"Important\",\n * color: \"#FF0000\",\n * description: \"Important text that needs attention\",\n * icon: \"\",\n * labelType: \"text\"\n * };\n *\n * // Create an annotation\n * const annotation = createAnnotationFromSearch(\n * \"ann-001\", \"IMPORTANT\", set.content, \"contract term\"\n * );\n * if (annotation) {\n * set.labelledText.push(annotation);\n * }\n *\n * // Validate and project onto HTML\n * const result = await validateExternalAnnotations(docxFile, set);\n * if (result.isValid) {\n * const html = await convertDocxToHtmlWithExternalAnnotations(docxFile, set);\n * }\n * ```\n */\nexport interface ExternalAnnotationSet extends OpenContractDocExport {\n /** Unique identifier for the source document (filename, UUID, or external reference) */\n documentId: string;\n /** SHA256 hash of the source document for integrity validation */\n documentHash: string;\n /** ISO 8601 timestamp when this annotation set was created */\n createdAt: string;\n /** ISO 8601 timestamp when this annotation set was last modified */\n updatedAt: string;\n /** Version of the external annotation format (for future migrations) */\n version: string;\n /** Text label definitions keyed by label ID */\n textLabels: Record<string, AnnotationLabel>;\n /** Document label definitions keyed by label ID */\n docLabelDefinitions: Record<string, AnnotationLabel>;\n}\n\n/**\n * Result of validating an external annotation set against a document.\n */\nexport interface ExternalAnnotationValidationResult {\n /** True if the annotation set is valid for the document */\n isValid: boolean;\n /** True if the document hash doesn't match, indicating the document may have been modified */\n hashMismatch: boolean;\n /** List of specific issues found during validation */\n issues: ExternalAnnotationValidationIssue[];\n}\n\n/**\n * A single validation issue found when validating an external annotation set.\n */\nexport interface ExternalAnnotationValidationIssue {\n /** ID of the annotation with the issue */\n annotationId: string;\n /** Type of issue: \"TextMismatch\", \"OutOfBounds\", or \"MissingLabel\" */\n issueType: \"TextMismatch\" | \"OutOfBounds\" | \"MissingLabel\";\n /** Human-readable description of the issue */\n description: string;\n /** For TextMismatch: the text that was expected (stored in annotation) */\n expectedText?: string;\n /** For TextMismatch: the actual text found at the annotation's offsets */\n actualText?: string;\n}\n\n/**\n * Settings for projecting external annotations onto HTML.\n */\nexport interface ExternalAnnotationProjectionSettings {\n /** CSS class prefix for annotation elements (default: \"ext-annot-\") */\n cssClassPrefix?: string;\n /** How to display annotation labels (default: Above) */\n labelMode?: AnnotationLabelMode;\n /** Whether to include annotation metadata as data attributes (default: true) */\n includeMetadata?: boolean;\n /** Whether to validate annotations before projection (default: true) */\n validateBeforeProjection?: boolean;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["session_exports", "__export", "ContextBoundary", "DocxSession", "PlaceholderKinds", "openDocxSession", "serializeVerificationRequest", "request", "companionArtifacts", "rest", "wire", "encodeCompanion", "artifact", "bytes", "bytesToBase64", "binary", "i", "chunk", "PlaceholderKinds", "DiffFormat", "ContextBoundary", "mutationBatchChangeSet", "before", "after", "key", "beforeGroups", "afterGroups", "group", "items", "target", "item", "index", "identity", "indices", "beforeMatched", "afterMatched", "modified", "afterIndices", "beforeIndices", "afterIndex", "beforeIndex", "remainingBefore", "remainingAfter", "modifiedCount", "_", "BATCH_REPLAY_CAVEATS", "BATCH_REPLAY_CAVEAT_TEXTS", "RETAINED_PREVIEW_RECEIPTS", "DocxSession", "_DocxSession", "handle", "wasm", "anchorId", "position", "xml", "pageMap", "expectedRendererFingerprint", "request", "preconditions", "mutation", "checked", "steps", "mode", "transaction", "options", "wire", "decode", "base64", "c", "artifact", "bytes", "rest", "run", "step", "result", "previewId", "commit", "envelope", "receipt", "warning", "body", "decision", "completed", "baseVersion", "observationWarnings", "inspect", "label", "read", "fallback", "error", "beforeRevisions", "beforeComments", "beforeAnnotations", "complete", "revisionChanges", "revision", "commentChanges", "comment", "annotationChanges", "annotation", "resultVersion", "warnings", "edit", "packageHash", "internalFailure", "value", "results", "failureOf", "rolledBack", "preflightOne", "preflight", "failedPreflight", "source", "failed", "htmlMode", "shadow", "html", "unwrapRendered", "rendered", "legacyProfileWarning", "retention", "retained", "preview", "depth", "citation", "err", "markdown", "apply", "sourceAnchorId", "targetAnchorId", "fromAnchorId", "toAnchorIdExclusive", "headingAnchorId", "characterOffset", "firstAnchorId", "secondAnchorId", "rule", "ruleJson", "rows", "cols", "optionsJson", "tableAnchorId", "cellAnchorId", "rowIndex", "columnIndex", "rowSpan", "colSpan", "content", "widthsTwips", "spec", "fill", "scope", "repeat", "kind", "field", "format", "op", "pos", "enabled", "bookmarkName", "endnotes", "span", "author", "opts", "spanJson", "revisionId", "parentCommentAnchorId", "commentAnchorId", "resolved", "scopes", "hyperlinkId", "imageBytesToBase64", "imageId", "dimensions", "altText", "title", "layout", "text", "isChecked", "displayText", "timestamp", "sectionAnchorId", "afterItemAnchorId", "itemAnchorId", "name", "range", "newName", "filter", "v", "repairs", "substring", "match", "styleId", "levelDelta", "lastAnchorId", "pattern", "find", "replace", "fold", "l", "isSpace", "isClauseTerm", "isOpen", "isClose", "extendLeft", "extendRight", "newInner", "picker", "kinds", "PlaceholderKinds", "maxPasses", "preserveDollarPrefix", "contextChars", "boundary", "ContextBoundary", "coalesceEmpty", "filled", "workPasses", "errors", "unfilled", "seenSkipKeys", "pass", "placeholders", "a", "b", "cmp", "passChanges", "p", "pick", "replacement", "r", "stillPresent", "json", "raw", "DiffFormat", "serializeVerificationRequest", "annotationId", "labelId", "needle", "regexOptions", "anchorIds", "update", "newAnchorId", "newSpan", "binary", "offset", "openDocxSession", "wasmExports", "settings", "bridge"]
|
|
7
|
+
}
|