docxmlater 11.0.10 → 12.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.
Files changed (361) hide show
  1. package/README.md +53 -13
  2. package/dist/core/Document.d.ts +29 -3
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +733 -170
  5. package/dist/core/Document.js.map +1 -1
  6. package/dist/core/DocumentGenerator.d.ts +1 -0
  7. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  8. package/dist/core/DocumentGenerator.js +77 -25
  9. package/dist/core/DocumentGenerator.js.map +1 -1
  10. package/dist/core/DocumentParser.d.ts +7 -3
  11. package/dist/core/DocumentParser.d.ts.map +1 -1
  12. package/dist/core/DocumentParser.js +427 -81
  13. package/dist/core/DocumentParser.js.map +1 -1
  14. package/dist/core/RelationshipManager.d.ts.map +1 -1
  15. package/dist/core/RelationshipManager.js +2 -2
  16. package/dist/core/RelationshipManager.js.map +1 -1
  17. package/dist/elements/Comment.d.ts +15 -1
  18. package/dist/elements/Comment.d.ts.map +1 -1
  19. package/dist/elements/Comment.js +67 -12
  20. package/dist/elements/Comment.js.map +1 -1
  21. package/dist/elements/CommentManager.d.ts +4 -0
  22. package/dist/elements/CommentManager.d.ts.map +1 -1
  23. package/dist/elements/CommentManager.js +74 -16
  24. package/dist/elements/CommentManager.js.map +1 -1
  25. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  26. package/dist/elements/EndnoteManager.js.map +1 -1
  27. package/dist/elements/Field.d.ts +10 -1
  28. package/dist/elements/Field.d.ts.map +1 -1
  29. package/dist/elements/Field.js +76 -34
  30. package/dist/elements/Field.js.map +1 -1
  31. package/dist/elements/FieldHelpers.d.ts +1 -0
  32. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  33. package/dist/elements/FieldHelpers.js +8 -4
  34. package/dist/elements/FieldHelpers.js.map +1 -1
  35. package/dist/elements/Footer.d.ts +3 -1
  36. package/dist/elements/Footer.d.ts.map +1 -1
  37. package/dist/elements/Footer.js +39 -53
  38. package/dist/elements/Footer.js.map +1 -1
  39. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  40. package/dist/elements/FootnoteManager.js.map +1 -1
  41. package/dist/elements/Header.d.ts +3 -1
  42. package/dist/elements/Header.d.ts.map +1 -1
  43. package/dist/elements/Header.js +39 -53
  44. package/dist/elements/Header.js.map +1 -1
  45. package/dist/elements/HeaderFooterManager.d.ts +4 -2
  46. package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
  47. package/dist/elements/HeaderFooterManager.js +36 -6
  48. package/dist/elements/HeaderFooterManager.js.map +1 -1
  49. package/dist/elements/Hyperlink.d.ts +6 -1
  50. package/dist/elements/Hyperlink.d.ts.map +1 -1
  51. package/dist/elements/Hyperlink.js +69 -44
  52. package/dist/elements/Hyperlink.js.map +1 -1
  53. package/dist/elements/Image.d.ts.map +1 -1
  54. package/dist/elements/Image.js +33 -6
  55. package/dist/elements/Image.js.map +1 -1
  56. package/dist/elements/ImageManager.d.ts +1 -0
  57. package/dist/elements/ImageManager.d.ts.map +1 -1
  58. package/dist/elements/ImageManager.js +11 -0
  59. package/dist/elements/ImageManager.js.map +1 -1
  60. package/dist/elements/Paragraph.d.ts +3 -0
  61. package/dist/elements/Paragraph.d.ts.map +1 -1
  62. package/dist/elements/Paragraph.js +91 -26
  63. package/dist/elements/Paragraph.js.map +1 -1
  64. package/dist/elements/Revision.d.ts +4 -0
  65. package/dist/elements/Revision.d.ts.map +1 -1
  66. package/dist/elements/Revision.js +369 -29
  67. package/dist/elements/Revision.js.map +1 -1
  68. package/dist/elements/Run.d.ts +1 -0
  69. package/dist/elements/Run.d.ts.map +1 -1
  70. package/dist/elements/Run.js +24 -4
  71. package/dist/elements/Run.js.map +1 -1
  72. package/dist/elements/Section.d.ts.map +1 -1
  73. package/dist/elements/Section.js +17 -7
  74. package/dist/elements/Section.js.map +1 -1
  75. package/dist/elements/Shape.d.ts.map +1 -1
  76. package/dist/elements/Shape.js +50 -42
  77. package/dist/elements/Shape.js.map +1 -1
  78. package/dist/elements/StructuredDocumentTag.d.ts +9 -1
  79. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  80. package/dist/elements/StructuredDocumentTag.js +46 -6
  81. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  82. package/dist/elements/Table.d.ts +2 -0
  83. package/dist/elements/Table.d.ts.map +1 -1
  84. package/dist/elements/Table.js +90 -42
  85. package/dist/elements/Table.js.map +1 -1
  86. package/dist/elements/TableCell.d.ts +1 -0
  87. package/dist/elements/TableCell.d.ts.map +1 -1
  88. package/dist/elements/TableCell.js +32 -13
  89. package/dist/elements/TableCell.js.map +1 -1
  90. package/dist/elements/TableOfContents.d.ts.map +1 -1
  91. package/dist/elements/TableOfContents.js +5 -7
  92. package/dist/elements/TableOfContents.js.map +1 -1
  93. package/dist/elements/TableRow.d.ts +1 -0
  94. package/dist/elements/TableRow.d.ts.map +1 -1
  95. package/dist/elements/TableRow.js +16 -1
  96. package/dist/elements/TableRow.js.map +1 -1
  97. package/dist/elements/TextBox.d.ts.map +1 -1
  98. package/dist/elements/TextBox.js +55 -42
  99. package/dist/elements/TextBox.js.map +1 -1
  100. package/dist/esm/core/Document.js +735 -172
  101. package/dist/esm/core/Document.js.map +1 -1
  102. package/dist/esm/core/DocumentGenerator.js +77 -25
  103. package/dist/esm/core/DocumentGenerator.js.map +1 -1
  104. package/dist/esm/core/DocumentParser.js +427 -81
  105. package/dist/esm/core/DocumentParser.js.map +1 -1
  106. package/dist/esm/core/RelationshipManager.js +2 -2
  107. package/dist/esm/core/RelationshipManager.js.map +1 -1
  108. package/dist/esm/elements/Comment.js +67 -12
  109. package/dist/esm/elements/Comment.js.map +1 -1
  110. package/dist/esm/elements/CommentManager.js +74 -16
  111. package/dist/esm/elements/CommentManager.js.map +1 -1
  112. package/dist/esm/elements/EndnoteManager.js.map +1 -1
  113. package/dist/esm/elements/Field.js +77 -35
  114. package/dist/esm/elements/Field.js.map +1 -1
  115. package/dist/esm/elements/FieldHelpers.js +7 -4
  116. package/dist/esm/elements/FieldHelpers.js.map +1 -1
  117. package/dist/esm/elements/Footer.js +39 -53
  118. package/dist/esm/elements/Footer.js.map +1 -1
  119. package/dist/esm/elements/FootnoteManager.js.map +1 -1
  120. package/dist/esm/elements/Header.js +39 -53
  121. package/dist/esm/elements/Header.js.map +1 -1
  122. package/dist/esm/elements/HeaderFooterManager.js +36 -6
  123. package/dist/esm/elements/HeaderFooterManager.js.map +1 -1
  124. package/dist/esm/elements/Hyperlink.js +69 -44
  125. package/dist/esm/elements/Hyperlink.js.map +1 -1
  126. package/dist/esm/elements/Image.js +33 -6
  127. package/dist/esm/elements/Image.js.map +1 -1
  128. package/dist/esm/elements/ImageManager.js +11 -0
  129. package/dist/esm/elements/ImageManager.js.map +1 -1
  130. package/dist/esm/elements/Paragraph.js +91 -26
  131. package/dist/esm/elements/Paragraph.js.map +1 -1
  132. package/dist/esm/elements/Revision.js +369 -29
  133. package/dist/esm/elements/Revision.js.map +1 -1
  134. package/dist/esm/elements/Run.js +24 -4
  135. package/dist/esm/elements/Run.js.map +1 -1
  136. package/dist/esm/elements/Section.js +17 -7
  137. package/dist/esm/elements/Section.js.map +1 -1
  138. package/dist/esm/elements/Shape.js +50 -42
  139. package/dist/esm/elements/Shape.js.map +1 -1
  140. package/dist/esm/elements/StructuredDocumentTag.js +46 -6
  141. package/dist/esm/elements/StructuredDocumentTag.js.map +1 -1
  142. package/dist/esm/elements/Table.js +90 -42
  143. package/dist/esm/elements/Table.js.map +1 -1
  144. package/dist/esm/elements/TableCell.js +32 -13
  145. package/dist/esm/elements/TableCell.js.map +1 -1
  146. package/dist/esm/elements/TableOfContents.js +5 -7
  147. package/dist/esm/elements/TableOfContents.js.map +1 -1
  148. package/dist/esm/elements/TableRow.js +16 -1
  149. package/dist/esm/elements/TableRow.js.map +1 -1
  150. package/dist/esm/elements/TextBox.js +55 -42
  151. package/dist/esm/elements/TextBox.js.map +1 -1
  152. package/dist/esm/formatting/AbstractNumbering.js +1 -1
  153. package/dist/esm/formatting/AbstractNumbering.js.map +1 -1
  154. package/dist/esm/formatting/NumberingLevel.js +8 -6
  155. package/dist/esm/formatting/NumberingLevel.js.map +1 -1
  156. package/dist/esm/formatting/NumberingManager.js +16 -1
  157. package/dist/esm/formatting/NumberingManager.js.map +1 -1
  158. package/dist/esm/formatting/Style.js +14 -0
  159. package/dist/esm/formatting/Style.js.map +1 -1
  160. package/dist/esm/formatting/StylesManager.js +14 -2
  161. package/dist/esm/formatting/StylesManager.js.map +1 -1
  162. package/dist/esm/helpers/CleanupHelper.js +103 -26
  163. package/dist/esm/helpers/CleanupHelper.js.map +1 -1
  164. package/dist/esm/images/ImageOptimizer.js +52 -4
  165. package/dist/esm/images/ImageOptimizer.js.map +1 -1
  166. package/dist/esm/index.js +1 -0
  167. package/dist/esm/index.js.map +1 -1
  168. package/dist/esm/internal.js +1 -1
  169. package/dist/esm/internal.js.map +1 -1
  170. package/dist/esm/processors/CompatibilityUpgrader.js +7 -1
  171. package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -1
  172. package/dist/esm/processors/InMemoryRevisionAcceptor.js +134 -13
  173. package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -1
  174. package/dist/esm/processors/RevisionWalker.js +223 -39
  175. package/dist/esm/processors/RevisionWalker.js.map +1 -1
  176. package/dist/esm/processors/SelectiveRevisionAcceptor.js +116 -17
  177. package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -1
  178. package/dist/esm/processors/acceptRevisions.js +20 -11
  179. package/dist/esm/processors/acceptRevisions.js.map +1 -1
  180. package/dist/esm/processors/cnfStyleDecoder.js +7 -7
  181. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
  182. package/dist/esm/processors/stripTrackedChanges.js +16 -5
  183. package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
  184. package/dist/esm/utils/deepClone.js +24 -11
  185. package/dist/esm/utils/deepClone.js.map +1 -1
  186. package/dist/esm/utils/units.js +1 -1
  187. package/dist/esm/utils/units.js.map +1 -1
  188. package/dist/esm/utils/validation.js +11 -23
  189. package/dist/esm/utils/validation.js.map +1 -1
  190. package/dist/esm/utils/xmlSanitization.js +131 -7
  191. package/dist/esm/utils/xmlSanitization.js.map +1 -1
  192. package/dist/esm/validation/RevisionAutoFixer.js +69 -55
  193. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
  194. package/dist/esm/validation/RevisionValidator.js +24 -20
  195. package/dist/esm/validation/RevisionValidator.js.map +1 -1
  196. package/dist/esm/xml/XMLBuilder.js +52 -20
  197. package/dist/esm/xml/XMLBuilder.js.map +1 -1
  198. package/dist/esm/xml/XMLParser.js +55 -13
  199. package/dist/esm/xml/XMLParser.js.map +1 -1
  200. package/dist/esm/zip/ZipHandler.js +37 -13
  201. package/dist/esm/zip/ZipHandler.js.map +1 -1
  202. package/dist/esm/zip/ZipReader.js +53 -6
  203. package/dist/esm/zip/ZipReader.js.map +1 -1
  204. package/dist/esm/zip/errors.js +7 -0
  205. package/dist/esm/zip/errors.js.map +1 -1
  206. package/dist/esm/zip/types.js +4 -0
  207. package/dist/esm/zip/types.js.map +1 -1
  208. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  209. package/dist/formatting/AbstractNumbering.js +1 -1
  210. package/dist/formatting/AbstractNumbering.js.map +1 -1
  211. package/dist/formatting/NumberingLevel.d.ts +1 -1
  212. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  213. package/dist/formatting/NumberingLevel.js +8 -6
  214. package/dist/formatting/NumberingLevel.js.map +1 -1
  215. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  216. package/dist/formatting/NumberingManager.js +16 -1
  217. package/dist/formatting/NumberingManager.js.map +1 -1
  218. package/dist/formatting/Style.d.ts.map +1 -1
  219. package/dist/formatting/Style.js +14 -0
  220. package/dist/formatting/Style.js.map +1 -1
  221. package/dist/formatting/StylesManager.d.ts +2 -0
  222. package/dist/formatting/StylesManager.d.ts.map +1 -1
  223. package/dist/formatting/StylesManager.js +14 -2
  224. package/dist/formatting/StylesManager.js.map +1 -1
  225. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  226. package/dist/helpers/CleanupHelper.js +103 -26
  227. package/dist/helpers/CleanupHelper.js.map +1 -1
  228. package/dist/images/ImageOptimizer.d.ts.map +1 -1
  229. package/dist/images/ImageOptimizer.js +52 -4
  230. package/dist/images/ImageOptimizer.js.map +1 -1
  231. package/dist/index.d.ts +3 -1
  232. package/dist/index.d.ts.map +1 -1
  233. package/dist/index.js +4 -2
  234. package/dist/index.js.map +1 -1
  235. package/dist/internal.d.ts +1 -1
  236. package/dist/internal.d.ts.map +1 -1
  237. package/dist/internal.js +2 -1
  238. package/dist/internal.js.map +1 -1
  239. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
  240. package/dist/processors/CompatibilityUpgrader.js +7 -1
  241. package/dist/processors/CompatibilityUpgrader.js.map +1 -1
  242. package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
  243. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
  244. package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
  245. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
  246. package/dist/processors/RevisionWalker.d.ts +9 -3
  247. package/dist/processors/RevisionWalker.d.ts.map +1 -1
  248. package/dist/processors/RevisionWalker.js +223 -39
  249. package/dist/processors/RevisionWalker.js.map +1 -1
  250. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
  251. package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
  252. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
  253. package/dist/processors/acceptRevisions.d.ts +1 -0
  254. package/dist/processors/acceptRevisions.d.ts.map +1 -1
  255. package/dist/processors/acceptRevisions.js +21 -11
  256. package/dist/processors/acceptRevisions.js.map +1 -1
  257. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
  258. package/dist/processors/cnfStyleDecoder.js +7 -7
  259. package/dist/processors/cnfStyleDecoder.js.map +1 -1
  260. package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
  261. package/dist/processors/stripTrackedChanges.js +16 -5
  262. package/dist/processors/stripTrackedChanges.js.map +1 -1
  263. package/dist/utils/deepClone.d.ts.map +1 -1
  264. package/dist/utils/deepClone.js +24 -11
  265. package/dist/utils/deepClone.js.map +1 -1
  266. package/dist/utils/units.d.ts.map +1 -1
  267. package/dist/utils/units.js +1 -1
  268. package/dist/utils/units.js.map +1 -1
  269. package/dist/utils/validation.d.ts.map +1 -1
  270. package/dist/utils/validation.js +11 -23
  271. package/dist/utils/validation.js.map +1 -1
  272. package/dist/utils/xmlSanitization.d.ts +2 -0
  273. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  274. package/dist/utils/xmlSanitization.js +133 -7
  275. package/dist/utils/xmlSanitization.js.map +1 -1
  276. package/dist/validation/RevisionAutoFixer.d.ts +6 -2
  277. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  278. package/dist/validation/RevisionAutoFixer.js +68 -54
  279. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  280. package/dist/validation/RevisionValidator.d.ts +2 -0
  281. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  282. package/dist/validation/RevisionValidator.js +26 -21
  283. package/dist/validation/RevisionValidator.js.map +1 -1
  284. package/dist/xml/XMLBuilder.d.ts +1 -0
  285. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  286. package/dist/xml/XMLBuilder.js +52 -20
  287. package/dist/xml/XMLBuilder.js.map +1 -1
  288. package/dist/xml/XMLParser.d.ts +1 -0
  289. package/dist/xml/XMLParser.d.ts.map +1 -1
  290. package/dist/xml/XMLParser.js +55 -13
  291. package/dist/xml/XMLParser.js.map +1 -1
  292. package/dist/zip/ZipHandler.d.ts.map +1 -1
  293. package/dist/zip/ZipHandler.js +37 -13
  294. package/dist/zip/ZipHandler.js.map +1 -1
  295. package/dist/zip/ZipReader.d.ts.map +1 -1
  296. package/dist/zip/ZipReader.js +52 -5
  297. package/dist/zip/ZipReader.js.map +1 -1
  298. package/dist/zip/errors.d.ts +3 -0
  299. package/dist/zip/errors.d.ts.map +1 -1
  300. package/dist/zip/errors.js +9 -1
  301. package/dist/zip/errors.js.map +1 -1
  302. package/dist/zip/types.d.ts +4 -0
  303. package/dist/zip/types.d.ts.map +1 -1
  304. package/dist/zip/types.js +4 -0
  305. package/dist/zip/types.js.map +1 -1
  306. package/package.json +2 -2
  307. package/src/core/Document.ts +1184 -242
  308. package/src/core/DocumentGenerator.ts +106 -26
  309. package/src/core/DocumentParser.ts +681 -114
  310. package/src/core/RelationshipManager.ts +446 -442
  311. package/src/elements/Comment.ts +123 -18
  312. package/src/elements/CommentManager.ts +121 -22
  313. package/src/elements/EndnoteManager.ts +4 -1
  314. package/src/elements/Field.ts +134 -43
  315. package/src/elements/FieldHelpers.ts +20 -4
  316. package/src/elements/Footer.ts +62 -67
  317. package/src/elements/FootnoteManager.ts +4 -1
  318. package/src/elements/Header.ts +62 -67
  319. package/src/elements/HeaderFooterManager.ts +56 -8
  320. package/src/elements/Hyperlink.ts +150 -55
  321. package/src/elements/Image.ts +51 -7
  322. package/src/elements/ImageManager.ts +24 -0
  323. package/src/elements/Paragraph.ts +161 -40
  324. package/src/elements/Revision.ts +446 -47
  325. package/src/elements/Run.ts +44 -6
  326. package/src/elements/Section.ts +25 -9
  327. package/src/elements/Shape.ts +52 -44
  328. package/src/elements/StructuredDocumentTag.ts +83 -8
  329. package/src/elements/Table.ts +151 -50
  330. package/src/elements/TableCell.ts +57 -17
  331. package/src/elements/TableOfContents.ts +10 -9
  332. package/src/elements/TableRow.ts +35 -3
  333. package/src/elements/TextBox.ts +58 -43
  334. package/src/formatting/AbstractNumbering.ts +4 -2
  335. package/src/formatting/NumberingLevel.ts +50 -12
  336. package/src/formatting/NumberingManager.ts +32 -3
  337. package/src/formatting/Style.ts +14 -0
  338. package/src/formatting/StylesManager.ts +29 -2
  339. package/src/helpers/CleanupHelper.ts +122 -30
  340. package/src/images/ImageOptimizer.ts +64 -5
  341. package/src/index.ts +7 -0
  342. package/src/internal.ts +1 -0
  343. package/src/processors/CompatibilityUpgrader.ts +15 -2
  344. package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
  345. package/src/processors/RevisionWalker.ts +390 -46
  346. package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
  347. package/src/processors/acceptRevisions.ts +67 -17
  348. package/src/processors/cnfStyleDecoder.ts +18 -12
  349. package/src/processors/stripTrackedChanges.ts +47 -10
  350. package/src/utils/deepClone.ts +48 -14
  351. package/src/utils/units.ts +3 -1
  352. package/src/utils/validation.ts +30 -32
  353. package/src/utils/xmlSanitization.ts +218 -22
  354. package/src/validation/RevisionAutoFixer.ts +109 -65
  355. package/src/validation/RevisionValidator.ts +48 -23
  356. package/src/xml/XMLBuilder.ts +82 -22
  357. package/src/xml/XMLParser.ts +87 -20
  358. package/src/zip/ZipHandler.ts +61 -21
  359. package/src/zip/ZipReader.ts +135 -13
  360. package/src/zip/errors.ts +15 -0
  361. package/src/zip/types.ts +44 -2
@@ -1 +1 @@
1
- {"version":3,"file":"acceptRevisions.js","sourceRoot":"","sources":["../../src/processors/acceptRevisions.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZipHandler } from '../zip/ZipHandler.js';\nimport { XMLParser } from '../xml/XMLParser.js';\nimport { RevisionWalker } from './RevisionWalker.js';\n\n/**\n * Markers covered: w:ins, w:del, w:moveFrom, w:moveTo,\n * w:rPrChange, w:pPrChange, w:tblPrChange, w:tblPrExChange,\n * w:trPrChange, w:tcPrChange, w:sectPrChange, w:numberingChange,\n * w:cellIns, w:cellDel, w:cellMerge, and any *RangeStart/End markers.\n */\nconst REVISION_MARKER_PATTERN =\n /<w:(?:ins|del|moveFrom|moveTo|rPrChange|pPrChange|tblPrChange|tblPrExChange|trPrChange|tcPrChange|sectPrChange|numberingChange|cellIns|cellDel|cellMerge|moveFromRangeStart|moveFromRangeEnd|moveToRangeStart|moveToRangeEnd|customXmlInsRangeStart|customXmlInsRangeEnd|customXmlDelRangeStart|customXmlDelRangeEnd|customXmlMoveFromRangeStart|customXmlMoveFromRangeEnd|customXmlMoveToRangeStart|customXmlMoveToRangeEnd)\\b/;\n\n/**\n * Accepts all tracked changes in a Word document per Microsoft's OpenXML SDK pattern\n *\n * This implementation uses DOM-based tree walking for reliability:\n * 1. Insertions (<w:ins>): Keep content, remove wrapper tags\n * 2. Deletions (<w:del>): Remove entirely (content and tags)\n * 3. Move From (<w:moveFrom>): Remove entirely (source of move)\n * 4. Move To (<w:moveTo>): Keep content, remove wrapper (destination of move)\n * 5. Property changes: Remove all *Change elements\n * 6. Range markers: Remove all boundary markers\n *\n * Also cleans up metadata in people.xml, settings.xml, and core.xml\n *\n * @see https://learn.microsoft.com/en-us/office/open-xml/how-to-accept-all-revisions\n */\nclass RevisionAcceptor {\n private zipHandler: ZipHandler;\n /** Feature flag for DOM-based processing (default: true) */\n private useDomBasedProcessing = true;\n\n constructor(zipHandler: ZipHandler) {\n this.zipHandler = zipHandler;\n }\n\n /**\n * Enable or disable DOM-based processing (for testing/migration)\n */\n setUseDomBasedProcessing(enabled: boolean): void {\n this.useDomBasedProcessing = enabled;\n }\n\n /**\n * Main method to accept all revisions in the document\n */\n public async acceptAllRevisions(): Promise<void> {\n // Process document.xml\n await this.processDocumentPart('word/document.xml');\n\n // Process headers / footers / footnotes / endnotes / comments.\n // Footnotes (§17.11.15), endnotes (§17.11.4), and comments (§17.13.4)\n // can all carry block-level content including tracked changes\n // (w:ins / w:del / pPrChange / rPrChange / moveFrom / moveTo).\n // Previously only document.xml + headers + footers were walked,\n // leaving footnote / endnote / comment revisions unaccepted so\n // Word still showed the document as having pending tracked\n // changes after `acceptAllRevisions()` returned.\n const files = this.zipHandler.getFilePaths();\n for (const file of files) {\n if (/^word\\/header\\d+\\.xml$/.exec(file)) {\n await this.processDocumentPart(file);\n }\n if (/^word\\/footer\\d+\\.xml$/.exec(file)) {\n await this.processDocumentPart(file);\n }\n }\n // Singleton notes / comments parts. Check presence explicitly\n // (not all documents have them) — processDocumentPart is a no-op\n // on missing files.\n for (const notesPath of ['word/footnotes.xml', 'word/endnotes.xml', 'word/comments.xml']) {\n if (this.zipHandler.getFileAsString(notesPath)) {\n await this.processDocumentPart(notesPath);\n }\n }\n\n // Clean up metadata files\n this.cleanupPeopleXml();\n this.cleanupSettingsXml();\n this.cleanupCorePropsXml();\n }\n\n /**\n * Process a document part (document.xml, header, footer) to accept revisions\n */\n private async processDocumentPart(partPath: string): Promise<void> {\n // Fast path: parts with no revision markup do not need to be re-serialised.\n // Re-serialising a part destroys the original whitespace / formatting\n // (XMLBuilder emits a different layout than the source), which can break\n // byte-for-byte passthrough preservation in downstream consumers\n // (e.g., comments.xml round-trip with no tracked changes inside).\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml || !RevisionAcceptor.containsRevisionMarkup(xml)) {\n return;\n }\n\n if (this.useDomBasedProcessing) {\n return this.processDocumentPartDOM(partPath);\n }\n return this.processDocumentPartRegex(partPath);\n }\n\n /**\n * Quick scan for any tracked-change marker. Returns false when the part\n * carries none, allowing the acceptor to skip an unnecessary parse +\n * re-serialise round-trip.\n */\n private static containsRevisionMarkup(xml: string): boolean {\n return REVISION_MARKER_PATTERN.test(xml);\n }\n\n /**\n * DOM-based implementation of revision acceptance\n * Uses XMLParser and RevisionWalker for reliable processing\n */\n private processDocumentPartDOM(partPath: string): void {\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml) {\n return;\n }\n\n // Step 1: Parse XML to object tree\n // IMPORTANT: trimValues: false preserves whitespace from xml:space=\"preserve\" attributes\n const parsed = XMLParser.parseToObject(xml, { trimValues: false });\n\n // Step 2: Process revisions using DOM walker\n const processed = RevisionWalker.processTree(parsed, {\n acceptInsertions: true,\n acceptDeletions: true,\n acceptMoves: true,\n acceptPropertyChanges: true,\n });\n\n // Step 3: Handle image relationship ID remapping\n this.remapImageRelationshipsInTree(processed);\n\n // Step 4: Convert back to XML\n const outputXml =\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n' + this.objectToXml(processed);\n\n // Step 5: Update file\n this.zipHandler.updateFile(partPath, outputXml);\n }\n\n /**\n * Legacy RegEx-based implementation (kept as fallback)\n */\n private processDocumentPartRegex(partPath: string): void {\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml) {\n return;\n }\n\n let content = xml;\n\n // Step 1: Remove all range markers FIRST (before processing revisions)\n // This prevents orphaned references when revision content is modified\n content = this.removeAllRangeMarkers(content);\n\n // Step 2: Remove all property change elements\n // These track formatting changes and must be removed before other processing\n content = this.removeAllPropertyChanges(content);\n\n // Step 3: Process deletions - remove entire element INCLUDING content\n // Must be done before insertions to handle nested scenarios\n content = this.acceptDeletions(content);\n\n // Step 4: Process move operations\n // Remove moveFrom entirely (source), unwrap moveTo (destination)\n content = this.acceptMoveFrom(content);\n content = this.acceptMoveTo(content);\n\n // Step 5: Process insertions - keep content, remove wrapper\n content = this.acceptInsertions(content);\n\n // Step 6: Final cleanup - remove any remaining orphaned tags\n content = this.cleanupOrphanedTags(content);\n\n // Update the file\n this.zipHandler.updateFile(partPath, content);\n }\n\n /**\n * Remove all range marker elements\n * These are boundary markers for tracked changes and moves\n */\n private removeAllRangeMarkers(xml: string): string {\n const patterns = [\n // Move range markers\n /<w:moveFromRangeStart[^>]*(?:\\/>|>.*?<\\/w:moveFromRangeStart>)/gs,\n /<w:moveFromRangeEnd[^>]*(?:\\/>|>.*?<\\/w:moveFromRangeEnd>)/gs,\n /<w:moveToRangeStart[^>]*(?:\\/>|>.*?<\\/w:moveToRangeStart>)/gs,\n /<w:moveToRangeEnd[^>]*(?:\\/>|>.*?<\\/w:moveToRangeEnd>)/gs,\n // Custom XML range markers\n /<w:customXmlInsRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlInsRangeStart>)/gs,\n /<w:customXmlInsRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlInsRangeEnd>)/gs,\n /<w:customXmlDelRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlDelRangeStart>)/gs,\n /<w:customXmlDelRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlDelRangeEnd>)/gs,\n /<w:customXmlMoveFromRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveFromRangeStart>)/gs,\n /<w:customXmlMoveFromRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveFromRangeEnd>)/gs,\n /<w:customXmlMoveToRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveToRangeStart>)/gs,\n /<w:customXmlMoveToRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveToRangeEnd>)/gs,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n return result;\n }\n\n /**\n * Remove all property change tracking elements\n * Per ECMA-376, these track previous state of formatting\n */\n private removeAllPropertyChanges(xml: string): string {\n const patterns = [\n // Run property changes\n /<w:rPrChange[^>]*>[\\s\\S]*?<\\/w:rPrChange>/g,\n // Paragraph property changes\n /<w:pPrChange[^>]*>[\\s\\S]*?<\\/w:pPrChange>/g,\n // Table property changes\n /<w:tblPrChange[^>]*>[\\s\\S]*?<\\/w:tblPrChange>/g,\n /<w:tblPrExChange[^>]*>[\\s\\S]*?<\\/w:tblPrExChange>/g,\n // Table cell property changes\n /<w:tcPrChange[^>]*>[\\s\\S]*?<\\/w:tcPrChange>/g,\n // Table row property changes\n /<w:trPrChange[^>]*>[\\s\\S]*?<\\/w:trPrChange>/g,\n // Section property changes\n /<w:sectPrChange[^>]*>[\\s\\S]*?<\\/w:sectPrChange>/g,\n // Table grid changes\n /<w:tblGridChange[^>]*>[\\s\\S]*?<\\/w:tblGridChange>/g,\n // Numbering changes\n /<w:numberingChange[^>]*>[\\s\\S]*?<\\/w:numberingChange>/g,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n return result;\n }\n\n /**\n * Accept deletions - remove the entire <w:del> element including its content.\n *\n * Per Microsoft SDK: \"DeletedRun elements should be removed along with\n * their content\". Additionally, per ECMA-376 Part 1 §17.13.5.14, a\n * self-closing `<w:del/>` inside `<w:trPr>` marks the entire row as a\n * tracked deletion — accepting it must remove the entire `<w:tr>` block,\n * not just the marker. Without that, zombie rows (the row wrapper with\n * empty cells) persist in the document after revision acceptance.\n */\n private acceptDeletions(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n // Pass A — row-level deletion: remove entire <w:tr> whose <w:trPr>\n // contains a self-closing row-deletion marker. Constraints:\n // - `<w:trPr\\b(?:\\s[^>]*)?>` only matches the OPEN form of trPr (i.e.\n // rejects self-closing `<w:trPr/>`, which by definition contains\n // no del markers), so the match anchors on the correct row.\n // - negative lookahead `(?!<w:tc\\b|<w:tr\\b|<\\/w:tr>)` between the\n // `<w:tr>` opening and the `<w:trPr>` prevents the match from\n // slipping past a cell boundary or nested-table row and latching\n // onto a later row's trPr-with-del.\n const rowDelPattern =\n /<w:tr\\b[^>]*>(?:(?!<w:tc\\b|<w:tr\\b|<\\/w:tr>)[\\s\\S])*?<w:trPr\\b(?:\\s[^>]*)?>(?:(?!<\\/w:trPr>)[\\s\\S])*?<w:del\\b[^>]*\\/>(?:(?!<\\/w:trPr>)[\\s\\S])*?<\\/w:trPr>(?:(?!<w:tr\\b|<\\/w:tr>)[\\s\\S])*?<\\/w:tr>/g;\n previousLength = 0;\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(rowDelPattern, '');\n }\n\n // Pass B — wrapper deletions: iterate until no more <w:del>..</w:del>\n // elements (handles nested cases).\n previousLength = 0;\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(/<w:del\\b[^>]*>[\\s\\S]*?<\\/w:del>/g, '');\n }\n\n // Pass C — remove any remaining self-closing deletion markers (paragraph\n // mark deletions inside pPr/rPr, orphans, etc.). By this point, any\n // row-level markers have already triggered full-row removal in Pass A,\n // so this pass only cleans up non-structural markers.\n result = result.replace(/<w:del\\b[^>]*\\/>/g, '');\n\n return result;\n }\n\n /**\n * Accept moveFrom - remove the entire element (source of moved content)\n *\n * The content exists at the moveTo destination, so we discard the source\n */\n private acceptMoveFrom(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(/<w:moveFrom\\b[^>]*>[\\s\\S]*?<\\/w:moveFrom>/g, '');\n }\n\n // Also remove self-closing tags\n result = result.replace(/<w:moveFrom\\b[^>]*\\/>/g, '');\n\n return result;\n }\n\n /**\n * Accept moveTo - keep the content, remove the wrapper tags\n *\n * The moveTo location is where the content should remain\n */\n private acceptMoveTo(xml: string): string {\n let result = xml;\n\n // Remove closing tags first (prevents issues with regex matching)\n result = result.replace(/<\\/w:moveTo>/g, '');\n\n // Remove opening tags (keeps content that was inside)\n result = result.replace(/<w:moveTo\\b[^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Accept insertions - keep the content, remove the wrapper tags\n *\n * Per Microsoft SDK: \"InsertedRun elements should be unwrapped, keeping their content\"\n *\n * IMPORTANT: This method now handles relationship ID remapping for images inside insertions.\n * When Word tracks changes with images, it can reuse relationship IDs (like rId5) because\n * they're in separate tracked change contexts. But when we unwrap them, duplicate IDs\n * cause corruption. This method assigns new unique IDs to images inside insertions.\n */\n private acceptInsertions(xml: string): string {\n let result = xml;\n\n // Parse existing relationships\n const relationships = this.parseRelationships();\n const existingIds = new Set(relationships.keys());\n\n // Process each w:ins element and remap images one by one\n const insRegex = /<w:ins\\b[^>]*>[\\s\\S]*?<\\/w:ins>/g;\n\n result = result.replace(insRegex, (insMatch) => {\n // For each image reference inside this insertion, generate a unique new ID\n return insMatch.replace(/r:embed=\"(rId\\d+)\"/g, (_embedMatch, oldId) => {\n // Generate new unique ID for THIS occurrence\n const newId = this.getNextRelationshipId(existingIds);\n existingIds.add(newId);\n\n // Add relationship with same target as original\n const target = relationships.get(oldId);\n if (target) {\n this.addRelationship(\n newId,\n target,\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'\n );\n }\n\n return `r:embed=\"${newId}\"`;\n });\n });\n\n // Now unwrap the w:ins tags (content has unique remapped IDs)\n result = result.replace(/<\\/w:ins>/g, '');\n result = result.replace(/<w:ins\\b[^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Final cleanup to remove any orphaned or malformed revision-related tags\n */\n private cleanupOrphanedTags(xml: string): string {\n let result = xml;\n\n // Remove any remaining self-closing revision tags\n result = result.replace(/<w:ins\\b[^>]*\\/>/g, '');\n result = result.replace(/<w:del\\b[^>]*\\/>/g, '');\n result = result.replace(/<w:moveFrom\\b[^>]*\\/>/g, '');\n result = result.replace(/<w:moveTo\\b[^>]*\\/>/g, '');\n\n // Remove empty w:r elements that might be left after removing deletions\n result = result.replace(/<w:r\\b[^>]*>\\s*<\\/w:r>/g, '');\n\n // Remove empty w:p elements (but preserve those with properties)\n // We keep <w:p><w:pPr>...</w:pPr></w:p> as those are intentional empty paragraphs with styling\n result = result.replace(/<w:p>\\s*<\\/w:p>/g, '');\n\n return result;\n }\n\n /**\n * Parse relationship IDs from word/_rels/document.xml.rels\n * Returns a map of relationship ID to target path\n */\n private parseRelationships(): Map<string, string> {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return new Map();\n\n const map = new Map<string, string>();\n const relationshipRegex = /<Relationship[^>]*Id=\"([^\"]+)\"[^>]*Target=\"([^\"]+)\"[^>]*\\/>/g;\n let match;\n\n while ((match = relationshipRegex.exec(relsXml)) !== null) {\n if (match[1] && match[2]) {\n map.set(match[1], match[2]); // rId -> target path\n }\n }\n\n return map;\n }\n\n /**\n * Get the next available relationship ID\n * Finds the highest numeric ID and increments it\n */\n private getNextRelationshipId(existingIds: Set<string>): string {\n let maxId = 0;\n for (const id of existingIds) {\n const num = parseInt(id.replace('rId', ''));\n if (!isNaN(num) && num > maxId) {\n maxId = num;\n }\n }\n return `rId${maxId + 1}`;\n }\n\n /**\n * Add a new relationship to word/_rels/document.xml.rels\n */\n private addRelationship(rId: string, target: string, type: string): void {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return;\n\n // Insert new relationship before closing tag\n const newRel = `<Relationship Id=\"${rId}\" Type=\"${type}\" Target=\"${target}\"/>`;\n const updated = relsXml.replace('</Relationships>', `${newRel}\\n</Relationships>`);\n\n this.zipHandler.updateFile('word/_rels/document.xml.rels', updated);\n }\n\n /**\n * Clean up all revision metadata files (people.xml, settings.xml, core.xml).\n *\n * This removes:\n * - All revision authors from people.xml\n * - Track changes settings from settings.xml\n * - Resets revision count in core.xml\n *\n * Called as part of acceptAllRevisions() but can also be called separately\n * when using in-memory revision acceptance.\n */\n public cleanupMetadata(): void {\n this.cleanupPeopleXml();\n this.cleanupSettingsXml();\n this.cleanupCorePropsXml();\n }\n\n /**\n * Clean up word/people.xml - remove all revision authors\n *\n * Handles both w: and w15: namespace variants\n */\n private cleanupPeopleXml(): void {\n const peopleXml = this.zipHandler.getFileAsString('word/people.xml');\n if (!peopleXml) {\n return;\n }\n\n let content = peopleXml;\n\n // Remove all person elements in any namespace variant\n content = content.replace(/<w:person\\b[^>]*>[\\s\\S]*?<\\/w:person>/g, '');\n content = content.replace(/<w15:person\\b[^>]*>[\\s\\S]*?<\\/w15:person>/g, '');\n\n // Handle any namespace-prefixed variants (w1:, w2:, etc.)\n content = content.replace(/<w\\d+:person\\b[^>]*>[\\s\\S]*?<\\/w\\d+:person>/g, '');\n\n // Also remove self-closing person elements\n content = content.replace(/<w:person\\b[^>]*\\/>/g, '');\n content = content.replace(/<w15:person\\b[^>]*\\/>/g, '');\n content = content.replace(/<w\\d+:person\\b[^>]*\\/>/g, '');\n\n this.zipHandler.updateFile('word/people.xml', content);\n }\n\n /**\n * Clean up word/settings.xml - disable track changes\n */\n private cleanupSettingsXml(): void {\n const settingsXml = this.zipHandler.getFileAsString('word/settings.xml');\n if (!settingsXml) {\n return;\n }\n\n let content = settingsXml;\n\n // Remove trackRevisions element (enables tracking)\n content = content.replace(/<w:trackRevisions\\b[^>]*\\/>/g, '');\n content = content.replace(/<w:trackRevisions\\b[^>]*>[\\s\\S]*?<\\/w:trackRevisions>/g, '');\n\n // Remove revisionView element (controls which revisions are visible)\n content = content.replace(/<w:revisionView\\b[^>]*\\/>/g, '');\n content = content.replace(/<w:revisionView\\b[^>]*>[\\s\\S]*?<\\/w:revisionView>/g, '');\n\n // Remove doNotTrackMoves (prevents move tracking)\n content = content.replace(/<w:doNotTrackMoves\\b[^>]*\\/>/g, '');\n content = content.replace(/<w:doNotTrackMoves\\b[^>]*>[\\s\\S]*?<\\/w:doNotTrackMoves>/g, '');\n\n // Remove doNotTrackFormatting\n content = content.replace(/<w:doNotTrackFormatting\\b[^>]*\\/>/g, '');\n content = content.replace(\n /<w:doNotTrackFormatting\\b[^>]*>[\\s\\S]*?<\\/w:doNotTrackFormatting>/g,\n ''\n );\n\n this.zipHandler.updateFile('word/settings.xml', content);\n }\n\n /**\n * Clean up docProps/core.xml - reset revision count\n */\n private cleanupCorePropsXml(): void {\n const coreXml = this.zipHandler.getFileAsString('docProps/core.xml');\n if (!coreXml) {\n return;\n }\n\n // Reset revision count to 1\n const content = coreXml.replace(\n /<cp:revision>\\d+<\\/cp:revision>/g,\n '<cp:revision>1</cp:revision>'\n );\n\n this.zipHandler.updateFile('docProps/core.xml', content);\n }\n\n // =========================================================================\n // DOM-based processing helper methods\n // =========================================================================\n\n /**\n * Convert parsed XML object back to XML string\n * Preserves element order using _orderedChildren metadata\n *\n * Based on DocumentParser.objectToXml() implementation\n */\n private objectToXml(obj: any): string {\n const buildXml = (o: any, name?: string): string => {\n // Handle simple string/number with a tag name: <tagName>value</tagName>\n if (name && (typeof o === 'string' || typeof o === 'number')) {\n return `<${name}>${this.escapeXml(String(o))}</${name}>`;\n }\n if (typeof o === 'string') return this.escapeXml(o);\n if (typeof o !== 'object' || o === null) return String(o ?? '');\n\n const keys = Object.keys(o);\n\n // If a name is provided, we're building a specific element\n // Don't return empty string for empty objects with a name - they become self-closing tags\n if (keys.length === 0 && !name) return '';\n\n const tagName = name || keys[0]!;\n const element = name ? o : o[tagName];\n\n let xml = `<${tagName}`;\n\n // Add attributes (keys starting with @_)\n if (element && typeof element === 'object') {\n for (const key of Object.keys(element)) {\n if (key.startsWith('@_')) {\n const attrName = key.substring(2);\n xml += ` ${attrName}=\"${this.escapeXml(String(element[key]))}\"`;\n }\n }\n }\n\n // Check for children (non-attribute, non-text, non-metadata keys)\n const hasChildren =\n element &&\n typeof element === 'object' &&\n Object.keys(element).some(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n // Per ECMA-376, certain elements MUST NOT be self-closing (e.g., <w:p/> is invalid).\n // This mirrors the CANNOT_SELF_CLOSE list in XMLBuilder.ts.\n const CANNOT_SELF_CLOSE = [\n 'w:t',\n 'w:r',\n 'w:p',\n 'w:tbl',\n 'w:tr',\n 'w:tc',\n 'w:body',\n 'w:document',\n 'w:hyperlink',\n 'w:sdt',\n 'w:sdtContent',\n 'w:sdtPr',\n 'w:pPr',\n 'w:rPr',\n 'w:sectPr',\n 'w:del',\n 'w:ins',\n 'w:moveFrom',\n 'w:moveTo',\n ];\n\n if (!hasChildren && !element?.['#text']) {\n if (CANNOT_SELF_CLOSE.includes(tagName)) {\n xml += `></${tagName}>`;\n } else {\n xml += '/>';\n }\n } else {\n xml += '>';\n\n // Add text content\n if (element?.['#text']) {\n xml += this.escapeXml(String(element['#text']));\n }\n\n // Add child elements using _orderedChildren if available\n if (element && typeof element === 'object') {\n const orderedChildren = element._orderedChildren as\n | { type: string; index: number }[]\n | undefined;\n\n if (orderedChildren && orderedChildren.length > 0) {\n // Use _orderedChildren to preserve element order\n for (const childInfo of orderedChildren) {\n const childType = childInfo.type;\n const childIndex = childInfo.index;\n\n if (element[childType] !== undefined) {\n const children = element[childType];\n\n if (Array.isArray(children)) {\n if (childIndex < children.length) {\n const childXml = buildXml(children[childIndex], childType);\n xml += childXml;\n }\n } else {\n // Single child element\n if (childIndex === 0) {\n const childXml = buildXml(children, childType);\n xml += childXml;\n }\n }\n }\n }\n } else {\n // Fallback: iterate through keys if no _orderedChildren\n for (const key of Object.keys(element)) {\n if (!key.startsWith('@_') && key !== '#text' && key !== '_orderedChildren') {\n const children = element[key];\n if (Array.isArray(children)) {\n for (const child of children) {\n xml += buildXml(child, key);\n }\n } else {\n xml += buildXml(children, key);\n }\n }\n }\n }\n }\n\n xml += `</${tagName}>`;\n }\n\n return xml;\n };\n\n return buildXml(obj);\n }\n\n /**\n * Escape special XML characters\n */\n private escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n }\n\n /**\n * Remap image relationship IDs in the parsed tree to prevent duplicates\n * Walks the tree looking for r:embed attributes and assigns unique IDs\n */\n private remapImageRelationshipsInTree(obj: any): void {\n const relationships = this.parseRelationships();\n const existingIds = new Set(relationships.keys());\n const remappedIds = new Map<string, string>();\n\n // Walk the tree and find all r:embed attributes\n this.walkTreeForEmbeds(obj, (embedId: string, parent: any, key: string) => {\n // Check if this ID has already been remapped\n if (remappedIds.has(embedId)) {\n parent[key] = remappedIds.get(embedId);\n return;\n }\n\n // Check if this ID needs remapping (duplicate)\n // For DOM-based processing, we check if we've seen this ID before in this pass\n const target = relationships.get(embedId);\n if (target) {\n // Generate new unique ID\n const newId = this.getNextRelationshipId(existingIds);\n existingIds.add(newId);\n remappedIds.set(embedId, newId);\n\n // Add relationship with same target\n this.addRelationship(\n newId,\n target,\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'\n );\n\n // Update the attribute\n parent[key] = newId;\n }\n });\n }\n\n /**\n * Walk the tree looking for r:embed attributes\n */\n private walkTreeForEmbeds(\n obj: any,\n callback: (embedId: string, parent: any, key: string) => void\n ): void {\n if (!obj || typeof obj !== 'object') {\n return;\n }\n\n for (const key of Object.keys(obj)) {\n // Check for r:embed attribute\n if (key === '@_r:embed') {\n callback(obj[key], obj, key);\n } else if (!key.startsWith('@_') && key !== '#text' && key !== '_orderedChildren') {\n const value = obj[key];\n if (Array.isArray(value)) {\n for (const item of value) {\n this.walkTreeForEmbeds(item, callback);\n }\n } else if (typeof value === 'object') {\n this.walkTreeForEmbeds(value, callback);\n }\n }\n }\n }\n}\n\n/**\n * Convenience function to accept all revisions in a document\n */\nexport async function acceptAllRevisions(zipHandler: ZipHandler): Promise<void> {\n const acceptor = new RevisionAcceptor(zipHandler);\n await acceptor.acceptAllRevisions();\n}\n\n/**\n * Convenience function to clean up revision metadata files.\n *\n * This removes:\n * - All revision authors from people.xml\n * - Track changes settings from settings.xml\n * - Resets revision count in core.xml\n *\n * Use this after in-memory revision acceptance to ensure metadata is also cleaned.\n * The raw XML acceptAllRevisions() function calls this automatically.\n *\n * @param zipHandler - The ZipHandler containing the DOCX package\n */\nexport function cleanupRevisionMetadata(zipHandler: ZipHandler): void {\n const acceptor = new RevisionAcceptor(zipHandler);\n acceptor.cleanupMetadata();\n}\n"]}
1
+ {"version":3,"file":"acceptRevisions.js","sourceRoot":"","sources":["../../src/processors/acceptRevisions.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZipHandler } from '../zip/ZipHandler.js';\nimport { XMLParser } from '../xml/XMLParser.js';\nimport { RevisionWalker } from './RevisionWalker.js';\n\n/**\n * Markers covered: w:ins, w:del, w:moveFrom, w:moveTo,\n * w:rPrChange, w:pPrChange, w:tblPrChange, w:tblPrExChange,\n * w:trPrChange, w:tcPrChange, w:sectPrChange, w:tblGridChange,\n * w:numberingChange, w:cellIns, w:cellDel, w:cellMerge, and any\n * *RangeStart/End markers.\n */\nconst REVISION_MARKER_PATTERN =\n /<w:(?:ins|del|moveFrom|moveTo|rPrChange|pPrChange|tblPrChange|tblPrExChange|trPrChange|tcPrChange|sectPrChange|tblGridChange|numberingChange|cellIns|cellDel|cellMerge|moveFromRangeStart|moveFromRangeEnd|moveToRangeStart|moveToRangeEnd|customXmlInsRangeStart|customXmlInsRangeEnd|customXmlDelRangeStart|customXmlDelRangeEnd|customXmlMoveFromRangeStart|customXmlMoveFromRangeEnd|customXmlMoveToRangeStart|customXmlMoveToRangeEnd)\\b/;\n\n/**\n * Applies tracked changes in a Word document per Microsoft's OpenXML SDK\n * pattern, in either direction (see `mode`).\n *\n * This implementation uses DOM-based tree walking for reliability. In 'accept'\n * mode (the post-edit document):\n * 1. Insertions (<w:ins>): Keep content, remove wrapper tags\n * 2. Deletions (<w:del>): Remove entirely (content and tags)\n * 3. Move From (<w:moveFrom>): Remove entirely (source of move)\n * 4. Move To (<w:moveTo>): Keep content, remove wrapper (destination of move)\n * 5. Property changes: Remove all *Change elements\n * 6. Range markers: Remove all boundary markers\n *\n * In 'reject' mode every content decision is inverted and property changes\n * restore the previous formatting (see RevisionWalker).\n *\n * Also cleans up metadata in people.xml, settings.xml, and core.xml\n *\n * @see https://learn.microsoft.com/en-us/office/open-xml/how-to-accept-all-revisions\n */\nclass RevisionProcessor {\n private zipHandler: ZipHandler;\n /** Feature flag for DOM-based processing (default: true) */\n private useDomBasedProcessing = true;\n /**\n * Processing direction. 'accept' yields the post-edit document; 'reject'\n * reverts to the original pre-edit document (the exact inverse). Reject is\n * DOM-only — the regex fallback cannot restore previous formatting.\n */\n private mode: 'accept' | 'reject';\n\n constructor(zipHandler: ZipHandler, mode: 'accept' | 'reject' = 'accept') {\n this.zipHandler = zipHandler;\n this.mode = mode;\n }\n\n /**\n * Enable or disable DOM-based processing (for testing/migration)\n */\n setUseDomBasedProcessing(enabled: boolean): void {\n this.useDomBasedProcessing = enabled;\n }\n\n /**\n * Main entry point: apply every tracked change in the document in the\n * configured direction (accept or reject).\n */\n public async process(): Promise<void> {\n // Process document.xml\n await this.processDocumentPart('word/document.xml');\n\n // Process headers / footers / footnotes / endnotes / comments.\n // Footnotes (§17.11.15), endnotes (§17.11.4), and comments (§17.13.4)\n // can all carry block-level content including tracked changes\n // (w:ins / w:del / pPrChange / rPrChange / moveFrom / moveTo).\n // Previously only document.xml + headers + footers were walked,\n // leaving footnote / endnote / comment revisions unaccepted so\n // Word still showed the document as having pending tracked\n // changes after `acceptAllRevisions()` returned.\n const files = this.zipHandler.getFilePaths();\n for (const file of files) {\n if (/^word\\/header\\d+\\.xml$/.exec(file)) {\n await this.processDocumentPart(file);\n }\n if (/^word\\/footer\\d+\\.xml$/.exec(file)) {\n await this.processDocumentPart(file);\n }\n }\n // Singleton notes / comments parts. Check presence explicitly\n // (not all documents have them) — processDocumentPart is a no-op\n // on missing files.\n for (const notesPath of ['word/footnotes.xml', 'word/endnotes.xml', 'word/comments.xml']) {\n if (this.zipHandler.getFileAsString(notesPath)) {\n await this.processDocumentPart(notesPath);\n }\n }\n\n // Clean up metadata files\n this.cleanupPeopleXml();\n this.cleanupSettingsXml();\n this.cleanupCorePropsXml();\n }\n\n /**\n * Process a document part (document.xml, header, footer) to accept revisions\n */\n private async processDocumentPart(partPath: string): Promise<void> {\n // Fast path: parts with no revision markup do not need to be re-serialised.\n // Re-serialising a part destroys the original whitespace / formatting\n // (XMLBuilder emits a different layout than the source), which can break\n // byte-for-byte passthrough preservation in downstream consumers\n // (e.g., comments.xml round-trip with no tracked changes inside).\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml || !RevisionProcessor.containsRevisionMarkup(xml)) {\n return;\n }\n\n // Reject must restore previous formatting from *Change snapshots, which the\n // regex fallback cannot do — always take the DOM path when rejecting.\n if (this.useDomBasedProcessing || this.mode === 'reject') {\n return this.processDocumentPartDOM(partPath);\n }\n return this.processDocumentPartRegex(partPath);\n }\n\n /**\n * Quick scan for any tracked-change marker. Returns false when the part\n * carries none, allowing the acceptor to skip an unnecessary parse +\n * re-serialise round-trip.\n */\n private static containsRevisionMarkup(xml: string): boolean {\n return REVISION_MARKER_PATTERN.test(xml);\n }\n\n /**\n * DOM-based implementation of revision acceptance\n * Uses XMLParser and RevisionWalker for reliable processing\n */\n private processDocumentPartDOM(partPath: string): void {\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml) {\n return;\n }\n\n // Step 1: Parse XML to object tree\n // IMPORTANT: trimValues: false preserves whitespace from xml:space=\"preserve\" attributes\n const parsed = XMLParser.parseToObject(xml, { trimValues: false });\n\n // Step 2: Process revisions using DOM walker\n const processed = RevisionWalker.processTree(parsed, {\n mode: this.mode,\n acceptInsertions: true,\n acceptDeletions: true,\n acceptMoves: true,\n acceptPropertyChanges: true,\n });\n\n // Step 3: Handle image relationship ID remapping.\n // Only relevant when accepting: unwrapping an inserted image can surface a\n // relationship ID that Word reused across tracked-change contexts, so a\n // fresh unique ID is assigned. Rejecting discards insertions and restores\n // the original content, whose relationship IDs are already unique, so\n // remapping would needlessly rewrite valid references.\n if (this.mode === 'accept') {\n this.remapImageRelationshipsInTree(processed);\n }\n\n // Step 4: Convert back to XML\n const outputXml =\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n' + this.objectToXml(processed);\n\n // Step 5: Update file\n this.zipHandler.updateFile(partPath, outputXml);\n }\n\n /**\n * Legacy RegEx-based implementation (kept as fallback)\n */\n private processDocumentPartRegex(partPath: string): void {\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml) {\n return;\n }\n\n let content = xml;\n\n // Step 1: Remove all range markers FIRST (before processing revisions)\n // This prevents orphaned references when revision content is modified\n content = this.removeAllRangeMarkers(content);\n\n // Step 2: Remove all property change elements\n // These track formatting changes and must be removed before other processing\n content = this.removeAllPropertyChanges(content);\n\n // Step 3: Process deletions - remove entire element INCLUDING content\n // Must be done before insertions to handle nested scenarios\n content = this.acceptDeletions(content);\n\n // Step 4: Process move operations\n // Remove moveFrom entirely (source), unwrap moveTo (destination)\n content = this.acceptMoveFrom(content);\n content = this.acceptMoveTo(content);\n\n // Step 5: Process insertions - keep content, remove wrapper\n content = this.acceptInsertions(content);\n\n // Step 6: Final cleanup - remove any remaining orphaned tags\n content = this.cleanupOrphanedTags(content);\n\n // Update the file\n this.zipHandler.updateFile(partPath, content);\n }\n\n /**\n * Remove all range marker elements\n * These are boundary markers for tracked changes and moves\n */\n private removeAllRangeMarkers(xml: string): string {\n const patterns = [\n // Move range markers\n /<w:moveFromRangeStart[^>]*(?:\\/>|>.*?<\\/w:moveFromRangeStart>)/gs,\n /<w:moveFromRangeEnd[^>]*(?:\\/>|>.*?<\\/w:moveFromRangeEnd>)/gs,\n /<w:moveToRangeStart[^>]*(?:\\/>|>.*?<\\/w:moveToRangeStart>)/gs,\n /<w:moveToRangeEnd[^>]*(?:\\/>|>.*?<\\/w:moveToRangeEnd>)/gs,\n // Custom XML range markers\n /<w:customXmlInsRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlInsRangeStart>)/gs,\n /<w:customXmlInsRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlInsRangeEnd>)/gs,\n /<w:customXmlDelRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlDelRangeStart>)/gs,\n /<w:customXmlDelRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlDelRangeEnd>)/gs,\n /<w:customXmlMoveFromRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveFromRangeStart>)/gs,\n /<w:customXmlMoveFromRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveFromRangeEnd>)/gs,\n /<w:customXmlMoveToRangeStart[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveToRangeStart>)/gs,\n /<w:customXmlMoveToRangeEnd[^>]*(?:\\/>|>.*?<\\/w:customXmlMoveToRangeEnd>)/gs,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n return result;\n }\n\n /**\n * Remove all property change tracking elements\n * Per ECMA-376, these track previous state of formatting\n */\n private removeAllPropertyChanges(xml: string): string {\n const patterns = [\n // Run property changes\n /<w:rPrChange[^>]*>[\\s\\S]*?<\\/w:rPrChange>/g,\n // Paragraph property changes\n /<w:pPrChange[^>]*>[\\s\\S]*?<\\/w:pPrChange>/g,\n // Table property changes\n /<w:tblPrChange[^>]*>[\\s\\S]*?<\\/w:tblPrChange>/g,\n /<w:tblPrExChange[^>]*>[\\s\\S]*?<\\/w:tblPrExChange>/g,\n // Table cell property changes\n /<w:tcPrChange[^>]*>[\\s\\S]*?<\\/w:tcPrChange>/g,\n // Table row property changes\n /<w:trPrChange[^>]*>[\\s\\S]*?<\\/w:trPrChange>/g,\n // Section property changes\n /<w:sectPrChange[^>]*>[\\s\\S]*?<\\/w:sectPrChange>/g,\n // Table grid changes\n /<w:tblGridChange[^>]*>[\\s\\S]*?<\\/w:tblGridChange>/g,\n // Numbering changes\n /<w:numberingChange[^>]*>[\\s\\S]*?<\\/w:numberingChange>/g,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n return result;\n }\n\n /**\n * Accept deletions - remove the entire <w:del> element including its content.\n *\n * Per Microsoft SDK: \"DeletedRun elements should be removed along with\n * their content\". Additionally, per ECMA-376 Part 1 §17.13.5.14, a\n * self-closing `<w:del/>` inside `<w:trPr>` marks the entire row as a\n * tracked deletion — accepting it must remove the entire `<w:tr>` block,\n * not just the marker. Without that, zombie rows (the row wrapper with\n * empty cells) persist in the document after revision acceptance.\n */\n private acceptDeletions(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n // Pass A — row-level deletion: remove entire <w:tr> whose <w:trPr>\n // contains a self-closing row-deletion marker. Constraints:\n // - `<w:trPr\\b(?:\\s[^>]*)?>` only matches the OPEN form of trPr (i.e.\n // rejects self-closing `<w:trPr/>`, which by definition contains\n // no del markers), so the match anchors on the correct row.\n // - negative lookahead `(?!<w:tc\\b|<w:tr\\b|<\\/w:tr>)` between the\n // `<w:tr>` opening and the `<w:trPr>` prevents the match from\n // slipping past a cell boundary or nested-table row and latching\n // onto a later row's trPr-with-del.\n const rowDelPattern =\n /<w:tr\\b[^>]*>(?:(?!<w:tc\\b|<w:tr\\b|<\\/w:tr>)[\\s\\S])*?<w:trPr\\b(?:\\s[^>]*)?>(?:(?!<\\/w:trPr>)[\\s\\S])*?<w:del\\b[^>]*\\/>(?:(?!<\\/w:trPr>)[\\s\\S])*?<\\/w:trPr>(?:(?!<w:tr\\b|<\\/w:tr>)[\\s\\S])*?<\\/w:tr>/g;\n previousLength = 0;\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(rowDelPattern, '');\n }\n\n // Pass B — wrapper deletions: iterate until no more <w:del>..</w:del>\n // elements (handles nested cases).\n previousLength = 0;\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(/<w:del\\b[^>]*>[\\s\\S]*?<\\/w:del>/g, '');\n }\n\n // Pass C — remove any remaining self-closing deletion markers (paragraph\n // mark deletions inside pPr/rPr, orphans, etc.). By this point, any\n // row-level markers have already triggered full-row removal in Pass A,\n // so this pass only cleans up non-structural markers.\n result = result.replace(/<w:del\\b[^>]*\\/>/g, '');\n\n return result;\n }\n\n /**\n * Accept moveFrom - remove the entire element (source of moved content)\n *\n * The content exists at the moveTo destination, so we discard the source\n */\n private acceptMoveFrom(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(/<w:moveFrom\\b[^>]*>[\\s\\S]*?<\\/w:moveFrom>/g, '');\n }\n\n // Also remove self-closing tags\n result = result.replace(/<w:moveFrom\\b[^>]*\\/>/g, '');\n\n return result;\n }\n\n /**\n * Accept moveTo - keep the content, remove the wrapper tags\n *\n * The moveTo location is where the content should remain\n */\n private acceptMoveTo(xml: string): string {\n let result = xml;\n\n // Remove closing tags first (prevents issues with regex matching)\n result = result.replace(/<\\/w:moveTo>/g, '');\n\n // Remove opening tags (keeps content that was inside)\n result = result.replace(/<w:moveTo\\b[^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Accept insertions - keep the content, remove the wrapper tags\n *\n * Per Microsoft SDK: \"InsertedRun elements should be unwrapped, keeping their content\"\n *\n * IMPORTANT: This method now handles relationship ID remapping for images inside insertions.\n * When Word tracks changes with images, it can reuse relationship IDs (like rId5) because\n * they're in separate tracked change contexts. But when we unwrap them, duplicate IDs\n * cause corruption. This method assigns new unique IDs to images inside insertions.\n */\n private acceptInsertions(xml: string): string {\n let result = xml;\n\n // Parse existing relationships\n const relationships = this.parseRelationships();\n const existingIds = new Set(relationships.keys());\n\n // Process each w:ins element and remap images one by one\n const insRegex = /<w:ins\\b[^>]*>[\\s\\S]*?<\\/w:ins>/g;\n\n result = result.replace(insRegex, (insMatch) => {\n // For each image reference inside this insertion, generate a unique new ID\n return insMatch.replace(/r:embed=\"(rId\\d+)\"/g, (_embedMatch, oldId) => {\n // Generate new unique ID for THIS occurrence\n const newId = this.getNextRelationshipId(existingIds);\n existingIds.add(newId);\n\n // Add relationship with same target as original\n const target = relationships.get(oldId);\n if (target) {\n this.addRelationship(\n newId,\n target,\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'\n );\n }\n\n return `r:embed=\"${newId}\"`;\n });\n });\n\n // Now unwrap the w:ins tags (content has unique remapped IDs)\n result = result.replace(/<\\/w:ins>/g, '');\n result = result.replace(/<w:ins\\b[^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Final cleanup to remove any orphaned or malformed revision-related tags\n */\n private cleanupOrphanedTags(xml: string): string {\n let result = xml;\n\n // Remove any remaining self-closing revision tags\n result = result.replace(/<w:ins\\b[^>]*\\/>/g, '');\n result = result.replace(/<w:del\\b[^>]*\\/>/g, '');\n result = result.replace(/<w:moveFrom\\b[^>]*\\/>/g, '');\n result = result.replace(/<w:moveTo\\b[^>]*\\/>/g, '');\n\n // Remove empty w:r elements that might be left after removing deletions\n result = result.replace(/<w:r\\b[^>]*>\\s*<\\/w:r>/g, '');\n\n // Remove empty w:p elements (but preserve those with properties)\n // We keep <w:p><w:pPr>...</w:pPr></w:p> as those are intentional empty paragraphs with styling\n result = result.replace(/<w:p>\\s*<\\/w:p>/g, '');\n\n return result;\n }\n\n /**\n * Parse relationship IDs from word/_rels/document.xml.rels\n * Returns a map of relationship ID to target path\n */\n private parseRelationships(): Map<string, string> {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return new Map();\n\n const map = new Map<string, string>();\n const relationshipRegex = /<Relationship[^>]*Id=\"([^\"]+)\"[^>]*Target=\"([^\"]+)\"[^>]*\\/>/g;\n let match;\n\n while ((match = relationshipRegex.exec(relsXml)) !== null) {\n if (match[1] && match[2]) {\n map.set(match[1], match[2]); // rId -> target path\n }\n }\n\n return map;\n }\n\n /**\n * Get the next available relationship ID\n * Finds the highest numeric ID and increments it\n */\n private getNextRelationshipId(existingIds: Set<string>): string {\n let maxId = 0;\n for (const id of existingIds) {\n const num = parseInt(id.replace('rId', ''));\n if (!isNaN(num) && num > maxId) {\n maxId = num;\n }\n }\n return `rId${maxId + 1}`;\n }\n\n /**\n * Add a new relationship to word/_rels/document.xml.rels\n */\n private addRelationship(rId: string, target: string, type: string): void {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return;\n\n // Insert new relationship before closing tag\n const newRel = `<Relationship Id=\"${rId}\" Type=\"${type}\" Target=\"${target}\"/>`;\n const updated = relsXml.replace('</Relationships>', `${newRel}\\n</Relationships>`);\n\n this.zipHandler.updateFile('word/_rels/document.xml.rels', updated);\n }\n\n /**\n * Clean up all revision metadata files (people.xml, settings.xml, core.xml).\n *\n * This removes:\n * - All revision authors from people.xml\n * - Track changes settings from settings.xml\n * - Resets revision count in core.xml\n *\n * Called as part of acceptAllRevisions() but can also be called separately\n * when using in-memory revision acceptance.\n */\n public cleanupMetadata(): void {\n this.cleanupPeopleXml();\n this.cleanupSettingsXml();\n this.cleanupCorePropsXml();\n }\n\n /**\n * Clean up word/people.xml - remove all revision authors\n *\n * Handles both w: and w15: namespace variants\n */\n private cleanupPeopleXml(): void {\n const peopleXml = this.zipHandler.getFileAsString('word/people.xml');\n if (!peopleXml) {\n return;\n }\n\n let content = peopleXml;\n\n // Remove all person elements in any namespace variant\n content = content.replace(/<w:person\\b[^>]*>[\\s\\S]*?<\\/w:person>/g, '');\n content = content.replace(/<w15:person\\b[^>]*>[\\s\\S]*?<\\/w15:person>/g, '');\n\n // Handle any namespace-prefixed variants (w1:, w2:, etc.)\n content = content.replace(/<w\\d+:person\\b[^>]*>[\\s\\S]*?<\\/w\\d+:person>/g, '');\n\n // Also remove self-closing person elements\n content = content.replace(/<w:person\\b[^>]*\\/>/g, '');\n content = content.replace(/<w15:person\\b[^>]*\\/>/g, '');\n content = content.replace(/<w\\d+:person\\b[^>]*\\/>/g, '');\n\n this.zipHandler.updateFile('word/people.xml', content);\n }\n\n /**\n * Clean up word/settings.xml - disable track changes\n */\n private cleanupSettingsXml(): void {\n const settingsXml = this.zipHandler.getFileAsString('word/settings.xml');\n if (!settingsXml) {\n return;\n }\n\n let content = settingsXml;\n\n // Remove trackRevisions element (enables tracking)\n content = content.replace(/<w:trackRevisions\\b[^>]*\\/>/g, '');\n content = content.replace(/<w:trackRevisions\\b[^>]*>[\\s\\S]*?<\\/w:trackRevisions>/g, '');\n\n // Remove revisionView element (controls which revisions are visible)\n content = content.replace(/<w:revisionView\\b[^>]*\\/>/g, '');\n content = content.replace(/<w:revisionView\\b[^>]*>[\\s\\S]*?<\\/w:revisionView>/g, '');\n\n // Remove doNotTrackMoves (prevents move tracking)\n content = content.replace(/<w:doNotTrackMoves\\b[^>]*\\/>/g, '');\n content = content.replace(/<w:doNotTrackMoves\\b[^>]*>[\\s\\S]*?<\\/w:doNotTrackMoves>/g, '');\n\n // Remove doNotTrackFormatting\n content = content.replace(/<w:doNotTrackFormatting\\b[^>]*\\/>/g, '');\n content = content.replace(\n /<w:doNotTrackFormatting\\b[^>]*>[\\s\\S]*?<\\/w:doNotTrackFormatting>/g,\n ''\n );\n\n this.zipHandler.updateFile('word/settings.xml', content);\n }\n\n /**\n * Clean up docProps/core.xml - reset revision count\n */\n private cleanupCorePropsXml(): void {\n const coreXml = this.zipHandler.getFileAsString('docProps/core.xml');\n if (!coreXml) {\n return;\n }\n\n // Reset revision count to 1\n const content = coreXml.replace(\n /<cp:revision>\\d+<\\/cp:revision>/g,\n '<cp:revision>1</cp:revision>'\n );\n\n this.zipHandler.updateFile('docProps/core.xml', content);\n }\n\n // =========================================================================\n // DOM-based processing helper methods\n // =========================================================================\n\n /**\n * Convert parsed XML object back to XML string\n * Preserves element order using _orderedChildren metadata\n *\n * Based on DocumentParser.objectToXml() implementation\n */\n private objectToXml(obj: any): string {\n const buildXml = (o: any, name?: string): string => {\n // Handle simple string/number with a tag name: <tagName>value</tagName>\n if (name && (typeof o === 'string' || typeof o === 'number')) {\n return `<${name}>${this.escapeXml(String(o))}</${name}>`;\n }\n if (typeof o === 'string') return this.escapeXml(o);\n if (typeof o !== 'object' || o === null) return String(o ?? '');\n\n const keys = Object.keys(o);\n\n // If a name is provided, we're building a specific element\n // Don't return empty string for empty objects with a name - they become self-closing tags\n if (keys.length === 0 && !name) return '';\n\n const tagName = name || keys[0]!;\n const element = name ? o : o[tagName];\n\n let xml = `<${tagName}`;\n\n // Add attributes (keys starting with @_)\n if (element && typeof element === 'object') {\n for (const key of Object.keys(element)) {\n if (key.startsWith('@_')) {\n const attrName = key.substring(2);\n xml += ` ${attrName}=\"${this.escapeXml(String(element[key]))}\"`;\n }\n }\n }\n\n // Check for children (non-attribute, non-text, non-metadata keys)\n const hasChildren =\n element &&\n typeof element === 'object' &&\n Object.keys(element).some(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n // Per ECMA-376, certain elements MUST NOT be self-closing (e.g., <w:p/> is invalid).\n // This mirrors the CANNOT_SELF_CLOSE list in XMLBuilder.ts.\n const CANNOT_SELF_CLOSE = [\n 'w:t',\n 'w:r',\n 'w:p',\n 'w:tbl',\n 'w:tr',\n 'w:tc',\n 'w:body',\n 'w:document',\n 'w:hyperlink',\n 'w:sdt',\n 'w:sdtContent',\n 'w:sdtPr',\n 'w:pPr',\n 'w:rPr',\n 'w:sectPr',\n 'w:del',\n 'w:ins',\n 'w:moveFrom',\n 'w:moveTo',\n ];\n\n if (!hasChildren && !element?.['#text']) {\n if (CANNOT_SELF_CLOSE.includes(tagName)) {\n xml += `></${tagName}>`;\n } else {\n xml += '/>';\n }\n } else {\n xml += '>';\n\n // Add text content\n if (element?.['#text']) {\n xml += this.escapeXml(String(element['#text']));\n }\n\n // Add child elements using _orderedChildren if available\n if (element && typeof element === 'object') {\n const orderedChildren = element._orderedChildren as\n | { type: string; index: number }[]\n | undefined;\n\n if (orderedChildren && orderedChildren.length > 0) {\n // Use _orderedChildren to preserve element order\n for (const childInfo of orderedChildren) {\n const childType = childInfo.type;\n const childIndex = childInfo.index;\n\n if (element[childType] !== undefined) {\n const children = element[childType];\n\n if (Array.isArray(children)) {\n if (childIndex < children.length) {\n const childXml = buildXml(children[childIndex], childType);\n xml += childXml;\n }\n } else {\n // Single child element\n if (childIndex === 0) {\n const childXml = buildXml(children, childType);\n xml += childXml;\n }\n }\n }\n }\n } else {\n // Fallback: iterate through keys if no _orderedChildren\n for (const key of Object.keys(element)) {\n if (!key.startsWith('@_') && key !== '#text' && key !== '_orderedChildren') {\n const children = element[key];\n if (Array.isArray(children)) {\n for (const child of children) {\n xml += buildXml(child, key);\n }\n } else {\n xml += buildXml(children, key);\n }\n }\n }\n }\n }\n\n xml += `</${tagName}>`;\n }\n\n return xml;\n };\n\n return buildXml(obj);\n }\n\n /**\n * Escape special XML characters\n */\n private escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n }\n\n /**\n * Remap image relationship IDs in the parsed tree to prevent duplicates\n * Walks the tree looking for r:embed attributes and assigns unique IDs\n */\n private remapImageRelationshipsInTree(obj: any): void {\n const relationships = this.parseRelationships();\n const existingIds = new Set(relationships.keys());\n const remappedIds = new Map<string, string>();\n\n // Walk the tree and find all r:embed attributes\n this.walkTreeForEmbeds(obj, (embedId: string, parent: any, key: string) => {\n // Check if this ID has already been remapped\n if (remappedIds.has(embedId)) {\n parent[key] = remappedIds.get(embedId);\n return;\n }\n\n // Check if this ID needs remapping (duplicate)\n // For DOM-based processing, we check if we've seen this ID before in this pass\n const target = relationships.get(embedId);\n if (target) {\n // Generate new unique ID\n const newId = this.getNextRelationshipId(existingIds);\n existingIds.add(newId);\n remappedIds.set(embedId, newId);\n\n // Add relationship with same target\n this.addRelationship(\n newId,\n target,\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'\n );\n\n // Update the attribute\n parent[key] = newId;\n }\n });\n }\n\n /**\n * Walk the tree looking for r:embed attributes\n */\n private walkTreeForEmbeds(\n obj: any,\n callback: (embedId: string, parent: any, key: string) => void\n ): void {\n if (!obj || typeof obj !== 'object') {\n return;\n }\n\n for (const key of Object.keys(obj)) {\n // Check for r:embed attribute\n if (key === '@_r:embed') {\n callback(obj[key], obj, key);\n } else if (!key.startsWith('@_') && key !== '#text' && key !== '_orderedChildren') {\n const value = obj[key];\n if (Array.isArray(value)) {\n for (const item of value) {\n this.walkTreeForEmbeds(item, callback);\n }\n } else if (typeof value === 'object') {\n this.walkTreeForEmbeds(value, callback);\n }\n }\n }\n }\n}\n\n/**\n * Convenience function to accept all revisions in a document\n */\nexport async function acceptAllRevisions(zipHandler: ZipHandler): Promise<void> {\n const acceptor = new RevisionProcessor(zipHandler);\n await acceptor.process();\n}\n\n/**\n * Convenience function to reject all revisions in a document, reverting it to\n * its original pre-edit state (the exact inverse of {@link acceptAllRevisions}):\n *\n * 1. Insertions (`w:ins`): removed — inserted content is discarded\n * 2. Deletions (`w:del`): unwrapped and `w:delText` restored to `w:t` — deleted\n * content reappears\n * 3. MoveFrom (`w:moveFrom`): unwrapped — the original source content is restored\n * 4. MoveTo (`w:moveTo`): removed — the moved-to destination is discarded\n * 5. Property changes (`w:rPrChange`, `w:pPrChange`, ...): previous formatting\n * stored inside the change is restored, then the marker is removed\n * 6. Inserted rows/tables are removed; deleted rows/tables are kept\n * 7. Range markers are removed and revision metadata is cleaned up\n *\n * Limitations (shared with {@link acceptAllRevisions}): cell-level markers\n * (`w:cellIns`/`w:cellDel`/`w:cellMerge`) are left in place, and the legacy\n * `w:numberingChange` is dropped rather than reverted (it embeds no recoverable\n * previous value).\n *\n * @param zipHandler - The ZipHandler containing the DOCX package\n */\nexport async function rejectAllRevisions(zipHandler: ZipHandler): Promise<void> {\n const rejector = new RevisionProcessor(zipHandler, 'reject');\n await rejector.process();\n}\n\n/**\n * Convenience function to clean up revision metadata files.\n *\n * This removes:\n * - All revision authors from people.xml\n * - Track changes settings from settings.xml\n * - Resets revision count in core.xml\n *\n * Use this after in-memory revision acceptance to ensure metadata is also cleaned.\n * The raw XML acceptAllRevisions() function calls this automatically.\n *\n * @param zipHandler - The ZipHandler containing the DOCX package\n */\nexport function cleanupRevisionMetadata(zipHandler: ZipHandler): void {\n const processor = new RevisionProcessor(zipHandler);\n processor.cleanupMetadata();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cnfStyleDecoder.d.ts","sourceRoot":"","sources":["../../src/processors/cnfStyleDecoder.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAMnE,MAAM,WAAW,aAAa;IAE5B,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,OAAO,CAAC;IAEjB,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,OAAO,CAAC;IAEjB,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,OAAO,CAAC;IAEnB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,EAAE,OAAO,CAAC;CACjB;AAKD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,aAAa,EAAE,yBAAyB,CAazF,CAAC;AA0BF,eAAO,MAAM,0BAA0B,EAAE,CAAC,MAAM,aAAa,CAAC,EAgB7D,CAAC;AAeF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAmB9D;AAcD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,CAUpE;AAcD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,yBAAyB,EAAE,CAWnF;AAgBD,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,MAAM,GACf,yBAAyB,EAAE,CAW7B"}
1
+ {"version":3,"file":"cnfStyleDecoder.d.ts","sourceRoot":"","sources":["../../src/processors/cnfStyleDecoder.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAMnE,MAAM,WAAW,aAAa;IAE5B,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,OAAO,CAAC;IAEjB,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,OAAO,CAAC;IAEjB,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,OAAO,CAAC;IAEnB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,EAAE,OAAO,CAAC;CACjB;AAKD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,aAAa,EAAE,yBAAyB,CAazF,CAAC;AAgCF,eAAO,MAAM,0BAA0B,EAAE,CAAC,MAAM,aAAa,CAAC,EAgB7D,CAAC;AAeF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAmB9D;AAcD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,CAUpE;AAcD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,yBAAyB,EAAE,CAWnF;AAgBD,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,MAAM,GACf,yBAAyB,EAAE,CAW7B"}
@@ -34,18 +34,18 @@ const BIT_POSITIONS = {
34
34
  swCell: 11,
35
35
  };
36
36
  exports.CONDITIONAL_PRIORITY_ORDER = [
37
- 'nwCell',
38
- 'neCell',
39
- 'swCell',
40
37
  'seCell',
41
- 'firstRow',
38
+ 'swCell',
39
+ 'neCell',
40
+ 'nwCell',
42
41
  'lastRow',
43
- 'firstCol',
42
+ 'firstRow',
44
43
  'lastCol',
45
- 'band1Horz',
44
+ 'firstCol',
46
45
  'band2Horz',
47
- 'band1Vert',
46
+ 'band1Horz',
48
47
  'band2Vert',
48
+ 'band1Vert',
49
49
  ];
50
50
  function decodeCnfStyle(cnfStyle) {
51
51
  const normalized = cnfStyle.padEnd(12, '0');
@@ -1 +1 @@
1
- {"version":3,"file":"cnfStyleDecoder.js","sourceRoot":"","sources":["../../src/processors/cnfStyleDecoder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * cnfStyle Decoder - Decodes the conditional formatting style bitmask\n * Per ECMA-376 Part 1 Section 17.4.7 (w:cnfStyle)\n *\n * The cnfStyle is a 12-character string where each character is '0' or '1'\n * representing whether a particular conditional format applies.\n */\n\nimport { ConditionalFormattingType } from '../formatting/Style.js';\n\n/**\n * Decoded cnfStyle flags\n * Each flag corresponds to a conditional formatting type that may apply to a cell\n */\nexport interface CnfStyleFlags {\n /** First row of table (header row) */\n firstRow: boolean;\n /** Last row of table */\n lastRow: boolean;\n /** First column of table */\n firstCol: boolean;\n /** Last column of table */\n lastCol: boolean;\n /** Odd vertical band (column banding) */\n band1Vert: boolean;\n /** Even vertical band (column banding) */\n band2Vert: boolean;\n /** Odd horizontal band (row banding) */\n band1Horz: boolean;\n /** Even horizontal band (row banding) */\n band2Horz: boolean;\n /** Northeast cell (top-right corner) */\n neCell: boolean;\n /** Northwest cell (top-left corner) */\n nwCell: boolean;\n /** Southeast cell (bottom-right corner) */\n seCell: boolean;\n /** Southwest cell (bottom-left corner) */\n swCell: boolean;\n}\n\n/**\n * Maps flag names to ConditionalFormattingType values\n */\nexport const CNF_TO_CONDITIONAL_MAP: Record<keyof CnfStyleFlags, ConditionalFormattingType> = {\n firstRow: 'firstRow',\n lastRow: 'lastRow',\n firstCol: 'firstCol',\n lastCol: 'lastCol',\n band1Vert: 'band1Vert',\n band2Vert: 'band2Vert',\n band1Horz: 'band1Horz',\n band2Horz: 'band2Horz',\n neCell: 'neCell',\n nwCell: 'nwCell',\n seCell: 'seCell',\n swCell: 'swCell',\n};\n\n/**\n * Bit positions in the cnfStyle string (0-indexed from left)\n * Per ECMA-376 Part 1 Section 17.4.7\n */\nconst BIT_POSITIONS: Record<keyof CnfStyleFlags, number> = {\n firstRow: 0,\n lastRow: 1,\n firstCol: 2,\n lastCol: 3,\n band1Vert: 4,\n band2Vert: 5,\n band1Horz: 6,\n band2Horz: 7,\n neCell: 8,\n nwCell: 9,\n seCell: 10,\n swCell: 11,\n};\n\n/**\n * Priority order for conditional formatting resolution\n * More specific conditions (corners) override less specific (edges, banding)\n * Per ECMA-376, this is the order in which conditionals should be applied\n */\nexport const CONDITIONAL_PRIORITY_ORDER: (keyof CnfStyleFlags)[] = [\n // Corner cells (most specific)\n 'nwCell',\n 'neCell',\n 'swCell',\n 'seCell',\n // Edge rows/columns\n 'firstRow',\n 'lastRow',\n 'firstCol',\n 'lastCol',\n // Banding (least specific)\n 'band1Horz',\n 'band2Horz',\n 'band1Vert',\n 'band2Vert',\n];\n\n/**\n * Decodes a cnfStyle string into individual flags\n *\n * @param cnfStyle - 12-character binary string (e.g., \"100000000000\" for firstRow)\n * @returns Decoded flags object\n *\n * @example\n * ```typescript\n * const flags = decodeCnfStyle('100000000000');\n * console.log(flags.firstRow); // true\n * console.log(flags.lastRow); // false\n * ```\n */\nexport function decodeCnfStyle(cnfStyle: string): CnfStyleFlags {\n // Pad to 12 characters if shorter (handles legacy or truncated values)\n // Use padEnd because the string represents left-to-right bit positions\n const normalized = cnfStyle.padEnd(12, '0');\n\n return {\n firstRow: normalized.startsWith('1'),\n lastRow: normalized[BIT_POSITIONS.lastRow] === '1',\n firstCol: normalized[BIT_POSITIONS.firstCol] === '1',\n lastCol: normalized[BIT_POSITIONS.lastCol] === '1',\n band1Vert: normalized[BIT_POSITIONS.band1Vert] === '1',\n band2Vert: normalized[BIT_POSITIONS.band2Vert] === '1',\n band1Horz: normalized[BIT_POSITIONS.band1Horz] === '1',\n band2Horz: normalized[BIT_POSITIONS.band2Horz] === '1',\n neCell: normalized[BIT_POSITIONS.neCell] === '1',\n nwCell: normalized[BIT_POSITIONS.nwCell] === '1',\n seCell: normalized[BIT_POSITIONS.seCell] === '1',\n swCell: normalized[BIT_POSITIONS.swCell] === '1',\n };\n}\n\n/**\n * Encodes CnfStyleFlags back to a binary string\n *\n * @param flags - Flags to encode\n * @returns 12-character binary string\n *\n * @example\n * ```typescript\n * const cnfStyle = encodeCnfStyle({ firstRow: true, lastCol: true });\n * console.log(cnfStyle); // '100100000000'\n * ```\n */\nexport function encodeCnfStyle(flags: Partial<CnfStyleFlags>): string {\n const bits = new Array(12).fill('0');\n\n for (const [key, position] of Object.entries(BIT_POSITIONS)) {\n if (flags[key as keyof CnfStyleFlags]) {\n bits[position] = '1';\n }\n }\n\n return bits.join('');\n}\n\n/**\n * Gets the active conditional formatting types from a cnfStyle\n *\n * @param cnfStyle - The cnfStyle string to decode\n * @returns Array of active ConditionalFormattingType values\n *\n * @example\n * ```typescript\n * const types = getActiveConditionals('110000000000');\n * console.log(types); // ['firstRow', 'lastRow']\n * ```\n */\nexport function getActiveConditionals(cnfStyle: string): ConditionalFormattingType[] {\n const flags = decodeCnfStyle(cnfStyle);\n const active: ConditionalFormattingType[] = [];\n\n for (const [key, isActive] of Object.entries(flags)) {\n if (isActive) {\n active.push(CNF_TO_CONDITIONAL_MAP[key as keyof CnfStyleFlags]);\n }\n }\n\n return active;\n}\n\n/**\n * Gets the active conditional formatting types in priority order\n * More specific conditions come first (corners before edges before banding)\n *\n * @param cnfStyle - The cnfStyle string to decode\n * @returns Array of active ConditionalFormattingType values in priority order\n *\n * @example\n * ```typescript\n * // Cell is both in first row and is the nwCell (top-left corner)\n * const types = getActiveConditionalsInPriorityOrder('100000000100');\n * console.log(types); // ['nwCell', 'firstRow'] - corner takes priority\n * ```\n */\nexport function getActiveConditionalsInPriorityOrder(\n cnfStyle: string\n): ConditionalFormattingType[] {\n const flags = decodeCnfStyle(cnfStyle);\n const active: ConditionalFormattingType[] = [];\n\n for (const flagName of CONDITIONAL_PRIORITY_ORDER) {\n if (flags[flagName]) {\n active.push(CNF_TO_CONDITIONAL_MAP[flagName]);\n }\n }\n\n return active;\n}\n"]}
1
+ {"version":3,"file":"cnfStyleDecoder.js","sourceRoot":"","sources":["../../src/processors/cnfStyleDecoder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * cnfStyle Decoder - Decodes the conditional formatting style bitmask\n * Per ECMA-376 Part 1 Section 17.4.7 (w:cnfStyle)\n *\n * The cnfStyle is a 12-character string where each character is '0' or '1'\n * representing whether a particular conditional format applies.\n */\n\nimport { ConditionalFormattingType } from '../formatting/Style.js';\n\n/**\n * Decoded cnfStyle flags\n * Each flag corresponds to a conditional formatting type that may apply to a cell\n */\nexport interface CnfStyleFlags {\n /** First row of table (header row) */\n firstRow: boolean;\n /** Last row of table */\n lastRow: boolean;\n /** First column of table */\n firstCol: boolean;\n /** Last column of table */\n lastCol: boolean;\n /** Odd vertical band (column banding) */\n band1Vert: boolean;\n /** Even vertical band (column banding) */\n band2Vert: boolean;\n /** Odd horizontal band (row banding) */\n band1Horz: boolean;\n /** Even horizontal band (row banding) */\n band2Horz: boolean;\n /** Northeast cell (top-right corner) */\n neCell: boolean;\n /** Northwest cell (top-left corner) */\n nwCell: boolean;\n /** Southeast cell (bottom-right corner) */\n seCell: boolean;\n /** Southwest cell (bottom-left corner) */\n swCell: boolean;\n}\n\n/**\n * Maps flag names to ConditionalFormattingType values\n */\nexport const CNF_TO_CONDITIONAL_MAP: Record<keyof CnfStyleFlags, ConditionalFormattingType> = {\n firstRow: 'firstRow',\n lastRow: 'lastRow',\n firstCol: 'firstCol',\n lastCol: 'lastCol',\n band1Vert: 'band1Vert',\n band2Vert: 'band2Vert',\n band1Horz: 'band1Horz',\n band2Horz: 'band2Horz',\n neCell: 'neCell',\n nwCell: 'nwCell',\n seCell: 'seCell',\n swCell: 'swCell',\n};\n\n/**\n * Bit positions in the cnfStyle string (0-indexed from left)\n * Per ECMA-376 Part 1 Section 17.4.7\n */\nconst BIT_POSITIONS: Record<keyof CnfStyleFlags, number> = {\n firstRow: 0,\n lastRow: 1,\n firstCol: 2,\n lastCol: 3,\n band1Vert: 4,\n band2Vert: 5,\n band1Horz: 6,\n band2Horz: 7,\n neCell: 8,\n nwCell: 9,\n seCell: 10,\n swCell: 11,\n};\n\n/**\n * Priority order for conditional formatting resolution\n *\n * ECMA-376 §17.7.6.6 applies conditional formats in sequence (banding, then\n * first/last row, first/last column, then corners top-left through\n * bottom-right) with subsequent formats overriding earlier ones. First-match\n * consumers need the opposite: the last-applied (winning) member of each\n * group listed first, so when two conditionals in the same group co-apply\n * (e.g. firstRow + lastRow in a single-row table) resolution picks the one\n * Word actually renders.\n */\nexport const CONDITIONAL_PRIORITY_ORDER: (keyof CnfStyleFlags)[] = [\n // Corner cells (most specific; spec applies nw, ne, sw, se — se wins)\n 'seCell',\n 'swCell',\n 'neCell',\n 'nwCell',\n // Edge rows/columns (within each pair, last is applied after first)\n 'lastRow',\n 'firstRow',\n 'lastCol',\n 'firstCol',\n // Banding (least specific; even banding is applied after odd)\n 'band2Horz',\n 'band1Horz',\n 'band2Vert',\n 'band1Vert',\n];\n\n/**\n * Decodes a cnfStyle string into individual flags\n *\n * @param cnfStyle - 12-character binary string (e.g., \"100000000000\" for firstRow)\n * @returns Decoded flags object\n *\n * @example\n * ```typescript\n * const flags = decodeCnfStyle('100000000000');\n * console.log(flags.firstRow); // true\n * console.log(flags.lastRow); // false\n * ```\n */\nexport function decodeCnfStyle(cnfStyle: string): CnfStyleFlags {\n // Pad to 12 characters if shorter (handles legacy or truncated values)\n // Use padEnd because the string represents left-to-right bit positions\n const normalized = cnfStyle.padEnd(12, '0');\n\n return {\n firstRow: normalized.startsWith('1'),\n lastRow: normalized[BIT_POSITIONS.lastRow] === '1',\n firstCol: normalized[BIT_POSITIONS.firstCol] === '1',\n lastCol: normalized[BIT_POSITIONS.lastCol] === '1',\n band1Vert: normalized[BIT_POSITIONS.band1Vert] === '1',\n band2Vert: normalized[BIT_POSITIONS.band2Vert] === '1',\n band1Horz: normalized[BIT_POSITIONS.band1Horz] === '1',\n band2Horz: normalized[BIT_POSITIONS.band2Horz] === '1',\n neCell: normalized[BIT_POSITIONS.neCell] === '1',\n nwCell: normalized[BIT_POSITIONS.nwCell] === '1',\n seCell: normalized[BIT_POSITIONS.seCell] === '1',\n swCell: normalized[BIT_POSITIONS.swCell] === '1',\n };\n}\n\n/**\n * Encodes CnfStyleFlags back to a binary string\n *\n * @param flags - Flags to encode\n * @returns 12-character binary string\n *\n * @example\n * ```typescript\n * const cnfStyle = encodeCnfStyle({ firstRow: true, lastCol: true });\n * console.log(cnfStyle); // '100100000000'\n * ```\n */\nexport function encodeCnfStyle(flags: Partial<CnfStyleFlags>): string {\n const bits = new Array(12).fill('0');\n\n for (const [key, position] of Object.entries(BIT_POSITIONS)) {\n if (flags[key as keyof CnfStyleFlags]) {\n bits[position] = '1';\n }\n }\n\n return bits.join('');\n}\n\n/**\n * Gets the active conditional formatting types from a cnfStyle\n *\n * @param cnfStyle - The cnfStyle string to decode\n * @returns Array of active ConditionalFormattingType values\n *\n * @example\n * ```typescript\n * const types = getActiveConditionals('110000000000');\n * console.log(types); // ['firstRow', 'lastRow']\n * ```\n */\nexport function getActiveConditionals(cnfStyle: string): ConditionalFormattingType[] {\n const flags = decodeCnfStyle(cnfStyle);\n const active: ConditionalFormattingType[] = [];\n\n for (const [key, isActive] of Object.entries(flags)) {\n if (isActive) {\n active.push(CNF_TO_CONDITIONAL_MAP[key as keyof CnfStyleFlags]);\n }\n }\n\n return active;\n}\n\n/**\n * Gets the active conditional formatting types in priority order\n * More specific conditions come first (corners before edges before banding)\n *\n * @param cnfStyle - The cnfStyle string to decode\n * @returns Array of active ConditionalFormattingType values in priority order\n *\n * @example\n * ```typescript\n * // Cell is both in first row and is the nwCell (top-left corner)\n * const types = getActiveConditionalsInPriorityOrder('100000000100');\n * console.log(types); // ['nwCell', 'firstRow'] - corner takes priority\n * ```\n */\nexport function getActiveConditionalsInPriorityOrder(\n cnfStyle: string\n): ConditionalFormattingType[] {\n const flags = decodeCnfStyle(cnfStyle);\n const active: ConditionalFormattingType[] = [];\n\n for (const flagName of CONDITIONAL_PRIORITY_ORDER) {\n if (flags[flagName]) {\n active.push(CNF_TO_CONDITIONAL_MAP[flagName]);\n }\n }\n\n return active;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stripTrackedChanges.d.ts","sourceRoot":"","sources":["../../src/processors/stripTrackedChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAyXlD,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E"}
1
+ {"version":3,"file":"stripTrackedChanges.d.ts","sourceRoot":"","sources":["../../src/processors/stripTrackedChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA8ZlD,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E"}
@@ -30,11 +30,12 @@ class TrackedChangesStripper {
30
30
  let content = xml;
31
31
  content = this.removeRangeMarkers(content);
32
32
  content = this.processInsertions(content);
33
+ content = this.removeDeletedRows(content);
34
+ content = this.removeSelfClosingRevisionTags(content);
33
35
  content = this.processDeletions(content);
34
36
  content = this.processMoveFrom(content);
35
37
  content = this.processMoveTo(content);
36
38
  content = this.removePropertyChanges(content);
37
- content = this.removeSelfClosingRevisionTags(content);
38
39
  this.zipHandler.updateFile(partPath, content);
39
40
  }
40
41
  removeRangeMarkers(xml) {
@@ -78,6 +79,16 @@ class TrackedChangesStripper {
78
79
  result = result.replace(/<w:ins[\s>][^>]*>/g, '');
79
80
  return result;
80
81
  }
82
+ removeDeletedRows(xml) {
83
+ const rowDelPattern = /<w:tr\b[^>]*>(?:(?!<w:tc\b|<w:tr\b|<\/w:tr>)[\s\S])*?<w:trPr\b(?:\s[^>]*)?>(?:(?!<\/w:trPr>)[\s\S])*?<w:del\b[^>]*\/>(?:(?!<\/w:trPr>)[\s\S])*?<\/w:trPr>(?:(?!<w:tr\b|<\/w:tr>)[\s\S])*?<\/w:tr>/g;
84
+ let result = xml;
85
+ let previousLength = 0;
86
+ while (result.length !== previousLength) {
87
+ previousLength = result.length;
88
+ result = result.replace(rowDelPattern, '');
89
+ }
90
+ return result;
91
+ }
81
92
  processDeletions(xml) {
82
93
  let result = xml;
83
94
  let previousLength = 0;
@@ -122,10 +133,10 @@ class TrackedChangesStripper {
122
133
  }
123
134
  removeSelfClosingRevisionTags(xml) {
124
135
  const patterns = [
125
- /<w:ins\s+[^>]*\/>/g,
126
- /<w:del\s+[^>]*\/>/g,
127
- /<w:moveFrom\s+[^>]*\/>/g,
128
- /<w:moveTo\s+[^>]*\/>/g,
136
+ /<w:ins\b[^>]*\/>/g,
137
+ /<w:del\b[^>]*\/>/g,
138
+ /<w:moveFrom\b[^>]*\/>/g,
139
+ /<w:moveTo\b[^>]*\/>/g,
129
140
  ];
130
141
  let result = xml;
131
142
  for (const pattern of patterns) {
@@ -1 +1 @@
1
- {"version":3,"file":"stripTrackedChanges.js","sourceRoot":"","sources":["../../src/processors/stripTrackedChanges.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZipHandler } from '../zip/ZipHandler.js';\n\n/**\n * Strips all tracked changes markup from a Word document\n * This includes insertions, deletions, move operations, and property changes\n * Also cleans up related metadata in people.xml, settings.xml, and core.xml\n */\nclass TrackedChangesStripper {\n private zipHandler: ZipHandler;\n\n constructor(zipHandler: ZipHandler) {\n this.zipHandler = zipHandler;\n }\n\n /**\n * Main method to strip all tracked changes from the document.\n *\n * Per ECMA-376 Part 1, tracked-change markup can appear in any\n * part that carries block-level content: the body (§17.2 w:body),\n * headers / footers (§17.10.3-4 CT_HdrFtr), footnotes (§17.11.15),\n * endnotes (§17.11.4), and comments (§17.13.4). All of these\n * must be walked — stripping document.xml alone would leave\n * tracked changes visible in Word for every header / footer /\n * note / comment revision.\n */\n public async stripTrackedChanges(): Promise<void> {\n // Always process the body.\n await this.stripPartRevisions('word/document.xml');\n\n // Process every header and footer part present in the ZIP.\n for (const file of this.zipHandler.getFilePaths()) {\n if (/^word\\/header\\d+\\.xml$/.exec(file) || /^word\\/footer\\d+\\.xml$/.exec(file)) {\n await this.stripPartRevisions(file);\n }\n }\n\n // Process singleton notes / comments parts when present.\n for (const path of ['word/footnotes.xml', 'word/endnotes.xml', 'word/comments.xml']) {\n if (this.zipHandler.getFileAsString(path)) {\n await this.stripPartRevisions(path);\n }\n }\n\n // Clean up metadata files\n await this.cleanupPeopleXml();\n await this.cleanupSettingsXml();\n await this.cleanupCorePropsXml();\n }\n\n /**\n * Strip ALL revision elements from a single document part.\n * The per-step pipeline is identical to the historical\n * document.xml implementation; the only difference is the\n * configurable source path.\n */\n private async stripPartRevisions(partPath: string): Promise<void> {\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml) {\n return;\n }\n\n let content = xml;\n\n // STEP 1: Remove all range markers (boundary markers for tracked changes)\n content = this.removeRangeMarkers(content);\n\n // STEP 2: Process insertions - keep content, remove wrapper\n content = this.processInsertions(content);\n\n // STEP 3: Process deletions - remove entirely\n content = this.processDeletions(content);\n\n // STEP 4: Process move operations\n content = this.processMoveFrom(content);\n content = this.processMoveTo(content);\n\n // STEP 5: Remove all property change tracking elements\n content = this.removePropertyChanges(content);\n\n // STEP 6: Remove any remaining self-closing revision tags\n content = this.removeSelfClosingRevisionTags(content);\n\n // Update the file in the zip\n this.zipHandler.updateFile(partPath, content);\n }\n\n /**\n * Remove all range marker elements\n */\n private removeRangeMarkers(xml: string): string {\n const patterns = [\n /<w:moveFromRangeStart[^>]*\\/>/g,\n /<w:moveFromRangeEnd[^>]*\\/>/g,\n /<w:moveToRangeStart[^>]*\\/>/g,\n /<w:moveToRangeEnd[^>]*\\/>/g,\n /<w:customXmlInsRangeStart[^>]*\\/>/g,\n /<w:customXmlInsRangeEnd[^>]*\\/>/g,\n /<w:customXmlDelRangeStart[^>]*\\/>/g,\n /<w:customXmlDelRangeEnd[^>]*\\/>/g,\n /<w:customXmlMoveFromRangeStart[^>]*\\/>/g,\n /<w:customXmlMoveFromRangeEnd[^>]*\\/>/g,\n /<w:customXmlMoveToRangeStart[^>]*\\/>/g,\n /<w:customXmlMoveToRangeEnd[^>]*\\/>/g,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:ins> elements - keep inner content, remove wrapper\n * Handles orphaned tags by removing opening and closing tags separately\n *\n * IMPORTANT: This method now handles relationship ID remapping for images inside insertions.\n * When Word tracks changes with images, it can reuse relationship IDs (like rId5) because\n * they're in separate tracked change contexts. But when we unwrap them, duplicate IDs\n * cause corruption. This method assigns new unique IDs to images inside insertions.\n */\n private processInsertions(xml: string): string {\n let result = xml;\n\n // Parse existing relationships\n const relationships = this.parseRelationships();\n const existingIds = new Set(relationships.keys());\n\n // Process each w:ins element and remap images one by one\n const insRegex = /<w:ins\\b[^>]*>[\\s\\S]*?<\\/w:ins>/g;\n\n result = result.replace(insRegex, (insMatch) => {\n // For each image reference inside this insertion, generate a unique new ID\n return insMatch.replace(/r:embed=\"(rId\\d+)\"/g, (_embedMatch, oldId) => {\n // Generate new unique ID for THIS occurrence\n const newId = this.getNextRelationshipId(existingIds);\n existingIds.add(newId);\n\n // Add relationship with same target as original\n const target = relationships.get(oldId);\n if (target) {\n this.addRelationship(\n newId,\n target,\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'\n );\n }\n\n return `r:embed=\"${newId}\"`;\n });\n });\n\n // First, remove all closing tags\n result = result.replace(/<\\/w:ins>/g, '');\n\n // Then, remove all opening tags (keeping any content that follows)\n result = result.replace(/<w:ins[\\s>][^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Process <w:del> elements - remove entire element\n * Uses iterative replacement to handle nested deletions\n */\n private processDeletions(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n // Keep replacing until no more changes (handles nested revisions)\n while (result.length !== previousLength) {\n previousLength = result.length;\n\n // Match entire deletion element and remove it\n // Use [\\s>] to match either space or closing bracket\n result = result.replace(/<w:del[\\s>][^>]*>.*?<\\/w:del>/gs, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:moveFrom> elements - remove entire element (source of move)\n * Uses iterative replacement to handle nested moves\n */\n private processMoveFrom(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n // Keep replacing until no more changes\n while (result.length !== previousLength) {\n previousLength = result.length;\n\n // Use [\\s>] to match either space or closing bracket\n result = result.replace(/<w:moveFrom[\\s>][^>]*>.*?<\\/w:moveFrom>/gs, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:moveTo> elements - keep inner content (destination of move)\n * Handles orphaned tags by removing opening and closing tags separately\n */\n private processMoveTo(xml: string): string {\n let result = xml;\n\n // First, remove all closing tags\n result = result.replace(/<\\/w:moveTo>/g, '');\n\n // Then, remove all opening tags (keeping any content that follows)\n result = result.replace(/<w:moveTo[\\s>][^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Remove all property change tracking elements\n */\n private removePropertyChanges(xml: string): string {\n const patterns = [\n /<w:rPrChange[^>]*>.*?<\\/w:rPrChange>/gs, // Run property changes\n /<w:pPrChange[^>]*>.*?<\\/w:pPrChange>/gs, // Paragraph property changes\n /<w:tblPrChange[^>]*>.*?<\\/w:tblPrChange>/gs, // Table property changes\n /<w:tblPrExChange[^>]*>.*?<\\/w:tblPrExChange>/gs, // Table property exception changes\n /<w:tcPrChange[^>]*>.*?<\\/w:tcPrChange>/gs, // Table cell property changes\n /<w:trPrChange[^>]*>.*?<\\/w:trPrChange>/gs, // Table row property changes\n /<w:sectPrChange[^>]*>.*?<\\/w:sectPrChange>/gs, // Section property changes\n /<w:tblGridChange[^>]*>.*?<\\/w:tblGridChange>/gs, // Table grid changes\n /<w:numberingChange[^>]*>.*?<\\/w:numberingChange>/gs, // Numbering changes\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n\n return result;\n }\n\n /**\n * Remove self-closing revision tags\n */\n private removeSelfClosingRevisionTags(xml: string): string {\n const patterns = [\n /<w:ins\\s+[^>]*\\/>/g,\n /<w:del\\s+[^>]*\\/>/g,\n /<w:moveFrom\\s+[^>]*\\/>/g,\n /<w:moveTo\\s+[^>]*\\/>/g,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n\n return result;\n }\n\n /**\n * Parse relationship IDs from word/_rels/document.xml.rels\n * Returns a map of relationship ID to target path\n */\n private parseRelationships(): Map<string, string> {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return new Map();\n\n const map = new Map<string, string>();\n const relationshipRegex = /<Relationship[^>]*Id=\"([^\"]+)\"[^>]*Target=\"([^\"]+)\"[^>]*\\/>/g;\n let match;\n\n while ((match = relationshipRegex.exec(relsXml)) !== null) {\n if (match[1] && match[2]) {\n map.set(match[1], match[2]); // rId -> target path\n }\n }\n\n return map;\n }\n\n /**\n * Get the next available relationship ID\n * Finds the highest numeric ID and increments it\n */\n private getNextRelationshipId(existingIds: Set<string>): string {\n let maxId = 0;\n for (const id of existingIds) {\n const num = parseInt(id.replace('rId', ''));\n if (!isNaN(num) && num > maxId) {\n maxId = num;\n }\n }\n return `rId${maxId + 1}`;\n }\n\n /**\n * Add a new relationship to word/_rels/document.xml.rels\n */\n private addRelationship(rId: string, target: string, type: string): void {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return;\n\n // Insert new relationship before closing tag\n const newRel = `<Relationship Id=\"${rId}\" Type=\"${type}\" Target=\"${target}\"/>`;\n const updated = relsXml.replace('</Relationships>', `${newRel}\\n</Relationships>`);\n\n this.zipHandler.updateFile('word/_rels/document.xml.rels', updated);\n }\n\n /**\n * Clean up word/people.xml - remove revision authors\n */\n private async cleanupPeopleXml(): Promise<void> {\n const peopleXml = this.zipHandler.getFileAsString('word/people.xml');\n if (!peopleXml) {\n return;\n }\n\n let content = peopleXml;\n\n // Remove all <w:person> elements (standard namespace)\n content = content.replace(/<w:person[^>]*>.*?<\\/w:person>/gs, '');\n\n // Remove all <w15:person> elements (Word 2013+ namespace)\n content = content.replace(/<w15:person[^>]*>.*?<\\/w15:person>/gs, '');\n\n // Remove any other namespace variants of person elements\n content = content.replace(/<w\\d*:person[^>]*>.*?<\\/w\\d*:person>/gs, '');\n\n this.zipHandler.updateFile('word/people.xml', content);\n }\n\n /**\n * Clean up word/settings.xml - disable track changes\n */\n private async cleanupSettingsXml(): Promise<void> {\n const settingsXml = this.zipHandler.getFileAsString('word/settings.xml');\n if (!settingsXml) {\n return;\n }\n\n let content = settingsXml;\n\n // Remove track changes settings\n content = content.replace(/<w:trackRevisions[^>]*\\/>/g, '');\n content = content.replace(/<w:trackRevisions[^>]*>.*?<\\/w:trackRevisions>/gs, '');\n\n // Remove revision view settings\n content = content.replace(/<w:revisionView[^>]*\\/>/g, '');\n content = content.replace(/<w:revisionView[^>]*>.*?<\\/w:revisionView>/gs, '');\n\n this.zipHandler.updateFile('word/settings.xml', content);\n }\n\n /**\n * Clean up docProps/core.xml - reset revision count\n */\n private async cleanupCorePropsXml(): Promise<void> {\n const coreXml = this.zipHandler.getFileAsString('docProps/core.xml');\n if (!coreXml) {\n return;\n }\n\n // Reset revision count to 1\n const content = coreXml.replace(\n /<cp:revision>\\d+<\\/cp:revision>/g,\n '<cp:revision>1</cp:revision>'\n );\n\n this.zipHandler.updateFile('docProps/core.xml', content);\n }\n}\n\n/**\n * Convenience function to strip tracked changes from a ZipHandler\n */\nexport async function stripTrackedChanges(zipHandler: ZipHandler): Promise<void> {\n const stripper = new TrackedChangesStripper(zipHandler);\n await stripper.stripTrackedChanges();\n}\n"]}
1
+ {"version":3,"file":"stripTrackedChanges.js","sourceRoot":"","sources":["../../src/processors/stripTrackedChanges.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZipHandler } from '../zip/ZipHandler.js';\n\n/**\n * Strips all tracked changes markup from a Word document\n * This includes insertions, deletions, move operations, and property changes\n * Also cleans up related metadata in people.xml, settings.xml, and core.xml\n */\nclass TrackedChangesStripper {\n private zipHandler: ZipHandler;\n\n constructor(zipHandler: ZipHandler) {\n this.zipHandler = zipHandler;\n }\n\n /**\n * Main method to strip all tracked changes from the document.\n *\n * Per ECMA-376 Part 1, tracked-change markup can appear in any\n * part that carries block-level content: the body (§17.2 w:body),\n * headers / footers (§17.10.3-4 CT_HdrFtr), footnotes (§17.11.15),\n * endnotes (§17.11.4), and comments (§17.13.4). All of these\n * must be walked — stripping document.xml alone would leave\n * tracked changes visible in Word for every header / footer /\n * note / comment revision.\n */\n public async stripTrackedChanges(): Promise<void> {\n // Always process the body.\n await this.stripPartRevisions('word/document.xml');\n\n // Process every header and footer part present in the ZIP.\n for (const file of this.zipHandler.getFilePaths()) {\n if (/^word\\/header\\d+\\.xml$/.exec(file) || /^word\\/footer\\d+\\.xml$/.exec(file)) {\n await this.stripPartRevisions(file);\n }\n }\n\n // Process singleton notes / comments parts when present.\n for (const path of ['word/footnotes.xml', 'word/endnotes.xml', 'word/comments.xml']) {\n if (this.zipHandler.getFileAsString(path)) {\n await this.stripPartRevisions(path);\n }\n }\n\n // Clean up metadata files\n await this.cleanupPeopleXml();\n await this.cleanupSettingsXml();\n await this.cleanupCorePropsXml();\n }\n\n /**\n * Strip ALL revision elements from a single document part.\n * The per-step pipeline is identical to the historical\n * document.xml implementation; the only difference is the\n * configurable source path.\n */\n private async stripPartRevisions(partPath: string): Promise<void> {\n const xml = this.zipHandler.getFileAsString(partPath);\n if (!xml) {\n return;\n }\n\n let content = xml;\n\n // STEP 1: Remove all range markers (boundary markers for tracked changes)\n content = this.removeRangeMarkers(content);\n\n // STEP 2: Process insertions - keep content, remove wrapper\n content = this.processInsertions(content);\n\n // STEP 3: Remove rows whose w:trPr carries a row-deletion marker\n // (self-closing <w:del/> per ECMA-376 §17.13.5.14 marks the ENTIRE\n // row as deleted). Must run before the marker itself is stripped in\n // STEP 4, otherwise the row would silently survive as un-deleted.\n content = this.removeDeletedRows(content);\n\n // STEP 4: Remove self-closing revision markers (paragraph-mark\n // deletions in w:pPr/w:rPr per ECMA-376 §17.13.5.15, etc.). Must run\n // BEFORE the block-removal steps: their [^>]* also matches the\n // trailing '/' of `<w:del .../>`, which would turn the marker into an\n // opening tag and swallow everything up to the next closing tag,\n // corrupting the part.\n content = this.removeSelfClosingRevisionTags(content);\n\n // STEP 5: Process deletions - remove entirely\n content = this.processDeletions(content);\n\n // STEP 6: Process move operations\n content = this.processMoveFrom(content);\n content = this.processMoveTo(content);\n\n // STEP 7: Remove all property change tracking elements\n content = this.removePropertyChanges(content);\n\n // Update the file in the zip\n this.zipHandler.updateFile(partPath, content);\n }\n\n /**\n * Remove all range marker elements\n */\n private removeRangeMarkers(xml: string): string {\n const patterns = [\n /<w:moveFromRangeStart[^>]*\\/>/g,\n /<w:moveFromRangeEnd[^>]*\\/>/g,\n /<w:moveToRangeStart[^>]*\\/>/g,\n /<w:moveToRangeEnd[^>]*\\/>/g,\n /<w:customXmlInsRangeStart[^>]*\\/>/g,\n /<w:customXmlInsRangeEnd[^>]*\\/>/g,\n /<w:customXmlDelRangeStart[^>]*\\/>/g,\n /<w:customXmlDelRangeEnd[^>]*\\/>/g,\n /<w:customXmlMoveFromRangeStart[^>]*\\/>/g,\n /<w:customXmlMoveFromRangeEnd[^>]*\\/>/g,\n /<w:customXmlMoveToRangeStart[^>]*\\/>/g,\n /<w:customXmlMoveToRangeEnd[^>]*\\/>/g,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:ins> elements - keep inner content, remove wrapper\n * Handles orphaned tags by removing opening and closing tags separately\n *\n * IMPORTANT: This method now handles relationship ID remapping for images inside insertions.\n * When Word tracks changes with images, it can reuse relationship IDs (like rId5) because\n * they're in separate tracked change contexts. But when we unwrap them, duplicate IDs\n * cause corruption. This method assigns new unique IDs to images inside insertions.\n */\n private processInsertions(xml: string): string {\n let result = xml;\n\n // Parse existing relationships\n const relationships = this.parseRelationships();\n const existingIds = new Set(relationships.keys());\n\n // Process each w:ins element and remap images one by one\n const insRegex = /<w:ins\\b[^>]*>[\\s\\S]*?<\\/w:ins>/g;\n\n result = result.replace(insRegex, (insMatch) => {\n // For each image reference inside this insertion, generate a unique new ID\n return insMatch.replace(/r:embed=\"(rId\\d+)\"/g, (_embedMatch, oldId) => {\n // Generate new unique ID for THIS occurrence\n const newId = this.getNextRelationshipId(existingIds);\n existingIds.add(newId);\n\n // Add relationship with same target as original\n const target = relationships.get(oldId);\n if (target) {\n this.addRelationship(\n newId,\n target,\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'\n );\n }\n\n return `r:embed=\"${newId}\"`;\n });\n });\n\n // First, remove all closing tags\n result = result.replace(/<\\/w:ins>/g, '');\n\n // Then, remove all opening tags (keeping any content that follows)\n result = result.replace(/<w:ins[\\s>][^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Remove entire <w:tr> rows marked as tracked deletions.\n *\n * Per ECMA-376 Part 1 §17.13.5.14, a self-closing `<w:del/>` inside\n * `<w:trPr>` marks the whole row as deleted — stripping just the marker\n * would resurrect the row instead of removing it. Mirrors the row-level\n * pass in acceptRevisions.ts: the negative lookaheads keep the match\n * anchored to a single row (it cannot slip past a cell boundary or a\n * nested-table row and latch onto a later row's trPr-with-del).\n */\n private removeDeletedRows(xml: string): string {\n const rowDelPattern =\n /<w:tr\\b[^>]*>(?:(?!<w:tc\\b|<w:tr\\b|<\\/w:tr>)[\\s\\S])*?<w:trPr\\b(?:\\s[^>]*)?>(?:(?!<\\/w:trPr>)[\\s\\S])*?<w:del\\b[^>]*\\/>(?:(?!<\\/w:trPr>)[\\s\\S])*?<\\/w:trPr>(?:(?!<w:tr\\b|<\\/w:tr>)[\\s\\S])*?<\\/w:tr>/g;\n\n let result = xml;\n let previousLength = 0;\n while (result.length !== previousLength) {\n previousLength = result.length;\n result = result.replace(rowDelPattern, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:del> elements - remove entire element\n * Uses iterative replacement to handle nested deletions\n */\n private processDeletions(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n // Keep replacing until no more changes (handles nested revisions)\n while (result.length !== previousLength) {\n previousLength = result.length;\n\n // Match entire deletion element and remove it\n // Use [\\s>] to match either space or closing bracket\n result = result.replace(/<w:del[\\s>][^>]*>.*?<\\/w:del>/gs, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:moveFrom> elements - remove entire element (source of move)\n * Uses iterative replacement to handle nested moves\n */\n private processMoveFrom(xml: string): string {\n let result = xml;\n let previousLength = 0;\n\n // Keep replacing until no more changes\n while (result.length !== previousLength) {\n previousLength = result.length;\n\n // Use [\\s>] to match either space or closing bracket\n result = result.replace(/<w:moveFrom[\\s>][^>]*>.*?<\\/w:moveFrom>/gs, '');\n }\n\n return result;\n }\n\n /**\n * Process <w:moveTo> elements - keep inner content (destination of move)\n * Handles orphaned tags by removing opening and closing tags separately\n */\n private processMoveTo(xml: string): string {\n let result = xml;\n\n // First, remove all closing tags\n result = result.replace(/<\\/w:moveTo>/g, '');\n\n // Then, remove all opening tags (keeping any content that follows)\n result = result.replace(/<w:moveTo[\\s>][^>]*>/g, '');\n\n return result;\n }\n\n /**\n * Remove all property change tracking elements\n */\n private removePropertyChanges(xml: string): string {\n const patterns = [\n /<w:rPrChange[^>]*>.*?<\\/w:rPrChange>/gs, // Run property changes\n /<w:pPrChange[^>]*>.*?<\\/w:pPrChange>/gs, // Paragraph property changes\n /<w:tblPrChange[^>]*>.*?<\\/w:tblPrChange>/gs, // Table property changes\n /<w:tblPrExChange[^>]*>.*?<\\/w:tblPrExChange>/gs, // Table property exception changes\n /<w:tcPrChange[^>]*>.*?<\\/w:tcPrChange>/gs, // Table cell property changes\n /<w:trPrChange[^>]*>.*?<\\/w:trPrChange>/gs, // Table row property changes\n /<w:sectPrChange[^>]*>.*?<\\/w:sectPrChange>/gs, // Section property changes\n /<w:tblGridChange[^>]*>.*?<\\/w:tblGridChange>/gs, // Table grid changes\n /<w:numberingChange[^>]*>.*?<\\/w:numberingChange>/gs, // Numbering changes\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n\n return result;\n }\n\n /**\n * Remove self-closing revision tags\n * `\\b` (not `\\s+`) so attribute-less markers like `<w:del/>` are also\n * caught while `<w:delText>` is not.\n */\n private removeSelfClosingRevisionTags(xml: string): string {\n const patterns = [\n /<w:ins\\b[^>]*\\/>/g,\n /<w:del\\b[^>]*\\/>/g,\n /<w:moveFrom\\b[^>]*\\/>/g,\n /<w:moveTo\\b[^>]*\\/>/g,\n ];\n\n let result = xml;\n for (const pattern of patterns) {\n result = result.replace(pattern, '');\n }\n\n return result;\n }\n\n /**\n * Parse relationship IDs from word/_rels/document.xml.rels\n * Returns a map of relationship ID to target path\n */\n private parseRelationships(): Map<string, string> {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return new Map();\n\n const map = new Map<string, string>();\n const relationshipRegex = /<Relationship[^>]*Id=\"([^\"]+)\"[^>]*Target=\"([^\"]+)\"[^>]*\\/>/g;\n let match;\n\n while ((match = relationshipRegex.exec(relsXml)) !== null) {\n if (match[1] && match[2]) {\n map.set(match[1], match[2]); // rId -> target path\n }\n }\n\n return map;\n }\n\n /**\n * Get the next available relationship ID\n * Finds the highest numeric ID and increments it\n */\n private getNextRelationshipId(existingIds: Set<string>): string {\n let maxId = 0;\n for (const id of existingIds) {\n const num = parseInt(id.replace('rId', ''));\n if (!isNaN(num) && num > maxId) {\n maxId = num;\n }\n }\n return `rId${maxId + 1}`;\n }\n\n /**\n * Add a new relationship to word/_rels/document.xml.rels\n */\n private addRelationship(rId: string, target: string, type: string): void {\n const relsXml = this.zipHandler.getFileAsString('word/_rels/document.xml.rels');\n if (!relsXml) return;\n\n // Insert new relationship before closing tag\n const newRel = `<Relationship Id=\"${rId}\" Type=\"${type}\" Target=\"${target}\"/>`;\n const updated = relsXml.replace('</Relationships>', `${newRel}\\n</Relationships>`);\n\n this.zipHandler.updateFile('word/_rels/document.xml.rels', updated);\n }\n\n /**\n * Clean up word/people.xml - remove revision authors\n */\n private async cleanupPeopleXml(): Promise<void> {\n const peopleXml = this.zipHandler.getFileAsString('word/people.xml');\n if (!peopleXml) {\n return;\n }\n\n let content = peopleXml;\n\n // Remove all <w:person> elements (standard namespace)\n content = content.replace(/<w:person[^>]*>.*?<\\/w:person>/gs, '');\n\n // Remove all <w15:person> elements (Word 2013+ namespace)\n content = content.replace(/<w15:person[^>]*>.*?<\\/w15:person>/gs, '');\n\n // Remove any other namespace variants of person elements\n content = content.replace(/<w\\d*:person[^>]*>.*?<\\/w\\d*:person>/gs, '');\n\n this.zipHandler.updateFile('word/people.xml', content);\n }\n\n /**\n * Clean up word/settings.xml - disable track changes\n */\n private async cleanupSettingsXml(): Promise<void> {\n const settingsXml = this.zipHandler.getFileAsString('word/settings.xml');\n if (!settingsXml) {\n return;\n }\n\n let content = settingsXml;\n\n // Remove track changes settings\n content = content.replace(/<w:trackRevisions[^>]*\\/>/g, '');\n content = content.replace(/<w:trackRevisions[^>]*>.*?<\\/w:trackRevisions>/gs, '');\n\n // Remove revision view settings\n content = content.replace(/<w:revisionView[^>]*\\/>/g, '');\n content = content.replace(/<w:revisionView[^>]*>.*?<\\/w:revisionView>/gs, '');\n\n this.zipHandler.updateFile('word/settings.xml', content);\n }\n\n /**\n * Clean up docProps/core.xml - reset revision count\n */\n private async cleanupCorePropsXml(): Promise<void> {\n const coreXml = this.zipHandler.getFileAsString('docProps/core.xml');\n if (!coreXml) {\n return;\n }\n\n // Reset revision count to 1\n const content = coreXml.replace(\n /<cp:revision>\\d+<\\/cp:revision>/g,\n '<cp:revision>1</cp:revision>'\n );\n\n this.zipHandler.updateFile('docProps/core.xml', content);\n }\n}\n\n/**\n * Convenience function to strip tracked changes from a ZipHandler\n */\nexport async function stripTrackedChanges(zipHandler: ZipHandler): Promise<void> {\n const stripper = new TrackedChangesStripper(zipHandler);\n await stripper.stripTrackedChanges();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"deepClone.d.ts","sourceRoot":"","sources":["../../src/utils/deepClone.ts"],"names":[],"mappings":"AAwBA,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAoDtC"}
1
+ {"version":3,"file":"deepClone.d.ts","sourceRoot":"","sources":["../../src/utils/deepClone.ts"],"names":[],"mappings":"AA8BA,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAKtC"}
@@ -2,41 +2,54 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deepClone = deepClone;
4
4
  function deepClone(obj) {
5
+ return cloneInternal(obj, new WeakMap());
6
+ }
7
+ function cloneInternal(obj, seen) {
5
8
  if (obj === null || typeof obj !== 'object') {
6
9
  return obj;
7
10
  }
11
+ const existing = seen.get(obj);
12
+ if (existing !== undefined) {
13
+ return existing;
14
+ }
8
15
  if (obj instanceof Date) {
9
- return new Date(obj.getTime());
16
+ const dateCopy = new Date(obj.getTime());
17
+ seen.set(obj, dateCopy);
18
+ return dateCopy;
19
+ }
20
+ if (obj instanceof RegExp) {
21
+ const regexpCopy = new RegExp(obj.source, obj.flags);
22
+ seen.set(obj, regexpCopy);
23
+ return regexpCopy;
10
24
  }
11
25
  if (Array.isArray(obj)) {
12
26
  const arrCopy = [];
27
+ seen.set(obj, arrCopy);
13
28
  for (let i = 0; i < obj.length; i++) {
14
- arrCopy[i] = deepClone(obj[i]);
29
+ arrCopy[i] = cloneInternal(obj[i], seen);
15
30
  }
16
31
  return arrCopy;
17
32
  }
18
33
  if (obj instanceof Map) {
19
34
  const mapCopy = new Map();
35
+ seen.set(obj, mapCopy);
20
36
  obj.forEach((value, key) => {
21
- mapCopy.set(deepClone(key), deepClone(value));
37
+ mapCopy.set(cloneInternal(key, seen), cloneInternal(value, seen));
22
38
  });
23
39
  return mapCopy;
24
40
  }
25
41
  if (obj instanceof Set) {
26
42
  const setCopy = new Set();
43
+ seen.set(obj, setCopy);
27
44
  obj.forEach((value) => {
28
- setCopy.add(deepClone(value));
45
+ setCopy.add(cloneInternal(value, seen));
29
46
  });
30
47
  return setCopy;
31
48
  }
32
- if (obj instanceof RegExp) {
33
- return new RegExp(obj.source, obj.flags);
34
- }
35
49
  const objCopy = Object.create(Object.getPrototypeOf(obj));
36
- for (const key in obj) {
37
- if (obj.hasOwnProperty(key)) {
38
- objCopy[key] = deepClone(obj[key]);
39
- }
50
+ seen.set(obj, objCopy);
51
+ for (const key of Object.keys(obj)) {
52
+ objCopy[key] = cloneInternal(obj[key], seen);
40
53
  }
41
54
  return objCopy;
42
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deepClone.js","sourceRoot":"","sources":["../../src/utils/deepClone.ts"],"names":[],"mappings":";;AAwBA,8BAoDC;AApDD,SAAgB,SAAS,CAAI,GAAM;IAEjC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,GAAG,CAAC;IACb,CAAC;IAGD,IAAI,GAAG,YAAY,IAAI,EAAE,CAAC;QACxB,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAM,CAAC;IACtC,CAAC;IAGD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,OAAO,GAAc,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,OAAY,CAAC;IACtB,CAAC;IAGD,IAAI,GAAG,YAAY,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACzB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,OAAO,OAAY,CAAC;IACtB,CAAC;IAGD,IAAI,GAAG,YAAY,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,OAAO,OAAY,CAAC;IACtB,CAAC;IAGD,IAAI,GAAG,YAAY,MAAM,EAAE,CAAC;QAC1B,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAM,CAAC;IAChD,CAAC;IAGD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAA4B,CAAC;IACrF,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,OAAO,OAAY,CAAC;AACtB,CAAC","sourcesContent":["/**\n * Deep clone utility for safely cloning objects\n * More efficient and type-safe than JSON.parse(JSON.stringify())\n */\n\n/**\n * Deep clone an object using structured cloning\n * Preserves most object types including Date, RegExp, Map, Set, etc.\n *\n * For simple objects (like formatting options), this is more efficient\n * than JSON.parse(JSON.stringify()) and doesn't lose non-serializable values.\n *\n * @param obj - Object to clone\n * @returns Deep cloned copy of the object\n *\n * @example\n * ```typescript\n * const original = { bold: true, color: \"FF0000\", date: new Date() };\n * const cloned = deepClone(original);\n * cloned.bold = false;\n * console.log(original.bold); // true (unchanged)\n * console.log(cloned.date instanceof Date); // true (preserved)\n * ```\n */\nexport function deepClone<T>(obj: T): T {\n // Handle primitive types and null\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n // Handle Date\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n // Handle Array\n if (Array.isArray(obj)) {\n const arrCopy: unknown[] = [];\n for (let i = 0; i < obj.length; i++) {\n arrCopy[i] = deepClone(obj[i]);\n }\n return arrCopy as T;\n }\n\n // Handle Map\n if (obj instanceof Map) {\n const mapCopy = new Map();\n obj.forEach((value, key) => {\n mapCopy.set(deepClone(key), deepClone(value));\n });\n return mapCopy as T;\n }\n\n // Handle Set\n if (obj instanceof Set) {\n const setCopy = new Set();\n obj.forEach((value) => {\n setCopy.add(deepClone(value));\n });\n return setCopy as T;\n }\n\n // Handle RegExp\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as T;\n }\n\n // Handle plain objects\n const objCopy = Object.create(Object.getPrototypeOf(obj)) as Record<string, unknown>;\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n objCopy[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n }\n\n return objCopy as T;\n}\n"]}
1
+ {"version":3,"file":"deepClone.js","sourceRoot":"","sources":["../../src/utils/deepClone.ts"],"names":[],"mappings":";;AA8BA,8BAKC;AALD,SAAgB,SAAS,CAAI,GAAM;IAIjC,OAAO,aAAa,CAAC,GAAG,EAAE,IAAI,OAAO,EAAmB,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,aAAa,CAAI,GAAM,EAAE,IAA8B;IAE9D,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,GAAG,CAAC;IACb,CAAC;IAMD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAa,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAa,CAAC;IACvB,CAAC;IAID,IAAI,GAAG,YAAY,IAAI,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,GAAa,EAAE,QAAQ,CAAC,CAAC;QAClC,OAAO,QAAa,CAAC;IACvB,CAAC;IAID,IAAI,GAAG,YAAY,MAAM,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,GAAa,EAAE,UAAU,CAAC,CAAC;QACpC,OAAO,UAAe,CAAC;IACzB,CAAC;IAGD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,OAAO,GAAc,EAAE,CAAC;QAE9B,IAAI,CAAC,GAAG,CAAC,GAAa,EAAE,OAAO,CAAC,CAAC;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,OAAY,CAAC;IACtB,CAAC;IAGD,IAAI,GAAG,YAAY,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACzB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,OAAO,OAAY,CAAC;IACtB,CAAC;IAGD,IAAI,GAAG,YAAY,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,OAAO,OAAY,CAAC;IACtB,CAAC;IAGD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAA4B,CAAC;IACrF,IAAI,CAAC,GAAG,CAAC,GAAa,EAAE,OAAO,CAAC,CAAC;IAIjC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAa,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,aAAa,CAAE,GAA+B,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,OAAY,CAAC;AACtB,CAAC","sourcesContent":["/**\n * Deep clone utility for safely cloning objects\n * More efficient and type-safe than JSON.parse(JSON.stringify())\n */\n\n/**\n * Deep clone an object using structured cloning\n * Preserves most object types including Date, RegExp, Map, Set, etc.\n *\n * For simple objects (like formatting options), this is more efficient\n * than JSON.parse(JSON.stringify()) and doesn't lose non-serializable values.\n *\n * Cyclic and shared references are handled via an internal seen-cache: an\n * object encountered more than once during a single clone is cloned exactly\n * once, so circular graphs cannot overflow the stack and shared sub-objects\n * (including shared Date and RegExp instances) retain a single shared identity\n * in the result.\n *\n * @param obj - Object to clone\n * @returns Deep cloned copy of the object\n *\n * @example\n * ```typescript\n * const original = { bold: true, color: \"FF0000\", date: new Date() };\n * const cloned = deepClone(original);\n * cloned.bold = false;\n * console.log(original.bold); // true (unchanged)\n * console.log(cloned.date instanceof Date); // true (preserved)\n * ```\n */\nexport function deepClone<T>(obj: T): T {\n // Map of already-cloned source objects to their clones, scoped to this call.\n // Guards against infinite recursion on cyclic input and preserves the\n // identity of references shared by multiple parents within the same graph.\n return cloneInternal(obj, new WeakMap<object, unknown>());\n}\n\nfunction cloneInternal<T>(obj: T, seen: WeakMap<object, unknown>): T {\n // Handle primitive types and null\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n // Return the existing clone for any object already seen in this call. Placed\n // before the Date/RegExp branches so a single Date/RegExp instance shared by\n // multiple nodes resolves to one shared clone (the JSDoc shared-identity\n // guarantee), not a fresh copy per reference.\n const existing = seen.get(obj as object);\n if (existing !== undefined) {\n return existing as T;\n }\n\n // Handle Date (immutable value copy; cannot form a cycle). Registered in\n // `seen` so repeat references to the same instance share this clone.\n if (obj instanceof Date) {\n const dateCopy = new Date(obj.getTime());\n seen.set(obj as object, dateCopy);\n return dateCopy as T;\n }\n\n // Handle RegExp (immutable value copy; cannot form a cycle). Registered in\n // `seen` so repeat references to the same instance share this clone.\n if (obj instanceof RegExp) {\n const regexpCopy = new RegExp(obj.source, obj.flags);\n seen.set(obj as object, regexpCopy);\n return regexpCopy as T;\n }\n\n // Handle Array\n if (Array.isArray(obj)) {\n const arrCopy: unknown[] = [];\n // Register before recursing so self/back references resolve to this clone.\n seen.set(obj as object, arrCopy);\n for (let i = 0; i < obj.length; i++) {\n arrCopy[i] = cloneInternal(obj[i], seen);\n }\n return arrCopy as T;\n }\n\n // Handle Map\n if (obj instanceof Map) {\n const mapCopy = new Map();\n seen.set(obj, mapCopy);\n obj.forEach((value, key) => {\n mapCopy.set(cloneInternal(key, seen), cloneInternal(value, seen));\n });\n return mapCopy as T;\n }\n\n // Handle Set\n if (obj instanceof Set) {\n const setCopy = new Set();\n seen.set(obj, setCopy);\n obj.forEach((value) => {\n setCopy.add(cloneInternal(value, seen));\n });\n return setCopy as T;\n }\n\n // Handle plain objects\n const objCopy = Object.create(Object.getPrototypeOf(obj)) as Record<string, unknown>;\n seen.set(obj as object, objCopy);\n // Object.keys avoids the prototype-builtins shadowing risk of\n // obj.hasOwnProperty(key) (matches sibling deepEqual.ts) and yields the same\n // own-enumerable string keys the previous for..in + hasOwnProperty loop did.\n for (const key of Object.keys(obj as object)) {\n objCopy[key] = cloneInternal((obj as Record<string, unknown>)[key], seen);\n }\n\n return objCopy as T;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../src/utils/units.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,YAAY,KAAK,CAAC;AAK/B,eAAO,MAAM,KAAK;;;;;;;;;;;CAqBR,CAAC;AAWX,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAOD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAWD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAOD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAOD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAOD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAQD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAE7E;AAWD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAOD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAOD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAWD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGzD;AAOD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE7D;AAWD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAOD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAOD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAQD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEjF;AAWD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5C;AAOD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAOD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7C;AAOD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7C;AAQD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEzE;AAYD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAE/E;AAQD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEjF;AAQD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEhF;AAQD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAE7E;AAQD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEjF;AASD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;CA0Bb,CAAC;AAKX,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;CA6BjB,CAAC"}
1
+ {"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../src/utils/units.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,YAAY,KAAK,CAAC;AAK/B,eAAO,MAAM,KAAK;;;;;;;;;;;CAqBR,CAAC;AAWX,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAOD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAWD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAOD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAOD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAOD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAQD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAE7E;AAWD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIpD;AAOD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAOD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAWD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGzD;AAOD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE7D;AAWD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAOD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAOD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAQD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEjF;AAWD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5C;AAOD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAOD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7C;AAOD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7C;AAQD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEzE;AAYD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAE/E;AAQD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEjF;AAQD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEhF;AAQD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAE7E;AAQD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAqB,GAAG,MAAM,CAEjF;AASD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;CA0Bb,CAAC;AAKX,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;CA6BjB,CAAC"}