@ansonlai/docx-redline-js 0.1.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/AGENTS.md +176 -0
- package/ARCHITECTURE.md +121 -0
- package/LICENSE +21 -0
- package/README.md +177 -0
- package/adapters/config.js +43 -0
- package/adapters/logger.js +89 -0
- package/adapters/xml-adapter.js +74 -0
- package/core/list-targeting.js +398 -0
- package/core/ooxml-identifiers.js +15 -0
- package/core/paragraph-offset-policy.js +50 -0
- package/core/paragraph-targeting.js +501 -0
- package/core/table-targeting.js +233 -0
- package/core/types.js +204 -0
- package/core/xml-query.js +99 -0
- package/dist/docx-redline-js.esm.js +8801 -0
- package/dist/docx-redline-js.esm.js.map +7 -0
- package/dist/docx-redline-js.esm.min.js +195 -0
- package/dist/docx-redline-js.esm.min.js.map +7 -0
- package/engine/format-application.js +358 -0
- package/engine/format-extraction.js +232 -0
- package/engine/format-paragraph-targeting.js +208 -0
- package/engine/format-span-application.js +178 -0
- package/engine/formatting-removal.js +330 -0
- package/engine/oxml-engine.js +279 -0
- package/engine/reconstruction-mapper.js +270 -0
- package/engine/reconstruction-mode.js +38 -0
- package/engine/reconstruction-writer.js +276 -0
- package/engine/rpr-helpers.js +194 -0
- package/engine/run-builders.js +235 -0
- package/engine/surgical-mode.js +520 -0
- package/engine/table-cell-context.js +151 -0
- package/engine/table-mode.js +172 -0
- package/index.js +308 -0
- package/orchestration/list-markdown.js +141 -0
- package/orchestration/list-parsing.js +73 -0
- package/orchestration/list-structural-fallback.js +530 -0
- package/orchestration/redline-operation-converter.js +141 -0
- package/orchestration/route-plan.js +160 -0
- package/package.json +76 -0
- package/pipeline/content-analysis.js +107 -0
- package/pipeline/diff-engine.js +204 -0
- package/pipeline/ingestion-export.js +255 -0
- package/pipeline/ingestion-paragraph.js +351 -0
- package/pipeline/ingestion-table.js +169 -0
- package/pipeline/ingestion-xml.js +39 -0
- package/pipeline/ingestion.js +8 -0
- package/pipeline/list-generation.js +280 -0
- package/pipeline/list-markers.js +77 -0
- package/pipeline/markdown-processor.js +160 -0
- package/pipeline/patching.js +408 -0
- package/pipeline/pipeline.js +326 -0
- package/pipeline/serialization.js +395 -0
- package/services/browser-demo-prompt-context.js +345 -0
- package/services/comment-builders.js +60 -0
- package/services/comment-engine.js +248 -0
- package/services/comment-locator.js +197 -0
- package/services/comment-package.js +113 -0
- package/services/numbering-helpers.js +416 -0
- package/services/numbering-service.js +290 -0
- package/services/package-builder.js +147 -0
- package/services/standalone-docx-plumbing.js +443 -0
- package/services/standalone-operation-runner.js +1169 -0
- package/services/table-reconciliation.js +344 -0
- package/standalone.js +5 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../node_modules/diff-match-patch/index.js", "../adapters/xml-adapter.js", "../adapters/logger.js", "../adapters/config.js", "../pipeline/markdown-processor.js", "../pipeline/list-markers.js", "../core/types.js", "../core/paragraph-offset-policy.js", "../core/xml-query.js", "../pipeline/ingestion-xml.js", "../pipeline/ingestion-paragraph.js", "../pipeline/ingestion-table.js", "../pipeline/diff-engine.js", "../pipeline/patching.js", "../services/package-builder.js", "../pipeline/serialization.js", "../services/numbering-service.js", "../services/table-reconciliation.js", "../pipeline/content-analysis.js", "../pipeline/list-generation.js", "../pipeline/pipeline.js", "../engine/rpr-helpers.js", "../engine/format-extraction.js", "../engine/run-builders.js", "../engine/format-paragraph-targeting.js", "../engine/format-span-application.js", "../engine/format-application.js", "../engine/table-cell-context.js", "../engine/surgical-mode.js", "../engine/reconstruction-mapper.js", "../engine/reconstruction-writer.js", "../engine/reconstruction-mode.js", "../engine/table-mode.js", "../engine/oxml-engine.js", "../core/paragraph-targeting.js", "../core/list-targeting.js", "../orchestration/list-parsing.js", "../orchestration/list-markdown.js", "../orchestration/list-structural-fallback.js", "../core/table-targeting.js", "../services/numbering-helpers.js", "../pipeline/ingestion-export.js", "../services/comment-builders.js", "../services/comment-locator.js", "../services/comment-package.js", "../services/comment-engine.js", "../engine/formatting-removal.js", "../services/standalone-docx-plumbing.js", "../orchestration/route-plan.js", "../core/ooxml-identifiers.js", "../index.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * Diff Match and Patch\n * Copyright 2018 The diff-match-patch Authors.\n * https://github.com/google/diff-match-patch\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Computes the difference between two texts to create a patch.\n * Applies the patch onto another text, allowing for errors.\n * @author fraser@google.com (Neil Fraser)\n */\n\n/**\n * Class containing the diff, match and patch methods.\n * @constructor\n */\nvar diff_match_patch = function() {\n\n // Defaults.\n // Redefine these in your program to override the defaults.\n\n // Number of seconds to map a diff before giving up (0 for infinity).\n this.Diff_Timeout = 1.0;\n // Cost of an empty edit operation in terms of edit characters.\n this.Diff_EditCost = 4;\n // At what point is no match declared (0.0 = perfection, 1.0 = very loose).\n this.Match_Threshold = 0.5;\n // How far to search for a match (0 = exact location, 1000+ = broad match).\n // A match this many characters away from the expected location will add\n // 1.0 to the score (0.0 is a perfect match).\n this.Match_Distance = 1000;\n // When deleting a large block of text (over ~64 characters), how close do\n // the contents have to be to match the expected contents. (0.0 = perfection,\n // 1.0 = very loose). Note that Match_Threshold controls how closely the\n // end points of a delete need to match.\n this.Patch_DeleteThreshold = 0.5;\n // Chunk size for context length.\n this.Patch_Margin = 4;\n\n // The number of bits in an int.\n this.Match_MaxBits = 32;\n};\n\n\n// DIFF FUNCTIONS\n\n\n/**\n * The data structure representing a diff is an array of tuples:\n * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]\n * which means: delete 'Hello', add 'Goodbye' and keep ' world.'\n */\nvar DIFF_DELETE = -1;\nvar DIFF_INSERT = 1;\nvar DIFF_EQUAL = 0;\n\n/**\n * Class representing one diff tuple.\n * ~Attempts to look like a two-element array (which is what this used to be).~\n * Constructor returns an actual two-element array, to allow destructing @JackuB\n * See https://github.com/JackuB/diff-match-patch/issues/14 for details\n * @param {number} op Operation, one of: DIFF_DELETE, DIFF_INSERT, DIFF_EQUAL.\n * @param {string} text Text to be deleted, inserted, or retained.\n * @constructor\n */\ndiff_match_patch.Diff = function(op, text) {\n return [op, text];\n};\n\n/**\n * Find the differences between two texts. Simplifies the problem by stripping\n * any common prefix or suffix off the texts before diffing.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean=} opt_checklines Optional speedup flag. If present and false,\n * then don't run a line-level diff first to identify the changed areas.\n * Defaults to true, which does a faster, slightly less optimal diff.\n * @param {number=} opt_deadline Optional time when the diff should be complete\n * by. Used internally for recursive calls. Users should set DiffTimeout\n * instead.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_main = function(text1, text2, opt_checklines,\n opt_deadline) {\n // Set a deadline by which time the diff must be complete.\n if (typeof opt_deadline == 'undefined') {\n if (this.Diff_Timeout <= 0) {\n opt_deadline = Number.MAX_VALUE;\n } else {\n opt_deadline = (new Date).getTime() + this.Diff_Timeout * 1000;\n }\n }\n var deadline = opt_deadline;\n\n // Check for null inputs.\n if (text1 == null || text2 == null) {\n throw new Error('Null input. (diff_main)');\n }\n\n // Check for equality (speedup).\n if (text1 == text2) {\n if (text1) {\n return [new diff_match_patch.Diff(DIFF_EQUAL, text1)];\n }\n return [];\n }\n\n if (typeof opt_checklines == 'undefined') {\n opt_checklines = true;\n }\n var checklines = opt_checklines;\n\n // Trim off common prefix (speedup).\n var commonlength = this.diff_commonPrefix(text1, text2);\n var commonprefix = text1.substring(0, commonlength);\n text1 = text1.substring(commonlength);\n text2 = text2.substring(commonlength);\n\n // Trim off common suffix (speedup).\n commonlength = this.diff_commonSuffix(text1, text2);\n var commonsuffix = text1.substring(text1.length - commonlength);\n text1 = text1.substring(0, text1.length - commonlength);\n text2 = text2.substring(0, text2.length - commonlength);\n\n // Compute the diff on the middle block.\n var diffs = this.diff_compute_(text1, text2, checklines, deadline);\n\n // Restore the prefix and suffix.\n if (commonprefix) {\n diffs.unshift(new diff_match_patch.Diff(DIFF_EQUAL, commonprefix));\n }\n if (commonsuffix) {\n diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, commonsuffix));\n }\n this.diff_cleanupMerge(diffs);\n return diffs;\n};\n\n\n/**\n * Find the differences between two texts. Assumes that the texts do not\n * have any common prefix or suffix.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean} checklines Speedup flag. If false, then don't run a\n * line-level diff first to identify the changed areas.\n * If true, then run a faster, slightly less optimal diff.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_compute_ = function(text1, text2, checklines,\n deadline) {\n var diffs;\n\n if (!text1) {\n // Just add some text (speedup).\n return [new diff_match_patch.Diff(DIFF_INSERT, text2)];\n }\n\n if (!text2) {\n // Just delete some text (speedup).\n return [new diff_match_patch.Diff(DIFF_DELETE, text1)];\n }\n\n var longtext = text1.length > text2.length ? text1 : text2;\n var shorttext = text1.length > text2.length ? text2 : text1;\n var i = longtext.indexOf(shorttext);\n if (i != -1) {\n // Shorter text is inside the longer text (speedup).\n diffs = [new diff_match_patch.Diff(DIFF_INSERT, longtext.substring(0, i)),\n new diff_match_patch.Diff(DIFF_EQUAL, shorttext),\n new diff_match_patch.Diff(DIFF_INSERT,\n longtext.substring(i + shorttext.length))];\n // Swap insertions for deletions if diff is reversed.\n if (text1.length > text2.length) {\n diffs[0][0] = diffs[2][0] = DIFF_DELETE;\n }\n return diffs;\n }\n\n if (shorttext.length == 1) {\n // Single character string.\n // After the previous speedup, the character can't be an equality.\n return [new diff_match_patch.Diff(DIFF_DELETE, text1),\n new diff_match_patch.Diff(DIFF_INSERT, text2)];\n }\n\n // Check to see if the problem can be split in two.\n var hm = this.diff_halfMatch_(text1, text2);\n if (hm) {\n // A half-match was found, sort out the return data.\n var text1_a = hm[0];\n var text1_b = hm[1];\n var text2_a = hm[2];\n var text2_b = hm[3];\n var mid_common = hm[4];\n // Send both pairs off for separate processing.\n var diffs_a = this.diff_main(text1_a, text2_a, checklines, deadline);\n var diffs_b = this.diff_main(text1_b, text2_b, checklines, deadline);\n // Merge the results.\n return diffs_a.concat([new diff_match_patch.Diff(DIFF_EQUAL, mid_common)],\n diffs_b);\n }\n\n if (checklines && text1.length > 100 && text2.length > 100) {\n return this.diff_lineMode_(text1, text2, deadline);\n }\n\n return this.diff_bisect_(text1, text2, deadline);\n};\n\n\n/**\n * Do a quick line-level diff on both strings, then rediff the parts for\n * greater accuracy.\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_lineMode_ = function(text1, text2, deadline) {\n // Scan the text on a line-by-line basis first.\n var a = this.diff_linesToChars_(text1, text2);\n text1 = a.chars1;\n text2 = a.chars2;\n var linearray = a.lineArray;\n\n var diffs = this.diff_main(text1, text2, false, deadline);\n\n // Convert the diff back to original text.\n this.diff_charsToLines_(diffs, linearray);\n // Eliminate freak matches (e.g. blank lines)\n this.diff_cleanupSemantic(diffs);\n\n // Rediff any replacement blocks, this time character-by-character.\n // Add a dummy entry at the end.\n diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, ''));\n var pointer = 0;\n var count_delete = 0;\n var count_insert = 0;\n var text_delete = '';\n var text_insert = '';\n while (pointer < diffs.length) {\n switch (diffs[pointer][0]) {\n case DIFF_INSERT:\n count_insert++;\n text_insert += diffs[pointer][1];\n break;\n case DIFF_DELETE:\n count_delete++;\n text_delete += diffs[pointer][1];\n break;\n case DIFF_EQUAL:\n // Upon reaching an equality, check for prior redundancies.\n if (count_delete >= 1 && count_insert >= 1) {\n // Delete the offending records and add the merged ones.\n diffs.splice(pointer - count_delete - count_insert,\n count_delete + count_insert);\n pointer = pointer - count_delete - count_insert;\n var subDiff =\n this.diff_main(text_delete, text_insert, false, deadline);\n for (var j = subDiff.length - 1; j >= 0; j--) {\n diffs.splice(pointer, 0, subDiff[j]);\n }\n pointer = pointer + subDiff.length;\n }\n count_insert = 0;\n count_delete = 0;\n text_delete = '';\n text_insert = '';\n break;\n }\n pointer++;\n }\n diffs.pop(); // Remove the dummy entry at the end.\n\n return diffs;\n};\n\n\n/**\n * Find the 'middle snake' of a diff, split the problem in two\n * and return the recursively constructed diff.\n * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_bisect_ = function(text1, text2, deadline) {\n // Cache the text lengths to prevent multiple calls.\n var text1_length = text1.length;\n var text2_length = text2.length;\n var max_d = Math.ceil((text1_length + text2_length) / 2);\n var v_offset = max_d;\n var v_length = 2 * max_d;\n var v1 = new Array(v_length);\n var v2 = new Array(v_length);\n // Setting all elements to -1 is faster in Chrome & Firefox than mixing\n // integers and undefined.\n for (var x = 0; x < v_length; x++) {\n v1[x] = -1;\n v2[x] = -1;\n }\n v1[v_offset + 1] = 0;\n v2[v_offset + 1] = 0;\n var delta = text1_length - text2_length;\n // If the total number of characters is odd, then the front path will collide\n // with the reverse path.\n var front = (delta % 2 != 0);\n // Offsets for start and end of k loop.\n // Prevents mapping of space beyond the grid.\n var k1start = 0;\n var k1end = 0;\n var k2start = 0;\n var k2end = 0;\n for (var d = 0; d < max_d; d++) {\n // Bail out if deadline is reached.\n if ((new Date()).getTime() > deadline) {\n break;\n }\n\n // Walk the front path one step.\n for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {\n var k1_offset = v_offset + k1;\n var x1;\n if (k1 == -d || (k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1])) {\n x1 = v1[k1_offset + 1];\n } else {\n x1 = v1[k1_offset - 1] + 1;\n }\n var y1 = x1 - k1;\n while (x1 < text1_length && y1 < text2_length &&\n text1.charAt(x1) == text2.charAt(y1)) {\n x1++;\n y1++;\n }\n v1[k1_offset] = x1;\n if (x1 > text1_length) {\n // Ran off the right of the graph.\n k1end += 2;\n } else if (y1 > text2_length) {\n // Ran off the bottom of the graph.\n k1start += 2;\n } else if (front) {\n var k2_offset = v_offset + delta - k1;\n if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) {\n // Mirror x2 onto top-left coordinate system.\n var x2 = text1_length - v2[k2_offset];\n if (x1 >= x2) {\n // Overlap detected.\n return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);\n }\n }\n }\n }\n\n // Walk the reverse path one step.\n for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {\n var k2_offset = v_offset + k2;\n var x2;\n if (k2 == -d || (k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1])) {\n x2 = v2[k2_offset + 1];\n } else {\n x2 = v2[k2_offset - 1] + 1;\n }\n var y2 = x2 - k2;\n while (x2 < text1_length && y2 < text2_length &&\n text1.charAt(text1_length - x2 - 1) ==\n text2.charAt(text2_length - y2 - 1)) {\n x2++;\n y2++;\n }\n v2[k2_offset] = x2;\n if (x2 > text1_length) {\n // Ran off the left of the graph.\n k2end += 2;\n } else if (y2 > text2_length) {\n // Ran off the top of the graph.\n k2start += 2;\n } else if (!front) {\n var k1_offset = v_offset + delta - k2;\n if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) {\n var x1 = v1[k1_offset];\n var y1 = v_offset + x1 - k1_offset;\n // Mirror x2 onto top-left coordinate system.\n x2 = text1_length - x2;\n if (x1 >= x2) {\n // Overlap detected.\n return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);\n }\n }\n }\n }\n }\n // Diff took too long and hit the deadline or\n // number of diffs equals number of characters, no commonality at all.\n return [new diff_match_patch.Diff(DIFF_DELETE, text1),\n new diff_match_patch.Diff(DIFF_INSERT, text2)];\n};\n\n\n/**\n * Given the location of the 'middle snake', split the diff in two parts\n * and recurse.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} x Index of split point in text1.\n * @param {number} y Index of split point in text2.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_bisectSplit_ = function(text1, text2, x, y,\n deadline) {\n var text1a = text1.substring(0, x);\n var text2a = text2.substring(0, y);\n var text1b = text1.substring(x);\n var text2b = text2.substring(y);\n\n // Compute both diffs serially.\n var diffs = this.diff_main(text1a, text2a, false, deadline);\n var diffsb = this.diff_main(text1b, text2b, false, deadline);\n\n return diffs.concat(diffsb);\n};\n\n\n/**\n * Split two texts into an array of strings. Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {{chars1: string, chars2: string, lineArray: !Array.<string>}}\n * An object containing the encoded text1, the encoded text2 and\n * the array of unique strings.\n * The zeroth element of the array of unique strings is intentionally blank.\n * @private\n */\ndiff_match_patch.prototype.diff_linesToChars_ = function(text1, text2) {\n var lineArray = []; // e.g. lineArray[4] == 'Hello\\n'\n var lineHash = {}; // e.g. lineHash['Hello\\n'] == 4\n\n // '\\x00' is a valid character, but various debuggers don't like it.\n // So we'll insert a junk entry to avoid generating a null character.\n lineArray[0] = '';\n\n /**\n * Split a text into an array of strings. Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * Modifies linearray and linehash through being a closure.\n * @param {string} text String to encode.\n * @return {string} Encoded string.\n * @private\n */\n function diff_linesToCharsMunge_(text) {\n var chars = '';\n // Walk the text, pulling out a substring for each line.\n // text.split('\\n') would would temporarily double our memory footprint.\n // Modifying text would create many large strings to garbage collect.\n var lineStart = 0;\n var lineEnd = -1;\n // Keeping our own length variable is faster than looking it up.\n var lineArrayLength = lineArray.length;\n while (lineEnd < text.length - 1) {\n lineEnd = text.indexOf('\\n', lineStart);\n if (lineEnd == -1) {\n lineEnd = text.length - 1;\n }\n var line = text.substring(lineStart, lineEnd + 1);\n\n if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) :\n (lineHash[line] !== undefined)) {\n chars += String.fromCharCode(lineHash[line]);\n } else {\n if (lineArrayLength == maxLines) {\n // Bail out at 65535 because\n // String.fromCharCode(65536) == String.fromCharCode(0)\n line = text.substring(lineStart);\n lineEnd = text.length;\n }\n chars += String.fromCharCode(lineArrayLength);\n lineHash[line] = lineArrayLength;\n lineArray[lineArrayLength++] = line;\n }\n lineStart = lineEnd + 1;\n }\n return chars;\n }\n // Allocate 2/3rds of the space for text1, the rest for text2.\n var maxLines = 40000;\n var chars1 = diff_linesToCharsMunge_(text1);\n maxLines = 65535;\n var chars2 = diff_linesToCharsMunge_(text2);\n return {chars1: chars1, chars2: chars2, lineArray: lineArray};\n};\n\n\n/**\n * Rehydrate the text in a diff from a string of line hashes to real lines of\n * text.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @param {!Array.<string>} lineArray Array of unique strings.\n * @private\n */\ndiff_match_patch.prototype.diff_charsToLines_ = function(diffs, lineArray) {\n for (var i = 0; i < diffs.length; i++) {\n var chars = diffs[i][1];\n var text = [];\n for (var j = 0; j < chars.length; j++) {\n text[j] = lineArray[chars.charCodeAt(j)];\n }\n diffs[i][1] = text.join('');\n }\n};\n\n\n/**\n * Determine the common prefix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the start of each\n * string.\n */\ndiff_match_patch.prototype.diff_commonPrefix = function(text1, text2) {\n // Quick check for common null cases.\n if (!text1 || !text2 || text1.charAt(0) != text2.charAt(0)) {\n return 0;\n }\n // Binary search.\n // Performance analysis: https://neil.fraser.name/news/2007/10/09/\n var pointermin = 0;\n var pointermax = Math.min(text1.length, text2.length);\n var pointermid = pointermax;\n var pointerstart = 0;\n while (pointermin < pointermid) {\n if (text1.substring(pointerstart, pointermid) ==\n text2.substring(pointerstart, pointermid)) {\n pointermin = pointermid;\n pointerstart = pointermin;\n } else {\n pointermax = pointermid;\n }\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n return pointermid;\n};\n\n\n/**\n * Determine the common suffix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of each string.\n */\ndiff_match_patch.prototype.diff_commonSuffix = function(text1, text2) {\n // Quick check for common null cases.\n if (!text1 || !text2 ||\n text1.charAt(text1.length - 1) != text2.charAt(text2.length - 1)) {\n return 0;\n }\n // Binary search.\n // Performance analysis: https://neil.fraser.name/news/2007/10/09/\n var pointermin = 0;\n var pointermax = Math.min(text1.length, text2.length);\n var pointermid = pointermax;\n var pointerend = 0;\n while (pointermin < pointermid) {\n if (text1.substring(text1.length - pointermid, text1.length - pointerend) ==\n text2.substring(text2.length - pointermid, text2.length - pointerend)) {\n pointermin = pointermid;\n pointerend = pointermin;\n } else {\n pointermax = pointermid;\n }\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n return pointermid;\n};\n\n\n/**\n * Determine if the suffix of one string is the prefix of another.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of the first\n * string and the start of the second string.\n * @private\n */\ndiff_match_patch.prototype.diff_commonOverlap_ = function(text1, text2) {\n // Cache the text lengths to prevent multiple calls.\n var text1_length = text1.length;\n var text2_length = text2.length;\n // Eliminate the null case.\n if (text1_length == 0 || text2_length == 0) {\n return 0;\n }\n // Truncate the longer string.\n if (text1_length > text2_length) {\n text1 = text1.substring(text1_length - text2_length);\n } else if (text1_length < text2_length) {\n text2 = text2.substring(0, text1_length);\n }\n var text_length = Math.min(text1_length, text2_length);\n // Quick check for the worst case.\n if (text1 == text2) {\n return text_length;\n }\n\n // Start by looking for a single character match\n // and increase length until no match is found.\n // Performance analysis: https://neil.fraser.name/news/2010/11/04/\n var best = 0;\n var length = 1;\n while (true) {\n var pattern = text1.substring(text_length - length);\n var found = text2.indexOf(pattern);\n if (found == -1) {\n return best;\n }\n length += found;\n if (found == 0 || text1.substring(text_length - length) ==\n text2.substring(0, length)) {\n best = length;\n length++;\n }\n }\n};\n\n\n/**\n * Do the two texts share a substring which is at least half the length of the\n * longer text?\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {Array.<string>} Five element Array, containing the prefix of\n * text1, the suffix of text1, the prefix of text2, the suffix of\n * text2 and the common middle. Or null if there was no match.\n * @private\n */\ndiff_match_patch.prototype.diff_halfMatch_ = function(text1, text2) {\n if (this.Diff_Timeout <= 0) {\n // Don't risk returning a non-optimal diff if we have unlimited time.\n return null;\n }\n var longtext = text1.length > text2.length ? text1 : text2;\n var shorttext = text1.length > text2.length ? text2 : text1;\n if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {\n return null; // Pointless.\n }\n var dmp = this; // 'this' becomes 'window' in a closure.\n\n /**\n * Does a substring of shorttext exist within longtext such that the substring\n * is at least half the length of longtext?\n * Closure, but does not reference any external variables.\n * @param {string} longtext Longer string.\n * @param {string} shorttext Shorter string.\n * @param {number} i Start index of quarter length substring within longtext.\n * @return {Array.<string>} Five element Array, containing the prefix of\n * longtext, the suffix of longtext, the prefix of shorttext, the suffix\n * of shorttext and the common middle. Or null if there was no match.\n * @private\n */\n function diff_halfMatchI_(longtext, shorttext, i) {\n // Start with a 1/4 length substring at position i as a seed.\n var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));\n var j = -1;\n var best_common = '';\n var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;\n while ((j = shorttext.indexOf(seed, j + 1)) != -1) {\n var prefixLength = dmp.diff_commonPrefix(longtext.substring(i),\n shorttext.substring(j));\n var suffixLength = dmp.diff_commonSuffix(longtext.substring(0, i),\n shorttext.substring(0, j));\n if (best_common.length < suffixLength + prefixLength) {\n best_common = shorttext.substring(j - suffixLength, j) +\n shorttext.substring(j, j + prefixLength);\n best_longtext_a = longtext.substring(0, i - suffixLength);\n best_longtext_b = longtext.substring(i + prefixLength);\n best_shorttext_a = shorttext.substring(0, j - suffixLength);\n best_shorttext_b = shorttext.substring(j + prefixLength);\n }\n }\n if (best_common.length * 2 >= longtext.length) {\n return [best_longtext_a, best_longtext_b,\n best_shorttext_a, best_shorttext_b, best_common];\n } else {\n return null;\n }\n }\n\n // First check if the second quarter is the seed for a half-match.\n var hm1 = diff_halfMatchI_(longtext, shorttext,\n Math.ceil(longtext.length / 4));\n // Check again based on the third quarter.\n var hm2 = diff_halfMatchI_(longtext, shorttext,\n Math.ceil(longtext.length / 2));\n var hm;\n if (!hm1 && !hm2) {\n return null;\n } else if (!hm2) {\n hm = hm1;\n } else if (!hm1) {\n hm = hm2;\n } else {\n // Both matched. Select the longest.\n hm = hm1[4].length > hm2[4].length ? hm1 : hm2;\n }\n\n // A half-match was found, sort out the return data.\n var text1_a, text1_b, text2_a, text2_b;\n if (text1.length > text2.length) {\n text1_a = hm[0];\n text1_b = hm[1];\n text2_a = hm[2];\n text2_b = hm[3];\n } else {\n text2_a = hm[0];\n text2_b = hm[1];\n text1_a = hm[2];\n text1_b = hm[3];\n }\n var mid_common = hm[4];\n return [text1_a, text1_b, text2_a, text2_b, mid_common];\n};\n\n\n/**\n * Reduce the number of edits by eliminating semantically trivial equalities.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupSemantic = function(diffs) {\n var changes = false;\n var equalities = []; // Stack of indices where equalities are found.\n var equalitiesLength = 0; // Keeping our own length var is faster in JS.\n /** @type {?string} */\n var lastEquality = null;\n // Always equal to diffs[equalities[equalitiesLength - 1]][1]\n var pointer = 0; // Index of current position.\n // Number of characters that changed prior to the equality.\n var length_insertions1 = 0;\n var length_deletions1 = 0;\n // Number of characters that changed after the equality.\n var length_insertions2 = 0;\n var length_deletions2 = 0;\n while (pointer < diffs.length) {\n if (diffs[pointer][0] == DIFF_EQUAL) { // Equality found.\n equalities[equalitiesLength++] = pointer;\n length_insertions1 = length_insertions2;\n length_deletions1 = length_deletions2;\n length_insertions2 = 0;\n length_deletions2 = 0;\n lastEquality = diffs[pointer][1];\n } else { // An insertion or deletion.\n if (diffs[pointer][0] == DIFF_INSERT) {\n length_insertions2 += diffs[pointer][1].length;\n } else {\n length_deletions2 += diffs[pointer][1].length;\n }\n // Eliminate an equality that is smaller or equal to the edits on both\n // sides of it.\n if (lastEquality && (lastEquality.length <=\n Math.max(length_insertions1, length_deletions1)) &&\n (lastEquality.length <= Math.max(length_insertions2,\n length_deletions2))) {\n // Duplicate record.\n diffs.splice(equalities[equalitiesLength - 1], 0,\n new diff_match_patch.Diff(DIFF_DELETE, lastEquality));\n // Change second copy to insert.\n diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;\n // Throw away the equality we just deleted.\n equalitiesLength--;\n // Throw away the previous equality (it needs to be reevaluated).\n equalitiesLength--;\n pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;\n length_insertions1 = 0; // Reset the counters.\n length_deletions1 = 0;\n length_insertions2 = 0;\n length_deletions2 = 0;\n lastEquality = null;\n changes = true;\n }\n }\n pointer++;\n }\n\n // Normalize the diff.\n if (changes) {\n this.diff_cleanupMerge(diffs);\n }\n this.diff_cleanupSemanticLossless(diffs);\n\n // Find any overlaps between deletions and insertions.\n // e.g: <del>abcxxx</del><ins>xxxdef</ins>\n // -> <del>abc</del>xxx<ins>def</ins>\n // e.g: <del>xxxabc</del><ins>defxxx</ins>\n // -> <ins>def</ins>xxx<del>abc</del>\n // Only extract an overlap if it is as big as the edit ahead or behind it.\n pointer = 1;\n while (pointer < diffs.length) {\n if (diffs[pointer - 1][0] == DIFF_DELETE &&\n diffs[pointer][0] == DIFF_INSERT) {\n var deletion = diffs[pointer - 1][1];\n var insertion = diffs[pointer][1];\n var overlap_length1 = this.diff_commonOverlap_(deletion, insertion);\n var overlap_length2 = this.diff_commonOverlap_(insertion, deletion);\n if (overlap_length1 >= overlap_length2) {\n if (overlap_length1 >= deletion.length / 2 ||\n overlap_length1 >= insertion.length / 2) {\n // Overlap found. Insert an equality and trim the surrounding edits.\n diffs.splice(pointer, 0, new diff_match_patch.Diff(DIFF_EQUAL,\n insertion.substring(0, overlap_length1)));\n diffs[pointer - 1][1] =\n deletion.substring(0, deletion.length - overlap_length1);\n diffs[pointer + 1][1] = insertion.substring(overlap_length1);\n pointer++;\n }\n } else {\n if (overlap_length2 >= deletion.length / 2 ||\n overlap_length2 >= insertion.length / 2) {\n // Reverse overlap found.\n // Insert an equality and swap and trim the surrounding edits.\n diffs.splice(pointer, 0, new diff_match_patch.Diff(DIFF_EQUAL,\n deletion.substring(0, overlap_length2)));\n diffs[pointer - 1][0] = DIFF_INSERT;\n diffs[pointer - 1][1] =\n insertion.substring(0, insertion.length - overlap_length2);\n diffs[pointer + 1][0] = DIFF_DELETE;\n diffs[pointer + 1][1] =\n deletion.substring(overlap_length2);\n pointer++;\n }\n }\n pointer++;\n }\n pointer++;\n }\n};\n\n\n/**\n * Look for single edits surrounded on both sides by equalities\n * which can be shifted sideways to align the edit to a word boundary.\n * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupSemanticLossless = function(diffs) {\n /**\n * Given two strings, compute a score representing whether the internal\n * boundary falls on logical boundaries.\n * Scores range from 6 (best) to 0 (worst).\n * Closure, but does not reference any external variables.\n * @param {string} one First string.\n * @param {string} two Second string.\n * @return {number} The score.\n * @private\n */\n function diff_cleanupSemanticScore_(one, two) {\n if (!one || !two) {\n // Edges are the best.\n return 6;\n }\n\n // Each port of this function behaves slightly differently due to\n // subtle differences in each language's definition of things like\n // 'whitespace'. Since this function's purpose is largely cosmetic,\n // the choice has been made to use each language's native features\n // rather than force total conformity.\n var char1 = one.charAt(one.length - 1);\n var char2 = two.charAt(0);\n var nonAlphaNumeric1 = char1.match(diff_match_patch.nonAlphaNumericRegex_);\n var nonAlphaNumeric2 = char2.match(diff_match_patch.nonAlphaNumericRegex_);\n var whitespace1 = nonAlphaNumeric1 &&\n char1.match(diff_match_patch.whitespaceRegex_);\n var whitespace2 = nonAlphaNumeric2 &&\n char2.match(diff_match_patch.whitespaceRegex_);\n var lineBreak1 = whitespace1 &&\n char1.match(diff_match_patch.linebreakRegex_);\n var lineBreak2 = whitespace2 &&\n char2.match(diff_match_patch.linebreakRegex_);\n var blankLine1 = lineBreak1 &&\n one.match(diff_match_patch.blanklineEndRegex_);\n var blankLine2 = lineBreak2 &&\n two.match(diff_match_patch.blanklineStartRegex_);\n\n if (blankLine1 || blankLine2) {\n // Five points for blank lines.\n return 5;\n } else if (lineBreak1 || lineBreak2) {\n // Four points for line breaks.\n return 4;\n } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) {\n // Three points for end of sentences.\n return 3;\n } else if (whitespace1 || whitespace2) {\n // Two points for whitespace.\n return 2;\n } else if (nonAlphaNumeric1 || nonAlphaNumeric2) {\n // One point for non-alphanumeric.\n return 1;\n }\n return 0;\n }\n\n var pointer = 1;\n // Intentionally ignore the first and last element (don't need checking).\n while (pointer < diffs.length - 1) {\n if (diffs[pointer - 1][0] == DIFF_EQUAL &&\n diffs[pointer + 1][0] == DIFF_EQUAL) {\n // This is a single edit surrounded by equalities.\n var equality1 = diffs[pointer - 1][1];\n var edit = diffs[pointer][1];\n var equality2 = diffs[pointer + 1][1];\n\n // First, shift the edit as far left as possible.\n var commonOffset = this.diff_commonSuffix(equality1, edit);\n if (commonOffset) {\n var commonString = edit.substring(edit.length - commonOffset);\n equality1 = equality1.substring(0, equality1.length - commonOffset);\n edit = commonString + edit.substring(0, edit.length - commonOffset);\n equality2 = commonString + equality2;\n }\n\n // Second, step character by character right, looking for the best fit.\n var bestEquality1 = equality1;\n var bestEdit = edit;\n var bestEquality2 = equality2;\n var bestScore = diff_cleanupSemanticScore_(equality1, edit) +\n diff_cleanupSemanticScore_(edit, equality2);\n while (edit.charAt(0) === equality2.charAt(0)) {\n equality1 += edit.charAt(0);\n edit = edit.substring(1) + equality2.charAt(0);\n equality2 = equality2.substring(1);\n var score = diff_cleanupSemanticScore_(equality1, edit) +\n diff_cleanupSemanticScore_(edit, equality2);\n // The >= encourages trailing rather than leading whitespace on edits.\n if (score >= bestScore) {\n bestScore = score;\n bestEquality1 = equality1;\n bestEdit = edit;\n bestEquality2 = equality2;\n }\n }\n\n if (diffs[pointer - 1][1] != bestEquality1) {\n // We have an improvement, save it back to the diff.\n if (bestEquality1) {\n diffs[pointer - 1][1] = bestEquality1;\n } else {\n diffs.splice(pointer - 1, 1);\n pointer--;\n }\n diffs[pointer][1] = bestEdit;\n if (bestEquality2) {\n diffs[pointer + 1][1] = bestEquality2;\n } else {\n diffs.splice(pointer + 1, 1);\n pointer--;\n }\n }\n }\n pointer++;\n }\n};\n\n// Define some regex patterns for matching boundaries.\ndiff_match_patch.nonAlphaNumericRegex_ = /[^a-zA-Z0-9]/;\ndiff_match_patch.whitespaceRegex_ = /\\s/;\ndiff_match_patch.linebreakRegex_ = /[\\r\\n]/;\ndiff_match_patch.blanklineEndRegex_ = /\\n\\r?\\n$/;\ndiff_match_patch.blanklineStartRegex_ = /^\\r?\\n\\r?\\n/;\n\n/**\n * Reduce the number of edits by eliminating operationally trivial equalities.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupEfficiency = function(diffs) {\n var changes = false;\n var equalities = []; // Stack of indices where equalities are found.\n var equalitiesLength = 0; // Keeping our own length var is faster in JS.\n /** @type {?string} */\n var lastEquality = null;\n // Always equal to diffs[equalities[equalitiesLength - 1]][1]\n var pointer = 0; // Index of current position.\n // Is there an insertion operation before the last equality.\n var pre_ins = false;\n // Is there a deletion operation before the last equality.\n var pre_del = false;\n // Is there an insertion operation after the last equality.\n var post_ins = false;\n // Is there a deletion operation after the last equality.\n var post_del = false;\n while (pointer < diffs.length) {\n if (diffs[pointer][0] == DIFF_EQUAL) { // Equality found.\n if (diffs[pointer][1].length < this.Diff_EditCost &&\n (post_ins || post_del)) {\n // Candidate found.\n equalities[equalitiesLength++] = pointer;\n pre_ins = post_ins;\n pre_del = post_del;\n lastEquality = diffs[pointer][1];\n } else {\n // Not a candidate, and can never become one.\n equalitiesLength = 0;\n lastEquality = null;\n }\n post_ins = post_del = false;\n } else { // An insertion or deletion.\n if (diffs[pointer][0] == DIFF_DELETE) {\n post_del = true;\n } else {\n post_ins = true;\n }\n /*\n * Five types to be split:\n * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>\n * <ins>A</ins>X<ins>C</ins><del>D</del>\n * <ins>A</ins><del>B</del>X<ins>C</ins>\n * <ins>A</del>X<ins>C</ins><del>D</del>\n * <ins>A</ins><del>B</del>X<del>C</del>\n */\n if (lastEquality && ((pre_ins && pre_del && post_ins && post_del) ||\n ((lastEquality.length < this.Diff_EditCost / 2) &&\n (pre_ins + pre_del + post_ins + post_del) == 3))) {\n // Duplicate record.\n diffs.splice(equalities[equalitiesLength - 1], 0,\n new diff_match_patch.Diff(DIFF_DELETE, lastEquality));\n // Change second copy to insert.\n diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;\n equalitiesLength--; // Throw away the equality we just deleted;\n lastEquality = null;\n if (pre_ins && pre_del) {\n // No changes made which could affect previous entry, keep going.\n post_ins = post_del = true;\n equalitiesLength = 0;\n } else {\n equalitiesLength--; // Throw away the previous equality.\n pointer = equalitiesLength > 0 ?\n equalities[equalitiesLength - 1] : -1;\n post_ins = post_del = false;\n }\n changes = true;\n }\n }\n pointer++;\n }\n\n if (changes) {\n this.diff_cleanupMerge(diffs);\n }\n};\n\n\n/**\n * Reorder and merge like edit sections. Merge equalities.\n * Any edit section can move as long as it doesn't cross an equality.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupMerge = function(diffs) {\n // Add a dummy entry at the end.\n diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, ''));\n var pointer = 0;\n var count_delete = 0;\n var count_insert = 0;\n var text_delete = '';\n var text_insert = '';\n var commonlength;\n while (pointer < diffs.length) {\n switch (diffs[pointer][0]) {\n case DIFF_INSERT:\n count_insert++;\n text_insert += diffs[pointer][1];\n pointer++;\n break;\n case DIFF_DELETE:\n count_delete++;\n text_delete += diffs[pointer][1];\n pointer++;\n break;\n case DIFF_EQUAL:\n // Upon reaching an equality, check for prior redundancies.\n if (count_delete + count_insert > 1) {\n if (count_delete !== 0 && count_insert !== 0) {\n // Factor out any common prefixies.\n commonlength = this.diff_commonPrefix(text_insert, text_delete);\n if (commonlength !== 0) {\n if ((pointer - count_delete - count_insert) > 0 &&\n diffs[pointer - count_delete - count_insert - 1][0] ==\n DIFF_EQUAL) {\n diffs[pointer - count_delete - count_insert - 1][1] +=\n text_insert.substring(0, commonlength);\n } else {\n diffs.splice(0, 0, new diff_match_patch.Diff(DIFF_EQUAL,\n text_insert.substring(0, commonlength)));\n pointer++;\n }\n text_insert = text_insert.substring(commonlength);\n text_delete = text_delete.substring(commonlength);\n }\n // Factor out any common suffixies.\n commonlength = this.diff_commonSuffix(text_insert, text_delete);\n if (commonlength !== 0) {\n diffs[pointer][1] = text_insert.substring(text_insert.length -\n commonlength) + diffs[pointer][1];\n text_insert = text_insert.substring(0, text_insert.length -\n commonlength);\n text_delete = text_delete.substring(0, text_delete.length -\n commonlength);\n }\n }\n // Delete the offending records and add the merged ones.\n pointer -= count_delete + count_insert;\n diffs.splice(pointer, count_delete + count_insert);\n if (text_delete.length) {\n diffs.splice(pointer, 0,\n new diff_match_patch.Diff(DIFF_DELETE, text_delete));\n pointer++;\n }\n if (text_insert.length) {\n diffs.splice(pointer, 0,\n new diff_match_patch.Diff(DIFF_INSERT, text_insert));\n pointer++;\n }\n pointer++;\n } else if (pointer !== 0 && diffs[pointer - 1][0] == DIFF_EQUAL) {\n // Merge this equality with the previous one.\n diffs[pointer - 1][1] += diffs[pointer][1];\n diffs.splice(pointer, 1);\n } else {\n pointer++;\n }\n count_insert = 0;\n count_delete = 0;\n text_delete = '';\n text_insert = '';\n break;\n }\n }\n if (diffs[diffs.length - 1][1] === '') {\n diffs.pop(); // Remove the dummy entry at the end.\n }\n\n // Second pass: look for single edits surrounded on both sides by equalities\n // which can be shifted sideways to eliminate an equality.\n // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC\n var changes = false;\n pointer = 1;\n // Intentionally ignore the first and last element (don't need checking).\n while (pointer < diffs.length - 1) {\n if (diffs[pointer - 1][0] == DIFF_EQUAL &&\n diffs[pointer + 1][0] == DIFF_EQUAL) {\n // This is a single edit surrounded by equalities.\n if (diffs[pointer][1].substring(diffs[pointer][1].length -\n diffs[pointer - 1][1].length) == diffs[pointer - 1][1]) {\n // Shift the edit over the previous equality.\n diffs[pointer][1] = diffs[pointer - 1][1] +\n diffs[pointer][1].substring(0, diffs[pointer][1].length -\n diffs[pointer - 1][1].length);\n diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];\n diffs.splice(pointer - 1, 1);\n changes = true;\n } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==\n diffs[pointer + 1][1]) {\n // Shift the edit over the next equality.\n diffs[pointer - 1][1] += diffs[pointer + 1][1];\n diffs[pointer][1] =\n diffs[pointer][1].substring(diffs[pointer + 1][1].length) +\n diffs[pointer + 1][1];\n diffs.splice(pointer + 1, 1);\n changes = true;\n }\n }\n pointer++;\n }\n // If shifts were made, the diff needs reordering and another shift sweep.\n if (changes) {\n this.diff_cleanupMerge(diffs);\n }\n};\n\n\n/**\n * loc is a location in text1, compute and return the equivalent location in\n * text2.\n * e.g. 'The cat' vs 'The big cat', 1->1, 5->8\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @param {number} loc Location within text1.\n * @return {number} Location within text2.\n */\ndiff_match_patch.prototype.diff_xIndex = function(diffs, loc) {\n var chars1 = 0;\n var chars2 = 0;\n var last_chars1 = 0;\n var last_chars2 = 0;\n var x;\n for (x = 0; x < diffs.length; x++) {\n if (diffs[x][0] !== DIFF_INSERT) { // Equality or deletion.\n chars1 += diffs[x][1].length;\n }\n if (diffs[x][0] !== DIFF_DELETE) { // Equality or insertion.\n chars2 += diffs[x][1].length;\n }\n if (chars1 > loc) { // Overshot the location.\n break;\n }\n last_chars1 = chars1;\n last_chars2 = chars2;\n }\n // Was the location was deleted?\n if (diffs.length != x && diffs[x][0] === DIFF_DELETE) {\n return last_chars2;\n }\n // Add the remaining character length.\n return last_chars2 + (loc - last_chars1);\n};\n\n\n/**\n * Convert a diff array into a pretty HTML report.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} HTML representation.\n */\ndiff_match_patch.prototype.diff_prettyHtml = function(diffs) {\n var html = [];\n var pattern_amp = /&/g;\n var pattern_lt = /</g;\n var pattern_gt = />/g;\n var pattern_para = /\\n/g;\n for (var x = 0; x < diffs.length; x++) {\n var op = diffs[x][0]; // Operation (insert, delete, equal)\n var data = diffs[x][1]; // Text of change.\n var text = data.replace(pattern_amp, '&').replace(pattern_lt, '<')\n .replace(pattern_gt, '>').replace(pattern_para, '¶<br>');\n switch (op) {\n case DIFF_INSERT:\n html[x] = '<ins style=\"background:#e6ffe6;\">' + text + '</ins>';\n break;\n case DIFF_DELETE:\n html[x] = '<del style=\"background:#ffe6e6;\">' + text + '</del>';\n break;\n case DIFF_EQUAL:\n html[x] = '<span>' + text + '</span>';\n break;\n }\n }\n return html.join('');\n};\n\n\n/**\n * Compute and return the source text (all equalities and deletions).\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} Source text.\n */\ndiff_match_patch.prototype.diff_text1 = function(diffs) {\n var text = [];\n for (var x = 0; x < diffs.length; x++) {\n if (diffs[x][0] !== DIFF_INSERT) {\n text[x] = diffs[x][1];\n }\n }\n return text.join('');\n};\n\n\n/**\n * Compute and return the destination text (all equalities and insertions).\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} Destination text.\n */\ndiff_match_patch.prototype.diff_text2 = function(diffs) {\n var text = [];\n for (var x = 0; x < diffs.length; x++) {\n if (diffs[x][0] !== DIFF_DELETE) {\n text[x] = diffs[x][1];\n }\n }\n return text.join('');\n};\n\n\n/**\n * Compute the Levenshtein distance; the number of inserted, deleted or\n * substituted characters.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {number} Number of changes.\n */\ndiff_match_patch.prototype.diff_levenshtein = function(diffs) {\n var levenshtein = 0;\n var insertions = 0;\n var deletions = 0;\n for (var x = 0; x < diffs.length; x++) {\n var op = diffs[x][0];\n var data = diffs[x][1];\n switch (op) {\n case DIFF_INSERT:\n insertions += data.length;\n break;\n case DIFF_DELETE:\n deletions += data.length;\n break;\n case DIFF_EQUAL:\n // A deletion and an insertion is one substitution.\n levenshtein += Math.max(insertions, deletions);\n insertions = 0;\n deletions = 0;\n break;\n }\n }\n levenshtein += Math.max(insertions, deletions);\n return levenshtein;\n};\n\n\n/**\n * Crush the diff into an encoded string which describes the operations\n * required to transform text1 into text2.\n * E.g. =3\\t-2\\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'.\n * Operations are tab-separated. Inserted text is escaped using %xx notation.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} Delta text.\n */\ndiff_match_patch.prototype.diff_toDelta = function(diffs) {\n var text = [];\n for (var x = 0; x < diffs.length; x++) {\n switch (diffs[x][0]) {\n case DIFF_INSERT:\n text[x] = '+' + encodeURI(diffs[x][1]);\n break;\n case DIFF_DELETE:\n text[x] = '-' + diffs[x][1].length;\n break;\n case DIFF_EQUAL:\n text[x] = '=' + diffs[x][1].length;\n break;\n }\n }\n return text.join('\\t').replace(/%20/g, ' ');\n};\n\n\n/**\n * Given the original text1, and an encoded string which describes the\n * operations required to transform text1 into text2, compute the full diff.\n * @param {string} text1 Source string for the diff.\n * @param {string} delta Delta text.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @throws {!Error} If invalid input.\n */\ndiff_match_patch.prototype.diff_fromDelta = function(text1, delta) {\n var diffs = [];\n var diffsLength = 0; // Keeping our own length var is faster in JS.\n var pointer = 0; // Cursor in text1\n var tokens = delta.split(/\\t/g);\n for (var x = 0; x < tokens.length; x++) {\n // Each token begins with a one character parameter which specifies the\n // operation of this token (delete, insert, equality).\n var param = tokens[x].substring(1);\n switch (tokens[x].charAt(0)) {\n case '+':\n try {\n diffs[diffsLength++] =\n new diff_match_patch.Diff(DIFF_INSERT, decodeURI(param));\n } catch (ex) {\n // Malformed URI sequence.\n throw new Error('Illegal escape in diff_fromDelta: ' + param);\n }\n break;\n case '-':\n // Fall through.\n case '=':\n var n = parseInt(param, 10);\n if (isNaN(n) || n < 0) {\n throw new Error('Invalid number in diff_fromDelta: ' + param);\n }\n var text = text1.substring(pointer, pointer += n);\n if (tokens[x].charAt(0) == '=') {\n diffs[diffsLength++] = new diff_match_patch.Diff(DIFF_EQUAL, text);\n } else {\n diffs[diffsLength++] = new diff_match_patch.Diff(DIFF_DELETE, text);\n }\n break;\n default:\n // Blank tokens are ok (from a trailing \\t).\n // Anything else is an error.\n if (tokens[x]) {\n throw new Error('Invalid diff operation in diff_fromDelta: ' +\n tokens[x]);\n }\n }\n }\n if (pointer != text1.length) {\n throw new Error('Delta length (' + pointer +\n ') does not equal source text length (' + text1.length + ').');\n }\n return diffs;\n};\n\n\n// MATCH FUNCTIONS\n\n\n/**\n * Locate the best instance of 'pattern' in 'text' near 'loc'.\n * @param {string} text The text to search.\n * @param {string} pattern The pattern to search for.\n * @param {number} loc The location to search around.\n * @return {number} Best match index or -1.\n */\ndiff_match_patch.prototype.match_main = function(text, pattern, loc) {\n // Check for null inputs.\n if (text == null || pattern == null || loc == null) {\n throw new Error('Null input. (match_main)');\n }\n\n loc = Math.max(0, Math.min(loc, text.length));\n if (text == pattern) {\n // Shortcut (potentially not guaranteed by the algorithm)\n return 0;\n } else if (!text.length) {\n // Nothing to match.\n return -1;\n } else if (text.substring(loc, loc + pattern.length) == pattern) {\n // Perfect match at the perfect spot! (Includes case of null pattern)\n return loc;\n } else {\n // Do a fuzzy compare.\n return this.match_bitap_(text, pattern, loc);\n }\n};\n\n\n/**\n * Locate the best instance of 'pattern' in 'text' near 'loc' using the\n * Bitap algorithm.\n * @param {string} text The text to search.\n * @param {string} pattern The pattern to search for.\n * @param {number} loc The location to search around.\n * @return {number} Best match index or -1.\n * @private\n */\ndiff_match_patch.prototype.match_bitap_ = function(text, pattern, loc) {\n if (pattern.length > this.Match_MaxBits) {\n throw new Error('Pattern too long for this browser.');\n }\n\n // Initialise the alphabet.\n var s = this.match_alphabet_(pattern);\n\n var dmp = this; // 'this' becomes 'window' in a closure.\n\n /**\n * Compute and return the score for a match with e errors and x location.\n * Accesses loc and pattern through being a closure.\n * @param {number} e Number of errors in match.\n * @param {number} x Location of match.\n * @return {number} Overall score for match (0.0 = good, 1.0 = bad).\n * @private\n */\n function match_bitapScore_(e, x) {\n var accuracy = e / pattern.length;\n var proximity = Math.abs(loc - x);\n if (!dmp.Match_Distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy;\n }\n return accuracy + (proximity / dmp.Match_Distance);\n }\n\n // Highest score beyond which we give up.\n var score_threshold = this.Match_Threshold;\n // Is there a nearby exact match? (speedup)\n var best_loc = text.indexOf(pattern, loc);\n if (best_loc != -1) {\n score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold);\n // What about in the other direction? (speedup)\n best_loc = text.lastIndexOf(pattern, loc + pattern.length);\n if (best_loc != -1) {\n score_threshold =\n Math.min(match_bitapScore_(0, best_loc), score_threshold);\n }\n }\n\n // Initialise the bit arrays.\n var matchmask = 1 << (pattern.length - 1);\n best_loc = -1;\n\n var bin_min, bin_mid;\n var bin_max = pattern.length + text.length;\n var last_rd;\n for (var d = 0; d < pattern.length; d++) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from 'loc' we can stray at this\n // error level.\n bin_min = 0;\n bin_mid = bin_max;\n while (bin_min < bin_mid) {\n if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) {\n bin_min = bin_mid;\n } else {\n bin_max = bin_mid;\n }\n bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min);\n }\n // Use the result from this iteration as the maximum for the next.\n bin_max = bin_mid;\n var start = Math.max(1, loc - bin_mid + 1);\n var finish = Math.min(loc + bin_mid, text.length) + pattern.length;\n\n var rd = Array(finish + 2);\n rd[finish + 1] = (1 << d) - 1;\n for (var j = finish; j >= start; j--) {\n // The alphabet (s) is a sparse hash, so the following line generates\n // warnings.\n var charMatch = s[text.charAt(j - 1)];\n if (d === 0) { // First pass: exact match.\n rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;\n } else { // Subsequent passes: fuzzy match.\n rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) |\n (((last_rd[j + 1] | last_rd[j]) << 1) | 1) |\n last_rd[j + 1];\n }\n if (rd[j] & matchmask) {\n var score = match_bitapScore_(d, j - 1);\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (score <= score_threshold) {\n // Told you so.\n score_threshold = score;\n best_loc = j - 1;\n if (best_loc > loc) {\n // When passing loc, don't exceed our current distance from loc.\n start = Math.max(1, 2 * loc - best_loc);\n } else {\n // Already passed loc, downhill from here on in.\n break;\n }\n }\n }\n }\n // No hope for a (better) match at greater error levels.\n if (match_bitapScore_(d + 1, loc) > score_threshold) {\n break;\n }\n last_rd = rd;\n }\n return best_loc;\n};\n\n\n/**\n * Initialise the alphabet for the Bitap algorithm.\n * @param {string} pattern The text to encode.\n * @return {!Object} Hash of character locations.\n * @private\n */\ndiff_match_patch.prototype.match_alphabet_ = function(pattern) {\n var s = {};\n for (var i = 0; i < pattern.length; i++) {\n s[pattern.charAt(i)] = 0;\n }\n for (var i = 0; i < pattern.length; i++) {\n s[pattern.charAt(i)] |= 1 << (pattern.length - i - 1);\n }\n return s;\n};\n\n\n// PATCH FUNCTIONS\n\n\n/**\n * Increase the context until it is unique,\n * but don't let the pattern expand beyond Match_MaxBits.\n * @param {!diff_match_patch.patch_obj} patch The patch to grow.\n * @param {string} text Source text.\n * @private\n */\ndiff_match_patch.prototype.patch_addContext_ = function(patch, text) {\n if (text.length == 0) {\n return;\n }\n if (patch.start2 === null) {\n throw Error('patch not initialized');\n }\n var pattern = text.substring(patch.start2, patch.start2 + patch.length1);\n var padding = 0;\n\n // Look for the first and last matches of pattern in text. If two different\n // matches are found, increase the pattern length.\n while (text.indexOf(pattern) != text.lastIndexOf(pattern) &&\n pattern.length < this.Match_MaxBits - this.Patch_Margin -\n this.Patch_Margin) {\n padding += this.Patch_Margin;\n pattern = text.substring(patch.start2 - padding,\n patch.start2 + patch.length1 + padding);\n }\n // Add one chunk for good luck.\n padding += this.Patch_Margin;\n\n // Add the prefix.\n var prefix = text.substring(patch.start2 - padding, patch.start2);\n if (prefix) {\n patch.diffs.unshift(new diff_match_patch.Diff(DIFF_EQUAL, prefix));\n }\n // Add the suffix.\n var suffix = text.substring(patch.start2 + patch.length1,\n patch.start2 + patch.length1 + padding);\n if (suffix) {\n patch.diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, suffix));\n }\n\n // Roll back the start points.\n patch.start1 -= prefix.length;\n patch.start2 -= prefix.length;\n // Extend the lengths.\n patch.length1 += prefix.length + suffix.length;\n patch.length2 += prefix.length + suffix.length;\n};\n\n\n/**\n * Compute a list of patches to turn text1 into text2.\n * Use diffs if provided, otherwise compute it ourselves.\n * There are four ways to call this function, depending on what data is\n * available to the caller:\n * Method 1:\n * a = text1, b = text2\n * Method 2:\n * a = diffs\n * Method 3 (optimal):\n * a = text1, b = diffs\n * Method 4 (deprecated, use method 3):\n * a = text1, b = text2, c = diffs\n *\n * @param {string|!Array.<!diff_match_patch.Diff>} a text1 (methods 1,3,4) or\n * Array of diff tuples for text1 to text2 (method 2).\n * @param {string|!Array.<!diff_match_patch.Diff>=} opt_b text2 (methods 1,4) or\n * Array of diff tuples for text1 to text2 (method 3) or undefined (method 2).\n * @param {string|!Array.<!diff_match_patch.Diff>=} opt_c Array of diff tuples\n * for text1 to text2 (method 4) or undefined (methods 1,2,3).\n * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.\n */\ndiff_match_patch.prototype.patch_make = function(a, opt_b, opt_c) {\n var text1, diffs;\n if (typeof a == 'string' && typeof opt_b == 'string' &&\n typeof opt_c == 'undefined') {\n // Method 1: text1, text2\n // Compute diffs from text1 and text2.\n text1 = /** @type {string} */(a);\n diffs = this.diff_main(text1, /** @type {string} */(opt_b), true);\n if (diffs.length > 2) {\n this.diff_cleanupSemantic(diffs);\n this.diff_cleanupEfficiency(diffs);\n }\n } else if (a && typeof a == 'object' && typeof opt_b == 'undefined' &&\n typeof opt_c == 'undefined') {\n // Method 2: diffs\n // Compute text1 from diffs.\n diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(a);\n text1 = this.diff_text1(diffs);\n } else if (typeof a == 'string' && opt_b && typeof opt_b == 'object' &&\n typeof opt_c == 'undefined') {\n // Method 3: text1, diffs\n text1 = /** @type {string} */(a);\n diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_b);\n } else if (typeof a == 'string' && typeof opt_b == 'string' &&\n opt_c && typeof opt_c == 'object') {\n // Method 4: text1, text2, diffs\n // text2 is not used.\n text1 = /** @type {string} */(a);\n diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_c);\n } else {\n throw new Error('Unknown call format to patch_make.');\n }\n\n if (diffs.length === 0) {\n return []; // Get rid of the null case.\n }\n var patches = [];\n var patch = new diff_match_patch.patch_obj();\n var patchDiffLength = 0; // Keeping our own length var is faster in JS.\n var char_count1 = 0; // Number of characters into the text1 string.\n var char_count2 = 0; // Number of characters into the text2 string.\n // Start with text1 (prepatch_text) and apply the diffs until we arrive at\n // text2 (postpatch_text). We recreate the patches one by one to determine\n // context info.\n var prepatch_text = text1;\n var postpatch_text = text1;\n for (var x = 0; x < diffs.length; x++) {\n var diff_type = diffs[x][0];\n var diff_text = diffs[x][1];\n\n if (!patchDiffLength && diff_type !== DIFF_EQUAL) {\n // A new patch starts here.\n patch.start1 = char_count1;\n patch.start2 = char_count2;\n }\n\n switch (diff_type) {\n case DIFF_INSERT:\n patch.diffs[patchDiffLength++] = diffs[x];\n patch.length2 += diff_text.length;\n postpatch_text = postpatch_text.substring(0, char_count2) + diff_text +\n postpatch_text.substring(char_count2);\n break;\n case DIFF_DELETE:\n patch.length1 += diff_text.length;\n patch.diffs[patchDiffLength++] = diffs[x];\n postpatch_text = postpatch_text.substring(0, char_count2) +\n postpatch_text.substring(char_count2 +\n diff_text.length);\n break;\n case DIFF_EQUAL:\n if (diff_text.length <= 2 * this.Patch_Margin &&\n patchDiffLength && diffs.length != x + 1) {\n // Small equality inside a patch.\n patch.diffs[patchDiffLength++] = diffs[x];\n patch.length1 += diff_text.length;\n patch.length2 += diff_text.length;\n } else if (diff_text.length >= 2 * this.Patch_Margin) {\n // Time for a new patch.\n if (patchDiffLength) {\n this.patch_addContext_(patch, prepatch_text);\n patches.push(patch);\n patch = new diff_match_patch.patch_obj();\n patchDiffLength = 0;\n // Unlike Unidiff, our patch lists have a rolling context.\n // https://github.com/google/diff-match-patch/wiki/Unidiff\n // Update prepatch text & pos to reflect the application of the\n // just completed patch.\n prepatch_text = postpatch_text;\n char_count1 = char_count2;\n }\n }\n break;\n }\n\n // Update the current character count.\n if (diff_type !== DIFF_INSERT) {\n char_count1 += diff_text.length;\n }\n if (diff_type !== DIFF_DELETE) {\n char_count2 += diff_text.length;\n }\n }\n // Pick up the leftover patch if not empty.\n if (patchDiffLength) {\n this.patch_addContext_(patch, prepatch_text);\n patches.push(patch);\n }\n\n return patches;\n};\n\n\n/**\n * Given an array of patches, return another array that is identical.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.\n */\ndiff_match_patch.prototype.patch_deepCopy = function(patches) {\n // Making deep copies is hard in JavaScript.\n var patchesCopy = [];\n for (var x = 0; x < patches.length; x++) {\n var patch = patches[x];\n var patchCopy = new diff_match_patch.patch_obj();\n patchCopy.diffs = [];\n for (var y = 0; y < patch.diffs.length; y++) {\n patchCopy.diffs[y] =\n new diff_match_patch.Diff(patch.diffs[y][0], patch.diffs[y][1]);\n }\n patchCopy.start1 = patch.start1;\n patchCopy.start2 = patch.start2;\n patchCopy.length1 = patch.length1;\n patchCopy.length2 = patch.length2;\n patchesCopy[x] = patchCopy;\n }\n return patchesCopy;\n};\n\n\n/**\n * Merge a set of patches onto the text. Return a patched text, as well\n * as a list of true/false values indicating which patches were applied.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @param {string} text Old text.\n * @return {!Array.<string|!Array.<boolean>>} Two element Array, containing the\n * new text and an array of boolean values.\n */\ndiff_match_patch.prototype.patch_apply = function(patches, text) {\n if (patches.length == 0) {\n return [text, []];\n }\n\n // Deep copy the patches so that no changes are made to originals.\n patches = this.patch_deepCopy(patches);\n\n var nullPadding = this.patch_addPadding(patches);\n text = nullPadding + text + nullPadding;\n\n this.patch_splitMax(patches);\n // delta keeps track of the offset between the expected and actual location\n // of the previous patch. If there are patches expected at positions 10 and\n // 20, but the first patch was found at 12, delta is 2 and the second patch\n // has an effective expected position of 22.\n var delta = 0;\n var results = [];\n for (var x = 0; x < patches.length; x++) {\n var expected_loc = patches[x].start2 + delta;\n var text1 = this.diff_text1(patches[x].diffs);\n var start_loc;\n var end_loc = -1;\n if (text1.length > this.Match_MaxBits) {\n // patch_splitMax will only provide an oversized pattern in the case of\n // a monster delete.\n start_loc = this.match_main(text, text1.substring(0, this.Match_MaxBits),\n expected_loc);\n if (start_loc != -1) {\n end_loc = this.match_main(text,\n text1.substring(text1.length - this.Match_MaxBits),\n expected_loc + text1.length - this.Match_MaxBits);\n if (end_loc == -1 || start_loc >= end_loc) {\n // Can't find valid trailing context. Drop this patch.\n start_loc = -1;\n }\n }\n } else {\n start_loc = this.match_main(text, text1, expected_loc);\n }\n if (start_loc == -1) {\n // No match found. :(\n results[x] = false;\n // Subtract the delta for this failed patch from subsequent patches.\n delta -= patches[x].length2 - patches[x].length1;\n } else {\n // Found a match. :)\n results[x] = true;\n delta = start_loc - expected_loc;\n var text2;\n if (end_loc == -1) {\n text2 = text.substring(start_loc, start_loc + text1.length);\n } else {\n text2 = text.substring(start_loc, end_loc + this.Match_MaxBits);\n }\n if (text1 == text2) {\n // Perfect match, just shove the replacement text in.\n text = text.substring(0, start_loc) +\n this.diff_text2(patches[x].diffs) +\n text.substring(start_loc + text1.length);\n } else {\n // Imperfect match. Run a diff to get a framework of equivalent\n // indices.\n var diffs = this.diff_main(text1, text2, false);\n if (text1.length > this.Match_MaxBits &&\n this.diff_levenshtein(diffs) / text1.length >\n this.Patch_DeleteThreshold) {\n // The end points match, but the content is unacceptably bad.\n results[x] = false;\n } else {\n this.diff_cleanupSemanticLossless(diffs);\n var index1 = 0;\n var index2;\n for (var y = 0; y < patches[x].diffs.length; y++) {\n var mod = patches[x].diffs[y];\n if (mod[0] !== DIFF_EQUAL) {\n index2 = this.diff_xIndex(diffs, index1);\n }\n if (mod[0] === DIFF_INSERT) { // Insertion\n text = text.substring(0, start_loc + index2) + mod[1] +\n text.substring(start_loc + index2);\n } else if (mod[0] === DIFF_DELETE) { // Deletion\n text = text.substring(0, start_loc + index2) +\n text.substring(start_loc + this.diff_xIndex(diffs,\n index1 + mod[1].length));\n }\n if (mod[0] !== DIFF_DELETE) {\n index1 += mod[1].length;\n }\n }\n }\n }\n }\n }\n // Strip the padding off.\n text = text.substring(nullPadding.length, text.length - nullPadding.length);\n return [text, results];\n};\n\n\n/**\n * Add some padding on text start and end so that edges can match something.\n * Intended to be called only from within patch_apply.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @return {string} The padding string added to each side.\n */\ndiff_match_patch.prototype.patch_addPadding = function(patches) {\n var paddingLength = this.Patch_Margin;\n var nullPadding = '';\n for (var x = 1; x <= paddingLength; x++) {\n nullPadding += String.fromCharCode(x);\n }\n\n // Bump all the patches forward.\n for (var x = 0; x < patches.length; x++) {\n patches[x].start1 += paddingLength;\n patches[x].start2 += paddingLength;\n }\n\n // Add some padding on start of first diff.\n var patch = patches[0];\n var diffs = patch.diffs;\n if (diffs.length == 0 || diffs[0][0] != DIFF_EQUAL) {\n // Add nullPadding equality.\n diffs.unshift(new diff_match_patch.Diff(DIFF_EQUAL, nullPadding));\n patch.start1 -= paddingLength; // Should be 0.\n patch.start2 -= paddingLength; // Should be 0.\n patch.length1 += paddingLength;\n patch.length2 += paddingLength;\n } else if (paddingLength > diffs[0][1].length) {\n // Grow first equality.\n var extraLength = paddingLength - diffs[0][1].length;\n diffs[0][1] = nullPadding.substring(diffs[0][1].length) + diffs[0][1];\n patch.start1 -= extraLength;\n patch.start2 -= extraLength;\n patch.length1 += extraLength;\n patch.length2 += extraLength;\n }\n\n // Add some padding on end of last diff.\n patch = patches[patches.length - 1];\n diffs = patch.diffs;\n if (diffs.length == 0 || diffs[diffs.length - 1][0] != DIFF_EQUAL) {\n // Add nullPadding equality.\n diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, nullPadding));\n patch.length1 += paddingLength;\n patch.length2 += paddingLength;\n } else if (paddingLength > diffs[diffs.length - 1][1].length) {\n // Grow last equality.\n var extraLength = paddingLength - diffs[diffs.length - 1][1].length;\n diffs[diffs.length - 1][1] += nullPadding.substring(0, extraLength);\n patch.length1 += extraLength;\n patch.length2 += extraLength;\n }\n\n return nullPadding;\n};\n\n\n/**\n * Look through the patches and break up any which are longer than the maximum\n * limit of the match algorithm.\n * Intended to be called only from within patch_apply.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n */\ndiff_match_patch.prototype.patch_splitMax = function(patches) {\n var patch_size = this.Match_MaxBits;\n for (var x = 0; x < patches.length; x++) {\n if (patches[x].length1 <= patch_size) {\n continue;\n }\n var bigpatch = patches[x];\n // Remove the big old patch.\n patches.splice(x--, 1);\n var start1 = bigpatch.start1;\n var start2 = bigpatch.start2;\n var precontext = '';\n while (bigpatch.diffs.length !== 0) {\n // Create one of several smaller patches.\n var patch = new diff_match_patch.patch_obj();\n var empty = true;\n patch.start1 = start1 - precontext.length;\n patch.start2 = start2 - precontext.length;\n if (precontext !== '') {\n patch.length1 = patch.length2 = precontext.length;\n patch.diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, precontext));\n }\n while (bigpatch.diffs.length !== 0 &&\n patch.length1 < patch_size - this.Patch_Margin) {\n var diff_type = bigpatch.diffs[0][0];\n var diff_text = bigpatch.diffs[0][1];\n if (diff_type === DIFF_INSERT) {\n // Insertions are harmless.\n patch.length2 += diff_text.length;\n start2 += diff_text.length;\n patch.diffs.push(bigpatch.diffs.shift());\n empty = false;\n } else if (diff_type === DIFF_DELETE && patch.diffs.length == 1 &&\n patch.diffs[0][0] == DIFF_EQUAL &&\n diff_text.length > 2 * patch_size) {\n // This is a large deletion. Let it pass in one chunk.\n patch.length1 += diff_text.length;\n start1 += diff_text.length;\n empty = false;\n patch.diffs.push(new diff_match_patch.Diff(diff_type, diff_text));\n bigpatch.diffs.shift();\n } else {\n // Deletion or equality. Only take as much as we can stomach.\n diff_text = diff_text.substring(0,\n patch_size - patch.length1 - this.Patch_Margin);\n patch.length1 += diff_text.length;\n start1 += diff_text.length;\n if (diff_type === DIFF_EQUAL) {\n patch.length2 += diff_text.length;\n start2 += diff_text.length;\n } else {\n empty = false;\n }\n patch.diffs.push(new diff_match_patch.Diff(diff_type, diff_text));\n if (diff_text == bigpatch.diffs[0][1]) {\n bigpatch.diffs.shift();\n } else {\n bigpatch.diffs[0][1] =\n bigpatch.diffs[0][1].substring(diff_text.length);\n }\n }\n }\n // Compute the head context for the next patch.\n precontext = this.diff_text2(patch.diffs);\n precontext =\n precontext.substring(precontext.length - this.Patch_Margin);\n // Append the end context for this patch.\n var postcontext = this.diff_text1(bigpatch.diffs)\n .substring(0, this.Patch_Margin);\n if (postcontext !== '') {\n patch.length1 += postcontext.length;\n patch.length2 += postcontext.length;\n if (patch.diffs.length !== 0 &&\n patch.diffs[patch.diffs.length - 1][0] === DIFF_EQUAL) {\n patch.diffs[patch.diffs.length - 1][1] += postcontext;\n } else {\n patch.diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, postcontext));\n }\n }\n if (!empty) {\n patches.splice(++x, 0, patch);\n }\n }\n }\n};\n\n\n/**\n * Take a list of patches and return a textual representation.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @return {string} Text representation of patches.\n */\ndiff_match_patch.prototype.patch_toText = function(patches) {\n var text = [];\n for (var x = 0; x < patches.length; x++) {\n text[x] = patches[x];\n }\n return text.join('');\n};\n\n\n/**\n * Parse a textual representation of patches and return a list of Patch objects.\n * @param {string} textline Text representation of patches.\n * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.\n * @throws {!Error} If invalid input.\n */\ndiff_match_patch.prototype.patch_fromText = function(textline) {\n var patches = [];\n if (!textline) {\n return patches;\n }\n var text = textline.split('\\n');\n var textPointer = 0;\n var patchHeader = /^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$/;\n while (textPointer < text.length) {\n var m = text[textPointer].match(patchHeader);\n if (!m) {\n throw new Error('Invalid patch string: ' + text[textPointer]);\n }\n var patch = new diff_match_patch.patch_obj();\n patches.push(patch);\n patch.start1 = parseInt(m[1], 10);\n if (m[2] === '') {\n patch.start1--;\n patch.length1 = 1;\n } else if (m[2] == '0') {\n patch.length1 = 0;\n } else {\n patch.start1--;\n patch.length1 = parseInt(m[2], 10);\n }\n\n patch.start2 = parseInt(m[3], 10);\n if (m[4] === '') {\n patch.start2--;\n patch.length2 = 1;\n } else if (m[4] == '0') {\n patch.length2 = 0;\n } else {\n patch.start2--;\n patch.length2 = parseInt(m[4], 10);\n }\n textPointer++;\n\n while (textPointer < text.length) {\n var sign = text[textPointer].charAt(0);\n try {\n var line = decodeURI(text[textPointer].substring(1));\n } catch (ex) {\n // Malformed URI sequence.\n throw new Error('Illegal escape in patch_fromText: ' + line);\n }\n if (sign == '-') {\n // Deletion.\n patch.diffs.push(new diff_match_patch.Diff(DIFF_DELETE, line));\n } else if (sign == '+') {\n // Insertion.\n patch.diffs.push(new diff_match_patch.Diff(DIFF_INSERT, line));\n } else if (sign == ' ') {\n // Minor equality.\n patch.diffs.push(new diff_match_patch.Diff(DIFF_EQUAL, line));\n } else if (sign == '@') {\n // Start of next patch.\n break;\n } else if (sign === '') {\n // Blank line? Whatever.\n } else {\n // WTF?\n throw new Error('Invalid patch mode \"' + sign + '\" in: ' + line);\n }\n textPointer++;\n }\n }\n return patches;\n};\n\n\n/**\n * Class representing one patch operation.\n * @constructor\n */\ndiff_match_patch.patch_obj = function() {\n /** @type {!Array.<!diff_match_patch.Diff>} */\n this.diffs = [];\n /** @type {?number} */\n this.start1 = null;\n /** @type {?number} */\n this.start2 = null;\n /** @type {number} */\n this.length1 = 0;\n /** @type {number} */\n this.length2 = 0;\n};\n\n\n/**\n * Emulate GNU diff's format.\n * Header: @@ -382,8 +481,9 @@\n * Indices are printed as 1-based, not 0-based.\n * @return {string} The GNU diff string.\n */\ndiff_match_patch.patch_obj.prototype.toString = function() {\n var coords1, coords2;\n if (this.length1 === 0) {\n coords1 = this.start1 + ',0';\n } else if (this.length1 == 1) {\n coords1 = this.start1 + 1;\n } else {\n coords1 = (this.start1 + 1) + ',' + this.length1;\n }\n if (this.length2 === 0) {\n coords2 = this.start2 + ',0';\n } else if (this.length2 == 1) {\n coords2 = this.start2 + 1;\n } else {\n coords2 = (this.start2 + 1) + ',' + this.length2;\n }\n var text = ['@@ -' + coords1 + ' +' + coords2 + ' @@\\n'];\n var op;\n // Escape the body of the patch with %xx notation.\n for (var x = 0; x < this.diffs.length; x++) {\n switch (this.diffs[x][0]) {\n case DIFF_INSERT:\n op = '+';\n break;\n case DIFF_DELETE:\n op = '-';\n break;\n case DIFF_EQUAL:\n op = ' ';\n break;\n }\n text[x + 1] = op + encodeURI(this.diffs[x][1]) + '\\n';\n }\n return text.join('').replace(/%20/g, ' ');\n};\n\n\n// The following export code was added by @ForbesLindesay\nmodule.exports = diff_match_patch;\nmodule.exports['diff_match_patch'] = diff_match_patch;\nmodule.exports['DIFF_DELETE'] = DIFF_DELETE;\nmodule.exports['DIFF_INSERT'] = DIFF_INSERT;\nmodule.exports['DIFF_EQUAL'] = DIFF_EQUAL;", "/**\r\n * XML adapter for parser/serializer portability.\r\n *\r\n * Default behavior uses browser-provided DOMParser/XMLSerializer.\r\n * Consumers can override these constructors for non-browser runtimes.\r\n */\r\n\r\nlet _DOMParser = globalThis.DOMParser;\r\nlet _XMLSerializer = globalThis.XMLSerializer;\r\n\r\n/**\r\n * Configures XML provider constructors.\r\n *\r\n * @param {Object} [options={}] - Provider overrides\r\n * @param {typeof DOMParser} [options.DOMParser] - DOMParser constructor\r\n * @param {typeof XMLSerializer} [options.XMLSerializer] - XMLSerializer constructor\r\n */\r\nexport function configureXmlProvider(options = {}) {\r\n if (options.DOMParser) _DOMParser = options.DOMParser;\r\n if (options.XMLSerializer) _XMLSerializer = options.XMLSerializer;\r\n}\r\n\r\n/**\r\n * Creates a parser instance.\r\n *\r\n * @returns {DOMParser}\r\n */\r\nexport function createParser() {\r\n if (!_DOMParser && globalThis.DOMParser) {\r\n _DOMParser = globalThis.DOMParser;\r\n }\r\n if (!_DOMParser) {\r\n throw new Error('DOMParser is not configured. Call configureXmlProvider({ DOMParser, XMLSerializer }) first.');\r\n }\r\n return new _DOMParser();\r\n}\r\n\r\n/**\r\n * Creates a serializer instance.\r\n *\r\n * @returns {XMLSerializer}\r\n */\r\nexport function createSerializer() {\r\n if (!_XMLSerializer && globalThis.XMLSerializer) {\r\n _XMLSerializer = globalThis.XMLSerializer;\r\n }\r\n if (!_XMLSerializer) {\r\n throw new Error('XMLSerializer is not configured. Call configureXmlProvider({ DOMParser, XMLSerializer }) first.');\r\n }\r\n return new _XMLSerializer();\r\n}\r\n\r\n/**\r\n * Parses XML text into a DOM document.\r\n *\r\n * @param {string} xmlString - XML string\r\n * @param {string} [contentType='text/xml'] - MIME type\r\n * @returns {Document}\r\n */\r\nexport function parseXml(xmlString, contentType = 'text/xml') {\r\n const parser = createParser();\r\n return parser.parseFromString(xmlString, contentType);\r\n}\r\n\r\n/**\r\n * Serializes a node to XML text.\r\n *\r\n * @param {Node} node - Node to serialize\r\n * @returns {string}\r\n */\r\nexport function serializeXml(node) {\r\n const serializer = createSerializer();\r\n return serializer.serializeToString(node);\r\n}\r\n", "/**\n * Logger adapter for reconciliation modules.\n */\n\nlet _logger = console;\n\nconst LEVELS = Object.freeze({\n silent: 0,\n error: 1,\n warn: 2,\n info: 3\n});\n\nconst DEFAULT_LOG_LEVEL = (() => {\n const isProd = typeof process !== 'undefined' && process?.env?.NODE_ENV === 'production';\n return isProd ? 'warn' : 'info';\n})();\n\nlet _logLevel = DEFAULT_LOG_LEVEL;\n\nfunction normalizeLogLevel(level) {\n const normalized = String(level || '').toLowerCase();\n return Object.prototype.hasOwnProperty.call(LEVELS, normalized) ? normalized : _logLevel;\n}\n\nfunction isEnabled(level) {\n return LEVELS[_logLevel] >= LEVELS[level];\n}\n\n/**\n * Configures logger implementation.\n *\n * @param {{log?: Function, warn?: Function, error?: Function}} logger - Logger object\n * @param {{ level?: 'silent'|'error'|'warn'|'info' }} [options={}] - Logger options\n */\nexport function configureLogger(logger, options = {}) {\n _logger = logger || console;\n if (options.level) {\n _logLevel = normalizeLogLevel(options.level);\n }\n}\n\n/**\n * Sets the minimum log level for reconciliation logs.\n *\n * @param {'silent'|'error'|'warn'|'info'} level - Desired log level\n */\nexport function setLogLevel(level) {\n _logLevel = normalizeLogLevel(level);\n}\n\n/**\n * Gets current logger level.\n *\n * @returns {'silent'|'error'|'warn'|'info'}\n */\nexport function getLogLevel() {\n return _logLevel;\n}\n\n/**\n * Log passthrough.\n *\n * @param {...any} args - Log args\n */\nexport function log(...args) {\n if (!isEnabled('info')) return;\n (_logger.log || (() => { }))(...args);\n}\n\r\n/**\r\n * Warn passthrough.\r\n *\r\n * @param {...any} args - Warn args\r\n */\r\nexport function warn(...args) {\n if (!isEnabled('warn')) return;\n (_logger.warn || (() => { }))(...args);\n}\n\r\n/**\r\n * Error passthrough.\r\n *\r\n * @param {...any} args - Error args\r\n */\r\nexport function error(...args) {\n if (!isEnabled('error')) return;\n (_logger.error || (() => { }))(...args);\n}\n", "/**\n * Configurable runtime defaults for the reconciliation core.\n * Callers can set these during bootstrap.\n */\n\nlet _defaultAuthor = 'Author';\nlet _platform = 'Unknown';\n\n/**\n * Set the default track-change author for revision metadata.\n *\n * @param {string} author\n */\nexport function setDefaultAuthor(author) {\n _defaultAuthor = typeof author === 'string' && author.trim() ? author.trim() : 'Author';\n}\n\n/**\n * Get the current default track-change author.\n *\n * @returns {string}\n */\nexport function getDefaultAuthor() {\n return _defaultAuthor;\n}\n\n/**\n * Set the platform identifier (e.g. 'Win32', 'Mac', 'OfficeOnline').\n *\n * @param {string} platform\n */\nexport function setPlatform(platform) {\n _platform = typeof platform === 'string' && platform.trim() ? platform.trim() : 'Unknown';\n}\n\n/**\n * Get the current platform identifier.\n *\n * @returns {string}\n */\nexport function getPlatform() {\n return _platform;\n}\n", "/**\r\n * OOXML Reconciliation Pipeline - Markdown Processor\r\n * \r\n * Strips markdown syntax and captures format hints for later application.\r\n */\r\n\r\nconst MARKDOWN_PATTERNS = [\r\n // HTML Bold: <b>text</b>, <strong>text</strong>\r\n { regex: /<b>(.+?)<\\/b>/i, format: { bold: true } },\r\n { regex: /<strong>(.+?)<\\/strong>/i, format: { bold: true } },\r\n // HTML Italic: <i>text</i>, <em>text</em>\r\n { regex: /<i>(.+?)<\\/i>/i, format: { italic: true } },\r\n { regex: /<em>(.+?)<\\/em>/i, format: { italic: true } },\r\n // HTML Underline: <u>text</u>\r\n { regex: /<u>(.+?)<\\/u>/i, format: { underline: true } },\r\n // HTML Strikethrough: <s>text</s>, <strike>text</strike>, <del>text</del>\r\n { regex: /<s>(.+?)<\\/s>/i, format: { strikethrough: true } },\r\n { regex: /<strike>(.+?)<\\/strike>/i, format: { strikethrough: true } },\r\n { regex: /<del>(.+?)<\\/del>/i, format: { strikethrough: true } },\r\n\r\n // Escaped HTML Bold: <b>text</b>, <strong>text</strong>\r\n { regex: /<b>(.+?)<\\/b>/i, format: { bold: true }, isEscaped: true },\r\n { regex: /<strong>(.+?)<\\/strong>/i, format: { bold: true }, isEscaped: true },\r\n // Escaped HTML Italic: <i>text</i>, <em>text</em>\r\n { regex: /<i>(.+?)<\\/i>/i, format: { italic: true }, isEscaped: true },\r\n { regex: /<em>(.+?)<\\/em>/i, format: { italic: true }, isEscaped: true },\r\n // Escaped HTML Underline: <u>text</u>\r\n { regex: /<u>(.+?)<\\/u>/i, format: { underline: true }, isEscaped: true },\r\n // Escaped HTML Strikethrough: <s>text</s>\r\n { regex: /<s>(.+?)<\\/s>/i, format: { strikethrough: true }, isEscaped: true },\r\n\r\n // Bold + Italic: ***text***\r\n { regex: /\\*\\*\\*(.+?)\\*\\*\\*/, format: { bold: true, italic: true } },\r\n // Bold + Underline: **++text++**\r\n { regex: /\\*\\*\\+\\+(.+?)\\+\\+\\*\\*/, format: { bold: true, underline: true } },\r\n // Bold: **text** or __text__\r\n { regex: /\\*\\*(.+?)\\*\\*/, format: { bold: true } },\r\n { regex: /__(.+?)__/, format: { bold: true } },\r\n // Underline: ++text++\r\n { regex: /\\+\\+(.+?)\\+\\+/, format: { underline: true } },\r\n // Strikethrough: ~~text~~ or ~text~\r\n { regex: /~~(.+?)~~/, format: { strikethrough: true } },\r\n { regex: /~(.+?)~/, format: { strikethrough: true } },\r\n // Italic: *text* or _text_ (using lookahead only for compatibility)\r\n { regex: /\\*(?!\\*)(.+?)\\*(?!\\*)/, format: { italic: true } },\r\n { regex: /_(?!_)(.+?)_(?!_)/, format: { italic: true } }\r\n];\r\n\r\n/**\r\n * Preprocesses markdown text by stripping formatting markers\r\n * and capturing their positions as format hints.\r\n */\r\nexport function preprocessMarkdown(text) {\r\n if (!text) {\r\n return { cleanText: '', formatHints: [] };\r\n }\r\n\r\n const formatHints = [];\r\n let cleanText = '';\r\n\r\n // Find all matches for all patterns\r\n const allMatches = [];\r\n for (const pattern of MARKDOWN_PATTERNS) {\r\n let match;\r\n const source = pattern.regex.source || pattern.regex.toString().replace(/^\\/|\\/[gimuy]*$/g, '');\r\n const flags = 'g' + (pattern.regex.ignoreCase ? 'i' : '');\r\n const regex = new RegExp(source, flags);\r\n\r\n while ((match = regex.exec(text)) !== null) {\r\n allMatches.push({\r\n start: match.index,\r\n end: match.index + match[0].length,\r\n fullMatch: match[0],\r\n innerText: pattern.isEscaped ? decodeHtmlEntities(match[1]) : match[1],\r\n format: pattern.format\r\n });\r\n if (match.index === regex.lastIndex) regex.lastIndex++;\r\n }\r\n }\r\n\r\n // Sort: earliest first, then longest first\r\n allMatches.sort((a, b) => (a.start - b.start) || (b.end - a.end));\r\n\r\n // Filter to keep only top-level matches\r\n const topLevelMatches = [];\r\n let lastEnd = 0;\r\n for (const match of allMatches) {\r\n if (match.start >= lastEnd) {\r\n topLevelMatches.push(match);\r\n lastEnd = match.end;\r\n }\r\n }\r\n\r\n // Recursive reconstruction\r\n let lastIndex = 0;\r\n for (const match of topLevelMatches) {\r\n cleanText += text.slice(lastIndex, match.start);\r\n\r\n const subResult = preprocessMarkdown(match.innerText);\r\n\r\n const segmentStart = cleanText.length;\r\n cleanText += subResult.cleanText;\r\n const segmentEnd = cleanText.length;\r\n\r\n formatHints.push({\r\n start: segmentStart,\r\n end: segmentEnd,\r\n format: match.format\r\n });\r\n\r\n for (const subHint of subResult.formatHints) {\r\n formatHints.push({\r\n start: segmentStart + subHint.start,\r\n end: segmentStart + subHint.end,\r\n format: subHint.format\r\n });\r\n }\r\n\r\n lastIndex = match.end;\r\n }\r\n\r\n cleanText += text.slice(lastIndex);\r\n return { cleanText, formatHints };\r\n}\r\n\r\n/**\r\n * Checks if any format hints apply to a given offset range.\r\n */\r\nexport function getApplicableFormatHints(formatHints, startOffset, endOffset) {\r\n return formatHints.filter(hint =>\r\n hint.start < endOffset && hint.end > startOffset\r\n );\r\n}\r\n\r\n/**\r\n * Merges format objects.\r\n */\r\nexport function mergeFormats(...formats) {\r\n const result = {};\r\n for (const format of formats) {\r\n if (format) {\r\n Object.assign(result, format);\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Decodes HTML entities in text.\r\n */\r\nfunction decodeHtmlEntities(text) {\r\n if (!text) return '';\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/"/g, '\"')\r\n .replace(/'/g, \"'\");\r\n}\r\n\r\n", "/**\r\n * Shared list-marker detection/parsing helpers.\r\n *\r\n * Keeps marker parsing consistent across router, pipeline, and patching flows.\r\n */\r\n\r\nconst LIST_MARKER_CORE = String.raw`(?:\\d+(?:\\.\\d+)*\\.?|\\((?:\\d+|[a-zA-Z]|[ivxlcIVXLC]+)\\)|[a-zA-Z]\\.|\\d+\\.|[ivxlcIVXLC]+\\.|[-*\\u2022])`;\r\n\r\nconst LINE_REGEX_STRICT = new RegExp(`^(\\\\s*)((?:${LIST_MARKER_CORE})\\\\s+)`);\r\nconst LINE_REGEX_LOOSE = new RegExp(`^(\\\\s*)((?:${LIST_MARKER_CORE})\\\\s*)`);\r\nconst MULTILINE_REGEX_STRICT = new RegExp(`^(\\\\s*)((?:${LIST_MARKER_CORE})\\\\s+)`, 'm');\r\nconst MULTILINE_REGEX_LOOSE = new RegExp(`^(\\\\s*)((?:${LIST_MARKER_CORE})\\\\s*)`, 'm');\r\n\r\n/**\r\n * Determines whether text should be treated as list-target content.\r\n * Strict mode requires at least one whitespace after the marker.\r\n *\r\n * @param {string} text - Candidate text\r\n * @returns {boolean}\r\n */\r\nexport function isListTargetStrict(text) {\r\n if (typeof text !== 'string') return false;\r\n return text.includes('\\n') && MULTILINE_REGEX_STRICT.test(text);\r\n}\r\n\r\n/**\r\n * Determines whether text should be treated as list-target content.\r\n * Loose mode allows markers with optional trailing whitespace.\r\n *\r\n * @param {string} text - Candidate text\r\n * @returns {boolean}\r\n */\r\nexport function isListTargetLoose(text) {\r\n if (typeof text !== 'string') return false;\r\n return text.includes('\\n') && MULTILINE_REGEX_LOOSE.test(text.trim());\r\n}\r\n\r\n/**\r\n * Matches a list marker at the start of a line.\r\n *\r\n * @param {string} line - Input line\r\n * @param {Object} [options={}] - Match options\r\n * @param {boolean} [options.allowZeroSpaceAfterMarker=false] - Allow zero spaces after marker\r\n * @returns {RegExpMatchArray|null}\r\n */\r\nexport function matchListMarker(line, options = {}) {\r\n const { allowZeroSpaceAfterMarker = false } = options;\r\n const regex = allowZeroSpaceAfterMarker ? LINE_REGEX_LOOSE : LINE_REGEX_STRICT;\r\n return line.match(regex);\r\n}\r\n\r\n/**\r\n * Extracts the marker text from a line.\r\n *\r\n * @param {string} line - Input line\r\n * @param {Object} [options={}] - Match options\r\n * @param {boolean} [options.allowZeroSpaceAfterMarker=false] - Allow zero spaces after marker\r\n * @returns {string}\r\n */\r\nexport function extractListMarker(line, options = {}) {\r\n const match = matchListMarker(line, options);\r\n return match ? match[2].trim() : '';\r\n}\r\n\r\n/**\r\n * Strips the marker (and its immediate trailing spacing) from a line.\r\n *\r\n * @param {string} line - Input line\r\n * @param {Object} [options={}] - Strip options\r\n * @param {boolean} [options.allowZeroSpaceAfterMarker=false] - Allow zero spaces after marker\r\n * @returns {string}\r\n */\r\nexport function stripListMarker(line, options = {}) {\r\n const { allowZeroSpaceAfterMarker = false } = options;\r\n const regex = allowZeroSpaceAfterMarker ? LINE_REGEX_LOOSE : LINE_REGEX_STRICT;\r\n return line.replace(regex, '');\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Core Types\r\n * \r\n * Data types and enums for the reconciliation system.\r\n */\r\n\r\nimport { getDefaultAuthor } from '../adapters/config.js';\n\n// WordprocessingML namespace\nexport const NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\nexport const NS_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';\n\r\n/**\r\n * Diff operation types from word-level diffing\r\n */\r\nexport const DiffOp = Object.freeze({\r\n EQUAL: 'equal',\r\n DELETE: 'delete',\r\n INSERT: 'insert'\r\n});\r\n\r\n/**\r\n * Run types in the run model\r\n */\r\nexport const RunKind = Object.freeze({\r\n TEXT: 'run',\r\n DELETION: 'deletion',\r\n INSERTION: 'insertion',\r\n HYPERLINK: 'hyperlink',\r\n BOOKMARK: 'bookmark',\r\n FIELD: 'field',\r\n // Container delimiters for preserving hierarchy\r\n CONTAINER_START: 'container_start',\r\n CONTAINER_END: 'container_end',\r\n // Multi-paragraph support\r\n PARAGRAPH_START: 'paragraph_start'\r\n});\r\n\r\n/**\r\n * Container types that wrap runs\r\n */\r\nexport const ContainerKind = Object.freeze({\r\n SDT: 'sdt', // Content Control\r\n SMART_TAG: 'smartTag', // Smart Tag\r\n CUSTOM_XML: 'customXml', // Custom XML\r\n FIELD_COMPLEX: 'fldComplex' // Complex field (fldChar-based)\r\n});\r\n\r\n/**\r\n * Content types for block-level detection\r\n */\r\nexport const ContentType = Object.freeze({\r\n PARAGRAPH: 'paragraph',\r\n BULLET_LIST: 'bullet_list',\r\n NUMBERED_LIST: 'numbered_list',\r\n TABLE: 'table'\r\n});\r\n\r\n/**\r\n * Supported numbering formats\r\n */\r\nexport const NumberFormat = Object.freeze({\r\n DECIMAL: 'decimal', // 1, 2, 3\r\n LOWER_ALPHA: 'lowerLetter', // a, b, c\r\n UPPER_ALPHA: 'upperLetter', // A, B, C\r\n LOWER_ROMAN: 'lowerRoman', // i, ii, iii\r\n UPPER_ROMAN: 'upperRoman', // I, II, III\r\n BULLET: 'bullet', // \u2022\r\n OUTLINE: 'outline' // 1.1.2.3\r\n});\r\n\r\n/**\r\n * Numbering suffixes/formats\r\n */\r\nexport const NumberSuffix = Object.freeze({\r\n PERIOD: 'period', // 1.\r\n PAREN_RIGHT: 'parenRight', // 1)\r\n PAREN_BOTH: 'parenBoth', // (1)\r\n NONE: 'none'\r\n});\r\n\r\n/**\r\n * @typedef {Object} RunEntry\r\n * @property {string} kind - RunKind value\r\n * @property {string} text - Text content of the run\r\n * @property {string} [rPrXml] - Serialized run properties (formatting)\r\n * @property {Element|null} [pPrElement] - Lazy paragraph properties element for PARAGRAPH_START entries\r\n * @property {string} [pPrXml] - Serialized paragraph properties for PARAGRAPH_START entries\r\n * @property {number} startOffset - Start offset in accepted text\r\n * @property {number} endOffset - End offset in accepted text\r\n * @property {string} [author] - Author for track changes\r\n * @property {string} [nodeXml] - Original XML for special elements\r\n */\r\n\r\n/**\r\n * @typedef {Object} DiffOperation\r\n * @property {string} type - DiffOp value\r\n * @property {number} startOffset - Start offset in original text\r\n * @property {number} endOffset - End offset in original text\r\n * @property {string} text - Text content of the operation\r\n */\r\n\r\n/**\r\n * @typedef {Object} FormatHint\r\n * @property {number} start - Start offset in clean text\r\n * @property {number} end - End offset in clean text\r\n * @property {Object} format - Format flags (bold, italic, etc.)\r\n */\r\n\r\n/**\r\n * @typedef {Object} IngestionResult\r\n * @property {RunEntry[]} runModel - Array of run entries\r\n * @property {string} acceptedText - Reconstructed text from runs\r\n * @property {Element|null} pPr - Paragraph properties element\r\n */\r\n\r\n/**\r\n * @typedef {Object} PreprocessResult\r\n * @property {string} cleanText - Text with markdown stripped\r\n * @property {FormatHint[]} formatHints - Position-based format information\r\n */\r\n\r\n/**\r\n * @typedef {Object} ReconciliationResult\r\n * @property {string} ooxml - The reconciled OOXML output\r\n * @property {boolean} isValid - Whether validation passed\r\n * @property {string[]} warnings - Any warnings during processing\r\n */\r\n\r\n/**\r\n * @typedef {Object} SerializationOptions\r\n * @property {string} [author] - Author for generated track changes (defaults to configured default author)\n * @property {boolean} [generateRedlines=true] - Toggle track-change wrappers\r\n * @property {string|null} [font=null] - Optional font override for generated runs\r\n */\r\n\r\n/**\r\n * @typedef {Object} DocumentFragmentOptions\r\n * @property {boolean} [includeNumbering=false] - Include numbering relationship/part\r\n * @property {string|null} [numberingXml=null] - Custom numbering part payload\r\n * @property {boolean} [appendTrailingParagraph=true] - Append trailing blank paragraph\r\n */\r\n\r\n/**\r\n * Escapes XML special characters\r\n * @param {string} str - String to escape\r\n * @returns {string} Escaped string\r\n */\r\nexport function escapeXml(str) {\r\n if (!str) return '';\r\n return str\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n\r\n// Global revision ID counter for track changes\r\nlet revisionIdCounter = 1000;\r\n\r\n/**\r\n * Gets the next unique revision ID for track changes\r\n * @returns {number} Unique revision ID\r\n */\r\nexport function getNextRevisionId() {\r\n return revisionIdCounter++;\r\n}\r\n\r\n/**\r\n * Returns the canonical ISO timestamp used for track-change metadata.\r\n *\r\n * @param {Date} [date] - Optional date source (for tests)\r\n * @returns {string}\r\n */\r\nexport function getRevisionTimestamp(date = new Date()) {\r\n return date.toISOString();\r\n}\r\n\r\n/**\r\n * Creates shared revision metadata for OOXML track-change tags.\r\n *\r\n * @param {string} [author] - Track-change author (defaults to configured default author)\n * @returns {{ id: number, author: string, date: string }}\n */\nexport function createRevisionMetadata(author) {\n const resolvedAuthor = typeof author === 'string' && author.trim()\n ? author.trim()\n : getDefaultAuthor();\n\n return {\n id: getNextRevisionId(),\n author: resolvedAuthor,\n date: getRevisionTimestamp()\n };\n}\n\r\n/**\r\n * Resets the revision ID counter (for testing)\r\n * @param {number} [startValue=1000] - Value to reset to\r\n */\r\nexport function resetRevisionIdCounter(startValue = 1000) {\r\n revisionIdCounter = startValue;\r\n}\r\n", "/**\r\n * Paragraph offset policy for text-model alignment.\r\n *\r\n * The reconciliation stack treats paragraph boundaries as a single newline\r\n * separator inserted between adjacent paragraphs (never after the last one).\r\n */\r\n\r\nexport const PARAGRAPH_BOUNDARY_TEXT = '\\n';\r\nexport const PARAGRAPH_BOUNDARY_LENGTH = PARAGRAPH_BOUNDARY_TEXT.length;\r\n\r\n/**\r\n * Returns true when a paragraph boundary separator should be inserted.\r\n *\r\n * @param {number} paragraphIndex - Zero-based paragraph index\r\n * @param {number} paragraphCount - Total paragraph count\r\n * @returns {boolean}\r\n */\r\nexport function hasParagraphBoundaryAfter(paragraphIndex, paragraphCount) {\r\n return paragraphIndex < paragraphCount - 1;\r\n}\r\n\r\n/**\r\n * Appends paragraph boundary text when policy requires one.\r\n *\r\n * @param {string} text - Source text\r\n * @param {number} paragraphIndex - Zero-based paragraph index\r\n * @param {number} paragraphCount - Total paragraph count\r\n * @returns {string}\r\n */\r\nexport function appendParagraphBoundary(text, paragraphIndex, paragraphCount) {\r\n if (!hasParagraphBoundaryAfter(paragraphIndex, paragraphCount)) {\r\n return text;\r\n }\r\n return text + PARAGRAPH_BOUNDARY_TEXT;\r\n}\r\n\r\n/**\r\n * Advances an offset by paragraph-boundary length when policy requires one.\r\n *\r\n * @param {number} offset - Current offset\r\n * @param {number} paragraphIndex - Zero-based paragraph index\r\n * @param {number} paragraphCount - Total paragraph count\r\n * @returns {number}\r\n */\r\nexport function advanceOffsetForParagraphBoundary(offset, paragraphIndex, paragraphCount) {\r\n if (!hasParagraphBoundaryAfter(paragraphIndex, paragraphCount)) {\r\n return offset;\r\n }\r\n return offset + PARAGRAPH_BOUNDARY_LENGTH;\r\n}\r\n", "/**\r\n * Shared XML query helpers for OOXML documents.\r\n *\r\n * These wrappers provide consistent first/all element access across:\r\n * - Namespace-aware lookups (`getElementsByTagNameNS`)\r\n * - Prefix-based fallbacks (`getElementsByTagName('w:...')`)\r\n */\r\n\r\n/**\r\n * Returns all descendant elements matching a qualified tag name.\r\n *\r\n * @param {Node|Document|Element|null|undefined} node - Query root\r\n * @param {string} tagName - Qualified element name (for example, `w:p`)\r\n * @returns {Element[]}\r\n */\r\nexport function getElementsByTag(node, tagName) {\r\n if (!node || typeof node.getElementsByTagName !== 'function') return [];\r\n return Array.from(node.getElementsByTagName(tagName));\r\n}\r\n\r\n/**\r\n * Returns the first descendant element matching a qualified tag name.\r\n *\r\n * @param {Node|Document|Element|null|undefined} node - Query root\r\n * @param {string} tagName - Qualified element name (for example, `w:p`)\r\n * @returns {Element|null}\r\n */\r\nexport function getFirstElementByTag(node, tagName) {\r\n if (!node || typeof node.getElementsByTagName !== 'function') return null;\r\n const elements = node.getElementsByTagName(tagName);\r\n return elements.length > 0 ? elements[0] : null;\r\n}\r\n\r\n/**\r\n * Returns all descendant elements matching namespace + local name.\r\n *\r\n * @param {Node|Document|Element|null|undefined} node - Query root\r\n * @param {string} namespaceUri - Namespace URI (or `*`)\r\n * @param {string} localName - Local tag name (for example, `p`)\r\n * @returns {Element[]}\r\n */\r\nexport function getElementsByTagNS(node, namespaceUri, localName) {\r\n if (!node || typeof node.getElementsByTagNameNS !== 'function') return [];\r\n return Array.from(node.getElementsByTagNameNS(namespaceUri, localName));\r\n}\r\n\r\n/**\r\n * Returns the first descendant element matching namespace + local name.\r\n *\r\n * @param {Node|Document|Element|null|undefined} node - Query root\r\n * @param {string} namespaceUri - Namespace URI (or `*`)\r\n * @param {string} localName - Local tag name (for example, `p`)\r\n * @returns {Element|null}\r\n */\r\nexport function getFirstElementByTagNS(node, namespaceUri, localName) {\r\n if (!node || typeof node.getElementsByTagNameNS !== 'function') return null;\r\n const elements = node.getElementsByTagNameNS(namespaceUri, localName);\r\n return elements.length > 0 ? elements[0] : null;\r\n}\r\n\r\n/**\r\n * Returns all elements using namespace-aware lookup with prefixed fallback.\r\n *\r\n * @param {Node|Document|Element|null|undefined} node - Query root\r\n * @param {string} namespaceUri - Namespace URI\r\n * @param {string} localName - Local name\r\n * @param {string} [fallbackTagName] - Optional prefixed fallback (default: `w:${localName}`)\r\n * @returns {Element[]}\r\n */\r\nexport function getElementsByTagNSOrTag(node, namespaceUri, localName, fallbackTagName = `w:${localName}`) {\r\n const namespacedElements = getElementsByTagNS(node, namespaceUri, localName);\r\n if (namespacedElements.length > 0) return namespacedElements;\r\n return getElementsByTag(node, fallbackTagName);\r\n}\r\n\r\n/**\r\n * Returns the first element using namespace-aware lookup with prefixed fallback.\r\n *\r\n * @param {Node|Document|Element|null|undefined} node - Query root\r\n * @param {string} namespaceUri - Namespace URI\r\n * @param {string} localName - Local name\r\n * @param {string} [fallbackTagName] - Optional prefixed fallback (default: `w:${localName}`)\r\n * @returns {Element|null}\r\n */\r\nexport function getFirstElementByTagNSOrTag(node, namespaceUri, localName, fallbackTagName = `w:${localName}`) {\r\n const namespacedElement = getFirstElementByTagNS(node, namespaceUri, localName);\r\n if (namespacedElement) return namespacedElement;\r\n return getFirstElementByTag(node, fallbackTagName);\r\n}\r\n\r\n/**\r\n * Returns XML parser error element if present.\r\n *\r\n * @param {Document|Element|null|undefined} xmlDoc - Parsed XML document\r\n * @returns {Element|null}\r\n */\r\nexport function getXmlParseError(xmlDoc) {\r\n return getFirstElementByTag(xmlDoc, 'parsererror');\r\n}\r\n", "/**\r\n * Shared XML helpers for ingestion flows.\r\n */\r\n\r\n/**\r\n * Returns all children as an array.\r\n *\r\n * @param {Node} node - Parent node\r\n * @returns {Node[]}\r\n */\r\nexport function childNodesToArray(node) {\r\n return Array.from(node?.childNodes || []);\r\n}\r\n\r\n/**\r\n * Serializes all attributes into a plain string.\r\n *\r\n * @param {Element} element - Element with attributes\r\n * @returns {string}\r\n */\r\nexport function serializeAttributes(element) {\r\n return Array.from(element.attributes)\r\n .map(attr => `${attr.name}=\"${attr.value}\"`)\r\n .join(' ');\r\n}\r\n\r\n/**\r\n * Returns true when a node belongs to the target namespace and optional local name.\r\n *\r\n * @param {Node} node - Candidate node\r\n * @param {string} namespaceUri - Namespace URI\r\n * @param {string} [localName] - Optional local name\r\n * @returns {boolean}\r\n */\r\nexport function isNamespacedNode(node, namespaceUri, localName = '') {\r\n if (!node || node.namespaceURI !== namespaceUri) return false;\r\n if (!localName) return true;\r\n return node.localName === localName;\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Paragraph Ingestion\r\n *\r\n * Parses paragraph content into run models and accepted text offsets.\r\n */\r\n\r\nimport { NS_W, RunKind, ContainerKind } from '../core/types.js';\r\nimport { appendParagraphBoundary, advanceOffsetForParagraphBoundary } from '../core/paragraph-offset-policy.js';\r\nimport { createParser, serializeXml } from '../adapters/xml-adapter.js';\r\nimport { warn, error as logError } from '../adapters/logger.js';\r\nimport {\r\n getElementsByTagNS,\r\n getFirstElementByTagNS,\r\n getFirstElementByTagNSOrTag,\r\n getXmlParseError\r\n} from '../core/xml-query.js';\r\nimport { childNodesToArray, isNamespacedNode, serializeAttributes } from './ingestion-xml.js';\r\n\r\nlet containerIdCounter = 0;\r\n\r\n/**\r\n * Ingests OOXML paragraph content and builds a run-aware text model.\r\n *\r\n * @param {string} ooxmlString - OOXML input\n * @param {{ xmlDoc?: Document|null }} [options={}] - Optional pre-parsed XML document\n * @returns {import('../core/types.js').IngestionResult}\n */\nexport function ingestOoxml(ooxmlString, options = {}) {\n const runModel = [];\n let acceptedText = '';\n const preParsedDoc = options.xmlDoc || null;\n\n if (!ooxmlString && !preParsedDoc) {\n return { runModel, acceptedText, pPr: null };\n }\n\n try {\n const doc = preParsedDoc || (() => {\n const parser = createParser();\n return parser.parseFromString(ooxmlString, 'application/xml');\n })();\n\n const parseError = getXmlParseError(doc);\n if (parseError) {\n logError('OOXML parse error:', parseError.textContent);\r\n return { runModel, acceptedText, pPr: null };\r\n }\r\n\r\n const paragraphs = getElementsByTagNS(doc, NS_W, 'p');\r\n if (paragraphs.length === 0) {\r\n warn('No paragraphs found in OOXML');\r\n return { runModel, acceptedText, pPr: null };\r\n }\r\n\r\n return ingestParagraphElements(paragraphs, { includeParagraphBoundaries: true });\r\n } catch (error) {\r\n logError('Error ingesting OOXML:', error);\r\n return { runModel, acceptedText, pPr: null };\r\n }\r\n}\r\n\r\n/**\r\n * Ingests a single paragraph element directly, avoiding serialize+reparse cycles.\r\n *\r\n * @param {Element} paragraphElement - Paragraph element\r\n * @returns {import('../core/types.js').IngestionResult}\r\n */\r\nexport function ingestParagraphElement(paragraphElement) {\r\n if (!paragraphElement) {\r\n return { runModel: [], acceptedText: '', pPr: null };\r\n }\r\n return ingestParagraphElements([paragraphElement], { includeParagraphBoundaries: false });\r\n}\r\n\r\n/**\r\n * Extracts numbering metadata from a paragraph.\r\n *\r\n * @param {Element} pElement - w:p element\r\n * @returns {Object|null}\r\n */\r\nexport function detectNumberingContext(pElement) {\r\n const pPr = getFirstElementByTagNS(pElement, NS_W, 'pPr');\r\n if (!pPr) return null;\r\n\r\n const numPr = getFirstElementByTagNS(pPr, NS_W, 'numPr');\r\n if (!numPr) return null;\r\n\r\n const numIdEl = getFirstElementByTagNS(numPr, NS_W, 'numId');\r\n const ilvlEl = getFirstElementByTagNS(numPr, NS_W, 'ilvl');\r\n if (!numIdEl) return null;\r\n\r\n const numId = numIdEl.getAttribute('w:val');\r\n const type = numId === '1' ? 'bullet' : (numId === '2' ? 'numbered' : 'unknown');\r\n\r\n return {\r\n numId,\r\n ilvl: parseInt(ilvlEl?.getAttribute('w:val') || '0', 10),\r\n type\r\n };\r\n}\r\n\r\nfunction ingestParagraphElements(paragraphs, options = {}) {\n const includeParagraphBoundaries = options.includeParagraphBoundaries ?? true;\r\n const runModel = [];\r\n let acceptedText = '';\r\n let currentOffset = 0;\r\n let firstPPr = null;\r\n\r\n for (let pIndex = 0; pIndex < paragraphs.length; pIndex++) {\n const pElement = paragraphs[pIndex];\n const pPr = getFirstElementByTagNS(pElement, NS_W, 'pPr');\n\n if (pIndex === 0) {\n firstPPr = pPr;\n }\n\n runModel.push({\n kind: RunKind.PARAGRAPH_START,\n // Keep pPr as a DOM reference; serialize only when downstream actually needs string XML.\n pPrElement: pPr || null,\n startOffset: currentOffset,\n endOffset: currentOffset,\n text: ''\n });\n\r\n const result = processNodeRecursive(pElement, currentOffset, runModel);\r\n acceptedText += result.text;\r\n currentOffset = acceptedText.length;\r\n\r\n if (includeParagraphBoundaries) {\r\n acceptedText = appendParagraphBoundary(acceptedText, pIndex, paragraphs.length);\r\n currentOffset = advanceOffsetForParagraphBoundary(currentOffset, pIndex, paragraphs.length);\r\n }\r\n }\r\n\r\n return { runModel, acceptedText, pPr: firstPPr };\r\n}\r\n\r\nfunction processNodeRecursive(node, currentOffset, runModel) {\r\n let localOffset = currentOffset;\r\n let text = '';\r\n\r\n const handlers = getNodeHandlers(runModel);\r\n for (const child of childNodesToArray(node)) {\r\n if (isNamespacedNode(child, NS_W, 'pPr') || isNamespacedNode(child, NS_W, 'proofErr')) {\r\n continue;\r\n }\r\n\r\n const handler = handlers.get(child.localName);\r\n if (!handler) continue;\r\n\r\n const result = handler(child, localOffset);\r\n localOffset = result.offset;\r\n text += result.text;\r\n }\r\n\r\n return { offset: localOffset, text };\r\n}\r\n\r\nfunction getNodeHandlers(runModel) {\r\n /** @type {Map<string, (child: Node, offset: number) => { offset: number, text: string }>} */\r\n const handlers = new Map();\r\n\r\n handlers.set('sdt', (child, offset) => {\r\n const containerId = `sdt_${containerIdCounter++}`;\r\n const sdtPr = getFirstElementByTagNS(child, NS_W, 'sdtPr');\r\n const sdtContent = getFirstElementByTagNS(child, NS_W, 'sdtContent');\r\n\r\n runModel.push({\r\n kind: RunKind.CONTAINER_START,\r\n containerKind: ContainerKind.SDT,\r\n containerId,\r\n propertiesXml: sdtPr ? serializeXml(sdtPr) : '',\r\n startOffset: offset,\r\n endOffset: offset,\r\n text: ''\r\n });\r\n\r\n const contentResult = sdtContent\r\n ? processNodeRecursive(sdtContent, offset, runModel)\r\n : { offset, text: '' };\r\n\r\n runModel.push({\r\n kind: RunKind.CONTAINER_END,\r\n containerKind: ContainerKind.SDT,\r\n containerId,\r\n startOffset: contentResult.offset,\r\n endOffset: contentResult.offset,\r\n text: ''\r\n });\r\n\r\n return contentResult;\r\n });\r\n\r\n handlers.set('smartTag', (child, offset) => {\r\n const containerId = `smartTag_${containerIdCounter++}`;\r\n runModel.push({\r\n kind: RunKind.CONTAINER_START,\r\n containerKind: ContainerKind.SMART_TAG,\r\n containerId,\r\n propertiesXml: serializeAttributes(child),\r\n startOffset: offset,\r\n endOffset: offset,\r\n text: ''\r\n });\r\n\r\n const contentResult = processNodeRecursive(child, offset, runModel);\r\n runModel.push({\r\n kind: RunKind.CONTAINER_END,\r\n containerKind: ContainerKind.SMART_TAG,\r\n containerId,\r\n startOffset: contentResult.offset,\r\n endOffset: contentResult.offset,\r\n text: ''\r\n });\r\n\r\n return contentResult;\r\n });\r\n\r\n handlers.set('del', (child, offset) => {\r\n const deletionEntry = processDeletion(child, offset);\r\n if (deletionEntry) {\r\n runModel.push(deletionEntry);\r\n }\r\n return { offset, text: '' };\r\n });\r\n\r\n handlers.set('bookmarkStart', (child, offset) => {\r\n runModel.push({\r\n kind: RunKind.BOOKMARK,\r\n nodeXml: serializeXml(child),\r\n startOffset: offset,\r\n endOffset: offset,\r\n text: ''\r\n });\r\n return { offset, text: '' };\r\n });\r\n\r\n handlers.set('bookmarkEnd', (child, offset) => {\r\n runModel.push({\r\n kind: RunKind.BOOKMARK,\r\n nodeXml: serializeXml(child),\r\n startOffset: offset,\r\n endOffset: offset,\r\n text: ''\r\n });\r\n return { offset, text: '' };\r\n });\r\n\r\n handlers.set('ins', (child, offset) => processNodeRecursive(child, offset, runModel));\r\n\r\n handlers.set('hyperlink', (child, offset) => {\r\n const containerId = `hyperlink_${containerIdCounter++}`;\r\n const rId = child.getAttribute('r:id') || '';\r\n const anchor = child.getAttribute('w:anchor') || '';\r\n\r\n runModel.push({\r\n kind: RunKind.CONTAINER_START,\r\n containerKind: 'hyperlink',\r\n containerId,\r\n propertiesXml: JSON.stringify({ rId, anchor }),\r\n startOffset: offset,\r\n endOffset: offset,\r\n text: ''\r\n });\r\n\r\n const contentResult = processNodeRecursive(child, offset, runModel);\r\n runModel.push({\r\n kind: RunKind.CONTAINER_END,\r\n containerKind: 'hyperlink',\r\n containerId,\r\n startOffset: contentResult.offset,\r\n endOffset: contentResult.offset,\r\n text: ''\r\n });\r\n\r\n return contentResult;\r\n });\r\n\r\n handlers.set('r', (child, offset) => {\r\n const runEntry = processRun(child, offset);\r\n if (!runEntry || !runEntry.text) {\r\n return { offset, text: '' };\r\n }\r\n\r\n runModel.push(runEntry);\r\n const nextOffset = offset + runEntry.text.length;\r\n return { offset: nextOffset, text: runEntry.text };\r\n });\r\n\r\n return handlers;\r\n}\r\n\r\nfunction processRun(runElement, startOffset) {\r\n const rPr = getFirstElementByTagNSOrTag(runElement, NS_W, 'rPr');\r\n const rPrXml = rPr ? serializeXml(rPr) : '';\r\n\r\n let text = '';\r\n for (const child of childNodesToArray(runElement)) {\r\n const nodeName = child.nodeName;\r\n if (nodeName.endsWith(':t') || nodeName === 't') {\r\n text += child.textContent || '';\r\n } else if (nodeName.endsWith(':br') || nodeName === 'br' || nodeName.endsWith(':cr') || nodeName === 'cr') {\r\n text += '\\n';\r\n } else if (nodeName.endsWith(':tab') || nodeName === 'tab') {\r\n text += '\\t';\r\n } else if (nodeName.endsWith(':noBreakHyphen') || nodeName === 'noBreakHyphen') {\r\n text += '\\u2011';\r\n }\r\n }\r\n\r\n if (!text) return null;\r\n\r\n return {\r\n kind: RunKind.TEXT,\r\n text,\r\n rPrXml,\r\n startOffset,\r\n endOffset: startOffset + text.length\r\n };\r\n}\r\n\r\nfunction processDeletion(delElement, offset) {\r\n const author = delElement.getAttribute('w:author') || '';\r\n\r\n let text = '';\r\n const delTexts = getElementsByTagNS(delElement, NS_W, 'delText');\r\n for (const delText of delTexts) {\r\n text += delText.textContent || '';\r\n }\r\n\r\n const runs = getElementsByTagNS(delElement, NS_W, 'r');\r\n for (const run of runs) {\r\n const innerDelTexts = getElementsByTagNS(run, NS_W, 'delText');\r\n for (const delText of innerDelTexts) {\r\n text += delText.textContent || '';\r\n }\r\n }\r\n\r\n if (!text) return null;\r\n\r\n return {\r\n kind: RunKind.DELETION,\r\n text,\r\n rPrXml: '',\r\n startOffset: offset,\r\n endOffset: offset,\r\n author,\r\n nodeXml: serializeXml(delElement)\r\n };\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Table Ingestion\r\n *\r\n * Builds virtual-grid table models with merged-cell awareness.\r\n */\r\n\r\nimport { NS_W } from '../core/types.js';\r\nimport { serializeXml } from '../adapters/xml-adapter.js';\r\nimport {\r\n getElementsByTagNS,\r\n getElementsByTagNSOrTag,\r\n getFirstElementByTag,\r\n getFirstElementByTagNS\r\n} from '../core/xml-query.js';\r\nimport { ingestParagraphElement } from './ingestion-paragraph.js';\r\n\r\n/**\r\n * Ingests a table into a virtual grid model to handle merged cells.\r\n *\r\n * @param {Element} tableNode - w:tbl element\r\n * @returns {Object}\r\n */\r\nexport function ingestTableToVirtualGrid(tableNode) {\r\n const tblGrid = getFirstElementByTagNS(tableNode, NS_W, 'tblGrid');\r\n const gridCols = tblGrid ? getElementsByTagNS(tblGrid, NS_W, 'gridCol') : [];\r\n const colCount = gridCols.length;\r\n\r\n const trElements = getElementsByTagNS(tableNode, NS_W, 'tr');\r\n const rowCount = trElements.length;\r\n\r\n const grid = Array.from({ length: rowCount }, () =>\r\n Array.from({ length: colCount }, () => null)\r\n );\r\n const cellMap = new Map();\r\n const vMergeOrigins = new Map();\r\n\r\n for (let rowIdx = 0; rowIdx < trElements.length; rowIdx++) {\r\n const tr = trElements[rowIdx];\r\n const tcElements = getElementsByTagNS(tr, NS_W, 'tc');\r\n let gridCol = 0;\r\n\r\n for (let tcIdx = 0; tcIdx < tcElements.length; tcIdx++) {\r\n const tc = tcElements[tcIdx];\r\n const tcPr = getFirstElementByTagNS(tc, NS_W, 'tcPr');\r\n\r\n while (gridCol < colCount && grid[rowIdx][gridCol] !== null) {\r\n gridCol++;\r\n }\r\n if (gridCol >= colCount) break;\r\n\r\n const gridSpanEl = tcPr ? (getFirstElementByTagNS(tcPr, NS_W, 'gridSpan') || getFirstElementByTag(tcPr, 'w:gridSpan')) : null;\r\n const colSpan = parseInt(gridSpanEl?.getAttribute('w:val') || '1', 10);\r\n\r\n const vMergeEl = tcPr ? (getFirstElementByTagNS(tcPr, NS_W, 'vMerge') || getFirstElementByTag(tcPr, 'w:vMerge')) : null;\r\n const vMergeVal = vMergeEl?.getAttribute('w:val');\r\n const hasVMerge = vMergeEl !== null;\r\n\r\n let cell;\r\n if (hasVMerge && vMergeVal !== 'restart') {\r\n const origin = vMergeOrigins.get(gridCol);\r\n if (origin) {\r\n origin.cell.rowSpan++;\r\n cell = {\r\n gridRow: rowIdx,\r\n gridCol,\r\n rowSpan: 0,\r\n colSpan,\r\n tcNode: tc,\r\n blocks: [],\r\n tcPrXml: serializeTcPr(tcPr),\r\n isMergeOrigin: false,\r\n isMergeContinuation: true,\r\n mergeOrigin: origin.cell\r\n };\r\n } else {\r\n cell = createRegularCell(rowIdx, gridCol, colSpan, tc, tcPr);\r\n }\r\n } else {\r\n const blocks = parseCellBlocks(tc);\r\n cell = {\r\n gridRow: rowIdx,\r\n gridCol,\r\n rowSpan: 1,\r\n colSpan,\r\n tcNode: tc,\r\n blocks,\r\n tcPrXml: serializeTcPr(tcPr),\r\n isMergeOrigin: hasVMerge && vMergeVal === 'restart',\r\n isMergeContinuation: false,\r\n getText: () => blocks.map(block => block.acceptedText).join('\\n')\r\n };\r\n\r\n if (hasVMerge && vMergeVal === 'restart') {\r\n for (let span = 0; span < colSpan; span++) {\r\n vMergeOrigins.set(gridCol + span, { originRow: rowIdx, cell });\r\n }\r\n } else {\r\n for (let span = 0; span < colSpan; span++) {\r\n vMergeOrigins.delete(gridCol + span);\r\n }\r\n }\r\n }\r\n\r\n for (let spanOffset = 0; spanOffset < colSpan; spanOffset++) {\r\n const targetCol = gridCol + spanOffset;\r\n if (targetCol < colCount) {\r\n grid[rowIdx][targetCol] = cell;\r\n cellMap.set(`${rowIdx},${targetCol}`, cell);\r\n }\r\n }\r\n\r\n gridCol += colSpan;\r\n }\r\n }\r\n\r\n return {\r\n rowCount,\r\n colCount,\r\n grid,\r\n cellMap,\r\n tblPrXml: extractTblPr(tableNode),\r\n tblGridXml: extractTblGrid(tableNode),\r\n trPrList: Array.from(trElements).map(tr => extractTrPr(tr))\r\n };\r\n}\r\n\r\nfunction createRegularCell(rowIdx, gridCol, colSpan, tc, tcPr) {\r\n const blocks = parseCellBlocks(tc);\r\n return {\r\n gridRow: rowIdx,\r\n gridCol,\r\n rowSpan: 1,\r\n colSpan,\r\n tcNode: tc,\r\n blocks,\r\n tcPrXml: serializeTcPr(tcPr),\r\n isMergeOrigin: false,\r\n isMergeContinuation: false,\r\n getText: () => blocks.map(block => block.acceptedText).join('\\n')\r\n };\r\n}\r\n\r\nfunction parseCellBlocks(tcNode) {\r\n const paragraphs = getElementsByTagNSOrTag(tcNode, NS_W, 'p');\r\n return paragraphs.map(paragraph => {\r\n const { runModel, acceptedText, pPr } = ingestParagraphElement(paragraph);\r\n return { runModel, acceptedText, pPr };\r\n });\r\n}\r\n\r\nfunction serializeTcPr(tcPrNode) {\r\n if (!tcPrNode) return '<w:tcPr/>';\r\n return serializeXml(tcPrNode);\r\n}\r\n\r\nfunction extractTblPr(tableNode) {\r\n const tblPr = getFirstElementByTagNS(tableNode, NS_W, 'tblPr');\r\n return tblPr ? serializeXml(tblPr) : '<w:tblPr/>';\r\n}\r\n\r\nfunction extractTblGrid(tableNode) {\r\n const tblGrid = getFirstElementByTagNS(tableNode, NS_W, 'tblGrid');\r\n return tblGrid ? serializeXml(tblGrid) : '<w:tblGrid/>';\r\n}\r\n\r\nfunction extractTrPr(trNode) {\r\n const trPr = getFirstElementByTagNS(trNode, NS_W, 'trPr');\r\n return trPr ? serializeXml(trPr) : '<w:trPr/>';\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Diff Engine\r\n * \r\n * Word-level diffing with offset tracking for precise run splitting.\r\n */\r\n\r\nimport { diff_match_patch } from 'diff-match-patch';\nimport { DiffOp } from '../core/types.js';\n\nconst DMP = new diff_match_patch();\n\n/**\r\n * Converts text into word tokens represented as unique characters.\r\n * This allows DMP to diff at word-level instead of character-level.\r\n * \r\n * @param {string} text1 - First text to tokenize\r\n * @param {string} text2 - Second text to tokenize\r\n * @returns {{ chars1: string, chars2: string, wordArray: string[] }}\r\n */\r\nexport function wordsToChars(text1, text2) {\r\n const wordArray = [];\r\n const wordHash = new Map();\r\n\r\n function tokenize(text) {\r\n const tokens = [];\r\n const regex = /(\\S+)(\\s*)/g;\r\n let match;\r\n while ((match = regex.exec(text)) !== null) {\r\n if (match[1]) tokens.push(match[1]);\r\n if (match[2]) tokens.push(match[2]);\r\n }\r\n return tokens;\r\n }\r\n\r\n function mapTokensToChars(tokens) {\r\n let chars = '';\r\n for (const token of tokens) {\r\n if (wordHash.has(token)) {\r\n chars += String.fromCharCode(wordHash.get(token));\r\n } else {\r\n const charCode = wordArray.length;\r\n wordArray.push(token);\r\n wordHash.set(token, charCode);\r\n chars += String.fromCharCode(charCode);\r\n }\r\n }\r\n return chars;\r\n }\r\n\r\n const tokens1 = tokenize(text1);\r\n const tokens2 = tokenize(text2);\r\n\r\n return {\r\n chars1: mapTokensToChars(tokens1),\r\n chars2: mapTokensToChars(tokens2),\r\n wordArray\r\n };\r\n}\r\n\r\n/**\r\n * Converts character-encoded diffs back to actual word diffs.\r\n * \r\n * @param {Array} diffs - DMP diff array with character codes\r\n * @param {string[]} wordArray - Array mapping char codes to words\r\n * @returns {Array} DMP-style diff array with actual words\r\n */\r\nexport function charsToWords(diffs, wordArray) {\n const wordDiffs = [];\n\n for (const [op, chars] of diffs) {\n const parts = [];\n for (let i = 0; i < chars.length; i++) {\n const charCode = chars.charCodeAt(i);\n if (charCode < wordArray.length) {\n parts.push(wordArray[charCode]);\n }\n }\n wordDiffs.push([op, parts.join('')]);\n }\n\n return wordDiffs;\n}\n\n/**\n * Computes word-level diff tuples using a shared diff engine instance.\n *\n * @param {string} originalText - Original text\n * @param {string} newText - New text\n * @param {{ cleanupSemantic?: boolean }} [options={}] - Diff options\n * @returns {Array<[number, string]>}\n */\nexport function computeWordDiffs(originalText, newText, options = {}) {\n if (originalText === newText) {\n return [[0, originalText]];\n }\n\n if (!originalText) {\n return [[1, newText]];\n }\n\n if (!newText) {\n return [[-1, originalText]];\n }\n\n const { cleanupSemantic = true } = options;\n\n const { chars1, chars2, wordArray } = wordsToChars(originalText, newText);\n const charDiffs = DMP.diff_main(chars1, chars2);\n if (cleanupSemantic) {\n DMP.diff_cleanupSemantic(charDiffs);\n }\n\n return charsToWords(charDiffs, wordArray);\n}\n\n/**\n * Computes word-level diff operations with offset tracking.\n * \r\n * @param {string} originalText - Original text\r\n * @param {string} newText - New text\r\n * @param {{ cleanupSemantic?: boolean }} [options={}] - Diff options\n * @returns {import('../core/types.js').DiffOperation[]}\n */\nexport function computeWordLevelDiffOps(originalText, newText, options = {}) {\n // Handle edge cases\r\n if (originalText === newText) {\r\n return [{\r\n type: DiffOp.EQUAL,\r\n startOffset: 0,\r\n endOffset: originalText.length,\r\n text: originalText\r\n }];\r\n }\r\n\r\n if (!originalText) {\r\n return [{\r\n type: DiffOp.INSERT,\r\n startOffset: 0,\r\n endOffset: 0,\r\n text: newText\r\n }];\r\n }\r\n\r\n if (!newText) {\r\n return [{\r\n type: DiffOp.DELETE,\r\n startOffset: 0,\r\n endOffset: originalText.length,\r\n text: originalText\r\n }];\r\n }\r\n\r\n const wordDiffs = computeWordDiffs(originalText, newText, options);\n\r\n // Convert to operations with offsets\r\n const operations = [];\r\n let originalOffset = 0;\r\n\r\n for (const [op, text] of wordDiffs) {\r\n if (op === 0) { // EQUAL\r\n operations.push({\r\n type: DiffOp.EQUAL,\r\n startOffset: originalOffset,\r\n endOffset: originalOffset + text.length,\r\n text\r\n });\r\n originalOffset += text.length;\r\n } else if (op === -1) { // DELETE\r\n operations.push({\r\n type: DiffOp.DELETE,\r\n startOffset: originalOffset,\r\n endOffset: originalOffset + text.length,\r\n text\r\n });\r\n originalOffset += text.length;\r\n } else if (op === 1) { // INSERT\r\n operations.push({\r\n type: DiffOp.INSERT,\r\n startOffset: originalOffset,\r\n endOffset: originalOffset, // Insertions don't span original text\r\n text\r\n });\r\n // Don't advance originalOffset for insertions\r\n }\r\n }\r\n\r\n return operations;\r\n}\r\n\r\n/**\r\n * Collects all unique boundary offsets from diff operations.\r\n * \r\n * @param {import('../core/types.js').DiffOperation[]} diffOps - Diff operations\r\n * @returns {Set<number>}\r\n */\r\nexport function collectDiffBoundaries(diffOps) {\r\n const boundaries = new Set();\r\n for (const op of diffOps) {\r\n boundaries.add(op.startOffset);\r\n boundaries.add(op.endOffset);\r\n }\r\n return boundaries;\r\n}\r\n\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Patching\r\n *\r\n * Splits runs at diff boundaries and applies patch operations.\r\n */\r\n\r\nimport { DiffOp, RunKind } from '../core/types.js';\nimport { log } from '../adapters/logger.js';\nimport { matchListMarker, stripListMarker } from './list-markers.js';\nimport { serializeXml } from '../adapters/xml-adapter.js';\n\nconst XMLNS_ATTR_REGEX = /\\s+xmlns:[^=]+=\"[^\"]*\"/g;\n\r\n/**\r\n * Splits runs at diff operation boundaries for precise patching.\r\n *\r\n * @param {import('../core/types.js').RunEntry[]} runModel - Original run model\r\n * @param {import('../core/types.js').DiffOperation[]} diffOps - Diff operations\r\n * @returns {import('../core/types.js').RunEntry[]} Split run model\r\n */\r\nexport function splitRunsAtDiffBoundaries(runModel, diffOps) {\r\n const boundaries = buildSortedDiffBoundaries(diffOps);\r\n const newModel = [];\r\n let boundaryCursor = 0;\r\n\r\n for (const run of runModel) {\r\n if (run.kind !== RunKind.TEXT && run.kind !== RunKind.HYPERLINK) {\r\n newModel.push(run);\r\n continue;\r\n }\r\n\r\n while (boundaryCursor < boundaries.length && boundaries[boundaryCursor] <= run.startOffset) {\r\n boundaryCursor++;\r\n }\r\n\r\n let cursor = boundaryCursor;\r\n let currentStart = run.startOffset;\r\n let hasSplit = false;\r\n\r\n while (cursor < boundaries.length) {\r\n const boundary = boundaries[cursor];\r\n if (boundary >= run.endOffset) break;\r\n\r\n if (boundary > currentStart) {\r\n hasSplit = true;\r\n newModel.push({\r\n ...run,\r\n text: run.text.slice(currentStart - run.startOffset, boundary - run.startOffset),\r\n startOffset: currentStart,\r\n endOffset: boundary\r\n });\r\n currentStart = boundary;\r\n }\r\n cursor++;\r\n }\r\n\r\n boundaryCursor = cursor;\r\n\r\n if (!hasSplit) {\r\n newModel.push(run);\r\n continue;\r\n }\r\n\r\n newModel.push({\r\n ...run,\r\n text: run.text.slice(currentStart - run.startOffset),\r\n startOffset: currentStart,\r\n endOffset: run.endOffset\r\n });\r\n }\r\n\r\n return newModel;\r\n}\r\n\r\n/**\r\n * Applies diff operations to the split run model.\r\n *\r\n * @param {import('../core/types.js').RunEntry[]} splitModel - Pre-split run model\r\n * @param {import('../core/types.js').DiffOperation[]} diffOps - Diff operations\r\n * @param {Object} options - Patching options\r\n * @param {boolean} options.generateRedlines - Whether to generate track changes\r\n * @param {string} options.author - Author for track changes\r\n * @param {import('../core/types.js').FormatHint[]} [options.formatHints] - Format hints\r\n * @returns {import('../core/types.js').RunEntry[]}\r\n */\r\nexport function applyPatches(splitModel, diffOps, options) {\n const { generateRedlines, author } = options;\r\n const patchedModel = [];\r\n const processedInsertions = new Set();\r\n const diffLookup = buildPatchLookupIndex(diffOps);\r\n const styleLookup = buildTextRunLookup(splitModel);\r\n const getCoveringDiffOp = createRangeCursorLookup(diffLookup.nonInsertOps);\r\n const state = {\n containerStack: [],\n lastParagraphStartIndex: -1,\n currentParagraphPPrXml: '',\n currentParagraphPPrElement: null\n };\n\r\n for (const run of splitModel) {\r\n if (run.kind === RunKind.CONTAINER_START) {\r\n state.containerStack.push(run.containerId);\r\n patchedModel.push({ ...run });\r\n continue;\r\n }\r\n\r\n if (run.kind === RunKind.CONTAINER_END) {\r\n state.containerStack.pop();\r\n patchedModel.push({ ...run });\r\n continue;\r\n }\r\n\r\n if (run.kind === RunKind.PARAGRAPH_START) {\n state.currentParagraphPPrXml = typeof run.pPrXml === 'string' ? run.pPrXml : '';\n state.currentParagraphPPrElement = run.pPrElement || null;\n patchedModel.push({ ...run });\n state.lastParagraphStartIndex = patchedModel.length - 1;\n continue;\n }\n\r\n if (run.kind === RunKind.BOOKMARK || run.kind === RunKind.DELETION) {\r\n patchedModel.push({ ...run });\r\n continue;\r\n }\r\n\r\n const op = getCoveringDiffOp(run.startOffset, run.endOffset);\r\n const insertOps = diffLookup.insertOpsByStartOffset.get(run.startOffset) || [];\r\n\r\n for (const insertOp of insertOps) {\r\n if (processedInsertions.has(insertOp)) continue;\r\n processedInsertions.add(insertOp);\r\n processInsertionOperation({\r\n insertOp,\r\n splitModel,\r\n styleLookup,\r\n patchedModel,\r\n state,\r\n options,\r\n generateRedlines,\r\n author\r\n });\r\n }\r\n\r\n if (!op || op.type === DiffOp.EQUAL) {\r\n patchedModel.push({\r\n ...run,\r\n containerContext: state.containerStack.length > 0 ? state.containerStack[state.containerStack.length - 1] : null\r\n });\r\n continue;\r\n }\r\n\r\n if (op.type === DiffOp.DELETE && generateRedlines) {\r\n patchedModel.push({\r\n ...run,\r\n kind: RunKind.DELETION,\r\n author,\r\n containerContext: state.containerStack.length > 0 ? state.containerStack[state.containerStack.length - 1] : null\r\n });\r\n }\r\n }\r\n\r\n const endOffset = splitModel.length > 0\r\n ? Math.max(...splitModel.map(run => run.endOffset))\r\n : 0;\r\n\r\n for (const insertOp of diffLookup.sortedInsertOps) {\r\n if (insertOp.startOffset < endOffset || processedInsertions.has(insertOp)) continue;\r\n\r\n const lastRun = splitModel[splitModel.length - 1];\r\n patchedModel.push({\r\n kind: generateRedlines ? RunKind.INSERTION : RunKind.TEXT,\r\n text: insertOp.text,\r\n rPrXml: lastRun?.rPrXml || '',\r\n startOffset: insertOp.startOffset,\r\n endOffset: insertOp.startOffset + insertOp.text.length,\r\n author: generateRedlines ? author : undefined\r\n });\r\n }\r\n\r\n return patchedModel;\r\n}\r\n\r\nfunction processInsertionOperation(context) {\n const {\r\n insertOp,\r\n splitModel,\r\n styleLookup,\r\n patchedModel,\r\n state,\r\n options,\r\n generateRedlines,\r\n author\r\n } = context;\r\n\r\n const lines = insertOp.text.split('\\n');\r\n const styleSource = chooseInsertionStyle(styleLookup, insertOp.startOffset, insertOp.text);\r\n\r\n for (let index = 0; index < lines.length; index++) {\n const parsed = parseInsertionLine(lines[index], options.numberingService, state);\n const lineText = parsed.lineText;\n\n if (index > 0) {\n let newPPrXml = resolveCurrentParagraphPPrXml(state);\n if (parsed.isListLine && parsed.numId) {\n newPPrXml = options.numberingService.buildListPPr(parsed.numId, parsed.ilvl);\n }\n\n patchedModel.push({\n kind: RunKind.PARAGRAPH_START,\n pPrXml: newPPrXml,\n startOffset: insertOp.startOffset,\n endOffset: insertOp.startOffset,\n text: ''\n });\n state.currentParagraphPPrXml = newPPrXml;\n state.currentParagraphPPrElement = null;\n state.lastParagraphStartIndex = patchedModel.length - 1;\n } else if (parsed.isListLine && parsed.numId && state.lastParagraphStartIndex >= 0) {\n const newPPrXml = options.numberingService.buildListPPr(parsed.numId, parsed.ilvl);\n patchedModel[state.lastParagraphStartIndex].pPrXml = newPPrXml;\n patchedModel[state.lastParagraphStartIndex].pPrElement = null;\n state.currentParagraphPPrXml = newPPrXml;\n state.currentParagraphPPrElement = null;\n log(`[Patching] Converted current paragraph to list item: numId=${parsed.numId}, ilvl=${parsed.ilvl}`);\n }\n\r\n if (lineText.length > 0 || index > 0) {\r\n patchedModel.push({\r\n kind: generateRedlines ? RunKind.INSERTION : RunKind.TEXT,\r\n text: lineText,\r\n rPrXml: styleSource?.rPrXml || '',\r\n startOffset: insertOp.startOffset,\r\n endOffset: insertOp.startOffset + lineText.length,\r\n author: generateRedlines ? author : undefined,\r\n containerContext: state.containerStack.length > 0 ? state.containerStack[state.containerStack.length - 1] : null\r\n });\r\n }\r\n }\n}\n\nfunction parseInsertionLine(line, numberingService, state) {\n if (!numberingService) {\n return { lineText: line, isListLine: false, numId: null, ilvl: 0 };\n }\n\n const markerMatch = matchListMarker(line, { allowZeroSpaceAfterMarker: true });\n if (!markerMatch) {\r\n return { lineText: line, isListLine: false, numId: null, ilvl: 0 };\r\n }\r\n\r\n const marker = markerMatch[2].trim();\r\n const lineFormat = numberingService.detectNumberingFormat(marker);\r\n const indentMatch = line.match(/^(\\s*)/);\n const indentSize = indentMatch ? indentMatch[1].length : 0;\n const indentStep = indentSize >= 4 ? 4 : 2;\n const indentLevel = Math.floor(indentSize / indentStep);\n\n const currentPPrXml = resolveCurrentParagraphPPrXml(state);\n const lineText = stripListMarker(line, { allowZeroSpaceAfterMarker: true });\n const numIdMatch = currentPPrXml.match(/w:numId w:val=\"(\\d+)\"/);\n const ilvlMatch = currentPPrXml.match(/w:ilvl w:val=\"(\\d+)\"/);\n const contextNumId = numIdMatch ? numIdMatch[1] : null;\n const contextIlvl = ilvlMatch ? parseInt(ilvlMatch[1], 10) : 0;\n\r\n const numId = numberingService.getOrCreateNumId(\r\n { type: lineFormat.format },\r\n { numId: contextNumId, type: 'unknown' }\r\n );\r\n\r\n const ilvl = lineFormat.format === 'outline'\r\n ? Math.min(8, lineFormat.depth)\r\n : Math.min(8, indentLevel + contextIlvl);\r\n\n return { lineText, isListLine: true, numId, ilvl };\n}\n\nfunction resolveCurrentParagraphPPrXml(state) {\n if (state.currentParagraphPPrXml) {\n return state.currentParagraphPPrXml;\n }\n\n if (!state.currentParagraphPPrElement) {\n return '';\n }\n\n state.currentParagraphPPrXml = serializeXml(state.currentParagraphPPrElement).replace(XMLNS_ATTR_REGEX, '');\n return state.currentParagraphPPrXml;\n}\n\r\nfunction chooseInsertionStyle(styleLookup, offset, insertText) {\r\n const prevRun = styleLookup.findRunBefore(offset);\r\n const nextRun = styleLookup.findRunAfter(offset);\r\n\r\n if (!prevRun && !nextRun) return null;\r\n if (!prevRun) return nextRun;\r\n if (!nextRun) return prevRun;\r\n\r\n if (insertText && insertText.endsWith(' ')) return nextRun;\r\n if (insertText && insertText.startsWith(' ')) return prevRun;\r\n\r\n return prevRun;\r\n}\r\n\r\nfunction buildTextRunLookup(runModel) {\r\n const textRuns = runModel.filter(run => run.kind === RunKind.TEXT);\r\n const starts = textRuns.map(run => run.startOffset);\r\n const ends = textRuns.map(run => run.endOffset);\r\n\r\n return {\r\n findRunBefore(offset) {\r\n let left = 0;\r\n let right = ends.length - 1;\r\n let answer = -1;\r\n\r\n while (left <= right) {\r\n const middle = (left + right) >> 1;\r\n if (ends[middle] <= offset) {\r\n answer = middle;\r\n left = middle + 1;\r\n } else {\r\n right = middle - 1;\r\n }\r\n }\r\n\r\n return answer >= 0 ? textRuns[answer] : null;\r\n },\r\n\r\n findRunAfter(offset) {\r\n let left = 0;\r\n let right = starts.length - 1;\r\n let answer = -1;\r\n\r\n while (left <= right) {\r\n const middle = (left + right) >> 1;\r\n if (starts[middle] >= offset) {\r\n answer = middle;\r\n right = middle - 1;\r\n } else {\r\n left = middle + 1;\r\n }\r\n }\r\n\r\n return answer >= 0 ? textRuns[answer] : null;\r\n }\r\n };\r\n}\r\n\r\nfunction createRangeCursorLookup(operations) {\r\n let cursor = 0;\r\n return (startOffset, endOffset) => {\r\n while (cursor < operations.length && operations[cursor].endOffset <= startOffset) {\r\n cursor++;\r\n }\r\n\r\n const operation = operations[cursor];\r\n if (!operation) return null;\r\n if (operation.startOffset <= startOffset && operation.endOffset >= endOffset) {\r\n return operation;\r\n }\r\n return null;\r\n };\r\n}\r\n\r\nfunction buildSortedDiffBoundaries(diffOps) {\r\n const unique = new Set();\r\n for (const op of diffOps) {\r\n unique.add(op.startOffset);\r\n unique.add(op.endOffset);\r\n }\r\n return Array.from(unique).sort((a, b) => a - b);\r\n}\r\n\r\n/**\r\n * Builds indexed diff lookups for patching hot paths.\r\n *\r\n * @param {import('../core/types.js').DiffOperation[]} diffOps - Diff operations\r\n * @returns {{\r\n * insertOpsByStartOffset: Map<number, import('../core/types.js').DiffOperation[]>,\r\n * nonInsertOps: import('../core/types.js').DiffOperation[],\r\n * sortedInsertOps: import('../core/types.js').DiffOperation[]\r\n * }}\r\n */\r\nfunction buildPatchLookupIndex(diffOps) {\r\n const insertOpsByStartOffset = new Map();\r\n const nonInsertOps = [];\r\n const sortedInsertOps = [];\r\n\r\n for (const op of diffOps) {\r\n if (op.type === DiffOp.INSERT) {\r\n if (!insertOpsByStartOffset.has(op.startOffset)) {\r\n insertOpsByStartOffset.set(op.startOffset, []);\r\n }\r\n insertOpsByStartOffset.get(op.startOffset).push(op);\r\n sortedInsertOps.push(op);\r\n continue;\r\n }\r\n nonInsertOps.push(op);\r\n }\r\n\r\n nonInsertOps.sort((a, b) => a.startOffset - b.startOffset || a.endOffset - b.endOffset);\r\n sortedInsertOps.sort((a, b) => a.startOffset - b.startOffset || a.endOffset - b.endOffset);\r\n\r\n return {\r\n insertOpsByStartOffset,\r\n nonInsertOps,\r\n sortedInsertOps\r\n };\r\n}\r\n", "/**\r\n * Shared OOXML package builders.\r\n *\r\n * Centralizes `pkg:package` construction used by pipeline/engine/services.\r\n */\r\n\r\nconst NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\r\nconst NS_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';\r\nconst NS_PKG = 'http://schemas.microsoft.com/office/2006/xmlPackage';\r\nconst NS_REL = 'http://schemas.openxmlformats.org/package/2006/relationships';\r\n\r\nconst REL_OFFICE_DOCUMENT = '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>';\r\nconst REL_NUMBERING = '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>';\r\nconst REL_COMMENTS = '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\" Target=\"comments.xml\"/>';\r\n\r\nconst DEFAULT_NUMBERING_XML = `\r\n<w:numbering xmlns:w=\"${NS_W}\">\r\n <w:abstractNum w:abstractNumId=\"0\">\r\n <w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"•\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n </w:abstractNum>\r\n <w:abstractNum w:abstractNumId=\"1\">\r\n <w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n </w:abstractNum>\r\n <w:num w:numId=\"1\"><w:abstractNumId w:val=\"0\"/></w:num>\r\n <w:num w:numId=\"2\"><w:abstractNumId w:val=\"1\"/></w:num>\r\n</w:numbering>`.trim();\r\n\r\nfunction stripXmlDeclaration(xml) {\r\n if (!xml) return '';\r\n return xml.replace(/<\\?xml[^>]*\\?>/g, '');\r\n}\r\n\r\nfunction buildWordDocument(bodyXml, includeRelationshipsNamespace = true) {\r\n const rNs = includeRelationshipsNamespace ? ` xmlns:r=\"${NS_R}\"` : '';\r\n return `<w:document xmlns:w=\"${NS_W}\"${rNs}><w:body>${bodyXml}</w:body></w:document>`;\r\n}\r\n\r\nfunction buildCommentsPart(commentsXml) {\r\n return `\r\n <pkg:part pkg:name=\"/word/comments.xml\" pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml\">\r\n <pkg:xmlData>\r\n ${commentsXml}\r\n </pkg:xmlData>\r\n </pkg:part>`;\r\n}\r\n\r\nfunction buildNumberingPart(numberingXml) {\r\n return `\r\n <pkg:part pkg:name=\"/word/numbering.xml\" pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\">\r\n <pkg:xmlData>\r\n ${stripXmlDeclaration(numberingXml)}\r\n </pkg:xmlData>\r\n </pkg:part>`;\r\n}\r\n\r\nfunction buildPackage(documentXml, documentRelationshipsXml = '', extraPartsXml = '') {\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n<pkg:package xmlns:pkg=\"${NS_PKG}\">\r\n <pkg:part pkg:name=\"/_rels/.rels\" pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\">\r\n <pkg:xmlData>\r\n <Relationships xmlns=\"${NS_REL}\">\r\n ${REL_OFFICE_DOCUMENT}\r\n </Relationships>\r\n </pkg:xmlData>\r\n </pkg:part>\r\n <pkg:part pkg:name=\"/word/_rels/document.xml.rels\" pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\">\r\n <pkg:xmlData>\r\n <Relationships xmlns=\"${NS_REL}\">\r\n ${documentRelationshipsXml}\r\n </Relationships>\r\n </pkg:xmlData>\r\n </pkg:part>${extraPartsXml}\r\n <pkg:part pkg:name=\"/word/document.xml\" pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\">\r\n <pkg:xmlData>\r\n ${documentXml}\r\n </pkg:xmlData>\r\n </pkg:part>\r\n</pkg:package>`;\r\n}\r\n\r\n/**\r\n * Builds a package for paragraph/document-fragment insertion.\r\n *\r\n * @param {string} paragraphXml - Paragraph OOXML content\r\n * @param {import('../core/types.js').DocumentFragmentOptions} [options={}] - Packaging options\r\n * @returns {string}\r\n */\r\nexport function buildDocumentFragmentPackage(paragraphXml, options = {}) {\r\n const {\r\n includeNumbering = false,\r\n numberingXml = null,\r\n appendTrailingParagraph = true\r\n } = options;\r\n\r\n const bodyXml = appendTrailingParagraph\r\n ? `${paragraphXml}<w:p><w:pPr></w:pPr></w:p>`\r\n : paragraphXml;\r\n\r\n const documentXml = buildWordDocument(bodyXml, true);\r\n\r\n let relationshipsXml = '';\r\n let extraPartsXml = '';\r\n\r\n if (numberingXml) {\r\n relationshipsXml = REL_NUMBERING;\r\n extraPartsXml += buildNumberingPart(numberingXml);\r\n } else if (includeNumbering) {\r\n relationshipsXml = REL_NUMBERING;\r\n extraPartsXml += buildNumberingPart(DEFAULT_NUMBERING_XML);\r\n }\r\n\r\n return buildPackage(documentXml, relationshipsXml, extraPartsXml);\r\n}\r\n\r\n/**\r\n * Builds a minimal package containing only paragraph XML in `word/document.xml`.\r\n *\r\n * @param {string} paragraphXml - Paragraph OOXML content\r\n * @returns {string}\r\n */\r\nexport function buildParagraphOnlyPackage(paragraphXml) {\r\n const documentXml = buildWordDocument(paragraphXml, true);\r\n return buildPackage(documentXml);\r\n}\r\n\r\n/**\r\n * Builds a minimal paragraph package with comments relationship + part.\r\n *\r\n * @param {string} paragraphXml - Paragraph OOXML content\r\n * @param {string} commentsXml - Comments part content\r\n * @returns {string}\r\n */\r\nexport function buildParagraphCommentsPackage(paragraphXml, commentsXml) {\r\n const documentXml = buildWordDocument(paragraphXml, false);\r\n return buildPackage(documentXml, REL_COMMENTS, buildCommentsPart(commentsXml));\r\n}\r\n\r\n/**\r\n * Builds a package around caller-provided document XML, adding comments part/relationship.\r\n *\r\n * @param {string} documentXml - Document XML payload for `word/document.xml`\r\n * @param {string} commentsXml - Comments part content\r\n * @returns {string}\r\n */\r\nexport function buildDocumentCommentsPackage(documentXml, commentsXml) {\r\n return buildPackage(documentXml, REL_COMMENTS, buildCommentsPart(commentsXml));\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Serialization\r\n * \r\n * Converts patched run model back to OOXML with track changes.\r\n */\r\n\r\nimport { RunKind, escapeXml, createRevisionMetadata } from '../core/types.js';\nimport { getApplicableFormatHints } from './markdown-processor.js';\nimport { serializeXml } from '../adapters/xml-adapter.js';\nimport { warn } from '../adapters/logger.js';\nimport { buildDocumentFragmentPackage } from '../services/package-builder.js';\nimport { getDefaultAuthor } from '../adapters/config.js';\n\nconst XMLNS_ATTR_REGEX = /\\s+xmlns:[^=]+=\"[^\"]*\"/g;\n\r\n/**\r\n * Serializes a patched run model to OOXML.\r\n * \r\n * @param {import('../core/types.js').RunEntry[]} patchedModel - The patched run model\r\n * @param {Element|null} pPr - Paragraph properties element\r\n * @param {import('../core/types.js').FormatHint[]} [formatHints=[]] - Format hints\r\n * @param {import('../core/types.js').SerializationOptions} [options={}] - Serialization options\r\n * @returns {string} OOXML paragraph string (WITHOUT namespace - added by wrapper)\r\n */\r\nexport function serializeToOoxml(patchedModel, pPr, formatHints = [], options = {}) {\n const serializationOptions = normalizeSerializationOptions(options);\n const { author, generateRedlines } = serializationOptions;\n const paragraphs = [];\n let currentPPrXml = '';\n let currentPPrElement = null;\n let currentRuns = [];\n\r\n // Helper to flush accumulated runs into a paragraph\r\n function flushParagraph() {\r\n if (currentRuns.length > 0 || paragraphs.length === 0) {\r\n // Build paragraph properties - handle both string and DOM element\r\n let pPrContent = '';\n if (currentPPrXml) {\n pPrContent = stripNamespaceDeclarations(currentPPrXml);\n } else if (currentPPrElement) {\n currentPPrXml = stripNamespaceDeclarations(serializeXml(currentPPrElement));\n pPrContent = currentPPrXml;\n } else if (pPr) {\n // Fallback to legacy pPr if no PARAGRAPH_START was seen\n if (typeof pPr === 'string') {\n pPrContent = pPr;\n } else {\n pPrContent = serializeXml(pPr);\n }\n pPrContent = stripNamespaceDeclarations(pPrContent);\n }\n paragraphs.push(`<w:p>${pPrContent}${currentRuns.join('')}</w:p>`);\n currentRuns = [];\n }\n }\r\n\r\n for (const item of patchedModel) {\r\n switch (item.kind) {\r\n case RunKind.PARAGRAPH_START:\r\n // Flush previous paragraph before starting a new one\r\n if (currentRuns.length > 0 || paragraphs.length > 0) {\n flushParagraph();\n }\n currentPPrXml = item.pPrXml || '';\n currentPPrElement = item.pPrElement || null;\n break;\n\r\n case RunKind.TEXT:\r\n currentRuns.push(buildRunXmlWithHints(item, formatHints, serializationOptions));\r\n break;\r\n\r\n case RunKind.DELETION:\r\n if (generateRedlines) {\r\n currentRuns.push(buildDeletionXml(item, serializationOptions));\r\n }\r\n // If redlines are disabled, we simply omit the deleted content\r\n break;\r\n\r\n case RunKind.INSERTION:\r\n if (generateRedlines) {\r\n currentRuns.push(buildInsertionXml(item, formatHints, serializationOptions));\r\n } else {\r\n // Treat insertion as a normal run when redlines are disabled\r\n currentRuns.push(buildRunXmlWithHints(item, formatHints, serializationOptions));\r\n }\r\n break;\r\n\r\n case RunKind.BOOKMARK:\r\n case RunKind.HYPERLINK:\r\n // Pass through original XML - but strip any namespace declarations\n if (item.nodeXml) {\n currentRuns.push(stripNamespaceDeclarations(item.nodeXml));\n }\n break;\n\r\n case RunKind.CONTAINER_START:\r\n if (item.containerKind === 'sdt') {\r\n currentRuns.push(`<w:sdt>${item.propertiesXml}<w:sdtContent>`);\r\n } else if (item.containerKind === 'smartTag') {\r\n currentRuns.push(`<w:smartTag ${item.propertiesXml}>`);\r\n } else if (item.containerKind === 'hyperlink') {\r\n const props = JSON.parse(item.propertiesXml);\r\n const rIdAttr = props.rId ? ` r:id=\"${props.rId}\"` : '';\r\n const anchorAttr = props.anchor ? ` w:anchor=\"${props.anchor}\"` : '';\r\n currentRuns.push(`<w:hyperlink${rIdAttr}${anchorAttr}>`);\r\n }\r\n break;\r\n\r\n case RunKind.CONTAINER_END:\r\n if (item.containerKind === 'sdt') {\r\n currentRuns.push(`</w:sdtContent></w:sdt>`);\r\n } else if (item.containerKind === 'smartTag') {\r\n currentRuns.push(`</w:smartTag>`);\r\n } else if (item.containerKind === 'hyperlink') {\r\n currentRuns.push(`</w:hyperlink>`);\r\n }\r\n break;\r\n\r\n default:\r\n warn('Unknown run kind:', item.kind);\r\n }\r\n }\r\n\r\n // Flush final paragraph\r\n flushParagraph();\r\n\r\n // Return all paragraphs WITHOUT namespace - wrapper will add it\r\n return paragraphs.join('');\r\n}\r\n\r\n/**\r\n * Normalizes serialization options to a single object contract.\r\n *\r\n * @param {import('../core/types.js').SerializationOptions|string|undefined|null} options - Raw options\r\n * @returns {import('../core/types.js').SerializationOptions}\r\n */\r\nfunction normalizeSerializationOptions(options) {\n // Backward compatibility: accept legacy `font` string signature.\n if (typeof options === 'string') {\n return {\n author: getDefaultAuthor(),\n generateRedlines: true,\n font: options\n };\n }\n\n const normalized = options && typeof options === 'object' ? options : {};\n const resolvedAuthor = typeof normalized.author === 'string' && normalized.author.trim()\n ? normalized.author.trim()\n : getDefaultAuthor();\n\n return {\n author: resolvedAuthor,\n generateRedlines: normalized.generateRedlines ?? true,\n font: normalized.font ?? null\n };\n}\n\r\n/**\r\n * Builds a run XML element, applying format hints if applicable.\r\n * \r\n * @param {import('../core/types.js').RunEntry} item - Run entry\r\n * @param {import('../core/types.js').FormatHint[]} formatHints - Format hints\r\n * @param {import('../core/types.js').SerializationOptions} options - Serialization options\r\n * @returns {string}\r\n */\r\nfunction buildRunXmlWithHints(item, formatHints, options = {}) {\n const applicableHints = getApplicableFormatHints(formatHints, item.startOffset, item.endOffset);\n const font = options?.font ?? null;\n let cleanRPr = item.rPrXml ? stripNamespaceDeclarations(item.rPrXml) : '';\n\r\n if (font) {\r\n cleanRPr = applyFont(cleanRPr, font);\r\n }\r\n\r\n if (applicableHints.length === 0) {\r\n // No formatting changes - use original rPr (strip namespace)\r\n return buildSimpleRun(item.text, cleanRPr);\r\n }\r\n\r\n // Split the run text at format boundaries and apply hints\r\n const runs = [];\r\n let pos = 0;\r\n const text = item.text;\r\n const baseOffset = item.startOffset;\r\n\r\n for (const hint of applicableHints) {\r\n const localStart = Math.max(0, hint.start - baseOffset);\r\n const localEnd = Math.min(text.length, hint.end - baseOffset);\r\n\r\n // Text before the hint\r\n if (localStart > pos) {\r\n runs.push(buildSimpleRun(text.slice(pos, localStart), cleanRPr));\r\n }\r\n\r\n // Formatted text\r\n const formattedRPr = injectFormatting(cleanRPr, hint.format);\r\n runs.push(buildSimpleRun(text.slice(localStart, localEnd), formattedRPr));\r\n pos = localEnd;\r\n }\r\n\r\n // Remaining text after last hint\r\n if (pos < text.length) {\r\n runs.push(buildSimpleRun(text.slice(pos), cleanRPr));\r\n }\r\n\r\n return runs.join('');\r\n}\r\n\r\n/**\r\n * Builds a simple w:r element.\r\n * \r\n * @param {string} text - Text content\r\n * @param {string} rPrXml - Run properties XML\r\n * @returns {string}\r\n */\r\nfunction buildSimpleRun(text, rPrXml) {\r\n if (!text) return '';\r\n const rPr = rPrXml || '';\r\n return `<w:r>${rPr}<w:t xml:space=\"preserve\">${escapeXml(text)}</w:t></w:r>`;\r\n}\r\n\r\n/**\r\n * Builds a deletion (w:del) element.\r\n * \r\n * @param {import('../core/types.js').RunEntry} item - Deletion entry\r\n * @param {import('../core/types.js').SerializationOptions} options - Serialization options\r\n * @returns {string}\r\n */\r\nfunction buildDeletionXml(item, options = {}) {\n const metadata = createRevisionMetadata(options.author ?? getDefaultAuthor());\n const font = options.font ?? null;\n let rPr = item.rPrXml ? stripNamespaceDeclarations(item.rPrXml) : '';\n\r\n if (font) {\r\n rPr = applyFont(rPr, font);\r\n }\r\n\r\n return `<w:del w:id=\"${metadata.id}\" w:author=\"${escapeXml(metadata.author)}\" w:date=\"${metadata.date}\">` +\r\n `<w:r>${rPr}<w:delText xml:space=\"preserve\">${escapeXml(item.text)}</w:delText></w:r>` +\r\n `</w:del>`;\r\n}\r\n\r\n/**\r\n * Builds an insertion (w:ins) element.\r\n * \r\n * @param {import('../core/types.js').RunEntry} item - Insertion entry\r\n * @param {import('../core/types.js').FormatHint[]} formatHints - Format hints\r\n * @param {import('../core/types.js').SerializationOptions} options - Serialization options\r\n * @returns {string}\r\n */\r\nfunction buildInsertionXml(item, formatHints, options = {}) {\n const metadata = createRevisionMetadata(options.author ?? getDefaultAuthor());\n const font = options.font ?? null;\r\n\r\n // Build the inner run content with format hints\r\n const applicableHints = getApplicableFormatHints(formatHints, item.startOffset, item.endOffset);\r\n let innerContent = '';\r\n let cleanRPr = item.rPrXml ? stripNamespaceDeclarations(item.rPrXml) : '';\n\r\n if (font) {\r\n cleanRPr = applyFont(cleanRPr, font);\r\n }\r\n\r\n if (applicableHints.length === 0) {\r\n innerContent = buildSimpleRun(item.text, cleanRPr);\r\n } else {\r\n // Apply format hints\r\n let pos = 0;\r\n const text = item.text;\r\n const baseOffset = item.startOffset;\r\n\r\n for (const hint of applicableHints) {\r\n const localStart = Math.max(0, hint.start - baseOffset);\r\n const localEnd = Math.min(text.length, hint.end - baseOffset);\r\n\r\n if (localStart > pos) {\r\n innerContent += buildSimpleRun(text.slice(pos, localStart), cleanRPr);\r\n }\r\n\r\n const formattedRPr = injectFormatting(cleanRPr, hint.format);\r\n innerContent += buildSimpleRun(text.slice(localStart, localEnd), formattedRPr);\r\n pos = localEnd;\r\n }\r\n\r\n if (pos < text.length) {\r\n innerContent += buildSimpleRun(text.slice(pos), cleanRPr);\r\n }\r\n }\r\n\r\n return `<w:ins w:id=\"${metadata.id}\" w:author=\"${escapeXml(metadata.author)}\" w:date=\"${metadata.date}\">` +\r\n innerContent +\r\n `</w:ins>`;\r\n}\r\n\r\n/**\r\n * Applies a font to run properties XML.\r\n * \r\n * @param {string} baseRPrXml - Base run properties\r\n * @param {string} font - Font name\r\n * @returns {string}\r\n */\r\nfunction applyFont(baseRPrXml, font) {\r\n if (!font) return baseRPrXml;\r\n\r\n // Extract existing content from rPr\r\n let content = '';\r\n if (baseRPrXml) {\r\n content = baseRPrXml.replace(/<\\/?w:rPr[^>]*>/g, '');\r\n }\r\n\r\n // Replace or add rFonts\r\n if (content.includes('<w:rFonts')) {\r\n content = content.replace(/<w:rFonts[^>]*\\/>/, `<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\"/>`);\r\n } else {\r\n content = `<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\"/>` + content;\r\n }\r\n\r\n return `<w:rPr>${content}</w:rPr>`;\r\n}\r\n\r\n/**\r\n * Injects formatting into run properties XML.\r\n * \r\n * @param {string} baseRPrXml - Base run properties\r\n * @param {Object} format - Format flags (bold, italic, underline, strikethrough)\r\n * @returns {string}\r\n */\r\nfunction injectFormatting(baseRPrXml, format) {\r\n if (!format || Object.keys(format).length === 0) {\r\n return baseRPrXml;\r\n }\r\n\r\n // Extract existing content from rPr\r\n let content = '';\r\n if (baseRPrXml) {\r\n content = baseRPrXml.replace(/<\\/?w:rPr[^>]*>/g, '');\r\n }\r\n\r\n // Add new formatting elements\r\n if (format.bold && !content.includes('<w:b')) {\r\n content = '<w:b/>' + content;\r\n }\r\n if (format.italic && !content.includes('<w:i')) {\r\n content = '<w:i/>' + content;\r\n }\r\n if (format.underline && !content.includes('<w:u')) {\r\n content = '<w:u w:val=\"single\"/>' + content;\r\n }\r\n if (format.strikethrough && !content.includes('<w:strike')) {\r\n content = '<w:strike/>' + content;\r\n }\r\n\r\n return `<w:rPr>${content}</w:rPr>`;\r\n}\r\n\r\n/**\r\n * Wraps OOXML paragraph content for Word's insertOoxml API.\r\n * Must include both the document part AND the relationships part.\r\n * \r\n * @param {string} paragraphXml - The paragraph XML (without namespace declarations)\r\n * @param {import('../core/types.js').DocumentFragmentOptions|boolean} [options={}] - Fragment options\r\n * @returns {string} Complete OOXML package for insertOoxml\r\n */\r\nexport function wrapInDocumentFragment(paragraphXml, options = {}) {\r\n const normalizedOptions = normalizeFragmentOptions(options);\r\n return buildDocumentFragmentPackage(paragraphXml, normalizedOptions);\r\n}\r\n\r\n/**\r\n * Normalizes wrapper options to object form.\r\n *\r\n * @param {import('../core/types.js').DocumentFragmentOptions|boolean|undefined|null} options - Raw options\r\n * @returns {import('../core/types.js').DocumentFragmentOptions}\r\n */\r\nfunction normalizeFragmentOptions(options) {\n if (typeof options === 'boolean') {\r\n return { includeNumbering: options };\r\n }\r\n\r\n if (!options || typeof options !== 'object') {\r\n return {};\r\n }\r\n\r\n return {\r\n includeNumbering: options.includeNumbering ?? false,\r\n numberingXml: options.numberingXml ?? null,\r\n appendTrailingParagraph: options.appendTrailingParagraph ?? true\r\n };\r\n}\n\nfunction stripNamespaceDeclarations(xml) {\n return xml ? xml.replace(XMLNS_ATTR_REGEX, '') : '';\n}\n\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Numbering Service\r\n * \r\n * Manages list numbering to ensure continuation and consistent formatting.\r\n */\r\n\r\nimport { NS_W, NumberFormat, NumberSuffix } from '../core/types.js';\r\n\r\nexport class NumberingService {\r\n constructor() {\r\n this.contextMap = new Map(); // Cache for numIds found in the document\r\n this.nextNumId = 1000;\r\n this.customConfigs = []; // Track custom configs needed for current run\r\n }\r\n\r\n /**\r\n * Preserves an existing numId for a given format signature.\r\n * \r\n * @param {string} signature - Format signature (e.g., 'bullet' or 'decimal')\r\n * @param {string} numId - Existing numId from Word\r\n */\r\n registerExistingNumId(signature, numId) {\r\n this.contextMap.set(signature, numId);\r\n }\r\n\r\n /**\r\n * Resolves the best numId to use for a requested list format.\r\n * \r\n * @param {Object} formatConfig - Requested format (type, depth)\r\n * @param {Object} existingContext - Context from adjacent paragraph\r\n * @returns {string} The numId to use\r\n */\r\n getOrCreateNumId(formatConfig, existingContext = null) {\r\n const requestedType = formatConfig.type || NumberFormat.BULLET;\r\n\r\n // Priority 1: Use existing context if it matches the requested type\r\n if (existingContext && existingContext.numId) {\r\n if (existingContext.type === requestedType || existingContext.type === 'unknown') {\r\n return existingContext.numId;\r\n }\r\n }\r\n\r\n // Priority 2: Use cached numId for this format\r\n if (this.contextMap.has(requestedType)) {\r\n return this.contextMap.get(requestedType);\r\n }\r\n\r\n // Priority 3: Special Handling for Outline (recursive 1.1.1)\r\n if (requestedType === NumberFormat.OUTLINE) {\r\n // Use our new predefined Outline scheme (numId 3)\r\n return '3';\r\n }\r\n\r\n // Priority 4: Fallback based on type\r\n if (requestedType === NumberFormat.DECIMAL) return '2';\r\n if (requestedType === NumberFormat.BULLET) return '1';\r\n\r\n // Priority 5: Handle specialized Alpha/Roman at Level 0 (or if context doesn't match)\r\n // If we are at Level 0 and want something other than Decimal, we need a custom config\r\n const ilvl = existingContext ? parseInt(existingContext.ilvl || '0') : 0;\r\n if (ilvl === 0 && requestedType !== NumberFormat.DECIMAL && requestedType !== NumberFormat.BULLET) {\r\n // Find or create a custom config for this specific format\r\n const signature = `custom_${requestedType}`;\r\n if (this.contextMap.has(signature)) {\r\n return this.contextMap.get(signature);\r\n }\r\n\r\n const newNumId = String(this.nextNumId++);\r\n this.customConfigs.push({\r\n numId: newNumId,\r\n levels: [\r\n { format: requestedType, suffix: formatConfig.suffix || NumberSuffix.PERIOD }\r\n ]\r\n });\r\n this.contextMap.set(signature, newNumId);\r\n return newNumId;\r\n }\r\n\r\n // Default fallback to NumId 2 (Legal/Nested)\r\n return '2';\r\n }\r\n\r\n /**\r\n * Detects numbering format from a string marker (e.g. \"1.\", \"(a)\", \"i.\", \"1.1.\")\r\n * \r\n * @param {string} marker - The marker text\r\n * @returns {Object} { format, suffix, depth }\r\n */\r\n detectNumberingFormat(marker) {\r\n const m = (marker || '').trim();\r\n if (!m) return { format: NumberFormat.BULLET, suffix: NumberSuffix.NONE, depth: 0 };\r\n\r\n // Bullet\r\n if (/^[-*\u2022]$/.test(m)) {\r\n return { format: NumberFormat.BULLET, suffix: NumberSuffix.NONE, depth: 0 };\r\n }\r\n\r\n // Hierarchical outline: 1.1.2 or 4.1.2.3\r\n const outlineMatch = m.match(/^(\\d+(?:\\.\\d+)+)\\.?$/);\r\n if (outlineMatch) {\r\n const depth = outlineMatch[1].split('.').length - 1;\r\n return { format: NumberFormat.OUTLINE, suffix: NumberSuffix.PERIOD, depth };\r\n }\r\n\r\n // Parenthesized formats: (a), (i), (1)\r\n if (/^\\([a-z]\\)$/.test(m)) {\r\n return { format: NumberFormat.LOWER_ALPHA, suffix: NumberSuffix.PAREN_BOTH, depth: 0 };\r\n }\r\n if (/^\\([ivxlc]+\\)$/i.test(m)) {\r\n const isLower = m === m.toLowerCase();\r\n return { format: isLower ? NumberFormat.LOWER_ROMAN : NumberFormat.UPPER_ROMAN, suffix: NumberSuffix.PAREN_BOTH, depth: 0 };\r\n }\r\n if (/^\\(\\d+\\)$/.test(m)) {\r\n return { format: NumberFormat.DECIMAL, suffix: NumberSuffix.PAREN_BOTH, depth: 0 };\r\n }\r\n\r\n // Standard formats with period: 1., a., A., i., I.\r\n if (/^\\d+\\.$/.test(m)) {\r\n return { format: NumberFormat.DECIMAL, suffix: NumberSuffix.PERIOD, depth: 0 };\r\n }\r\n if (/^[a-z]\\.$/.test(m)) {\r\n return { format: NumberFormat.LOWER_ALPHA, suffix: NumberSuffix.PERIOD, depth: 0 };\r\n }\r\n if (/^[A-Z]\\.$/.test(m)) {\r\n return { format: NumberFormat.UPPER_ALPHA, suffix: NumberSuffix.PERIOD, depth: 0 };\r\n }\r\n if (/^[ivxlc]+\\.$/i.test(m)) {\r\n const isLower = m === m.toLowerCase();\r\n return { format: isLower ? NumberFormat.LOWER_ROMAN : NumberFormat.UPPER_ROMAN, suffix: NumberSuffix.PERIOD, depth: 0 };\r\n }\r\n\r\n // Default to decimal if it looks like a number\r\n if (/^\\d+/.test(m)) return { format: NumberFormat.DECIMAL, suffix: NumberSuffix.PERIOD, depth: 0 };\r\n\r\n return { format: NumberFormat.BULLET, suffix: NumberSuffix.NONE, depth: 0 };\r\n }\r\n\r\n /**\r\n * Maps internal format to OOXML numFmt string\r\n */\r\n formatToOoxmlNumFmt(format) {\r\n const map = {\r\n [NumberFormat.DECIMAL]: 'decimal',\r\n [NumberFormat.LOWER_ALPHA]: 'lowerLetter',\r\n [NumberFormat.UPPER_ALPHA]: 'upperLetter',\r\n [NumberFormat.LOWER_ROMAN]: 'lowerRoman',\r\n [NumberFormat.UPPER_ROMAN]: 'upperRoman',\r\n [NumberFormat.BULLET]: 'bullet',\r\n [NumberFormat.OUTLINE]: 'decimal'\r\n };\r\n return map[format] || 'decimal';\r\n }\r\n\r\n /**\r\n * Maps levels and suffix to OOXML lvlText\r\n */\r\n suffixToOoxmlLevelText(format, suffix, ilvl = 0) {\r\n if (format === NumberFormat.BULLET) return '\u2022';\r\n\r\n // Placeholder for current level\r\n const num = `%${ilvl + 1}`;\r\n\r\n if (format === NumberFormat.OUTLINE) {\r\n // Outline %1.%2.%3.\r\n return Array(ilvl + 1).fill(0).map((_, i) => `%${i + 1}`).join('.') + '.';\r\n }\r\n\r\n switch (suffix) {\r\n case NumberSuffix.PERIOD: return `${num}.`;\r\n case NumberSuffix.PAREN_RIGHT: return `${num})`;\r\n case NumberSuffix.PAREN_BOTH: return `(${num})`;\r\n default: return num;\r\n }\r\n }\r\n\r\n /**\r\n * Builds paragraph properties for a list item.\r\n * \r\n * @param {string} numId - The numId\r\n * @param {number} ilvl - Indentation level\r\n * @returns {string} Serialized w:pPr XML\r\n */\r\n buildListPPr(numId, ilvl, options = {}) {\n const includeListParagraphStyle = options.includeListParagraphStyle === true;\n const styleXml = includeListParagraphStyle ? '\\n <w:pStyle w:val=\"ListParagraph\"/>' : '';\n return `\n <w:pPr>${styleXml}\n <w:numPr>\n <w:ilvl w:val=\"${ilvl}\"/>\n <w:numId w:val=\"${numId}\"/>\n </w:numPr>\n </w:pPr>\n `;\n }\n\r\n /**\r\n * Generates a full w:numbering XML block including custom legal schemes.\r\n * \r\n * @param {Array} externalConfigs - Optional array of { numId, levels: [{ format, suffix }] }\r\n * @returns {string} w:numbering XML\r\n */\r\n generateNumberingXml(externalConfigs = []) {\r\n // Merge internal customConfigs with external ones\r\n const allCustomConfigs = [...this.customConfigs, ...externalConfigs];\r\n\r\n // Default Bullet (numId 1)\r\n let abstractNum0 = `\r\n <w:abstractNum w:abstractNumId=\"0\">\r\n <w:multiLevelType w:val=\"hybridMultilevel\"/>\r\n ${[0, 1, 2, 3, 4, 5, 6, 7, 8].map(lvl => `\r\n <w:lvl w:ilvl=\"${lvl}\">\r\n <w:start w:val=\"1\"/>\r\n <w:numFmt w:val=\"${lvl % 3 === 0 ? 'bullet' : lvl % 3 === 1 ? 'circle' : 'square'}\"/>\r\n <w:lvlText w:val=\"${lvl % 3 === 0 ? '\u2022' : lvl % 3 === 1 ? '\u25CB' : '\u25A0'}\"/>\r\n <w:lvlJc w:val=\"left\"/>\r\n <w:pPr><w:ind w:left=\"${720 * (lvl + 1)}\" w:hanging=\"360\"/></w:pPr>\r\n </w:lvl>`).join('')}\r\n </w:abstractNum>`;\r\n\r\n // Default Numbered (numId 2) - US/Legal Style\r\n // Level 0: 1.\r\n // Level 1: (a)\r\n // Level 2: (i)\r\n // Level 3: (1)\r\n // Level 4: (a) - repeating with different indent...\r\n let abstractNum1 = `\r\n <w:abstractNum w:abstractNumId=\"1\">\r\n <w:multiLevelType w:val=\"multilevel\"/>\r\n <w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"lowerLetter\"/><w:lvlText w:val=\"(%2)\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"2\"><w:start w:val=\"1\"/><w:numFmt w:val=\"lowerRoman\"/><w:lvlText w:val=\"(%3)\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"3\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"(%4)\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2880\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"4\"><w:start w:val=\"1\"/><w:numFmt w:val=\"lowerLetter\"/><w:lvlText w:val=\"%5.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3600\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n </w:abstractNum>`;\r\n\r\n // Outline Numbered (numId 3) - 1 / 1.1 / 1.1.1\r\n let abstractNum2 = `\r\n <w:abstractNum w:abstractNumId=\"2\">\r\n <w:multiLevelType w:val=\"multilevel\"/>\r\n <w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"2\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2.%3\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"3\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2.%3.%4\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2880\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n <w:lvl w:ilvl=\"4\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2.%3.%4.%5\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3600\" w:hanging=\"360\"/></w:pPr></w:lvl>\r\n </w:abstractNum>`;\r\n\r\n // Handle custom configurations (e.g. outline 1.1.1)\r\n let customAbstractNums = '';\r\n let customNums = '';\r\n\r\n allCustomConfigs.forEach((config, idx) => {\r\n const absId = 10 + idx;\r\n customAbstractNums += `\r\n <w:abstractNum w:abstractNumId=\"${absId}\">\r\n <w:multiLevelType w:val=\"multilevel\"/>\r\n ${config.levels.map((l, ilvl) => `\r\n <w:lvl w:ilvl=\"${ilvl}\">\r\n <w:start w:val=\"1\"/>\r\n <w:numFmt w:val=\"${this.formatToOoxmlNumFmt(l.format)}\"/>\r\n <w:lvlText w:val=\"${this.suffixToOoxmlLevelText(l.format, l.suffix, ilvl)}\"/>\r\n <w:lvlJc w:val=\"left\"/>\r\n <w:pPr><w:ind w:left=\"${720 * (ilvl + 1)}\" w:hanging=\"360\"/></w:pPr>\r\n </w:lvl>`).join('')}\r\n </w:abstractNum>`;\r\n\r\n customNums += `\r\n <w:num w:numId=\"${config.numId}\">\r\n <w:abstractNumId w:val=\"${absId}\"/>\r\n </w:num>`;\r\n });\r\n\r\n return `\r\n <w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\r\n ${abstractNum0}\r\n ${abstractNum1}\r\n ${abstractNum2}\r\n ${customAbstractNums}\r\n <w:num w:numId=\"1\">\r\n <w:abstractNumId w:val=\"0\"/>\r\n </w:num>\r\n <w:num w:numId=\"2\">\r\n <w:abstractNumId w:val=\"1\"/>\r\n </w:num>\r\n <w:num w:numId=\"3\">\r\n <w:abstractNumId w:val=\"2\"/>\r\n </w:num>\r\n ${customNums}\r\n </w:numbering>`;\r\n }\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Table Reconciliation\r\n * \r\n * Logic for reconciling tables using a Virtual Grid to handle merged cells.\r\n */\r\n\r\nimport { computeWordLevelDiffOps } from '../pipeline/diff-engine.js';\r\nimport { splitRunsAtDiffBoundaries, applyPatches } from '../pipeline/patching.js';\r\nimport { serializeToOoxml } from '../pipeline/serialization.js';\r\nimport { NS_W, getNextRevisionId, getRevisionTimestamp, createRevisionMetadata, escapeXml, RunKind } from '../core/types.js';\r\nimport { preprocessMarkdown } from '../pipeline/markdown-processor.js';\r\n\r\n/**\r\n * Generates a new w:tbl OOXML structure from Markdown table data.\r\n * This enables pure OOXML table creation without Word JS API.\r\n * \r\n * @param {Object} tableData - Parsed Markdown table { headers, rows, hasHeader }\r\n * @param {Object} options - { generateRedlines, author }\r\n * @returns {string} Complete w:tbl OOXML\r\n */\r\nexport function generateTableOoxml(tableData, options = {}) {\r\n const { generateRedlines = false, author = 'AI' } = options;\r\n const date = getRevisionTimestamp();\r\n const revId = generateRedlines ? getNextRevisionId() : null;\r\n\r\n // Determine number of columns\r\n const numCols = tableData.headers?.length || (tableData.rows?.[0]?.length || 1);\r\n\r\n // Build default table properties (100% width, single borders)\r\n const tblPr = `\r\n <w:tblPr>\r\n <w:tblW w:w=\"5000\" w:type=\"pct\"/>\r\n <w:tblBorders>\r\n <w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>\r\n <w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>\r\n <w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>\r\n <w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>\r\n <w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>\r\n <w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>\r\n </w:tblBorders>\r\n <w:tblLook w:val=\"04A0\" w:firstRow=\"1\" w:lastRow=\"0\" w:firstColumn=\"1\" w:lastColumn=\"0\" w:noHBand=\"0\" w:noVBand=\"1\"/>\r\n </w:tblPr>\r\n `.trim();\r\n\r\n // Build grid columns (equal width)\r\n const gridCols = Array(numCols).fill('<w:gridCol/>').join('');\r\n const tblGrid = `<w:tblGrid>${gridCols}</w:tblGrid>`;\r\n\r\n // Build all rows\r\n const allRows = tableData.hasHeader ? [tableData.headers, ...tableData.rows] : tableData.rows;\r\n let rowsXml = '';\r\n\r\n for (let r = 0; r < allRows.length; r++) {\r\n const isHeaderRow = tableData.hasHeader && r === 0;\r\n const row = allRows[r] || [];\r\n let cellsXml = '';\r\n\r\n for (let c = 0; c < numCols; c++) {\r\n const cellText = row[c] || '';\r\n const { cleanText, formatHints } = preprocessMarkdown(cellText);\r\n\r\n // Build run model for the cell\r\n const runModel = [{\r\n kind: generateRedlines ? RunKind.INSERTION : RunKind.TEXT,\r\n text: cleanText,\r\n rPrXml: isHeaderRow ? '<w:rPr><w:b/></w:rPr>' : '',\r\n author,\r\n startOffset: 0,\r\n endOffset: cleanText.length\r\n }];\r\n\r\n const runsOoxml = serializeToOoxml(runModel, null, formatHints, { author, generateRedlines });\r\n\r\n // Cell properties\r\n const tcPr = '<w:tcPr><w:tcW w:w=\"0\" w:type=\"auto\"/></w:tcPr>';\r\n // serializeToOoxml already returns one or more w:p blocks.\r\n cellsXml += `<w:tc>${tcPr}${runsOoxml}</w:tc>`;\r\n }\r\n\r\n // Row properties\r\n const trPr = '<w:trPr/>';\r\n rowsXml += `<w:tr>${trPr}${cellsXml}</w:tr>`;\r\n }\r\n\r\n // Build the table\r\n let tableXml = `<w:tbl>${tblPr}${tblGrid}${rowsXml}</w:tbl>`;\r\n\r\n // Wrap entire table in w:ins if generating redlines\r\n if (generateRedlines && revId) {\r\n tableXml = `<w:ins w:id=\"${revId}\" w:author=\"${escapeXml(author)}\" w:date=\"${date}\">${tableXml}</w:ins>`;\r\n }\r\n\r\n return tableXml;\r\n}\r\n\r\n/**\r\n * Computes operations to reconcile two tables.\r\n * \r\n * @param {Object} oldGrid - Original Virtual Grid model\r\n * @param {Object} newTableData - Parsed markdown table data\r\n * @returns {Array} List of operations\r\n */\r\n\r\nexport function diffTablesWithVirtualGrid(oldGrid, newTableData) {\r\n const operations = [];\r\n const { headers, rows: newRowsData, hasHeader } = newTableData;\r\n const allNewRows = hasHeader ? [headers, ...newRowsData] : newRowsData;\r\n\r\n const maxRows = Math.max(oldGrid.rowCount, allNewRows.length);\r\n\r\n for (let row = 0; row < maxRows; row++) {\r\n // Row insertion\r\n if (row >= oldGrid.rowCount && allNewRows[row]) {\r\n operations.push({\r\n type: 'row_insert',\r\n gridRow: row,\r\n cells: allNewRows[row]\r\n });\r\n continue;\r\n }\r\n\r\n // Row deletion\r\n if (row < oldGrid.rowCount && !allNewRows[row]) {\r\n operations.push({\r\n type: 'row_delete',\r\n gridRow: row\r\n });\r\n continue;\r\n }\r\n\r\n const newRow = allNewRows[row];\r\n\r\n for (let col = 0; col < oldGrid.colCount; col++) {\r\n const oldCell = oldGrid.grid[row]?.[col];\r\n const newCellText = newRow?.[col];\r\n\r\n if (!oldCell) continue;\r\n if (oldCell.isMergeContinuation) continue;\r\n if (col > oldCell.gridCol) continue;\r\n\r\n if (newCellText !== undefined) {\r\n const oldText = oldCell.getText();\r\n if (oldText !== newCellText) {\r\n operations.push({\r\n type: 'cell_modify',\r\n gridRow: row,\r\n gridCol: col,\r\n originalCell: oldCell,\r\n newText: newCellText\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n return operations;\r\n}\r\n\r\n/**\r\n * Serializes the virtual grid back to OOXML after applying operations.\r\n * \r\n * @param {Object} grid - The Virtual Grid\r\n * @param {Array} operations - Diff operations\r\n * @param {Object} options - Options (generateRedlines, author)\r\n * @returns {string} Reconciled w:tbl OOXML\r\n */\r\nexport function serializeVirtualGridToOoxml(grid, operations, options) {\r\n const { generateRedlines, author } = options;\r\n const opIndex = buildTableOperationIndex(operations);\r\n\r\n let rowsXml = '';\r\n\r\n for (let row = 0; row < grid.rowCount; row++) {\r\n const rowDeleteOp = opIndex.rowDeleteByRow.get(row) || null;\r\n\r\n if (rowDeleteOp && !generateRedlines) continue;\r\n\r\n let cellsXml = '';\r\n let col = 0;\r\n\r\n while (col < grid.colCount) {\r\n const cell = grid.grid[row][col];\r\n\r\n if (!cell) {\r\n col++;\r\n continue;\r\n }\r\n\r\n if (cell.isMergeContinuation) {\r\n col++;\r\n continue;\r\n }\r\n\r\n const modOp = opIndex.cellModifyByCoordinate.get(`${row}:${col}`) || null;\r\n\r\n let cellContent;\r\n if (modOp) {\r\n cellContent = reconcileCellContent(cell, modOp.newText, options);\r\n } else {\r\n cellContent = serializeCellBlocks(cell.blocks);\r\n }\r\n\r\n cellsXml += buildTcXml(cell, cellContent, options);\r\n col += cell.colSpan;\r\n }\r\n\r\n let trPr = grid.trPrList[row] || '<w:trPr/>';\r\n\r\n if (rowDeleteOp && generateRedlines) {\r\n const metadata = createRevisionMetadata(author);\r\n const delMark = `<w:del w:id=\"${metadata.id}\" w:author=\"${escapeXml(metadata.author)}\" w:date=\"${metadata.date}\"/>`;\r\n if (trPr.includes('</w:trPr>')) {\r\n trPr = trPr.replace('</w:trPr>', `${delMark}</w:trPr>`);\r\n } else {\r\n trPr = `<w:trPr>${delMark}</w:trPr>`;\r\n }\r\n }\r\n\r\n rowsXml += `<w:tr>${trPr}${cellsXml}</w:tr>`;\r\n }\r\n\r\n // Handle row insertions\r\n const insertOps = opIndex.rowInsertOperations;\r\n for (const op of insertOps) {\r\n let cellsXml = '';\r\n const rowInsertMeta = generateRedlines ? createRevisionMetadata(author) : null;\r\n\r\n for (const cellText of op.cells) {\r\n const { cleanText, formatHints } = preprocessMarkdown(cellText);\r\n // Simple run model for new cell\r\n const runModel = [{\r\n kind: generateRedlines ? RunKind.INSERTION : RunKind.TEXT,\r\n text: cleanText,\r\n rPrXml: '',\r\n author,\r\n startOffset: 0,\r\n endOffset: cleanText.length\r\n }];\r\n\r\n const runsOoxml = serializeToOoxml(runModel, null, formatHints, { author, generateRedlines });\r\n // serializeToOoxml already returns one or more w:p blocks.\r\n cellsXml += `<w:tc><w:tcPr><w:tcW w:w=\"0\" w:type=\"auto\"/></w:tcPr>${runsOoxml}</w:tc>`;\r\n }\r\n\r\n let trPr = '<w:trPr/>';\r\n if (generateRedlines) {\r\n trPr = `<w:trPr><w:ins w:id=\"${rowInsertMeta.id}\" w:author=\"${escapeXml(rowInsertMeta.author)}\" w:date=\"${rowInsertMeta.date}\"/></w:trPr>`;\r\n }\r\n\r\n rowsXml += `<w:tr>${trPr}${cellsXml}</w:tr>`;\r\n }\r\n\r\n return `\r\n <w:tbl>\r\n ${grid.tblPrXml}\r\n ${grid.tblGridXml}\r\n ${rowsXml}\r\n </w:tbl>\r\n `;\r\n}\r\n\r\n/**\r\n * Builds indexed table operation lookups for row/cell hot paths.\r\n *\r\n * @param {Array} operations - Table diff operations\r\n * @returns {{\r\n * rowDeleteByRow: Map<number, Object>,\r\n * cellModifyByCoordinate: Map<string, Object>,\r\n * rowInsertOperations: Object[]\r\n * }}\r\n */\r\nfunction buildTableOperationIndex(operations) {\r\n const rowDeleteByRow = new Map();\r\n const cellModifyByCoordinate = new Map();\r\n const rowInsertOperations = [];\r\n\r\n for (const operation of operations) {\r\n if (operation.type === 'row_delete') {\r\n rowDeleteByRow.set(operation.gridRow, operation);\r\n } else if (operation.type === 'cell_modify') {\r\n cellModifyByCoordinate.set(`${operation.gridRow}:${operation.gridCol}`, operation);\r\n } else if (operation.type === 'row_insert') {\r\n rowInsertOperations.push(operation);\r\n }\r\n }\r\n\r\n rowInsertOperations.sort((a, b) => a.gridRow - b.gridRow);\r\n\r\n return {\r\n rowDeleteByRow,\r\n cellModifyByCoordinate,\r\n rowInsertOperations\r\n };\r\n}\r\n\r\nfunction reconcileCellContent(cell, newText, options) {\r\n const { generateRedlines, author } = options;\r\n const { cleanText, formatHints } = preprocessMarkdown(newText);\r\n\r\n // For now, satisfy with single block or join blocks\r\n // In a full implementation, we'd diff paragraphs within the cell\r\n const oldText = cell.getText();\r\n const diffOps = computeWordLevelDiffOps(oldText, cleanText);\r\n\r\n // Use the first block as reference for formatting if available\r\n const baseBlock = cell.blocks[0] || { runModel: [], pPr: null };\r\n const splitModel = splitRunsAtDiffBoundaries(baseBlock.runModel, diffOps);\r\n const patchedModel = applyPatches(splitModel, diffOps, {\r\n generateRedlines,\r\n author,\r\n formatHints\r\n });\r\n\r\n const runsOoxml = serializeToOoxml(patchedModel, baseBlock.pPr, formatHints, { author, generateRedlines });\r\n return runsOoxml;\r\n}\r\n\r\nfunction serializeCellBlocks(blocks) {\r\n return blocks.map(b => {\r\n const runsOoxml = serializeToOoxml(b.runModel, b.pPr, [], {});\r\n // serializeToOoxml already returns one or more w:p blocks.\r\n return runsOoxml;\r\n }).join('');\r\n}\r\n\r\nfunction buildTcXml(cell, content, options) {\r\n let tcPr = cell.tcPrXml;\r\n\r\n // Ensure gridSpan is preserved\r\n if (cell.colSpan > 1 && !tcPr.includes('gridSpan')) {\r\n tcPr = tcPr.replace('</w:tcPr>', `<w:gridSpan w:val=\"${cell.colSpan}\"/></w:tcPr>`);\r\n } else if (cell.colSpan > 1 && tcPr === '<w:tcPr/>') {\r\n tcPr = `<w:tcPr><w:gridSpan w:val=\"${cell.colSpan}\"/></w:tcPr>`;\r\n }\r\n\r\n // Ensure vMerge is preserved for origin cells\r\n if (cell.rowSpan > 1 && cell.isMergeOrigin && !tcPr.includes('vMerge')) {\r\n tcPr = tcPr.replace('</w:tcPr>', '<w:vMerge w:val=\"restart\"/></w:tcPr>');\r\n } else if (cell.rowSpan > 1 && cell.isMergeOrigin && tcPr === '<w:tcPr/>') {\r\n tcPr = '<w:tcPr><w:vMerge w:val=\"restart\"/></w:tcPr>';\r\n }\r\n\r\n return `<w:tc>${tcPr}${content}</w:tc>`;\r\n}\r\n", "/**\r\n * Content analysis helpers for paragraph/list/table classification.\r\n */\r\n\r\nimport { ContentType } from '../core/types.js';\r\nimport { matchListMarker, stripListMarker } from './list-markers.js';\r\n\r\n/**\r\n * Parses table from markdown-style table text.\r\n *\r\n * @param {string} text - Table text\r\n * @returns {{ headers: string[], rows: string[][], hasHeader: boolean }}\r\n */\r\nexport function parseTable(text) {\n const lines = text\n .split('\\n')\n .map(line => line.trim())\n .filter(line => line.startsWith('|'));\n if (lines.length === 0) {\n return { headers: [], rows: [], hasHeader: false };\n }\n\n const isSeparatorLine = line => {\n const normalized = line.replace(/\\s+/g, '');\n return /^\\|:?-{3,}:?(\\|:?-{3,}:?)+\\|?$/.test(normalized);\n };\n\n const hasHeader = lines.some(isSeparatorLine);\n const dataLines = lines.filter(line => !isSeparatorLine(line));\n const parsedRows = dataLines.map(line =>\n line\n .split('|')\n .slice(1, -1)\n .map(cell => cell.trim())\n );\n\n if (!hasHeader) {\n return {\n headers: [],\n rows: parsedRows,\n hasHeader: false\n };\n }\n\n return {\n headers: parsedRows[0] || [],\n rows: parsedRows.slice(1),\n hasHeader: true\n };\n}\n\r\n/**\r\n * Parses list items from markdown-style list text.\r\n *\r\n * @param {string} text - List text\r\n * @returns {Array<{ line: string, text: string, marker: string, indent: number, level: number, listType: 'bullet'|'numbered' }>}\r\n */\r\nexport function parseListItems(text) {\r\n const lines = text.split('\\n').filter(line => line.trim().length > 0);\r\n const items = [];\r\n\r\n lines.forEach(line => {\r\n const markerMatch = matchListMarker(line, { allowZeroSpaceAfterMarker: true });\r\n if (!markerMatch) return;\r\n\r\n const marker = markerMatch[2].trim();\r\n const indent = (line.match(/^(\\s*)/)?.[1].length) || 0;\r\n const listType = /^[-*+\u2022]/.test(marker) ? 'bullet' : 'numbered';\r\n const outlineDepth = (marker.match(/\\./g) || []).length;\r\n const level = outlineDepth > 1 ? Math.min(8, outlineDepth - 1) : Math.min(8, Math.floor(indent / 2));\r\n\r\n items.push({\r\n line,\r\n text: stripListMarker(line, { allowZeroSpaceAfterMarker: true }),\r\n marker,\r\n indent,\r\n level,\r\n listType\r\n });\r\n });\r\n\r\n return items;\r\n}\r\n\r\n/**\r\n * Detects content type from text.\r\n *\r\n * @param {string} text - Text to classify\r\n * @returns {ContentType}\r\n */\r\nexport function detectContentType(text) {\r\n const normalized = (text || '').trim();\r\n if (!normalized) return ContentType.PARAGRAPH;\r\n\r\n const table = parseTable(normalized);\r\n if (table.headers.length > 0 || table.rows.length > 0) {\r\n return ContentType.TABLE;\r\n }\r\n\r\n const listItems = parseListItems(normalized);\r\n if (listItems.length > 0) {\r\n const hasBullet = listItems.some(item => item.listType === 'bullet');\r\n return hasBullet ? ContentType.BULLET_LIST : ContentType.NUMBERED_LIST;\r\n }\r\n\r\n return ContentType.PARAGRAPH;\r\n}\r\n", "/**\r\n * List generation flow extracted from ReconciliationPipeline.\r\n */\r\n\r\nimport { preprocessMarkdown } from './markdown-processor.js';\r\nimport { matchListMarker, stripListMarker } from './list-markers.js';\nimport { serializeToOoxml } from './serialization.js';\r\nimport { generateTableOoxml } from '../services/table-reconciliation.js';\r\nimport { parseTable } from './content-analysis.js';\r\nimport { log } from '../adapters/logger.js';\r\n\r\n/**\r\n * Executes list generation when paragraph content expands into list/table blocks.\r\n *\r\n * @param {Object} options - Generation options\r\n * @param {string} options.cleanText - Preprocessed target text\r\n * @param {Object|null} options.numberingContext - Existing numbering context\r\n * @param {Array} [options.originalRunModel=[]] - Original run model\r\n * @param {string} [options.originalText=''] - Original text fallback\r\n * @param {boolean} [options.generateRedlines=true] - Track-change toggle\r\n * @param {string} [options.author='AI'] - Author metadata\r\n * @param {string|null} [options.font=null] - Optional font\r\n * @param {import('../services/numbering-service.js').NumberingService} options.numberingService - Numbering service\r\n * @returns {Promise<import('../core/types.js').ReconciliationResult>}\r\n */\r\nexport async function executeListGeneration(options) {\n const {\r\n cleanText,\r\n numberingContext,\r\n originalRunModel = [],\r\n originalText = '',\r\n generateRedlines = true,\r\n author = 'AI',\r\n font = null,\r\n numberingService\r\n } = options;\r\n\r\n const normalizedListText = normalizeCompositeListMarkers(cleanText);\n const lineMetadata = buildLineMetadata(normalizedListText);\n const rawLines = lineMetadata.map(line => line.raw);\n const results = [];\r\n\r\n let deletionRuns = [];\r\n if (generateRedlines) {\r\n if (originalRunModel && originalRunModel.length > 0) {\r\n deletionRuns = originalRunModel\r\n .filter(run => run.kind === 'text' || run.kind === 'run')\r\n .map(run => ({ ...run, kind: 'deletion', author }));\r\n } else if (originalText && originalText.trim().length > 0) {\r\n const trimmed = originalText.trim();\r\n deletionRuns = [{\r\n kind: 'deletion',\r\n text: trimmed,\r\n author,\r\n startOffset: 0,\r\n endOffset: trimmed.length\r\n }];\r\n }\r\n }\r\n\r\n const indentStep = detectIndentationStep(rawLines);\r\n log(`[ListGen] Detected indentation step: ${indentStep} spaces/chars`);\r\n\r\n const firstMarker = lineMetadata.find(line => line.marker)?.marker || '';\n const { format: defaultFormat } = numberingService.detectNumberingFormat(firstMarker);\r\n log(`[ListGen] Detected primary marker: \"${firstMarker}\", format: ${defaultFormat}`);\r\n\r\n for (let i = 0; i < lineMetadata.length; i++) {\r\n const tableBlock = collectMarkdownTableBlock(lineMetadata, i);\r\n if (tableBlock) {\r\n const tableData = parseTable(tableBlock.tableText);\r\n if (tableData.headers.length > 0 || tableData.rows.length > 0) {\r\n if (generateRedlines && results.length === 0 && deletionRuns.length > 0) {\r\n results.push(serializeToOoxml(deletionRuns, null, [], {\r\n author,\r\n generateRedlines,\r\n font\r\n }));\r\n }\r\n\r\n results.push(generateTableOoxml(tableData, { generateRedlines, author }));\r\n i = tableBlock.endIndex;\r\n continue;\r\n }\r\n }\r\n\r\n const line = lineMetadata[i];\r\n const entry = buildListEntry(\r\n line,\r\n i,\r\n indentStep,\r\n numberingContext,\r\n numberingService,\r\n generateRedlines,\r\n author,\r\n font,\r\n deletionRuns\r\n );\r\n results.push(entry.ooxml);\r\n }\r\n\r\n const numberingXml = numberingService.generateNumberingXml();\r\n const finalOoxml = results.join('');\r\n const blankParagraph = '<w:p><w:pPr></w:pPr></w:p>';\r\n const oxmlWithSpacing = finalOoxml + blankParagraph;\r\n\r\n log(`[ListGen] \u2705 Generated OOXML for ${results.length} list items, total length: ${oxmlWithSpacing.length}`);\r\n log(`[ListGen] First 200 chars: ${oxmlWithSpacing.substring(0, 200)}...`);\r\n\r\n return {\r\n ooxml: oxmlWithSpacing,\r\n isValid: true,\r\n warnings: ['Paragraph expanded to list fragment'],\r\n type: 'fragment',\r\n includeNumbering: true,\r\n numberingXml\r\n };\r\n}\n\r\n/**\r\n * Heuristically detects indentation step (spaces/tabs per level).\r\n *\r\n * @param {string[]} lines - Raw lines\r\n * @returns {number}\r\n */\r\nexport function detectIndentationStep(lines) {\r\n const indentations = lines\r\n .map(line => line.match(/^(\\s*)/)[0].length)\r\n .filter(length => length > 0)\r\n .sort((a, b) => a - b);\r\n\r\n if (indentations.length === 0) return 2;\r\n\r\n let minJump = indentations[0];\r\n for (let i = 1; i < indentations.length; i++) {\r\n const jump = indentations[i] - indentations[i - 1];\r\n if (jump > 0 && jump < minJump) {\r\n minJump = jump;\r\n }\r\n }\r\n\r\n return minJump || 2;\r\n}\r\n\r\nfunction buildLineMetadata(cleanText) {\n return cleanText\r\n .split('\\n')\r\n .filter(line => line.trim().length > 0)\r\n .map(raw => {\r\n const markerMatch = matchListMarker(raw);\r\n const headerMatch = raw.match(/^\\s*(#{1,9})\\s+(.*)/);\r\n return {\r\n raw,\r\n marker: markerMatch ? markerMatch[2].trim() : '',\r\n headerMatch,\r\n indentSize: (raw.match(/^(\\s*)/)?.[1].length) || 0,\r\n isTableLine: /^\\s*\\|/.test(raw),\r\n isTableSeparator: /^\\s*\\|?[\\s:-]*-[-\\s|:]*\\|?\\s*$/.test(raw)\r\n };\r\n });\n}\n\nfunction normalizeCompositeListMarkers(text) {\n const lines = String(text || '').split('\\n');\n const nonEmptyIndexes = lines\n .map((line, index) => ({ line, index }))\n .filter(entry => entry.line.trim().length > 0);\n if (nonEmptyIndexes.length < 2) return text;\n\n const rewrites = [];\n let rewrittenCount = 0;\n\n for (const { line, index } of nonEmptyIndexes) {\n const outerMarkerMatch = matchListMarker(line);\n if (!outerMarkerMatch) return text;\n\n const stripped = stripListMarker(line);\n const innerMarkerMatch = matchListMarker(stripped);\n if (!innerMarkerMatch) return text;\n\n const outerMarker = (outerMarkerMatch[2] || '').trim();\n const innerMarker = (innerMarkerMatch[2] || '').trim();\n if (!outerMarker || !innerMarker || outerMarker === innerMarker) return text;\n\n const indent = outerMarkerMatch[1] || '';\n const rewritten = `${indent}${stripped.trimStart()}`;\n rewrites.push({ index, rewritten });\n rewrittenCount++;\n }\n\n if (rewrittenCount < 2) return text;\n\n const updated = lines.slice();\n for (const rewrite of rewrites) {\n updated[rewrite.index] = rewrite.rewritten;\n }\n log(`[ListGen] Normalized ${rewrittenCount} composite list markers (e.g., \"- A.\" -> \"A.\").`);\n return updated.join('\\n');\n}\n\r\nfunction collectMarkdownTableBlock(lineMetadata, index) {\r\n const current = lineMetadata[index];\r\n const next = lineMetadata[index + 1];\r\n\r\n if (!current?.isTableLine || !next?.isTableLine || !next?.isTableSeparator) {\r\n return null;\r\n }\r\n\r\n const tableLines = [];\r\n let cursor = index;\r\n while (cursor < lineMetadata.length && lineMetadata[cursor].isTableLine) {\r\n tableLines.push(lineMetadata[cursor].raw);\r\n cursor++;\r\n }\r\n\r\n return {\r\n tableText: tableLines.join('\\n'),\r\n endIndex: cursor - 1\r\n };\r\n}\r\n\r\nfunction buildListEntry(\r\n line,\r\n lineIndex,\r\n indentStep,\r\n numberingContext,\r\n numberingService,\r\n generateRedlines,\r\n author,\r\n font,\r\n deletionRuns\r\n) {\r\n let pPrXml = '';\r\n let segmentText = '';\r\n\r\n if (line.headerMatch) {\r\n const level = Math.min(line.headerMatch[1].length, 9);\r\n const outlineLevel = Math.min(level - 1, 8);\r\n const headingSizes = [32, 28, 26, 24, 22, 20, 20, 20, 20];\r\n const headingSize = headingSizes[level - 1] || headingSizes[headingSizes.length - 1];\r\n segmentText = line.headerMatch[2].trim();\r\n pPrXml = `<w:pPr><w:pStyle w:val=\"Heading${level}\"/><w:outlineLvl w:val=\"${outlineLevel}\"/><w:rPr><w:b/><w:sz w:val=\"${headingSize}\"/><w:szCs w:val=\"${headingSize}\"/></w:rPr></w:pPr>`;\r\n } else if (line.marker) {\r\n const lineFormat = numberingService.detectNumberingFormat(line.marker);\r\n const indentLevel = indentStep > 0 ? Math.floor(line.indentSize / indentStep) : 0;\r\n const contextLevel = numberingContext?.ilvl || 0;\r\n const ilvl = lineFormat.format === 'outline'\r\n ? Math.min(8, lineFormat.depth)\r\n : Math.min(8, indentLevel + contextLevel);\r\n\r\n segmentText = stripListMarker(line.raw);\r\n const numId = numberingService.getOrCreateNumId({ type: lineFormat.format }, numberingContext);\r\n pPrXml = numberingService.buildListPPr(numId, ilvl);\r\n } else {\r\n segmentText = line.raw;\r\n }\r\n\r\n const { cleanText, formatHints } = preprocessMarkdown(segmentText);\r\n const runModel = [];\r\n\r\n if (lineIndex === 0 && deletionRuns.length > 0) {\r\n runModel.push(...deletionRuns);\r\n }\r\n\r\n runModel.push({\r\n kind: generateRedlines ? 'insertion' : 'run',\r\n text: cleanText,\r\n author,\r\n startOffset: 0,\r\n endOffset: cleanText.length\r\n });\r\n\r\n return {\r\n ooxml: serializeToOoxml(runModel, pPrXml, formatHints, {\r\n author,\r\n generateRedlines,\r\n font\r\n })\r\n };\r\n}\r\n", "/**\r\n * OOXML Reconciliation Pipeline - Main Pipeline\r\n * \r\n * Orchestrates the reconciliation process from OOXML input to output.\r\n */\r\n\r\nimport { ingestOoxml } from './ingestion.js';\r\nimport { preprocessMarkdown } from './markdown-processor.js';\r\nimport { isListTargetLoose, isListTargetStrict } from './list-markers.js';\nimport { computeWordLevelDiffOps } from './diff-engine.js';\r\nimport { splitRunsAtDiffBoundaries, applyPatches } from './patching.js';\r\nimport { serializeToOoxml, wrapInDocumentFragment } from './serialization.js';\r\nimport { RunKind } from '../core/types.js';\r\nimport { NumberingService } from '../services/numbering-service.js';\r\nimport { detectNumberingContext } from './ingestion.js';\r\nimport { generateTableOoxml } from '../services/table-reconciliation.js';\r\nimport { executeListGeneration, detectIndentationStep } from './list-generation.js';\r\nimport { detectContentType, parseListItems, parseTable } from './content-analysis.js';\nimport { createParser } from '../adapters/xml-adapter.js';\nimport { log, error as logError } from '../adapters/logger.js';\nimport { getFirstElementByTagNS, getXmlParseError } from '../core/xml-query.js';\nimport { getPlatform } from '../adapters/config.js';\n\nconst WEB_PLATFORM_NAMES = new Set(['officeonline', 'officeweb', 'web']);\n\nfunction isWebPlatform(platform) {\n if (!platform) return false;\n return WEB_PLATFORM_NAMES.has(String(platform).toLowerCase());\n}\n\nfunction isProductionBuild() {\n return typeof process !== 'undefined' && process?.env?.NODE_ENV === 'production';\n}\n\nfunction yieldToEventLoop() {\n return new Promise(resolve => setTimeout(resolve, 0));\n}\n\r\n/**\r\n * Main reconciliation pipeline class.\r\n * Orchestrates the process of diffing and patching OOXML content.\r\n */\r\nexport class ReconciliationPipeline {\r\n /**\r\n * @param {Object} options - Pipeline options\r\n * @param {boolean} [options.generateRedlines=true] - Generate track changes\r\n * @param {string} [options.author='AI'] - Author for track changes\r\n * @param {boolean} [options.validateOutput=true] - Validate output before returning\r\n */\r\n constructor(options = {}) {\n this.generateRedlines = options.generateRedlines ?? true;\n this.author = options.author ?? 'AI';\n this.validateOutput = options.validateOutput ?? true;\n this.validationMode = options.validationMode ?? 'auto';\n this.numberingService = options.numberingService || new NumberingService();\n this.font = options.font || null;\n this.platform = options.platform ?? getPlatform();\n this.isWebPlatform = options.isWebPlatform ?? isWebPlatform(this.platform);\n this.enableEventLoopYielding = options.enableEventLoopYielding ?? this.isWebPlatform;\n this.yieldRunThreshold = options.yieldRunThreshold ?? 50;\n this.yieldCharThreshold = options.yieldCharThreshold ?? 5000;\n this.disableSemanticCleanupOverChars = options.disableSemanticCleanupOverChars ?? (this.isWebPlatform ? 8000 : Number.POSITIVE_INFINITY);\n }\n\r\n /**\r\n * Executes the reconciliation pipeline.\n * \n * @param {string} originalOoxml - Original OOXML paragraph content\n * @param {string} newText - New text with optional markdown formatting\n * @param {{ xmlDoc?: Document|null }} [options={}] - Optional execution options\n * @returns {Promise<import('../core/types.js').ReconciliationResult>}\n */\n async execute(originalOoxml, newText, options = {}) {\n const warnings = [];\n\n try {\n // Stage 1: Ingest OOXML\n const doc = options.xmlDoc || (() => {\n const parser = createParser();\n return parser.parseFromString(originalOoxml, 'application/xml');\n })();\n const pElement = getFirstElementByTagNS(doc, '*', 'p');\n\n const { runModel, acceptedText, pPr } = ingestOoxml(originalOoxml, { xmlDoc: doc });\n const numberingContext = pElement ? detectNumberingContext(pElement) : null;\n\n log(`[Reconcile] Ingested ${runModel.length} runs, ${acceptedText.length} chars, numbering:`, numberingContext);\n await this.maybeYield(runModel.length, Math.max(acceptedText.length, newText?.length || 0));\n\n // Stage 2: Preprocess markdown\n const { cleanText, formatHints } = preprocessMarkdown(newText);\n log(`[Reconcile] Preprocessed: ${formatHints.length} format hints`);\n await this.maybeYield(runModel.length, Math.max(acceptedText.length, cleanText.length));\n\n // Detect list-target content before any no-op short-circuit.\n // Structural conversion may still be required even when text is identical\n // (for example plain \"A./B./C.\" lines -> true Word numbered list paragraphs).\n const isTargetListStrict = isListTargetStrict(cleanText);\n const isTargetListLoose = isListTargetLoose(cleanText);\n const isTargetList = isTargetListStrict || isTargetListLoose;\n if (!isTargetListStrict && isTargetListLoose) {\n log('[Reconcile] List-target detected via loose marker parsing; bypassing no-op short-circuit for structural conversion.');\n }\n\n // Early exit if no change\n if (acceptedText === cleanText && formatHints.length === 0 && !isTargetList) {\n log('[Reconcile] No changes detected');\n return {\n ooxml: originalOoxml,\n isValid: true,\n warnings: ['No changes detected']\n };\r\n }\n\n // Stage 3: Compute word-level diff\n const shouldCleanupSemantic = Math.max(acceptedText.length, cleanText.length) < this.disableSemanticCleanupOverChars;\n const diffOps = computeWordLevelDiffOps(acceptedText, cleanText, {\n cleanupSemantic: shouldCleanupSemantic\n });\n if (!shouldCleanupSemantic) {\n log('[Reconcile] Skipping semantic diff cleanup for large web payload');\n }\n await this.maybeYield(runModel.length, Math.max(acceptedText.length, cleanText.length));\n\r\n // Count actual paragraph elements ingested\r\n const paragraphCount = runModel.filter(r => r.kind === RunKind.PARAGRAPH_START).length;\r\n\r\n log(`[Reconcile] isTargetList: ${isTargetList}, paragraphCount: ${paragraphCount}`);\n\r\n // If target is a list, always use list generation logic\r\n // This handles both expansion (1 para -> N items) and conversion (N paras -> M items)\r\n if (isTargetList) {\r\n log('[Reconcile] \uD83C\uDFAF ENTERING LIST GENERATION PATH');\r\n log(`[Reconcile] cleanText preview: ${cleanText.substring(0, 100)}...`);\r\n log(`[Reconcile] acceptedText preview: ${acceptedText.substring(0, 100)}...`);\r\n return this.executeListGeneration(cleanText, numberingContext, runModel);\r\n }\r\n\r\n log(`[Reconcile] Computed ${diffOps.length} diff operations`);\r\n\r\n // Stage 4: Pre-split runs at boundaries\r\n const splitModel = splitRunsAtDiffBoundaries(runModel, diffOps);\r\n log(`[Reconcile] Split into ${splitModel.length} runs`);\r\n\r\n // Stage 5: Apply patches\r\n const patchedModel = applyPatches(splitModel, diffOps, {\n generateRedlines: this.generateRedlines,\n author: this.author,\n formatHints,\n numberingService: this.numberingService\n });\n log(`[Reconcile] Patched model has ${patchedModel.length} runs`);\n await this.maybeYield(patchedModel.length, Math.max(acceptedText.length, cleanText.length));\n\r\n // Stage 6: Serialize to OOXML\r\n const resultOoxml = serializeToOoxml(patchedModel, pPr, formatHints, {\r\n author: this.author,\r\n generateRedlines: this.generateRedlines\r\n });\r\n\r\n // Stage 7: Basic validation\n if (this.shouldRunValidation()) {\n const validation = this.validateBasic(resultOoxml);\n if (!validation.isValid) {\n warnings.push(...validation.errors);\n }\n }\n\r\n return {\r\n ooxml: resultOoxml,\r\n isValid: warnings.length === 0,\r\n warnings\r\n };\r\n\r\n } catch (error) {\r\n logError('[Reconcile] Pipeline error:', error);\r\n return {\r\n ooxml: originalOoxml,\r\n isValid: false,\r\n warnings: [`Pipeline error: ${error.message}`]\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Performs basic validation on generated OOXML.\r\n * \r\n * @param {string} ooxml - Generated OOXML\r\n * @returns {{ isValid: boolean, errors: string[] }}\r\n */\r\n validateBasic(ooxml) {\n const errors = [];\r\n\r\n try {\r\n // Check for well-formed XML by wrapping in namespace container\r\n const wrappedXml = `<root xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">${ooxml}</root>`;\r\n const parser = createParser();\r\n const doc = parser.parseFromString(wrappedXml, 'application/xml');\r\n\r\n const parseError = getXmlParseError(doc);\r\n if (parseError) {\r\n errors.push('Generated OOXML is not well-formed XML: ' + parseError.textContent.substring(0, 100));\r\n }\r\n\r\n // Check for basic structure\r\n if (!ooxml.includes('<w:p')) {\r\n errors.push('Generated OOXML missing paragraph element');\r\n }\r\n\r\n } catch (e) {\r\n errors.push(`Validation error: ${e.message}`);\r\n }\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n }\n\n /**\n * Decides if basic output validation should run for this pipeline instance.\n *\n * Modes:\n * - `always`: validate whenever `validateOutput` is true\n * - `never`: never validate\n * - `auto` (default): skip only in production web runtime\n *\n * @returns {boolean}\n */\n shouldRunValidation() {\n if (!this.validateOutput) return false;\n\n if (this.validationMode === 'always') return true;\n if (this.validationMode === 'never') return false;\n\n // Auto mode: avoid extra parse round-trips in Word Online production.\n return !(this.isWebPlatform && isProductionBuild());\n }\n\n /**\n * Yields to the event loop for large operations to keep web UI responsive.\n *\n * @param {number} runCount - Run model size\n * @param {number} charCount - Text size\n * @returns {Promise<void>}\n */\n async maybeYield(runCount, charCount) {\n if (!this.enableEventLoopYielding) return;\n if (runCount <= this.yieldRunThreshold && charCount <= this.yieldCharThreshold) return;\n await yieldToEventLoop();\n }\n\r\n /**\r\n * Wraps the reconciled content for document insertion.\r\n * \r\n * @param {string} ooxml - Reconciled OOXML paragraph\r\n * @param {import('../core/types.js').DocumentFragmentOptions|boolean} [options={}] - Fragment options\r\n * @returns {string} Wrapped document fragment\r\n */\r\n wrapForInsertion(ooxml, options = {}) {\r\n return wrapInDocumentFragment(ooxml, options);\r\n }\r\n\r\n /**\r\n * Executes list generation when a single paragraph expands into a list.\r\n * \r\n * @param {string} cleanText - Preprocessed new text (markdown list)\r\n * @param {Object} numberingContext - Original numbering context\r\n * @param {Array} originalRunModel - Run model of the original paragraph (optional)\r\n * @param {string} originalText - Plain text of the original paragraph (optional, used if runModel not provided)\r\n */\r\n async executeListGeneration(cleanText, numberingContext, originalRunModel, originalText = '') {\r\n return executeListGeneration({\r\n cleanText,\r\n numberingContext,\r\n originalRunModel,\r\n originalText,\r\n generateRedlines: this.generateRedlines,\r\n author: this.author,\r\n font: this.font,\r\n numberingService: this.numberingService\r\n });\r\n }\r\n\r\n /**\r\n * Heuristically detects the indentation step (number of spaces or tabs per level).\r\n * \r\n * @param {string[]} lines - Array of lines\r\n * @returns {number} The detected step (defaulting to 2)\r\n */\r\n detectIndentationStep(lines) {\r\n return detectIndentationStep(lines);\r\n }\r\n\r\n\r\n /**\r\n * Executes table generation from markdown text.\r\n * \r\n * @param {string} markdownTable - Markdown table text\r\n * @returns {Object} ReconciliationResult containing the table OOXML\r\n */\r\n executeTableGeneration(markdownTable) {\r\n const tableData = parseTable(markdownTable);\r\n if (tableData.rows.length === 0 && tableData.headers.length === 0) {\r\n return {\r\n ooxml: '',\r\n isValid: false,\r\n warnings: ['Could not parse Markdown table']\r\n };\r\n }\r\n\r\n const tableOoxml = generateTableOoxml(tableData, {\r\n generateRedlines: this.generateRedlines,\r\n author: this.author\r\n });\r\n\r\n return {\r\n ooxml: tableOoxml,\r\n isValid: true,\r\n warnings: [],\r\n includeNumbering: false\r\n };\r\n }\r\n}\r\nexport { detectContentType, parseListItems, parseTable };\r\n\r\n", "/**\r\n * Run property (w:rPr) helper utilities.\r\n *\r\n * This module owns low-level formatting element operations, including\r\n * schema-order insertion, format extraction, and format add/remove transforms.\r\n */\r\n\r\n/**\r\n * Canonical OOXML run-property schema ordering.\r\n * Shared by all rPr synchronizers.\r\n */\r\nexport const RPR_SCHEMA_ORDER = [\r\n 'w:rStyle', 'w:rFonts', 'w:b', 'w:bCs', 'w:i', 'w:iCs', 'w:caps', 'w:smallCaps',\r\n 'w:strike', 'w:dstrike', 'w:outline', 'w:shadow', 'w:emboss', 'w:imprint', 'w:noProof',\r\n 'w:snapToGrid', 'w:vanish', 'w:webHidden', 'w:color', 'w:spacing', 'w:w', 'w:kern',\r\n 'w:position', 'w:sz', 'w:szCs', 'w:highlight', 'w:u', 'w:effect', 'w:bdr', 'w:shd',\r\n 'w:fitText', 'w:vertAlign', 'w:rtl', 'w:cs', 'w:em', 'w:lang', 'w:eastAsianLayout',\r\n 'w:specVanish', 'w:oMath'\r\n];\r\n\r\n/**\r\n * Inserts an rPr child node in schema order.\r\n *\r\n * @param {Element} rPr - Run properties element\r\n * @param {Element} el - Child element to insert\r\n */\r\nexport function insertRPrChildInOrder(rPr, el) {\r\n const myIndex = RPR_SCHEMA_ORDER.indexOf(el.nodeName);\r\n const myPriority = myIndex === -1 ? 999 : myIndex;\r\n\r\n let inserted = false;\r\n for (const child of Array.from(rPr.childNodes)) {\r\n if (child.nodeType !== 1) continue;\r\n const childIndex = RPR_SCHEMA_ORDER.indexOf(child.nodeName);\r\n const childPriority = childIndex === -1 ? 999 : childIndex;\r\n if (childPriority > myPriority) {\r\n rPr.insertBefore(el, child);\r\n inserted = true;\r\n break;\r\n }\r\n }\r\n if (!inserted) rPr.appendChild(el);\r\n}\r\n\r\n/**\r\n * Shared override routine used by add/remove format transforms.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} rPr - Run properties target\r\n * @param {{bold?: boolean, italic?: boolean, underline?: boolean, strikethrough?: boolean}} formatFlags - Flags to apply\r\n * @param {'remove'|'add'} mode - Override mode\r\n */\r\nfunction _applyOverrides(xmlDoc, rPr, formatFlags, mode) {\r\n if (!rPr || !formatFlags) return;\r\n\r\n const applyBold = !!formatFlags.bold;\r\n const applyItalic = !!formatFlags.italic;\r\n const applyUnderline = !!formatFlags.underline;\r\n const applyStrike = !!formatFlags.strikethrough;\r\n\r\n const removalSet = new Set();\r\n if (applyBold) {\r\n removalSet.add('w:b');\r\n removalSet.add('w:bCs');\r\n }\r\n if (applyItalic) {\r\n removalSet.add('w:i');\r\n removalSet.add('w:iCs');\r\n }\r\n if (applyUnderline) removalSet.add('w:u');\r\n if (applyStrike) removalSet.add('w:strike');\r\n\r\n if (removalSet.size > 0) {\r\n const toRemove = [];\r\n for (const child of Array.from(rPr.childNodes)) {\r\n if (removalSet.has(child.nodeName)) {\r\n toRemove.push(child);\r\n }\r\n }\r\n for (const el of toRemove) {\r\n rPr.removeChild(el);\r\n }\r\n }\r\n\r\n if (applyBold) {\r\n const b = xmlDoc.createElement('w:b');\r\n b.setAttribute('w:val', mode === 'add' ? '1' : '0');\r\n insertRPrChildInOrder(rPr, b);\r\n\r\n const bCs = xmlDoc.createElement('w:bCs');\r\n bCs.setAttribute('w:val', mode === 'add' ? '1' : '0');\r\n insertRPrChildInOrder(rPr, bCs);\r\n }\r\n if (applyItalic) {\r\n const i = xmlDoc.createElement('w:i');\r\n i.setAttribute('w:val', mode === 'add' ? '1' : '0');\r\n insertRPrChildInOrder(rPr, i);\r\n\r\n const iCs = xmlDoc.createElement('w:iCs');\r\n iCs.setAttribute('w:val', mode === 'add' ? '1' : '0');\r\n insertRPrChildInOrder(rPr, iCs);\r\n }\r\n if (applyUnderline) {\r\n const u = xmlDoc.createElement('w:u');\r\n u.setAttribute('w:val', mode === 'add' ? 'single' : 'none');\r\n insertRPrChildInOrder(rPr, u);\r\n }\r\n if (applyStrike) {\r\n const strike = xmlDoc.createElement('w:strike');\r\n strike.setAttribute('w:val', mode === 'add' ? '1' : '0');\r\n insertRPrChildInOrder(rPr, strike);\r\n }\r\n}\r\n\r\n/**\r\n * Builds an rPr XML snippet that explicitly removes formatting while preserving other properties.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} originalRun - Source run\r\n * @param {Object} formatToRemove - Format flags to remove\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @returns {string}\r\n */\r\nexport function buildOverrideRPrXml(xmlDoc, originalRun, formatToRemove, serializer) {\r\n const baseRPr = originalRun.getElementsByTagName('w:rPr')[0] || null;\r\n const rPr = baseRPr ? baseRPr.cloneNode(true) : xmlDoc.createElement('w:rPr');\r\n _applyOverrides(xmlDoc, rPr, formatToRemove, 'remove');\r\n\r\n let rPrXml = serializer.serializeToString(rPr);\r\n rPrXml = rPrXml.replace(/\\s+xmlns:[^=]+=\"[^\"]*\"/g, '');\r\n return rPrXml === '<w:rPr/>' ? '' : rPrXml;\r\n}\r\n\r\n/**\r\n * Removes formatting tags and adds explicit off overrides for the specified flags.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} rPr - Run properties\r\n * @param {Object} formatToRemove - Format flags to remove\r\n */\r\nexport function applyFormatOverridesToRPr(xmlDoc, rPr, formatToRemove) {\r\n _applyOverrides(xmlDoc, rPr, formatToRemove, 'remove');\r\n}\r\n\r\n/**\r\n * Extracts format flags from a run properties element.\r\n *\r\n * @param {Element|null} rPr - Run properties element\r\n * @returns {{ bold: boolean, italic: boolean, underline: boolean, strikethrough: boolean, hasFormatting: boolean }}\r\n */\r\nexport function extractFormatFromRPr(rPr) {\r\n const format = { bold: false, italic: false, underline: false, strikethrough: false, hasFormatting: false };\r\n if (!rPr) return format;\r\n\r\n for (const child of Array.from(rPr.childNodes)) {\r\n if (child.nodeName === 'w:b') format.bold = isFormattingElementEnabled(child, false);\r\n if (child.nodeName === 'w:i') format.italic = isFormattingElementEnabled(child, false);\r\n if (child.nodeName === 'w:u') format.underline = isFormattingElementEnabled(child, true);\r\n if (child.nodeName === 'w:strike') format.strikethrough = isFormattingElementEnabled(child, false);\r\n\r\n if (child.nodeName === 'w:rStyle') {\r\n const styleRef = child.getAttribute('w:val');\r\n if (styleRef) {\r\n const lowerStyle = styleRef.toLowerCase();\r\n if (lowerStyle.includes('bold') || lowerStyle.includes('strong')) format.bold = true;\r\n if (lowerStyle.includes('italic') || lowerStyle.includes('emphasis')) format.italic = true;\r\n if (lowerStyle.includes('underline')) format.underline = true;\r\n }\r\n }\r\n }\r\n\r\n format.hasFormatting = format.bold || format.italic || format.underline || format.strikethrough;\r\n return format;\r\n}\r\n\r\n/**\r\n * Determines whether a formatting element is effectively \"on\".\r\n *\r\n * @param {Element} element - Formatting element\r\n * @param {boolean} isUnderline - Underline semantic handling\r\n * @returns {boolean}\r\n */\r\nfunction isFormattingElementEnabled(element, isUnderline) {\r\n const rawValue = element.getAttribute('w:val') || element.getAttribute('val') || '';\r\n const value = rawValue.toLowerCase();\r\n\r\n if (!value) return true;\r\n\r\n if (isUnderline) {\r\n return value !== 'none' && value !== '0' && value !== 'false' && value !== 'off';\r\n }\r\n\r\n return value !== '0' && value !== 'false' && value !== 'off';\r\n}\r\n", "/**\r\n * OOXML format extraction utilities.\r\n *\r\n * Provides shared paragraph filtering, text-span extraction, and run-format\r\n * extraction for formatting-aware reconciliation flows.\r\n */\r\n\r\nimport { extractFormatFromRPr } from './rpr-helpers.js';\r\nimport { advanceOffsetForParagraphBoundary } from '../core/paragraph-offset-policy.js';\r\nimport { log } from '../adapters/logger.js';\r\nimport { getElementsByTag, getElementsByTagNS, getFirstElementByTag } from '../core/xml-query.js';\n\nconst NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\n\nfunction isWordElement(node, localName) {\n if (!node || node.nodeType !== 1) return false;\n if (node.namespaceURI === NS_W && node.localName === localName) return true;\n const nodeName = String(node.nodeName || '');\n return nodeName === `w:${localName}` || nodeName === localName;\n}\n\nfunction isExcludedRevisionContainer(node) {\n if (!node || node.nodeType !== 1 || node.namespaceURI !== NS_W) return false;\n return node.localName === 'del' || node.localName === 'moveFrom';\n}\n\nfunction collectParagraphRuns(paragraph) {\n const runs = [];\n const stack = Array.from(paragraph?.childNodes || []).reverse();\n\n while (stack.length > 0) {\n const node = stack.pop();\n if (!node || node.nodeType !== 1) continue;\n if (isExcludedRevisionContainer(node)) continue;\n\n if (isWordElement(node, 'r')) {\n runs.push(node);\n continue;\n }\n\n const children = Array.from(node.childNodes || []);\n for (let i = children.length - 1; i >= 0; i -= 1) {\n stack.push(children[i]);\n }\n }\n\n return runs;\n}\n\r\n/**\r\n * Returns only document body paragraphs, excluding comments/footnotes/endnotes.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @returns {Element[]}\r\n */\r\nexport function getDocumentParagraphs(xmlDoc) {\n const excludedContainers = new Set(['comment', 'footnote', 'endnote']);\n const allParagraphs = getElementsByTagNS(xmlDoc, '*', 'p');\n\n return allParagraphs.filter(p => {\n let node = p.parentNode;\n while (node && node.nodeName) {\n const localName = String(node.localName || '').toLowerCase();\n if (excludedContainers.has(localName)) {\n return false;\n }\n node = node.parentNode;\n }\r\n return true;\r\n });\r\n}\r\n\r\n/**\r\n * Builds linear text spans from paragraph elements.\r\n *\r\n * @param {Element[]} paragraphs - Paragraph nodes\r\n * @returns {{ textSpans: Array, charOffset: number }}\r\n */\r\nexport function buildTextSpansFromParagraphs(paragraphs) {\n const textSpans = [];\r\n let charOffset = 0;\r\n\r\n for (let pIndex = 0; pIndex < paragraphs.length; pIndex++) {\n const p = paragraphs[pIndex];\n const runs = collectParagraphRuns(p);\n for (const run of runs) {\n const rPr = getFirstElementByTag(run, 'w:rPr');\n Array.from(run.childNodes || []).forEach(rc => {\n if (isWordElement(rc, 't')) {\n const text = rc.textContent || '';\n if (text.length > 0) {\n textSpans.push({\n charStart: charOffset,\n charEnd: charOffset + text.length,\n textElement: rc,\n runElement: run,\n paragraph: p,\n container: run.parentNode,\n rPr\n });\n charOffset += text.length;\n }\n } else if (isWordElement(rc, 'br') || isWordElement(rc, 'cr') || isWordElement(rc, 'tab') || isWordElement(rc, 'noBreakHyphen')) {\n textSpans.push({\n charStart: charOffset,\n charEnd: charOffset + 1,\n textElement: rc,\n runElement: run,\n paragraph: p,\n container: run.parentNode,\n rPr\n });\n charOffset += 1;\n }\n });\n }\n charOffset = advanceOffsetForParagraphBoundary(charOffset, pIndex, paragraphs.length);\n }\n\r\n return { textSpans, charOffset };\r\n}\r\n\r\n/**\r\n * Processes a single run element and appends extracted spans/hints.\r\n *\r\n * @param {Element} run - `w:r` element\r\n * @param {Element} paragraph - Parent paragraph\r\n * @param {number} charOffset - Start offset\r\n * @param {Array} textSpans - Span collection (mutated)\r\n * @param {Array} formatHints - Format hint collection (mutated)\r\n * @param {Object|null} pFormat - Paragraph-level run format defaults\r\n * @returns {number}\r\n */\r\nexport function processRunForFormatting(run, paragraph, charOffset, textSpans, formatHints, pFormat = null) {\n let rPr = null;\n for (const child of Array.from(run.childNodes)) {\n if (isWordElement(child, 'rPr')) {\n rPr = child;\n break;\n }\n }\r\n\r\n const format = extractFormatFromRPr(rPr);\r\n\r\n if (pFormat) {\r\n if (pFormat.bold && !format.bold) format.bold = true;\r\n if (pFormat.italic && !format.italic) format.italic = true;\r\n if (pFormat.underline && !format.underline) format.underline = true;\r\n if (pFormat.strikethrough && !format.strikethrough) format.strikethrough = true;\r\n }\r\n\r\n format.hasFormatting = format.bold || format.italic || format.underline || format.strikethrough;\r\n\r\n let currentOffset = charOffset;\n for (const child of Array.from(run.childNodes)) {\n if (isWordElement(child, 't')) {\n const text = child.textContent || '';\n if (text.length > 0) {\n const start = currentOffset;\n const end = currentOffset + text.length;\r\n\r\n textSpans.push({\r\n charStart: start,\r\n charEnd: end,\r\n textElement: child,\r\n runElement: run,\r\n paragraph,\r\n rPr,\r\n format: { ...format }\r\n });\r\n\r\n if (format.hasFormatting) {\r\n formatHints.push({\r\n start,\r\n end,\r\n format: { ...format },\r\n run,\r\n rPr\r\n });\r\n }\r\n\r\n currentOffset = end;\r\n }\r\n }\r\n }\r\n\r\n return currentOffset;\r\n}\r\n\r\n/**\r\n * Extracts existing formatting hints from OOXML paragraph runs.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @returns {{ existingFormatHints: Array, textSpans: Array, paragraphs: Element[] }}\n */\nexport function extractFormattingFromOoxml(xmlDoc) {\n const existingFormatHints = [];\n const textSpans = [];\n let charOffset = 0;\n\n const paragraphs = getDocumentParagraphs(xmlDoc);\n\n for (let pIndex = 0; pIndex < paragraphs.length; pIndex++) {\n const p = paragraphs[pIndex];\n let pRPr = null;\n for (const child of Array.from(p.childNodes)) {\n if (isWordElement(child, 'pPr')) {\n for (const pChild of Array.from(child.childNodes)) {\n if (isWordElement(pChild, 'rPr')) {\n pRPr = pChild;\n break;\n }\n }\r\n break;\r\n }\r\n }\r\n\r\n const pFormat = extractFormatFromRPr(pRPr);\r\n if (pFormat.hasFormatting) {\r\n log(`[OxmlEngine] Found paragraph-level formatting: ${JSON.stringify(pFormat)}`);\r\n }\r\n\n const runs = collectParagraphRuns(p);\n for (const run of runs) {\n charOffset = processRunForFormatting(run, p, charOffset, textSpans, existingFormatHints, pFormat);\n }\n charOffset = advanceOffsetForParagraphBoundary(charOffset, pIndex, paragraphs.length);\n }\n\n log(`[OxmlEngine] Extracted ${textSpans.length} text spans, ${existingFormatHints.length} format hints`);\n return { existingFormatHints, textSpans, paragraphs };\n}\n", "/**\r\n * OOXML run/track-change builders.\r\n *\r\n * This module centralizes creation of `w:r`, `w:ins`, `w:del`, `w:rPrChange`,\r\n * and `w:pPrChange` elements used by surgical and reconstruction modes.\r\n */\r\n\r\nimport { RPR_SCHEMA_ORDER } from './rpr-helpers.js';\r\nimport { createRevisionMetadata, getRevisionTimestamp } from '../core/types.js';\r\nimport { getFirstElementByTag } from '../core/xml-query.js';\r\n\r\n/**\r\n * Creates an insertion/deletion wrapper.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {'ins'|'del'} type - Wrapper type\r\n * @param {Element|null} run - Optional run to append\r\n * @param {string} author - Change author\r\n * @returns {Element}\r\n */\r\nexport function createTrackChange(xmlDoc, type, run, author) {\r\n const wrapper = xmlDoc.createElement(type === 'ins' ? 'w:ins' : 'w:del');\r\n const metadata = createRevisionMetadata(author);\r\n wrapper.setAttribute('w:id', String(metadata.id));\r\n wrapper.setAttribute('w:author', metadata.author);\r\n wrapper.setAttribute('w:date', metadata.date);\r\n if (run) {\r\n wrapper.appendChild(run);\r\n }\r\n return wrapper;\r\n}\r\n\r\n/**\r\n * Creates a text run with optional formatting.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} text - Text content\r\n * @param {Element|null} rPr - Run properties\r\n * @param {boolean} isDelete - Use `w:delText` instead of `w:t`\r\n * @returns {Element}\r\n */\r\nexport function createTextRun(xmlDoc, text, rPr, isDelete) {\r\n const run = xmlDoc.createElement('w:r');\r\n if (rPr) run.appendChild(rPr.cloneNode(true));\r\n\r\n const textEl = xmlDoc.createElement(isDelete ? 'w:delText' : 'w:t');\r\n textEl.setAttribute('xml:space', 'preserve');\r\n textEl.textContent = text;\r\n run.appendChild(textEl);\r\n\r\n return run;\r\n}\r\n\r\n/**\r\n * Creates an array of runs with formatting applied from hints.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} text - Text to split and format\r\n * @param {Element|null} baseRPr - Base run properties\r\n * @param {Array} formatHints - Formatting hints\r\n * @param {number} baseOffset - Absolute base offset\r\n * @param {string} [author] - Change author\r\n * @param {boolean} [generateRedlines] - Whether to create rPrChange\r\n * @returns {Element[]}\r\n */\r\nexport function createFormattedRuns(xmlDoc, text, baseRPr, formatHints, baseOffset, author, generateRedlines) {\r\n if (!text) return [];\r\n\r\n const breaks = new Set([0, text.length]);\r\n for (const hint of formatHints) {\r\n const localStart = Math.max(0, hint.start - baseOffset);\r\n const localEnd = Math.min(text.length, hint.end - baseOffset);\r\n if (localStart >= 0 && localStart < text.length) breaks.add(localStart);\r\n if (localEnd > 0 && localEnd <= text.length) breaks.add(localEnd);\r\n }\r\n\r\n const sortedBreaks = Array.from(breaks).sort((a, b) => a - b);\r\n const runs = [];\r\n\r\n for (let i = 0; i < sortedBreaks.length - 1; i++) {\r\n const start = sortedBreaks[i];\r\n const end = sortedBreaks[i + 1];\r\n const segment = text.slice(start, end);\r\n if (!segment) continue;\r\n\r\n const segmentBaseOffset = baseOffset + start;\r\n const segmentEndOffset = baseOffset + end;\r\n\r\n const applicableHints = formatHints.filter(h =>\r\n h.start <= segmentBaseOffset && h.end >= segmentEndOffset\r\n );\r\n\r\n const combinedFormat = {};\r\n applicableHints.forEach(h => {\r\n if (h.format) Object.assign(combinedFormat, h.format);\r\n });\r\n\r\n const formattedRPr = injectFormattingToRPr(xmlDoc, baseRPr, combinedFormat, author, generateRedlines);\r\n runs.push(createTextRunWithRPrElement(xmlDoc, segment, formattedRPr, false));\r\n }\r\n\r\n return runs;\r\n}\r\n\r\n/**\r\n * Creates a text run with an existing rPr element (no clone).\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} text - Text content\r\n * @param {Element|null} rPrElement - Run properties element\r\n * @param {boolean} isDelete - Use `w:delText` instead of `w:t`\r\n * @returns {Element}\r\n */\r\nexport function createTextRunWithRPrElement(xmlDoc, text, rPrElement, isDelete) {\r\n const run = xmlDoc.createElement('w:r');\r\n if (rPrElement) run.appendChild(rPrElement);\r\n\r\n const textEl = xmlDoc.createElement(isDelete ? 'w:delText' : 'w:t');\r\n textEl.setAttribute('xml:space', 'preserve');\r\n textEl.textContent = text;\r\n run.appendChild(textEl);\r\n\r\n return run;\r\n}\r\n\r\n/**\r\n * Creates a new rPr synchronized to the requested core formatting flags.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element|null} baseRPr - Base run properties\r\n * @param {Object|null} format - Format flags\r\n * @param {string} [author] - Change author\r\n * @param {boolean} [generateRedlines] - Whether to create rPrChange\r\n * @returns {Element}\r\n */\r\nexport function injectFormattingToRPr(xmlDoc, baseRPr, format, author, generateRedlines) {\r\n const rPr = xmlDoc.createElement('w:rPr');\r\n\r\n if (baseRPr) {\r\n Array.from(baseRPr.childNodes).forEach(child => {\r\n if (!['w:b', 'w:bCs', 'w:i', 'w:iCs', 'w:u', 'w:strike', 'w:rPrChange'].includes(child.nodeName)) {\r\n rPr.appendChild(child.cloneNode(true));\r\n }\r\n });\r\n }\r\n\r\n const activeFormat = format || { bold: false, italic: false, underline: false, strikethrough: false };\r\n\r\n if (author && generateRedlines) {\r\n createRPrChange(xmlDoc, rPr, author, baseRPr);\r\n }\r\n\r\n const syncElement = (tagName, isOn, valOn = null, valOff = '0') => {\r\n const el = xmlDoc.createElement(tagName);\r\n if (isOn) {\r\n if (valOn) el.setAttribute('w:val', valOn);\r\n } else if (valOff) {\r\n el.setAttribute('w:val', valOff);\r\n }\r\n\r\n const myIndex = RPR_SCHEMA_ORDER.indexOf(tagName);\r\n const myPriority = myIndex === -1 ? 999 : myIndex;\r\n\r\n let inserted = false;\r\n for (const child of Array.from(rPr.childNodes)) {\r\n if (child.nodeType !== 1) continue;\r\n const childIndex = RPR_SCHEMA_ORDER.indexOf(child.nodeName);\r\n const childPriority = childIndex === -1 ? 999 : childIndex;\r\n if (childPriority > myPriority) {\r\n rPr.insertBefore(el, child);\r\n inserted = true;\r\n break;\r\n }\r\n }\r\n if (!inserted) rPr.appendChild(el);\r\n };\r\n\r\n syncElement('w:b', !!activeFormat.bold, '1', '0');\r\n syncElement('w:bCs', !!activeFormat.bold, '1', '0');\r\n syncElement('w:i', !!activeFormat.italic, '1', '0');\r\n syncElement('w:iCs', !!activeFormat.italic, '1', '0');\r\n syncElement('w:u', !!activeFormat.underline, 'single', 'none');\r\n syncElement('w:strike', !!activeFormat.strikethrough, '1', '0');\r\n\r\n return rPr;\r\n}\r\n\r\n/**\r\n * Creates and attaches a `w:rPrChange` snapshot.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} rPr - Target run properties\r\n * @param {string} author - Change author\r\n * @param {string} dateStr - ISO date string\r\n * @param {Element} [sourceNode] - Optional source for previous state snapshot\r\n * @returns {Element}\r\n */\r\nexport function snapshotAndAttachRPrChange(xmlDoc, rPr, author, dateStr, sourceNode) {\r\n const rPrChange = xmlDoc.createElement('w:rPrChange');\r\n rPrChange.setAttribute('w:id', String(createRevisionMetadata(author).id));\r\n rPrChange.setAttribute('w:author', author);\r\n rPrChange.setAttribute('w:date', dateStr);\r\n\r\n const previousRPr = xmlDoc.createElement('w:rPr');\r\n const source = sourceNode || rPr;\r\n\r\n Array.from(source.childNodes).forEach(child => {\r\n if (child.nodeName !== 'w:rPrChange') {\r\n previousRPr.appendChild(child.cloneNode(true));\r\n }\r\n });\r\n\r\n rPrChange.appendChild(previousRPr);\r\n\r\n const existing = getFirstElementByTag(rPr, 'w:rPrChange');\r\n if (existing) {\r\n rPr.removeChild(existing);\r\n }\r\n\r\n rPr.appendChild(rPrChange);\r\n return rPrChange;\r\n}\r\n\r\n/**\r\n * Creates `w:rPrChange` for track formatting changes.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} rPr - Run properties target\r\n * @param {string} author - Change author\r\n * @param {Element} [previousRPrArg] - Optional explicit previous-state source\r\n * @returns {void}\r\n */\r\nfunction createRPrChange(xmlDoc, rPr, author, previousRPrArg) {\r\n snapshotAndAttachRPrChange(xmlDoc, rPr, author, getRevisionTimestamp(), previousRPrArg || rPr);\r\n}\r\n", "import { advanceOffsetForParagraphBoundary } from '../core/paragraph-offset-policy.js';\n\nconst NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\n\nfunction isWordElement(node, localName) {\n if (!node || node.nodeType !== 1) return false;\n if (node.namespaceURI === NS_W && node.localName === localName) return true;\n const nodeName = String(node.nodeName || '');\n return nodeName === `w:${localName}` || nodeName === localName;\n}\n\r\n/**\r\n * Paragraph targeting helpers for format-only operations.\r\n *\r\n * Encapsulates paragraph text reconstruction and matching logic used to map\r\n * AI-provided text ranges to the correct paragraph/spans in OOXML.\r\n */\r\n\r\n/**\r\n * Builds paragraph metadata (text, spans, offsets) used for format-only changes.\r\n *\r\n * @param {Document} xmlDoc - XML document (unused, kept for signature compatibility)\r\n * @param {Element[]} paragraphs - Paragraph elements\r\n * @param {Array} textSpans - Extracted text spans\r\n * @returns {Array}\r\n */\r\nexport function buildParagraphInfos(xmlDoc, paragraphs, textSpans) {\n void xmlDoc;\n const spansByParagraph = new Map();\n for (const span of textSpans) {\r\n if (!span || !span.paragraph) continue;\r\n if (!spansByParagraph.has(span.paragraph)) {\r\n spansByParagraph.set(span.paragraph, []);\r\n }\r\n spansByParagraph.get(span.paragraph).push(span);\r\n }\r\n\r\n const infos = [];\r\n let runningOffset = 0;\r\n\r\n paragraphs.forEach((p, index) => {\n const spans = (spansByParagraph.get(p) || []).slice().sort((a, b) => a.charStart - b.charStart);\n const text = buildParagraphTextFromSpans(spans);\n const normalizedText = normalizeParagraphComparisonText(text);\n const normalizedTrim = normalizedText.trim();\n\n infos.push({\n paragraph: p,\n spans,\n text,\n normalizedText,\n normalizedTrim,\n startOffset: runningOffset\n });\n\n runningOffset += normalizedText.length;\n runningOffset = advanceOffsetForParagraphBoundary(runningOffset, index, paragraphs.length);\n });\n\r\n return infos;\r\n}\r\n\r\n/**\r\n * Finds a paragraph info entry that matches the provided text.\r\n *\r\n * @param {Array} paragraphInfos - Paragraph metadata\r\n * @param {string} originalText - Original text\r\n * @returns {Object|null}\r\n */\r\nexport function findMatchingParagraphInfo(paragraphInfos, originalText) {\r\n if (!originalText) return null;\r\n\r\n const normalizedOriginal = normalizeParagraphComparisonText(originalText);\r\n const normalizedTrim = normalizedOriginal.trim();\r\n if (!normalizedTrim) return null;\r\n\r\n for (const info of paragraphInfos) {\n if (info.normalizedText === normalizedOriginal) {\n return info;\n }\n }\n\n for (const info of paragraphInfos) {\n if (info.normalizedTrim === normalizedTrim) {\n return info;\n }\n }\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Finds the best target paragraph and offset for format-only operations.\r\n *\r\n * @param {Array} paragraphInfos - Paragraph metadata\r\n * @param {string} originalText - Original text used for matching\r\n * @returns {{ targetInfo: Object|null, matchOffset: number }}\r\n */\r\nexport function findTargetParagraphInfo(paragraphInfos, originalText) {\n const normalizedOriginalFull = normalizeParagraphComparisonText(originalText);\r\n const normalizedOriginalTrim = normalizedOriginalFull.trim();\r\n\r\n let targetInfo = null;\r\n let matchOffset = 0;\r\n\r\n for (const info of paragraphInfos) {\n if (info.normalizedText === normalizedOriginalFull) {\n targetInfo = info;\n return { targetInfo, matchOffset };\n }\n }\n\n if (normalizedOriginalTrim.length > 0) {\n for (const info of paragraphInfos) {\n if (info.normalizedTrim === normalizedOriginalTrim) {\n targetInfo = info;\n return { targetInfo, matchOffset };\n }\n }\n }\n\n if (normalizedOriginalTrim.length > 0) {\n const docPlain = paragraphInfos.map(info => info.normalizedText).join('\\n');\n const idx = docPlain.indexOf(normalizedOriginalTrim);\n if (idx !== -1) {\n for (const info of paragraphInfos) {\n const start = info.startOffset;\n const length = info.normalizedText.length;\n if (idx >= start && idx <= start + length) {\n targetInfo = info;\n matchOffset = idx - start;\n break;\r\n }\r\n }\n }\n }\n\n // Fallback: single-paragraph scope where extracted span text is only a subset\n // of original paragraph text (common when prior tracked wrappers contain text\n // that is not represented in direct run-span extraction).\n if (!targetInfo && paragraphInfos.length === 1 && normalizedOriginalFull.length > 0) {\n const onlyInfo = paragraphInfos[0];\n const paragraphTrim = onlyInfo.normalizedTrim || '';\n if (paragraphTrim.length > 0) {\n const subsetIndex = normalizedOriginalFull.indexOf(paragraphTrim);\n if (subsetIndex >= 0) {\n targetInfo = onlyInfo;\n matchOffset = -subsetIndex;\n }\n }\n }\n\n return { targetInfo, matchOffset };\n}\n\r\n/**\r\n * Walks up the DOM to find the containing paragraph for a run.\r\n *\r\n * @param {Node} node - Starting node\r\n * @returns {Element|null}\r\n */\r\nexport function getContainingParagraph(node) {\n let current = node;\n while (current) {\n if (isWordElement(current, 'p')) return current;\n current = current.parentNode;\n }\n return null;\n}\r\n\r\n/**\r\n * Reconstructs human-readable text from spans to align with Word paragraph text.\r\n *\r\n * @param {Array} spans - Span collection\r\n * @returns {string}\r\n */\r\nfunction buildParagraphTextFromSpans(spans) {\r\n if (!spans || spans.length === 0) return '';\r\n\r\n let text = '';\r\n for (const span of spans) {\n if (!span || !span.textElement) continue;\n const textElement = span.textElement;\n if (isWordElement(textElement, 't')) {\n text += span.textElement.textContent || '';\n } else if (isWordElement(textElement, 'tab')) {\n text += '\\t';\n } else if (isWordElement(textElement, 'br') || isWordElement(textElement, 'cr')) {\n text += '\\n';\n } else if (isWordElement(textElement, 'noBreakHyphen')) {\n text += '\\u2011';\n }\n }\n return text;\r\n}\r\n\r\n/**\r\n * Normalizes paragraph text for comparisons (handles carriage returns and NBSP).\r\n *\r\n * @param {string} text - Text input\r\n * @returns {string}\r\n */\r\nfunction normalizeParagraphComparisonText(text) {\r\n if (!text) return '';\r\n return text\r\n .replace(/\\r/g, '\\n')\r\n .replace(/\\u00a0/g, ' ');\r\n}\r\n", "/**\r\n * Span-level formatting helpers.\r\n *\r\n * Handles boundary splitting and robust format application on already-extracted\r\n * text spans without owning paragraph targeting concerns.\r\n */\r\n\r\nimport { mergeFormats } from '../pipeline/markdown-processor.js';\r\nimport { injectFormattingToRPr, createTextRun } from './run-builders.js';\r\n\r\n/**\r\n * Splits spans at all supplied absolute boundaries.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Array} textSpans - Input spans\r\n * @param {number[]} boundaries - Absolute boundaries\r\n * @returns {Array}\r\n */\r\nexport function splitSpansAtBoundaries(xmlDoc, textSpans, boundaries) {\n const sortedBoundaries = Array.from(new Set(boundaries)).sort((a, b) => a - b);\n if (sortedBoundaries.length === 0 || textSpans.length === 0) {\n return [...textSpans];\n }\n\n const orderedSpans = [...textSpans].sort((a, b) => a.charStart - b.charStart || a.charEnd - b.charEnd);\n const splitSpans = [];\n let boundaryIndex = 0;\n\n for (const span of orderedSpans) {\n while (boundaryIndex < sortedBoundaries.length && sortedBoundaries[boundaryIndex] <= span.charStart) {\n boundaryIndex++;\n }\n\n let currentSpan = span;\n while (boundaryIndex < sortedBoundaries.length && sortedBoundaries[boundaryIndex] < currentSpan.charEnd) {\n const boundary = sortedBoundaries[boundaryIndex];\n const splitResult = splitSpanAtOffset(xmlDoc, currentSpan, boundary);\n\n if (!splitResult) {\n boundaryIndex++;\n continue;\n }\n\n splitSpans.push(splitResult[0]);\n currentSpan = splitResult[1];\n boundaryIndex++;\n }\n\n splitSpans.push(currentSpan);\n }\n\n return splitSpans;\n}\n\r\n/**\r\n * Robust formatting application.\r\n * Identifies all boundaries, splits all runs first, then applies merged formats.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Array} textSpans - Text spans\r\n * @param {Array} formatHints - Format hints\r\n * @param {string} author - Change author\r\n * @param {boolean} generateRedlines - Track change toggle\r\n * @returns {void}\r\n */\r\nexport function applyFormatHintsToSpansRobust(xmlDoc, textSpans, formatHints, author, generateRedlines) {\n if (textSpans.length === 0) return;\n\r\n const boundaries = [];\r\n for (const hint of formatHints) {\r\n boundaries.push(hint.start, hint.end);\r\n }\r\n\r\n const currentSpans = splitSpansAtBoundaries(xmlDoc, textSpans, boundaries)\n .sort((a, b) => a.charStart - b.charStart || a.charEnd - b.charEnd);\n const getOverlappingHints = createFormatHintOverlapLookup(formatHints);\n\n for (const span of currentSpans) {\n const applicableHints = getOverlappingHints(span.charStart, span.charEnd);\n if (applicableHints.length > 0) {\n const targetFormat = mergeFormats(...applicableHints.map(h => h.format));\n addFormattingToRun(xmlDoc, span.runElement, targetFormat, author, generateRedlines);\n }\r\n }\r\n}\n\nfunction createFormatHintOverlapLookup(formatHints) {\n const sortedHints = (formatHints || [])\n .slice()\n .sort((a, b) => a.start - b.start || a.end - b.end);\n\n const activeHints = [];\n let nextHintIndex = 0;\n\n return (start, end) => {\n while (nextHintIndex < sortedHints.length && sortedHints[nextHintIndex].start < end) {\n activeHints.push(sortedHints[nextHintIndex]);\n nextHintIndex++;\n }\n\n for (let i = activeHints.length - 1; i >= 0; i--) {\n if (activeHints[i].end <= start) {\n activeHints.splice(i, 1);\n }\n }\n\n const overlaps = [];\n for (const hint of activeHints) {\n if (hint.start < end && hint.end > start) {\n overlaps.push(hint);\n }\n }\n return overlaps;\n };\n}\n\r\n/**\r\n * Splits a text span at a specific absolute character offset.\r\n * Modifies the DOM and returns the two new span objects.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Object} span - Text span\r\n * @param {number} absoluteOffset - Absolute split offset\r\n * @returns {Array|null}\r\n */\r\nexport function splitSpanAtOffset(xmlDoc, span, absoluteOffset) {\r\n const run = span.runElement;\r\n const parent = run.parentNode;\r\n if (!parent) return null;\r\n\r\n const fullText = span.textElement.textContent || '';\r\n const localSplitPoint = absoluteOffset - span.charStart;\r\n\r\n const textBefore = fullText.substring(0, localSplitPoint);\r\n const textAfter = fullText.substring(localSplitPoint);\r\n\r\n if (textBefore.length === 0 || textAfter.length === 0) return null;\r\n\r\n const runBefore = createTextRun(xmlDoc, textBefore, span.rPr, false);\r\n const runAfter = createTextRun(xmlDoc, textAfter, span.rPr, false);\r\n\r\n parent.insertBefore(runBefore, run);\r\n parent.insertBefore(runAfter, run);\r\n parent.removeChild(run);\r\n\r\n const tBefore = runBefore.getElementsByTagName('w:t')[0];\r\n const tAfter = runAfter.getElementsByTagName('w:t')[0];\r\n\r\n return [\r\n { ...span, charEnd: absoluteOffset, textElement: tBefore, runElement: runBefore },\r\n { ...span, charStart: absoluteOffset, textElement: tAfter, runElement: runAfter }\r\n ];\r\n}\r\n\r\n/**\r\n * Adds formatting elements to a run's rPr, with track change support.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} run - Run element\r\n * @param {Object} format - Format flags\r\n * @param {string} author - Change author\r\n * @param {boolean} generateRedlines - Track change toggle\r\n * @returns {void}\r\n */\r\nfunction addFormattingToRun(xmlDoc, run, format, author, generateRedlines) {\r\n let rPr = run.getElementsByTagName('w:rPr')[0];\r\n const baseRPr = rPr ? rPr.cloneNode(true) : null;\r\n\r\n if (!rPr) {\r\n rPr = xmlDoc.createElement('w:rPr');\r\n run.insertBefore(rPr, run.firstChild);\r\n }\r\n\r\n const newRPr = injectFormattingToRPr(xmlDoc, baseRPr, format, author, generateRedlines);\r\n\r\n while (rPr.firstChild) rPr.removeChild(rPr.firstChild);\r\n Array.from(newRPr.childNodes).forEach(child => rPr.appendChild(child));\r\n}\r\n", "/**\r\n * Formatting application orchestration utilities.\r\n *\r\n * Applies format-only changes and surgical formatting synchronization over\r\n * existing OOXML runs.\r\n */\r\n\r\nimport { mergeFormats } from '../pipeline/markdown-processor.js';\r\nimport { applyFormatOverridesToRPr, extractFormatFromRPr } from './rpr-helpers.js';\r\nimport { snapshotAndAttachRPrChange, injectFormattingToRPr } from './run-builders.js';\r\nimport { getDocumentParagraphs, buildTextSpansFromParagraphs } from './format-extraction.js';\r\nimport { buildParagraphInfos, findTargetParagraphInfo } from './format-paragraph-targeting.js';\r\nimport { splitSpansAtBoundaries, applyFormatHintsToSpansRobust } from './format-span-application.js';\r\nimport { getRevisionTimestamp } from '../core/types.js';\nimport { warn, log } from '../adapters/logger.js';\nimport { getFirstElementByTag } from '../core/xml-query.js';\nimport { getDefaultAuthor } from '../adapters/config.js';\n\nconst NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\n\nfunction isWordElement(node, localName) {\n if (!node || node.nodeType !== 1) return false;\n if (node.namespaceURI === NS_W && node.localName === localName) return true;\n const nodeName = String(node.nodeName || '');\n return nodeName === `w:${localName}` || nodeName === localName;\n}\n\nfunction normalizePrecomputedFormatContext(precomputedContext) {\n if (Array.isArray(precomputedContext)) {\n return {\n textSpans: precomputedContext,\n paragraphs: null,\n paragraphInfos: null\n };\n }\n\n if (!precomputedContext || typeof precomputedContext !== 'object') {\n return {\n textSpans: null,\n paragraphs: null,\n paragraphInfos: null\n };\n }\n\n return {\n textSpans: Array.isArray(precomputedContext.textSpans) ? precomputedContext.textSpans : null,\n paragraphs: Array.isArray(precomputedContext.paragraphs) ? precomputedContext.paragraphs : null,\n paragraphInfos: Array.isArray(precomputedContext.paragraphInfos) ? precomputedContext.paragraphInfos : null\n };\n}\n\n/**\n * Removes existing core formatting via `w:rPrChange` snapshots and explicit overrides.\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Array} textSpans - Text spans (unused, kept for compatibility)\r\n * @param {Array} existingFormatHints - Existing formatting hints\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Change author\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applyFormatRemovalAsSurgicalReplacement(xmlDoc, textSpans, existingFormatHints, serializer, author, generateRedlines = true) {\r\n void textSpans;\r\n let hasAnyChanges = false;\r\n const processedRuns = new Set();\r\n const dateStr = getRevisionTimestamp();\r\n\r\n log(`[OxmlEngine] Surgical format removal: ${existingFormatHints.length} hints to process (using w:rPrChange)`);\r\n\r\n for (const hint of existingFormatHints) {\r\n const run = hint.run;\r\n if (processedRuns.has(run)) continue;\r\n processedRuns.add(run);\r\n if (!run.parentNode) continue;\r\n\r\n log('[OxmlEngine] Processing run for surgical format removal, format:', hint.format);\r\n\r\n let rPr = getFirstElementByTag(run, 'w:rPr');\r\n if (!rPr) {\r\n rPr = xmlDoc.createElement('w:rPr');\r\n run.insertBefore(rPr, run.firstChild);\r\n }\r\n\r\n if (generateRedlines) {\n snapshotAndAttachRPrChange(xmlDoc, rPr, author || getDefaultAuthor(), dateStr);\n }\n\r\n applyFormatOverridesToRPr(xmlDoc, rPr, hint.format);\r\n hasAnyChanges = true;\r\n }\r\n\r\n if (hasAnyChanges) {\r\n log('[OxmlEngine] Surgical format removal completed successfully (Pure Format Mode)');\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: true };\r\n }\r\n\r\n log('[OxmlEngine] No format changes were applied');\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: false };\r\n}\r\n\r\n/**\r\n * Applies format additions by synchronizing run-level target state after boundary splitting.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Array} textSpans - Extracted text spans\r\n * @param {Array} formatHints - Format hints\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Change author\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applyFormatAdditionsAsSurgicalReplacement(xmlDoc, textSpans, formatHints, serializer, author, generateRedlines = true) {\r\n let hasAnyChanges = false;\r\n const processedRuns = new Set();\r\n\r\n if (!textSpans || textSpans.length === 0) {\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: false };\r\n }\r\n\r\n const boundaries = [];\r\n for (const hint of formatHints) {\r\n boundaries.push(hint.start, hint.end);\r\n }\r\n const currentSpans = splitSpansAtBoundaries(xmlDoc, textSpans, boundaries);\r\n const orderedSpans = currentSpans\r\n .slice()\r\n .sort((a, b) => a.charStart - b.charStart || a.charEnd - b.charEnd);\r\n const getOverlappingHints = createFormatHintOverlapLookup(formatHints);\n\n for (const span of orderedSpans) {\n if (!span || !span.textElement || !isWordElement(span.textElement, 't')) continue;\n\n const applicableHints = getOverlappingHints(span.charStart, span.charEnd);\n if (applicableHints.length === 0) continue;\n\r\n const mergedDesiredFormat = mergeFormats(...applicableHints.map(h => h.format));\r\n const desiredFormat = {\r\n bold: !!mergedDesiredFormat.bold,\r\n italic: !!mergedDesiredFormat.italic,\r\n underline: !!mergedDesiredFormat.underline,\r\n strikethrough: !!mergedDesiredFormat.strikethrough\r\n };\r\n\r\n const existingFormatRaw = span.format || extractFormatFromRPr(span.rPr);\r\n const existingFormat = {\r\n bold: !!existingFormatRaw.bold,\r\n italic: !!existingFormatRaw.italic,\r\n underline: !!existingFormatRaw.underline,\r\n strikethrough: !!existingFormatRaw.strikethrough\r\n };\r\n\r\n const formatsToCheck = ['bold', 'italic', 'underline', 'strikethrough'];\r\n const needsSync = formatsToCheck.some(f => desiredFormat[f] !== existingFormat[f]);\r\n if (!needsSync) continue;\r\n\r\n if (processedRuns.has(span.runElement)) continue;\r\n processedRuns.add(span.runElement);\r\n\r\n const textContent = span.textElement.textContent || '';\r\n if (!textContent) continue;\r\n\r\n const parentNode = span.runElement.parentNode;\r\n if (!parentNode) continue;\r\n\r\n const run = span.runElement;\r\n const baseRPr = getFirstElementByTag(run, 'w:rPr');\r\n const syncedRPr = injectFormattingToRPr(\n xmlDoc,\n baseRPr,\n desiredFormat,\n author || getDefaultAuthor(),\n generateRedlines\n );\n\r\n let rPr = baseRPr;\r\n if (!rPr) {\r\n run.insertBefore(syncedRPr, run.firstChild);\r\n } else {\r\n while (rPr.firstChild) {\r\n rPr.removeChild(rPr.firstChild);\r\n }\r\n Array.from(syncedRPr.childNodes).forEach(child => rPr.appendChild(child));\r\n }\r\n\r\n hasAnyChanges = true;\r\n }\r\n\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: hasAnyChanges };\r\n}\r\n\r\n/**\r\n * Applies formatting changes to existing text without modifying content.\r\n * Used when markdown formatting is applied to unchanged text.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} originalText - Original plain text\r\n * @param {Array} formatHints - Format hints\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Change author\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @param {Array|Object|null} [precomputedContext=null] - Optional precomputed format context\n * @returns {{ oxml?: string, hasChanges: boolean, useNativeApi?: boolean, formatHints?: Array, originalText?: string }}\n */\nexport function applyFormatOnlyChanges(xmlDoc, originalText, formatHints, serializer, author, generateRedlines = true, precomputedContext = null) {\n const precomputed = normalizePrecomputedFormatContext(precomputedContext);\n const allParagraphs = precomputed.paragraphs || getDocumentParagraphs(xmlDoc);\n\n let textSpans = precomputed.textSpans || [];\n if (!precomputed.textSpans) {\n ({ textSpans } = buildTextSpansFromParagraphs(allParagraphs));\n }\n\r\n if (!textSpans || textSpans.length === 0) {\r\n warn('[OxmlEngine] No spans available for format-only change; requesting caller fallback strategy');\n return {\r\n hasChanges: true,\r\n useNativeApi: true,\r\n formatHints,\r\n originalText\r\n };\r\n }\r\n\r\n if (!formatHints || formatHints.length === 0) {\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: false };\r\n }\r\n\r\n const paragraphInfos = precomputed.paragraphInfos || buildParagraphInfos(xmlDoc, allParagraphs, textSpans);\n const { targetInfo, matchOffset } = findTargetParagraphInfo(paragraphInfos, originalText);\n\r\n if (!targetInfo || !targetInfo.spans || targetInfo.spans.length === 0) {\r\n warn('[OxmlEngine] Unable to pinpoint target paragraph for format-only change; requesting caller fallback strategy');\n return {\r\n hasChanges: true,\r\n useNativeApi: true,\r\n formatHints,\r\n originalText\r\n };\r\n }\r\n\r\n const baseOffset = targetInfo.spans[0].charStart;\r\n const localizedSpans = targetInfo.spans.map(span => ({\r\n ...span,\r\n charStart: span.charStart - baseOffset,\r\n charEnd: span.charEnd - baseOffset\r\n }));\r\n\r\n const adjustedHints = formatHints.map(hint => ({\r\n ...hint,\r\n start: hint.start + matchOffset,\r\n end: hint.end + matchOffset\r\n }));\r\n\r\n applyFormatHintsToSpansRobust(xmlDoc, localizedSpans, adjustedHints, author, generateRedlines);\r\n\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: true };\r\n}\r\n\r\n/**\r\n * Surgical variant of format-only changes.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} originalText - Original plain text\r\n * @param {Array} formatHints - Format hints\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Change author\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @param {Array|Object|null} [precomputedContext=null] - Optional precomputed format context\n * @returns {{ oxml?: string, hasChanges: boolean, useNativeApi?: boolean, formatHints?: Array, originalText?: string }}\n */\nexport function applyFormatOnlyChangesSurgical(xmlDoc, originalText, formatHints, serializer, author, generateRedlines = true, precomputedContext = null) {\n const precomputed = normalizePrecomputedFormatContext(precomputedContext);\n const allParagraphs = precomputed.paragraphs || getDocumentParagraphs(xmlDoc);\n\n let textSpans = precomputed.textSpans || [];\n if (!precomputed.textSpans) {\n ({ textSpans } = buildTextSpansFromParagraphs(allParagraphs));\n }\n\r\n if (!textSpans || textSpans.length === 0) {\r\n warn('[OxmlEngine] No spans available for surgical format-only change; requesting caller fallback strategy');\n return {\r\n hasChanges: true,\r\n useNativeApi: true,\r\n formatHints,\r\n originalText\r\n };\r\n }\r\n\r\n if (!formatHints || formatHints.length === 0) {\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: false };\r\n }\r\n\r\n const paragraphInfos = precomputed.paragraphInfos || buildParagraphInfos(xmlDoc, allParagraphs, textSpans);\n const { targetInfo, matchOffset } = findTargetParagraphInfo(paragraphInfos, originalText);\n\r\n if (!targetInfo || !targetInfo.spans || targetInfo.spans.length === 0) {\r\n warn('[OxmlEngine] Unable to pinpoint target paragraph for surgical format-only change; requesting caller fallback strategy');\n return {\r\n hasChanges: true,\r\n useNativeApi: true,\r\n formatHints,\r\n originalText\r\n };\r\n }\r\n\r\n const baseOffset = targetInfo.spans[0].charStart;\r\n const localizedSpans = targetInfo.spans.map(span => ({\r\n ...span,\r\n charStart: span.charStart - baseOffset,\r\n charEnd: span.charEnd - baseOffset\r\n }));\r\n\r\n const adjustedHints = formatHints.map(hint => ({\r\n ...hint,\r\n start: hint.start + matchOffset,\r\n end: hint.end + matchOffset\r\n }));\r\n\r\n return applyFormatAdditionsAsSurgicalReplacement(\r\n xmlDoc,\r\n localizedSpans,\r\n adjustedHints,\r\n serializer,\r\n author,\r\n generateRedlines\r\n );\r\n}\r\n\r\n/**\r\n * Builds a sweep-line overlap lookup for format hints.\r\n *\r\n * @param {Array} formatHints - Format hints\r\n * @returns {(start:number, end:number)=>Array}\r\n */\r\nfunction createFormatHintOverlapLookup(formatHints) {\r\n const sortedHints = (formatHints || [])\r\n .slice()\r\n .sort((a, b) => a.start - b.start || a.end - b.end);\r\n\r\n const activeHints = [];\r\n let nextHintIndex = 0;\r\n\r\n return (start, end) => {\r\n while (nextHintIndex < sortedHints.length && sortedHints[nextHintIndex].start < end) {\r\n activeHints.push(sortedHints[nextHintIndex]);\r\n nextHintIndex++;\r\n }\r\n\r\n for (let i = activeHints.length - 1; i >= 0; i--) {\r\n if (activeHints[i].end <= start) {\r\n activeHints.splice(i, 1);\r\n }\r\n }\r\n\r\n return activeHints.filter(hint => hint.start < end && hint.end > start);\r\n };\r\n}\r\n", "/**\r\n * Table-cell context helpers.\r\n *\r\n * Handles detection of table-wrapped paragraph OOXML and extraction of only\r\n * target paragraph content for safe `insertOoxml` replacement.\r\n */\r\n\r\nimport { getDocumentParagraphs } from './format-extraction.js';\r\nimport { log } from '../adapters/logger.js';\r\nimport { buildParagraphOnlyPackage } from '../services/package-builder.js';\r\nimport { getElementsByTag } from '../core/xml-query.js';\r\n\r\nconst W14_NS = 'http://schemas.microsoft.com/office/word/2010/wordml';\r\n\r\n/**\r\n * Detects whether the current XML is table-wrapped and resolves target paragraph context.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} originalText - Source paragraph text\r\n * @param {Object} [options={}] - Detection options\r\n * @param {string|null} [options.targetParagraphId=null] - Preferred paragraph id (`w14:paraId`)\r\n * @returns {{\r\n * hasTableWrapper: boolean,\r\n * isTableCellParagraph: boolean,\r\n * targetParagraph?: Element|null,\r\n * paragraphs: Element[],\r\n * paragraph: Element|null,\r\n * tableElement: Element|null\r\n * }}\r\n */\r\nexport function detectTableCellContext(xmlDoc, originalText, options = {}) {\r\n const { targetParagraphId = null } = options;\r\n const tables = getElementsByTag(xmlDoc, 'w:tbl');\r\n if (tables.length === 0) {\r\n return { hasTableWrapper: false, isTableCellParagraph: false, paragraphs: [], paragraph: null, tableElement: null };\r\n }\r\n\r\n const allParagraphs = getDocumentParagraphs(xmlDoc);\r\n const paragraphsInCells = allParagraphs.filter(p => {\r\n let parent = p.parentNode;\r\n while (parent) {\r\n if (parent.nodeName === 'w:tc') return true;\r\n parent = parent.parentNode;\r\n }\r\n return false;\r\n });\r\n\r\n log(`[OxmlEngine] Table wrapper detected: ${tables.length} tables, ${paragraphsInCells.length} paragraphs in cells`);\r\n\r\n let targetParagraph = null;\r\n\r\n // Most reliable selector when available (avoids ambiguous duplicate text matches in tables).\r\n if (targetParagraphId) {\r\n const normalizedTargetId = String(targetParagraphId).toUpperCase();\r\n targetParagraph = paragraphsInCells.find(p => {\r\n const paragraphId = getParagraphId(p);\r\n return paragraphId && paragraphId.toUpperCase() === normalizedTargetId;\r\n }) || null;\r\n\r\n if (targetParagraph) {\r\n log(`[OxmlEngine] Found target paragraph by paraId: \"${targetParagraphId}\"`);\r\n } else {\r\n log(`[OxmlEngine] paraId \"${targetParagraphId}\" not found in wrapper, falling back to text match`);\r\n }\r\n }\r\n\r\n if (originalText && originalText.trim()) {\r\n const normalizedTarget = originalText.trim();\r\n if (!targetParagraph) {\r\n for (const p of paragraphsInCells) {\r\n const textNodes = getElementsByTag(p, 'w:t');\r\n let paragraphText = '';\r\n for (const t of textNodes) {\r\n paragraphText += t.textContent || '';\r\n }\r\n\r\n if (paragraphText.trim() === normalizedTarget) {\r\n targetParagraph = p;\r\n log(`[OxmlEngine] Found target paragraph by text match: \"${normalizedTarget.substring(0, 30)}...\"`);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n hasTableWrapper: true,\r\n isTableCellParagraph: paragraphsInCells.length > 0,\r\n targetParagraph,\r\n paragraphs: paragraphsInCells,\r\n paragraph: targetParagraph || paragraphsInCells[0] || null,\r\n tableElement: tables[0]\r\n };\r\n}\r\n\r\n/**\r\n * Serializes one or more paragraphs without surrounding table wrappers.\r\n *\r\n * @param {Document} xmlDoc - XML document (unused, kept for signature compatibility)\r\n * @param {Element|Element[]} paragraphs - Paragraph or paragraph array\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @returns {string}\r\n */\r\nexport function serializeParagraphOnly(xmlDoc, paragraphs, serializer) {\r\n const paragraphArray = Array.isArray(paragraphs) ? paragraphs : [paragraphs];\r\n\r\n let combinedXml = '';\r\n for (const p of paragraphArray) {\r\n if (!p) continue;\r\n let pXml = serializer.serializeToString(p);\r\n pXml = pXml.replace(/\\s+xmlns:w=\"[^\"]*\"/g, '');\r\n pXml = pXml.replace(/\\s+xmlns:r=\"[^\"]*\"/g, '');\r\n pXml = pXml.replace(/\\s+xmlns:wp=\"[^\"]*\"/g, '');\r\n combinedXml += pXml;\r\n }\r\n\r\n log(`[OxmlEngine] Stripping table wrapper, serializing ${paragraphArray.length} paragraphs`);\r\n log(`[OxmlEngine] Paragraph XML preview: ${combinedXml.substring(0, 200)}...`);\r\n\r\n return wrapParagraphInPackage(combinedXml);\r\n}\r\n\r\n/**\r\n * Wraps paragraph XML in a complete OOXML package.\r\n *\r\n * @param {string} paragraphXml - Paragraph-only XML\r\n * @returns {string}\r\n */\r\nexport function wrapParagraphInPackage(paragraphXml) {\r\n return buildParagraphOnlyPackage(paragraphXml);\r\n}\r\n\r\n/**\r\n * Reads the best available paragraph identity from OOXML attributes.\r\n *\r\n * @param {Element} paragraph - Paragraph element\r\n * @returns {string|null}\r\n */\r\nfunction getParagraphId(paragraph) {\r\n if (!paragraph) return null;\r\n\r\n const namespacedId = typeof paragraph.getAttributeNS === 'function'\r\n ? paragraph.getAttributeNS(W14_NS, 'paraId')\r\n : null;\r\n if (namespacedId) return namespacedId;\r\n\r\n return paragraph.getAttribute('w14:paraId')\r\n || paragraph.getAttribute('w:paraId')\r\n || paragraph.getAttribute('paraId')\r\n || null;\r\n}\r\n", "/**\r\n * Surgical reconciliation mode.\r\n *\r\n * This mode performs in-place run-level edits and preserves existing structure,\r\n * making it safe for tables and other complex OOXML containers.\r\n */\r\n\r\nimport { getApplicableFormatHints } from '../pipeline/markdown-processor.js';\r\nimport { computeWordDiffs } from '../pipeline/diff-engine.js';\r\nimport { appendParagraphBoundary } from '../core/paragraph-offset-policy.js';\r\nimport { NS_W, getNextRevisionId } from '../core/types.js';\r\nimport { createSerializer } from '../adapters/xml-adapter.js';\r\nimport { getDocumentParagraphs } from './format-extraction.js';\nimport { buildOverrideRPrXml } from './rpr-helpers.js';\nimport { getFirstElementByTag } from '../core/xml-query.js';\nimport { getDefaultAuthor } from '../adapters/config.js';\nimport {\r\n createTrackChange,\r\n createTextRun,\r\n createFormattedRuns,\r\n createTextRunWithRPrElement,\r\n injectFormattingToRPr\r\n} from './run-builders.js';\r\n\r\n/**\r\n * Builds minimal OOXML for a surgical text replacement with track changes.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} originalRun - Original run\r\n * @param {string} textContent - Replacement text\r\n * @param {string} author - Author name\r\n * @param {string} dateStr - ISO date\r\n * @param {Object} formatToRemove - Format flags to force off\r\n * @returns {string}\r\n */\r\nfunction buildSurgicalReplacementOoxml(xmlDoc, originalRun, textContent, author, dateStr, formatToRemove) {\n const authorName = author || getDefaultAuthor();\n const delId = getNextRevisionId();\r\n const insId = getNextRevisionId();\r\n\r\n const serializer = createSerializer();\r\n\r\n let rPrXml = '';\r\n const rPr = getFirstElementByTag(originalRun, 'w:rPr');\r\n if (rPr) {\r\n rPrXml = serializer.serializeToString(rPr);\r\n rPrXml = rPrXml.replace(/\\s+xmlns:[^=]+=\"[^\"]*\"/g, '');\r\n }\r\n\r\n const unformattedRPrXml = buildOverrideRPrXml(xmlDoc, originalRun, formatToRemove, serializer);\r\n\r\n const escapedText = textContent\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>');\r\n\r\n const delFragment = `<w:del xmlns:w=\"${NS_W}\" w:id=\"${delId}\" w:author=\"${authorName}\" w:date=\"${dateStr}\">` +\r\n `<w:r>${rPrXml}<w:delText xml:space=\"preserve\">${escapedText}</w:delText></w:r>` +\r\n `</w:del>`;\r\n\r\n const insFragment = `<w:ins xmlns:w=\"${NS_W}\" w:id=\"${insId}\" w:author=\"${authorName}\" w:date=\"${dateStr}\">` +\r\n `<w:r>${unformattedRPrXml}<w:t xml:space=\"preserve\">${escapedText}</w:t></w:r>` +\r\n `</w:ins>`;\r\n\r\n return `${delFragment}${insFragment}`;\r\n}\r\n\r\n/**\r\n * Builds minimal OOXML for an unformatted run (without track wrappers).\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} originalRun - Original run\r\n * @param {string} textContent - Replacement text\r\n * @param {Object} formatToRemove - Format flags to force off\r\n * @returns {string}\r\n */\r\nfunction buildUnformattedRunOoxml(xmlDoc, originalRun, textContent, formatToRemove) {\r\n const serializer = createSerializer();\r\n const unformattedRPrXml = buildOverrideRPrXml(xmlDoc, originalRun, formatToRemove, serializer);\r\n\r\n const escapedText = textContent\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>');\r\n\r\n return `<w:r xmlns:w=\"${NS_W}\">${unformattedRPrXml}<w:t xml:space=\"preserve\">${escapedText}</w:t></w:r>`;\r\n}\r\n\r\n/**\r\n * Applies surgical mode reconciliation.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} originalText - Original text\r\n * @param {string} modifiedText - Modified text\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Author name\r\n * @param {Array} formatHints - Format hints\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @param {Element|null} [targetParagraph=null] - Optional scope paragraph\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applySurgicalMode(xmlDoc, originalText, modifiedText, serializer, author, formatHints, generateRedlines = true, targetParagraph = null) {\r\n let fullText = '';\r\n const textSpans = [];\r\n\r\n const allParagraphs = targetParagraph\r\n ? [targetParagraph]\r\n : getDocumentParagraphs(xmlDoc);\r\n\r\n allParagraphs.forEach((p, pIndex) => {\r\n const container = p.parentNode;\r\n\r\n for (let child = p.firstChild; child; child = child.nextSibling) {\r\n if (child.nodeName === 'w:r') {\r\n const runResult = processRunElement(child, p, container, fullText.length, textSpans);\r\n fullText += runResult.text;\r\n } else if (child.nodeName === 'w:hyperlink') {\r\n for (let hc = child.firstChild; hc; hc = hc.nextSibling) {\r\n if (hc.nodeName === 'w:r') {\r\n const runResult = processRunElement(hc, p, container, fullText.length, textSpans);\r\n fullText += runResult.text;\r\n }\r\n }\r\n }\r\n }\r\n\r\n fullText = appendParagraphBoundary(fullText, pIndex, allParagraphs.length);\r\n });\r\n\r\n const diffs = computeWordDiffs(fullText, modifiedText);\r\n const spanIndex = buildSpanIndex(textSpans);\r\n\r\n let originalPos = 0;\r\n let newPos = 0;\r\n const processedSpans = new Set();\r\n\r\n for (const [op, text] of diffs) {\r\n if (op === 0) {\r\n const len = text.length;\r\n const startPos = originalPos;\r\n const endPos = originalPos + len;\r\n\r\n forEachOverlappingSpan(spanIndex, startPos, endPos, span => {\r\n const overlapStartOriginal = Math.max(span.charStart, startPos);\r\n const overlapEndOriginal = Math.min(span.charEnd, endPos);\r\n const segmentLen = overlapEndOriginal - overlapStartOriginal;\r\n const relativeOffset = overlapStartOriginal - startPos;\r\n const overlapStartNew = newPos + relativeOffset;\r\n const overlapEndNew = overlapStartNew + segmentLen;\r\n const applicableHints = getApplicableFormatHints(formatHints, overlapStartNew, overlapEndNew);\r\n reconcileFormattingForTextSpan(xmlDoc, span, overlapStartOriginal, overlapEndOriginal, applicableHints, author, generateRedlines);\r\n });\r\n\r\n originalPos += len;\r\n newPos += len;\r\n } else if (op === -1) {\r\n processDelete(xmlDoc, spanIndex, originalPos, originalPos + text.length, processedSpans, author, generateRedlines);\r\n originalPos += text.length;\r\n } else if (op === 1) {\r\n const textWithoutNewlines = text.replace(/\\n/g, ' ');\r\n if (textWithoutNewlines.trim().length > 0) {\r\n processInsert(xmlDoc, spanIndex, originalPos, textWithoutNewlines, processedSpans, author, formatHints, newPos, generateRedlines);\r\n }\r\n newPos += text.length;\r\n }\r\n }\r\n\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: true };\r\n}\r\n\r\n/**\r\n * Reconciles formatting for a text span segment.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Object} span - Text span\r\n * @param {number} start - Absolute start\r\n * @param {number} end - Absolute end\r\n * @param {Array} applicableHints - Applicable format hints\r\n * @param {string} author - Author name\r\n * @param {boolean} generateRedlines - Track change toggle\r\n */\r\nfunction reconcileFormattingForTextSpan(xmlDoc, span, start, end, applicableHints, author, generateRedlines) {\r\n const desiredFormat = {};\r\n if (applicableHints.length > 0) {\r\n applicableHints.forEach(h => Object.assign(desiredFormat, h.format));\r\n }\r\n\r\n const rPr = span.rPr;\r\n const hasElement = (tagName) => {\r\n if (!rPr) return false;\r\n for (let node = rPr.firstChild; node; node = node.nextSibling) {\r\n if (node.nodeName === tagName) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n\r\n const existingFormat = {\r\n bold: hasElement('w:b'),\r\n italic: hasElement('w:i'),\r\n underline: hasElement('w:u'),\r\n strikethrough: hasElement('w:strike')\r\n };\r\n\r\n const formatsToCheck = ['bold', 'italic', 'underline', 'strikethrough'];\r\n const changesNeeded = formatsToCheck.some(f => !!desiredFormat[f] !== existingFormat[f]);\r\n\r\n if (!changesNeeded) return;\r\n\r\n const parent = span.runElement.parentNode;\r\n if (!parent) return;\r\n\r\n const fullText = span.textElement.textContent || '';\r\n const runStart = span.charStart;\r\n\r\n const localStart = start - runStart;\r\n const localEnd = end - runStart;\r\n\r\n const beforeText = fullText.substring(0, localStart);\r\n const affectedText = fullText.substring(localStart, localEnd);\r\n const afterText = fullText.substring(localEnd);\r\n\r\n if (beforeText.length > 0) {\r\n const beforeRun = createTextRun(xmlDoc, beforeText, rPr, false);\r\n parent.insertBefore(beforeRun, span.runElement);\r\n }\r\n\r\n const newRPr = injectFormattingToRPr(xmlDoc, rPr, desiredFormat, author, generateRedlines);\r\n const newRun = createTextRunWithRPrElement(xmlDoc, affectedText, newRPr, false);\r\n parent.insertBefore(newRun, span.runElement);\r\n\r\n if (afterText.length > 0) {\r\n const afterRun = createTextRun(xmlDoc, afterText, rPr, false);\r\n parent.insertBefore(afterRun, span.runElement);\r\n }\r\n\r\n parent.removeChild(span.runElement);\r\n}\r\n\r\n/**\r\n * Processes a run and appends text span metadata.\r\n *\r\n * @param {Element} r - Run element\r\n * @param {Element} p - Paragraph element\r\n * @param {Element} container - Parent container\r\n * @param {number} currentOffset - Absolute offset\r\n * @param {Array} textSpans - Span collection\r\n * @returns {{ nextOffset: number, text: string }}\r\n */\r\nfunction processRunElement(r, p, container, currentOffset, textSpans) {\r\n const rPr = getFirstElementByTag(r, 'w:rPr');\r\n let localOffset = currentOffset;\r\n const textParts = [];\r\n\r\n for (let rc = r.firstChild; rc; rc = rc.nextSibling) {\r\n if (rc.nodeName === 'w:t') {\r\n const text = rc.textContent || '';\r\n if (text.length > 0) {\r\n textSpans.push({\r\n charStart: localOffset,\r\n charEnd: localOffset + text.length,\r\n textElement: rc,\r\n runElement: r,\r\n paragraph: p,\r\n container,\r\n rPr\r\n });\r\n localOffset += text.length;\r\n textParts.push(text);\r\n }\r\n } else if (rc.nodeName === 'w:br' || rc.nodeName === 'w:cr') {\r\n textSpans.push({\r\n charStart: localOffset,\r\n charEnd: localOffset + 1,\r\n textElement: rc,\r\n runElement: r,\r\n paragraph: p,\r\n container,\r\n rPr\r\n });\r\n localOffset += 1;\r\n textParts.push('\\n');\r\n } else if (rc.nodeName === 'w:tab') {\r\n textSpans.push({\r\n charStart: localOffset,\r\n charEnd: localOffset + 1,\r\n textElement: rc,\r\n runElement: r,\r\n paragraph: p,\r\n container,\r\n rPr\r\n });\r\n localOffset += 1;\r\n textParts.push('\\t');\r\n } else if (rc.nodeName === 'w:noBreakHyphen') {\r\n textSpans.push({\r\n charStart: localOffset,\r\n charEnd: localOffset + 1,\r\n textElement: rc,\r\n runElement: r,\r\n paragraph: p,\r\n container,\r\n rPr\r\n });\r\n localOffset += 1;\r\n textParts.push('\\u2011');\r\n }\r\n }\r\n return { nextOffset: localOffset, text: textParts.join('') };\r\n}\r\n\r\n/**\r\n * Applies deletion over affected spans.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {{ spans: Array, starts: number[], ends: number[] }} spanIndex - Indexed spans\r\n * @param {number} startPos - Delete start\r\n * @param {number} endPos - Delete end\r\n * @param {Set<Node>} processedSpans - Processed marker set\r\n * @param {string} author - Author name\r\n * @param {boolean} generateRedlines - Track change toggle\r\n */\r\nfunction processDelete(xmlDoc, spanIndex, startPos, endPos, processedSpans, author, generateRedlines) {\r\n forEachOverlappingSpan(spanIndex, startPos, endPos, span => {\r\n if (processedSpans.has(span.textElement)) return;\r\n\r\n const deleteStart = Math.max(0, startPos - span.charStart);\r\n const deleteEnd = Math.min(span.charEnd - span.charStart, endPos - span.charStart);\r\n\r\n const originalText = span.textElement.textContent || '';\r\n const beforeText = originalText.substring(0, deleteStart);\r\n const deletedText = originalText.substring(deleteStart, deleteEnd);\r\n const afterText = originalText.substring(deleteEnd);\r\n\r\n if (deletedText.length === 0) return;\r\n\r\n const parent = span.runElement.parentNode;\r\n if (!parent) return;\r\n\r\n if (beforeText.length === 0 && afterText.length === 0) {\r\n const delRun = createTextRun(xmlDoc, deletedText, span.rPr, true);\r\n if (generateRedlines) {\r\n const delWrapper = createTrackChange(xmlDoc, 'del', delRun, author);\r\n parent.insertBefore(delWrapper, span.runElement);\r\n }\r\n parent.removeChild(span.runElement);\r\n } else {\r\n const oldRun = span.runElement;\r\n\r\n if (beforeText.length > 0) {\r\n const beforeRun = createTextRun(xmlDoc, beforeText, span.rPr, false);\r\n parent.insertBefore(beforeRun, oldRun);\r\n }\r\n\r\n const delRun = createTextRun(xmlDoc, deletedText, span.rPr, true);\r\n if (generateRedlines) {\r\n const delWrapper = createTrackChange(xmlDoc, 'del', delRun, author);\r\n parent.insertBefore(delWrapper, oldRun);\r\n }\r\n\r\n if (afterText.length > 0) {\r\n const afterRun = createTextRun(xmlDoc, afterText, span.rPr, false);\r\n parent.insertBefore(afterRun, oldRun);\r\n span.runElement = afterRun;\r\n span.textElement = getFirstElementByTag(afterRun, 'w:t') || getFirstElementByTag(afterRun, 't');\r\n }\r\n\r\n parent.removeChild(oldRun);\r\n }\r\n\r\n processedSpans.add(span.textElement);\r\n });\r\n}\r\n\r\n/**\r\n * Inserts new text at an absolute position.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {{ spans: Array, starts: number[], ends: number[] }} spanIndex - Indexed spans\r\n * @param {number} pos - Insertion position\r\n * @param {string} text - Text to insert\r\n * @param {Set<Node>} processedSpans - Processed marker set (unused, kept for signature)\r\n * @param {string} author - Author name\r\n * @param {Array} [formatHints=[]] - Format hints\r\n * @param {number} [insertOffset=0] - Offset in modified text\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n */\r\nfunction processInsert(xmlDoc, spanIndex, pos, text, processedSpans, author, formatHints = [], insertOffset = 0, generateRedlines = true) {\r\n void processedSpans;\r\n\r\n let targetSpan = findContainingSpan(spanIndex, pos);\r\n\r\n if (!targetSpan && pos > 0) {\r\n targetSpan = findFirstSpanEndingAt(spanIndex, pos);\r\n }\r\n\r\n if (!targetSpan && pos > 0) {\r\n targetSpan = findLastSpanEndingBeforeOrAt(spanIndex, pos);\r\n }\r\n\r\n if (!targetSpan && spanIndex.spans.length > 0) {\r\n targetSpan = spanIndex.spans[spanIndex.spans.length - 1];\r\n }\r\n\r\n if (targetSpan) {\r\n const applicableHints = getApplicableFormatHints(formatHints, insertOffset, insertOffset + text.length);\r\n const baseRPr = targetSpan.rPr;\r\n const parent = targetSpan.runElement.parentNode;\r\n\r\n if (parent) {\r\n const referenceNode = (pos === targetSpan.charStart) ? targetSpan.runElement : targetSpan.runElement.nextSibling;\r\n\r\n if (applicableHints.length === 0) {\r\n const insRun = createTextRun(xmlDoc, text, baseRPr, false);\r\n if (generateRedlines) {\r\n const insWrapper = createTrackChange(xmlDoc, 'ins', insRun, author);\r\n parent.insertBefore(insWrapper, referenceNode);\r\n } else {\r\n parent.insertBefore(insRun, referenceNode);\r\n }\r\n } else {\r\n const runs = createFormattedRuns(xmlDoc, text, baseRPr, applicableHints, insertOffset, author, generateRedlines);\r\n\r\n if (generateRedlines) {\r\n const insWrapper = createTrackChange(xmlDoc, 'ins', null, author);\r\n runs.forEach(run => insWrapper.appendChild(run));\r\n parent.insertBefore(insWrapper, referenceNode);\r\n } else {\r\n runs.forEach(run => parent.insertBefore(run, referenceNode));\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction buildSpanIndex(textSpans) {\r\n const spans = textSpans\r\n .slice()\r\n .sort((a, b) => a.charStart - b.charStart || a.charEnd - b.charEnd);\r\n\r\n const starts = spans.map(span => span.charStart);\r\n const ends = spans.map(span => span.charEnd);\r\n\r\n return { spans, starts, ends };\r\n}\r\n\r\nfunction upperBound(values, target) {\r\n let left = 0;\r\n let right = values.length;\r\n\r\n while (left < right) {\r\n const middle = (left + right) >> 1;\r\n if (values[middle] <= target) {\r\n left = middle + 1;\r\n } else {\r\n right = middle;\r\n }\r\n }\r\n\r\n return left;\r\n}\r\n\r\nfunction lowerBound(values, target) {\r\n let left = 0;\r\n let right = values.length;\r\n\r\n while (left < right) {\r\n const middle = (left + right) >> 1;\r\n if (values[middle] < target) {\r\n left = middle + 1;\r\n } else {\r\n right = middle;\r\n }\r\n }\r\n\r\n return left;\r\n}\r\n\r\nfunction forEachOverlappingSpan(spanIndex, startPos, endPos, callback) {\r\n if (endPos <= startPos || spanIndex.spans.length === 0) {\r\n return;\r\n }\r\n\r\n let index = upperBound(spanIndex.ends, startPos);\r\n while (index < spanIndex.spans.length) {\r\n const span = spanIndex.spans[index];\r\n if (span.charStart >= endPos) {\r\n break;\r\n }\r\n callback(span);\r\n index++;\r\n }\r\n}\r\n\r\nfunction findContainingSpan(spanIndex, pos) {\r\n if (spanIndex.spans.length === 0) return null;\r\n\r\n const index = upperBound(spanIndex.starts, pos) - 1;\r\n if (index < 0) return null;\r\n\r\n const span = spanIndex.spans[index];\r\n return pos >= span.charStart && pos < span.charEnd ? span : null;\r\n}\r\n\r\nfunction findFirstSpanEndingAt(spanIndex, pos) {\r\n const index = lowerBound(spanIndex.ends, pos);\r\n if (index < spanIndex.spans.length && spanIndex.ends[index] === pos) {\r\n return spanIndex.spans[index];\r\n }\r\n return null;\r\n}\r\n\r\nfunction findLastSpanEndingBeforeOrAt(spanIndex, pos) {\r\n const index = upperBound(spanIndex.ends, pos) - 1;\r\n if (index >= 0) {\r\n return spanIndex.spans[index];\r\n }\r\n return null;\r\n}\r\n", "/**\r\n * Reconstruction mapper.\r\n *\r\n * Builds paragraph/property/sentinel mappings and indexed lookups used by reconstruction writing.\r\n */\r\n\r\nimport { appendParagraphBoundary } from '../core/paragraph-offset-policy.js';\r\nimport { getDocumentParagraphs } from './format-extraction.js';\r\nimport { getElementsByTag, getFirstElementByTag } from '../core/xml-query.js';\r\n\r\nfunction createRangeCursorLookup(ranges) {\r\n let cursor = 0;\r\n return {\r\n at(index) {\r\n while (cursor < ranges.length && ranges[cursor].end <= index) {\r\n cursor++;\r\n }\r\n const match = ranges[cursor];\r\n if (!match) return null;\r\n if (match.start <= index && index < match.end) return match;\r\n return null;\r\n }\r\n };\r\n}\r\n\r\nfunction indexSentinelsByStart(sentinelMap) {\r\n const sentinelMapByStart = new Map();\r\n sentinelMap.forEach(sentinel => {\r\n if (!sentinelMapByStart.has(sentinel.start)) {\r\n sentinelMapByStart.set(sentinel.start, []);\r\n }\r\n sentinelMapByStart.get(sentinel.start).push(sentinel);\r\n });\r\n return sentinelMapByStart;\r\n}\r\n\r\n/**\r\n * Builds reconstruction mapping and cursor-based lookup helpers.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} modifiedText - Modified text\r\n * @returns {{\r\n * paragraphs: Element[],\r\n * body: Element|Document,\r\n * paragraphMap: Array<{start:number,end:number,pPr:Element|null,container:Node}>,\r\n * paragraphStarts: Set<number>,\r\n * propertyMap: Array<{start:number,end:number,rPr:Element|null,wrapper?:Element}>,\r\n * sentinelMap: Array<Object>,\r\n * sentinelMapByStart: Map<number, Object[]>,\r\n * referenceMap: Map<string, Node>,\r\n * tokenToCharMap: Map<string, string>,\r\n * containerFragments: Map<Node, DocumentFragment>,\r\n * replacementContainers: Map<Node, Node>,\r\n * originalFullText: string,\r\n * processedModifiedText: string,\r\n * getParagraphInfo: (index:number) => {start:number,end:number,pPr:Element|null,container:Node},\r\n * getRunProperties: (index:number) => {rPr:Element|null,wrapper?:Element},\r\n * getPropertySpanLength: (index:number,maxLength:number) => number,\r\n * isParagraphStart: (index:number) => boolean\r\n * }}\r\n */\r\nexport function buildReconstructionMapping(xmlDoc, modifiedText) {\r\n const rootElement = xmlDoc.documentElement;\r\n const isBodyRoot = rootElement.nodeName === 'w:body' || rootElement.nodeName.endsWith(':package');\r\n const paragraphs = getDocumentParagraphs(xmlDoc);\r\n\r\n let body = getFirstElementByTag(xmlDoc, 'w:body');\r\n if (!body && isBodyRoot) body = rootElement;\r\n\r\n let originalFullText = '';\r\n const propertyMap = [];\r\n const paragraphMap = [];\r\n const sentinelMap = [];\r\n const referenceMap = new Map();\r\n const tokenToCharMap = new Map();\r\n let nextCharCode = 0xe000;\r\n const uniqueContainers = new Set();\r\n\r\n paragraphs.forEach((paragraph, paragraphIndex) => {\r\n const paragraphStart = originalFullText.length;\r\n\r\n Array.from(paragraph.childNodes).forEach(child => {\r\n originalFullText = processChildNode(\r\n child,\r\n originalFullText,\r\n propertyMap,\r\n sentinelMap,\r\n referenceMap,\r\n tokenToCharMap,\r\n nextCharCode\r\n );\r\n if (referenceMap.size > tokenToCharMap.size) {\r\n nextCharCode++;\r\n }\r\n });\r\n\r\n originalFullText = appendParagraphBoundary(originalFullText, paragraphIndex, paragraphs.length);\r\n\r\n const paragraphEnd = originalFullText.length;\r\n const pPr = getFirstElementByTag(paragraph, 'w:pPr');\r\n const container = paragraph.parentNode;\r\n if (container) uniqueContainers.add(container);\r\n\r\n paragraphMap.push({\r\n start: paragraphStart,\r\n end: paragraphEnd,\r\n pPr,\r\n container: container || body\r\n });\r\n });\r\n\r\n let processedModifiedText = modifiedText;\r\n tokenToCharMap.forEach((char, tokenString) => {\r\n const escapedToken = tokenString.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\r\n processedModifiedText = processedModifiedText.replace(new RegExp(escapedToken, 'g'), char);\r\n });\r\n\r\n const containerFragments = new Map();\r\n uniqueContainers.forEach(container => {\r\n containerFragments.set(container, xmlDoc.createDocumentFragment());\r\n });\r\n if (body && !containerFragments.has(body)) {\r\n containerFragments.set(body, xmlDoc.createDocumentFragment());\r\n }\r\n if (!containerFragments.has(xmlDoc)) {\r\n containerFragments.set(xmlDoc, xmlDoc.createDocumentFragment());\r\n }\r\n\r\n const replacementContainers = new Map();\r\n const paragraphStarts = new Set(paragraphMap.map(paragraph => paragraph.start));\r\n const paragraphLookup = createRangeCursorLookup(paragraphMap);\r\n const propertyLookup = createRangeCursorLookup(propertyMap);\r\n const sentinelMapByStart = indexSentinelsByStart(sentinelMap);\r\n\r\n const getParagraphInfo = (index) => {\r\n const match = paragraphLookup.at(index);\r\n if (match) return match;\r\n if (paragraphMap.length > 0) return paragraphMap[paragraphMap.length - 1];\r\n return { start: 0, end: 0, pPr: null, container: body || xmlDoc };\r\n };\r\n\r\n const getRunProperties = (index) => {\r\n const match = propertyLookup.at(index);\r\n return match ? { rPr: match.rPr, wrapper: match.wrapper } : { rPr: null };\r\n };\r\n\r\n const getPropertySpanLength = (index, maxLength) => {\r\n const match = propertyLookup.at(index);\r\n if (!match) return 1;\r\n return Math.min(match.end - index, maxLength);\r\n };\r\n\r\n return {\r\n paragraphs,\r\n body: body || xmlDoc,\r\n paragraphMap,\r\n paragraphStarts,\r\n propertyMap,\r\n sentinelMap,\r\n sentinelMapByStart,\r\n referenceMap,\r\n tokenToCharMap,\r\n containerFragments,\r\n replacementContainers,\r\n originalFullText,\r\n processedModifiedText,\r\n getParagraphInfo,\r\n getRunProperties,\r\n getPropertySpanLength,\r\n isParagraphStart: index => paragraphStarts.has(index)\r\n };\r\n}\r\n\r\nfunction processChildNode(child, originalFullText, propertyMap, sentinelMap, referenceMap, tokenToCharMap, nextCharCode) {\r\n if (child.nodeName === 'w:r') {\r\n return processRunForReconstruction(child, originalFullText, propertyMap, sentinelMap, referenceMap, tokenToCharMap, nextCharCode);\r\n }\r\n if (child.nodeName === 'w:hyperlink') {\r\n return processHyperlinkForReconstruction(child, originalFullText, propertyMap);\r\n }\r\n if (['w:sdt', 'w:oMath', 'm:oMath', 'w:bookmarkStart', 'w:bookmarkEnd'].includes(child.nodeName)) {\r\n sentinelMap.push({ start: originalFullText.length, node: child });\r\n return originalFullText + '\\uFFFC';\r\n }\r\n if (['w:commentRangeStart', 'w:commentRangeEnd'].includes(child.nodeName)) {\r\n sentinelMap.push({ start: originalFullText.length, node: child, isCommentMarker: true });\r\n return originalFullText;\r\n }\r\n return originalFullText;\r\n}\r\n\r\nfunction processRunForReconstruction(runElement, originalFullText, propertyMap, sentinelMap, referenceMap, tokenToCharMap, nextCharCode) {\r\n let fullText = originalFullText;\r\n const rPr = getFirstElementByTag(runElement, 'w:rPr');\r\n\r\n Array.from(runElement.childNodes).forEach(runChild => {\r\n if (runChild.nodeName === 'w:t') {\r\n const textContent = runChild.textContent || '';\r\n if (textContent.length > 0) {\r\n propertyMap.push({\r\n start: fullText.length,\r\n end: fullText.length + textContent.length,\r\n rPr\r\n });\r\n fullText += textContent;\r\n }\r\n } else if (runChild.nodeName === 'w:br' || runChild.nodeName === 'w:cr') {\r\n fullText += '\\n';\r\n propertyMap.push({ start: fullText.length - 1, end: fullText.length, rPr });\r\n } else if (runChild.nodeName === 'w:tab') {\r\n fullText += '\\t';\r\n propertyMap.push({ start: fullText.length - 1, end: fullText.length, rPr });\r\n } else if (runChild.nodeName === 'w:noBreakHyphen') {\r\n fullText += '\\u2011';\r\n propertyMap.push({ start: fullText.length - 1, end: fullText.length, rPr });\r\n } else if (['w:drawing', 'w:pict', 'w:object', 'w:fldChar', 'w:instrText', 'w:sym'].includes(runChild.nodeName)) {\r\n const textBoxContent = getFirstElementByTag(runChild, 'w:txbxContent');\r\n const hasTextBox = runChild.nodeName === 'w:pict' && !!textBoxContent;\r\n\r\n sentinelMap.push({\r\n start: fullText.length,\r\n node: runChild,\r\n isTextBox: hasTextBox,\r\n originalContainer: hasTextBox ? textBoxContent : undefined\r\n });\r\n fullText += '\\uFFFC';\r\n propertyMap.push({ start: fullText.length - 1, end: fullText.length, rPr });\r\n } else if (runChild.nodeName === 'w:footnoteReference' || runChild.nodeName === 'w:endnoteReference') {\r\n const id = runChild.getAttribute('w:id');\r\n if (id) {\r\n const type = runChild.nodeName === 'w:footnoteReference' ? 'FN' : 'EN';\r\n const tokenString = `{{__${type}_${id}__}}`;\r\n const char = String.fromCharCode(nextCharCode);\r\n referenceMap.set(char, runChild);\r\n tokenToCharMap.set(tokenString, char);\r\n fullText += char;\r\n propertyMap.push({ start: fullText.length - 1, end: fullText.length, rPr });\r\n }\r\n } else if (runChild.nodeName === 'w:commentReference') {\r\n sentinelMap.push({ start: fullText.length, node: runChild, isCommentMarker: true });\r\n }\r\n });\r\n\r\n return fullText;\r\n}\r\n\r\nfunction processHyperlinkForReconstruction(hyperlinkElement, originalFullText, propertyMap) {\r\n let fullText = originalFullText;\r\n\r\n Array.from(hyperlinkElement.childNodes).forEach(hyperlinkChild => {\r\n if (hyperlinkChild.nodeName !== 'w:r') return;\r\n\r\n const rPr = getFirstElementByTag(hyperlinkChild, 'w:rPr');\r\n const texts = getElementsByTag(hyperlinkChild, 'w:t');\r\n texts.forEach(textNode => {\r\n const textContent = textNode.textContent || '';\r\n if (textContent.length === 0) return;\r\n\r\n propertyMap.push({\r\n start: fullText.length,\r\n end: fullText.length + textContent.length,\r\n rPr,\r\n wrapper: hyperlinkElement\r\n });\r\n fullText += textContent;\r\n });\r\n });\r\n\r\n return fullText;\r\n}\r\n", "/**\r\n * Reconstruction writer.\r\n *\r\n * Applies diff segments to mapped reconstruction context and writes updated DOM content.\r\n */\r\n\r\nimport { getApplicableFormatHints } from '../pipeline/markdown-processor.js';\r\nimport { createTrackChange, createFormattedRuns } from './run-builders.js';\r\nimport { getFirstElementByTag } from '../core/xml-query.js';\r\n\r\n/**\r\n * Applies diffs to reconstruction context and writes updated XML.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Array<[number, string]>} diffs - Diff tuples from diff-match-patch\r\n * @param {ReturnType<import('./reconstruction-mapper.js').buildReconstructionMapping>} context - Reconstruction mapping\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Author name\r\n * @param {Array} formatHints - Format hints\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applyReconstructionDiffs(xmlDoc, diffs, context, serializer, author, formatHints, generateRedlines = true) {\r\n const {\r\n paragraphs,\r\n paragraphMap,\r\n containerFragments,\r\n sentinelMapByStart,\r\n referenceMap,\r\n replacementContainers,\r\n getParagraphInfo,\r\n getRunProperties,\r\n getPropertySpanLength,\r\n isParagraphStart\r\n } = context;\r\n\r\n const createNewParagraph = (pPr) => {\r\n const newParagraph = xmlDoc.createElement('w:p');\r\n if (pPr) newParagraph.appendChild(pPr.cloneNode(true));\r\n return newParagraph;\r\n };\r\n\r\n const startInfo = getParagraphInfo(0);\r\n let currentParagraph = createNewParagraph(startInfo.pPr);\r\n const initialFragment = containerFragments.get(startInfo.container);\r\n if (initialFragment) {\r\n initialFragment.appendChild(currentParagraph);\r\n }\r\n\r\n let currentOriginalIndex = 0;\r\n let currentInsertOffset = 0;\r\n\r\n for (const [op, text] of diffs) {\r\n if (op === 0 || op === -1) {\r\n const type = op === 0 ? 'equal' : 'delete';\r\n let offset = 0;\r\n\r\n while (offset < text.length) {\r\n const chunkStart = currentOriginalIndex + offset;\r\n const properties = getRunProperties(chunkStart);\r\n const chunkLength = getPropertySpanLength(chunkStart, text.length - offset);\r\n const chunk = text.substring(offset, offset + chunkLength);\r\n\r\n appendTextToCurrent(\r\n xmlDoc,\r\n chunk,\r\n type,\r\n properties.rPr,\r\n properties.wrapper,\r\n chunkStart,\r\n currentParagraph,\r\n containerFragments,\r\n sentinelMapByStart,\r\n referenceMap,\r\n replacementContainers,\r\n getParagraphInfo,\r\n createNewParagraph,\r\n author,\r\n formatHints,\r\n currentInsertOffset,\r\n generateRedlines\r\n );\r\n\r\n if (op === 0) {\r\n currentInsertOffset += chunkLength;\r\n }\r\n offset += chunkLength;\r\n }\r\n\r\n currentOriginalIndex += text.length;\r\n continue;\r\n }\r\n\r\n if (op === 1) {\r\n const properties = currentOriginalIndex > 0 && !isParagraphStart(currentOriginalIndex)\r\n ? getRunProperties(currentOriginalIndex - 1)\r\n : getRunProperties(currentOriginalIndex);\r\n\r\n appendTextToCurrent(\r\n xmlDoc,\r\n text,\r\n 'insert',\r\n properties.rPr,\r\n properties.wrapper,\r\n currentOriginalIndex,\r\n currentParagraph,\r\n containerFragments,\r\n sentinelMapByStart,\r\n referenceMap,\r\n replacementContainers,\r\n getParagraphInfo,\r\n createNewParagraph,\r\n author,\r\n formatHints,\r\n currentInsertOffset,\r\n generateRedlines\r\n );\r\n currentInsertOffset += text.length;\r\n }\r\n }\r\n\r\n paragraphs.forEach(paragraph => {\r\n if (paragraph.parentNode) {\r\n paragraph.parentNode.removeChild(paragraph);\r\n }\r\n });\r\n\r\n containerFragments.forEach((fragment, container) => {\r\n const replacement = replacementContainers.get(container);\r\n const target = replacement || container;\r\n\r\n if (target.nodeType === 9) {\r\n const firstChild = fragment.firstChild;\r\n if (firstChild) {\r\n target.appendChild(firstChild);\r\n while (fragment.firstChild) {\r\n target.documentElement.appendChild(fragment.firstChild);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n target.appendChild(fragment);\r\n });\r\n\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: true };\r\n}\r\n\r\nfunction appendTextToCurrent(\r\n xmlDoc,\r\n text,\r\n type,\r\n rPr,\r\n wrapper,\r\n baseIndex,\r\n currentParagraphRef,\r\n containerFragments,\r\n sentinelMapByStart,\r\n referenceMap,\r\n replacementContainers,\r\n getParagraphInfo,\r\n createNewParagraph,\r\n author,\r\n formatHints = [],\r\n insertOffset = 0,\r\n generateRedlines = true\r\n) {\r\n let localBaseIndex = baseIndex;\r\n let localInsertOffset = insertOffset;\r\n let localParagraph = currentParagraphRef;\r\n\r\n const parts = text.split(/([\\n\\uFFFC]|[\\uE000-\\uF8FF])/);\r\n\r\n parts.forEach(part => {\r\n const sentinelsAtOffset = sentinelMapByStart.get(localBaseIndex) || [];\r\n const commentMarkers = sentinelsAtOffset.filter(sentinel => sentinel.isCommentMarker);\r\n\r\n commentMarkers.forEach(marker => {\r\n if (marker.node.nodeName === 'w:commentReference') {\r\n const run = xmlDoc.createElement('w:r');\r\n run.appendChild(marker.node.cloneNode(true));\r\n localParagraph.appendChild(run);\r\n } else {\r\n localParagraph.appendChild(marker.node.cloneNode(true));\r\n }\r\n });\r\n\r\n if (part === '\\n') {\r\n if (type !== 'delete') {\r\n const info = getParagraphInfo(localBaseIndex);\r\n const nextParagraph = createNewParagraph(info.pPr);\r\n const fragment = containerFragments.get(info.container);\r\n if (fragment) {\r\n fragment.appendChild(nextParagraph);\r\n localParagraph = nextParagraph;\r\n }\r\n }\r\n localBaseIndex++;\r\n if (type !== 'delete') localInsertOffset++;\r\n return;\r\n }\r\n\r\n if (part === '\\uFFFC') {\r\n const sentinel = sentinelsAtOffset.find(entry => !entry.isCommentMarker) || sentinelsAtOffset[0];\r\n if (sentinel) {\r\n const clone = sentinel.node.cloneNode(true);\r\n if (sentinel.isTextBox && sentinel.originalContainer) {\r\n const newContainer = getFirstElementByTag(clone, 'w:txbxContent');\r\n if (newContainer) {\r\n while (newContainer.firstChild) newContainer.removeChild(newContainer.firstChild);\r\n replacementContainers.set(sentinel.originalContainer, newContainer);\r\n }\r\n }\r\n localParagraph.appendChild(clone);\r\n }\r\n localBaseIndex++;\r\n if (type !== 'delete') localInsertOffset++;\r\n return;\r\n }\r\n\r\n if (referenceMap.has(part)) {\r\n if (type !== 'delete') {\r\n const refNode = referenceMap.get(part);\r\n if (refNode) {\r\n const clone = refNode.cloneNode(true);\r\n const run = xmlDoc.createElement('w:r');\r\n if (rPr) run.appendChild(rPr.cloneNode(true));\r\n run.appendChild(clone);\r\n localParagraph.appendChild(run);\r\n }\r\n }\r\n localBaseIndex++;\r\n if (type !== 'delete') localInsertOffset++;\r\n return;\r\n }\r\n\r\n if (part.length === 0) return;\r\n\r\n let parent = localParagraph;\r\n if (wrapper) {\r\n const wrapperClone = wrapper.cloneNode(false);\r\n parent = wrapperClone;\r\n localParagraph.appendChild(wrapperClone);\r\n }\r\n\r\n if (type === 'delete') {\r\n const run = xmlDoc.createElement('w:r');\r\n if (rPr) run.appendChild(rPr.cloneNode(true));\r\n const delText = xmlDoc.createElement('w:delText');\r\n delText.setAttribute('xml:space', 'preserve');\r\n delText.textContent = part;\r\n run.appendChild(delText);\r\n\r\n if (generateRedlines) {\r\n const del = createTrackChange(xmlDoc, 'del', run, author);\r\n parent.appendChild(del);\r\n }\r\n } else {\r\n const applicableHints = getApplicableFormatHints(formatHints, localInsertOffset, localInsertOffset + part.length);\r\n const runs = createFormattedRuns(xmlDoc, part, rPr, applicableHints, localInsertOffset, author, generateRedlines);\r\n\r\n if (type === 'insert' && generateRedlines) {\r\n const ins = createTrackChange(xmlDoc, 'ins', null, author);\r\n runs.forEach(run => ins.appendChild(run));\r\n parent.appendChild(ins);\r\n } else {\r\n runs.forEach(run => parent.appendChild(run));\r\n }\r\n }\r\n\r\n if (type !== 'delete') {\r\n localInsertOffset += part.length;\r\n }\r\n localBaseIndex += part.length;\r\n });\r\n}\r\n", "/**\n * Reconstruction reconciliation mode orchestration.\n */\n\nimport { computeWordDiffs } from '../pipeline/diff-engine.js';\nimport { buildReconstructionMapping } from './reconstruction-mapper.js';\nimport { applyReconstructionDiffs } from './reconstruction-writer.js';\n\r\n/**\r\n * Applies reconstruction mode reconciliation.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} originalText - Original text (kept for signature compatibility)\r\n * @param {string} modifiedText - Modified text\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {string} author - Author name\r\n * @param {Array} formatHints - Format hints\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applyReconstructionMode(xmlDoc, originalText, modifiedText, serializer, author, formatHints, generateRedlines = true) {\r\n const mapping = buildReconstructionMapping(xmlDoc, modifiedText);\r\n if (mapping.paragraphs.length === 0) {\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: false };\r\n }\r\n\r\n const diffs = computeWordDiffs(mapping.originalFullText, mapping.processedModifiedText);\n\n return applyReconstructionDiffs(\n xmlDoc,\n diffs,\r\n mapping,\r\n serializer,\r\n author,\r\n formatHints,\r\n generateRedlines\r\n );\r\n}\r\n", "/**\r\n * Table-specific reconciliation and transformation flows.\r\n */\r\n\r\nimport { NS_W, getNextRevisionId, getRevisionTimestamp } from '../core/types.js';\r\nimport {\r\n getElementsByTag,\r\n getElementsByTagNS,\r\n getFirstElementByTag,\r\n getFirstElementByTagNS,\r\n getXmlParseError\r\n} from '../core/xml-query.js';\r\nimport { createParser } from '../adapters/xml-adapter.js';\r\nimport { log, error } from '../adapters/logger.js';\r\nimport { diffTablesWithVirtualGrid, serializeVirtualGridToOoxml, generateTableOoxml } from '../services/table-reconciliation.js';\r\nimport { parseTable } from '../pipeline/pipeline.js';\r\nimport { ingestTableToVirtualGrid } from '../pipeline/ingestion.js';\r\n\r\nfunction noChanges(serializer, xmlDoc) {\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: false };\r\n}\r\n\r\n/**\r\n * Applies structural reconciliation to tables using Virtual Grid.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} modifiedText - Markdown/target table text\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {DOMParser} parser - Parser instance\r\n * @param {string} author - Author name\r\n * @param {boolean} [generateRedlines=true] - Track change toggle\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applyTableReconciliation(xmlDoc, modifiedText, serializer, parser, author, generateRedlines = true) {\r\n const tableNodes = getElementsByTag(xmlDoc, 'w:tbl');\r\n const newTableData = parseTable(modifiedText);\r\n const hasNewContent = newTableData.rows.length > 0 || newTableData.headers.length > 0;\r\n\r\n if (tableNodes.length === 0 || !hasNewContent) {\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n const targetTable = tableNodes[0];\r\n const oldGrid = ingestTableToVirtualGrid(targetTable);\r\n const operations = diffTablesWithVirtualGrid(oldGrid, newTableData);\r\n\r\n if (operations.length === 0) {\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n const options = { generateRedlines, author };\r\n const reconciledOxml = serializeVirtualGridToOoxml(oldGrid, operations, options);\r\n const wrappedOxml = `<root xmlns:w=\"${NS_W}\">${reconciledOxml}</root>`;\r\n const reconcileParser = parser || createParser();\r\n const reconciledDoc = reconcileParser.parseFromString(wrappedOxml, 'application/xml');\r\n\r\n const parseError = getXmlParseError(reconciledDoc);\r\n if (parseError) {\r\n error('[OxmlEngine] Failed to parse reconciled table OOXML:', parseError.textContent);\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n const newTableNode = getFirstElementByTag(reconciledDoc, 'w:tbl');\r\n if (!newTableNode) {\r\n error('[OxmlEngine] No table found in reconciled OOXML');\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n const importedTable = xmlDoc.importNode(newTableNode, true);\r\n targetTable.parentNode.replaceChild(importedTable, targetTable);\r\n\r\n return { oxml: serializer.serializeToString(xmlDoc), hasChanges: true };\r\n}\r\n\r\n/**\r\n * Transforms paragraph content into a new table from Markdown text.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {string} modifiedText - Markdown table text\r\n * @param {XMLSerializer} serializer - Serializer instance\r\n * @param {DOMParser} parser - Parser instance\r\n * @param {string} author - Author name\r\n * @param {boolean} generateRedlines - Track change toggle\r\n * @returns {{ oxml: string, hasChanges: boolean }}\r\n */\r\nexport function applyTextToTableTransformation(xmlDoc, modifiedText, serializer, parser, author, generateRedlines) {\r\n const tableData = parseTable(modifiedText);\r\n if (!tableData || (tableData.rows.length === 0 && tableData.headers.length === 0)) {\r\n log('[OxmlEngine] Failed to parse table data from Markdown');\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n const tableOoxml = generateTableOoxml(tableData, { generateRedlines, author });\r\n const activeParser = parser || createParser();\r\n const tableDoc = activeParser.parseFromString(`<root xmlns:w=\"${NS_W}\">${tableOoxml}</root>`, 'application/xml');\r\n\r\n const tableParseError = getXmlParseError(tableDoc);\r\n if (tableParseError) {\r\n error('[OxmlEngine] Failed to parse generated table OOXML:', tableParseError.textContent);\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n let newTableElement = getFirstElementByTagNS(tableDoc, NS_W, 'tbl');\r\n if (!newTableElement) {\r\n newTableElement = getFirstElementByTagNS(tableDoc, NS_W, 'ins');\r\n }\r\n if (!newTableElement) {\r\n error('[OxmlEngine] No table element found in generated OOXML');\r\n return noChanges(serializer, xmlDoc);\r\n }\r\n\r\n let workingDoc = xmlDoc;\r\n let paragraphs = getElementsByTagNS(workingDoc, NS_W, 'p');\r\n if (paragraphs.length === 0) {\r\n log('[OxmlEngine] No paragraphs found to replace');\r\n return noChanges(serializer, workingDoc);\r\n }\r\n\r\n let firstParagraph = paragraphs[0];\r\n let parent = firstParagraph.parentNode;\r\n\r\n if (parent && parent.nodeType === 9) {\r\n const wrappedDoc = activeParser.parseFromString(\r\n `<w:document xmlns:w=\"${NS_W}\"><w:body/></w:document>`,\r\n 'application/xml'\r\n );\r\n const wrappedBody = getFirstElementByTagNS(wrappedDoc, NS_W, 'body');\r\n paragraphs.forEach(p => wrappedBody.appendChild(wrappedDoc.importNode(p, true)));\r\n\r\n workingDoc = wrappedDoc;\r\n paragraphs = getElementsByTagNS(workingDoc, NS_W, 'p');\r\n firstParagraph = paragraphs[0];\r\n parent = firstParagraph.parentNode;\r\n }\r\n\r\n const importedTable = workingDoc.importNode(newTableElement, true);\r\n\r\n if (generateRedlines) {\r\n const date = getRevisionTimestamp();\r\n paragraphs.forEach(p => {\r\n const runs = getElementsByTagNS(p, NS_W, 'r');\r\n runs.forEach(run => {\r\n const textNodes = getElementsByTagNS(run, NS_W, 't');\r\n textNodes.forEach(t => {\r\n const text = t.textContent || '';\r\n if (text.trim()) {\r\n const delText = workingDoc.createElementNS(NS_W, 'w:delText');\r\n delText.textContent = text;\r\n t.parentNode.replaceChild(delText, t);\r\n }\r\n });\r\n\r\n const del = workingDoc.createElementNS(NS_W, 'w:del');\r\n del.setAttribute('w:id', String(getNextRevisionId()));\r\n del.setAttribute('w:author', author);\r\n del.setAttribute('w:date', date);\r\n run.parentNode.insertBefore(del, run);\r\n del.appendChild(run);\r\n });\r\n });\r\n } else {\r\n paragraphs.slice(1).forEach(p => p.parentNode.removeChild(p));\r\n }\r\n\r\n parent.insertBefore(importedTable, firstParagraph);\r\n if (!generateRedlines) {\r\n parent.removeChild(firstParagraph);\r\n }\r\n\r\n log('[OxmlEngine] Text-to-table transformation complete');\r\n return { oxml: serializer.serializeToString(workingDoc), hasChanges: true };\r\n}\r\n", "/**\r\n * OOXML Engine V5.1 - Hybrid Mode\r\n *\r\n * Router/orchestrator for formatting/text reconciliation modes.\r\n */\r\n\r\nimport { preprocessMarkdown } from '../pipeline/markdown-processor.js';\r\nimport { isListTargetLoose } from '../pipeline/list-markers.js';\r\nimport { ReconciliationPipeline } from '../pipeline/pipeline.js';\r\nimport { wrapInDocumentFragment } from '../pipeline/serialization.js';\r\nimport {\r\n getElementsByTag,\r\n getXmlParseError\r\n} from '../core/xml-query.js';\r\nimport { createParser, createSerializer, parseXml, serializeXml } from '../adapters/xml-adapter.js';\r\nimport { log, error } from '../adapters/logger.js';\r\nimport { extractFormattingFromOoxml } from './format-extraction.js';\r\nimport {\r\n applyFormatRemovalAsSurgicalReplacement,\r\n applyFormatOnlyChangesSurgical\r\n} from './format-application.js';\r\nimport { buildParagraphInfos, findMatchingParagraphInfo, getContainingParagraph } from './format-paragraph-targeting.js';\r\nimport { detectTableCellContext, serializeParagraphOnly } from './table-cell-context.js';\r\nimport { applySurgicalMode } from './surgical-mode.js';\nimport { applyReconstructionMode } from './reconstruction-mode.js';\nimport { applyTableReconciliation, applyTextToTableTransformation } from './table-mode.js';\nimport { getDefaultAuthor } from '../adapters/config.js';\n\r\n/**\r\n * Applies redline track changes to OOXML by modifying the DOM in-place.\r\n *\r\n * @param {string} oxml - Original OOXML string\r\n * @param {string} originalText - Original plain text\r\n * @param {string} modifiedText - New text (may contain markdown)\r\n * @param {Object} [options={}] - Options\r\n * @param {string} [options.author='AI'] - Author for track changes\r\n * @param {string|null} [options.targetParagraphId=null] - Preferred paragraph identity for table wrappers\r\n * @returns {Promise<{ oxml: string, hasChanges: boolean }>}\r\n */\r\nexport async function applyRedlineToOxml(oxml, originalText, modifiedText, options = {}) {\n const generateRedlines = options.generateRedlines ?? true;\n const author = options.author || getDefaultAuthor();\n const parser = createParser();\r\n const serializer = createSerializer();\r\n const noChanges = () => ({ oxml, hasChanges: false });\r\n\r\n let xmlDoc;\r\n try {\r\n xmlDoc = parser.parseFromString(oxml, 'text/xml');\r\n } catch (e) {\r\n error('[OxmlEngine] Failed to parse OXML:', e);\r\n return noChanges();\r\n }\r\n\r\n const parseError = getXmlParseError(xmlDoc);\r\n if (parseError) {\r\n error('[OxmlEngine] XML parse error:', parseError.textContent);\r\n return noChanges();\r\n }\r\n\r\n const initialTableCellContext = detectTableCellContext(xmlDoc, originalText, options);\r\n if (initialTableCellContext.hasTableWrapper && initialTableCellContext.targetParagraph && !options._isolatedTableCell) {\r\n log('[OxmlEngine] Isolating table-cell paragraph before diff');\r\n const isolatedOxml = serializeParagraphOnly(xmlDoc, initialTableCellContext.targetParagraph, serializer);\r\n return applyRedlineToOxml(isolatedOxml, originalText, modifiedText, {\r\n ...options,\r\n _isolatedTableCell: true\r\n });\r\n }\r\n\r\n const sanitizedText = sanitizeAiResponse(modifiedText);\r\n const { cleanText: cleanModifiedText, formatHints } = preprocessMarkdown(sanitizedText);\r\n\r\n const hasTextChanges = cleanModifiedText.trim() !== originalText.trim();\r\n const hasFormatHints = formatHints.length > 0;\r\n\r\n const { existingFormatHints, textSpans, paragraphs } = extractFormattingFromOoxml(xmlDoc);\r\n const hasExistingFormatting = existingFormatHints.length > 0;\n let paragraphInfos = null;\n const getParagraphInfos = () => {\n if (!paragraphInfos) {\n paragraphInfos = buildParagraphInfos(xmlDoc, paragraphs, textSpans);\n }\n return paragraphInfos;\n };\n const applyFormatOnlyWithOoxmlFallback = (precomputedContext = null) => {\n const formatResult = applyFormatOnlyChangesSurgical(\n xmlDoc,\n originalText,\n formatHints,\n serializer,\n author,\n generateRedlines,\n precomputedContext\n );\n if (!formatResult.useNativeApi) {\n return formatResult;\n }\n\n log('[OxmlEngine] Format-only surgical fallback signal encountered; retrying with OOXML reconstruction fallback');\n return applyReconstructionMode(\n xmlDoc,\n originalText,\n cleanModifiedText,\n serializer,\n author,\n formatHints,\n generateRedlines\n );\n };\n\r\n log(`[OxmlEngine] Text changes: ${hasTextChanges}, New format hints: ${formatHints.length}, Existing format hints: ${existingFormatHints.length}`);\r\n\r\n const needsFormatRemoval = !hasTextChanges && !hasFormatHints && hasExistingFormatting;\r\n\r\n if (!hasTextChanges && !hasFormatHints && !hasExistingFormatting) {\r\n log('[OxmlEngine] No text changes, no format hints, and no existing formatting detected');\r\n return noChanges();\r\n }\r\n\r\n if (needsFormatRemoval) {\r\n log('[OxmlEngine] Format REMOVAL detected: applying surgical replacement in OOXML');\r\n\r\n const tableCellCtx = initialTableCellContext;\r\n let targetParagraph = tableCellCtx.targetParagraph || null;\r\n\r\n if (!targetParagraph) {\r\n const matchedInfo = findMatchingParagraphInfo(getParagraphInfos(), originalText);\r\n if (matchedInfo) {\r\n targetParagraph = matchedInfo.paragraph;\r\n }\r\n }\r\n\r\n let filteredHints = existingFormatHints;\r\n if (targetParagraph) {\r\n filteredHints = existingFormatHints.filter(hint => {\r\n const hintParagraph = getContainingParagraph(hint.run);\r\n return hintParagraph === targetParagraph;\r\n });\r\n }\r\n\r\n const removalResult = applyFormatRemovalAsSurgicalReplacement(\r\n xmlDoc,\r\n textSpans,\r\n filteredHints,\r\n serializer,\r\n author,\r\n generateRedlines\r\n );\r\n\r\n if (tableCellCtx.hasTableWrapper && targetParagraph) {\r\n return {\r\n oxml: serializeParagraphOnly(xmlDoc, targetParagraph, serializer),\r\n hasChanges: removalResult.hasChanges\r\n };\r\n }\r\n\r\n return removalResult;\r\n }\r\n\r\n if (!hasTextChanges && hasFormatHints) {\r\n log(`[OxmlEngine] Format-only change detected: ${formatHints.length} format hints`);\r\n\r\n const tableCellCtx = initialTableCellContext;\r\n const precomputedFormatContext = {\r\n textSpans,\r\n paragraphs,\r\n paragraphInfos: getParagraphInfos()\r\n };\r\n if (tableCellCtx.hasTableWrapper && tableCellCtx.targetParagraph) {\n log('[OxmlEngine] Table cell context: applying formatting to target paragraph only');\n\n const formatResult = applyFormatOnlyWithOoxmlFallback(precomputedFormatContext);\n\n log('[OxmlEngine] Stripping table wrapper for table cell paragraph (format-only)');\n return {\n oxml: serializeParagraphOnly(xmlDoc, tableCellCtx.targetParagraph, serializer),\n hasChanges: formatResult.hasChanges\n };\n }\n\n return applyFormatOnlyWithOoxmlFallback(precomputedFormatContext);\n }\n\r\n const tables = getElementsByTag(xmlDoc, 'w:tbl');\r\n const hasTables = tables.length > 0;\r\n const isMarkdownTable = /^\\|.+\\|/.test(cleanModifiedText.trim()) && cleanModifiedText.includes('\\n');\r\n const isTargetList = isListTargetLoose(cleanModifiedText);\r\n const tableCellContext = initialTableCellContext;\r\n\r\n log(`[OxmlEngine] Mode: ${hasTables ? 'SURGICAL' : 'RECONSTRUCTION'}, formatHints: ${formatHints.length}, isMarkdownTable: ${isMarkdownTable}, isTargetList: ${isTargetList}, isTableCellParagraph: ${tableCellContext.isTableCellParagraph}`);\r\n\r\n if (isMarkdownTable && !hasTables) {\r\n log('[OxmlEngine] Text-to-table transformation: generating new table from Markdown');\r\n return applyTextToTableTransformation(xmlDoc, cleanModifiedText, serializer, parser, author, generateRedlines);\r\n }\r\n\r\n if (hasTables && isMarkdownTable) {\r\n return applyTableReconciliation(xmlDoc, cleanModifiedText, serializer, parser, author, generateRedlines);\r\n }\r\n if (hasTables) {\r\n const surgicalTarget = tableCellContext.hasTableWrapper && tableCellContext.targetParagraph\r\n ? tableCellContext.targetParagraph\r\n : null;\r\n if (surgicalTarget) {\r\n log('[OxmlEngine] Table cell edit: scoping surgical mode to target paragraph');\r\n }\r\n\r\n const result = applySurgicalMode(\r\n xmlDoc,\r\n originalText,\r\n cleanModifiedText,\r\n serializer,\r\n author,\r\n formatHints,\r\n generateRedlines,\r\n surgicalTarget\r\n );\r\n\r\n if (tableCellContext.hasTableWrapper && result.hasChanges && tableCellContext.targetParagraph) {\r\n log('[OxmlEngine] Stripping table wrapper for table cell paragraph (surgical mode)');\r\n return { oxml: serializeParagraphOnly(xmlDoc, tableCellContext.targetParagraph, serializer), hasChanges: true };\r\n }\r\n return result;\r\n }\r\n if (isTargetList) {\r\n log('[OxmlEngine] \uD83C\uDFAF Using reconciliation pipeline for list generation');\r\n const pipeline = new ReconciliationPipeline({ author, generateRedlines });\r\n const result = await pipeline.execute(oxml, modifiedText, { xmlDoc });\r\n\r\n if (result.isValid && result.ooxml && result.ooxml !== oxml) {\r\n log(`[OxmlEngine] Wrapping list OOXML with numbering definitions, includeNumbering=${result.includeNumbering}`);\r\n const wrapped = wrapInDocumentFragment(result.ooxml, {\r\n includeNumbering: result.includeNumbering ?? true,\r\n numberingXml: result.numberingXml\r\n });\r\n log(`[OxmlEngine] \u2705 Wrapped OOXML length: ${wrapped.length}`);\r\n return { oxml: wrapped, hasChanges: true };\r\n }\r\n return noChanges();\r\n }\r\n\r\n return applyReconstructionMode(xmlDoc, originalText, cleanModifiedText, serializer, author, formatHints, generateRedlines);\r\n}\r\n\r\n/**\r\n * Sanitizes AI response text by removing common prefixes.\r\n *\r\n * @param {string} text - AI response text\r\n * @returns {string}\r\n */\r\nexport function sanitizeAiResponse(text) {\r\n let cleaned = text;\r\n cleaned = cleaned.replace(/^(Here is the redline:|Here is the text:|Sure, I can help:|Here's the updated text:)\\s*/i, '');\r\n cleaned = cleaned.replace(/\\$\\\\text\\{/g, '').replace(/\\}\\$/g, '');\r\n cleaned = cleaned.replace(/\\$([^0-9\\n]+?)\\$/g, '$1');\r\n cleaned = cleaned.replace(/\\\\r\\\\n/g, '\\n').replace(/\\\\n/g, '\\n');\r\n return cleaned;\r\n}\r\n\r\n/**\r\n * Parses OOXML into a DOM document.\r\n *\r\n * @param {string} ooxmlString - OOXML text\r\n * @returns {Document}\r\n */\r\nexport function parseOoxml(ooxmlString) {\r\n return parseXml(ooxmlString, 'application/xml');\r\n}\r\n\r\n/**\r\n * Serializes a DOM document to OOXML text.\r\n *\r\n * @param {Node} doc - XML document/node\r\n * @returns {string}\r\n */\r\nexport function serializeOoxml(doc) {\r\n return serializeXml(doc);\r\n}\r\n", "/**\n * Shared paragraph-targeting helpers for standalone/add-in consumers.\n *\n * This module centralizes target parsing and matching used by callers that\n * apply per-paragraph operations (for example chat redlines/comments/highlights).\n */\n\nfunction toArray(nodeList) {\n return Array.from(nodeList || []);\n}\n\nexport const WORD_MAIN_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\n\nfunction getElementsByLocalName(node, localName) {\n if (!node) return [];\n\n if (typeof node.getElementsByTagNameNS === 'function') {\n const namespaced = toArray(node.getElementsByTagNameNS('*', localName));\n if (namespaced.length > 0) return namespaced;\n }\n\n if (typeof node.getElementsByTagName !== 'function') return [];\n\n const prefixed = toArray(node.getElementsByTagName(`w:${localName}`));\n if (prefixed.length > 0) return prefixed;\n\n return toArray(node.getElementsByTagName(localName));\n}\n\nfunction toParagraphText(paragraph) {\n const textNodes = getElementsByLocalName(paragraph, 't');\n return textNodes.map(node => node.textContent || '').join('');\n}\n\n/**\n * Reads visible text from a paragraph by concatenating `w:t` nodes.\n *\n * @param {Element|null|undefined} paragraph - OOXML paragraph node\n * @returns {string}\n */\nexport function getParagraphText(paragraph) {\n if (!paragraph) return '';\n return toParagraphText(paragraph);\n}\n\n/**\n * Returns body paragraphs for a document, or all paragraphs as fallback.\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document root\n * @returns {Element[]}\n */\nexport function getDocumentParagraphNodes(xmlDoc) {\n if (!xmlDoc) return [];\n const bodies = getElementsByLocalName(xmlDoc, 'body');\n const searchRoot = bodies.length > 0 ? bodies[0] : xmlDoc;\n return getElementsByLocalName(searchRoot, 'p');\n}\n\n/**\n * Normalizes whitespace for paragraph-comparison matching.\n *\n * @param {string} text - Input text\n * @returns {string}\n */\nexport function normalizeWhitespaceForTargeting(text) {\n return String(text || '').replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Detects markdown table syntax used for table reconciliation.\n *\n * @param {string} text - Candidate markdown text\n * @returns {boolean}\n */\nexport function isMarkdownTableText(text) {\n const trimmed = String(text || '').trim();\n return /^\\|.+\\|/.test(trimmed) && trimmed.includes('\\n');\n}\n\n/**\n * Parses paragraph references such as `P12`, `[P12]`, `12`, or `P12.3`.\n *\n * @param {string|number|null|undefined} rawValue - Reference input\n * @returns {number|null}\n */\nexport function parseParagraphReference(rawValue) {\n if (rawValue == null) return null;\n if (typeof rawValue === 'number' && Number.isInteger(rawValue) && rawValue > 0) return rawValue;\n\n const text = String(rawValue).trim();\n if (!text) return null;\n\n const prefixed = text.match(/^\\[?P(\\d+)(?:\\.\\d+)?\\]?$/i);\n if (prefixed) return Number.parseInt(prefixed[1], 10);\n\n const numeric = text.match(/^(\\d+)$/);\n if (numeric) return Number.parseInt(numeric[1], 10);\n\n return null;\n}\n\n/**\n * Removes leading paragraph labels (for example `[P12]`) from text fields.\n *\n * @param {string|null|undefined} text - Input text\n * @returns {string}\n */\nexport function stripLeadingParagraphMarker(text) {\n if (text == null) return '';\n return String(text).replace(/^\\s*\\[P\\d+(?:\\.\\d+)?\\]\\s*/i, '').trim();\n}\n\n/**\n * Splits a leading paragraph label from text.\n *\n * @param {string|null|undefined} text - Input text\n * @returns {{ text: string, targetRef: number|null }}\n */\nexport function splitLeadingParagraphMarker(text) {\n const raw = String(text || '');\n const marker = raw.match(/^\\s*\\[P(\\d+)(?:\\.\\d+)?\\]\\s*/i);\n if (!marker) return { text: raw.trim(), targetRef: null };\n\n return {\n text: raw.replace(/^\\s*\\[P\\d+(?:\\.\\d+)?\\]\\s*/i, '').trim(),\n targetRef: Number.parseInt(marker[1], 10)\n };\n}\n\n/**\n * Resolves a paragraph by 1-based paragraph index.\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document\n * @param {number|null|undefined} targetRef - 1-based paragraph number\n * @returns {Element|null}\n */\nexport function findParagraphByReference(xmlDoc, targetRef) {\n if (!Number.isInteger(targetRef) || targetRef < 1) return null;\n const paragraphs = getDocumentParagraphNodes(xmlDoc);\n return paragraphs[targetRef - 1] || null;\n}\n\n/**\n * Finds the closest ancestor matching Word namespace + localName.\n *\n * @param {Node|null|undefined} node - Start node\n * @param {string} localName - WordprocessingML local element name (for example `tbl`, `tc`)\n * @param {string} [namespaceUri] - Namespace URI to match\n * @returns {Element|null}\n */\nexport function findContainingWordElement(node, localName, namespaceUri = WORD_MAIN_NS) {\n let current = node;\n while (current) {\n if (\n current.nodeType === 1 &&\n current.namespaceURI === namespaceUri &&\n current.localName === localName\n ) {\n return current;\n }\n current = current.parentNode;\n }\n return null;\n}\n\n/**\n * Finds paragraph by exact/normalized text equality.\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document\n * @param {string} targetText - Target paragraph text\n * @returns {Element|null}\n */\nexport function findParagraphByStrictText(xmlDoc, targetText) {\n const paragraphs = getDocumentParagraphNodes(xmlDoc);\n const normalizedTarget = String(targetText || '').trim();\n if (!normalizedTarget) return null;\n\n const exact = paragraphs.find(p => getParagraphText(p).trim() === normalizedTarget);\n if (exact) return exact;\n\n const normTarget = normalizeWhitespaceForTargeting(normalizedTarget);\n return paragraphs.find(p => normalizeWhitespaceForTargeting(getParagraphText(p)) === normTarget) || null;\n}\n\n/**\n * Finds paragraph by strict match, then fuzzy fallback heuristics.\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document\n * @param {string} targetText - Target paragraph text\n * @param {{ onInfo?: (msg:string)=>void }} [options] - Optional logger callbacks\n * @returns {Element|null}\n */\nexport function findParagraphByBestTextMatch(xmlDoc, targetText, options = {}) {\n const onInfo = typeof options.onInfo === 'function' ? options.onInfo : () => {};\n const paragraphs = getDocumentParagraphNodes(xmlDoc);\n const normalizedTarget = String(targetText || '').trim();\n if (!normalizedTarget) return null;\n\n const strictMatch = findParagraphByStrictText(xmlDoc, normalizedTarget);\n if (strictMatch) return strictMatch;\n\n const normTarget = normalizeWhitespaceForTargeting(normalizedTarget);\n\n const startsWithMatch = paragraphs.find(p => {\n const paragraphText = normalizeWhitespaceForTargeting(getParagraphText(p));\n return paragraphText.length > 10 && normTarget.startsWith(paragraphText);\n });\n if (startsWithMatch) {\n onInfo(`[Fuzzy] Prefix match (target starts with paragraph): \"${getParagraphText(startsWithMatch).trim().slice(0, 60)}...\"`);\n return startsWithMatch;\n }\n\n const containsMatch = paragraphs.find(p => {\n const paragraphText = normalizeWhitespaceForTargeting(getParagraphText(p));\n return paragraphText.length > 15 && normTarget.includes(paragraphText);\n });\n if (containsMatch) {\n onInfo(`[Fuzzy] Contains match: \"${getParagraphText(containsMatch).trim().slice(0, 60)}...\"`);\n return containsMatch;\n }\n\n let bestScore = 0;\n let bestParagraph = null;\n const targetWords = new Set(normTarget.toLowerCase().split(/\\s+/).filter(word => word.length > 2));\n for (const paragraph of paragraphs) {\n const paragraphText = getParagraphText(paragraph).trim();\n if (!paragraphText) continue;\n\n const paragraphWords = normalizeWhitespaceForTargeting(paragraphText)\n .toLowerCase()\n .split(/\\s+/)\n .filter(word => word.length > 2);\n const overlap = paragraphWords.filter(word => targetWords.has(word)).length;\n const score = overlap / Math.max(targetWords.size, 1);\n if (score > bestScore && score > 0.5) {\n bestScore = score;\n bestParagraph = paragraph;\n }\n }\n\n if (bestParagraph) {\n onInfo(`[Fuzzy] Best word-overlap match (${(bestScore * 100).toFixed(0)}%): \"${getParagraphText(bestParagraph).trim().slice(0, 60)}...\"`);\n return bestParagraph;\n }\n\n return null;\n}\n\n/**\n * Resolves a target paragraph from `targetRef` + `targetText`.\n *\n * Resolution order:\n * 1) `targetRef` when provided and valid\n * 2) strict text match\n * 3) fuzzy text match\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document\n * @param {{\n * targetText?: string,\n * targetRef?: string|number|null,\n * opType?: string,\n * onInfo?: (msg:string)=>void,\n * onWarn?: (msg:string)=>void\n * }} options - Resolution options\n * @returns {{ paragraph: Element, resolvedBy: 'ref'|'strict_text'|'fuzzy_text'|'strict_text_after_ref_drift'|'fuzzy_text_after_ref_drift' }}\n */\nexport function resolveTargetParagraph(xmlDoc, options = {}) {\n const onInfo = typeof options.onInfo === 'function' ? options.onInfo : () => {};\n const onWarn = typeof options.onWarn === 'function' ? options.onWarn : () => {};\n const opType = options.opType || 'operation';\n const cleanTargetText = String(options.targetText || '').trim();\n const parsedRef = parseParagraphReference(options.targetRef);\n\n if (parsedRef) {\n const byRef = findParagraphByReference(xmlDoc, parsedRef);\n if (byRef) {\n if (cleanTargetText) {\n const strictMatch = findParagraphByStrictText(xmlDoc, cleanTargetText);\n const byRefText = getParagraphText(byRef).trim();\n const byRefNorm = normalizeWhitespaceForTargeting(byRefText);\n const targetNorm = normalizeWhitespaceForTargeting(cleanTargetText);\n const hasDrift = byRefNorm !== targetNorm;\n\n if (hasDrift && strictMatch && strictMatch !== byRef) {\n onInfo(`[Target] [P${parsedRef}] drifted for ${opType}; using strict text rematch.`);\n return { paragraph: strictMatch, resolvedBy: 'strict_text_after_ref_drift' };\n }\n\n if (hasDrift) {\n const fuzzyMatch = findParagraphByBestTextMatch(xmlDoc, cleanTargetText, { onInfo });\n if (fuzzyMatch && fuzzyMatch !== byRef) {\n onInfo(`[Target] [P${parsedRef}] drifted for ${opType}; using fuzzy text rematch.`);\n return { paragraph: fuzzyMatch, resolvedBy: 'fuzzy_text_after_ref_drift' };\n }\n onInfo(`[Target] Using [P${parsedRef}] fallback for ${opType}; target text drifted.`);\n } else if (strictMatch && strictMatch !== byRef) {\n onInfo(`[Target] [P${parsedRef}] disambiguated duplicate target text for ${opType}.`);\n }\n } else {\n onInfo(`[Target] Using [P${parsedRef}] fallback for ${opType}.`);\n }\n return { paragraph: byRef, resolvedBy: 'ref' };\n }\n\n onWarn(`[WARN] Target reference [P${parsedRef}] not found; falling back to text matching for ${opType}.`);\n }\n\n if (cleanTargetText) {\n const strictMatch = findParagraphByStrictText(xmlDoc, cleanTargetText);\n if (strictMatch) return { paragraph: strictMatch, resolvedBy: 'strict_text' };\n\n const fuzzyMatch = findParagraphByBestTextMatch(xmlDoc, cleanTargetText, { onInfo });\n if (fuzzyMatch) return { paragraph: fuzzyMatch, resolvedBy: 'fuzzy_text' };\n }\n\n if (cleanTargetText) throw new Error(`Target paragraph not found: \"${cleanTargetText}\"`);\n if (parsedRef) throw new Error(`Target paragraph reference not found: [P${parsedRef}]`);\n throw new Error('Operation target missing: provide \"target\" text or \"targetRef\" ([P#]).');\n}\n\nfunction isParagraphInTable(paragraph) {\n return !!findContainingWordElement(paragraph, 'tbl');\n}\n\nfunction findStrictTargetCandidates(xmlDoc, targetText) {\n const normalizedTarget = normalizeWhitespaceForTargeting(targetText);\n if (!normalizedTarget) return [];\n\n const paragraphs = getDocumentParagraphNodes(xmlDoc);\n const candidates = [];\n for (let i = 0; i < paragraphs.length; i++) {\n const paragraph = paragraphs[i];\n const paragraphText = getParagraphText(paragraph).trim();\n if (!paragraphText) continue;\n if (normalizeWhitespaceForTargeting(paragraphText) !== normalizedTarget) continue;\n candidates.push({\n paragraph,\n index: i + 1,\n inTable: isParagraphInTable(paragraph)\n });\n }\n return candidates;\n}\n\nfunction selectBestTargetCandidate(candidates, parsedRef, expectedInTable = null) {\n if (!Array.isArray(candidates) || candidates.length === 0) return null;\n\n let scoped = candidates.slice();\n if (typeof expectedInTable === 'boolean') {\n const sameContext = scoped.filter(candidate => candidate.inTable === expectedInTable);\n if (sameContext.length > 0) scoped = sameContext;\n }\n\n if (Number.isInteger(parsedRef) && parsedRef > 0) {\n scoped.sort((a, b) => Math.abs(a.index - parsedRef) - Math.abs(b.index - parsedRef));\n }\n\n return scoped[0] || null;\n}\n\n/**\n * Builds a turn-start paragraph snapshot keyed by 1-based paragraph index.\n *\n * Intended for callers that apply multiple operations sequentially and need to\n * detect `targetRef` drift after earlier structural edits.\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document root\n * @returns {Map<number, { text: string, normalizedText: string, inTable: boolean }>}\n */\nexport function buildTargetReferenceSnapshot(xmlDoc) {\n const paragraphs = getDocumentParagraphNodes(xmlDoc);\n const snapshot = new Map();\n for (let i = 0; i < paragraphs.length; i++) {\n const paragraph = paragraphs[i];\n const text = getParagraphText(paragraph).trim();\n snapshot.set(i + 1, {\n text,\n normalizedText: normalizeWhitespaceForTargeting(text),\n inTable: isParagraphInTable(paragraph)\n });\n }\n return snapshot;\n}\n\n/**\n * Resolves a paragraph using the standard resolver, then corrects stale\n * `targetRef` mappings via strict rematch when a turn-start snapshot is provided.\n *\n * @param {Document|Element|null|undefined} xmlDoc - OOXML document\n * @param {{\n * targetText?: string,\n * targetRef?: string|number|null,\n * opType?: string,\n * targetRefSnapshot?: Map<number, { text?: string, inTable?: boolean }>|null,\n * onInfo?: (msg:string)=>void,\n * onWarn?: (msg:string)=>void\n * }} options - Resolution options\n * @returns {{ paragraph: Element, resolvedBy: 'ref'|'strict_text'|'fuzzy_text'|'strict_text_after_ref_drift' }}\n */\nexport function resolveTargetParagraphWithSnapshot(xmlDoc, options = {}) {\n const onInfo = typeof options.onInfo === 'function' ? options.onInfo : () => {};\n const resolved = resolveTargetParagraph(xmlDoc, options);\n\n const parsedRef = parseParagraphReference(options.targetRef);\n if (!parsedRef || resolved?.resolvedBy !== 'ref') return resolved;\n\n const snapshotEntry = options.targetRefSnapshot instanceof Map\n ? (options.targetRefSnapshot.get(parsedRef) || null)\n : null;\n if (!snapshotEntry) return resolved;\n\n const cleanTargetText = String(options.targetText || '').trim();\n const expectedText = cleanTargetText || snapshotEntry.text || '';\n const expectedNorm = normalizeWhitespaceForTargeting(expectedText);\n if (!expectedNorm) return resolved;\n\n const resolvedNorm = normalizeWhitespaceForTargeting(getParagraphText(resolved.paragraph));\n if (resolvedNorm === expectedNorm) return resolved;\n\n const candidateTexts = [];\n if (cleanTargetText) candidateTexts.push(cleanTargetText);\n if (snapshotEntry.text) {\n const snapshotNorm = normalizeWhitespaceForTargeting(snapshotEntry.text);\n if (snapshotNorm && !candidateTexts.some(text => normalizeWhitespaceForTargeting(text) === snapshotNorm)) {\n candidateTexts.push(snapshotEntry.text);\n }\n }\n\n let bestCandidate = null;\n for (const candidateText of candidateTexts) {\n const candidates = findStrictTargetCandidates(xmlDoc, candidateText);\n const selected = selectBestTargetCandidate(candidates, parsedRef, snapshotEntry.inTable);\n if (!selected) continue;\n if (!bestCandidate) bestCandidate = selected;\n if (selected.paragraph !== resolved.paragraph) {\n bestCandidate = selected;\n break;\n }\n }\n\n if (bestCandidate && bestCandidate.paragraph !== resolved.paragraph) {\n const opType = options.opType || 'operation';\n onInfo(`[Target] [P${parsedRef}] appears stale after prior edits; using strict text rematch for ${opType}.`);\n return { paragraph: bestCandidate.paragraph, resolvedBy: 'strict_text_after_ref_drift' };\n }\n\n return resolved;\n}\n\n/**\n * Resolves a contiguous paragraph range using paragraph references.\n *\n * @param {Document} xmlDoc - XML document\n * @param {string|number|null} startRef - Start paragraph reference (e.g. P12)\n * @param {string|number|null} endRef - End paragraph reference (e.g. P15)\n * @param {Object} [options={}] - Resolution options\n * @param {string} [options.opType='redline'] - Operation type hint\n * @param {Array|null} [options.targetRefSnapshot=null] - Optional target snapshot\n * @param {(message: string) => void} [options.onInfo] - Optional info logger\n * @param {(message: string) => void} [options.onWarn] - Optional warn logger\n * @returns {Element[]|null}\n */\nexport function resolveParagraphRangeByRefs(xmlDoc, startRef, endRef, options = {}) {\n if (!xmlDoc || !startRef || !endRef) return null;\n\n const opType = options?.opType || 'redline';\n const targetRefSnapshot = options?.targetRefSnapshot || null;\n const onInfo = typeof options?.onInfo === 'function' ? options.onInfo : () => { };\n const onWarn = typeof options?.onWarn === 'function' ? options.onWarn : () => { };\n\n const start = resolveTargetParagraphWithSnapshot(xmlDoc, {\n targetRef: startRef,\n opType,\n targetRefSnapshot,\n onInfo,\n onWarn\n })?.paragraph;\n if (!start) return null;\n\n const end = resolveTargetParagraphWithSnapshot(xmlDoc, {\n targetRef: endRef,\n opType,\n targetRefSnapshot,\n onInfo,\n onWarn\n })?.paragraph;\n if (!end) return null;\n\n const allParagraphs = Array.from(xmlDoc.getElementsByTagNameNS('*', 'p'));\n const startIdx = allParagraphs.indexOf(start);\n const endIdx = allParagraphs.indexOf(end);\n if (startIdx < 0 || endIdx < startIdx) return null;\n\n const range = allParagraphs.slice(startIdx, endIdx + 1);\n if (range.length === 0) return null;\n\n const parent = range[0]?.parentNode || null;\n if (!parent) return null;\n if (!range.every(node => node && node.parentNode === parent)) return null;\n return range;\n}\n", "/**\r\n * Shared list-targeting helpers for per-paragraph redline callers.\r\n */\r\n\r\nimport {\r\n WORD_MAIN_NS,\r\n getParagraphText,\r\n normalizeWhitespaceForTargeting\r\n} from './paragraph-targeting.js';\r\n\r\nfunction getFirstDescendantByLocalName(node, localName) {\r\n if (!node || typeof node.getElementsByTagNameNS !== 'function') return null;\r\n const namespaced = node.getElementsByTagNameNS(WORD_MAIN_NS, localName);\r\n if (namespaced.length > 0) return namespaced[0];\r\n const anyNs = node.getElementsByTagNameNS('*', localName);\r\n return anyNs.length > 0 ? anyNs[0] : null;\r\n}\r\n\r\nfunction readValAttribute(element) {\r\n if (!element) return null;\r\n if (typeof element.getAttributeNS === 'function') {\r\n const namespaced = element.getAttributeNS(WORD_MAIN_NS, 'val');\r\n if (namespaced) return namespaced;\r\n }\r\n return element.getAttribute('w:val') || element.getAttribute('val') || null;\r\n}\r\n\r\nfunction parseOutlineLevelFromMarker(marker) {\n const normalized = String(marker || '').trim();\n if (!/^\\d+(?:\\.\\d+)+\\.?$/.test(normalized)) return null;\n const parts = normalized.replace(/\\.$/, '').split('.');\n return Math.max(0, parts.length - 1);\n}\n\nconst REDUNDANT_LIST_PREFIX_REGEX = /^(?:(?:\\d+(?:\\.\\d+)*\\.?|\\((?:\\d+|[a-zA-Z]|[ivxlcIVXLC]+)\\)|[a-zA-Z]\\.|[ivxlcIVXLC]+\\.|[-*+\\u2022]))\\s+/;\n\n/**\n * Strips redundant manual list markers from the start of list item text.\n *\n * Useful when model output contains doubled markers like:\n * - \"2.1. - Item text\"\n * - \"- 2.1. Item text\"\n *\n * @param {string} text - Candidate list item text\n * @returns {string}\n */\nexport function stripRedundantLeadingListMarkers(text) {\n let value = String(text || '').trim();\n let passes = 0;\n while (passes < 4 && REDUNDANT_LIST_PREFIX_REGEX.test(value)) {\n value = value.replace(REDUNDANT_LIST_PREFIX_REGEX, '').trimStart();\n passes++;\n }\n return value.trim();\n}\n\nfunction parseModifiedListItems(modifiedText) {\n const rawLines = String(modifiedText || '').split(/\\r?\\n/g);\n const items = [];\n let hasListMarkers = false;\n\r\n for (const rawLine of rawLines) {\r\n const line = rawLine.trimEnd();\r\n if (!line.trim()) continue;\r\n\r\n const markerMatch = line.match(/^(\\s*)((?:\\d+(?:\\.\\d+)*\\.?|\\((?:\\d+|[a-zA-Z]|[ivxlcIVXLC]+)\\)|[a-zA-Z]\\.|[ivxlcIVXLC]+\\.|[-*+\\u2022]))\\s+(.*)$/);\r\n if (markerMatch) {\r\n hasListMarkers = true;\r\n const marker = markerMatch[2];\r\n const markerType = /^[-*+\\u2022]$/.test(marker) ? 'bullet' : 'numbered';\r\n const level = Math.floor((markerMatch[1] || '').length / 2);\r\n items.push({\n kind: 'list',\n markerType,\n level,\n marker,\n outlineLevel: markerType === 'numbered' ? parseOutlineLevelFromMarker(marker) : null,\n text: stripRedundantLeadingListMarkers(markerMatch[3])\n });\n continue;\n }\n\r\n items.push({\r\n kind: 'text',\r\n text: line.trim()\r\n });\r\n }\r\n\r\n return { items, hasListMarkers };\r\n}\r\n\r\nfunction toMarkdownLine(level, markerType, text) {\r\n const indent = ' '.repeat(Math.max(0, level));\r\n const marker = markerType === 'numbered' ? '1.' : '-';\r\n return `${indent}${marker} ${String(text || '').trim()}`.trimEnd();\r\n}\r\n\r\nfunction isNormalizedTextEqual(a, b) {\r\n return normalizeWhitespaceForTargeting(a) === normalizeWhitespaceForTargeting(b);\r\n}\r\n\r\nfunction resolveInsertionLevel(item, anchorLevel, baselineLevel) {\n if (Number.isInteger(item?.outlineLevel)) {\n return Math.max(0, item.outlineLevel);\n }\n return Math.max(0, anchorLevel + ((item?.level || 0) - baselineLevel));\n}\n\nfunction shouldPromoteBulletInsertionsToChildDepth(parsedItems, normalizedTargetText, anchorLevel) {\n if (!Array.isArray(parsedItems) || parsedItems.length < 2) return false;\n if (!Number.isInteger(anchorLevel) || anchorLevel < 1) return false;\n\n const firstItem = parsedItems[0];\n const trailingListItems = parsedItems.slice(1).filter(item => item.kind === 'list');\n if (trailingListItems.length === 0) return false;\n if (trailingListItems.some(item => item.markerType !== 'bullet')) return false;\n if (trailingListItems.some(item => Number.isInteger(item.outlineLevel))) return false;\n\n if (firstItem?.kind === 'text') {\n return isNormalizedTextEqual(firstItem.text, normalizedTargetText);\n }\n\n if (firstItem?.kind === 'list' && firstItem.markerType === 'numbered') {\n return isNormalizedTextEqual(firstItem.text, normalizedTargetText);\n }\n\n return false;\n}\n\nfunction promoteBulletInsertionsToChildDepth(entries, anchorLevel) {\n return entries.map(entry => {\n const relativeDepth = Math.max(0, (entry.ilvl || 0) - anchorLevel);\n return {\n ...entry,\n ilvl: Math.min(8, anchorLevel + 1 + relativeDepth)\n };\n });\n}\n\r\nfunction buildListEntriesForInsertion(parsedItems, normalizedTargetText, anchorLevel, defaultMarkerType) {\r\n const firstItem = parsedItems[0];\r\n const trailingListItems = parsedItems.slice(1).filter(item => item.kind === 'list');\r\n\r\n // Pattern A: plain anchor text + list item lines (target line + inserted lines)\r\n if (\r\n firstItem?.kind === 'text' &&\r\n isNormalizedTextEqual(firstItem.text, normalizedTargetText) &&\r\n trailingListItems.length > 0\r\n ) {\r\n const firstTrailingLevel = trailingListItems[0].level;\r\n return trailingListItems.map(item => ({\r\n ilvl: resolveInsertionLevel(item, anchorLevel, firstTrailingLevel),\r\n markerType: item.markerType || defaultMarkerType,\r\n text: item.text\r\n }));\r\n }\r\n\r\n // Pattern B: list lines where first line repeats target item.\r\n if (parsedItems.every(item => item.kind === 'list')) {\r\n const firstList = parsedItems[0];\r\n if (!firstList || !isNormalizedTextEqual(firstList.text, normalizedTargetText)) {\r\n return null;\r\n }\r\n const firstLevel = firstList.level;\r\n return parsedItems\r\n .slice(1)\r\n .map(item => ({\r\n ilvl: resolveInsertionLevel(item, anchorLevel, firstLevel),\r\n markerType: item.markerType || defaultMarkerType,\r\n text: item.text\r\n }))\r\n .filter(item => item.text);\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Reads list numbering metadata from paragraph OOXML.\r\n *\r\n * @param {Element} paragraph - Paragraph element\r\n * @returns {{ numId: string, ilvl: number }|null}\r\n */\r\nexport function getParagraphListInfo(paragraph) {\r\n if (!paragraph) return null;\r\n\r\n const pPr = getFirstDescendantByLocalName(paragraph, 'pPr');\r\n if (!pPr) return null;\r\n const numPr = getFirstDescendantByLocalName(pPr, 'numPr');\r\n if (!numPr) return null;\r\n const numIdEl = getFirstDescendantByLocalName(numPr, 'numId');\r\n if (!numIdEl) return null;\r\n\r\n const numId = readValAttribute(numIdEl);\r\n if (!numId) return null;\r\n\r\n const ilvlEl = getFirstDescendantByLocalName(numPr, 'ilvl');\r\n const ilvlRaw = readValAttribute(ilvlEl);\r\n const ilvl = Number.parseInt(ilvlRaw || '0', 10);\r\n\r\n return {\r\n numId: String(numId),\r\n ilvl: Number.isFinite(ilvl) ? ilvl : 0\r\n };\r\n}\r\n\r\n/**\r\n * Collects contiguous sibling list paragraphs sharing the same `numId`.\r\n *\r\n * @param {Element} targetParagraph - Target paragraph\r\n * @returns {Element[]|null}\r\n */\r\nexport function collectContiguousListParagraphBlock(targetParagraph) {\r\n const targetInfo = getParagraphListInfo(targetParagraph);\r\n if (!targetInfo) return null;\r\n\r\n const parent = targetParagraph.parentNode;\r\n if (!parent) return null;\r\n\r\n const siblings = Array.from(parent.childNodes || []).filter(\r\n node =>\r\n node &&\r\n node.nodeType === 1 &&\r\n node.namespaceURI === WORD_MAIN_NS &&\r\n node.localName === 'p'\r\n );\r\n const targetIndex = siblings.indexOf(targetParagraph);\r\n if (targetIndex < 0) return null;\r\n\r\n let start = targetIndex;\r\n while (start > 0) {\r\n const prevInfo = getParagraphListInfo(siblings[start - 1]);\r\n if (!prevInfo || prevInfo.numId !== targetInfo.numId) break;\r\n start--;\r\n }\r\n\r\n let end = targetIndex;\r\n while (end < siblings.length - 1) {\r\n const nextInfo = getParagraphListInfo(siblings[end + 1]);\r\n if (!nextInfo || nextInfo.numId !== targetInfo.numId) break;\r\n end++;\r\n }\r\n\r\n return siblings.slice(start, end + 1);\r\n}\r\n\r\n/**\r\n * Synthesizes block-level list markdown edits when a single list item receives\r\n * multiline list content (for example insert-between-item intent).\r\n *\r\n * @param {Element} targetParagraph - Resolved target paragraph\r\n * @param {string} modifiedText - Proposed replacement text\r\n * @param {{\r\n * currentParagraphText?: string,\r\n * onInfo?: (msg:string)=>void,\r\n * onWarn?: (msg:string)=>void\r\n * }} [options] - Optional logging/context options\r\n * @returns {{ paragraphs: Element[], originalText: string, modifiedText: string }|null}\r\n */\r\nexport function synthesizeExpandedListScopeEdit(targetParagraph, modifiedText, options = {}) {\r\n const onInfo = typeof options.onInfo === 'function' ? options.onInfo : () => {};\r\n const onWarn = typeof options.onWarn === 'function' ? options.onWarn : () => {};\r\n\r\n const rawModified = String(modifiedText || '');\r\n if (!rawModified.includes('\\n')) return null;\r\n\r\n const targetListInfo = getParagraphListInfo(targetParagraph);\r\n if (!targetListInfo) return null;\r\n\r\n const blockParagraphs = collectContiguousListParagraphBlock(targetParagraph);\r\n if (!blockParagraphs || blockParagraphs.length === 0) return null;\r\n\r\n const parsed = parseModifiedListItems(rawModified);\r\n if (!parsed.hasListMarkers || parsed.items.length < 2) return null;\r\n\r\n const normalizedTargetText = normalizeWhitespaceForTargeting(\r\n options.currentParagraphText || getParagraphText(targetParagraph)\r\n );\r\n const listItemsOnly = parsed.items.filter(item => item.kind === 'list');\r\n const firstListType = listItemsOnly[0]?.markerType || 'bullet';\r\n\r\n const blockInfos = blockParagraphs.map(paragraph => ({\r\n paragraph,\r\n list: getParagraphListInfo(paragraph),\r\n text: String(getParagraphText(paragraph) || '').trim()\r\n }));\r\n const targetIndex = blockParagraphs.indexOf(targetParagraph);\r\n if (targetIndex < 0) return null;\r\n\r\n const baseLevel = Math.min(...blockInfos.map(info => info.list?.ilvl ?? 0));\r\n const originalMarkdownLines = blockInfos.map(info =>\r\n toMarkdownLine((info.list?.ilvl ?? 0) - baseLevel, firstListType, info.text)\r\n );\r\n\r\n let replacementEntries = null;\r\n const firstItem = parsed.items[0];\r\n const trailingListItems = parsed.items.slice(1).filter(item => item.kind === 'list');\r\n\r\n if (firstItem?.kind === 'text' && isNormalizedTextEqual(firstItem.text, normalizedTargetText) && trailingListItems.length > 0) {\r\n const anchorLevel = Math.max(0, (blockInfos[targetIndex].list?.ilvl ?? 0) - baseLevel);\r\n const firstTrailingLevel = trailingListItems[0].level;\r\n replacementEntries = [\r\n {\r\n level: anchorLevel,\r\n markerType: firstListType,\r\n text: blockInfos[targetIndex].text\r\n },\r\n ...trailingListItems.map(item => ({\r\n level: resolveInsertionLevel(item, anchorLevel, firstTrailingLevel),\r\n markerType: item.markerType || firstListType,\r\n text: item.text\r\n }))\r\n ];\r\n } else if (parsed.items.every(item => item.kind === 'list')) {\r\n const anchorLevel = Math.max(0, (blockInfos[targetIndex].list?.ilvl ?? 0) - baseLevel);\r\n const firstLevel = parsed.items[0].level;\r\n replacementEntries = parsed.items.map(item => ({\r\n level: resolveInsertionLevel(item, anchorLevel, firstLevel),\r\n markerType: item.markerType || firstListType,\r\n text: item.text\r\n }));\r\n } else {\r\n onWarn('[List] Multiline list edit did not match supported insertion/replace patterns; skipping list-block synthesis.');\r\n return null;\r\n }\r\n\r\n const replacementLines = replacementEntries.map(entry => toMarkdownLine(entry.level, entry.markerType, entry.text));\r\n const modifiedMarkdownLines = originalMarkdownLines\r\n .slice(0, targetIndex)\r\n .concat(replacementLines)\r\n .concat(originalMarkdownLines.slice(targetIndex + 1));\r\n\r\n const originalText = originalMarkdownLines.join('\\n');\r\n const nextModifiedText = modifiedMarkdownLines.join('\\n');\r\n if (nextModifiedText === originalText) return null;\r\n\r\n onInfo('[List] Expanded single-item list edit to contiguous list block for stable middle insertion.');\r\n return {\r\n paragraphs: blockParagraphs,\r\n originalText,\r\n modifiedText: nextModifiedText\r\n };\r\n}\r\n\r\n/**\r\n * Plans insertion-only list edits for multiline middle-insert requests.\r\n *\r\n * This returns only new list items to insert after the target paragraph, so\r\n * callers can emit insertion-only redlines instead of deleting/reinserting\r\n * whole list blocks.\r\n *\r\n * @param {Element} targetParagraph - Resolved target list paragraph\r\n * @param {string} modifiedText - Proposed replacement text\r\n * @param {{\r\n * currentParagraphText?: string,\r\n * onInfo?: (msg:string)=>void,\r\n * onWarn?: (msg:string)=>void\r\n * }} [options] - Optional context/log callbacks\r\n * @returns {{ targetParagraph: Element, numId: string, entries: Array<{ ilvl: number, text: string, markerType: 'bullet'|'numbered' }> }|null}\r\n */\r\nexport function planListInsertionOnlyEdit(targetParagraph, modifiedText, options = {}) {\n const onInfo = typeof options.onInfo === 'function' ? options.onInfo : () => {};\r\n const onWarn = typeof options.onWarn === 'function' ? options.onWarn : () => {};\r\n\r\n const rawModified = String(modifiedText || '');\r\n if (!rawModified.includes('\\n')) return null;\r\n\r\n const targetListInfo = getParagraphListInfo(targetParagraph);\r\n if (!targetListInfo) return null;\r\n\r\n const parsed = parseModifiedListItems(rawModified);\r\n if (!parsed.hasListMarkers || parsed.items.length < 2) return null;\r\n\r\n const normalizedTargetText = normalizeWhitespaceForTargeting(\n options.currentParagraphText || getParagraphText(targetParagraph)\n );\n const listItemsOnly = parsed.items.filter(item => item.kind === 'list');\n const defaultMarkerType = listItemsOnly[0]?.markerType || 'bullet';\n const anchorLevel = Math.max(0, targetListInfo.ilvl);\n let entries = buildListEntriesForInsertion(parsed.items, normalizedTargetText, anchorLevel, defaultMarkerType);\n\n if (!entries || entries.length === 0) {\n onWarn('[List] Could not derive insertion-only entries from multiline list edit.');\n return null;\n }\n\n if (shouldPromoteBulletInsertionsToChildDepth(parsed.items, normalizedTargetText, anchorLevel)) {\n entries = promoteBulletInsertionsToChildDepth(entries, anchorLevel);\n onInfo('[List] Promoted bullet insertion to child depth for nested numbered-list intent.');\n }\n\n onInfo('[List] Planned insertion-only list redline entries (no block rewrite).');\n return {\n targetParagraph,\r\n numId: targetListInfo.numId,\r\n entries\r\n };\r\n}\r\n", "/**\n * Shared markdown list parsing for command adapters.\n *\n * Keeps command-layer list parsing aligned with reconciliation marker logic.\n */\n\nimport { matchListMarker, stripListMarker } from '../pipeline/list-markers.js';\n\n/**\n * Parses markdown list-like content into structured items.\n *\n * Output shape is compatible with command-layer expectations from `parseMarkdownList`.\n *\n * @param {string} content - Raw markdown/text content\n * @returns {{ type: 'numbered'|'bullet'|'text', items: Array<{ type: 'numbered'|'bullet'|'text', level: number, text: string, marker?: string }> }|null}\n */\nexport function parseMarkdownListContent(content) {\n if (!content) return null;\n\n const normalized = String(content).trim();\n if (!normalized) return null;\n\n const lines = normalized.split('\\n');\n const items = [];\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n const markerMatch = matchListMarker(line, { allowZeroSpaceAfterMarker: false });\n if (markerMatch) {\n const indent = markerMatch[1] || '';\n const marker = markerMatch[2].trim();\n const text = stripListMarker(line, { allowZeroSpaceAfterMarker: false }).trim();\n const level = Math.floor(indent.length / 2);\n const isBullet = /^[-*+\\u2022]$/.test(marker);\n\n items.push({\n type: isBullet ? 'bullet' : 'numbered',\n level,\n text,\n marker\n });\n continue;\n }\n\n items.push({\n type: 'text',\n level: 0,\n text: line.trim()\n });\n }\n\n if (items.length === 0) return null;\n\n const hasNumbered = items.some(item => item.type === 'numbered');\n const hasBullet = items.some(item => item.type === 'bullet');\n\n return {\n type: hasNumbered ? 'numbered' : (hasBullet ? 'bullet' : 'text'),\n items\n };\n}\n\n/**\n * Checks whether parsed list data includes at least one real list item.\n *\n * @param {{ items?: Array<{ type?: string }> }|null} parsedListData - Parsed list data\n * @returns {boolean}\n */\nexport function hasListItems(parsedListData) {\n if (!parsedListData || !Array.isArray(parsedListData.items)) return false;\n return parsedListData.items.some(item => item?.type === 'numbered' || item?.type === 'bullet');\n}\n", "/**\n * Shared list markdown construction/parsing helpers for command adapters.\n */\n\n/**\n * Infers numbering style from a list marker.\n *\n * @param {string} marker - Marker text\n * @returns {'decimal'|'lowerAlpha'|'upperAlpha'|'lowerRoman'|'upperRoman'}\n */\nexport function inferNumberingStyleFromMarker(marker) {\n const m = (marker || '').trim();\n if (!m) return 'decimal';\n if (/^\\d+(?:\\.\\d+)*\\.?$/.test(m) || /^\\(\\d+\\)$/.test(m)) return 'decimal';\n if (/^[ivxlcdm]+\\.$/.test(m)) return 'lowerRoman';\n if (/^[IVXLCDM]{2,}\\.$/.test(m)) return 'upperRoman';\n if (/^[a-z]\\.$/.test(m)) return 'lowerAlpha';\n if (/^[A-Z]\\.$/.test(m)) return 'upperAlpha';\n return 'decimal';\n}\n\n/**\n * Builds list markdown from normalized item+level input.\n *\n * @param {Array<{ text: string, level: number }>} itemsWithLevels - Items with indentation levels\n * @param {'bullet'|'numbered'} listType - List kind\n * @param {'decimal'|'lowerAlpha'|'upperAlpha'|'lowerRoman'|'upperRoman'} numberingStyle - Number style for numbered lists\n * @returns {string}\n */\nexport function buildListMarkdown(itemsWithLevels, listType, numberingStyle) {\n const levelCounters = new Map();\n const lines = [];\n\n for (const item of itemsWithLevels) {\n const level = Math.max(0, Number(item?.level) || 0);\n for (const key of Array.from(levelCounters.keys())) {\n if (key > level) {\n levelCounters.delete(key);\n }\n }\n\n const nextCounter = (levelCounters.get(level) || 0) + 1;\n levelCounters.set(level, nextCounter);\n\n const marker = buildListMarker(nextCounter, listType, numberingStyle);\n const indent = ' '.repeat(level * 4);\n lines.push(`${indent}${marker} ${item.text || ''}`.trimEnd());\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Normalizes list item text/indentation into markdown-ready model.\n *\n * @param {Array<string>} rawItems - Raw tool items\n * @param {Object} [options={}] - Normalize options\n * @param {number} [options.indentSpaces=4] - Spaces per indent level\n * @returns {Array<{ text: string, level: number, removedMarker: string|null }>}\n */\nexport function normalizeListItemsWithLevels(rawItems, options = {}) {\n const indentSpaces = Math.max(1, Number(options.indentSpaces) || 4);\n const markersRegex = /^((?:\\d+(?:\\.\\d+)*\\.?|\\((?:\\d+|[a-zA-Z]|[ivxlcIVXLC]+)\\)|[a-zA-Z]\\.|\\d+\\.|[ivxlcIVXLC]+\\.|[-*\u2022])\\s*)/;\n\n return (rawItems || []).map((rawItem) => {\n const item = String(rawItem ?? '');\n const indentMatch = item.match(/^(\\s*)/);\n const indentSize = indentMatch ? indentMatch[1].length : 0;\n const level = Math.floor(indentSize / indentSpaces);\n\n let stripped = item.trim();\n let removedMarker = null;\n const markerMatch = stripped.match(markersRegex);\n if (markerMatch) {\n removedMarker = markerMatch[1].trim() || null;\n stripped = stripped.replace(markersRegex, '');\n }\n\n return {\n text: stripped.trim(),\n level,\n removedMarker\n };\n });\n}\n\nfunction buildListMarker(counter, listType, numberingStyle) {\n if (listType === 'bullet') return '-';\n\n switch (numberingStyle) {\n case 'lowerAlpha':\n return `${toAlphaSequence(counter, false)}.`;\n case 'upperAlpha':\n return `${toAlphaSequence(counter, true)}.`;\n case 'lowerRoman':\n return `${toRoman(counter, false)}.`;\n case 'upperRoman':\n return `${toRoman(counter, true)}.`;\n case 'decimal':\n default:\n return `${counter}.`;\n }\n}\n\nfunction toAlphaSequence(value, upper = false) {\n let n = Math.max(1, Number(value) || 1);\n let out = '';\n while (n > 0) {\n n -= 1;\n out = String.fromCharCode(97 + (n % 26)) + out;\n n = Math.floor(n / 26);\n }\n return upper ? out.toUpperCase() : out;\n}\n\nfunction toRoman(value, upper = false) {\n let n = Math.max(1, Number(value) || 1);\n const romanPairs = [\n [1000, 'M'],\n [900, 'CM'],\n [500, 'D'],\n [400, 'CD'],\n [100, 'C'],\n [90, 'XC'],\n [50, 'L'],\n [40, 'XL'],\n [10, 'X'],\n [9, 'IX'],\n [5, 'V'],\n [4, 'IV'],\n [1, 'I']\n ];\n let out = '';\n for (const [num, sym] of romanPairs) {\n while (n >= num) {\n out += sym;\n n -= num;\n }\n }\n return upper ? out : out.toLowerCase();\n}\n", "/**\n * Shared fallback helpers for structural list conversion when a redline is a\n * text no-op but the target is marker-prefixed plain text (for example `1. X`).\n */\n\nimport { createParser, createSerializer } from '../adapters/xml-adapter.js';\nimport { getXmlParseError } from '../core/xml-query.js';\nimport {\n getDocumentParagraphNodes,\n normalizeWhitespaceForTargeting\n} from '../core/paragraph-targeting.js';\nimport { getParagraphListInfo } from '../core/list-targeting.js';\nimport { ReconciliationPipeline } from '../pipeline/pipeline.js';\nimport { preprocessMarkdown } from '../pipeline/markdown-processor.js';\nimport { parseMarkdownListContent, hasListItems } from './list-parsing.js';\nimport { inferNumberingStyleFromMarker } from './list-markdown.js';\n\nfunction parseSingleLineListCandidate(text) {\n const rawText = String(text || '');\n if (!rawText.trim()) return null;\n if (rawText.includes('\\n')) return null;\n\n const parsed = parseMarkdownListContent(rawText);\n if (!parsed || !hasListItems(parsed) || !Array.isArray(parsed.items) || parsed.items.length !== 1) {\n return null;\n }\n\n const item = parsed.items[0];\n if (!item || (item.type !== 'numbered' && item.type !== 'bullet')) return null;\n\n const marker = String(item.marker || '').trim();\n const numberingStyle = item.type === 'numbered'\n ? inferNumberingStyleFromMarker(marker || '1.')\n : 'bullet';\n\n return {\n type: item.type,\n marker,\n numberingStyle,\n startAt: parseMarkerStart(marker, numberingStyle),\n contentText: String(item.text || '').trim(),\n normalizedContent: normalizeWhitespaceForTargeting(String(item.text || ''))\n };\n}\n\n/**\n * Removes the leading single-line list marker from text when present.\n *\n * Example:\n * - `1. HEADER` -> `HEADER`\n * - `2.2.1. Clause` -> `Clause`\n *\n * @param {string} text - Candidate single-line list text\n * @returns {string}\n */\nexport function stripSingleLineListMarkerPrefix(text) {\n const candidate = parseSingleLineListCandidate(text);\n if (!candidate) return String(text || '').trim();\n return String(candidate.contentText || '').trim();\n}\n\nfunction parseMarkerStart(marker, numberingStyle) {\n if (numberingStyle !== 'decimal') return null;\n const match = String(marker || '').trim().match(/^(\\d+)\\.?$/);\n if (!match) return null;\n const value = Number.parseInt(match[1], 10);\n return Number.isFinite(value) && value > 0 ? value : null;\n}\n\n/**\n * Resolves how a caller should handle numbering ownership for a single-line\n * structural list fallback across multi-operation runs.\n *\n * @param {{\n * numberingKey?: string|null,\n * startAt?: number|null\n * }|null} plan - Single-line fallback plan\n * @param {{\n * explicitByNumberingKey?: Map<string, { numId: string, nextStartAt: number }>\n * }|null} sequenceState - Optional mutable sequence state\n * @returns {{\n * type: 'none'|'sharedByStyle'|'explicitReuse'|'explicitStartNew'|'explicitIsolated',\n * numberingKey: string|null,\n * startAt: number|null,\n * numId: string|null\n * }}\n */\nexport function resolveSingleLineListFallbackNumberingAction(plan, sequenceState = null) {\n const numberingKey = plan?.numberingKey ? String(plan.numberingKey) : null;\n const startAt = Number.isInteger(plan?.startAt) && plan.startAt > 0 ? plan.startAt : null;\n\n if (!numberingKey) {\n return {\n type: 'none',\n numberingKey: null,\n startAt,\n numId: null\n };\n }\n\n if (startAt == null) {\n return {\n type: 'sharedByStyle',\n numberingKey,\n startAt: null,\n numId: null\n };\n }\n\n const explicitMap = sequenceState?.explicitByNumberingKey;\n if (!(explicitMap instanceof Map)) {\n return {\n type: 'explicitIsolated',\n numberingKey,\n startAt,\n numId: null\n };\n }\n\n const existing = explicitMap.get(numberingKey) || null;\n if (\n existing &&\n existing.numId != null &&\n Number.isInteger(existing.nextStartAt) &&\n existing.nextStartAt === startAt\n ) {\n return {\n type: 'explicitReuse',\n numberingKey,\n startAt,\n numId: String(existing.numId)\n };\n }\n\n return {\n type: 'explicitStartNew',\n numberingKey,\n startAt,\n numId: null\n };\n}\n\n/**\n * Records/advances explicit numeric single-line sequence state.\n *\n * @param {{\n * explicitByNumberingKey?: Map<string, { numId: string, nextStartAt: number }>\n * }|null} sequenceState - Mutable sequence state\n * @param {string|null} numberingKey - Numbering signature key\n * @param {string|number|null} numId - Sequence numId\n * @param {number|null} startAt - Current explicit start marker\n */\nexport function recordSingleLineListFallbackExplicitSequence(sequenceState, numberingKey, numId, startAt) {\n if (!sequenceState || !(sequenceState.explicitByNumberingKey instanceof Map)) return;\n if (!numberingKey || numId == null || !Number.isInteger(startAt) || startAt < 1) return;\n\n sequenceState.explicitByNumberingKey.set(String(numberingKey), {\n numId: String(numId),\n nextStartAt: startAt + 1\n });\n}\n\n/**\n * Clears explicit sequence tracking for a numbering signature.\n *\n * @param {{\n * explicitByNumberingKey?: Map<string, { numId: string, nextStartAt: number }>\n * }|null} sequenceState - Mutable sequence state\n * @param {string|null} numberingKey - Numbering signature key\n */\nexport function clearSingleLineListFallbackExplicitSequence(sequenceState, numberingKey) {\n if (!sequenceState || !(sequenceState.explicitByNumberingKey instanceof Map)) return;\n if (!numberingKey) return;\n sequenceState.explicitByNumberingKey.delete(String(numberingKey));\n}\n\nfunction getDirectWordChild(element, localName) {\n if (!element) return null;\n return Array.from(element.childNodes || []).find(\n node =>\n node &&\n node.nodeType === 1 &&\n node.namespaceURI === 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' &&\n node.localName === localName\n ) || null;\n}\n\n/**\n * Forces explicit list bindings on paragraph nodes.\n *\n * Useful when callers need deterministic `w:numPr` assignment regardless of\n * incoming generator quirks or paragraph property tracked-change payloads.\n *\n * @param {Node[]|null|undefined} nodes - Candidate nodes containing paragraphs\n * @param {{\n * numId: string|number,\n * ilvl?: number,\n * clearParagraphPropertyChanges?: boolean,\n * removeListPropertyNode?: boolean\n * }} options - Binding options\n * @returns {number} Number of paragraph nodes updated\n */\nexport function enforceListBindingOnParagraphNodes(nodes, options = {}) {\n const numId = options?.numId;\n if (numId == null) return 0;\n const ilvl = Number.isInteger(options?.ilvl) ? Math.max(0, options.ilvl) : 0;\n const clearParagraphPropertyChanges = options?.clearParagraphPropertyChanges !== false;\n const removeListPropertyNode = options?.removeListPropertyNode !== false;\n\n const paragraphs = (Array.isArray(nodes) ? nodes : [])\n .filter(node => node && node.nodeType === 1 && node.localName === 'p');\n let updated = 0;\n\n for (const paragraph of paragraphs) {\n const ownerDoc = paragraph.ownerDocument;\n if (!ownerDoc) continue;\n\n let pPr = getDirectWordChild(paragraph, 'pPr');\n if (!pPr) {\n pPr = ownerDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:pPr'\n );\n paragraph.insertBefore(pPr, paragraph.firstChild);\n }\n\n if (clearParagraphPropertyChanges) {\n const pPrChange = getDirectWordChild(pPr, 'pPrChange');\n if (pPrChange) pPr.removeChild(pPrChange);\n }\n\n if (removeListPropertyNode) {\n const listPr = getDirectWordChild(pPr, 'listPr');\n if (listPr) pPr.removeChild(listPr);\n }\n\n let numPr = getDirectWordChild(pPr, 'numPr');\n if (!numPr) {\n numPr = ownerDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:numPr'\n );\n pPr.appendChild(numPr);\n }\n\n let ilvlEl = getDirectWordChild(numPr, 'ilvl');\n if (!ilvlEl) {\n ilvlEl = ownerDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:ilvl'\n );\n numPr.appendChild(ilvlEl);\n }\n ilvlEl.setAttribute('w:val', String(ilvl));\n\n let numIdEl = getDirectWordChild(numPr, 'numId');\n if (!numIdEl) {\n numIdEl = ownerDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:numId'\n );\n numPr.appendChild(numIdEl);\n }\n numIdEl.setAttribute('w:val', String(numId));\n updated++;\n }\n\n return updated;\n}\n\nfunction getFirstParagraphFromOxml(oxml) {\n const parser = createParser();\n const doc = parser.parseFromString(String(oxml || ''), 'application/xml');\n const parseError = getXmlParseError(doc);\n if (parseError) return null;\n const paragraphs = getDocumentParagraphNodes(doc);\n return paragraphs[0] || null;\n}\n\nfunction trimTrailingBlankParagraph(oxml) {\n if (!oxml) return '';\n return String(oxml).replace(/<w:p>\\s*<w:pPr>\\s*<\\/w:pPr>\\s*<\\/w:p>\\s*$/i, '');\n}\n\nfunction getAttributeFirst(element, names) {\n for (const name of names) {\n const value = element.getAttribute(name);\n if (value != null && value !== '') return value;\n }\n return null;\n}\n\nfunction getElementId(element, names) {\n const raw = getAttributeFirst(element, names);\n const parsed = Number.parseInt(String(raw || ''), 10);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction setElementVal(element, value) {\n element.setAttribute('w:val', String(value));\n}\n\nfunction extractFirstParagraphNumIdFromOxml(oxml) {\n const parser = createParser();\n const doc = parser.parseFromString(String(oxml || ''), 'application/xml');\n const parseError = getXmlParseError(doc);\n if (parseError) return null;\n\n const paragraphs = getDocumentParagraphNodes(doc);\n const firstParagraph = paragraphs[0] || null;\n if (!firstParagraph) return null;\n\n const numIdNodes = Array.from(firstParagraph.getElementsByTagNameNS('*', 'numId'));\n for (const numIdNode of numIdNodes) {\n const numId = getElementId(numIdNode, ['w:val', 'val']);\n if (numId != null) return String(numId);\n }\n return null;\n}\n\nfunction applyStartOverrideToNumberingXml(numberingXml, targetNumId, startAt, options = {}) {\n if (!numberingXml || !targetNumId || !Number.isInteger(startAt) || startAt < 1) return numberingXml;\n const setAbstractStartOverride = options.setAbstractStartOverride !== false;\n const parser = createParser();\n const serializer = createSerializer();\n const numberingDoc = parser.parseFromString(String(numberingXml || ''), 'application/xml');\n const parseError = getXmlParseError(numberingDoc);\n if (parseError) return numberingXml;\n\n const nums = Array.from(numberingDoc.getElementsByTagNameNS('*', 'num'));\n const target = nums.find(node => {\n const id = getElementId(node, ['w:numId', 'numId']);\n return id != null && String(id) === String(targetNumId);\n });\n if (!target) return numberingXml;\n\n const abstractNumIdNode = Array.from(target.getElementsByTagNameNS('*', 'abstractNumId'))[0] || null;\n const abstractNumId = getElementId(abstractNumIdNode, ['w:val', 'val']);\n\n let lvlOverride = Array.from(target.getElementsByTagNameNS('*', 'lvlOverride'))\n .find(node => {\n const ilvl = getElementId(node, ['w:ilvl', 'ilvl']);\n return ilvl === 0;\n }) || null;\n if (!lvlOverride) {\n lvlOverride = numberingDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:lvlOverride'\n );\n lvlOverride.setAttribute('w:ilvl', '0');\n target.appendChild(lvlOverride);\n }\n\n let startOverride = Array.from(lvlOverride.getElementsByTagNameNS('*', 'startOverride'))[0] || null;\n if (!startOverride) {\n startOverride = numberingDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:startOverride'\n );\n lvlOverride.appendChild(startOverride);\n }\n setElementVal(startOverride, startAt);\n\n // Optional compatibility mode: set abstract-level <w:start> in addition to\n // num-level <w:startOverride>. This can influence other lists sharing that\n // abstract definition in some renderers, so callers may disable it.\n if (setAbstractStartOverride && abstractNumId != null) {\n const abstractNums = Array.from(numberingDoc.getElementsByTagNameNS('*', 'abstractNum'));\n const abstractNum = abstractNums.find(node => {\n const id = getElementId(node, ['w:abstractNumId', 'abstractNumId']);\n return id != null && id === abstractNumId;\n }) || null;\n if (abstractNum) {\n let lvl = Array.from(abstractNum.getElementsByTagNameNS('*', 'lvl'))\n .find(node => {\n const ilvl = getElementId(node, ['w:ilvl', 'ilvl']);\n return ilvl === 0;\n }) || null;\n if (!lvl) {\n lvl = numberingDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:lvl'\n );\n lvl.setAttribute('w:ilvl', '0');\n abstractNum.appendChild(lvl);\n }\n\n let startNode = Array.from(lvl.getElementsByTagNameNS('*', 'start'))[0] || null;\n if (!startNode) {\n startNode = numberingDoc.createElementNS(\n 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n 'w:start'\n );\n lvl.insertBefore(startNode, lvl.firstChild);\n }\n setElementVal(startNode, startAt);\n }\n }\n\n return serializer.serializeToString(numberingDoc);\n}\n\n/**\n * Builds a plan for single-line structural list fallback.\n *\n * @param {{\n * oxml: string,\n * originalText: string,\n * modifiedText: string,\n * allowExistingList?: boolean\n * }} options - Input values for fallback detection\n * @returns {{ listInput: string, numberingKey: string, originalText: string, wasListParagraph: boolean, startAt: number|null }|null}\n */\nexport function buildSingleLineListStructuralFallbackPlan(options = {}) {\n const oxml = String(options.oxml || '');\n const originalText = String(options.originalText || '');\n const modifiedText = String(options.modifiedText || '');\n const allowExistingList = options.allowExistingList === true;\n\n if (!oxml.trim() || !modifiedText.trim()) return null;\n\n const paragraph = getFirstParagraphFromOxml(oxml);\n if (!paragraph) return null;\n\n const existingListInfo = getParagraphListInfo(paragraph);\n if (existingListInfo && !allowExistingList) return null;\n\n const modifiedCleanText = preprocessMarkdown(modifiedText).cleanText || modifiedText;\n const modifiedCandidate = parseSingleLineListCandidate(modifiedText)\n || parseSingleLineListCandidate(modifiedCleanText);\n if (!modifiedCandidate) return null;\n\n const currentCandidate = parseSingleLineListCandidate(originalText);\n const sameRawText =\n normalizeWhitespaceForTargeting(originalText) === normalizeWhitespaceForTargeting(modifiedCleanText);\n const sameListText = !!currentCandidate\n && currentCandidate.type === modifiedCandidate.type\n && currentCandidate.normalizedContent === modifiedCandidate.normalizedContent;\n if (!sameRawText && !sameListText) return null;\n\n return {\n listInput: `${modifiedCandidate.marker} ${modifiedCandidate.contentText}`.trim(),\n numberingKey: `${modifiedCandidate.type}:${modifiedCandidate.numberingStyle}:single`,\n originalText,\n wasListParagraph: !!existingListInfo,\n startAt: modifiedCandidate.startAt\n };\n}\n\n/**\n * Executes a single-line structural list fallback plan.\n *\n * Returns list fragment OOXML (not wrapped package), plus `numberingXml`.\n *\n * @param {{ listInput: string, numberingKey: string, originalText?: string, startAt?: number|null }} plan - Fallback plan\n * @param {{\n * author?: string,\n * generateRedlines?: boolean,\n * pipeline?: ReconciliationPipeline,\n * setAbstractStartOverride?: boolean\n * }} [options={}] - Execution options\n * @returns {Promise<{\n * hasChanges: boolean,\n * oxml: string,\n * numberingXml: string|null,\n * includeNumbering: boolean,\n * listStructuralFallbackApplied: boolean,\n * listStructuralFallbackKey: string|null,\n * warnings: string[]\n * }>}\n */\nexport async function executeSingleLineListStructuralFallback(plan, options = {}) {\n if (!plan || !plan.listInput) {\n return {\n hasChanges: false,\n oxml: '',\n numberingXml: null,\n includeNumbering: false,\n listStructuralFallbackApplied: false,\n listStructuralFallbackKey: null,\n warnings: ['Single-line list fallback plan missing']\n };\n }\n\n const author = options.author || 'AI';\n const generateRedlines = options.generateRedlines ?? true;\n const pipeline = options.pipeline || new ReconciliationPipeline({ author, generateRedlines });\n\n const result = await pipeline.executeListGeneration(\n plan.listInput,\n null,\n null,\n String(plan.originalText || '')\n );\n\n const rawOxml = result?.oxml || result?.ooxml || '';\n const oxml = trimTrailingBlankParagraph(rawOxml);\n const generatedNumId = extractFirstParagraphNumIdFromOxml(oxml);\n const numberingXmlWithStart = applyStartOverrideToNumberingXml(\n result?.numberingXml || null,\n generatedNumId,\n Number.isInteger(plan?.startAt) ? plan.startAt : null,\n {\n setAbstractStartOverride: options.setAbstractStartOverride\n }\n );\n const isValid = result?.isValid !== false;\n if (!oxml || !isValid) {\n return {\n hasChanges: false,\n oxml: '',\n numberingXml: null,\n includeNumbering: false,\n listStructuralFallbackApplied: false,\n listStructuralFallbackKey: plan.numberingKey || null,\n warnings: ['Single-line list fallback produced no valid OOXML']\n };\n }\n\n return {\n hasChanges: true,\n oxml,\n numberingXml: numberingXmlWithStart,\n includeNumbering: true,\n listStructuralFallbackApplied: true,\n listStructuralFallbackKey: plan.numberingKey || null,\n listStructuralFallbackStartAt: Number.isInteger(plan?.startAt) ? plan.startAt : null,\n warnings: ['Single-line list structural fallback applied']\n };\n}\n", "/**\n * Shared table-targeting helpers for per-paragraph redline callers.\n */\n\nimport {\n WORD_MAIN_NS,\n getParagraphText,\n isMarkdownTableText,\n findContainingWordElement,\n normalizeWhitespaceForTargeting\n} from './paragraph-targeting.js';\n\nfunction getDirectWordChildren(element, localName) {\n if (!element) return [];\n return Array.from(element.childNodes || []).filter(\n node =>\n node &&\n node.nodeType === 1 &&\n node.namespaceURI === WORD_MAIN_NS &&\n node.localName === localName\n );\n}\n\nfunction escapeMarkdownCell(text) {\n return String(text || '')\n .replace(/\\|/g, '\\\\|')\n .replace(/\\r?\\n/g, '<br>');\n}\n\nfunction extractTableMatrix(tableElement) {\n const rowElements = getDirectWordChildren(tableElement, 'tr');\n const matrix = rowElements.map(row => {\n const cellElements = getDirectWordChildren(row, 'tc');\n return cellElements.map(cell => {\n const paragraphs = getDirectWordChildren(cell, 'p');\n if (paragraphs.length === 0) return normalizeWhitespaceForTargeting(getParagraphText(cell));\n const lines = paragraphs\n .map(p => normalizeWhitespaceForTargeting(getParagraphText(p)))\n .filter(Boolean);\n return lines.join('\\n');\n });\n });\n\n const columnCount = matrix.reduce((max, row) => Math.max(max, row.length), 0);\n matrix.forEach(row => {\n while (row.length < columnCount) row.push('');\n });\n\n return { matrix, rowElements, columnCount };\n}\n\nfunction tableMatrixToMarkdown(matrix, columnCount) {\n if (!Array.isArray(matrix) || matrix.length === 0 || columnCount <= 0) return null;\n const normalized = matrix.map(row => {\n const copy = Array.isArray(row) ? row.slice(0, columnCount) : [];\n while (copy.length < columnCount) copy.push('');\n return copy;\n });\n\n const header = normalized[0];\n const separator = new Array(columnCount).fill('---');\n const bodyRows = normalized.slice(1);\n const toLine = row => `| ${row.map(cell => escapeMarkdownCell(cell)).join(' | ')} |`;\n\n return [toLine(header), toLine(separator), ...bodyRows.map(toLine)].join('\\n');\n}\n\nfunction isSymmetricLabelRow(rowValues) {\n if (!Array.isArray(rowValues) || rowValues.length < 2) return false;\n const normalized = rowValues.map(value => normalizeWhitespaceForTargeting(value)).filter(Boolean);\n if (normalized.length < 2) return false;\n return normalized.every(value => value === normalized[0]);\n}\n\n/**\n * Heuristic detector for paragraphs likely belonging to a table-source block.\n *\n * @param {string} text - Paragraph text\n * @returns {boolean}\n */\nexport function isLikelyStructuredTableSourceParagraph(text) {\n const normalized = String(text || '').trim();\n if (!normalized) return false;\n if (/^and$/i.test(normalized)) return true;\n if (/^\\[.*\\]$/.test(normalized)) return true;\n if (/^\\(.*\\)$/.test(normalized)) return true;\n if (/:\\s*$/.test(normalized)) return true;\n if (normalized.length <= 90 && !/[.!?]$/.test(normalized) && /[:\\[\\]()]/.test(normalized)) return true;\n if (/^[\\[(]/.test(normalized)) return true;\n return false;\n}\n\n/**\n * Infers a contiguous paragraph block for table conversion starting from a paragraph.\n *\n * @param {Element|null} startParagraph - Starting w:p node\n * @param {Object} [options={}] - Inference options\n * @param {number} [options.maxScan=10] - Max sibling paragraphs to inspect\n * @param {(paragraph: Element) => string} [options.getParagraphText] - Optional text getter\n * @returns {Element[]|null}\n */\nexport function inferTableReplacementParagraphBlock(startParagraph, options = {}) {\n const maxScan = Number.isInteger(options?.maxScan) && options.maxScan > 0 ? options.maxScan : 10;\n const paragraphTextGetter = typeof options?.getParagraphText === 'function'\n ? options.getParagraphText\n : getParagraphText;\n\n if (!startParagraph || !startParagraph.parentNode) return null;\n\n const block = [startParagraph];\n let cursor = startParagraph.nextSibling;\n let scanned = 0;\n\n while (cursor && scanned < maxScan) {\n scanned += 1;\n const nextCursor = cursor.nextSibling;\n if (cursor.nodeType !== 1 || cursor.namespaceURI !== WORD_MAIN_NS || cursor.localName !== 'p') {\n cursor = nextCursor;\n continue;\n }\n\n const text = String(paragraphTextGetter(cursor) || '').trim();\n if (!text) {\n if (block.length > 1) break;\n cursor = nextCursor;\n continue;\n }\n\n if (!isLikelyStructuredTableSourceParagraph(text)) break;\n block.push(cursor);\n cursor = nextCursor;\n }\n\n return block.length > 1 ? block : null;\n}\n\n/**\n * Builds full-table markdown when a table-cell redline uses multiline text.\n *\n * Heuristic:\n * - If target paragraph is inside a table cell\n * - and `modifiedText` is multiline but not markdown-table syntax\n * - and first line matches current paragraph text\n * Then treat extra lines as row insertions in the target column.\n * For symmetric label rows (for example `Title:` in both signature columns),\n * inserted values are mirrored across columns.\n *\n * @param {Element} targetParagraph - Resolved target paragraph\n * @param {string} modifiedText - User/model modified text\n * @param {{\n * tableElement?: Element|null,\n * currentParagraphText?: string,\n * onInfo?: (msg:string)=>void,\n * onWarn?: (msg:string)=>void\n * }} [options] - Optional context/log callbacks\n * @returns {string|null}\n */\nexport function synthesizeTableMarkdownFromMultilineCellEdit(targetParagraph, modifiedText, options = {}) {\n const onInfo = typeof options.onInfo === 'function' ? options.onInfo : () => {};\n const onWarn = typeof options.onWarn === 'function' ? options.onWarn : () => {};\n\n const rawModified = String(modifiedText || '');\n if (!rawModified.includes('\\n')) return null;\n if (isMarkdownTableText(rawModified)) return null;\n\n const lines = rawModified\n .split(/\\r?\\n/g)\n .map(line => line.trim())\n .filter(Boolean);\n if (lines.length < 2) return null;\n\n const tableElement = options.tableElement || findContainingWordElement(targetParagraph, 'tbl');\n const rowElement = findContainingWordElement(targetParagraph, 'tr');\n const cellElement = findContainingWordElement(targetParagraph, 'tc');\n if (!tableElement || !rowElement || !cellElement) return null;\n\n const currentParagraphText = normalizeWhitespaceForTargeting(\n options.currentParagraphText || getParagraphText(targetParagraph)\n );\n const firstLine = normalizeWhitespaceForTargeting(lines[0]);\n if (currentParagraphText && firstLine && firstLine !== currentParagraphText) {\n // Avoid rewriting full tables from ambiguous multiline content.\n onWarn('[Table] Multiline cell text did not anchor to original cell text; skipping table-row synthesis heuristic.');\n return null;\n }\n\n const { matrix, rowElements, columnCount } = extractTableMatrix(tableElement);\n if (matrix.length === 0 || columnCount === 0) return null;\n\n const rowIndex = rowElements.indexOf(rowElement);\n const cellElements = getDirectWordChildren(rowElement, 'tc');\n const colIndex = cellElements.indexOf(cellElement);\n if (rowIndex < 0 || colIndex < 0 || colIndex >= columnCount) return null;\n\n matrix[rowIndex][colIndex] = lines[0];\n const mirrorAcrossColumns = isSymmetricLabelRow(matrix[rowIndex]);\n if (mirrorAcrossColumns) {\n onInfo('[Table] Symmetric row detected; mirroring inserted row values across columns.');\n }\n\n for (let i = 1; i < lines.length; i++) {\n const insertIndex = rowIndex + i;\n const extraValue = lines[i];\n if (\n insertIndex < matrix.length &&\n !normalizeWhitespaceForTargeting(matrix[insertIndex][colIndex])\n ) {\n if (mirrorAcrossColumns) {\n for (let col = 0; col < columnCount; col++) {\n if (!normalizeWhitespaceForTargeting(matrix[insertIndex][col])) {\n matrix[insertIndex][col] = extraValue;\n }\n }\n } else {\n matrix[insertIndex][colIndex] = extraValue;\n }\n } else {\n const newRow = new Array(columnCount).fill('');\n if (mirrorAcrossColumns) {\n for (let col = 0; col < columnCount; col++) newRow[col] = extraValue;\n } else {\n newRow[colIndex] = extraValue;\n }\n matrix.splice(Math.min(insertIndex, matrix.length), 0, newRow);\n }\n }\n\n const markdown = tableMatrixToMarkdown(matrix, columnCount);\n if (!markdown) return null;\n\n onInfo('[Table] Synthesized full markdown table from multiline cell edit for table-scope reconciliation.');\n return markdown;\n}\n", "import { parseOoxml, serializeOoxml } from '../engine/oxml-engine.js';\nimport { WORD_MAIN_NS } from '../core/paragraph-targeting.js';\n\nfunction parseIntegerAttribute(element, names) {\n if (!element || !Array.isArray(names)) return null;\n for (const name of names) {\n const raw = element.getAttribute(name);\n if (raw == null || raw === '') continue;\n const parsed = Number.parseInt(String(raw), 10);\n if (Number.isFinite(parsed)) return parsed;\n }\n return null;\n}\n\nfunction nextAvailableId(startId, occupiedIds, maxPreferred = null) {\n let candidate = Number.isInteger(startId) && startId > 0 ? startId : 1;\n const occupied = occupiedIds instanceof Set ? occupiedIds : new Set();\n\n while (occupied.has(candidate)) {\n candidate += 1;\n }\n\n if (Number.isInteger(maxPreferred) && maxPreferred > 0 && candidate > maxPreferred) {\n for (let probe = 1; probe <= maxPreferred; probe += 1) {\n if (!occupied.has(probe)) return probe;\n }\n }\n\n return candidate;\n}\n\n/**\n * Builds a dynamic numbering-id state from existing numbering XML.\n *\n * This avoids hardcoded ID floors and keeps IDs deterministic relative to the\n * current document numbering definitions.\n *\n * @param {string} numberingXml - Existing `word/numbering.xml` content\n * @param {{\n * minId?: number,\n * maxPreferred?: number\n * }} [options={}] - Optional ID preferences\n * @returns {{\n * nextNumId: number,\n * nextAbstractNumId: number,\n * usedNumIds: Set<number>,\n * usedAbstractNumIds: Set<number>,\n * minId: number,\n * maxPreferred: number\n * }}\n */\nexport function createDynamicNumberingIdState(numberingXml, options = {}) {\n const minId = Number.isInteger(options?.minId) && options.minId > 0 ? options.minId : 1;\n const maxPreferred = Number.isInteger(options?.maxPreferred) && options.maxPreferred >= minId\n ? options.maxPreferred\n : 32767;\n\n const usedNumIds = new Set();\n const usedAbstractNumIds = new Set();\n\n if (String(numberingXml || '').trim()) {\n try {\n const numberingDoc = parseOoxml(numberingXml);\n const abstractNums = Array.from(numberingDoc.getElementsByTagNameNS('*', 'abstractNum'));\n const nums = Array.from(numberingDoc.getElementsByTagNameNS('*', 'num'));\n\n for (const abstractNum of abstractNums) {\n const id = parseIntegerAttribute(abstractNum, ['w:abstractNumId', 'abstractNumId']);\n if (id != null) usedAbstractNumIds.add(id);\n }\n for (const num of nums) {\n const id = parseIntegerAttribute(num, ['w:numId', 'numId']);\n if (id != null) usedNumIds.add(id);\n }\n } catch {\n // Ignore malformed numbering XML and fall back to empty sets.\n }\n }\n\n const maxUsedNumId = usedNumIds.size > 0 ? Math.max(...usedNumIds) : 0;\n const maxUsedAbstractNumId = usedAbstractNumIds.size > 0 ? Math.max(...usedAbstractNumIds) : 0;\n const baseNumId = Math.max(minId, maxUsedNumId + 1);\n const baseAbstractNumId = Math.max(minId, maxUsedAbstractNumId + 1);\n\n return {\n nextNumId: nextAvailableId(baseNumId, usedNumIds, maxPreferred),\n nextAbstractNumId: nextAvailableId(baseAbstractNumId, usedAbstractNumIds, maxPreferred),\n usedNumIds,\n usedAbstractNumIds,\n minId,\n maxPreferred\n };\n}\n\nfunction normalizeNumberingIdState(state) {\n if (!state || typeof state !== 'object') return null;\n\n if (!(state.usedNumIds instanceof Set)) state.usedNumIds = new Set();\n if (!(state.usedAbstractNumIds instanceof Set)) state.usedAbstractNumIds = new Set();\n\n if (!Number.isInteger(state.minId) || state.minId < 1) {\n state.minId = 1;\n }\n if (!Number.isInteger(state.maxPreferred) || state.maxPreferred < state.minId) {\n state.maxPreferred = 32767;\n }\n\n if (!Number.isInteger(state.nextNumId) || state.nextNumId < state.minId) {\n state.nextNumId = state.minId;\n }\n if (!Number.isInteger(state.nextAbstractNumId) || state.nextAbstractNumId < state.minId) {\n state.nextAbstractNumId = state.minId;\n }\n\n state.nextNumId = nextAvailableId(state.nextNumId, state.usedNumIds, state.maxPreferred);\n state.nextAbstractNumId = nextAvailableId(state.nextAbstractNumId, state.usedAbstractNumIds, state.maxPreferred);\n return state;\n}\n\n/**\n * Reserves the next available ID from a mutable numbering-id state.\n *\n * @param {ReturnType<typeof createDynamicNumberingIdState>} state\n * @param {'num'|'abstract'} [kind='num']\n * @returns {number|null}\n */\nexport function reserveNextNumberingId(state, kind = 'num') {\n const normalized = normalizeNumberingIdState(state);\n if (!normalized) return null;\n\n const useAbstract = kind === 'abstract';\n const id = useAbstract ? normalized.nextAbstractNumId : normalized.nextNumId;\n if (!Number.isInteger(id) || id < 1) return null;\n\n if (useAbstract) {\n normalized.usedAbstractNumIds.add(id);\n normalized.nextAbstractNumId = nextAvailableId(id + 1, normalized.usedAbstractNumIds, normalized.maxPreferred);\n } else {\n normalized.usedNumIds.add(id);\n normalized.nextNumId = nextAvailableId(id + 1, normalized.usedNumIds, normalized.maxPreferred);\n }\n\n return id;\n}\n\n/**\n * Reserves the next available numbering IDs on a mutable numbering-id state.\n *\n * @param {ReturnType<typeof createDynamicNumberingIdState>} state\n * @returns {{ numId: number, abstractNumId: number } | null}\n */\nexport function reserveNextNumberingIdPair(state) {\n const numId = reserveNextNumberingId(state, 'num');\n const abstractNumId = reserveNextNumberingId(state, 'abstract');\n if (numId == null || abstractNumId == null) return null;\n\n return { numId, abstractNumId };\n}\n\nfunction hasXmlParseError(doc) {\n if (!doc || !doc.documentElement) return true;\n if (doc.documentElement.localName === 'parsererror') return true;\n return doc.getElementsByTagName('parsererror').length > 0;\n}\n\nfunction isDirectWordChild(node, localName) {\n return !!(\n node &&\n node.nodeType === 1 &&\n node.namespaceURI === WORD_MAIN_NS &&\n node.localName === localName\n );\n}\n\nfunction insertNumberingNodeInSchemaOrder(root, node, kind) {\n if (!root || !node) return;\n const directChildren = Array.from(root.childNodes || []).filter(\n child => child && child.nodeType === 1 && child.namespaceURI === WORD_MAIN_NS\n );\n\n let anchor = null;\n if (kind === 'abstract') {\n anchor = directChildren.find(\n child => child.localName === 'num' || child.localName === 'numIdMacAtCleanup'\n ) || null;\n } else {\n anchor = directChildren.find(child => child.localName === 'numIdMacAtCleanup') || null;\n }\n\n if (anchor) root.insertBefore(node, anchor);\n else root.appendChild(node);\n}\n\nfunction getAttributeFirst(element, names) {\n for (const name of names || []) {\n const value = element?.getAttribute?.(name);\n if (value != null && value !== '') return value;\n }\n return null;\n}\n\nfunction getElementId(element, names) {\n const raw = getAttributeFirst(element, names);\n const parsed = Number.parseInt(String(raw || ''), 10);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction setElementId(element, preferredName, idValue) {\n element?.setAttribute?.(preferredName, String(idValue));\n}\n\nfunction setElementVal(element, value) {\n element?.setAttribute?.('w:val', String(value));\n}\n\n/**\n * Overwrites all paragraph-level `w:numId` references in a node collection.\n *\n * @param {Node[]|null|undefined} paragraphNodes\n * @param {string|number|null|undefined} targetNumId\n */\nexport function overwriteParagraphNumIds(paragraphNodes, targetNumId) {\n if (!Array.isArray(paragraphNodes) || targetNumId == null) return;\n for (const node of paragraphNodes) {\n const numIdNodes = Array.from(node?.getElementsByTagNameNS?.('*', 'numId') || []);\n for (const numIdNode of numIdNodes) {\n setElementVal(numIdNode, targetNumId);\n }\n }\n}\n\n/**\n * Extracts the first `w:numId` value from a node collection.\n *\n * @param {Node[]|null|undefined} paragraphNodes\n * @returns {string|null}\n */\nexport function extractFirstParagraphNumId(paragraphNodes) {\n for (const node of paragraphNodes || []) {\n const numIdNodes = Array.from(node?.getElementsByTagNameNS?.('*', 'numId') || []);\n for (const numIdNode of numIdNodes) {\n const numId = getElementId(numIdNode, ['w:val', 'val']);\n if (numId != null) return String(numId);\n }\n }\n return null;\n}\n\n/**\n * Builds multilevel decimal numbering XML for explicit-start header conversion.\n *\n * @param {string|number} numId\n * @param {string|number} abstractNumId\n * @param {number} startAt\n * @returns {string}\n */\nexport function buildExplicitDecimalMultilevelNumberingXml(numId, abstractNumId, startAt) {\n const safeNumId = String(numId);\n const safeAbstractNumId = String(abstractNumId);\n const safeStartAt = Number.isInteger(startAt) && startAt > 0 ? startAt : 1;\n const levelsXml = Array.from({ length: 9 }, (_, level) => {\n const lvlText = Array.from({ length: level + 1 }, (_, i) => `%${i + 1}`).join('.') + '.';\n const left = 720 * (level + 1);\n return `\n <w:lvl w:ilvl=\"${level}\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"${lvlText}\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"${left}\" w:hanging=\"360\"/></w:pPr>\n </w:lvl>`;\n }).join('');\n return `\n<w:numbering xmlns:w=\"${WORD_MAIN_NS}\">\n <w:abstractNum w:abstractNumId=\"${safeAbstractNumId}\">\n <w:multiLevelType w:val=\"multilevel\"/>\n ${levelsXml}\n </w:abstractNum>\n <w:num w:numId=\"${safeNumId}\">\n <w:abstractNumId w:val=\"${safeAbstractNumId}\"/>\n <w:lvlOverride w:ilvl=\"0\">\n <w:startOverride w:val=\"${safeStartAt}\"/>\n </w:lvlOverride>\n </w:num>\n</w:numbering>`.trim();\n}\n\n/**\n * Remaps incoming numbering payload IDs to document-safe IDs, and updates the\n * provided replacement nodes to reference the remapped `w:numId` values.\n *\n * @param {string} numberingXml\n * @param {Node[]} replacementNodes\n * @param {ReturnType<typeof createDynamicNumberingIdState>} numberingIdState\n * @returns {{ numberingXml: string, replacementNodes: Node[] }}\n */\nexport function remapNumberingPayloadForDocument(numberingXml, replacementNodes, numberingIdState) {\n const numberingDoc = parseOoxml(numberingXml);\n if (hasXmlParseError(numberingDoc)) {\n return {\n numberingXml: String(numberingXml || ''),\n replacementNodes: Array.isArray(replacementNodes)\n ? replacementNodes.map(node => node?.cloneNode ? node.cloneNode(true) : node)\n : []\n };\n }\n\n const abstractNumMap = new Map();\n const numIdMap = new Map();\n\n const abstractNums = Array.from(numberingDoc.getElementsByTagNameNS('*', 'abstractNum'));\n for (const abstractNum of abstractNums) {\n const oldId = getElementId(abstractNum, ['w:abstractNumId', 'abstractNumId']);\n if (oldId == null) continue;\n const newId = reserveNextNumberingId(numberingIdState, 'abstract');\n if (newId == null) continue;\n abstractNumMap.set(oldId, newId);\n setElementId(abstractNum, 'w:abstractNumId', newId);\n }\n\n const nums = Array.from(numberingDoc.getElementsByTagNameNS('*', 'num'));\n for (const num of nums) {\n const oldNumId = getElementId(num, ['w:numId', 'numId']);\n if (oldNumId == null) continue;\n const newNumId = reserveNextNumberingId(numberingIdState, 'num');\n if (newNumId == null) continue;\n numIdMap.set(oldNumId, newNumId);\n setElementId(num, 'w:numId', newNumId);\n\n const abstractNumIdNode = Array.from(num.getElementsByTagNameNS('*', 'abstractNumId'))[0] || null;\n if (abstractNumIdNode) {\n const oldAbsRef = getElementId(abstractNumIdNode, ['w:val', 'val']);\n if (oldAbsRef != null && abstractNumMap.has(oldAbsRef)) {\n setElementVal(abstractNumIdNode, abstractNumMap.get(oldAbsRef));\n }\n }\n }\n\n const clonedNodes = Array.isArray(replacementNodes)\n ? replacementNodes.map(node => node?.cloneNode ? node.cloneNode(true) : node)\n : [];\n for (const node of clonedNodes) {\n const numIdNodes = Array.from(node?.getElementsByTagNameNS?.('*', 'numId') || []);\n for (const numIdNode of numIdNodes) {\n const oldNumRef = getElementId(numIdNode, ['w:val', 'val']);\n if (oldNumRef != null && numIdMap.has(oldNumRef)) {\n setElementVal(numIdNode, numIdMap.get(oldNumRef));\n }\n }\n }\n\n return {\n numberingXml: serializeOoxml(numberingDoc),\n replacementNodes: clonedNodes\n };\n}\n\n/**\n * Merges incoming numbering definitions into an existing numbering part while\n * preserving schema child order (`abstractNum*` before `num*`).\n *\n * @param {string} existingNumberingXml\n * @param {string} incomingNumberingXml\n * @returns {string}\n */\nexport function mergeNumberingXmlBySchemaOrder(existingNumberingXml, incomingNumberingXml) {\n const existingText = String(existingNumberingXml || '');\n const incomingText = String(incomingNumberingXml || '');\n if (!incomingText.trim()) return existingText;\n if (!existingText.trim()) return incomingText;\n\n try {\n const existingDoc = parseOoxml(existingText);\n const incomingDoc = parseOoxml(incomingText);\n if (hasXmlParseError(existingDoc) || hasXmlParseError(incomingDoc)) {\n return existingText;\n }\n\n const existingRoot = existingDoc.documentElement;\n const incomingRoot = incomingDoc.documentElement;\n if (!existingRoot || !incomingRoot) return existingText;\n\n const existingAbstractIds = new Set(\n Array.from(existingRoot.childNodes || [])\n .filter(node => isDirectWordChild(node, 'abstractNum'))\n .map(node => parseIntegerAttribute(node, ['w:abstractNumId', 'abstractNumId']))\n .filter(id => id != null)\n );\n const existingNumIds = new Set(\n Array.from(existingRoot.childNodes || [])\n .filter(node => isDirectWordChild(node, 'num'))\n .map(node => parseIntegerAttribute(node, ['w:numId', 'numId']))\n .filter(id => id != null)\n );\n\n for (const incomingNode of Array.from(incomingRoot.childNodes || [])) {\n if (!isDirectWordChild(incomingNode, 'abstractNum')) continue;\n const incomingId = parseIntegerAttribute(incomingNode, ['w:abstractNumId', 'abstractNumId']);\n if (incomingId == null || existingAbstractIds.has(incomingId)) continue;\n insertNumberingNodeInSchemaOrder(existingRoot, existingDoc.importNode(incomingNode, true), 'abstract');\n existingAbstractIds.add(incomingId);\n }\n\n for (const incomingNode of Array.from(incomingRoot.childNodes || [])) {\n if (!isDirectWordChild(incomingNode, 'num')) continue;\n const incomingId = parseIntegerAttribute(incomingNode, ['w:numId', 'numId']);\n if (incomingId == null || existingNumIds.has(incomingId)) continue;\n insertNumberingNodeInSchemaOrder(existingRoot, existingDoc.importNode(incomingNode, true), 'num');\n existingNumIds.add(incomingId);\n }\n\n return serializeOoxml(existingDoc);\n } catch {\n return existingText;\n }\n}\n", "/**\n * Word OOXML ingestion helpers for plain-text/markdown export.\n *\n * These helpers are intentionally conservative and only map obvious signals:\n * - Paragraph structure\n * - Heading styles\n * - List paragraph properties\n * - Run-level bold/italic formatting\n */\n\nimport { createParser } from '../adapters/xml-adapter.js';\nimport { NS_W } from '../core/types.js';\nimport { getXmlParseError } from '../core/xml-query.js';\n\nfunction hasParserError(doc) {\n if (!doc || !doc.documentElement) return true;\n if (doc.documentElement.localName === 'parsererror') return true;\n return !!getXmlParseError(doc);\n}\n\nfunction parseWordOoxml(ooxml) {\n const source = typeof ooxml === 'string' ? ooxml : String(ooxml || '');\n if (!source.trim()) {\n return null;\n }\n\n try {\n const parser = createParser();\n const doc = parser.parseFromString(source, 'application/xml');\n if (hasParserError(doc)) {\n return null;\n }\n return doc;\n } catch {\n return null;\n }\n}\n\nfunction getWordParagraphs(doc) {\n if (!doc) return [];\n const namespaced = Array.from(doc.getElementsByTagNameNS(NS_W, 'p'));\n if (namespaced.length > 0) return namespaced;\n return Array.from(doc.getElementsByTagNameNS('*', 'p')).filter(node => node?.localName === 'p');\n}\n\nfunction getDirectWordChild(node, localName) {\n const children = Array.from(node?.childNodes || []);\n for (const child of children) {\n if (child?.nodeType !== 1) continue;\n if (child.namespaceURI !== NS_W) continue;\n if (child.localName === localName) return child;\n }\n return null;\n}\n\nfunction getWordDescendants(node, localName) {\n return Array.from(node?.getElementsByTagNameNS?.(NS_W, localName) || []);\n}\n\nfunction getWordAttribute(element, names) {\n if (!element) return '';\n for (const name of names) {\n const value = element.getAttribute(name);\n if (value != null && value !== '') return value;\n }\n return '';\n}\n\nfunction hasWordAncestorWithin(node, localName, boundary) {\n let cursor = node?.parentNode || null;\n while (cursor && cursor !== boundary) {\n if (cursor.nodeType === 1 && cursor.namespaceURI === NS_W && cursor.localName === localName) {\n return true;\n }\n cursor = cursor.parentNode;\n }\n return false;\n}\n\nfunction readRunText(run) {\n let text = '';\n for (const child of Array.from(run?.childNodes || [])) {\n if (!child || child.nodeType !== 1 || child.namespaceURI !== NS_W) continue;\n if (child.localName === 't') {\n text += child.textContent || '';\n } else if (child.localName === 'tab') {\n text += '\\t';\n } else if (child.localName === 'br' || child.localName === 'cr') {\n text += '\\n';\n } else if (child.localName === 'noBreakHyphen') {\n text += '\\u2011';\n }\n }\n return text;\n}\n\nfunction getRunFormatting(run) {\n const rPr = getDirectWordChild(run, 'rPr');\n if (!rPr) return { bold: false, italic: false };\n const rStyle = getWordDescendants(rPr, 'rStyle')[0] || null;\n const rStyleValue = getWordAttribute(rStyle, ['w:val', 'val']).toLowerCase();\n const styleImpliesBold = rStyleValue.includes('strong') || rStyleValue.includes('bold');\n const styleImpliesItalic = rStyleValue.includes('italic') || rStyleValue.includes('emphasis');\n return {\n bold: getWordDescendants(rPr, 'b').length > 0 || styleImpliesBold,\n italic: getWordDescendants(rPr, 'i').length > 0 || styleImpliesItalic\n };\n}\n\nfunction collectParagraphSegments(paragraph) {\n const segments = [];\n const runs = Array.from(paragraph?.getElementsByTagNameNS?.(NS_W, 'r') || []);\n for (const run of runs) {\n if (hasWordAncestorWithin(run, 'del', paragraph)) continue;\n const text = readRunText(run);\n if (!text) continue;\n segments.push({\n text,\n ...getRunFormatting(run)\n });\n }\n return segments;\n}\n\nfunction normalizeInlineWhitespace(text) {\n const normalizedLines = String(text || '')\n .replace(/\\r/g, '')\n .split('\\n')\n .map(line => line.replace(/[ \\t]+/g, ' ').trim());\n return normalizedLines.join('\\n').trim();\n}\n\nfunction wrapRunMarkdown(text, format) {\n const raw = String(text || '');\n if (!raw) return '';\n if (!format?.bold && !format?.italic) return raw;\n\n const match = raw.match(/^(\\s*)([\\s\\S]*?)(\\s*)$/);\n if (!match) return raw;\n const leading = match[1] || '';\n const core = match[2] || '';\n const trailing = match[3] || '';\n if (!core.trim()) return raw;\n\n let wrapped = core;\n if (format.bold && format.italic) wrapped = `***${core}***`;\n else if (format.bold) wrapped = `**${core}**`;\n else if (format.italic) wrapped = `*${core}*`;\n return `${leading}${wrapped}${trailing}`;\n}\n\nfunction parseHeadingLevel(paragraph) {\n const pPr = getDirectWordChild(paragraph, 'pPr');\n if (!pPr) return null;\n\n const pStyle = getWordDescendants(pPr, 'pStyle')[0] || null;\n const styleVal = getWordAttribute(pStyle, ['w:val', 'val']);\n if (styleVal) {\n const match = styleVal.match(/^heading\\s*([1-9])$/i);\n if (match) {\n const level = Number.parseInt(match[1], 10);\n if (Number.isInteger(level)) return Math.min(Math.max(level, 1), 6);\n }\n }\n\n const outlineLvl = getWordDescendants(pPr, 'outlineLvl')[0] || null;\n const outlineRaw = getWordAttribute(outlineLvl, ['w:val', 'val']);\n const outline = Number.parseInt(outlineRaw, 10);\n if (Number.isInteger(outline) && outline >= 0) {\n return Math.min(outline + 1, 6);\n }\n\n return null;\n}\n\nfunction parseListInfo(paragraph) {\n const pPr = getDirectWordChild(paragraph, 'pPr');\n if (!pPr) return null;\n\n const numPr = getWordDescendants(pPr, 'numPr')[0] || null;\n if (!numPr) return null;\n\n const ilvlEl = getWordDescendants(numPr, 'ilvl')[0] || null;\n const numIdEl = getWordDescendants(numPr, 'numId')[0] || null;\n const ilvl = Number.parseInt(getWordAttribute(ilvlEl, ['w:val', 'val']), 10);\n const numId = getWordAttribute(numIdEl, ['w:val', 'val']);\n\n const safeLevel = Number.isInteger(ilvl) && ilvl >= 0 ? ilvl : 0;\n const marker = numId === '1' ? '-' : '1.';\n return { level: safeLevel, marker };\n}\n\nfunction paragraphToPlainText(paragraph) {\n const text = collectParagraphSegments(paragraph).map(segment => segment.text).join('');\n return normalizeInlineWhitespace(text);\n}\n\nfunction paragraphToMarkdown(paragraph) {\n const segments = collectParagraphSegments(paragraph);\n const inline = segments.map(segment => wrapRunMarkdown(segment.text, segment)).join('');\n const normalizedInline = normalizeInlineWhitespace(inline);\n if (!normalizedInline) return '';\n\n const headingLevel = parseHeadingLevel(paragraph);\n if (headingLevel != null) {\n return `${'#'.repeat(headingLevel)} ${normalizedInline}`;\n }\n\n const list = parseListInfo(paragraph);\n if (list) {\n const indent = ' '.repeat(list.level);\n return `${indent}${list.marker} ${normalizedInline}`;\n }\n\n return normalizedInline;\n}\n\n/**\n * Ingests Word OOXML and returns readable plain text.\n *\n * @param {string} ooxml\n * @returns {string}\n */\nexport function ingestWordOoxmlToPlainText(ooxml) {\n const doc = parseWordOoxml(ooxml);\n if (!doc) return '';\n\n const paragraphs = getWordParagraphs(doc);\n if (paragraphs.length === 0) {\n const fallback = normalizeInlineWhitespace(doc.documentElement?.textContent || '');\n return fallback;\n }\n\n const lines = paragraphs.map(paragraphToPlainText);\n return lines.join('\\n\\n').trim();\n}\n\n/**\n * Ingests Word OOXML and returns basic markdown.\n *\n * @param {string} ooxml\n * @returns {string}\n */\nexport function ingestWordOoxmlToMarkdown(ooxml) {\n const doc = parseWordOoxml(ooxml);\n if (!doc) return '';\n\n const paragraphs = getWordParagraphs(doc);\n if (paragraphs.length === 0) {\n return '';\n }\n\n const lines = paragraphs.map(paragraphToMarkdown);\n return lines.join('\\n\\n').trim();\n}\n", "/**\r\n * Comment XML builders.\r\n */\r\n\r\nimport { NS_W, escapeXml } from '../core/types.js';\r\n\r\n/**\r\n * Builds a single w:comment element.\r\n *\r\n * @param {number} commentId - Unique comment ID\r\n * @param {string} author - Author name\r\n * @param {string} content - Comment text content\r\n * @param {string} date - ISO date string\r\n * @returns {string}\r\n */\r\nexport function buildCommentElement(commentId, author, content, date) {\r\n const initials = author.split(' ').map(word => word[0]).join('').toUpperCase() || 'AI';\r\n const escapedContent = escapeXml(content);\r\n const escapedAuthor = escapeXml(author);\r\n\r\n return `<w:comment w:id=\"${commentId}\" w:author=\"${escapedAuthor}\" w:date=\"${date}\" w:initials=\"${initials}\">\r\n <w:p>\r\n <w:r><w:t>${escapedContent}</w:t></w:r>\r\n </w:p>\r\n </w:comment>`;\r\n}\r\n\r\n/**\r\n * Builds the complete comments.xml part.\r\n *\r\n * @param {Array<{id:number,content:string,author:string,date:string}>} comments - Placed comments\r\n * @returns {string}\r\n */\r\nexport function buildCommentsPartXml(comments) {\r\n if (!comments || comments.length === 0) {\r\n return `<w:comments xmlns:w=\"${NS_W}\"></w:comments>`;\r\n }\r\n\r\n const commentElements = comments.map(comment =>\r\n buildCommentElement(comment.id, comment.author, comment.content, comment.date)\r\n ).join('\\n ');\r\n\r\n return `<w:comments xmlns:w=\"${NS_W}\">\r\n ${commentElements}\r\n </w:comments>`;\r\n}\r\n\r\n/**\r\n * Builds inline range/reference markers for a comment id.\r\n *\r\n * @param {number} commentId - The comment ID\r\n * @returns {{ start: string, end: string, reference: string }}\r\n */\r\nexport function buildCommentMarkers(commentId) {\r\n return {\r\n start: `<w:commentRangeStart w:id=\"${commentId}\"/>`,\r\n end: `<w:commentRangeEnd w:id=\"${commentId}\"/>`,\r\n reference: `<w:r><w:rPr></w:rPr><w:commentReference w:id=\"${commentId}\"/></w:r>`\r\n };\r\n}\r\n", "/**\r\n * Comment text location and marker injection helpers.\r\n */\r\n\r\nimport { NS_W } from '../core/types.js';\r\nimport { getElementsByTag, getFirstElementByTag } from '../core/xml-query.js';\r\n\r\n/**\r\n * Builds a paragraph text index in a single pass for repeated lookups.\r\n *\r\n * @param {Element} paragraph - w:p element\r\n * @returns {{ fullText: string, runOffsets: Array<{run: Element, start: number, end: number}> }}\r\n */\r\nexport function createParagraphTextIndex(paragraph) {\r\n const runs = getElementsByTag(paragraph, 'w:r');\r\n const runOffsets = [];\r\n let fullText = '';\r\n\r\n for (const run of runs) {\r\n const start = fullText.length;\r\n const textNodes = getElementsByTag(run, 'w:t');\r\n for (const textNode of textNodes) {\r\n fullText += textNode.textContent || '';\r\n }\r\n runOffsets.push({ run, start, end: fullText.length });\r\n }\r\n\r\n return { fullText, runOffsets };\r\n}\r\n\r\n/**\r\n * Finds text within a prebuilt paragraph text index.\r\n *\r\n * @param {{ fullText: string, runOffsets: Array<{run: Element, start: number, end: number}> }} paragraphIndex - Prebuilt index\r\n * @param {string} searchText - Text to locate\r\n * @returns {{ found: boolean, startRun?: Element, startOffset?: number, endRun?: Element, endOffset?: number }}\r\n */\r\nexport function findTextInParagraphIndex(paragraphIndex, searchText) {\r\n const searchIndex = paragraphIndex.fullText.indexOf(searchText);\r\n if (searchIndex === -1) {\r\n return { found: false };\r\n }\r\n\r\n const searchEnd = searchIndex + searchText.length;\r\n let startRun = null;\r\n let endRun = null;\r\n let startOffset = 0;\r\n let endOffset = 0;\r\n\r\n for (const { run, start, end } of paragraphIndex.runOffsets) {\r\n if (searchIndex >= start && searchIndex < end) {\r\n startRun = run;\r\n startOffset = searchIndex - start;\r\n }\r\n if (searchEnd > start && searchEnd <= end) {\r\n endRun = run;\r\n endOffset = searchEnd - start;\r\n }\r\n }\r\n\r\n return {\r\n found: true,\r\n startRun,\r\n startOffset,\r\n endRun,\r\n endOffset\r\n };\r\n}\r\n\r\nfunction cloneRunWithText(xmlDoc, rPr, newText) {\r\n const newRun = xmlDoc.createElementNS(NS_W, 'w:r');\r\n if (rPr) {\r\n newRun.appendChild(rPr.cloneNode(true));\r\n }\r\n\r\n const newTextNode = xmlDoc.createElementNS(NS_W, 'w:t');\r\n newTextNode.setAttribute('xml:space', 'preserve');\r\n newTextNode.textContent = newText;\r\n newRun.appendChild(newTextNode);\r\n return newRun;\r\n}\r\n\r\n/**\r\n * Injects comment markers around text in a paragraph.\r\n *\r\n * @param {Document} xmlDoc - XML document\r\n * @param {Element} paragraph - w:p element\r\n * @param {string} textToFind - Target text\r\n * @param {number} commentId - Comment id\r\n * @param {{ fullText: string, runOffsets: Array<{run: Element, start: number, end: number}> }|null} [paragraphIndex=null] - Optional prebuilt index\r\n * @returns {boolean}\r\n */\r\nexport function injectMarkersIntoParagraph(xmlDoc, paragraph, textToFind, commentId, paragraphIndex = null) {\r\n const activeIndex = paragraphIndex || createParagraphTextIndex(paragraph);\r\n const location = findTextInParagraphIndex(activeIndex, textToFind);\r\n if (!location.found || !location.startRun) {\r\n return false;\r\n }\r\n\r\n const startMarker = xmlDoc.createElementNS(NS_W, 'w:commentRangeStart');\r\n startMarker.setAttribute('w:id', String(commentId));\r\n\r\n const endMarker = xmlDoc.createElementNS(NS_W, 'w:commentRangeEnd');\r\n endMarker.setAttribute('w:id', String(commentId));\r\n\r\n const referenceRun = xmlDoc.createElementNS(NS_W, 'w:r');\r\n const reference = xmlDoc.createElementNS(NS_W, 'w:commentReference');\r\n reference.setAttribute('w:id', String(commentId));\r\n referenceRun.appendChild(reference);\r\n\r\n if (location.startRun === location.endRun) {\r\n const run = location.startRun;\r\n const textNode = getFirstElementByTag(run, 'w:t');\r\n if (!textNode) {\r\n run.parentNode.insertBefore(startMarker, run);\r\n if (run.nextSibling) {\r\n run.parentNode.insertBefore(endMarker, run.nextSibling);\r\n endMarker.parentNode.insertBefore(referenceRun, endMarker.nextSibling);\r\n } else {\r\n run.parentNode.appendChild(endMarker);\r\n run.parentNode.appendChild(referenceRun);\r\n }\r\n return true;\r\n }\r\n\r\n const fullText = textNode.textContent || '';\r\n const beforeText = fullText.substring(0, location.startOffset);\r\n const highlightedText = fullText.substring(location.startOffset, location.endOffset);\r\n const afterText = fullText.substring(location.endOffset);\r\n const rPr = getFirstElementByTag(run, 'w:rPr');\r\n const parent = run.parentNode;\r\n\r\n if (beforeText) {\r\n parent.insertBefore(cloneRunWithText(xmlDoc, rPr, beforeText), run);\r\n }\r\n\r\n parent.insertBefore(startMarker, run);\r\n textNode.textContent = highlightedText;\r\n\r\n if (run.nextSibling) {\r\n parent.insertBefore(endMarker, run.nextSibling);\r\n } else {\r\n parent.appendChild(endMarker);\r\n }\r\n parent.insertBefore(referenceRun, endMarker.nextSibling || null);\r\n\r\n if (afterText) {\r\n parent.insertBefore(cloneRunWithText(xmlDoc, rPr, afterText), referenceRun.nextSibling || null);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n const startTextNode = getFirstElementByTag(location.startRun, 'w:t');\r\n if (startTextNode && location.startOffset > 0) {\r\n const fullText = startTextNode.textContent || '';\r\n const beforeText = fullText.substring(0, location.startOffset);\r\n const highlightedStart = fullText.substring(location.startOffset);\r\n\r\n if (beforeText) {\r\n const rPr = getFirstElementByTag(location.startRun, 'w:rPr');\r\n location.startRun.parentNode.insertBefore(cloneRunWithText(xmlDoc, rPr, beforeText), location.startRun);\r\n }\r\n startTextNode.textContent = highlightedStart;\r\n }\r\n\r\n location.startRun.parentNode.insertBefore(startMarker, location.startRun);\r\n\r\n const endRun = location.endRun || location.startRun;\r\n const endTextNode = getFirstElementByTag(endRun, 'w:t');\r\n if (endTextNode && location.endOffset < (endTextNode.textContent || '').length) {\r\n const fullText = endTextNode.textContent || '';\r\n const highlightedEnd = fullText.substring(0, location.endOffset);\r\n const afterText = fullText.substring(location.endOffset);\r\n\r\n endTextNode.textContent = highlightedEnd;\r\n\r\n if (afterText) {\r\n const rPr = getFirstElementByTag(endRun, 'w:rPr');\r\n if (endRun.nextSibling) {\r\n endRun.parentNode.insertBefore(cloneRunWithText(xmlDoc, rPr, afterText), endRun.nextSibling);\r\n } else {\r\n endRun.parentNode.appendChild(cloneRunWithText(xmlDoc, rPr, afterText));\r\n }\r\n }\r\n }\r\n\r\n if (endRun.nextSibling) {\r\n endRun.parentNode.insertBefore(endMarker, endRun.nextSibling);\r\n endMarker.parentNode.insertBefore(referenceRun, endMarker.nextSibling);\r\n } else {\r\n endRun.parentNode.appendChild(endMarker);\r\n endRun.parentNode.appendChild(referenceRun);\r\n }\r\n\r\n return true;\r\n}\r\n", "/**\r\n * Comment package builders and pkg:part wiring.\r\n */\r\n\r\nimport { createParser, createSerializer } from '../adapters/xml-adapter.js';\r\nimport { error as logError } from '../adapters/logger.js';\r\nimport { buildDocumentCommentsPackage, buildParagraphCommentsPackage } from './package-builder.js';\r\nimport { getElementsByTagNS, getXmlParseError } from '../core/xml-query.js';\r\n\r\nconst PKG_NS = 'http://schemas.microsoft.com/office/2006/xmlPackage';\r\nconst RELS_NS = 'http://schemas.openxmlformats.org/package/2006/relationships';\r\n\r\n/**\r\n * Wraps paragraph XML with minimal package structure including comments part.\r\n *\r\n * @param {string} paragraphXml - Paragraph XML content\r\n * @param {string} commentsXml - comments.xml payload\r\n * @returns {string}\r\n */\r\nexport function wrapParagraphWithComments(paragraphXml, commentsXml) {\r\n return buildParagraphCommentsPackage(paragraphXml, commentsXml);\r\n}\r\n\r\n/**\r\n * Injects comments.xml and relationship entry into an existing pkg:package.\r\n *\r\n * @param {string} packageOxml - Existing package XML\r\n * @param {string} commentsXml - comments.xml payload\r\n * @returns {string}\r\n */\r\nexport function injectCommentsIntoPackage(packageOxml, commentsXml) {\r\n const parser = createParser();\r\n const serializer = createSerializer();\r\n const pkgDoc = parser.parseFromString(packageOxml, 'text/xml');\r\n\r\n const parseError = getXmlParseError(pkgDoc);\r\n if (parseError) {\r\n logError('[CommentEngine] Failed to parse package:', parseError.textContent);\r\n return packageOxml;\r\n }\r\n\r\n const pkgPackage = pkgDoc.documentElement;\r\n\r\n const commentsPart = pkgDoc.createElementNS(PKG_NS, 'pkg:part');\r\n commentsPart.setAttribute('pkg:name', '/word/comments.xml');\r\n commentsPart.setAttribute('pkg:contentType', 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml');\r\n\r\n const commentsXmlData = pkgDoc.createElementNS(PKG_NS, 'pkg:xmlData');\r\n const commentsDoc = parser.parseFromString(commentsXml, 'text/xml');\r\n commentsXmlData.appendChild(pkgDoc.importNode(commentsDoc.documentElement, true));\r\n commentsPart.appendChild(commentsXmlData);\r\n pkgPackage.appendChild(commentsPart);\r\n\r\n const parts = getElementsByTagNS(pkgPackage, PKG_NS, 'part');\r\n const docRelsPart = parts.find(part => part.getAttribute('pkg:name') === '/word/_rels/document.xml.rels');\r\n\r\n if (docRelsPart) {\r\n const xmlDataNodes = getElementsByTagNS(docRelsPart, PKG_NS, 'xmlData');\r\n if (xmlDataNodes.length > 0) {\r\n const relsNodes = getElementsByTagNS(xmlDataNodes[0], RELS_NS, 'Relationships');\r\n if (relsNodes.length > 0) {\r\n const relationships = relsNodes[0];\r\n const existingRels = getElementsByTagNS(relationships, RELS_NS, 'Relationship');\r\n const hasCommentsRel = existingRels.some(rel =>\r\n rel.getAttribute('Type')?.includes('comments')\r\n );\r\n\r\n if (!hasCommentsRel) {\r\n let maxId = 0;\r\n existingRels.forEach(rel => {\r\n const id = rel.getAttribute('Id');\r\n const idNumber = parseInt(id?.replace('rId', '') || '0', 10);\r\n if (idNumber > maxId) maxId = idNumber;\r\n });\r\n\r\n const newRel = pkgDoc.createElementNS(RELS_NS, 'Relationship');\r\n newRel.setAttribute('Id', `rId${maxId + 1}`);\r\n newRel.setAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments');\r\n newRel.setAttribute('Target', 'comments.xml');\r\n relationships.appendChild(newRel);\r\n }\r\n }\r\n }\r\n } else {\r\n const newDocRelsPart = pkgDoc.createElementNS(PKG_NS, 'pkg:part');\r\n newDocRelsPart.setAttribute('pkg:name', '/word/_rels/document.xml.rels');\r\n newDocRelsPart.setAttribute('pkg:contentType', 'application/vnd.openxmlformats-package.relationships+xml');\r\n\r\n const relsXmlData = pkgDoc.createElementNS(PKG_NS, 'pkg:xmlData');\r\n const relationships = pkgDoc.createElementNS(RELS_NS, 'Relationships');\r\n const commentsRel = pkgDoc.createElementNS(RELS_NS, 'Relationship');\r\n commentsRel.setAttribute('Id', 'rId1');\r\n commentsRel.setAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments');\r\n commentsRel.setAttribute('Target', 'comments.xml');\r\n relationships.appendChild(commentsRel);\r\n relsXmlData.appendChild(relationships);\r\n newDocRelsPart.appendChild(relsXmlData);\r\n pkgPackage.appendChild(newDocRelsPart);\r\n }\r\n\r\n return serializer.serializeToString(pkgDoc);\r\n}\r\n\r\n/**\r\n * @deprecated Use injectCommentsIntoPackage instead.\r\n *\r\n * @param {string} documentXml - Document OOXML\r\n * @param {string} commentsXml - comments.xml payload\r\n * @returns {string}\r\n */\r\nexport function wrapWithCommentsPart(documentXml, commentsXml) {\r\n return buildDocumentCommentsPackage(documentXml, commentsXml);\r\n}\r\n", "/**\r\n * OOXML Comment Engine\r\n *\r\n * Provides pure OOXML-based comment insertion without Word JS API calls.\r\n */\r\n\r\nimport { NS_W, getNextRevisionId, getRevisionTimestamp, resetRevisionIdCounter } from '../core/types.js';\r\nimport { createParser, createSerializer } from '../adapters/xml-adapter.js';\nimport { log, error as logError } from '../adapters/logger.js';\nimport { getElementsByTag, getFirstElementByTag, getXmlParseError } from '../core/xml-query.js';\nimport { buildCommentElement, buildCommentsPartXml, buildCommentMarkers } from './comment-builders.js';\nimport { getDefaultAuthor } from '../adapters/config.js';\nimport { createParagraphTextIndex, injectMarkersIntoParagraph } from './comment-locator.js';\nimport {\n injectCommentsIntoPackage as injectCommentsIntoExistingPackage,\r\n wrapParagraphWithComments,\r\n wrapWithCommentsPart\r\n} from './comment-package.js';\r\n\r\nexport { getNextRevisionId, resetRevisionIdCounter };\r\nexport { buildCommentElement, buildCommentsPartXml, buildCommentMarkers };\r\n\r\n/**\r\n * @typedef {Object} CommentRequest\r\n * @property {number} paragraphIndex - 1-based paragraph index\r\n * @property {string} textToFind - Text to attach comment to\r\n * @property {string} commentContent - The comment text\r\n */\r\n\r\n/**\r\n * @typedef {Object} CommentInjectionResult\r\n * @property {string} oxml - Complete OOXML package with comments\r\n * @property {string} [commentsXml] - comments.xml content when comments are applied\r\n * @property {number} commentsApplied - Number of successfully placed comments\r\n * @property {string[]} warnings - Any issues encountered\r\n */\r\n\r\nfunction parseDocumentOxml(oxml, parser, parseFailureWarning) {\r\n try {\r\n const xmlDoc = parser.parseFromString(oxml, 'text/xml');\r\n const parseError = getXmlParseError(xmlDoc);\r\n if (parseError) {\r\n return { xmlDoc: null, warning: parseFailureWarning(parseError.textContent || 'parse error') };\r\n }\r\n return { xmlDoc, warning: null };\r\n } catch (error) {\r\n return { xmlDoc: null, warning: parseFailureWarning(error.message) };\r\n }\r\n}\r\n\r\n/**\r\n * Injects comments into OOXML using pure XML manipulation.\r\n *\r\n * @param {string} oxml - Original document OOXML\r\n * @param {CommentRequest[]} comments - Comment requests\r\n * @param {Object} [options={}] - Options\r\n * @param {string} [options.author] - Author for comments (defaults to configured default author)\n * @returns {CommentInjectionResult}\n */\nexport function injectCommentsIntoOoxml(oxml, comments, options = {}) {\n const author = options?.author || getDefaultAuthor();\n const date = getRevisionTimestamp();\r\n const warnings = [];\r\n const placedComments = [];\r\n\r\n if (!comments || comments.length === 0) {\r\n return {\r\n oxml,\r\n commentsApplied: 0,\r\n warnings: ['No comments to inject']\r\n };\r\n }\r\n\r\n const parser = createParser();\r\n const serializer = createSerializer();\r\n const parseResult = parseDocumentOxml(\r\n oxml,\r\n parser,\r\n warning => `Failed to parse OXML: ${warning}`\r\n );\r\n\r\n if (!parseResult.xmlDoc) {\r\n logError('[CommentEngine] Parse failure:', parseResult.warning);\r\n return {\r\n oxml,\r\n commentsApplied: 0,\r\n warnings: [parseResult.warning]\r\n };\r\n }\r\n\r\n const xmlDoc = parseResult.xmlDoc;\r\n const paragraphs = getElementsByTag(xmlDoc, 'w:p');\r\n log(`[CommentEngine] Found ${paragraphs.length} paragraphs, processing ${comments.length} comment requests`);\r\n\r\n /** @type {Map<number, number>} */\r\n const remainingRequestsByParagraph = new Map();\r\n for (const request of comments) {\r\n const paragraphIndex = request.paragraphIndex - 1;\r\n if (paragraphIndex < 0 || paragraphIndex >= paragraphs.length) {\r\n warnings.push(`Paragraph ${request.paragraphIndex} out of range (1-${paragraphs.length})`);\r\n continue;\r\n }\r\n remainingRequestsByParagraph.set(paragraphIndex, (remainingRequestsByParagraph.get(paragraphIndex) || 0) + 1);\r\n }\r\n\r\n /** @type {Map<number, { fullText: string, runOffsets: Array<{run: Element, start: number, end: number}> }>} */\r\n const paragraphIndexes = new Map();\r\n\r\n for (const request of comments) {\r\n const paragraphIndex = request.paragraphIndex - 1;\r\n if (paragraphIndex < 0 || paragraphIndex >= paragraphs.length) {\r\n continue;\r\n }\r\n\r\n const targetParagraph = paragraphs[paragraphIndex];\r\n let textIndex = paragraphIndexes.get(paragraphIndex);\r\n if (!textIndex) {\r\n textIndex = createParagraphTextIndex(targetParagraph);\r\n paragraphIndexes.set(paragraphIndex, textIndex);\r\n }\r\n\r\n const commentId = getNextRevisionId();\r\n const success = injectMarkersIntoParagraph(\r\n xmlDoc,\r\n targetParagraph,\r\n request.textToFind,\r\n commentId,\r\n textIndex\r\n );\r\n\r\n const remaining = (remainingRequestsByParagraph.get(paragraphIndex) || 1) - 1;\r\n remainingRequestsByParagraph.set(paragraphIndex, remaining);\r\n\r\n if (!success) {\r\n warnings.push(`Could not find \"${request.textToFind.substring(0, 30)}...\" in paragraph ${request.paragraphIndex}`);\r\n if (remaining === 0) {\r\n paragraphIndexes.delete(paragraphIndex);\r\n }\r\n continue;\r\n }\r\n\r\n placedComments.push({\r\n id: commentId,\r\n content: request.commentContent,\r\n author,\r\n date\r\n });\r\n\r\n if (remaining > 0) {\r\n // Rebuild only when another request still targets this paragraph.\r\n paragraphIndexes.set(paragraphIndex, createParagraphTextIndex(targetParagraph));\r\n } else {\r\n paragraphIndexes.delete(paragraphIndex);\r\n }\r\n }\r\n\r\n if (placedComments.length === 0) {\r\n return {\r\n oxml,\r\n commentsApplied: 0,\r\n warnings\r\n };\r\n }\r\n\r\n return {\r\n oxml: serializer.serializeToString(xmlDoc),\r\n commentsXml: buildCommentsPartXml(placedComments),\r\n commentsApplied: placedComments.length,\r\n warnings\r\n };\r\n}\r\n\r\n/**\r\n * Injects a comment into a single paragraph OOXML and returns a complete mini-package.\r\n *\r\n * @param {string} paragraphOoxml - Paragraph OOXML (raw paragraph or pkg:package)\r\n * @param {string} textToFind - Target text\r\n * @param {string} commentContent - Comment body\r\n * @param {Object} [options={}] - Options\r\n * @param {string} [options.author='AI Assistant'] - Comment author\r\n * @returns {{ success: boolean, package?: string, warning?: string, commentId?: number }}\r\n */\r\nexport function injectCommentIntoParagraphOoxml(paragraphOoxml, textToFind, commentContent, options = {}) {\r\n const { author = 'AI Assistant' } = options;\r\n const date = getRevisionTimestamp();\r\n const commentId = getNextRevisionId();\r\n\r\n const parser = createParser();\r\n const serializer = createSerializer();\r\n const parseResult = parseDocumentOxml(\r\n paragraphOoxml,\r\n parser,\r\n warning => `Failed to parse paragraph OOXML: ${warning}`\r\n );\r\n\r\n if (!parseResult.xmlDoc) {\r\n return { success: false, warning: parseResult.warning };\r\n }\r\n\r\n const xmlDoc = parseResult.xmlDoc;\r\n const paragraphs = getElementsByTag(xmlDoc, 'w:p');\r\n if (paragraphs.length === 0) {\r\n return { success: false, warning: 'No paragraph found in OOXML' };\r\n }\r\n\r\n const paragraph = paragraphs[0];\r\n const paragraphIndex = createParagraphTextIndex(paragraph);\r\n const success = injectMarkersIntoParagraph(xmlDoc, paragraph, textToFind, commentId, paragraphIndex);\r\n if (!success) {\r\n return { success: false, warning: `Could not find \"${textToFind.substring(0, 30)}...\" in paragraph` };\r\n }\r\n\r\n const commentElement = buildCommentElement(commentId, author, commentContent, date);\r\n const commentsXml = `<w:comments xmlns:w=\"${NS_W}\">${commentElement}</w:comments>`;\r\n const pkgPackage = getFirstElementByTag(xmlDoc, 'pkg:package');\r\n\r\n if (pkgPackage) {\r\n const withComments = injectCommentsIntoExistingPackage(serializer.serializeToString(xmlDoc), commentsXml);\r\n return { success: true, package: withComments, commentId };\r\n }\r\n\r\n const modifiedParagraphXml = serializer.serializeToString(xmlDoc);\r\n return {\r\n success: true,\r\n package: wrapParagraphWithComments(modifiedParagraphXml, commentsXml),\r\n commentId\r\n };\r\n}\r\n\r\n/**\r\n * Injects comments part into an existing OOXML package from getOoxml().\r\n *\r\n * @param {string} packageOxml - Existing pkg:package\r\n * @param {string} commentsXml - comments.xml payload\r\n * @returns {string}\r\n */\r\nexport function injectCommentsIntoPackage(packageOxml, commentsXml) {\r\n return injectCommentsIntoExistingPackage(packageOxml, commentsXml);\r\n}\r\n\r\n/**\r\n * @deprecated Use injectCommentsIntoPackage instead.\r\n *\r\n * @param {string} documentXml - Document XML\r\n * @param {string} commentsXml - comments.xml payload\r\n * @returns {string}\r\n */\r\nexport { wrapWithCommentsPart };\r\n", "/**\r\n * OOXML Formatting Removal Utilities\r\n * \r\n * Provides functions to surgically remove formatting from OOXML runs\r\n * while preserving the text content and other properties.\r\n */\r\n\r\nimport { parseOoxml, serializeOoxml } from './oxml-engine.js';\nimport { getDefaultAuthor } from '../adapters/config.js';\n\r\n/**\r\n * Removes specific formatting properties from a run properties (w:rPr) element.\r\n * This allows surgical removal of bold, italic, underline, color, etc. from OOXML.\r\n * \r\n * @param {Element} rPr - The w:rPr element to modify\r\n * @param {string[]} formatTypes - Array of format types to remove: ['bold', 'italic', 'underline', 'strikethrough', 'color', 'highlight', 'fontSize', 'fontFamily', 'all']\r\n * @returns {Element|null} Modified rPr element, or null if all formatting removed\r\n */\r\nexport function removeFormattingFromRPr(rPr, formatTypes = ['all']) {\r\n if (!rPr) return null;\r\n\r\n const rPrClone = rPr.cloneNode(true);\r\n\r\n if (formatTypes.includes('all')) {\r\n // Remove all character formatting properties\r\n const toRemove = ['w:b', 'w:i', 'w:u', 'w:strike', 'w:dstrike', 'w:color',\r\n 'w:sz', 'w:szCs', 'w:rFonts', 'w:highlight', 'w:vertAlign',\r\n 'w:spacing', 'w:w', 'w:kern', 'w:position'];\r\n toRemove.forEach(tag => {\r\n // Handle both namespaced and non-namespaced versions\r\n const elements = rPrClone.querySelectorAll(`${tag}, ${tag.replace('w:', '')}`);\r\n elements.forEach(el => el.remove());\r\n });\r\n } else {\r\n // Remove specific properties\r\n const tagMap = {\r\n 'bold': 'w:b',\r\n 'italic': 'w:i',\r\n 'underline': 'w:u',\r\n 'strikethrough': 'w:strike',\r\n 'doubleStrike': 'w:dstrike',\r\n 'color': 'w:color',\r\n 'highlight': 'w:highlight',\r\n 'fontSize': 'w:sz',\r\n 'fontSizeCs': 'w:szCs', // Complex script font size\r\n 'fontFamily': 'w:rFonts',\r\n 'superscript': 'w:vertAlign',\r\n 'subscript': 'w:vertAlign'\r\n };\r\n\r\n formatTypes.forEach(type => {\r\n const tag = tagMap[type];\r\n if (tag) {\r\n // Handle both namespaced and non-namespaced versions\r\n const elements = rPrClone.querySelectorAll(`${tag}, ${tag.replace('w:', '')}`);\r\n elements.forEach(el => el.remove());\r\n }\r\n });\r\n }\r\n\r\n // Return null if rPr is now empty (no children)\r\n return rPrClone.children.length > 0 ? rPrClone : null;\r\n}\r\n\r\n/**\r\n * Applies formatting removal to OOXML containing the specified text.\r\n * Searches for text in runs and removes specified formatting properties.\r\n * \r\n * @param {string} ooxmlString - OOXML string (paragraph or larger structure)\r\n * @param {string} targetText - Text to find and remove formatting from\r\n * @param {string[]} formatTypes - Array of format types to remove\r\n * @returns {string} Modified OOXML string\r\n */\r\nexport function applyFormattingRemovalToOoxml(ooxmlString, targetText, formatTypes) {\r\n if (!targetText || !ooxmlString) return ooxmlString;\r\n\r\n const doc = parseOoxml(ooxmlString);\r\n const NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\r\n\r\n // Find all text runs\r\n const runs = doc.getElementsByTagNameNS(NS_W, 'r');\r\n\r\n // Also handle runs inside w:ins (insertions)\r\n const insertions = doc.getElementsByTagNameNS(NS_W, 'ins');\r\n const allRuns = [...Array.from(runs)];\r\n\r\n for (const ins of insertions) {\r\n const insideRuns = ins.getElementsByTagNameNS(NS_W, 'r');\r\n allRuns.push(...Array.from(insideRuns));\r\n }\r\n\r\n for (const run of allRuns) {\r\n // Extract text from this run\r\n const textNodes = run.getElementsByTagNameNS(NS_W, 't');\r\n const runText = Array.from(textNodes).map(t => t.textContent).join('');\r\n\r\n // If this run contains the target text (or equals it)\r\n if (runText.includes(targetText) || runText === targetText) {\r\n // Find the rPr element\r\n const rPrElements = run.getElementsByTagNameNS(NS_W, 'rPr');\r\n\r\n if (rPrElements.length > 0) {\r\n const rPr = rPrElements[0];\r\n const newRPr = removeFormattingFromRPr(rPr, formatTypes);\r\n\r\n if (newRPr) {\r\n // Replace with modified rPr\r\n if (rPr.parentNode) {\r\n rPr.parentNode.replaceChild(newRPr, rPr);\r\n }\r\n } else {\r\n // Remove entire rPr if empty\r\n rPr.remove();\r\n }\r\n }\r\n }\r\n }\r\n\r\n return serializeOoxml(doc);\r\n}\r\n\r\n// ==================== HIGHLIGHT INJECTION ====================\r\n\r\n/**\r\n * Word API color names \u2192 OOXML w:highlight values\r\n */\r\nconst HIGHLIGHT_COLOR_MAP = {\r\n 'yellow': 'yellow', 'green': 'green', 'cyan': 'cyan',\r\n 'magenta': 'magenta', 'blue': 'blue', 'red': 'red',\r\n 'darkblue': 'darkBlue', 'darkcyan': 'darkCyan',\r\n 'darkgreen': 'darkGreen', 'darkmagenta': 'darkMagenta',\r\n 'darkred': 'darkRed', 'darkyellow': 'darkYellow',\r\n 'gray25': 'lightGray', 'gray50': 'darkGray',\r\n 'black': 'black', 'white': 'white'\r\n};\r\n\r\n/**\r\n * Injects a highlight color into a run properties (w:rPr) element.\r\n * If rPr is null, creates a new rPr element with the highlight.\r\n * Supports track changes via w:rPrChange.\r\n * \r\n * @param {Document} doc - The OOXML document (for creating new elements)\r\n * @param {Element|null} rPr - The w:rPr element to modify (or null to create new)\r\n * @param {string} color - Highlight color name (default: 'yellow')\r\n * @param {Object} options - Options { generateRedlines: boolean, author: string }\r\n * @returns {Element} Modified or new rPr element with highlight\r\n */\r\nexport function injectHighlightIntoRPr(doc, rPr, color = 'yellow', options = {}) {\n const NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\n const ooxmlColor = HIGHLIGHT_COLOR_MAP[color.toLowerCase()] || 'yellow';\n const generateRedlines = options?.generateRedlines ?? false;\n const author = options?.author || getDefaultAuthor();\n\r\n let rPrElement = rPr;\r\n if (!rPrElement) {\r\n // Create new rPr element\r\n rPrElement = doc.createElementNS(NS_W, 'w:rPr');\r\n } else {\r\n rPrElement = rPr.cloneNode(true);\r\n }\r\n\r\n // Capture \"previous\" state for redlines BEFORE modification\r\n // Clone the *original* rPr children before we touch them\r\n let previousRPrState = null;\r\n if (generateRedlines) {\r\n previousRPrState = doc.createElementNS(NS_W, 'w:rPr');\r\n Array.from(rPrElement.childNodes).forEach(child => {\r\n // Don't include existing rPrChange in the \"previous\" state wrapper usually, \r\n // but for simplicity we clone children. Word generally handles nested track changes poorly,\r\n // so best to exclude rPrChange from the inner previous state.\r\n if (child.nodeName !== 'w:rPrChange') {\r\n previousRPrState.appendChild(child.cloneNode(true));\r\n }\r\n });\r\n }\r\n\r\n // --- APPLY CHANGE ---\r\n // Remove any existing highlight\r\n const existingHighlight = rPrElement.getElementsByTagNameNS(NS_W, 'highlight');\r\n Array.from(existingHighlight).forEach(el => el.remove());\r\n\r\n // Create and add new highlight element\r\n const highlightEl = doc.createElementNS(NS_W, 'w:highlight');\r\n highlightEl.setAttributeNS(NS_W, 'w:val', ooxmlColor);\r\n rPrElement.appendChild(highlightEl);\r\n\r\n // --- WRAP IN REDLINES IF ENABLED ---\r\n if (generateRedlines && previousRPrState) {\r\n const rPrChange = doc.createElementNS(NS_W, 'w:rPrChange');\r\n\r\n // Attributes\r\n rPrChange.setAttributeNS(NS_W, 'w:id', Math.floor(Math.random() * 9999999).toString());\r\n rPrChange.setAttributeNS(NS_W, 'w:author', author);\r\n rPrChange.setAttributeNS(NS_W, 'w:date', new Date().toISOString());\r\n\r\n // Format: <w:rPrChange ...> <w:rPr>...previous...</w:rPr> </w:rPrChange>\r\n rPrChange.appendChild(previousRPrState);\r\n\r\n // Remove any EXISTING rPrChange to avoid duplicates or nested weirdness\r\n const existingChange = rPrElement.getElementsByTagNameNS(NS_W, 'rPrChange');\r\n Array.from(existingChange).forEach(el => el.remove());\r\n\r\n // Append to rPr\r\n rPrElement.appendChild(rPrChange);\r\n }\r\n\r\n return rPrElement;\r\n}\r\n\r\n/**\r\n * Applies highlight formatting to OOXML runs containing the specified text.\r\n * Performs surgical splitting of runs if the text is a substring.\r\n * \r\n * @param {string} ooxmlString - OOXML string (paragraph or package)\r\n * @param {string} targetText - Text to find and highlight\r\n * @param {string} color - Highlight color (default: 'yellow')\r\n * @returns {string} Modified OOXML string with highlights applied\r\n */\r\nexport function applyHighlightToOoxml(ooxmlString, targetText, color = 'yellow', options = {}) {\r\n if (!targetText || !ooxmlString) return ooxmlString;\r\n\r\n const doc = parseOoxml(ooxmlString);\r\n const NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\r\n\r\n // Helper to get text from a run\r\n const getRunText = (run) => {\r\n const textNodes = run.getElementsByTagNameNS(NS_W, 't');\r\n return Array.from(textNodes).map(t => t.textContent).join('');\r\n };\r\n\r\n // Find all runs recursively (this already includes runs inside w:ins)\r\n const allRuns = Array.from(doc.getElementsByTagNameNS(NS_W, 'r'));\r\n\r\n // Process runs \r\n // Note: We need to be careful about mutating the DOM while iterating.\r\n // However, since we split one run into multiple, we don't disturb the *order* of subsequent processed runs usually,\r\n // but a safe approach is to process updates after identification, or break after first match if we assume 1 match per call.\r\n // Given the task usually implies \"highlight all occurrences\" or \"highlight this specific recurrence\", \r\n // but the current API is simple \"textToFind\". We'll assume \"highlight all non-overlapping occurrences\".\r\n\r\n for (let i = 0; i < allRuns.length; i++) {\r\n const run = allRuns[i];\r\n const runText = getRunText(run);\r\n\r\n if (!runText) continue;\r\n\r\n const matchIndex = runText.indexOf(targetText);\r\n if (matchIndex === -1) continue;\r\n\r\n // --- SPLITTING LOGIC ---\r\n // 1. Prefix (if match > 0)\r\n // 2. Match (highlighted)\r\n // 3. Suffix (if match + len < total len)\r\n\r\n const parent = run.parentNode;\r\n if (!parent) {\r\n console.warn(\"[Highlight] Run parent is null; skipping. Likely already processed.\");\r\n continue;\r\n }\r\n\r\n const prefixText = runText.substring(0, matchIndex);\r\n const matchText = runText.substring(matchIndex, matchIndex + targetText.length);\r\n const suffixText = runText.substring(matchIndex + targetText.length);\r\n\r\n // We replace the single 'run' with a fragment of 1-3 runs\r\n const fragment = doc.createDocumentFragment();\r\n\r\n // 1. Create Prefix Run\r\n if (prefixText.length > 0) {\r\n const prefixRun = run.cloneNode(true);\r\n // Update text content\r\n const tNodes = prefixRun.getElementsByTagNameNS(NS_W, 't');\r\n // Simply remove all t nodes and add one with new text to avoid complexity of multiple t nodes\r\n Array.from(tNodes).forEach(t => t.remove());\r\n const newT = doc.createElementNS(NS_W, 'w:t');\r\n // Preserve xml:space=\"preserve\" if it existed, or just add it usually\r\n newT.setAttribute('xml:space', 'preserve');\r\n newT.textContent = prefixText;\r\n prefixRun.appendChild(newT);\r\n fragment.appendChild(prefixRun);\r\n }\r\n\r\n // 2. Create Match Run (With Highlight)\r\n if (matchText.length > 0) {\r\n const matchRun = run.cloneNode(true);\r\n // Update text content\r\n const tNodes = matchRun.getElementsByTagNameNS(NS_W, 't');\r\n Array.from(tNodes).forEach(t => t.remove());\r\n const newT = doc.createElementNS(NS_W, 'w:t');\r\n newT.setAttribute('xml:space', 'preserve');\r\n newT.textContent = matchText;\r\n matchRun.appendChild(newT);\r\n\r\n // Inject Highlight\r\n const rPrElements = matchRun.getElementsByTagNameNS(NS_W, 'rPr');\r\n const existingRPr = rPrElements.length > 0 ? rPrElements[0] : null;\r\n const newRPr = injectHighlightIntoRPr(doc, existingRPr, color, options);\r\n\r\n if (existingRPr) {\r\n matchRun.replaceChild(newRPr, existingRPr);\r\n } else {\r\n matchRun.insertBefore(newRPr, matchRun.firstChild);\r\n }\r\n fragment.appendChild(matchRun);\r\n }\r\n\r\n // 3. Create Suffix Run\r\n if (suffixText.length > 0) {\r\n const suffixRun = run.cloneNode(true);\r\n // Update text content\r\n const tNodes = suffixRun.getElementsByTagNameNS(NS_W, 't');\r\n Array.from(tNodes).forEach(t => t.remove());\r\n const newT = doc.createElementNS(NS_W, 'w:t');\r\n newT.setAttribute('xml:space', 'preserve');\r\n newT.textContent = suffixText;\r\n suffixRun.appendChild(newT);\r\n fragment.appendChild(suffixRun);\r\n }\r\n\r\n // Replace original run\r\n parent.replaceChild(fragment, run);\r\n\r\n // IMPORTANT: If we had a suffix that *also* contained the text (e.g. \"target target\"), \r\n // our simple loop won't catch it because we replaced the node 'run'.\r\n // For now, we'll assume one match per run for simplicity, or we would need to recurse on the suffix.\r\n // Given the short contexts usually, this is acceptable for v1 fix.\r\n }\r\n\r\n return serializeOoxml(doc);\r\n}\r\n", "/**\n * Standalone OOXML/Docx plumbing helpers shared by browser and Node hosts.\n */\n\nimport { createParser, createSerializer } from '../adapters/xml-adapter.js';\n\nconst NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';\nconst NS_CT = 'http://schemas.openxmlformats.org/package/2006/content-types';\nconst NS_RELS = 'http://schemas.openxmlformats.org/package/2006/relationships';\nconst NUMBERING_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering';\nconst NUMBERING_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml';\nconst COMMENTS_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments';\nconst COMMENTS_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml';\n\nconst DOCUMENT_PATH = 'word/document.xml';\nconst NUMBERING_PATH = 'word/numbering.xml';\nconst COMMENTS_PATH = 'word/comments.xml';\nconst CONTENT_TYPES_PATH = '[Content_Types].xml';\nconst DOCUMENT_RELS_PATH = 'word/_rels/document.xml.rels';\n\nexport function parseXmlStrictStandalone(xmlText, label = 'xml') {\n const parser = createParser();\n const xmlDoc = parser.parseFromString(xmlText, 'application/xml');\n const parseError = xmlDoc.getElementsByTagName('parsererror')[0];\n if (parseError) {\n throw new Error(`[XML parse error] ${label}: ${parseError.textContent || 'Unknown'}`);\n }\n return xmlDoc;\n}\n\nfunction isSectionPropertiesElement(node) {\n return !!node && node.nodeType === 1 && node.namespaceURI === NS_W && node.localName === 'sectPr';\n}\n\nexport function getBodyElementFromDocument(xmlDoc) {\n return xmlDoc.getElementsByTagNameNS('*', 'body')[0] || null;\n}\n\nfunction getDirectSectionProperties(body) {\n for (const child of Array.from(body.childNodes || [])) {\n if (isSectionPropertiesElement(child)) return child;\n }\n return null;\n}\n\nexport function insertBodyElementBeforeSectPr(body, element) {\n const sectPr = getDirectSectionProperties(body);\n if (sectPr) {\n body.insertBefore(element, sectPr);\n } else {\n body.appendChild(element);\n }\n}\n\nexport function normalizeBodySectionOrderStandalone(xmlDoc) {\n const body = getBodyElementFromDocument(xmlDoc);\n if (!body) return;\n const sectPr = getDirectSectionProperties(body);\n if (!sectPr) return;\n let cursor = sectPr.nextSibling;\n while (cursor) {\n const next = cursor.nextSibling;\n if (cursor.nodeType === 1) {\n body.insertBefore(cursor, sectPr);\n }\n cursor = next;\n }\n}\n\n/**\n * Flattens nested table-cell paragraphs (`w:tc > w:p > w:p`) by promoting\n * inner paragraphs to direct `w:tc` children.\n *\n * @param {Document} xmlDoc\n * @param {{ onInfo?: (message: string) => void }} [options]\n * @returns {number} number of nested paragraphs fixed\n */\nexport function sanitizeNestedParagraphsInTables(xmlDoc, options = {}) {\n const onInfo = typeof options?.onInfo === 'function' ? options.onInfo : () => {};\n const tcs = xmlDoc.getElementsByTagNameNS(NS_W, 'tc');\n let fixed = 0;\n for (const tc of Array.from(tcs)) {\n const outerParagraphs = Array.from(tc.childNodes || []).filter(\n node => node.nodeType === 1 && node.namespaceURI === NS_W && node.localName === 'p'\n );\n for (const outerParagraph of outerParagraphs) {\n const innerParagraphs = Array.from(outerParagraph.childNodes || []).filter(\n node => node.nodeType === 1 && node.namespaceURI === NS_W && node.localName === 'p'\n );\n for (const innerParagraph of innerParagraphs) {\n tc.insertBefore(innerParagraph, outerParagraph);\n fixed += 1;\n }\n }\n }\n if (fixed > 0) {\n onInfo(`[Sanitize] Fixed ${fixed} nested w:p element(s) in table cells`);\n }\n return fixed;\n}\n\nexport function getPackagePartName(partElement) {\n return partElement.getAttribute('pkg:name') || partElement.getAttribute('name') || '';\n}\n\nfunction extractFromPackageXml(packageXml) {\n const parser = createParser();\n const serializer = createSerializer();\n const pkgDoc = parser.parseFromString(packageXml, 'application/xml');\n const parts = Array.from(pkgDoc.getElementsByTagNameNS('*', 'part'));\n const documentPart = parts.find(part => getPackagePartName(part) === '/word/document.xml');\n if (!documentPart) {\n throw new Error('Package output missing /word/document.xml part');\n }\n\n const xmlData = documentPart.getElementsByTagNameNS('*', 'xmlData')[0];\n if (!xmlData) {\n throw new Error('Package document part missing pkg:xmlData');\n }\n const documentNode = Array.from(xmlData.childNodes || []).find(node => node.nodeType === 1);\n if (!documentNode) {\n throw new Error('Package document part missing XML payload');\n }\n\n const body = documentNode.getElementsByTagNameNS('*', 'body')[0];\n const replacementNodes = body\n ? Array.from(body.childNodes || []).filter(node => node.nodeType === 1 && !isSectionPropertiesElement(node))\n : [documentNode];\n\n const numberingPart = parts.find(part => getPackagePartName(part) === '/word/numbering.xml');\n let numberingXml = null;\n if (numberingPart) {\n const numberingXmlData = numberingPart.getElementsByTagNameNS('*', 'xmlData')[0];\n const numberingNode = numberingXmlData\n ? Array.from(numberingXmlData.childNodes || []).find(node => node.nodeType === 1)\n : null;\n if (numberingNode) {\n numberingXml = serializer.serializeToString(numberingNode);\n }\n }\n\n return {\n replacementNodes,\n numberingXml,\n sourceType: 'package'\n };\n}\n\n/**\n * Extracts replacement nodes and optional numbering payload from engine output.\n *\n * @param {string} outputOxml\n * @returns {{ replacementNodes: Element[], numberingXml: string|null, sourceType: 'package'|'document'|'fragment' }}\n */\nexport function extractReplacementNodesFromOoxml(outputOxml) {\n if (typeof outputOxml !== 'string' || !outputOxml.trim()) {\n throw new Error('Reconciliation engine returned no OOXML payload for this operation');\n }\n\n if (outputOxml.includes('<pkg:package')) {\n return extractFromPackageXml(outputOxml);\n }\n\n if (outputOxml.includes('<w:document')) {\n const parser = createParser();\n const doc = parser.parseFromString(outputOxml, 'application/xml');\n const body = doc.getElementsByTagNameNS('*', 'body')[0];\n const replacementNodes = body\n ? Array.from(body.childNodes || []).filter(node => node.nodeType === 1 && !isSectionPropertiesElement(node))\n : Array.from(doc.childNodes || []).filter(node => node.nodeType === 1);\n return { replacementNodes, numberingXml: null, sourceType: 'document' };\n }\n\n const wrapped = `<root xmlns:w=\"${NS_W}\">${outputOxml}</root>`;\n const parser = createParser();\n const fragmentDoc = parser.parseFromString(wrapped, 'application/xml');\n const replacementNodes = Array.from(fragmentDoc.documentElement.childNodes || []).filter(node => node.nodeType === 1);\n return { replacementNodes, numberingXml: null, sourceType: 'fragment' };\n}\n\nfunction upsertContentTypeOverride(ctDoc, partName, contentType) {\n const overrides = Array.from(ctDoc.getElementsByTagNameNS('*', 'Override'));\n const hasOverride = overrides.some(\n override => (override.getAttribute('PartName') || '').toLowerCase() === String(partName).toLowerCase()\n );\n if (hasOverride) return false;\n\n const override = ctDoc.createElementNS(NS_CT, 'Override');\n override.setAttribute('PartName', partName);\n override.setAttribute('ContentType', contentType);\n ctDoc.documentElement.appendChild(override);\n return true;\n}\n\nfunction upsertDocumentRelationship(relsDoc, relType, target) {\n const relsRoot = relsDoc.getElementsByTagNameNS('*', 'Relationships')[0] || relsDoc.documentElement;\n const rels = Array.from(relsRoot.getElementsByTagNameNS('*', 'Relationship'));\n const hasRel = rels.some(rel => (rel.getAttribute('Type') || '') === relType);\n if (hasRel) return false;\n\n let maxId = 0;\n for (const rel of rels) {\n const idValue = rel.getAttribute('Id') || '';\n const idNum = Number.parseInt(idValue.replace(/^rId/i, ''), 10);\n if (Number.isFinite(idNum)) {\n maxId = Math.max(maxId, idNum);\n }\n }\n\n const rel = relsDoc.createElementNS(NS_RELS, 'Relationship');\n rel.setAttribute('Id', `rId${maxId + 1}`);\n rel.setAttribute('Type', relType);\n rel.setAttribute('Target', target);\n relsRoot.appendChild(rel);\n return true;\n}\n\nasync function readZipText(zip, filePath) {\n const entry = zip.file(filePath);\n if (!entry) return null;\n return entry.async('string');\n}\n\n/**\n * Ensures numbering part + package metadata exist and merges numbering payloads.\n *\n * @param {any} zip\n * @param {string|string[]|null|undefined} numberingXmlList\n * @param {{\n * mergeNumberingXml?: ((existingXml: string, incomingXml: string) => string),\n * onInfo?: (message: string) => void\n * }} [options]\n */\nexport async function ensureNumberingArtifactsInZip(zip, numberingXmlList, options = {}) {\n const onInfo = typeof options?.onInfo === 'function' ? options.onInfo : () => {};\n const mergeNumberingXml = typeof options?.mergeNumberingXml === 'function'\n ? options.mergeNumberingXml\n : null;\n const incomingPayloads = (Array.isArray(numberingXmlList) ? numberingXmlList : [numberingXmlList]).filter(Boolean);\n if (incomingPayloads.length === 0) return;\n\n const existing = await readZipText(zip, NUMBERING_PATH);\n let mergedNumberingXml = existing || null;\n for (const incomingNumberingXml of incomingPayloads) {\n if (!mergedNumberingXml) {\n mergedNumberingXml = incomingNumberingXml;\n continue;\n }\n mergedNumberingXml = mergeNumberingXml\n ? mergeNumberingXml(mergedNumberingXml, incomingNumberingXml)\n : incomingNumberingXml;\n }\n\n if (!existing) {\n onInfo('[Demo] Adding numbering.xml');\n } else {\n onInfo('[Demo] Merging numbering.xml payload(s) into existing numbering definitions');\n }\n zip.file(NUMBERING_PATH, mergedNumberingXml);\n\n const parser = createParser();\n const serializer = createSerializer();\n\n const ctText = await readZipText(zip, CONTENT_TYPES_PATH);\n if (ctText) {\n const ctDoc = parser.parseFromString(ctText, 'application/xml');\n if (upsertContentTypeOverride(ctDoc, '/word/numbering.xml', NUMBERING_CONTENT_TYPE)) {\n zip.file(CONTENT_TYPES_PATH, serializer.serializeToString(ctDoc));\n }\n }\n\n const relsText = await readZipText(zip, DOCUMENT_RELS_PATH);\n if (relsText) {\n const relsDoc = parser.parseFromString(relsText, 'application/xml');\n if (upsertDocumentRelationship(relsDoc, NUMBERING_REL_TYPE, 'numbering.xml')) {\n zip.file(DOCUMENT_RELS_PATH, serializer.serializeToString(relsDoc));\n }\n }\n}\n\n/**\n * Ensures comments part + package metadata exist and merges incoming comments.\n *\n * @param {any} zip\n * @param {string|null|undefined} commentsXml\n * @param {{ onInfo?: (message: string) => void }} [options]\n */\nexport async function ensureCommentsArtifactsInZip(zip, commentsXml, options = {}) {\n const onInfo = typeof options?.onInfo === 'function' ? options.onInfo : () => {};\n if (!commentsXml) return;\n\n const parser = createParser();\n const serializer = createSerializer();\n const existingText = await readZipText(zip, COMMENTS_PATH);\n if (!existingText) {\n onInfo('[Demo] Adding comments.xml');\n zip.file(COMMENTS_PATH, commentsXml);\n } else {\n const existingDoc = parseXmlStrictStandalone(existingText, 'word/comments.xml (existing)');\n const incomingDoc = parseXmlStrictStandalone(commentsXml, 'word/comments.xml (incoming)');\n const existingRoot = existingDoc.documentElement;\n const existingIds = new Set(\n Array.from(existingRoot.getElementsByTagNameNS(NS_W, 'comment'))\n .map(comment => comment.getAttribute('w:id') || comment.getAttribute('id'))\n .filter(Boolean)\n );\n for (const incomingComment of Array.from(incomingDoc.documentElement.getElementsByTagNameNS(NS_W, 'comment'))) {\n const id = incomingComment.getAttribute('w:id') || incomingComment.getAttribute('id');\n if (id && existingIds.has(id)) {\n throw new Error(`Duplicate comment id: ${id}`);\n }\n existingRoot.appendChild(existingDoc.importNode(incomingComment, true));\n }\n zip.file(COMMENTS_PATH, serializer.serializeToString(existingDoc));\n }\n\n const ctText = await readZipText(zip, CONTENT_TYPES_PATH);\n if (ctText) {\n const ctDoc = parser.parseFromString(ctText, 'application/xml');\n if (upsertContentTypeOverride(ctDoc, '/word/comments.xml', COMMENTS_CONTENT_TYPE)) {\n zip.file(CONTENT_TYPES_PATH, serializer.serializeToString(ctDoc));\n }\n }\n\n const relsText = await readZipText(zip, DOCUMENT_RELS_PATH);\n if (relsText) {\n const relsDoc = parser.parseFromString(relsText, 'application/xml');\n if (upsertDocumentRelationship(relsDoc, COMMENTS_REL_TYPE, 'comments.xml')) {\n zip.file(DOCUMENT_RELS_PATH, serializer.serializeToString(relsDoc));\n }\n }\n}\n\n/**\n * Validates core package integrity for document/comments/numbering artifacts.\n *\n * @param {any} zip\n */\nexport async function validateDocxPackage(zip) {\n const documentXml = await readZipText(zip, DOCUMENT_PATH);\n if (!documentXml) {\n throw new Error('Validation failed: missing word/document.xml');\n }\n\n const documentDoc = parseXmlStrictStandalone(documentXml, DOCUMENT_PATH);\n normalizeBodySectionOrderStandalone(documentDoc);\n const body = getBodyElementFromDocument(documentDoc);\n if (!body) {\n throw new Error('Validation failed: word/document.xml has no w:body');\n }\n\n const directBodyElements = Array.from(body.childNodes || []).filter(node => node.nodeType === 1);\n const sectPrIndexes = directBodyElements\n .map((node, index) => ({ node, index }))\n .filter(entry => isSectionPropertiesElement(entry.node))\n .map(entry => entry.index);\n\n if (sectPrIndexes.length > 1) {\n throw new Error('Validation failed: multiple body-level w:sectPr');\n }\n if (sectPrIndexes.length === 1 && sectPrIndexes[0] !== directBodyElements.length - 1) {\n throw new Error('Validation failed: w:sectPr not last');\n }\n\n const tcs = documentDoc.getElementsByTagNameNS(NS_W, 'tc');\n for (const tc of Array.from(tcs)) {\n for (const child of Array.from(tc.childNodes || []).filter(node => node.nodeType === 1)) {\n if (child.namespaceURI === NS_W && child.localName === 'p') {\n const hasNestedParagraph = Array.from(child.childNodes || []).some(\n node => node.nodeType === 1 && node.namespaceURI === NS_W && node.localName === 'p'\n );\n if (hasNestedParagraph) {\n throw new Error('Validation failed: nested w:p');\n }\n }\n }\n }\n\n const hasNumberingUsage = documentDoc.getElementsByTagNameNS(NS_W, 'numPr').length > 0;\n const hasCommentUsage =\n documentDoc.getElementsByTagNameNS(NS_W, 'commentRangeStart').length > 0\n || documentDoc.getElementsByTagNameNS(NS_W, 'commentRangeEnd').length > 0\n || documentDoc.getElementsByTagNameNS(NS_W, 'commentReference').length > 0;\n\n const numberingXml = await readZipText(zip, NUMBERING_PATH);\n const commentsXml = await readZipText(zip, COMMENTS_PATH);\n\n if (numberingXml) {\n parseXmlStrictStandalone(numberingXml, NUMBERING_PATH);\n } else if (hasNumberingUsage) {\n throw new Error('Validation failed: numbering used but part missing');\n }\n\n if (commentsXml) {\n parseXmlStrictStandalone(commentsXml, COMMENTS_PATH);\n } else if (hasCommentUsage) {\n throw new Error('Validation failed: comments used but part missing');\n }\n\n const ctXml = await readZipText(zip, CONTENT_TYPES_PATH);\n if (!ctXml) {\n throw new Error(`Validation failed: missing ${CONTENT_TYPES_PATH}`);\n }\n const ctDoc = parseXmlStrictStandalone(ctXml, CONTENT_TYPES_PATH);\n\n const relsXml = await readZipText(zip, DOCUMENT_RELS_PATH);\n if (!relsXml) {\n throw new Error(`Validation failed: missing ${DOCUMENT_RELS_PATH}`);\n }\n const relsDoc = parseXmlStrictStandalone(relsXml, DOCUMENT_RELS_PATH);\n\n if (numberingXml) {\n const hasNumberingContentType = Array.from(ctDoc.getElementsByTagNameNS('*', 'Override')).some(override =>\n (override.getAttribute('PartName') || '').toLowerCase() === '/word/numbering.xml'\n && (override.getAttribute('ContentType') || '') === NUMBERING_CONTENT_TYPE\n );\n const hasNumberingRel = Array.from(relsDoc.getElementsByTagNameNS('*', 'Relationship')).some(rel =>\n (rel.getAttribute('Type') || '') === NUMBERING_REL_TYPE\n );\n if (!hasNumberingContentType) {\n throw new Error('Validation failed: numbering CT override missing');\n }\n if (!hasNumberingRel) {\n throw new Error('Validation failed: numbering rel missing');\n }\n }\n\n if (commentsXml) {\n const hasCommentsContentType = Array.from(ctDoc.getElementsByTagNameNS('*', 'Override')).some(override =>\n (override.getAttribute('PartName') || '').toLowerCase() === '/word/comments.xml'\n && (override.getAttribute('ContentType') || '') === COMMENTS_CONTENT_TYPE\n );\n const hasCommentsRel = Array.from(relsDoc.getElementsByTagNameNS('*', 'Relationship')).some(rel =>\n (rel.getAttribute('Type') || '') === COMMENTS_REL_TYPE\n );\n if (!hasCommentsContentType) {\n throw new Error('Validation failed: comments CT override missing');\n }\n if (!hasCommentsRel) {\n throw new Error('Validation failed: comments rel missing');\n }\n }\n}\n", "/**\n * Pure routing plan builder used by command-layer Word adapters.\n *\n * This module must remain Word-agnostic.\n */\n\nimport { parseTable } from '../pipeline/content-analysis.js';\nimport { parseMarkdownListContent } from './list-parsing.js';\n\nexport const RoutePlanKind = Object.freeze({\n STRUCTURED_LIST_DIRECT: 'structured_list_direct',\n EMPTY_FORMATTED_TEXT: 'empty_formatted_text',\n EMPTY_HTML: 'empty_html',\n BLOCK_HTML: 'block_html',\n OOXML_ENGINE: 'ooxml_engine'\n});\n\n/**\n * Converts literal escape sequences (for example \"\\\\n\") into actual characters.\n *\n * @param {string} content - Raw model content\n * @returns {string}\n */\nexport function normalizeContentEscapesForRouting(content) {\n if (!content || typeof content !== 'string') return content || '';\n return content\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\r/g, '\\r');\n}\n\n/**\n * Builds a deterministic route plan for command-layer application.\n *\n * @param {Object} params - Plan input\n * @param {string} params.originalText - Current paragraph text\n * @param {string} params.newContent - Requested new content\n * @returns {Object}\n */\nexport function buildReconciliationPlan(params = {}) {\n const originalText = params.originalText || '';\n const normalizedContent = normalizeContentEscapesForRouting(params.newContent || '');\n\n const parsedListData = parseMarkdownListContent(normalizedContent) || { type: 'text', items: [] };\n const hasStructuredListContent = normalizedContent.includes('\\n') && parsedListData.type !== 'text';\n if (hasStructuredListContent) {\n return {\n kind: RoutePlanKind.STRUCTURED_LIST_DIRECT,\n normalizedContent,\n parsedListData,\n flags: {\n hasStructuredListContent: true,\n isOriginalEmpty: isEmpty(originalText),\n hasInlineFormatting: hasInlineMarkdownFormatting(normalizedContent),\n hasBlockElements: hasBlockElements(normalizedContent),\n hasMarkdownTable: hasMarkdownTable(normalizedContent)\n }\n };\n }\n\n const isOriginalEmpty = isEmpty(originalText);\n if (isOriginalEmpty) {\n const hasInlineFormatting = hasInlineMarkdownFormatting(normalizedContent);\n if (hasInlineFormatting) {\n return {\n kind: RoutePlanKind.EMPTY_FORMATTED_TEXT,\n normalizedContent,\n parsedListData,\n flags: {\n hasStructuredListContent: false,\n isOriginalEmpty: true,\n hasInlineFormatting: true,\n hasBlockElements: hasBlockElements(normalizedContent),\n hasMarkdownTable: hasMarkdownTable(normalizedContent)\n }\n };\n }\n\n return {\n kind: RoutePlanKind.EMPTY_HTML,\n normalizedContent,\n parsedListData,\n flags: {\n hasStructuredListContent: false,\n isOriginalEmpty: true,\n hasInlineFormatting: false,\n hasBlockElements: hasBlockElements(normalizedContent),\n hasMarkdownTable: hasMarkdownTable(normalizedContent)\n }\n };\n }\n\n const hasBlocks = hasBlockElements(normalizedContent);\n if (hasBlocks) {\n return {\n kind: RoutePlanKind.BLOCK_HTML,\n normalizedContent,\n parsedListData,\n flags: {\n hasStructuredListContent: false,\n isOriginalEmpty: false,\n hasInlineFormatting: hasInlineMarkdownFormatting(normalizedContent),\n hasBlockElements: true,\n hasMarkdownTable: hasMarkdownTable(normalizedContent)\n }\n };\n }\n\n return {\n kind: RoutePlanKind.OOXML_ENGINE,\n normalizedContent,\n parsedListData,\n flags: {\n hasStructuredListContent: false,\n isOriginalEmpty: false,\n hasInlineFormatting: hasInlineMarkdownFormatting(normalizedContent),\n hasBlockElements: false,\n hasMarkdownTable: hasMarkdownTable(normalizedContent)\n }\n };\n}\n\nfunction isEmpty(text) {\n return !text || text.trim().length === 0;\n}\n\nfunction hasMarkdownTable(content) {\n if (!content || !content.includes('|')) return false;\n const tableData = parseTable(content);\n return tableData.rows.length > 0 || tableData.headers.length > 0;\n}\n\nfunction hasInlineMarkdownFormatting(text) {\n if (!text) return false;\n return /(\\*\\*.+?\\*\\*|\\*.+?\\*|__.+?__|_.+?_|`.+?`|~~.+?~~|\\+\\+.+?\\+\\+)/.test(text);\n}\n\nfunction hasBlockElements(content) {\n if (!content) return false;\n\n const hasUnorderedList = /^[\\s]*[-*+]\\s+/m.test(content);\n const hasOrderedList = /^[\\s]*\\d+\\.\\s+/m.test(content);\n const hasOutlineList = /^[\\s]*\\d+\\.\\d+(?:\\.\\d+)*\\.?\\s+/m.test(content);\n const hasAlphaDotList = /^[\\s]*[A-Za-z]\\.\\s+/m.test(content);\n const hasRomanDotList = /^[\\s]*[ivxlcIVXLC]+\\.\\s+/m.test(content);\n const hasAlphaList = /^[\\s]*\\([a-z]\\)\\s+/m.test(content);\n const hasTable = /\\|.*\\|.*\\n/.test(content);\n const hasHeading = /^#{1,9}\\s/m.test(content);\n const hasMultipleLineBreaks = content.includes('\\n\\n');\n\n return hasUnorderedList\n || hasOrderedList\n || hasOutlineList\n || hasAlphaDotList\n || hasRomanDotList\n || hasAlphaList\n || hasTable\n || hasHeading\n || hasMultipleLineBreaks;\n}\n", "/**\n * OOXML identity extraction helpers.\n */\n\n/**\n * Extracts a paragraph identity token from OOXML (`w14:paraId` when present).\n *\n * @param {string} ooxml - OOXML payload\n * @returns {string|null}\n */\nexport function extractParagraphIdFromOoxml(ooxml) {\n if (!ooxml || typeof ooxml !== 'string') return null;\n const match = ooxml.match(/\\b(?:w14:paraId|w:paraId|paraId)=\"([^\"]+)\"/i);\n return match ? match[1] : null;\n}\n", "/**\r\n * Standalone reconciliation entrypoint (no Word JS API dependencies).\r\n */\r\n\r\n// Adapters\nexport { configureXmlProvider } from './adapters/xml-adapter.js';\nexport { configureLogger } from './adapters/logger.js';\nexport { setDefaultAuthor, getDefaultAuthor, setPlatform, getPlatform } from './adapters/config.js';\n\r\n// Engine\r\nimport {\n applyRedlineToOxml as applyRedlineToOxmlEngine,\n sanitizeAiResponse,\n parseOoxml,\n serializeOoxml\n} from './engine/oxml-engine.js';\nimport { parseTable as parseMarkdownTable } from './pipeline/pipeline.js';\nimport { wrapInDocumentFragment as wrapInDocumentFragmentShared } from './pipeline/serialization.js';\nimport {\n buildSingleLineListStructuralFallbackPlan,\n executeSingleLineListStructuralFallback,\n resolveSingleLineListFallbackNumberingAction,\n recordSingleLineListFallbackExplicitSequence,\n clearSingleLineListFallbackExplicitSequence,\n enforceListBindingOnParagraphNodes,\n stripSingleLineListMarkerPrefix\n} from './orchestration/list-structural-fallback.js';\n\r\n/**\r\n * Standalone-safe redline wrapper.\r\n *\r\n * In non-Word runtimes, the engine can return `{ useNativeApi: true, hasChanges: true }`\r\n * without an OOXML payload for some format-only operations. Standalone callers cannot\r\n * complete that native fallback path, so normalize to a no-op with warnings.\r\n */\r\nexport async function applyRedlineToOxml(oxml, originalText, modifiedText, options = {}) {\n const result = await applyRedlineToOxmlEngine(oxml, originalText, modifiedText, options);\n if (result?.useNativeApi && typeof result?.oxml !== 'string') {\n const existingWarnings = Array.isArray(result?.warnings) ? result.warnings : [];\n return {\n ...result,\r\n oxml,\r\n hasChanges: false,\r\n warnings: [\r\n ...existingWarnings,\r\n 'Standalone mode cannot execute native Word API fallback for this operation.'\r\n ]\r\n };\r\n }\n return result;\n}\n\n/**\n * Reconciles a Markdown table against an OOXML scope.\n *\n * This centralizes table-specific validation + reconciliation so Word add-in\n * and browser modules can share the same entrypoint.\n *\n * @param {string} oxml - OOXML scope to reconcile (paragraph/range/table package)\n * @param {string} originalText - Original visible text in that scope\n * @param {string} markdownTable - Markdown table text\n * @param {Object} [options={}] - Reconciliation options forwarded to applyRedlineToOxml\n * @returns {Promise<{ oxml: string, hasChanges: boolean, warnings?: string[], isMarkdownTable: boolean, tableData?: Object }>}\n */\nexport async function reconcileMarkdownTableOoxml(oxml, originalText, markdownTable, options = {}) {\n const sourceOoxml = typeof oxml === 'string' ? oxml : '';\n const tableText = typeof markdownTable === 'string' ? markdownTable : String(markdownTable || '');\n let tableData;\n\n try {\n tableData = parseMarkdownTable(tableText);\n } catch {\n tableData = { headers: [], rows: [] };\n }\n\n const hasTableData = (tableData?.headers?.length || 0) > 0 || (tableData?.rows?.length || 0) > 0;\n if (!hasTableData) {\n return {\n oxml: sourceOoxml,\n hasChanges: false,\n isMarkdownTable: false,\n warnings: ['Could not parse Markdown table from input.']\n };\n }\n\n const result = await applyRedlineToOxml(\n sourceOoxml,\n originalText || '',\n tableText,\n options\n );\n\n return {\n ...result,\n isMarkdownTable: true,\n tableData\n };\n}\n\nexport { resolveParagraphRangeByRefs } from './core/paragraph-targeting.js';\r\nexport { inferTableReplacementParagraphBlock, isLikelyStructuredTableSourceParagraph } from './core/table-targeting.js';\r\n\r\n/**\n * Applies redline reconciliation, then forces single-line structural list\n * conversion when the redline is a no-op on marker-prefixed list text.\n *\n * This is useful for inputs like `1. HEADER` where text diff is unchanged but\n * OOXML should convert plain text markers into real Word list structure.\n *\n * @param {string} oxml - Original OOXML\n * @param {string} originalText - Original visible text\n * @param {string} modifiedText - Proposed modified text\n * @param {Object} [options={}] - Reconciliation options\n * @param {boolean} [options.listFallbackAllowExistingList=true] - Allow fallback even when paragraph is already list-bound\n * @returns {Promise<{ oxml: string, hasChanges: boolean } & Record<string, any>>}\n */\nexport async function applyRedlineToOxmlWithListFallback(oxml, originalText, modifiedText, options = {}) {\n const allowExistingListForFallback = options.listFallbackAllowExistingList !== false;\n const plan = buildSingleLineListStructuralFallbackPlan({\n oxml,\n originalText,\n modifiedText,\n allowExistingList: allowExistingListForFallback\n });\n const preferListFallback = options.preferListStructuralFallback !== false;\n let preflightFallbackWarnings = [];\n\n if (plan && preferListFallback) {\n const fallbackResult = await executeSingleLineListStructuralFallback(plan, {\n author: options.author,\n generateRedlines: options.generateRedlines,\n pipeline: options.listFallbackPipeline\n });\n if (fallbackResult?.hasChanges && fallbackResult?.oxml) {\n const wrappedOxml = wrapInDocumentFragmentShared(fallbackResult.oxml, {\n includeNumbering: fallbackResult.includeNumbering ?? true,\n numberingXml: fallbackResult.numberingXml\n });\n const fallbackWarnings = Array.isArray(fallbackResult?.warnings) ? fallbackResult.warnings : [];\n return {\n oxml: wrappedOxml,\n hasChanges: true,\n warnings: fallbackWarnings,\n listStructuralFallbackApplied: true,\n listStructuralFallbackKey: fallbackResult.listStructuralFallbackKey || null,\n listStructuralFallbackNumberingXml: fallbackResult.numberingXml || null\n };\n }\n preflightFallbackWarnings = Array.isArray(fallbackResult?.warnings) ? fallbackResult.warnings : [];\n }\n\n const baseResult = await applyRedlineToOxml(oxml, originalText, modifiedText, options);\n\n if (!plan) {\n return {\n ...baseResult,\n warnings: [\n ...(Array.isArray(baseResult?.warnings) ? baseResult.warnings : []),\n ...preflightFallbackWarnings\n ],\n listStructuralFallbackApplied: false\n };\n }\n\n if (preferListFallback) {\n return {\n ...baseResult,\n warnings: [\n ...(Array.isArray(baseResult?.warnings) ? baseResult.warnings : []),\n ...preflightFallbackWarnings\n ],\n listStructuralFallbackApplied: false\n };\n }\n\n if (baseResult?.hasChanges) {\n return {\n ...baseResult,\n listStructuralFallbackApplied: false\n };\n }\n\n const fallbackResult = await executeSingleLineListStructuralFallback(plan, {\n author: options.author,\n generateRedlines: options.generateRedlines,\n pipeline: options.listFallbackPipeline\n });\n if (!fallbackResult?.hasChanges || !fallbackResult?.oxml) {\n const existingWarnings = Array.isArray(baseResult?.warnings) ? baseResult.warnings : [];\n const fallbackWarnings = Array.isArray(fallbackResult?.warnings) ? fallbackResult.warnings : [];\n return {\n ...baseResult,\n warnings: [...existingWarnings, ...fallbackWarnings],\n listStructuralFallbackApplied: false\n };\n }\n\n const wrappedOxml = wrapInDocumentFragmentShared(fallbackResult.oxml, {\n includeNumbering: fallbackResult.includeNumbering ?? true,\n numberingXml: fallbackResult.numberingXml\n });\n const existingWarnings = Array.isArray(baseResult?.warnings) ? baseResult.warnings : [];\n const fallbackWarnings = Array.isArray(fallbackResult?.warnings) ? fallbackResult.warnings : [];\n\n return {\n ...baseResult,\n oxml: wrappedOxml,\n hasChanges: true,\n warnings: [...existingWarnings, ...preflightFallbackWarnings, ...fallbackWarnings],\n listStructuralFallbackApplied: true,\n listStructuralFallbackKey: fallbackResult.listStructuralFallbackKey || null,\n listStructuralFallbackNumberingXml: fallbackResult.numberingXml || null\n };\n}\n\nexport { sanitizeAiResponse, parseOoxml, serializeOoxml };\n\nexport {\n createDynamicNumberingIdState,\n reserveNextNumberingId,\n reserveNextNumberingIdPair,\n overwriteParagraphNumIds,\n extractFirstParagraphNumId,\n buildExplicitDecimalMultilevelNumberingXml,\n remapNumberingPayloadForDocument,\n mergeNumberingXmlBySchemaOrder\n} from './services/numbering-helpers.js';\n\n// Pipeline components\nexport { ReconciliationPipeline } from './pipeline/pipeline.js';\nexport { ingestOoxml } from './pipeline/ingestion.js';\nexport { ingestWordOoxmlToPlainText, ingestWordOoxmlToMarkdown } from './pipeline/ingestion-export.js';\nexport { preprocessMarkdown } from './pipeline/markdown-processor.js';\nexport { serializeToOoxml, wrapInDocumentFragment } from './pipeline/serialization.js';\n\r\n// Comment engine\r\nexport {\r\n injectCommentsIntoOoxml,\r\n injectCommentsIntoPackage,\r\n buildCommentElement,\r\n buildCommentsPartXml\r\n} from './services/comment-engine.js';\r\n\r\n// Formatting removal utilities\nexport {\n removeFormattingFromRPr,\n applyFormattingRemovalToOoxml,\n applyHighlightToOoxml\n} from './engine/formatting-removal.js';\n\r\n// Table/list tools\r\nexport { generateTableOoxml } from './services/table-reconciliation.js';\nexport { NumberingService } from './services/numbering-service.js';\nexport {\n parseXmlStrictStandalone,\n getBodyElementFromDocument,\n insertBodyElementBeforeSectPr,\n normalizeBodySectionOrderStandalone,\n sanitizeNestedParagraphsInTables,\n getPackagePartName,\n extractReplacementNodesFromOoxml,\n ensureNumberingArtifactsInZip,\n ensureCommentsArtifactsInZip,\n validateDocxPackage\n} from './services/standalone-docx-plumbing.js';\nexport { buildReconciliationPlan, RoutePlanKind, normalizeContentEscapesForRouting } from './orchestration/route-plan.js';\nexport { parseMarkdownListContent, hasListItems } from './orchestration/list-parsing.js';\nexport { buildListMarkdown, inferNumberingStyleFromMarker, normalizeListItemsWithLevels } from './orchestration/list-markdown.js';\nexport {\n buildSingleLineListStructuralFallbackPlan,\n executeSingleLineListStructuralFallback,\n resolveSingleLineListFallbackNumberingAction,\n recordSingleLineListFallbackExplicitSequence,\n clearSingleLineListFallbackExplicitSequence,\n enforceListBindingOnParagraphNodes,\n stripSingleLineListMarkerPrefix\n} from './orchestration/list-structural-fallback.js';\n\r\n// Core types/constants\r\nexport { DiffOp, RunKind, ContainerKind, ContentType, NS_W, escapeXml } from './core/types.js';\r\nexport { extractParagraphIdFromOoxml } from './core/ooxml-identifiers.js';\r\nexport {\n WORD_MAIN_NS,\n getParagraphText,\n getDocumentParagraphNodes,\n normalizeWhitespaceForTargeting,\n isMarkdownTableText,\r\n parseParagraphReference,\r\n stripLeadingParagraphMarker,\r\n splitLeadingParagraphMarker,\r\n findContainingWordElement,\r\n findParagraphByReference,\n findParagraphByStrictText,\n findParagraphByBestTextMatch,\n resolveTargetParagraph,\n buildTargetReferenceSnapshot,\n resolveTargetParagraphWithSnapshot\n} from './core/paragraph-targeting.js';\nexport { synthesizeTableMarkdownFromMultilineCellEdit } from './core/table-targeting.js';\r\nexport {\n getParagraphListInfo,\n collectContiguousListParagraphBlock,\n synthesizeExpandedListScopeEdit,\n planListInsertionOnlyEdit,\n stripRedundantLeadingListMarkers\n} from './core/list-targeting.js';\n\r\n\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["diff_match_patch", "longtext", "shorttext", "error", "NS_W", "NS_W", "XMLNS_ATTR_REGEX", "error", "NS_W", "NS_W", "isWordElement", "NS_W", "isWordElement", "createRangeCursorLookup", "noChanges", "getAttributeFirst", "getElementId", "setElementVal", "_", "getDirectWordChild", "error", "injectCommentsIntoPackage", "NS_W", "NS_W", "parser", "replacementNodes", "override", "rel", "applyRedlineToOxml", "fallbackResult", "wrappedOxml", "fallbackWarnings", "existingWarnings"]
|
|
7
|
+
}
|