@harbour-enterprises/superdoc 1.0.0-beta.13 → 1.0.0-beta.19

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 (42) hide show
  1. package/dist/chunks/{PdfViewer-D_E86Mtr.cjs → PdfViewer-BLFV17De.cjs} +2 -2
  2. package/dist/chunks/{PdfViewer-D0cPi5hG.es.js → PdfViewer-D_4g-jsZ.es.js} +2 -2
  3. package/dist/chunks/{eventemitter3-ByBH0NYV.es.js → eventemitter3-CcXAdeql.es.js} +1 -1
  4. package/dist/chunks/{eventemitter3-CFCpOk3d.cjs → eventemitter3-DQmQUge-.cjs} +1 -1
  5. package/dist/chunks/{index-BMAfbNel-CvPc3jnD.es.js → index-CRpn1mWd-B4eH8Zok.es.js} +1 -1
  6. package/dist/chunks/{index-BMAfbNel-DBZCkkMj.cjs → index-CRpn1mWd-BUbbd3Jq.cjs} +1 -1
  7. package/dist/chunks/{index-BHmLKAul.es.js → index-NPXppXmC.es.js} +11 -7
  8. package/dist/chunks/{index-CL4VptDO.cjs → index-k02voMEs.cjs} +11 -7
  9. package/dist/chunks/{jszip-BwsONqK5.es.js → jszip-5vvIqAEE.es.js} +1 -1
  10. package/dist/chunks/{jszip-B99MTu59.cjs → jszip-BdEez1WM.cjs} +1 -1
  11. package/dist/chunks/{super-editor.es-5gtBhP8I.es.js → super-editor.es-CHU4dmes.es.js} +9554 -2211
  12. package/dist/chunks/{super-editor.es-riuOlaxm.cjs → super-editor.es-C_Gk8cDd.cjs} +9554 -2211
  13. package/dist/chunks/{vue-CztqUvm1.es.js → vue-Dysv_7z5.es.js} +101 -12
  14. package/dist/chunks/{vue-ARQSyfaw.cjs → vue-jWLMl8Ts.cjs} +89 -0
  15. package/dist/chunks/xml-js-ClO_jHnq.es.js +2 -0
  16. package/dist/chunks/xml-js-Dz51sEbr.cjs +3 -0
  17. package/dist/packages/superdoc/src/components/CommentsLayer/use-comment.d.ts.map +1 -1
  18. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  19. package/dist/packages/superdoc/src/stores/comments-store.d.ts.map +1 -1
  20. package/dist/style.css +57 -18
  21. package/dist/super-editor/ai-writer.es.js +2 -2
  22. package/dist/super-editor/chunks/{converter-D9KiDgXx.js → converter-Cu26_LdN.js} +1190 -385
  23. package/dist/super-editor/chunks/{docx-zipper-DQmUj-ef.js → docx-zipper-C8lozSFd.js} +1 -1
  24. package/dist/super-editor/chunks/{editor-ByPqJ2k8.js → editor-BXC2Hzba.js} +7704 -1712
  25. package/dist/super-editor/chunks/{index-BMAfbNel.js → index-CRpn1mWd.js} +1 -1
  26. package/dist/super-editor/chunks/{toolbar-Da2cOhJ-.js → toolbar-BglLOe8y.js} +36 -22
  27. package/dist/super-editor/converter.es.js +1 -1
  28. package/dist/super-editor/docx-zipper.es.js +2 -2
  29. package/dist/super-editor/editor.es.js +3 -3
  30. package/dist/super-editor/file-zipper.es.js +1 -1
  31. package/dist/super-editor/style.css +57 -18
  32. package/dist/super-editor/super-editor.es.js +770 -200
  33. package/dist/super-editor/toolbar.es.js +2 -2
  34. package/dist/super-editor.cjs +4 -4
  35. package/dist/super-editor.es.js +2 -2
  36. package/dist/superdoc.cjs +2 -2
  37. package/dist/superdoc.es.js +2 -2
  38. package/dist/superdoc.umd.js +9623 -2200
  39. package/dist/superdoc.umd.js.map +1 -1
  40. package/package.json +1 -1
  41. package/dist/chunks/xml-js-BZPSMmVo.es.js +0 -2
  42. package/dist/chunks/xml-js-DQa4Ye5C.cjs +0 -3
@@ -18972,7 +18972,6 @@ const encode$B = (params, encodedAttrs = {}) => {
18972
18972
  }
18973
18973
  }
18974
18974
  });
18975
- console.log("subs:", subs);
18976
18975
  return subs;
18977
18976
  };
18978
18977
  function decode$D(params) {
@@ -19181,6 +19180,7 @@ function getUnderlineCssString({ type: type2 = "single", color = null, thickness
19181
19180
  if (color) add("text-decoration-color", color);
19182
19181
  return parts.join("; ");
19183
19182
  }
19183
+ const INLINE_OVERRIDE_PROPERTIES = ["fontSize", "bold", "italic", "strike", "underline", "letterSpacing"];
19184
19184
  const resolveRunProperties = (params, inlineRpr, resolvedPpr, isListNumber = false, numberingDefinedInline = false) => {
19185
19185
  const paragraphStyleId = resolvedPpr?.styleId;
19186
19186
  const paragraphStyleProps = resolveStyleChain(params, paragraphStyleId, translator$1N);
@@ -19217,6 +19217,11 @@ const resolveRunProperties = (params, inlineRpr, resolvedPpr, isListNumber = fal
19217
19217
  styleChain = [...styleChain, paragraphStyleProps, runStyleProps, inlineRpr];
19218
19218
  }
19219
19219
  const finalProps = combineProperties(styleChain, ["fontFamily", "color"]);
19220
+ for (const prop of INLINE_OVERRIDE_PROPERTIES) {
19221
+ if (inlineRpr?.[prop] != null) {
19222
+ finalProps[prop] = inlineRpr[prop];
19223
+ }
19224
+ }
19220
19225
  return finalProps;
19221
19226
  };
19222
19227
  function resolveParagraphProperties(params, inlineProps, insideTable = false, overrideInlineStyleId = false, tableStyleId = null) {
@@ -19774,7 +19779,7 @@ function decodeRPrFromMarks(marks) {
19774
19779
  return runProperties;
19775
19780
  }
19776
19781
  marks.forEach((mark) => {
19777
- switch (mark.type) {
19782
+ switch (mark.type.name ?? mark.type) {
19778
19783
  case "strike":
19779
19784
  case "italic":
19780
19785
  case "bold":
@@ -20131,6 +20136,51 @@ function getStrikeValue(attributes) {
20131
20136
  if (value === "0" || value === "false" || value === "off") return "0";
20132
20137
  return "1";
20133
20138
  }
20139
+ function parseProperties(node) {
20140
+ const marks = [];
20141
+ const unknownMarks = [];
20142
+ const { attributes = {}, elements = [] } = node;
20143
+ const { nodes, paragraphProperties = {}, runProperties = {} } = splitElementsAndProperties(elements);
20144
+ const hasRun = elements.find((element) => element.name === "w:r");
20145
+ if (hasRun) paragraphProperties.elements = paragraphProperties?.elements?.filter((el) => el.name !== "w:rPr");
20146
+ if (runProperties && runProperties?.elements?.length) {
20147
+ marks.push(...parseMarks(runProperties, unknownMarks));
20148
+ }
20149
+ if (paragraphProperties && paragraphProperties.elements?.length) {
20150
+ const disallowedParagraphProperties = ["w:u"];
20151
+ const filteredParagraphProperties = {
20152
+ ...paragraphProperties,
20153
+ elements: paragraphProperties.elements?.filter((el) => !disallowedParagraphProperties.includes(el.name))
20154
+ };
20155
+ marks.push(...parseMarks(filteredParagraphProperties, unknownMarks));
20156
+ }
20157
+ marks.push(...handleStyleChangeMarks(runProperties, marks));
20158
+ if (paragraphProperties && paragraphProperties.elements?.length) {
20159
+ attributes["paragraphProperties"] = paragraphProperties;
20160
+ }
20161
+ if (marks && node.name === "w:p") {
20162
+ marks.forEach((mark) => {
20163
+ const attrValue = Object.keys(mark.attrs ?? {})[0];
20164
+ if (attrValue) {
20165
+ const value = mark.attrs[attrValue];
20166
+ attributes[attrValue] = value;
20167
+ }
20168
+ });
20169
+ }
20170
+ return { elements: nodes, attributes, marks, unknownMarks };
20171
+ }
20172
+ function splitElementsAndProperties(elements) {
20173
+ const pPr = elements.find((el) => el.name === "w:pPr");
20174
+ const rPr = elements.find((el) => el.name === "w:rPr");
20175
+ const sectPr = elements.find((el) => el.name === "w:sectPr");
20176
+ const els = elements.filter((el) => el.name !== "w:pPr" && el.name !== "w:rPr" && el.name !== "w:sectPr");
20177
+ return {
20178
+ nodes: els,
20179
+ paragraphProperties: pPr,
20180
+ runProperties: rPr,
20181
+ sectionProperties: sectPr
20182
+ };
20183
+ }
20134
20184
  function getTableStyleId(path) {
20135
20185
  const tbl = path.find((ancestor) => ancestor.name === "w:tbl");
20136
20186
  if (!tbl) {
@@ -20155,13 +20205,6 @@ const handleParagraphNode$1 = (params) => {
20155
20205
  if (pPr) {
20156
20206
  inlineParagraphProperties = translator$12.encode({ ...params, nodes: [pPr] }) || {};
20157
20207
  }
20158
- const handleStandardNode2 = nodeListHandler.handlerEntities.find(
20159
- (e) => e.handlerName === "standardNodeHandler"
20160
- )?.handler;
20161
- if (!handleStandardNode2) {
20162
- console.error("Standard node handler not found");
20163
- return null;
20164
- }
20165
20208
  const insideTable = (params.path || []).some((ancestor) => ancestor.name === "w:tc");
20166
20209
  const tableStyleId = getTableStyleId(params.path || []);
20167
20210
  const resolvedParagraphProperties = resolveParagraphProperties(
@@ -20170,15 +20213,29 @@ const handleParagraphNode$1 = (params) => {
20170
20213
  insideTable,
20171
20214
  tableStyleId
20172
20215
  );
20173
- const updatedParams = {
20174
- ...params,
20175
- nodes: [node],
20176
- extraParams: { ...params.extraParams, paragraphProperties: resolvedParagraphProperties }
20177
- };
20178
- const result = handleStandardNode2(updatedParams);
20179
- if (result.nodes.length === 1) {
20180
- schemaNode = result.nodes[0];
20216
+ const { elements = [], attributes = {}, marks = [] } = parseProperties(node, params.docx);
20217
+ const childContent = [];
20218
+ if (elements.length) {
20219
+ const updatedElements = elements.map((el) => {
20220
+ if (!el.marks) el.marks = [];
20221
+ el.marks.push(...marks);
20222
+ return el;
20223
+ });
20224
+ const childParams = {
20225
+ ...params,
20226
+ nodes: updatedElements,
20227
+ extraParams: { ...params.extraParams, paragraphProperties: resolvedParagraphProperties },
20228
+ path: [...params.path || [], node]
20229
+ };
20230
+ const translatedChildren = nodeListHandler.handler(childParams);
20231
+ childContent.push(...translatedChildren);
20181
20232
  }
20233
+ schemaNode = {
20234
+ type: "paragraph",
20235
+ content: childContent,
20236
+ attrs: { ...attributes },
20237
+ marks: []
20238
+ };
20182
20239
  schemaNode.type = "paragraph";
20183
20240
  schemaNode.attrs.paragraphProperties = inlineParagraphProperties;
20184
20241
  schemaNode.attrs.rsidRDefault = node.attributes?.["w:rsidRDefault"];
@@ -20788,6 +20845,11 @@ const decode$q = (params, decodedAttrs = {}) => {
20788
20845
  runs.push(trackedClone);
20789
20846
  return;
20790
20847
  }
20848
+ if (child.name === "w:commentRangeStart" || child.name === "w:commentRangeEnd") {
20849
+ const commentRangeClone = cloneXmlNode(child);
20850
+ runs.push(commentRangeClone);
20851
+ return;
20852
+ }
20791
20853
  const runWrapper = { name: XML_NODE_NAME$i, elements: [] };
20792
20854
  applyBaseRunProps(runWrapper);
20793
20855
  if (!Array.isArray(runWrapper.elements)) runWrapper.elements = [];
@@ -21649,7 +21711,7 @@ function handleAnnotationNode(params) {
21649
21711
  attrs.displayLabel = placeholderLabel;
21650
21712
  }
21651
21713
  const { attrs: marksAsAttrs, marks } = parseAnnotationMarks(sdtContent);
21652
- const allAttrs = { ...attrs, ...marksAsAttrs };
21714
+ const allAttrs = { ...attrs, ...marksAsAttrs, ...sdtPr && { sdtPr } };
21653
21715
  if (!allAttrs.hash) allAttrs.hash = generateDocxRandomId(4);
21654
21716
  if (!attrs.fieldId || !attrs.type) {
21655
21717
  return null;
@@ -21809,16 +21871,13 @@ function handleDocPartObj(params) {
21809
21871
  const sdtPr = node.elements.find((el) => el.name === "w:sdtPr");
21810
21872
  const docPartObj = sdtPr?.elements.find((el) => el.name === "w:docPartObj");
21811
21873
  const docPartGallery = docPartObj?.elements.find((el) => el.name === "w:docPartGallery");
21812
- const docPartGalleryType = docPartGallery?.attributes["w:val"];
21813
- if (!docPartGalleryType || !validGalleryTypeMap[docPartGalleryType]) {
21814
- return null;
21815
- }
21874
+ const docPartGalleryType = docPartGallery?.attributes?.["w:val"] ?? null;
21816
21875
  const content = node?.elements.find((el) => el.name === "w:sdtContent");
21817
- const handler2 = validGalleryTypeMap[docPartGalleryType];
21876
+ const handler2 = validGalleryTypeMap[docPartGalleryType] || genericDocPartHandler;
21818
21877
  const result = handler2({
21819
21878
  ...params,
21820
21879
  nodes: [content],
21821
- extraParams: { ...params.extraParams || {}, sdtPr }
21880
+ extraParams: { ...params.extraParams || {}, sdtPr, docPartGalleryType }
21822
21881
  });
21823
21882
  return result;
21824
21883
  }
@@ -21829,15 +21888,46 @@ const tableOfContentsHandler = (params) => {
21829
21888
  nodes: node.elements,
21830
21889
  path: [...params.path || [], node]
21831
21890
  });
21891
+ const normalizedContent = normalizeDocPartContent(translatedContent);
21832
21892
  const sdtPr = params.extraParams.sdtPr;
21833
21893
  const id = sdtPr.elements?.find((el) => el.name === "w:id")?.attributes["w:val"] || "";
21894
+ const docPartObj = sdtPr?.elements.find((el) => el.name === "w:docPartObj");
21895
+ const docPartUnique = docPartObj?.elements.some((el) => el.name === "w:docPartUnique") ?? false;
21834
21896
  const result = {
21835
21897
  type: "documentPartObject",
21836
- content: translatedContent,
21898
+ content: normalizedContent,
21837
21899
  attrs: {
21838
21900
  id,
21839
21901
  docPartGallery: "Table of Contents",
21840
- docPartUnique: true
21902
+ docPartUnique,
21903
+ sdtPr
21904
+ // Passthrough for round-trip preservation
21905
+ }
21906
+ };
21907
+ return result;
21908
+ };
21909
+ const genericDocPartHandler = (params) => {
21910
+ const node = params.nodes[0];
21911
+ const translatedContent = params.nodeListHandler.handler({
21912
+ ...params,
21913
+ nodes: node.elements,
21914
+ path: [...params.path || [], node]
21915
+ });
21916
+ const sdtPr = params.extraParams.sdtPr;
21917
+ const docPartGalleryType = params.extraParams.docPartGalleryType;
21918
+ const id = sdtPr?.elements?.find((el) => el.name === "w:id")?.attributes["w:val"] || "";
21919
+ const docPartObj = sdtPr?.elements.find((el) => el.name === "w:docPartObj");
21920
+ const docPartGallery = docPartGalleryType ?? docPartObj?.elements?.find((el) => el.name === "w:docPartGallery")?.attributes?.["w:val"] ?? null;
21921
+ const docPartUnique = docPartObj?.elements.some((el) => el.name === "w:docPartUnique") ?? false;
21922
+ const result = {
21923
+ type: "documentPartObject",
21924
+ content: translatedContent,
21925
+ attrs: {
21926
+ id,
21927
+ docPartGallery,
21928
+ docPartUnique,
21929
+ sdtPr
21930
+ // Passthrough for round-trip preservation of all sdtPr elements
21841
21931
  }
21842
21932
  };
21843
21933
  return result;
@@ -21845,6 +21935,22 @@ const tableOfContentsHandler = (params) => {
21845
21935
  const validGalleryTypeMap = {
21846
21936
  "Table of Contents": tableOfContentsHandler
21847
21937
  };
21938
+ const inlineNodeTypes = /* @__PURE__ */ new Set(["bookmarkStart", "bookmarkEnd"]);
21939
+ const wrapInlineNode = (node) => ({
21940
+ type: "paragraph",
21941
+ content: [node]
21942
+ });
21943
+ const normalizeDocPartContent = (nodes = []) => {
21944
+ const normalized = [];
21945
+ nodes.forEach((node) => {
21946
+ if (inlineNodeTypes.has(node?.type)) {
21947
+ normalized.push(wrapInlineNode(node));
21948
+ } else {
21949
+ normalized.push(node);
21950
+ }
21951
+ });
21952
+ return normalized;
21953
+ };
21848
21954
  function handleDocumentSectionNode(params) {
21849
21955
  const { nodes, nodeListHandler } = params;
21850
21956
  if (nodes.length === 0 || nodes[0].name !== "w:sdt") {
@@ -21859,6 +21965,9 @@ function handleDocumentSectionNode(params) {
21859
21965
  const titleTag = sdtPr?.elements.find((el) => el.name === "w:alias");
21860
21966
  const title = titleTag?.attributes?.["w:val"] || tagValue.title || null;
21861
21967
  const { description } = tagValue;
21968
+ const lockTag = sdtPr?.elements.find((el) => el.name === "w:lock");
21969
+ const lockValue = lockTag?.attributes?.["w:val"];
21970
+ const isLocked = lockValue === "sdtContentLocked";
21862
21971
  const sdtContent = node.elements.find((el) => el.name === "w:sdtContent");
21863
21972
  const translatedContent = nodeListHandler.handler({
21864
21973
  ...params,
@@ -21871,7 +21980,10 @@ function handleDocumentSectionNode(params) {
21871
21980
  attrs: {
21872
21981
  id,
21873
21982
  title,
21874
- description
21983
+ description,
21984
+ isLocked,
21985
+ ...sdtPr && { sdtPr }
21986
+ // Passthrough for round-trip preservation of unknown elements only if it exists
21875
21987
  }
21876
21988
  };
21877
21989
  return result;
@@ -24664,7 +24776,10 @@ function getThemeColor(name) {
24664
24776
  text1: "#000000",
24665
24777
  text2: "#1f497d",
24666
24778
  background1: "#ffffff",
24667
- background2: "#eeece1"
24779
+ background2: "#eeece1",
24780
+ // Office XML shortcuts
24781
+ bg1: "#ffffff",
24782
+ bg2: "#eeece1"
24668
24783
  };
24669
24784
  return colors[name] ?? "#000000";
24670
24785
  }
@@ -24701,7 +24816,10 @@ function applyColorModifier(hexColor, modifier, value) {
24701
24816
  function extractStrokeWidth(spPr) {
24702
24817
  const ln = spPr?.elements?.find((el) => el.name === "a:ln");
24703
24818
  const w2 = ln?.attributes?.["w"];
24704
- return w2 ? emuToPixels(w2) : 1;
24819
+ if (!w2) return 1;
24820
+ const emu = typeof w2 === "string" ? parseFloat(w2) : w2;
24821
+ const STROKE_DPI = 72;
24822
+ return emu * STROKE_DPI / 914400;
24705
24823
  }
24706
24824
  function extractStrokeColor(spPr, style) {
24707
24825
  const ln = spPr?.elements?.find((el) => el.name === "a:ln");
@@ -24762,6 +24880,7 @@ function extractFillColor(spPr, style) {
24762
24880
  if (schemeClr2) {
24763
24881
  const themeName2 = schemeClr2.attributes?.["val"];
24764
24882
  let color2 = getThemeColor(themeName2);
24883
+ let alpha = null;
24765
24884
  const modifiers2 = schemeClr2.elements || [];
24766
24885
  modifiers2.forEach((mod) => {
24767
24886
  if (mod.name === "a:shade") {
@@ -24772,18 +24891,32 @@ function extractFillColor(spPr, style) {
24772
24891
  color2 = applyColorModifier(color2, "lumMod", mod.attributes["val"]);
24773
24892
  } else if (mod.name === "a:lumOff") {
24774
24893
  color2 = applyColorModifier(color2, "lumOff", mod.attributes["val"]);
24894
+ } else if (mod.name === "a:alpha") {
24895
+ alpha = parseInt(mod.attributes["val"]) / 1e5;
24775
24896
  }
24776
24897
  });
24898
+ if (alpha !== null && alpha < 1) {
24899
+ return { type: "solidWithAlpha", color: color2, alpha };
24900
+ }
24777
24901
  return color2;
24778
24902
  }
24779
24903
  const srgbClr = solidFill.elements?.find((el) => el.name === "a:srgbClr");
24780
24904
  if (srgbClr) {
24781
- return "#" + srgbClr.attributes?.["val"];
24905
+ let alpha = null;
24906
+ const alphaEl = srgbClr.elements?.find((el) => el.name === "a:alpha");
24907
+ if (alphaEl) {
24908
+ alpha = parseInt(alphaEl.attributes?.["val"] || "100000", 10) / 1e5;
24909
+ }
24910
+ const color2 = "#" + srgbClr.attributes?.["val"];
24911
+ if (alpha !== null && alpha < 1) {
24912
+ return { type: "solidWithAlpha", color: color2, alpha };
24913
+ }
24914
+ return color2;
24782
24915
  }
24783
24916
  }
24784
24917
  const gradFill = spPr?.elements?.find((el) => el.name === "a:gradFill");
24785
24918
  if (gradFill) {
24786
- return "#cccccc";
24919
+ return extractGradientFill(gradFill);
24787
24920
  }
24788
24921
  const blipFill = spPr?.elements?.find((el) => el.name === "a:blipFill");
24789
24922
  if (blipFill) {
@@ -24792,6 +24925,8 @@ function extractFillColor(spPr, style) {
24792
24925
  if (!style) return "#5b9bd5";
24793
24926
  const fillRef = style.elements?.find((el) => el.name === "a:fillRef");
24794
24927
  if (!fillRef) return "#5b9bd5";
24928
+ const fillRefIdx = fillRef.attributes?.["idx"];
24929
+ if (fillRefIdx === "0") return null;
24795
24930
  const schemeClr = fillRef.elements?.find((el) => el.name === "a:schemeClr");
24796
24931
  if (!schemeClr) return "#5b9bd5";
24797
24932
  const themeName = schemeClr.attributes?.["val"];
@@ -24808,9 +24943,49 @@ function extractFillColor(spPr, style) {
24808
24943
  });
24809
24944
  return color;
24810
24945
  }
24946
+ function extractGradientFill(gradFill) {
24947
+ const gradient = {
24948
+ type: "gradient",
24949
+ stops: [],
24950
+ angle: 0
24951
+ };
24952
+ const gsLst = gradFill.elements?.find((el) => el.name === "a:gsLst");
24953
+ if (gsLst) {
24954
+ const stops = gsLst.elements?.filter((el) => el.name === "a:gs") || [];
24955
+ gradient.stops = stops.map((stop) => {
24956
+ const pos = parseInt(stop.attributes?.["pos"] || "0", 10) / 1e5;
24957
+ const srgbClr = stop.elements?.find((el) => el.name === "a:srgbClr");
24958
+ let color = "#000000";
24959
+ let alpha = 1;
24960
+ if (srgbClr) {
24961
+ color = "#" + srgbClr.attributes?.["val"];
24962
+ const alphaEl = srgbClr.elements?.find((el) => el.name === "a:alpha");
24963
+ if (alphaEl) {
24964
+ alpha = parseInt(alphaEl.attributes?.["val"] || "100000", 10) / 1e5;
24965
+ }
24966
+ }
24967
+ return { position: pos, color, alpha };
24968
+ });
24969
+ }
24970
+ const lin = gradFill.elements?.find((el) => el.name === "a:lin");
24971
+ if (lin) {
24972
+ const ang = parseInt(lin.attributes?.["ang"] || "0", 10) / 6e4;
24973
+ gradient.angle = ang;
24974
+ }
24975
+ const path = gradFill.elements?.find((el) => el.name === "a:path");
24976
+ if (path) {
24977
+ gradient.gradientType = "radial";
24978
+ gradient.path = path.attributes?.["path"] || "circle";
24979
+ } else {
24980
+ gradient.gradientType = "linear";
24981
+ }
24982
+ return gradient;
24983
+ }
24811
24984
  const DRAWING_XML_TAG = "w:drawing";
24812
24985
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
24813
24986
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
24987
+ const DEFAULT_SHAPE_WIDTH = 100;
24988
+ const DEFAULT_SHAPE_HEIGHT = 100;
24814
24989
  function handleImageNode(node, params, isAnchor) {
24815
24990
  const { docx, filename } = params;
24816
24991
  const { attributes } = node;
@@ -24854,7 +25029,8 @@ function handleImageNode(node, params, isAnchor) {
24854
25029
  horizontal: positionHValue,
24855
25030
  top: positionVValue
24856
25031
  };
24857
- const simplePos = node.elements.find((el) => el.name === "wp:simplePos");
25032
+ const useSimplePos = attributes["simplePos"] === "1" || attributes["simplePos"] === 1 || attributes["simplePos"] === true;
25033
+ const simplePosNode = node.elements.find((el) => el.name === "wp:simplePos");
24858
25034
  const wrapNode = isAnchor ? node.elements.find(
24859
25035
  (el) => ["wp:wrapNone", "wp:wrapSquare", "wp:wrapThrough", "wp:wrapTight", "wp:wrapTopAndBottom"].includes(el.name)
24860
25036
  ) : null;
@@ -24934,7 +25110,7 @@ function handleImageNode(node, params, isAnchor) {
24934
25110
  horizontal: positionHValue,
24935
25111
  top: positionVValue
24936
25112
  };
24937
- return handleShapeDrawing(params, node, graphicData, size, padding, shapeMarginOffset);
25113
+ return handleShapeDrawing(params, node, graphicData, size, padding, shapeMarginOffset, anchorData, wrap2, isAnchor);
24938
25114
  }
24939
25115
  if (uri2 === GROUP_URI) {
24940
25116
  const shapeMarginOffset = {
@@ -24942,13 +25118,16 @@ function handleImageNode(node, params, isAnchor) {
24942
25118
  horizontal: positionHValue,
24943
25119
  top: positionVValue
24944
25120
  };
24945
- return handleShapeGroup(params, node, graphicData, size, padding, shapeMarginOffset);
25121
+ return handleShapeGroup(params, node, graphicData, size, padding, shapeMarginOffset, anchorData, wrap2);
24946
25122
  }
24947
25123
  const picture = graphicData?.elements.find((el) => el.name === "pic:pic");
24948
25124
  if (!picture || !picture.elements) return null;
24949
25125
  const blipFill = picture.elements.find((el) => el.name === "pic:blipFill");
24950
25126
  const blip = blipFill?.elements.find((el) => el.name === "a:blip");
24951
25127
  if (!blip) return null;
25128
+ const stretch = blipFill?.elements.find((el) => el.name === "a:stretch");
25129
+ const fillRect = stretch?.elements.find((el) => el.name === "a:fillRect");
25130
+ const shouldStretch = Boolean(stretch && fillRect);
24952
25131
  const spPr = picture.elements.find((el) => el.name === "pic:spPr");
24953
25132
  if (spPr) {
24954
25133
  const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
@@ -24991,10 +25170,10 @@ function handleImageNode(node, params, isAnchor) {
24991
25170
  anchorData,
24992
25171
  isAnchor,
24993
25172
  transformData,
24994
- ...simplePos && {
25173
+ ...useSimplePos && {
24995
25174
  simplePos: {
24996
- x: simplePos.attributes.x,
24997
- y: simplePos.attributes.y
25175
+ x: simplePosNode.attributes?.x,
25176
+ y: simplePosNode.attributes?.y
24998
25177
  }
24999
25178
  },
25000
25179
  wrap: wrap2,
@@ -25002,6 +25181,7 @@ function handleImageNode(node, params, isAnchor) {
25002
25181
  wrapText: wrap2.attrs.wrapText
25003
25182
  } : {},
25004
25183
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
25184
+ shouldStretch,
25005
25185
  originalPadding: {
25006
25186
  distT: attributes["distT"],
25007
25187
  distB: attributes["distB"],
@@ -25013,26 +25193,25 @@ function handleImageNode(node, params, isAnchor) {
25013
25193
  }
25014
25194
  };
25015
25195
  }
25016
- const handleShapeDrawing = (params, node, graphicData, size, padding, marginOffset) => {
25196
+ const handleShapeDrawing = (params, node, graphicData, size, padding, marginOffset, anchorData, wrap2, isAnchor) => {
25017
25197
  const wsp = graphicData.elements.find((el) => el.name === "wps:wsp");
25018
25198
  const textBox = wsp.elements.find((el) => el.name === "wps:txbx");
25019
25199
  const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
25020
25200
  const spPr = wsp.elements.find((el) => el.name === "wps:spPr");
25021
25201
  const prstGeom = spPr?.elements.find((el) => el.name === "a:prstGeom");
25022
25202
  const shapeType = prstGeom?.attributes["prst"];
25023
- if (shapeType === "rect" && !textBoxContent) {
25024
- return getRectangleShape(params, spPr);
25203
+ const hasGradientFill = spPr?.elements?.find((el) => el.name === "a:gradFill");
25204
+ if (shapeType === "rect" && !textBoxContent && !hasGradientFill) {
25205
+ return getRectangleShape(params, spPr, node, marginOffset, anchorData, wrap2, isAnchor);
25025
25206
  }
25026
- if (shapeType && !textBoxContent) {
25027
- const result = getVectorShape({ params, graphicData });
25207
+ if (shapeType) {
25208
+ const result = getVectorShape({ params, node, graphicData, size, marginOffset, anchorData, wrap: wrap2, isAnchor });
25028
25209
  if (result) return result;
25029
25210
  }
25030
- if (!textBoxContent) {
25031
- return buildShapePlaceholder(node, size, padding, marginOffset, "drawing");
25032
- }
25033
- return buildShapePlaceholder(node, size, padding, marginOffset, "textbox");
25211
+ const fallbackType = textBoxContent ? "textbox" : "drawing";
25212
+ return buildShapePlaceholder(node, size, padding, marginOffset, fallbackType);
25034
25213
  };
25035
- const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset) => {
25214
+ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset, anchorData, wrap2) => {
25036
25215
  const wgp = graphicData.elements.find((el) => el.name === "wpg:wgp");
25037
25216
  if (!wgp) {
25038
25217
  return buildShapePlaceholder(node, size, padding, marginOffset, "group");
@@ -25065,6 +25244,7 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25065
25244
  }
25066
25245
  }
25067
25246
  const childShapes = wgp.elements.filter((el) => el.name === "wps:wsp");
25247
+ const childPictures = wgp.elements.filter((el) => el.name === "pic:pic");
25068
25248
  const shapes = childShapes.map((wsp) => {
25069
25249
  const spPr = wsp.elements?.find((el) => el.name === "wps:spPr");
25070
25250
  if (!spPr) return null;
@@ -25103,6 +25283,14 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25103
25283
  const cNvPr = wsp.elements?.find((el) => el.name === "wps:cNvPr");
25104
25284
  const shapeId = cNvPr?.attributes?.["id"];
25105
25285
  const shapeName = cNvPr?.attributes?.["name"];
25286
+ const textBox = wsp.elements?.find((el) => el.name === "wps:txbx");
25287
+ const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
25288
+ const bodyPr = wsp.elements?.find((el) => el.name === "wps:bodyPr");
25289
+ let textContent = null;
25290
+ if (textBoxContent) {
25291
+ textContent = extractTextFromTextBox(textBoxContent, bodyPr);
25292
+ }
25293
+ const textAlign = textContent?.horizontalAlign || "left";
25106
25294
  return {
25107
25295
  shapeType: "vectorShape",
25108
25296
  attrs: {
@@ -25118,10 +25306,75 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25118
25306
  strokeColor,
25119
25307
  strokeWidth,
25120
25308
  shapeId,
25121
- shapeName
25309
+ shapeName,
25310
+ textContent,
25311
+ textAlign,
25312
+ textVerticalAlign: textContent?.verticalAlign,
25313
+ textInsets: textContent?.insets
25122
25314
  }
25123
25315
  };
25124
25316
  }).filter(Boolean);
25317
+ const pictures = childPictures.map((pic) => {
25318
+ const spPr = pic.elements?.find((el) => el.name === "pic:spPr");
25319
+ if (!spPr) return null;
25320
+ const xfrm2 = spPr.elements?.find((el) => el.name === "a:xfrm");
25321
+ const off = xfrm2?.elements?.find((el) => el.name === "a:off");
25322
+ const ext = xfrm2?.elements?.find((el) => el.name === "a:ext");
25323
+ const rawX = off?.attributes?.["x"] ? parseFloat(off.attributes["x"]) : 0;
25324
+ const rawY = off?.attributes?.["y"] ? parseFloat(off.attributes["y"]) : 0;
25325
+ const rawWidth = ext?.attributes?.["cx"] ? parseFloat(ext.attributes["cx"]) : 914400;
25326
+ const rawHeight = ext?.attributes?.["cy"] ? parseFloat(ext.attributes["cy"]) : 914400;
25327
+ let x2, y2, width, height;
25328
+ if (groupTransform.childWidth && groupTransform.childHeight) {
25329
+ const scaleX = groupTransform.width / groupTransform.childWidth;
25330
+ const scaleY = groupTransform.height / groupTransform.childHeight;
25331
+ const childOriginX = groupTransform.childOriginXEmu || 0;
25332
+ const childOriginY = groupTransform.childOriginYEmu || 0;
25333
+ x2 = groupTransform.x + emuToPixels((rawX - childOriginX) * scaleX);
25334
+ y2 = groupTransform.y + emuToPixels((rawY - childOriginY) * scaleY);
25335
+ width = emuToPixels(rawWidth * scaleX);
25336
+ height = emuToPixels(rawHeight * scaleY);
25337
+ } else {
25338
+ x2 = emuToPixels(rawX);
25339
+ y2 = emuToPixels(rawY);
25340
+ width = emuToPixels(rawWidth);
25341
+ height = emuToPixels(rawHeight);
25342
+ }
25343
+ const blipFill = pic.elements?.find((el) => el.name === "pic:blipFill");
25344
+ const blip = blipFill?.elements?.find((el) => el.name === "a:blip");
25345
+ if (!blip) return null;
25346
+ const rEmbed = blip.attributes?.["r:embed"];
25347
+ if (!rEmbed) return null;
25348
+ const currentFile = params.filename || "document.xml";
25349
+ let rels = params.docx[`word/_rels/${currentFile}.rels`];
25350
+ if (!rels) rels = params.docx[`word/_rels/document.xml.rels`];
25351
+ const relationships = rels?.elements.find((el) => el.name === "Relationships");
25352
+ const { elements } = relationships || [];
25353
+ const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
25354
+ if (!rel) return null;
25355
+ const targetPath = rel.attributes?.["Target"];
25356
+ let path = `word/${targetPath}`;
25357
+ if (targetPath.startsWith("/word") || targetPath.startsWith("/media")) {
25358
+ path = targetPath.substring(1);
25359
+ }
25360
+ const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
25361
+ const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
25362
+ const picId = cNvPr?.attributes?.["id"];
25363
+ const picName = cNvPr?.attributes?.["name"];
25364
+ return {
25365
+ shapeType: "image",
25366
+ attrs: {
25367
+ x: x2,
25368
+ y: y2,
25369
+ width,
25370
+ height,
25371
+ src: path,
25372
+ imageId: picId,
25373
+ imageName: picName
25374
+ }
25375
+ };
25376
+ }).filter(Boolean);
25377
+ const allShapes = [...pictures, ...shapes];
25125
25378
  const schemaAttrs = {};
25126
25379
  const drawingNode = params.nodes?.[0];
25127
25380
  if (drawingNode?.name === DRAWING_XML_TAG) {
@@ -25132,38 +25385,137 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25132
25385
  attrs: {
25133
25386
  ...schemaAttrs,
25134
25387
  groupTransform,
25135
- shapes,
25388
+ shapes: allShapes,
25136
25389
  size,
25137
25390
  padding,
25138
- marginOffset
25391
+ marginOffset,
25392
+ anchorData,
25393
+ wrap: wrap2,
25394
+ originalAttributes: node?.attributes
25139
25395
  }
25140
25396
  };
25141
25397
  return result;
25142
25398
  };
25143
- const getRectangleShape = (params, node) => {
25399
+ function extractTextFromTextBox(textBoxContent, bodyPr) {
25400
+ if (!textBoxContent || !textBoxContent.elements) return null;
25401
+ const paragraphs = textBoxContent.elements.filter((el) => el.name === "w:p");
25402
+ const textParts = [];
25403
+ let horizontalAlign = null;
25404
+ paragraphs.forEach((paragraph, paragraphIndex) => {
25405
+ if (!horizontalAlign) {
25406
+ const pPr = paragraph.elements?.find((el) => el.name === "w:pPr");
25407
+ const jc = pPr?.elements?.find((el) => el.name === "w:jc");
25408
+ if (jc) {
25409
+ const jcVal = jc.attributes?.["val"] || jc.attributes?.["w:val"];
25410
+ if (jcVal === "left" || jcVal === "start") horizontalAlign = "left";
25411
+ else if (jcVal === "right" || jcVal === "end") horizontalAlign = "right";
25412
+ else if (jcVal === "center") horizontalAlign = "center";
25413
+ }
25414
+ }
25415
+ const runs = paragraph.elements?.filter((el) => el.name === "w:r") || [];
25416
+ let paragraphHasText = false;
25417
+ runs.forEach((run2) => {
25418
+ const textEl = run2.elements?.find((el) => el.name === "w:t");
25419
+ if (textEl && textEl.elements) {
25420
+ const text = textEl.elements.find((el) => el.type === "text");
25421
+ if (text) {
25422
+ paragraphHasText = true;
25423
+ const cleanedText = typeof text.text === "string" ? text.text.replace(/\[\[sdspace\]\]/g, " ") : text.text;
25424
+ const rPr = run2.elements?.find((el) => el.name === "w:rPr");
25425
+ const formatting = {};
25426
+ if (rPr) {
25427
+ const bold = rPr.elements?.find((el) => el.name === "w:b");
25428
+ const italic = rPr.elements?.find((el) => el.name === "w:i");
25429
+ const color = rPr.elements?.find((el) => el.name === "w:color");
25430
+ const sz = rPr.elements?.find((el) => el.name === "w:sz");
25431
+ if (bold) formatting.bold = true;
25432
+ if (italic) formatting.italic = true;
25433
+ if (color) formatting.color = color.attributes?.["val"] || color.attributes?.["w:val"];
25434
+ if (sz) {
25435
+ const szVal = sz.attributes?.["val"] || sz.attributes?.["w:val"];
25436
+ formatting.fontSize = parseInt(szVal, 10) / 2;
25437
+ }
25438
+ }
25439
+ textParts.push({
25440
+ text: cleanedText,
25441
+ formatting
25442
+ });
25443
+ }
25444
+ }
25445
+ });
25446
+ if (paragraphIndex < paragraphs.length - 1) {
25447
+ textParts.push({
25448
+ text: "\n",
25449
+ formatting: {},
25450
+ isLineBreak: true,
25451
+ isEmptyParagraph: !paragraphHasText
25452
+ // Mark empty paragraphs for extra spacing
25453
+ });
25454
+ }
25455
+ });
25456
+ if (textParts.length === 0) return null;
25457
+ const bodyPrAttrs = bodyPr?.attributes || {};
25458
+ let verticalAlign = "center";
25459
+ const anchorAttr = bodyPrAttrs["anchor"];
25460
+ if (anchorAttr === "t") verticalAlign = "top";
25461
+ else if (anchorAttr === "ctr") verticalAlign = "center";
25462
+ else if (anchorAttr === "b") verticalAlign = "bottom";
25463
+ const EMU_TO_PX = 96 / 914400;
25464
+ const DEFAULT_HORIZONTAL_INSET_EMU = 91440;
25465
+ const DEFAULT_VERTICAL_INSET_EMU = 45720;
25466
+ const lIns = bodyPrAttrs["lIns"] != null ? parseFloat(bodyPrAttrs["lIns"]) : DEFAULT_HORIZONTAL_INSET_EMU;
25467
+ const tIns = bodyPrAttrs["tIns"] != null ? parseFloat(bodyPrAttrs["tIns"]) : DEFAULT_VERTICAL_INSET_EMU;
25468
+ const rIns = bodyPrAttrs["rIns"] != null ? parseFloat(bodyPrAttrs["rIns"]) : DEFAULT_HORIZONTAL_INSET_EMU;
25469
+ const bIns = bodyPrAttrs["bIns"] != null ? parseFloat(bodyPrAttrs["bIns"]) : DEFAULT_VERTICAL_INSET_EMU;
25470
+ const insets = {
25471
+ top: tIns * EMU_TO_PX,
25472
+ right: rIns * EMU_TO_PX,
25473
+ bottom: bIns * EMU_TO_PX,
25474
+ left: lIns * EMU_TO_PX
25475
+ };
25476
+ const wrap2 = bodyPrAttrs["wrap"] || "square";
25477
+ return {
25478
+ parts: textParts,
25479
+ horizontalAlign: horizontalAlign || "left",
25480
+ // Default to left if not specified
25481
+ verticalAlign,
25482
+ insets,
25483
+ wrap: wrap2
25484
+ };
25485
+ }
25486
+ const getRectangleShape = (params, spPr, node, marginOffset, anchorData, wrap2, isAnchor) => {
25144
25487
  const schemaAttrs = {};
25145
- const [drawingNode] = params.nodes;
25488
+ const drawingNode = params.nodes?.[0];
25146
25489
  if (drawingNode?.name === DRAWING_XML_TAG) {
25147
25490
  schemaAttrs.drawingContent = drawingNode;
25148
25491
  }
25149
- const xfrm = node.elements.find((el) => el.name === "a:xfrm");
25150
- const start = xfrm.elements.find((el) => el.name === "a:off");
25151
- const size = xfrm.elements.find((el) => el.name === "a:ext");
25152
- const solidFill = node.elements.find((el) => el.name === "a:solidFill");
25153
- const rectangleSize = {
25154
- top: emuToPixels(start.attributes["y"]),
25155
- left: emuToPixels(start.attributes["x"]),
25156
- width: emuToPixels(size.attributes["cx"]),
25157
- height: emuToPixels(size.attributes["cy"])
25158
- };
25159
- schemaAttrs.size = rectangleSize;
25492
+ const xfrm = spPr?.elements?.find((el) => el.name === "a:xfrm");
25493
+ const start = xfrm?.elements?.find((el) => el.name === "a:off");
25494
+ const size = xfrm?.elements?.find((el) => el.name === "a:ext");
25495
+ const solidFill = spPr?.elements?.find((el) => el.name === "a:solidFill");
25496
+ if (start && size) {
25497
+ const rectangleSize = {
25498
+ top: emuToPixels(start.attributes?.["y"] || 0),
25499
+ left: emuToPixels(start.attributes?.["x"] || 0),
25500
+ width: emuToPixels(size.attributes?.["cx"] || 0),
25501
+ height: emuToPixels(size.attributes?.["cy"] || 0)
25502
+ };
25503
+ schemaAttrs.size = rectangleSize;
25504
+ }
25160
25505
  const background = solidFill?.elements[0]?.attributes["val"];
25161
25506
  if (background) {
25162
25507
  schemaAttrs.background = "#" + background;
25163
25508
  }
25164
25509
  return {
25165
25510
  type: "contentBlock",
25166
- attrs: schemaAttrs
25511
+ attrs: {
25512
+ ...schemaAttrs,
25513
+ marginOffset,
25514
+ anchorData,
25515
+ wrap: wrap2,
25516
+ isAnchor,
25517
+ originalAttributes: node?.attributes
25518
+ }
25167
25519
  };
25168
25520
  };
25169
25521
  const buildShapePlaceholder = (node, size, padding, marginOffset, shapeType) => {
@@ -25212,7 +25564,7 @@ const buildShapePlaceholder = (node, size, padding, marginOffset, shapeType) =>
25212
25564
  attrs
25213
25565
  };
25214
25566
  };
25215
- function getVectorShape({ params, graphicData }) {
25567
+ function getVectorShape({ params, node, graphicData, size, marginOffset, anchorData, wrap: wrap2, isAnchor }) {
25216
25568
  const schemaAttrs = {};
25217
25569
  const drawingNode = params.nodes?.[0];
25218
25570
  if (drawingNode?.name === "w:drawing") {
@@ -25232,10 +25584,9 @@ function getVectorShape({ params, graphicData }) {
25232
25584
  console.warn("Shape kind not found");
25233
25585
  }
25234
25586
  schemaAttrs.kind = shapeKind;
25587
+ const width = size?.width ?? DEFAULT_SHAPE_WIDTH;
25588
+ const height = size?.height ?? DEFAULT_SHAPE_HEIGHT;
25235
25589
  const xfrm = spPr.elements?.find((el) => el.name === "a:xfrm");
25236
- const extent = xfrm?.elements?.find((el) => el.name === "a:ext");
25237
- const width = extent?.attributes?.["cx"] ? emuToPixels(extent.attributes["cx"]) : 100;
25238
- const height = extent?.attributes?.["cy"] ? emuToPixels(extent.attributes["cy"]) : 100;
25239
25590
  const rotation = xfrm?.attributes?.["rot"] ? rotToDegrees(xfrm.attributes["rot"]) : 0;
25240
25591
  const flipH = xfrm?.attributes?.["flipH"] === "1";
25241
25592
  const flipV = xfrm?.attributes?.["flipV"] === "1";
@@ -25243,6 +25594,15 @@ function getVectorShape({ params, graphicData }) {
25243
25594
  const fillColor = extractFillColor(spPr, style);
25244
25595
  const strokeColor = extractStrokeColor(spPr, style);
25245
25596
  const strokeWidth = extractStrokeWidth(spPr);
25597
+ const textBox = wsp.elements?.find((el) => el.name === "wps:txbx");
25598
+ const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
25599
+ const bodyPr = wsp.elements?.find((el) => el.name === "wps:bodyPr");
25600
+ let textContent = null;
25601
+ let textAlign = "left";
25602
+ if (textBoxContent) {
25603
+ textContent = extractTextFromTextBox(textBoxContent, bodyPr);
25604
+ textAlign = textContent?.horizontalAlign || "left";
25605
+ }
25246
25606
  return {
25247
25607
  type: "vectorShape",
25248
25608
  attrs: {
@@ -25254,7 +25614,16 @@ function getVectorShape({ params, graphicData }) {
25254
25614
  flipV,
25255
25615
  fillColor,
25256
25616
  strokeColor,
25257
- strokeWidth
25617
+ strokeWidth,
25618
+ marginOffset,
25619
+ anchorData,
25620
+ wrap: wrap2,
25621
+ isAnchor,
25622
+ textContent,
25623
+ textAlign,
25624
+ textVerticalAlign: textContent?.verticalAlign,
25625
+ textInsets: textContent?.insets,
25626
+ originalAttributes: node?.attributes
25258
25627
  }
25259
25628
  };
25260
25629
  }
@@ -27606,9 +27975,11 @@ function updateNumberingProperties(newNumberingProperties, paragraphNode, pos, e
27606
27975
  const newAttrs = {
27607
27976
  ...paragraphNode.attrs,
27608
27977
  paragraphProperties: newProperties,
27609
- numberingProperties: newProperties.numberingProperties,
27610
- listRendering: null
27978
+ numberingProperties: newProperties.numberingProperties
27611
27979
  };
27980
+ if (!newNumberingProperties) {
27981
+ newAttrs.listRendering = null;
27982
+ }
27612
27983
  tr.setNodeMarkup(pos, null, newAttrs);
27613
27984
  }
27614
27985
  const generateNewListDefinition = ({ numId, listType, level, start, text, fmt, editor }) => {
@@ -28140,13 +28511,36 @@ const handleDocxPaste = (html, editor, view) => {
28140
28511
  extractAndRemoveConditionalPrefix(item);
28141
28512
  });
28142
28513
  transformWordLists(tempDiv, editor);
28143
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(tempDiv);
28514
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(tempDiv);
28515
+ doc2 = wrapTextsInRuns(doc2);
28144
28516
  tempDiv.remove();
28145
28517
  const { dispatch } = editor.view;
28146
28518
  if (!dispatch) return false;
28147
28519
  dispatch(view.state.tr.replaceSelectionWith(doc2, true));
28148
28520
  return true;
28149
28521
  };
28522
+ const wrapTextsInRuns = (doc2) => {
28523
+ const runType = doc2.type?.schema?.nodes?.run;
28524
+ if (!runType) return doc2;
28525
+ const wrapNode = (node, parent) => {
28526
+ if (node.isText) {
28527
+ if (parent?.type?.name === "run") return node;
28528
+ const runProperties = decodeRPrFromMarks(node.marks);
28529
+ return runType.create({ runProperties }, [node]);
28530
+ }
28531
+ if (!node.childCount) return node;
28532
+ let changed = false;
28533
+ const wrappedChildren = [];
28534
+ node.forEach((child) => {
28535
+ const wrappedChild = wrapNode(child, node);
28536
+ if (wrappedChild !== child) changed = true;
28537
+ wrappedChildren.push(wrappedChild);
28538
+ });
28539
+ if (!changed) return node;
28540
+ return node.copy(Fragment.fromArray(wrappedChildren));
28541
+ };
28542
+ return wrapNode(doc2, null);
28543
+ };
28150
28544
  const transformWordLists = (container, editor) => {
28151
28545
  const listItems = Array.from(container.querySelectorAll("[data-num-id]"));
28152
28546
  const lists = {};
@@ -28576,7 +28970,8 @@ const handleGoogleDocsHtml = (html, editor, view) => {
28576
28970
  tempDiv.innerHTML = cleanedHtml;
28577
28971
  const htmlWithMergedLists = mergeSeparateLists(tempDiv);
28578
28972
  const flattenHtml = flattenListsInHtml(htmlWithMergedLists, editor);
28579
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(flattenHtml);
28973
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(flattenHtml);
28974
+ doc2 = wrapTextsInRuns(doc2);
28580
28975
  tempDiv.remove();
28581
28976
  const { dispatch } = editor.view;
28582
28977
  if (!dispatch) return false;
@@ -28909,7 +29304,8 @@ function isGoogleDocsHtml(html) {
28909
29304
  function handleHtmlPaste(html, editor, source) {
28910
29305
  let cleanedHtml;
28911
29306
  cleanedHtml = htmlHandler(html, editor);
28912
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
29307
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
29308
+ doc2 = wrapTextsInRuns(doc2);
28913
29309
  const { dispatch, state: state2 } = editor.view;
28914
29310
  if (!dispatch) return false;
28915
29311
  const { $from } = state2.selection;
@@ -29014,7 +29410,9 @@ function createDocFromHTML(content, editor, options = {}) {
29014
29410
  } else {
29015
29411
  parsedContent = content;
29016
29412
  }
29017
- return DOMParser$1.fromSchema(editor.schema).parse(parsedContent);
29413
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(parsedContent);
29414
+ doc2 = wrapTextsInRuns(doc2);
29415
+ return doc2;
29018
29416
  }
29019
29417
  function L() {
29020
29418
  return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
@@ -30138,9 +30536,11 @@ function processContent({ content, type: type2, editor }) {
30138
30536
  para.textContent = content;
30139
30537
  wrapper.appendChild(para);
30140
30538
  doc2 = DOMParser$1.fromSchema(editor.schema).parse(wrapper);
30539
+ doc2 = wrapTextsInRuns(doc2);
30141
30540
  break;
30142
30541
  case "schema":
30143
30542
  doc2 = editor.schema.nodeFromJSON(content);
30543
+ doc2 = wrapTextsInRuns(doc2);
30144
30544
  break;
30145
30545
  default:
30146
30546
  throw new Error(`Unknown content type: ${type2}`);
@@ -30531,12 +30931,13 @@ function translateShapeGroup(params) {
30531
30931
  function translateAnchorNode(params) {
30532
30932
  const { attrs } = params.node;
30533
30933
  const anchorElements = [];
30534
- if (attrs.simplePos) {
30934
+ const hasSimplePos = attrs.simplePos || attrs.originalAttributes?.simplePos;
30935
+ if (hasSimplePos) {
30535
30936
  anchorElements.push({
30536
30937
  name: "wp:simplePos",
30537
30938
  attributes: {
30538
- x: 0,
30539
- y: 0
30939
+ x: attrs.simplePos?.x ?? 0,
30940
+ y: attrs.simplePos?.y ?? 0
30540
30941
  }
30541
30942
  });
30542
30943
  }
@@ -30588,8 +30989,8 @@ function translateAnchorNode(params) {
30588
30989
  }
30589
30990
  if (attrs.originalAttributes?.simplePos !== void 0) {
30590
30991
  inlineAttrs.simplePos = attrs.originalAttributes.simplePos;
30591
- } else if (attrs.simplePos !== void 0) {
30592
- inlineAttrs.simplePos = attrs.simplePos;
30992
+ } else if (hasSimplePos) {
30993
+ inlineAttrs.simplePos = "1";
30593
30994
  }
30594
30995
  if (attrs.originalAttributes?.locked !== void 0) {
30595
30996
  inlineAttrs.locked = attrs.originalAttributes.locked;
@@ -31148,16 +31549,24 @@ function translateFieldAnnotation(params) {
31148
31549
  hash: attrs.hash
31149
31550
  };
31150
31551
  const annotationAttrsJson = JSON.stringify(annotationAttrs);
31552
+ const sdtPrElements = [
31553
+ { name: "w:alias", attributes: { "w:val": attrs.displayLabel } },
31554
+ { name: "w:tag", attributes: { "w:val": annotationAttrsJson } },
31555
+ { name: "w:id", attributes: { "w:val": id } }
31556
+ ];
31557
+ if (attrs.sdtPr?.elements && Array.isArray(attrs.sdtPr.elements)) {
31558
+ const elementsToExclude = ["w:alias", "w:tag", "w:id"];
31559
+ const passthroughElements = attrs.sdtPr.elements.filter(
31560
+ (el) => el && el.name && !elementsToExclude.includes(el.name)
31561
+ );
31562
+ sdtPrElements.push(...passthroughElements);
31563
+ }
31151
31564
  const result = {
31152
31565
  name: "w:sdt",
31153
31566
  elements: [
31154
31567
  {
31155
31568
  name: "w:sdtPr",
31156
- elements: [
31157
- { name: "w:alias", attributes: { "w:val": attrs.displayLabel } },
31158
- { name: "w:tag", attributes: { "w:val": annotationAttrsJson } },
31159
- { name: "w:id", attributes: { "w:val": id } }
31160
- ]
31569
+ elements: sdtPrElements
31161
31570
  },
31162
31571
  {
31163
31572
  name: "w:sdtContent",
@@ -31389,7 +31798,7 @@ function translateDocumentSection(params) {
31389
31798
  type: "documentSection",
31390
31799
  description: attrs.description
31391
31800
  });
31392
- const sdtPr = generateSdtPrTagForDocumentSection(attrs.id, attrs.title, exportedTag);
31801
+ const sdtPr = generateSdtPrTagForDocumentSection(attrs.id, attrs.title, exportedTag, attrs.sdtPr);
31393
31802
  const { isLocked } = attrs;
31394
31803
  if (isLocked) {
31395
31804
  sdtPr.elements.push({
@@ -31406,73 +31815,115 @@ function translateDocumentSection(params) {
31406
31815
  };
31407
31816
  return result;
31408
31817
  }
31409
- const generateSdtPrTagForDocumentSection = (id, title, tag) => {
31818
+ const generateSdtPrTagForDocumentSection = (id, title, tag, sdtPr) => {
31819
+ const coreElements = [
31820
+ {
31821
+ name: "w:id",
31822
+ attributes: {
31823
+ "w:val": id
31824
+ }
31825
+ },
31826
+ {
31827
+ name: "w:alias",
31828
+ attributes: {
31829
+ "w:val": title
31830
+ }
31831
+ },
31832
+ {
31833
+ name: "w:tag",
31834
+ attributes: {
31835
+ "w:val": tag
31836
+ }
31837
+ }
31838
+ ];
31839
+ if (sdtPr?.elements && Array.isArray(sdtPr.elements)) {
31840
+ const elementsToExclude = ["w:id", "w:alias", "w:tag", "w:lock"];
31841
+ const passthroughElements = sdtPr.elements.filter((el) => el && el.name && !elementsToExclude.includes(el.name));
31842
+ coreElements.push(...passthroughElements);
31843
+ }
31410
31844
  return {
31411
31845
  name: "w:sdtPr",
31412
- elements: [
31413
- {
31414
- name: "w:id",
31415
- attributes: {
31416
- "w:val": id
31417
- }
31418
- },
31419
- {
31420
- name: "w:alias",
31421
- attributes: {
31422
- "w:val": title
31423
- }
31424
- },
31425
- {
31426
- name: "w:tag",
31427
- attributes: {
31428
- "w:val": tag
31429
- }
31430
- }
31431
- ]
31846
+ elements: coreElements
31432
31847
  };
31433
31848
  };
31434
31849
  function translateDocumentPartObj(params) {
31435
31850
  const { node } = params;
31436
31851
  const { attrs = {} } = node;
31437
31852
  const childContent = translateChildNodes({ ...params, nodes: node.content });
31853
+ const sdtPr = generateSdtPrForDocPartObj(attrs);
31438
31854
  const nodeElements = [
31855
+ sdtPr,
31439
31856
  {
31857
+ name: "w:sdtContent",
31858
+ elements: childContent
31859
+ }
31860
+ ];
31861
+ const result = {
31862
+ name: "w:sdt",
31863
+ elements: nodeElements
31864
+ };
31865
+ return result;
31866
+ }
31867
+ function generateSdtPrForDocPartObj(attrs) {
31868
+ const existingDocPartObj = attrs.sdtPr?.elements?.find((el) => el.name === "w:docPartObj");
31869
+ const existingDocPartGallery = existingDocPartObj?.elements?.find((el) => el.name === "w:docPartGallery")?.attributes?.["w:val"];
31870
+ const docPartGallery = attrs.docPartGallery ?? existingDocPartGallery ?? null;
31871
+ const id = attrs.id ?? attrs.sdtPr?.elements?.find((el) => el.name === "w:id")?.attributes?.["w:val"] ?? "";
31872
+ const docPartUnique = attrs.docPartUnique ?? existingDocPartObj?.elements?.some((el) => el.name === "w:docPartUnique") ?? false;
31873
+ if (docPartGallery === null) {
31874
+ if (attrs.sdtPr) {
31875
+ return attrs.sdtPr;
31876
+ }
31877
+ return {
31440
31878
  name: "w:sdtPr",
31441
31879
  elements: [
31442
31880
  {
31443
31881
  name: "w:id",
31444
31882
  attributes: {
31445
- "w:val": attrs.id
31883
+ "w:val": id
31446
31884
  }
31447
31885
  },
31448
31886
  {
31449
31887
  name: "w:docPartObj",
31450
- elements: [
31451
- {
31452
- name: "w:docPartGallery",
31453
- attributes: {
31454
- "w:val": attrs.docPartGallery
31455
- }
31456
- },
31457
- ...attrs.docPartUnique ? [
31458
- {
31459
- name: "w:docPartUnique"
31460
- }
31461
- ] : []
31462
- ]
31888
+ elements: []
31463
31889
  }
31464
31890
  ]
31891
+ };
31892
+ }
31893
+ const docPartObjElements = [
31894
+ {
31895
+ name: "w:docPartGallery",
31896
+ attributes: {
31897
+ "w:val": docPartGallery
31898
+ }
31899
+ }
31900
+ ];
31901
+ if (docPartUnique) {
31902
+ docPartObjElements.push({ name: "w:docPartUnique" });
31903
+ }
31904
+ const sdtPrElements = [
31905
+ {
31906
+ name: "w:id",
31907
+ attributes: {
31908
+ "w:val": id
31909
+ }
31465
31910
  },
31466
31911
  {
31467
- name: "w:sdtContent",
31468
- elements: childContent
31912
+ name: "w:docPartObj",
31913
+ elements: docPartObjElements
31469
31914
  }
31470
31915
  ];
31471
- const result = {
31472
- name: "w:sdt",
31473
- elements: nodeElements
31916
+ if (attrs.sdtPr?.elements && Array.isArray(attrs.sdtPr.elements)) {
31917
+ const elementsToExclude = ["w:id", "w:docPartObj"];
31918
+ const passthroughElements = attrs.sdtPr.elements.filter(
31919
+ (el) => el && el.name && !elementsToExclude.includes(el.name)
31920
+ );
31921
+ sdtPrElements.push(...passthroughElements);
31922
+ }
31923
+ return {
31924
+ name: "w:sdtPr",
31925
+ elements: sdtPrElements
31474
31926
  };
31475
- return result;
31476
31927
  }
31477
31928
  const RUN_LEVEL_WRAPPERS = /* @__PURE__ */ new Set(["w:hyperlink", "w:ins", "w:del"]);
31478
31929
  function convertSdtContentToRuns(elements) {
@@ -32379,15 +32830,26 @@ const getCommentSchema = (type2, commentIndex) => {
32379
32830
  }
32380
32831
  };
32381
32832
  };
32382
- const getConfig = (type2) => ({
32383
- xmlName: `${XML_NODE_NAME$7}${type2}`,
32384
- sdNodeOrKeyName: `${SD_NODE_NAME$6}${type2}`,
32385
- type: NodeTranslator.translatorTypes.NODE,
32386
- encode: () => {
32387
- },
32388
- decode: decode$7,
32389
- attributes: [attrConfig]
32390
- });
32833
+ const getConfig = (type2) => {
32834
+ const sdName = `${SD_NODE_NAME$6}${type2}`;
32835
+ const isStart = type2 === "Start";
32836
+ return {
32837
+ xmlName: `${XML_NODE_NAME$7}${type2}`,
32838
+ sdNodeOrKeyName: sdName,
32839
+ type: NodeTranslator.translatorTypes.NODE,
32840
+ encode: ({ nodes }) => {
32841
+ const node = nodes?.[0];
32842
+ if (!node) return void 0;
32843
+ const attrs = node.attributes ? { ...node.attributes } : {};
32844
+ return {
32845
+ type: isStart ? "commentRangeStart" : "commentRangeEnd",
32846
+ attrs
32847
+ };
32848
+ },
32849
+ decode: decode$7,
32850
+ attributes: [attrConfig]
32851
+ };
32852
+ };
32391
32853
  const commentRangeStartTranslator = NodeTranslator.from(getConfig("Start"));
32392
32854
  const commentRangeEndTranslator = NodeTranslator.from(getConfig("End"));
32393
32855
  const XML_NODE_NAME$6 = "sd:pageReference";
@@ -33111,127 +33573,224 @@ const sdtNodeHandlerEntity = {
33111
33573
  handlerName: "sdtNodeHandler",
33112
33574
  handler: handleSdtNode
33113
33575
  };
33114
- function parseProperties(node) {
33115
- const marks = [];
33116
- const unknownMarks = [];
33117
- const { attributes = {}, elements = [] } = node;
33118
- const { nodes, paragraphProperties = {}, runProperties = {} } = splitElementsAndProperties(elements);
33119
- const hasRun = elements.find((element) => element.name === "w:r");
33120
- if (hasRun) paragraphProperties.elements = paragraphProperties?.elements?.filter((el) => el.name !== "w:rPr");
33121
- if (runProperties && runProperties?.elements?.length) {
33122
- marks.push(...parseMarks(runProperties, unknownMarks));
33123
- }
33124
- if (paragraphProperties && paragraphProperties.elements?.length) {
33125
- const disallowedParagraphProperties = ["w:u"];
33126
- const filteredParagraphProperties = {
33127
- ...paragraphProperties,
33128
- elements: paragraphProperties.elements?.filter((el) => !disallowedParagraphProperties.includes(el.name))
33129
- };
33130
- marks.push(...parseMarks(filteredParagraphProperties, unknownMarks));
33131
- }
33132
- marks.push(...handleStyleChangeMarks(runProperties, marks));
33133
- if (paragraphProperties && paragraphProperties.elements?.length) {
33134
- attributes["paragraphProperties"] = paragraphProperties;
33576
+ const translatorList = Array.from(
33577
+ /* @__PURE__ */ new Set([
33578
+ translator$1M,
33579
+ translator$6,
33580
+ translator$5,
33581
+ translator$4,
33582
+ translator$3,
33583
+ translator$1L,
33584
+ translator$1K,
33585
+ translator$1J,
33586
+ translator$20,
33587
+ translator$1r,
33588
+ translator$1$,
33589
+ translator$q,
33590
+ translator$7,
33591
+ translator$8,
33592
+ translator$1p,
33593
+ translator$23,
33594
+ translator$F,
33595
+ translator$1R,
33596
+ translator$1H,
33597
+ translator$1W,
33598
+ translator$1G,
33599
+ translator$2,
33600
+ translator$1F,
33601
+ translator$s,
33602
+ translator$1X,
33603
+ translator$X,
33604
+ translator$1E,
33605
+ translator$E,
33606
+ translator$D,
33607
+ translator$b,
33608
+ translator$Z,
33609
+ translator$J,
33610
+ translator$I,
33611
+ translator$C,
33612
+ translator$K,
33613
+ translator$22,
33614
+ translator$10,
33615
+ translator$1_,
33616
+ translator$1x,
33617
+ translator$1D,
33618
+ translator$1w,
33619
+ translator$V,
33620
+ translator$U,
33621
+ translator$1C,
33622
+ translator$1B,
33623
+ translator$1A,
33624
+ translator$1z,
33625
+ translator$1P,
33626
+ translator$1n,
33627
+ translator$1y,
33628
+ translator$O,
33629
+ translator$1v,
33630
+ translator$1u,
33631
+ translator$1t,
33632
+ translator$1s,
33633
+ translator$11,
33634
+ translator$1f,
33635
+ translator$1h,
33636
+ translator$12,
33637
+ translator$1g,
33638
+ translator$$,
33639
+ translator$1V,
33640
+ translator$1N,
33641
+ translator$1U,
33642
+ translator$1l,
33643
+ translator$r,
33644
+ translator$1Q,
33645
+ translator$1e,
33646
+ translator$1d,
33647
+ translator$1c,
33648
+ translator$1b,
33649
+ translator$1a,
33650
+ translator$T,
33651
+ translator$1Y,
33652
+ translator$1T,
33653
+ translator$1S,
33654
+ translator$1,
33655
+ translator$21,
33656
+ translator$19,
33657
+ translator$9,
33658
+ translator$e,
33659
+ translator$p,
33660
+ translator$d,
33661
+ translator$B,
33662
+ translator$o,
33663
+ translator$a,
33664
+ translator$A,
33665
+ translator$n,
33666
+ translator$m,
33667
+ translator$l,
33668
+ translator$k,
33669
+ translator$c,
33670
+ translator$j,
33671
+ translator$i,
33672
+ translator$h,
33673
+ translator$g,
33674
+ translator$f,
33675
+ translator$G,
33676
+ translator$P,
33677
+ translator$M,
33678
+ translator$N,
33679
+ translator$H,
33680
+ translator$_,
33681
+ translator$17,
33682
+ translator$R,
33683
+ translator$v,
33684
+ translator$Q,
33685
+ translator$z,
33686
+ translator$w,
33687
+ translator$18,
33688
+ translator$16,
33689
+ translator$15,
33690
+ translator$1j,
33691
+ translator$1Z,
33692
+ translator$L,
33693
+ translator$Y,
33694
+ translator$y,
33695
+ translator$x,
33696
+ translator$14,
33697
+ translator$13,
33698
+ translator$u,
33699
+ translator$t,
33700
+ commentRangeStartTranslator,
33701
+ commentRangeEndTranslator
33702
+ ])
33703
+ );
33704
+ const additionalHandlers = Object.freeze(
33705
+ translatorList.reduce((acc, translator2) => {
33706
+ const key = translator2?.xmlName;
33707
+ if (!key) return acc;
33708
+ acc[key] = translator2;
33709
+ return acc;
33710
+ }, {})
33711
+ );
33712
+ const baseHandlers = {
33713
+ ...additionalHandlers
33714
+ };
33715
+ const registeredHandlers = Object.freeze(baseHandlers);
33716
+ const INLINE_PARENT_NAMES = /* @__PURE__ */ new Set([
33717
+ "w:r",
33718
+ "w:hyperlink",
33719
+ "w:smartTag",
33720
+ "w:fldSimple",
33721
+ "w:proofErr",
33722
+ "w:del",
33723
+ "w:ins"
33724
+ ]);
33725
+ const INLINE_NODE_NAMES = /* @__PURE__ */ new Set([
33726
+ "m:oMathPara",
33727
+ "m:oMath",
33728
+ "m:t",
33729
+ "m:r",
33730
+ "m:ctrlPr",
33731
+ "m:sSupPr",
33732
+ "m:e",
33733
+ "m:sup",
33734
+ "m:sSup"
33735
+ ]);
33736
+ const BLOCK_BOUNDARY_NAMES = /* @__PURE__ */ new Set(["w:p", "w:body", "w:tbl", "w:tc", "w:tr"]);
33737
+ const isInlineContext = (path = [], currentNodeName) => {
33738
+ if (currentNodeName && INLINE_NODE_NAMES.has(currentNodeName)) {
33739
+ return true;
33135
33740
  }
33136
- if (marks && node.name === "w:p") {
33137
- marks.forEach((mark) => {
33138
- const attrValue = Object.keys(mark.attrs ?? {})[0];
33139
- if (attrValue) {
33140
- const value = mark.attrs[attrValue];
33141
- attributes[attrValue] = value;
33142
- }
33143
- });
33741
+ if (!Array.isArray(path) || path.length === 0) return false;
33742
+ for (let i = path.length - 1; i >= 0; i--) {
33743
+ const ancestorName = path[i]?.name;
33744
+ if (!ancestorName) continue;
33745
+ if (INLINE_NODE_NAMES.has(ancestorName) || INLINE_PARENT_NAMES.has(ancestorName)) {
33746
+ return true;
33747
+ }
33748
+ if (BLOCK_BOUNDARY_NAMES.has(ancestorName)) {
33749
+ return false;
33750
+ }
33144
33751
  }
33145
- return { elements: nodes, attributes, marks, unknownMarks };
33146
- }
33147
- function splitElementsAndProperties(elements) {
33148
- const pPr = elements.find((el) => el.name === "w:pPr");
33149
- const rPr = elements.find((el) => el.name === "w:rPr");
33150
- const sectPr = elements.find((el) => el.name === "w:sectPr");
33151
- const els = elements.filter((el) => el.name !== "w:pPr" && el.name !== "w:rPr" && el.name !== "w:sectPr");
33152
- return {
33153
- nodes: els,
33154
- paragraphProperties: pPr,
33155
- runProperties: rPr,
33156
- sectionProperties: sectPr
33157
- };
33158
- }
33159
- function getElementName(element) {
33160
- return SuperConverter.allowedElements[element.name || element.type];
33161
- }
33162
- const isPropertiesElement = (element) => {
33163
- return !!SuperConverter.propertyTypes[element.name || element.type];
33752
+ return false;
33164
33753
  };
33165
- const handleStandardNode = (params) => {
33166
- const { nodes, docx, nodeListHandler } = params;
33167
- if (!nodes || nodes.length === 0) {
33168
- return { nodes: [], consumed: 0 };
33169
- }
33754
+ const handlePassthroughNode = (params) => {
33755
+ const { nodes = [] } = params;
33170
33756
  const node = nodes[0];
33171
- const { name } = node;
33172
- const { attributes, elements, marks = [] } = parseProperties(node);
33173
- if (name === "w:sdt") {
33757
+ if (!node) return { nodes: [], consumed: 0 };
33758
+ if (registeredHandlers[node.name] || node.name === "w:commentReference") {
33174
33759
  return { nodes: [], consumed: 0 };
33175
33760
  }
33176
- if (isPropertiesElement(node)) {
33177
- return {
33178
- nodes: [
33179
- {
33180
- type: getElementName(node),
33181
- attrs: { ...attributes },
33182
- marks: []
33183
- }
33184
- ],
33185
- consumed: 0
33186
- };
33187
- }
33188
- if (!getElementName(node)) {
33189
- return {
33190
- nodes: [
33191
- {
33192
- type: name,
33193
- content: elements,
33194
- attrs: { ...attributes },
33195
- marks
33196
- }
33197
- ],
33198
- consumed: 0,
33199
- unhandled: true
33200
- };
33201
- }
33202
- const content = [];
33203
- const parentStyleId = getParentStyleId(node);
33204
- if (elements && elements.length) {
33205
- const updatedElements = elements.map((el) => {
33206
- if (!el.marks) el.marks = [];
33207
- el.marks.push(...marks);
33208
- return el;
33209
- });
33761
+ const originalXml = carbonCopy(node) || {};
33762
+ const originalElementsSource = originalXml.elements;
33763
+ const originalElements = originalElementsSource ? carbonCopy(originalElementsSource) : [];
33764
+ const childElements = Array.isArray(node.elements) ? node.elements : [];
33765
+ let childContent = [];
33766
+ if (childElements.length && params.nodeListHandler?.handler) {
33210
33767
  const childParams = {
33211
33768
  ...params,
33212
- nodes: updatedElements,
33213
- parentStyleId,
33769
+ nodes: childElements,
33214
33770
  path: [...params.path || [], node]
33215
33771
  };
33216
- const childContent = nodeListHandler.handler(childParams);
33217
- content.push(...childContent);
33772
+ childContent = params.nodeListHandler.handler(childParams) || [];
33218
33773
  }
33219
- const resultNode = {
33220
- type: getElementName(node),
33221
- content,
33222
- attrs: { ...attributes },
33223
- marks: []
33774
+ if (originalElements?.length) {
33775
+ originalXml.elements = originalElements;
33776
+ }
33777
+ const passthroughNode = {
33778
+ type: isInlineContext(params.path, node.name) ? "passthroughInline" : "passthroughBlock",
33779
+ attrs: {
33780
+ originalName: node.name,
33781
+ originalXml
33782
+ },
33783
+ marks: [],
33784
+ content: childContent
33785
+ };
33786
+ return {
33787
+ nodes: [passthroughNode],
33788
+ consumed: 1
33224
33789
  };
33225
- return { nodes: [resultNode], consumed: 1 };
33226
- };
33227
- const getParentStyleId = (node) => {
33228
- const pPr = node.elements?.find((el) => el.name === "w:pPr");
33229
- const styleTag = pPr?.elements?.find((el) => el.name === "w:pStyle");
33230
- return styleTag ? styleTag.attributes["w:val"] : null;
33231
33790
  };
33232
- const standardNodeHandlerEntity = {
33233
- handlerName: "standardNodeHandler",
33234
- handler: handleStandardNode
33791
+ const passthroughNodeHandlerEntity = {
33792
+ handlerName: "passthroughNodeHandler",
33793
+ handler: handlePassthroughNode
33235
33794
  };
33236
33795
  const handler = (params) => {
33237
33796
  const { nodes } = params;
@@ -33255,13 +33814,6 @@ const handleBookmarkNode = (params) => {
33255
33814
  return { nodes: [], consumed: 0 };
33256
33815
  }
33257
33816
  const node = nodes[0];
33258
- const handleStandardNode2 = nodeListHandler.handlerEntities.find(
33259
- (e) => e.handlerName === "standardNodeHandler"
33260
- )?.handler;
33261
- if (!handleStandardNode2) {
33262
- console.error("Standard node handler not found");
33263
- return { nodes: [], consumed: 0 };
33264
- }
33265
33817
  const customMarks = editor?.extensionService?.extensions?.filter((e) => e.isExternal === true) || [];
33266
33818
  const bookmarkName = node.attributes["w:name"]?.split(";")[0];
33267
33819
  const customMark = customMarks.find((mark) => mark.name === bookmarkName);
@@ -33270,7 +33822,6 @@ const handleBookmarkNode = (params) => {
33270
33822
  (n) => n.name === "w:bookmarkEnd" && n.attributes["w:id"] === node.attributes["w:id"]
33271
33823
  );
33272
33824
  const textNodes = nodes.slice(1, bookmarkEndIndex);
33273
- const nodeListHandler2 = params.nodeListHandler;
33274
33825
  const attrs = {};
33275
33826
  node.attributes["w:name"].split(";").forEach((name) => {
33276
33827
  const [key, value] = name.split("=");
@@ -33278,7 +33829,7 @@ const handleBookmarkNode = (params) => {
33278
33829
  attrs[key] = value;
33279
33830
  }
33280
33831
  });
33281
- const translatedText = nodeListHandler2.handler({
33832
+ const translatedText = nodeListHandler.handler({
33282
33833
  ...params,
33283
33834
  nodes: textNodes,
33284
33835
  path: [...params.path || [], node]
@@ -33294,13 +33845,11 @@ const handleBookmarkNode = (params) => {
33294
33845
  consumed: translatedText.length + 2
33295
33846
  };
33296
33847
  }
33297
- const updatedParams = { ...params, nodes: [node] };
33298
- const result = handleStandardNode2(updatedParams);
33299
- if (result.nodes.length === 1) {
33300
- result.nodes[0].attrs.name = node.attributes["w:name"];
33301
- result.nodes[0].attrs.id = node.attributes["w:id"];
33848
+ const encoded = translator$8.encode({ ...params, nodes: [node] });
33849
+ if (!encoded) {
33850
+ return { nodes: [], consumed: 0 };
33302
33851
  }
33303
- return result;
33852
+ return { nodes: [encoded], consumed: 1 };
33304
33853
  };
33305
33854
  const handleBookmarkStartNode = (params) => {
33306
33855
  const { nodes } = params;
@@ -33506,7 +34055,11 @@ function importCommentData({ docx, editor, converter }) {
33506
34055
  const generateCommentsWithExtendedData = ({ docx, comments }) => {
33507
34056
  if (!comments?.length) return [];
33508
34057
  const commentsExtended = docx["word/commentsExtended.xml"];
33509
- if (!commentsExtended) return comments.map((comment) => ({ ...comment, isDone: comment.isDone ?? false }));
34058
+ if (!commentsExtended) {
34059
+ const commentRanges = extractCommentRangesFromDocument(docx);
34060
+ const commentsWithThreading = detectThreadingFromRanges(comments, commentRanges);
34061
+ return commentsWithThreading.map((comment) => ({ ...comment, isDone: comment.isDone ?? false }));
34062
+ }
33510
34063
  const { elements: initialElements = [] } = commentsExtended;
33511
34064
  if (!initialElements?.length) return comments.map((comment) => ({ ...comment, isDone: comment.isDone ?? false }));
33512
34065
  const { elements = [] } = initialElements[0] ?? {};
@@ -33532,6 +34085,79 @@ const getExtendedDetails = (commentEx) => {
33532
34085
  const paraIdParent = attributes["w15:paraIdParent"];
33533
34086
  return { paraId, isDone, paraIdParent };
33534
34087
  };
34088
+ const extractCommentRangesFromDocument = (docx) => {
34089
+ const documentXml = docx["word/document.xml"];
34090
+ if (!documentXml) {
34091
+ return [];
34092
+ }
34093
+ const pendingComments = [];
34094
+ const walkElements = (elements) => {
34095
+ if (!elements || !Array.isArray(elements)) return;
34096
+ elements.forEach((element) => {
34097
+ if (element.name === "w:commentRangeStart") {
34098
+ const commentId = element.attributes?.["w:id"];
34099
+ if (commentId !== void 0) {
34100
+ pendingComments.push({
34101
+ type: "start",
34102
+ commentId: String(commentId)
34103
+ });
34104
+ }
34105
+ } else if (element.name === "w:commentRangeEnd") {
34106
+ const commentId = element.attributes?.["w:id"];
34107
+ if (commentId !== void 0) {
34108
+ pendingComments.push({
34109
+ type: "end",
34110
+ commentId: String(commentId)
34111
+ });
34112
+ }
34113
+ }
34114
+ if (element.elements && Array.isArray(element.elements)) {
34115
+ walkElements(element.elements);
34116
+ }
34117
+ });
34118
+ };
34119
+ if (documentXml.elements && documentXml.elements.length > 0) {
34120
+ const body = documentXml.elements[0];
34121
+ if (body.elements) {
34122
+ walkElements(body.elements);
34123
+ }
34124
+ }
34125
+ return pendingComments;
34126
+ };
34127
+ const detectThreadingFromRanges = (comments, rangeEvents) => {
34128
+ if (!rangeEvents || rangeEvents.length === 0) {
34129
+ return comments;
34130
+ }
34131
+ const openRanges = [];
34132
+ const parentMap = /* @__PURE__ */ new Map();
34133
+ rangeEvents.forEach((event) => {
34134
+ if (event.type === "start") {
34135
+ if (openRanges.length > 0) {
34136
+ const parentCommentId = openRanges[openRanges.length - 1];
34137
+ parentMap.set(event.commentId, parentCommentId);
34138
+ }
34139
+ openRanges.push(event.commentId);
34140
+ } else if (event.type === "end") {
34141
+ const index2 = openRanges.lastIndexOf(event.commentId);
34142
+ if (index2 !== -1) {
34143
+ openRanges.splice(index2, 1);
34144
+ }
34145
+ }
34146
+ });
34147
+ return comments.map((comment) => {
34148
+ const parentCommentId = parentMap.get(comment.importedId);
34149
+ if (parentCommentId) {
34150
+ const parentComment = comments.find((c) => c.importedId === parentCommentId);
34151
+ if (parentComment) {
34152
+ return {
34153
+ ...comment,
34154
+ parentCommentId: parentComment.commentId
34155
+ };
34156
+ }
34157
+ }
34158
+ return comment;
34159
+ });
34160
+ };
33535
34161
  const RELATIONSHIP_TYPES = (
33536
34162
  /** @type {const} */
33537
34163
  {
@@ -34222,18 +34848,22 @@ const getInstructionPreProcessor = (instruction) => {
34222
34848
  const preProcessNodesForFldChar = (nodes = [], docx) => {
34223
34849
  const processedNodes = [];
34224
34850
  let collectedNodesStack = [];
34851
+ let rawCollectedNodesStack = [];
34225
34852
  let currentFieldStack = [];
34226
34853
  let unpairedEnd = null;
34227
34854
  let collecting = false;
34228
34855
  const finalizeField = () => {
34229
34856
  if (collecting) {
34230
34857
  const collectedNodes = collectedNodesStack.pop().filter((n) => n !== null);
34858
+ const rawCollectedNodes = rawCollectedNodesStack.pop().filter((n) => n !== null);
34231
34859
  const currentField = currentFieldStack.pop();
34232
- const combined = _processCombinedNodesForFldChar(collectedNodes, currentField.instrText.trim(), docx);
34860
+ const combinedResult = _processCombinedNodesForFldChar(collectedNodes, currentField.instrText.trim(), docx);
34861
+ const outputNodes = combinedResult.handled ? combinedResult.nodes : rawCollectedNodes;
34233
34862
  if (collectedNodesStack.length === 0) {
34234
- processedNodes.push(...combined);
34863
+ processedNodes.push(...outputNodes);
34235
34864
  } else {
34236
- collectedNodesStack[collectedNodesStack.length - 1].push(...combined);
34865
+ collectedNodesStack[collectedNodesStack.length - 1].push(...outputNodes);
34866
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(...outputNodes);
34237
34867
  }
34238
34868
  } else {
34239
34869
  unpairedEnd = true;
@@ -34245,18 +34875,26 @@ const preProcessNodesForFldChar = (nodes = [], docx) => {
34245
34875
  const instrTextEl = node.elements?.find((el) => el.name === "w:instrText");
34246
34876
  collecting = collectedNodesStack.length > 0;
34247
34877
  if (fldType === "begin") {
34248
- collectedNodesStack.push([null]);
34878
+ collectedNodesStack.push([]);
34879
+ rawCollectedNodesStack.push([node]);
34249
34880
  currentFieldStack.push({ instrText: "" });
34250
34881
  continue;
34251
34882
  }
34252
34883
  if (instrTextEl && collecting && currentFieldStack.length > 0) {
34884
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34253
34885
  currentFieldStack[currentFieldStack.length - 1].instrText += (instrTextEl.elements?.[0]?.text || "") + " ";
34254
34886
  continue;
34255
34887
  }
34256
34888
  if (fldType === "end") {
34889
+ if (collecting) {
34890
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34891
+ }
34257
34892
  finalizeField();
34258
34893
  continue;
34259
34894
  } else if (fldType === "separate") {
34895
+ if (collecting) {
34896
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34897
+ }
34260
34898
  continue;
34261
34899
  }
34262
34900
  if (Array.isArray(node.elements)) {
@@ -34266,17 +34904,21 @@ const preProcessNodesForFldChar = (nodes = [], docx) => {
34266
34904
  childResult.unpairedBegin.forEach((pendingField) => {
34267
34905
  currentFieldStack.push(pendingField.fieldInfo);
34268
34906
  collectedNodesStack.push([node]);
34907
+ rawCollectedNodesStack.push([node]);
34269
34908
  });
34270
34909
  } else if (childResult.unpairedEnd) {
34271
34910
  collectedNodesStack[collectedNodesStack.length - 1].push(node);
34911
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34272
34912
  finalizeField();
34273
34913
  } else if (collecting) {
34274
34914
  collectedNodesStack[collectedNodesStack.length - 1].push(node);
34915
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34275
34916
  } else {
34276
34917
  processedNodes.push(node);
34277
34918
  }
34278
34919
  } else if (collecting) {
34279
34920
  collectedNodesStack[collectedNodesStack.length - 1].push(node);
34921
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34280
34922
  } else {
34281
34923
  processedNodes.push(node);
34282
34924
  }
@@ -34298,11 +34940,91 @@ const _processCombinedNodesForFldChar = (nodesToCombine = [], instrText, docx) =
34298
34940
  const instructionType = instrText.trim().split(" ")[0];
34299
34941
  const instructionPreProcessor = getInstructionPreProcessor(instructionType);
34300
34942
  if (instructionPreProcessor) {
34301
- return instructionPreProcessor(nodesToCombine, instrText, docx);
34302
- } else {
34303
- return nodesToCombine;
34943
+ return { nodes: instructionPreProcessor(nodesToCombine, instrText, docx), handled: true };
34944
+ }
34945
+ return { nodes: nodesToCombine, handled: false };
34946
+ };
34947
+ const preProcessPageFieldsOnly = (nodes = []) => {
34948
+ const processedNodes = [];
34949
+ let i = 0;
34950
+ while (i < nodes.length) {
34951
+ const node = nodes[i];
34952
+ const fldCharEl = node.elements?.find((el) => el.name === "w:fldChar");
34953
+ const fldType = fldCharEl?.attributes?.["w:fldCharType"];
34954
+ if (fldType === "begin") {
34955
+ const fieldInfo = scanFieldSequence(nodes, i);
34956
+ if (fieldInfo && (fieldInfo.fieldType === "PAGE" || fieldInfo.fieldType === "NUMPAGES")) {
34957
+ const preprocessor = fieldInfo.fieldType === "PAGE" ? preProcessPageInstruction : preProcessNumPagesInstruction;
34958
+ const contentNodes = fieldInfo.contentNodes;
34959
+ const processedField = preprocessor(contentNodes, fieldInfo.instrText);
34960
+ processedNodes.push(...processedField);
34961
+ i = fieldInfo.endIndex + 1;
34962
+ continue;
34963
+ } else {
34964
+ if (fieldInfo) {
34965
+ for (let j2 = i; j2 <= fieldInfo.endIndex; j2++) {
34966
+ const passNode = nodes[j2];
34967
+ if (Array.isArray(passNode.elements)) {
34968
+ const childResult = preProcessPageFieldsOnly(passNode.elements);
34969
+ passNode.elements = childResult.processedNodes;
34970
+ }
34971
+ processedNodes.push(passNode);
34972
+ }
34973
+ i = fieldInfo.endIndex + 1;
34974
+ continue;
34975
+ }
34976
+ }
34977
+ }
34978
+ if (Array.isArray(node.elements)) {
34979
+ const childResult = preProcessPageFieldsOnly(node.elements);
34980
+ node.elements = childResult.processedNodes;
34981
+ }
34982
+ processedNodes.push(node);
34983
+ i++;
34304
34984
  }
34985
+ return { processedNodes };
34305
34986
  };
34987
+ function scanFieldSequence(nodes, beginIndex) {
34988
+ let instrText = "";
34989
+ let separateIndex = -1;
34990
+ let endIndex = -1;
34991
+ const contentNodes = [];
34992
+ for (let i = beginIndex + 1; i < nodes.length; i++) {
34993
+ const node = nodes[i];
34994
+ const fldCharEl = node.elements?.find((el) => el.name === "w:fldChar");
34995
+ const fldType = fldCharEl?.attributes?.["w:fldCharType"];
34996
+ const instrTextEl = node.elements?.find((el) => el.name === "w:instrText");
34997
+ if (instrTextEl) {
34998
+ instrText += (instrTextEl.elements?.[0]?.text || "") + " ";
34999
+ }
35000
+ if (fldType === "separate") {
35001
+ separateIndex = i;
35002
+ } else if (fldType === "end") {
35003
+ endIndex = i;
35004
+ break;
35005
+ } else if (separateIndex !== -1 && fldType !== "begin") {
35006
+ contentNodes.push(node);
35007
+ }
35008
+ }
35009
+ if (endIndex === -1) {
35010
+ return null;
35011
+ }
35012
+ const fieldType = instrText.trim().split(" ")[0];
35013
+ return {
35014
+ fieldType,
35015
+ instrText: instrText.trim(),
35016
+ contentNodes,
35017
+ endIndex
35018
+ };
35019
+ }
35020
+ const commentRangeStartHandlerEntity = generateV2HandlerEntity(
35021
+ "commentRangeStartHandler",
35022
+ commentRangeStartTranslator
35023
+ );
35024
+ const commentRangeEndHandlerEntity = generateV2HandlerEntity(
35025
+ "commentRangeEndHandler",
35026
+ commentRangeEndTranslator
35027
+ );
34306
35028
  const createDocumentJson = (docx, converter, editor) => {
34307
35029
  const json = carbonCopy(getInitialJSON(docx));
34308
35030
  if (!json) return null;
@@ -34364,6 +35086,7 @@ const createDocumentJson = (docx, converter, editor) => {
34364
35086
  path: []
34365
35087
  });
34366
35088
  parsedContent = filterOutRootInlineNodes(parsedContent);
35089
+ collapseWhitespaceNextToInlinePassthrough(parsedContent);
34367
35090
  const result = {
34368
35091
  type: "doc",
34369
35092
  content: parsedContent,
@@ -34404,6 +35127,8 @@ const defaultNodeListHandler = () => {
34404
35127
  bookmarkStartNodeHandlerEntity,
34405
35128
  bookmarkEndNodeHandlerEntity,
34406
35129
  hyperlinkNodeHandlerEntity,
35130
+ commentRangeStartHandlerEntity,
35131
+ commentRangeEndHandlerEntity,
34407
35132
  drawingNodeHandlerEntity,
34408
35133
  trackChangeNodeHandlerEntity,
34409
35134
  tableNodeHandlerEntity,
@@ -34412,7 +35137,7 @@ const defaultNodeListHandler = () => {
34412
35137
  autoPageHandlerEntity,
34413
35138
  autoTotalPageCountEntity,
34414
35139
  pageReferenceEntity,
34415
- standardNodeHandlerEntity
35140
+ passthroughNodeHandlerEntity
34416
35141
  ];
34417
35142
  const handler2 = createNodeListHandler(entities);
34418
35143
  return {
@@ -34699,6 +35424,8 @@ const importHeadersFooters = (docx, converter, mainEditor) => {
34699
35424
  editor.options.annotations = true;
34700
35425
  headers.forEach((header) => {
34701
35426
  const { rId, referenceFile, currentFileName } = getHeaderFooterSectionData(header, docx);
35427
+ const headerNodes = carbonCopy(referenceFile.elements[0].elements ?? []);
35428
+ const { processedNodes: headerProcessedNodes } = preProcessPageFieldsOnly(headerNodes);
34702
35429
  const sectPrHeader = allSectPrElements.find(
34703
35430
  (el) => el.name === "w:headerReference" && el.attributes["r:id"] === rId
34704
35431
  );
@@ -34706,7 +35433,7 @@ const importHeadersFooters = (docx, converter, mainEditor) => {
34706
35433
  if (converter.headerIds[sectionType]) sectionType = null;
34707
35434
  const nodeListHandler = defaultNodeListHandler();
34708
35435
  let schema = nodeListHandler.handler({
34709
- nodes: referenceFile.elements[0].elements,
35436
+ nodes: headerProcessedNodes,
34710
35437
  nodeListHandler,
34711
35438
  docx,
34712
35439
  converter,
@@ -34727,13 +35454,15 @@ const importHeadersFooters = (docx, converter, mainEditor) => {
34727
35454
  if (titlePg) converter.headerIds.titlePg = true;
34728
35455
  footers.forEach((footer) => {
34729
35456
  const { rId, referenceFile, currentFileName } = getHeaderFooterSectionData(footer, docx);
35457
+ const footerNodes = carbonCopy(referenceFile.elements[0].elements ?? []);
35458
+ const { processedNodes: footerProcessedNodes } = preProcessPageFieldsOnly(footerNodes);
34730
35459
  const sectPrFooter = allSectPrElements.find(
34731
35460
  (el) => el.name === "w:footerReference" && el.attributes["r:id"] === rId
34732
35461
  );
34733
35462
  const sectionType = sectPrFooter?.attributes["w:type"];
34734
35463
  const nodeListHandler = defaultNodeListHandler();
34735
35464
  let schema = nodeListHandler.handler({
34736
- nodes: referenceFile.elements[0].elements,
35465
+ nodes: footerProcessedNodes,
34737
35466
  nodeListHandler,
34738
35467
  docx,
34739
35468
  converter,
@@ -34796,6 +35525,51 @@ function filterOutRootInlineNodes(content = []) {
34796
35525
  ]);
34797
35526
  return content.filter((node) => node && typeof node.type === "string" && !INLINE_TYPES.has(node.type));
34798
35527
  }
35528
+ function collapseWhitespaceNextToInlinePassthrough(content = []) {
35529
+ if (!Array.isArray(content) || content.length === 0) return;
35530
+ const sequence = collectInlineSequence(content);
35531
+ sequence.forEach((entry, index2) => {
35532
+ if (entry.kind !== "passthrough") return;
35533
+ const prev = findNeighborText(sequence, index2, -1);
35534
+ const next = findNeighborText(sequence, index2, 1);
35535
+ if (!prev || !next) return;
35536
+ if (!prev.node.text.endsWith(" ") || !next.node.text.startsWith(" ")) return;
35537
+ prev.node.text = prev.node.text.replace(/ +$/, " ");
35538
+ next.node.text = next.node.text.replace(/^ +/, "");
35539
+ if (next.node.text.length === 0) {
35540
+ next.parent.splice(next.index, 1);
35541
+ }
35542
+ });
35543
+ }
35544
+ function collectInlineSequence(nodes, result = [], insidePassthrough = false) {
35545
+ if (!Array.isArray(nodes) || nodes.length === 0) return result;
35546
+ nodes.forEach((node, index2) => {
35547
+ if (!node) return;
35548
+ const isPassthrough = node.type === "passthroughInline";
35549
+ if (isPassthrough && !insidePassthrough) {
35550
+ result.push({ kind: "passthrough", parent: nodes, index: index2 });
35551
+ }
35552
+ if (node.type === "text" && typeof node.text === "string" && !insidePassthrough) {
35553
+ result.push({ kind: "text", node, parent: nodes, index: index2 });
35554
+ }
35555
+ if (Array.isArray(node.content) && node.content.length) {
35556
+ const nextInside = insidePassthrough || isPassthrough;
35557
+ collectInlineSequence(node.content, result, nextInside);
35558
+ }
35559
+ });
35560
+ return result;
35561
+ }
35562
+ function findNeighborText(sequence, startIndex, direction) {
35563
+ let cursor = startIndex + direction;
35564
+ while (cursor >= 0 && cursor < sequence.length) {
35565
+ const entry = sequence[cursor];
35566
+ if (entry.kind === "text") {
35567
+ return entry;
35568
+ }
35569
+ cursor += direction;
35570
+ }
35571
+ return null;
35572
+ }
34799
35573
  function getThemeColorPalette(docx) {
34800
35574
  const themePart = docx?.["word/theme/theme1.xml"];
34801
35575
  if (!themePart || !Array.isArray(themePart.elements)) return void 0;
@@ -35158,7 +35932,9 @@ function exportSchemaToJson(params) {
35158
35932
  "page-number": translator$4,
35159
35933
  "total-page-number": translator$3,
35160
35934
  pageReference: translator$6,
35161
- tableOfContents: translator$5
35935
+ tableOfContents: translator$5,
35936
+ passthroughBlock: translatePassthroughNode,
35937
+ passthroughInline: translatePassthroughNode
35162
35938
  };
35163
35939
  let handler2 = router[type2];
35164
35940
  if (handler2 && "decode" in handler2 && typeof handler2.decode === "function") {
@@ -35170,6 +35946,11 @@ function exportSchemaToJson(params) {
35170
35946
  }
35171
35947
  return handler2(params);
35172
35948
  }
35949
+ function translatePassthroughNode(params) {
35950
+ const original = params?.node?.attrs?.originalXml;
35951
+ if (!original) return null;
35952
+ return carbonCopy(original);
35953
+ }
35173
35954
  function translateBodyNode(params) {
35174
35955
  let sectPr = params.bodyNode?.elements?.find((n) => n.name === "w:sectPr");
35175
35956
  if (!sectPr) {
@@ -35492,10 +36273,12 @@ const toIsoNoFractional = (unixMillis) => {
35492
36273
  const updateCommentsXml = (commentDefs = [], commentsXml) => {
35493
36274
  const newCommentsXml = carbonCopy(commentsXml);
35494
36275
  commentDefs.forEach((commentDef) => {
35495
- const elements = commentDef.elements[0].elements;
36276
+ const paraNode = commentDef.elements[0];
36277
+ if (!paraNode.attributes) paraNode.attributes = {};
36278
+ const elements = paraNode.elements;
35496
36279
  elements.unshift(COMMENT_REF);
35497
36280
  const paraId = commentDef.attributes["w15:paraId"];
35498
- commentDef.elements[0].attributes["w14:paraId"] = paraId;
36281
+ paraNode.attributes["w14:paraId"] = paraId;
35499
36282
  commentDef.attributes = {
35500
36283
  "w:id": commentDef.attributes["w:id"],
35501
36284
  "w:author": commentDef.attributes["w:author"],
@@ -35869,7 +36652,7 @@ const _SuperConverter = class _SuperConverter {
35869
36652
  static getStoredSuperdocVersion(docx) {
35870
36653
  return _SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
35871
36654
  }
35872
- static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.0.0-beta.13") {
36655
+ static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.0.0-beta.19") {
35873
36656
  return _SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
35874
36657
  }
35875
36658
  /**
@@ -36210,6 +36993,112 @@ const _SuperConverter = class _SuperConverter {
36210
36993
  });
36211
36994
  return { result, params };
36212
36995
  }
36996
+ /**
36997
+ * Creates a default empty header for the specified variant.
36998
+ *
36999
+ * This method programmatically creates a new header section with an empty ProseMirror
37000
+ * document. The header is added to the converter's data structures and will be included
37001
+ * in subsequent DOCX exports.
37002
+ *
37003
+ * @param {('default' | 'first' | 'even' | 'odd')} variant - The header variant to create
37004
+ * @returns {string} The relationship ID of the created header
37005
+ *
37006
+ * @throws {Error} If variant is invalid or header already exists for this variant
37007
+ *
37008
+ * @example
37009
+ * ```javascript
37010
+ * const headerId = converter.createDefaultHeader('default');
37011
+ * // headerId: 'rId-header-default'
37012
+ * // converter.headers['rId-header-default'] contains empty PM doc
37013
+ * // converter.headerIds.default === 'rId-header-default'
37014
+ * ```
37015
+ */
37016
+ createDefaultHeader(variant = "default") {
37017
+ if (typeof variant !== "string") {
37018
+ throw new TypeError(`variant must be a string, received ${typeof variant}`);
37019
+ }
37020
+ const validVariants = ["default", "first", "even", "odd"];
37021
+ if (!validVariants.includes(variant)) {
37022
+ throw new Error(`Invalid header variant: ${variant}. Must be one of: ${validVariants.join(", ")}`);
37023
+ }
37024
+ if (this.headerIds[variant]) {
37025
+ console.warn(`[SuperConverter] Header already exists for variant '${variant}': ${this.headerIds[variant]}`);
37026
+ return this.headerIds[variant];
37027
+ }
37028
+ const rId = `rId-header-${variant}`;
37029
+ const emptyDoc = {
37030
+ type: "doc",
37031
+ content: [
37032
+ {
37033
+ type: "paragraph",
37034
+ content: []
37035
+ }
37036
+ ]
37037
+ };
37038
+ this.headers[rId] = emptyDoc;
37039
+ this.headerIds[variant] = rId;
37040
+ if (!this.headerIds.ids) {
37041
+ this.headerIds.ids = [];
37042
+ }
37043
+ if (!this.headerIds.ids.includes(rId)) {
37044
+ this.headerIds.ids.push(rId);
37045
+ }
37046
+ this.documentModified = true;
37047
+ return rId;
37048
+ }
37049
+ /**
37050
+ * Creates a default empty footer for the specified variant.
37051
+ *
37052
+ * This method programmatically creates a new footer section with an empty ProseMirror
37053
+ * document. The footer is added to the converter's data structures and will be included
37054
+ * in subsequent DOCX exports.
37055
+ *
37056
+ * @param {('default' | 'first' | 'even' | 'odd')} variant - The footer variant to create
37057
+ * @returns {string} The relationship ID of the created footer
37058
+ *
37059
+ * @throws {Error} If variant is invalid or footer already exists for this variant
37060
+ *
37061
+ * @example
37062
+ * ```javascript
37063
+ * const footerId = converter.createDefaultFooter('default');
37064
+ * // footerId: 'rId-footer-default'
37065
+ * // converter.footers['rId-footer-default'] contains empty PM doc
37066
+ * // converter.footerIds.default === 'rId-footer-default'
37067
+ * ```
37068
+ */
37069
+ createDefaultFooter(variant = "default") {
37070
+ if (typeof variant !== "string") {
37071
+ throw new TypeError(`variant must be a string, received ${typeof variant}`);
37072
+ }
37073
+ const validVariants = ["default", "first", "even", "odd"];
37074
+ if (!validVariants.includes(variant)) {
37075
+ throw new Error(`Invalid footer variant: ${variant}. Must be one of: ${validVariants.join(", ")}`);
37076
+ }
37077
+ if (this.footerIds[variant]) {
37078
+ console.warn(`[SuperConverter] Footer already exists for variant '${variant}': ${this.footerIds[variant]}`);
37079
+ return this.footerIds[variant];
37080
+ }
37081
+ const rId = `rId-footer-${variant}`;
37082
+ const emptyDoc = {
37083
+ type: "doc",
37084
+ content: [
37085
+ {
37086
+ type: "paragraph",
37087
+ content: []
37088
+ }
37089
+ ]
37090
+ };
37091
+ this.footers[rId] = emptyDoc;
37092
+ this.footerIds[variant] = rId;
37093
+ if (!this.footerIds.ids) {
37094
+ this.footerIds.ids = [];
37095
+ }
37096
+ if (!this.footerIds.ids.includes(rId)) {
37097
+ this.footerIds.ids.push(rId);
37098
+ }
37099
+ this.documentModified = true;
37100
+ return rId;
37101
+ }
36213
37102
  // Deprecated methods for backward compatibility
36214
37103
  static getStoredSuperdocId(docx) {
36215
37104
  console.warn("getStoredSuperdocId is deprecated, use getDocumentGuid instead");
@@ -36483,7 +37372,6 @@ export {
36483
37372
  inputRulesPlugin as Z,
36484
37373
  TrackDeleteMarkName as _,
36485
37374
  Plugin as a,
36486
- translator$L as a$,
36487
37375
  v4 as a0,
36488
37376
  TrackFormatMarkName as a1,
36489
37377
  comments_module_events as a2,
@@ -36494,33 +37382,23 @@ export {
36494
37382
  twipsToLines as a7,
36495
37383
  pixelsToTwips as a8,
36496
37384
  helpers as a9,
36497
- Transform as aA,
36498
- findParentNodeClosestToPos as aB,
36499
- isInTable as aC,
36500
- generateDocxRandomId as aD,
36501
- insertNewRelationship as aE,
36502
- inchesToPixels as aF,
36503
- kebabCase as aG,
36504
- getUnderlineCssString as aH,
36505
- commonjsGlobal as aI,
36506
- getDefaultExportFromCjs$2 as aJ,
36507
- getContentTypesFromXml as aK,
36508
- xmljs as aL,
36509
- vClickOutside as aM,
36510
- getActiveFormatting as aN,
36511
- getFileObject as aO,
36512
- translator$H as aP,
36513
- translator$N as aQ,
36514
- translator$P as aR,
36515
- translator$I as aS,
36516
- translator$J as aT,
36517
- translator$Q as aU,
36518
- translator$R as aV,
36519
- translator$17 as aW,
36520
- translator$K as aX,
36521
- translator$_ as aY,
36522
- translator$M as aZ,
36523
- translator$O as a_,
37385
+ SelectionRange as aA,
37386
+ Transform as aB,
37387
+ findParentNodeClosestToPos as aC,
37388
+ isInTable as aD,
37389
+ generateDocxRandomId as aE,
37390
+ insertNewRelationship as aF,
37391
+ inchesToPixels as aG,
37392
+ kebabCase as aH,
37393
+ getUnderlineCssString as aI,
37394
+ commonjsGlobal as aJ,
37395
+ getDefaultExportFromCjs$2 as aK,
37396
+ getContentTypesFromXml as aL,
37397
+ xmljs as aM,
37398
+ vClickOutside as aN,
37399
+ getActiveFormatting as aO,
37400
+ getFileObject as aP,
37401
+ registeredHandlers as aQ,
36524
37402
  posToDOMRect as aa,
36525
37403
  CommandService as ab,
36526
37404
  SuperConverter as ac,
@@ -36537,91 +37415,18 @@ export {
36537
37415
  updateDOMAttributes as an,
36538
37416
  findChildren as ao,
36539
37417
  generateRandomSigned32BitIntStrId as ap,
36540
- calculateResolvedParagraphProperties as aq,
36541
- encodeCSSFromPPr as ar,
36542
- twipsToPixels as as,
36543
- resolveRunProperties as at,
36544
- encodeCSSFromRPr as au,
36545
- generateOrderedListIndex as av,
36546
- docxNumberingHelpers as aw,
36547
- InputRule as ax,
36548
- convertSizeToCSS as ay,
36549
- SelectionRange as az,
37418
+ decodeRPrFromMarks as aq,
37419
+ calculateResolvedParagraphProperties as ar,
37420
+ encodeCSSFromPPr as as,
37421
+ twipsToPixels as at,
37422
+ resolveRunProperties as au,
37423
+ encodeCSSFromRPr as av,
37424
+ generateOrderedListIndex as aw,
37425
+ docxNumberingHelpers as ax,
37426
+ InputRule as ay,
37427
+ convertSizeToCSS as az,
36550
37428
  Slice as b,
36551
- translator$23 as b$,
36552
- translator$Z as b0,
36553
- translator$Y as b1,
36554
- commentRangeEndTranslator as b2,
36555
- commentRangeStartTranslator as b3,
36556
- translator$t as b4,
36557
- translator$u as b5,
36558
- translator$x as b6,
36559
- translator$y as b7,
36560
- translator$1Z as b8,
36561
- translator$w as b9,
36562
- translator$T as bA,
36563
- translator$1Q as bB,
36564
- translator$r as bC,
36565
- translator$1l as bD,
36566
- translator$1U as bE,
36567
- translator$1N as bF,
36568
- translator$1V as bG,
36569
- translator$$ as bH,
36570
- translator$11 as bI,
36571
- translator$1n as bJ,
36572
- translator$1C as bK,
36573
- translator$U as bL,
36574
- translator$V as bM,
36575
- translator$1_ as bN,
36576
- translator$10 as bO,
36577
- translator$22 as bP,
36578
- translator$C as bQ,
36579
- translator$b as bR,
36580
- translator$D as bS,
36581
- translator$E as bT,
36582
- translator$X as bU,
36583
- translator$s as bV,
36584
- translator$1F as bW,
36585
- translator$1W as bX,
36586
- translator$1H as bY,
36587
- translator$1R as bZ,
36588
- translator$F as b_,
36589
- translator$z as ba,
36590
- translator$v as bb,
36591
- translator$1j as bc,
36592
- translator$G as bd,
36593
- translator$f as be,
36594
- translator$g as bf,
36595
- translator$h as bg,
36596
- translator$i as bh,
36597
- translator$j as bi,
36598
- translator$c as bj,
36599
- translator$k as bk,
36600
- translator$l as bl,
36601
- translator$m as bm,
36602
- translator$n as bn,
36603
- translator$A as bo,
36604
- translator$a as bp,
36605
- translator$o as bq,
36606
- translator$B as br,
36607
- translator$d as bs,
36608
- translator$p as bt,
36609
- translator$e as bu,
36610
- translator$9 as bv,
36611
- translator$21 as bw,
36612
- translator$1S as bx,
36613
- translator$1T as by,
36614
- translator$1Y as bz,
36615
37429
  DOMParser$1 as c,
36616
- translator$1p as c0,
36617
- translator$8 as c1,
36618
- translator$7 as c2,
36619
- translator$q as c3,
36620
- translator$1$ as c4,
36621
- translator$20 as c5,
36622
- translator$5 as c6,
36623
- translator$6 as c7,
36624
- translator$1M as c8,
36625
37430
  Mark as d,
36626
37431
  dropPoint as e,
36627
37432
  callOrGet as f,