@harbour-enterprises/superdoc 0.20.0-next.14 → 0.20.0-next.15

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 (107) hide show
  1. package/dist/chunks/{PdfViewer-_NPRPRHl.es.js → PdfViewer-D3gJ5ozH.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-D-erp24R.cjs → PdfViewer-DuEWa8ox.cjs} +1 -1
  3. package/dist/chunks/{index-duHcNiwD.cjs → index-D2h9q27o.cjs} +31 -8
  4. package/dist/chunks/{index-dMbV_syB.es.js → index-DiSIyVKk.es.js} +31 -8
  5. package/dist/chunks/{super-editor.es-BKurmwFy.es.js → super-editor.es-4Ig7dBJr.es.js} +2846 -851
  6. package/dist/chunks/{super-editor.es-ly_a915J.cjs → super-editor.es-lzaBZOn2.cjs} +2846 -851
  7. package/dist/core/SuperDoc.d.ts.map +1 -1
  8. package/dist/stores/comments-store.d.ts.map +1 -1
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-Brf9NxwA.js → converter-BJVy6JMW.js} +1971 -636
  11. package/dist/super-editor/chunks/{docx-zipper-Dld3TtPb.js → docx-zipper-DWDJGX0b.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-N0dhAC41.js → editor-BUCOmU2Y.js} +1026 -410
  13. package/dist/super-editor/chunks/{toolbar-CXinz1gO.js → toolbar-CiBIcgiI.js} +2 -2
  14. package/dist/super-editor/converter.es.js +1 -1
  15. package/dist/super-editor/docx-zipper.es.js +2 -2
  16. package/dist/super-editor/editor.es.js +3 -3
  17. package/dist/super-editor/file-zipper.es.js +1 -1
  18. package/dist/super-editor/src/components/toolbar/format-negation.d.ts +5 -0
  19. package/dist/super-editor/src/core/commands/index.d.ts +1 -0
  20. package/dist/super-editor/src/core/commands/toggleMarkCascade.d.ts +42 -0
  21. package/dist/super-editor/src/core/commands/types/index.d.ts +29 -1
  22. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +5 -0
  23. package/dist/super-editor/src/core/super-converter/exporter.d.ts +8 -0
  24. package/dist/super-editor/src/core/super-converter/helpers.d.ts +2 -0
  25. package/dist/super-editor/src/core/super-converter/v2/importer/markImporter.d.ts +12 -0
  26. package/dist/super-editor/src/core/super-converter/v2/importer/runNodeImporter.d.ts +6 -6
  27. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/east-asian-regex.d.ts +1 -0
  28. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/index.d.ts +1 -0
  29. package/dist/super-editor/src/core/super-converter/v3/handlers/index.d.ts +2 -12
  30. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/index.d.ts +3 -0
  31. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/w-val.d.ts +4 -0
  32. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/b-translator.d.ts +7 -0
  33. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/index.d.ts +1 -0
  34. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/index.d.ts +2 -0
  35. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-color.d.ts +4 -0
  36. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-shade.d.ts +4 -0
  37. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-tint.d.ts +4 -0
  38. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-val.d.ts +4 -0
  39. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/color-translator.d.ts +7 -0
  40. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/index.d.ts +2 -0
  41. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/w-val.d.ts +4 -0
  42. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/highlight-translator.d.ts +4 -0
  43. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/index.d.ts +2 -0
  44. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/w-val.d.ts +4 -0
  45. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/i-translator.d.ts +7 -0
  46. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/index.d.ts +2 -0
  47. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-del.d.ts +4 -0
  48. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r-pr.d.ts +4 -0
  49. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r.d.ts +4 -0
  50. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/helpers.d.ts +40 -0
  51. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/index.d.ts +3 -0
  52. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/split-run-properties.d.ts +9 -0
  53. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/track-change-helpers.d.ts +5 -0
  54. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/index.d.ts +1 -0
  55. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/r-translator.d.ts +4 -0
  56. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/index.d.ts +2 -0
  57. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-ascii.d.ts +4 -0
  58. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-cs.d.ts +4 -0
  59. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-east-asia.d.ts +4 -0
  60. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-hansi.d.ts +4 -0
  61. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-val.d.ts +4 -0
  62. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/index.d.ts +1 -0
  63. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/rFonts-translator.d.ts +5 -0
  64. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/index.d.ts +2 -0
  65. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/w-val.d.ts +4 -0
  66. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/index.d.ts +1 -0
  67. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/rstyle-translator.d.ts +7 -0
  68. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/index.d.ts +1 -0
  69. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/rpr-translator.d.ts +5 -0
  70. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/run-property-translators.d.ts +11 -0
  71. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/index.d.ts +2 -0
  72. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/w-val.d.ts +4 -0
  73. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/strike-translator.d.ts +7 -0
  74. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/index.d.ts +2 -0
  75. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/w-val.d.ts +4 -0
  76. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/sz-translator.d.ts +4 -0
  77. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/index.d.ts +2 -0
  78. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/w-val.d.ts +4 -0
  79. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/szcs-translator.d.ts +4 -0
  80. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/index.d.ts +2 -0
  81. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-color.d.ts +4 -0
  82. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-color.d.ts +4 -0
  83. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-shade.d.ts +4 -0
  84. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-tint.d.ts +4 -0
  85. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-val.d.ts +4 -0
  86. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/u-translator.d.ts +7 -0
  87. package/dist/super-editor/src/extensions/index.d.ts +2 -2
  88. package/dist/super-editor/src/extensions/linked-styles/index.d.ts +1 -0
  89. package/dist/super-editor/src/extensions/linked-styles/underline-css.d.ts +17 -0
  90. package/dist/super-editor/src/extensions/list-item/helpers/listItemTypography.d.ts +62 -0
  91. package/dist/super-editor/src/extensions/run/commands/index.d.ts +1 -0
  92. package/dist/super-editor/src/extensions/run/commands/split-run.d.ts +1 -0
  93. package/dist/super-editor/src/extensions/run/index.d.ts +1 -0
  94. package/dist/super-editor/src/extensions/run/run.d.ts +6 -0
  95. package/dist/super-editor/src/extensions/shared/cascade-toggle.d.ts +8 -0
  96. package/dist/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +12 -0
  97. package/dist/super-editor/src/extensions/tab/tab.d.ts +4 -0
  98. package/dist/super-editor/src/tests/helpers/getParagraphText.d.ts +2 -0
  99. package/dist/super-editor/super-editor.es.js +90 -21
  100. package/dist/super-editor/toolbar.es.js +2 -2
  101. package/dist/super-editor.cjs +1 -1
  102. package/dist/super-editor.es.js +1 -1
  103. package/dist/superdoc.cjs +2 -2
  104. package/dist/superdoc.es.js +2 -2
  105. package/dist/superdoc.umd.js +2877 -859
  106. package/dist/superdoc.umd.js.map +1 -1
  107. package/package.json +1 -1
@@ -14905,25 +14905,47 @@ const getContentTypesFromXml = (contentTypesXml) => {
14905
14905
  const defaults = xmlDoc.querySelectorAll("Default");
14906
14906
  return Array.from(defaults).map((item) => item.getAttribute("Extension"));
14907
14907
  };
14908
+ const DOCX_HIGHLIGHT_KEYWORD_MAP = /* @__PURE__ */ new Map([
14909
+ ["yellow", "FFFF00"],
14910
+ ["green", "00FF00"],
14911
+ ["blue", "0000FF"],
14912
+ ["cyan", "00FFFF"],
14913
+ ["magenta", "FF00FF"],
14914
+ ["red", "FF0000"],
14915
+ ["darkYellow", "808000"],
14916
+ ["darkGreen", "008000"],
14917
+ ["darkBlue", "000080"],
14918
+ ["darkCyan", "008080"],
14919
+ ["darkMagenta", "800080"],
14920
+ ["darkGray", "808080"],
14921
+ ["darkRed", "800000"],
14922
+ ["lightGray", "C0C0C0"],
14923
+ ["black", "000000"],
14924
+ ["white", "FFFFFF"]
14925
+ ]);
14926
+ const normalizeHexColor = (hex2) => {
14927
+ if (!hex2) return null;
14928
+ let value = hex2.replace("#", "").trim();
14929
+ if (!value) return null;
14930
+ value = value.toUpperCase();
14931
+ if (value.length === 3)
14932
+ value = value.split("").map((c2) => c2 + c2).join("");
14933
+ if (value.length === 8) value = value.slice(0, 6);
14934
+ return value;
14935
+ };
14908
14936
  const getHexColorFromDocxSystem = (docxColor) => {
14909
- const colorMap = /* @__PURE__ */ new Map([
14910
- ["yellow", "#ffff00"],
14911
- ["green", "#00ff00"],
14912
- ["blue", "#0000FFFF"],
14913
- ["cyan", "#00ffff"],
14914
- ["magenta", "#ff00ff"],
14915
- ["red", "#ff0000"],
14916
- ["darkYellow", "#808000FF"],
14917
- ["darkGreen", "#008000FF"],
14918
- ["darkBlue", "#000080"],
14919
- ["darkCyan", "#008080FF"],
14920
- ["darkMagenta", "#800080FF"],
14921
- ["darkGray", "#808080FF"],
14922
- ["darkRed", "#800000FF"],
14923
- ["lightGray", "#C0C0C0FF"],
14924
- ["black", "#000"]
14925
- ]);
14926
- return colorMap.get(docxColor) || null;
14937
+ const hex2 = DOCX_HIGHLIGHT_KEYWORD_MAP.get(docxColor);
14938
+ return hex2 ? `#${hex2}` : null;
14939
+ };
14940
+ const getDocxHighlightKeywordFromHex = (hexColor) => {
14941
+ if (!hexColor) return null;
14942
+ if (DOCX_HIGHLIGHT_KEYWORD_MAP.has(hexColor)) return hexColor;
14943
+ const normalized = normalizeHexColor(hexColor);
14944
+ if (!normalized) return null;
14945
+ for (const [keyword, hex2] of DOCX_HIGHLIGHT_KEYWORD_MAP.entries()) {
14946
+ if (hex2 === normalized) return keyword;
14947
+ }
14948
+ return null;
14927
14949
  };
14928
14950
  function isValidHexColor(color) {
14929
14951
  if (!color || typeof color !== "string") return false;
@@ -24311,37 +24333,37 @@ const _NodeTranslator = class _NodeTranslator2 {
24311
24333
  };
24312
24334
  __publicField$2(_NodeTranslator, "translatorTypes", TranslatorTypes);
24313
24335
  let NodeTranslator = _NodeTranslator;
24314
- const encode$A = (attributes) => {
24336
+ const encode$17 = (attributes) => {
24315
24337
  return attributes["w:type"];
24316
24338
  };
24317
- const decode$A = (attrs) => {
24339
+ const decode$_ = (attrs) => {
24318
24340
  const { lineBreakType } = attrs;
24319
24341
  return lineBreakType;
24320
24342
  };
24321
- const attrConfig$i = Object.freeze({
24343
+ const attrConfig$F = Object.freeze({
24322
24344
  xmlName: "w:type",
24323
24345
  sdName: "lineBreakType",
24324
- encode: encode$A,
24325
- decode: decode$A
24346
+ encode: encode$17,
24347
+ decode: decode$_
24326
24348
  });
24327
- const encode$z = (attributes) => {
24349
+ const encode$16 = (attributes) => {
24328
24350
  const xmlAttrValue = attributes["w:clear"];
24329
24351
  return xmlAttrValue;
24330
24352
  };
24331
- const decode$z = (attrs) => {
24353
+ const decode$Z = (attrs) => {
24332
24354
  const { clear } = attrs;
24333
24355
  return clear;
24334
24356
  };
24335
- const attrConfig$h = Object.freeze({
24357
+ const attrConfig$E = Object.freeze({
24336
24358
  xmlName: "w:clear",
24337
24359
  sdName: "clear",
24338
- encode: encode$z,
24339
- decode: decode$z
24360
+ encode: encode$16,
24361
+ decode: decode$Z
24340
24362
  });
24341
- const validXmlAttributes$b = [attrConfig$i, attrConfig$h];
24342
- const XML_NODE_NAME$h = "w:br";
24363
+ const validXmlAttributes$l = [attrConfig$F, attrConfig$E];
24364
+ const XML_NODE_NAME$t = "w:br";
24343
24365
  const SD_NODE_NAME$c = "lineBreak";
24344
- const encode$y = (_2, encodedAttrs) => {
24366
+ const encode$15 = (_2, encodedAttrs) => {
24345
24367
  const isPageBreak = encodedAttrs?.lineBreakType === "page";
24346
24368
  const translated = {
24347
24369
  type: isPageBreak ? "hardBreak" : "lineBreak"
@@ -24351,7 +24373,7 @@ const encode$y = (_2, encodedAttrs) => {
24351
24373
  }
24352
24374
  return translated;
24353
24375
  };
24354
- const decode$y = (params2, decodedAttrs) => {
24376
+ const decode$Y = (params2, decodedAttrs) => {
24355
24377
  const { node } = params2;
24356
24378
  if (!node) return;
24357
24379
  const wBreak = { name: "w:br" };
@@ -24368,63 +24390,125 @@ const decode$y = (params2, decodedAttrs) => {
24368
24390
  };
24369
24391
  return translated;
24370
24392
  };
24371
- const config$f = {
24372
- xmlName: XML_NODE_NAME$h,
24393
+ const config$r = {
24394
+ xmlName: XML_NODE_NAME$t,
24373
24395
  sdNodeOrKeyName: SD_NODE_NAME$c,
24374
24396
  type: NodeTranslator.translatorTypes.NODE,
24375
- encode: encode$y,
24376
- decode: decode$y,
24377
- attributes: validXmlAttributes$b
24397
+ encode: encode$15,
24398
+ decode: decode$Y,
24399
+ attributes: validXmlAttributes$l
24400
+ };
24401
+ const translator$15 = NodeTranslator.from(config$r);
24402
+ const encode$14 = (attributes) => attributes?.["w:val"];
24403
+ const decode$X = (attrs) => attrs?.highlight;
24404
+ const attrConfig$D = Object.freeze({
24405
+ xmlName: "w:val",
24406
+ sdName: "highlight",
24407
+ encode: encode$14,
24408
+ decode: decode$X
24409
+ });
24410
+ const validXmlAttributes$k = [attrConfig$D];
24411
+ const XML_NODE_NAME$s = "w:highlight";
24412
+ const SD_ATTR_KEY$f = "highlight";
24413
+ const DISABLED_TOKENS = /* @__PURE__ */ new Set(["transparent", "none", "inherit"]);
24414
+ const encode$13 = (params2, encodedAttrs = {}) => {
24415
+ const { nodes } = params2;
24416
+ const node = nodes?.[0];
24417
+ const value = encodedAttrs.highlight ?? node?.attributes?.["w:val"];
24418
+ return {
24419
+ type: "attr",
24420
+ xmlName: XML_NODE_NAME$s,
24421
+ sdNodeOrKeyName: SD_ATTR_KEY$f,
24422
+ attributes: { "w:val": value ?? null }
24423
+ };
24424
+ };
24425
+ const decode$W = (params2) => {
24426
+ const attrs = params2?.node?.attrs || {};
24427
+ const highlightValue = attrs.highlight ?? attrs.color ?? null;
24428
+ if (!highlightValue) return void 0;
24429
+ const normalizedValue = String(highlightValue).trim().toLowerCase();
24430
+ if (!normalizedValue) return void 0;
24431
+ if (DISABLED_TOKENS.has(normalizedValue)) {
24432
+ return {
24433
+ name: XML_NODE_NAME$s,
24434
+ attributes: { "w:val": "none" }
24435
+ };
24436
+ }
24437
+ const keyword = getDocxHighlightKeywordFromHex(highlightValue);
24438
+ if (keyword) {
24439
+ return {
24440
+ name: XML_NODE_NAME$s,
24441
+ attributes: { "w:val": keyword }
24442
+ };
24443
+ }
24444
+ const fill = normalizeHexColor(highlightValue);
24445
+ if (!fill) return void 0;
24446
+ return {
24447
+ name: "w:shd",
24448
+ attributes: {
24449
+ "w:color": "auto",
24450
+ "w:val": "clear",
24451
+ "w:fill": fill
24452
+ }
24453
+ };
24378
24454
  };
24379
- const translator$V = NodeTranslator.from(config$f);
24380
- const encode$x = (attributes) => {
24455
+ const config$q = {
24456
+ xmlName: XML_NODE_NAME$s,
24457
+ sdNodeOrKeyName: SD_ATTR_KEY$f,
24458
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
24459
+ encode: encode$13,
24460
+ decode: decode$W,
24461
+ attributes: validXmlAttributes$k
24462
+ };
24463
+ const translator$14 = NodeTranslator.from(config$q);
24464
+ const encode$12 = (attributes) => {
24381
24465
  return attributes["w:val"];
24382
24466
  };
24383
- const decode$x = (attrs) => {
24467
+ const decode$V = (attrs) => {
24384
24468
  const { tabSize } = attrs || {};
24385
24469
  return tabSize;
24386
24470
  };
24387
- const attrConfig$g = Object.freeze({
24471
+ const attrConfig$C = Object.freeze({
24388
24472
  xmlName: "w:val",
24389
24473
  sdName: "tabSize",
24390
- encode: encode$x,
24391
- decode: decode$x
24474
+ encode: encode$12,
24475
+ decode: decode$V
24392
24476
  });
24393
- const encode$w = (attributes) => {
24477
+ const encode$11 = (attributes) => {
24394
24478
  return attributes["w:leader"];
24395
24479
  };
24396
- const decode$w = (attrs) => {
24480
+ const decode$U = (attrs) => {
24397
24481
  const { leader } = attrs || {};
24398
24482
  return leader;
24399
24483
  };
24400
- const attrConfig$f = Object.freeze({
24484
+ const attrConfig$B = Object.freeze({
24401
24485
  xmlName: "w:leader",
24402
24486
  sdName: "leader",
24403
- encode: encode$w,
24404
- decode: decode$w
24487
+ encode: encode$11,
24488
+ decode: decode$U
24405
24489
  });
24406
- const encode$v = (attributes) => {
24490
+ const encode$10 = (attributes) => {
24407
24491
  return attributes["w:pos"];
24408
24492
  };
24409
- const decode$v = (attrs) => {
24493
+ const decode$T = (attrs) => {
24410
24494
  const { pos } = attrs || {};
24411
24495
  return pos;
24412
24496
  };
24413
- const attrConfig$e = Object.freeze({
24497
+ const attrConfig$A = Object.freeze({
24414
24498
  xmlName: "w:pos",
24415
24499
  sdName: "pos",
24416
- encode: encode$v,
24417
- decode: decode$v
24500
+ encode: encode$10,
24501
+ decode: decode$T
24418
24502
  });
24419
- const validXmlAttributes$a = [attrConfig$g, attrConfig$e, attrConfig$f];
24420
- const XML_NODE_NAME$g = "w:tab";
24503
+ const validXmlAttributes$j = [attrConfig$C, attrConfig$A, attrConfig$B];
24504
+ const XML_NODE_NAME$r = "w:tab";
24421
24505
  const SD_NODE_NAME$b = "tab";
24422
- const encode$u = (_2, encodedAttrs = {}) => {
24506
+ const encode$$ = (_2, encodedAttrs = {}) => {
24423
24507
  const translated = { type: "tab" };
24424
24508
  if (encodedAttrs) translated.attrs = { ...encodedAttrs };
24425
24509
  return translated;
24426
24510
  };
24427
- const decode$u = (params2, decodedAttrs = {}) => {
24511
+ const decode$S = (params2, decodedAttrs = {}) => {
24428
24512
  const { node } = params2 || {};
24429
24513
  if (!node) return;
24430
24514
  const wTab = { name: "w:tab" };
@@ -24440,15 +24524,15 @@ const decode$u = (params2, decodedAttrs = {}) => {
24440
24524
  }
24441
24525
  return translated;
24442
24526
  };
24443
- const config$e = {
24444
- xmlName: XML_NODE_NAME$g,
24527
+ const config$p = {
24528
+ xmlName: XML_NODE_NAME$r,
24445
24529
  sdNodeOrKeyName: SD_NODE_NAME$b,
24446
24530
  type: NodeTranslator.translatorTypes.NODE,
24447
- encode: encode$u,
24448
- decode: decode$u,
24449
- attributes: validXmlAttributes$a
24531
+ encode: encode$$,
24532
+ decode: decode$S,
24533
+ attributes: validXmlAttributes$j
24450
24534
  };
24451
- const translator$U = NodeTranslator.from(config$e);
24535
+ const translator$13 = NodeTranslator.from(config$p);
24452
24536
  const mergeTextNodes = (nodes) => {
24453
24537
  if (!nodes || !Array.isArray(nodes)) {
24454
24538
  return nodes;
@@ -24623,17 +24707,21 @@ function getMarkValue(markType, attributes, docx) {
24623
24707
  function getFontFamilyValue(attributes, docx) {
24624
24708
  const ascii = attributes["w:ascii"];
24625
24709
  const themeAscii = attributes["w:asciiTheme"];
24626
- if (!docx || !themeAscii) return ascii;
24627
- const theme = docx["word/theme/theme1.xml"];
24628
- if (!theme) return ascii;
24629
- const { elements: topElements } = theme;
24630
- const { elements } = topElements[0];
24631
- const themeElements = elements.find((el) => el.name === "a:themeElements");
24632
- const fontScheme = themeElements.elements.find((el) => el.name === "a:fontScheme");
24633
- const majorFont = fontScheme.elements.find((el) => el.name === "a:majorFont");
24634
- const latin = majorFont.elements.find((el) => el.name === "a:latin");
24635
- const typeface = latin.attributes["typeface"];
24636
- return typeface;
24710
+ let resolved = ascii;
24711
+ if (docx && themeAscii) {
24712
+ const theme = docx["word/theme/theme1.xml"];
24713
+ if (theme?.elements?.length) {
24714
+ const { elements: topElements } = theme;
24715
+ const { elements } = topElements[0] || {};
24716
+ const themeElements = elements?.find((el) => el.name === "a:themeElements");
24717
+ const fontScheme = themeElements?.elements?.find((el) => el.name === "a:fontScheme");
24718
+ const majorFont = fontScheme?.elements?.find((el) => el.name === "a:majorFont");
24719
+ const latin = majorFont?.elements?.find((el) => el.name === "a:latin");
24720
+ resolved = latin?.attributes?.typeface || resolved;
24721
+ }
24722
+ }
24723
+ if (!resolved) return null;
24724
+ return SuperConverter.toCssFontFamily(resolved, docx);
24637
24725
  }
24638
24726
  function getIndentValue(attributes) {
24639
24727
  let value = attributes["w:left"];
@@ -24654,7 +24742,11 @@ function getHighLightValue(attributes) {
24654
24742
  return getHexColorFromDocxSystem(attributes?.["w:val"]) || null;
24655
24743
  }
24656
24744
  function getStrikeValue(attributes) {
24657
- return attributes?.["w:val"] === "1" ? attributes["w:val"] : null;
24745
+ const raw = attributes?.["w:val"];
24746
+ if (raw === void 0 || raw === null) return "1";
24747
+ const value = String(raw).trim().toLowerCase();
24748
+ if (value === "1" || value === "true" || value === "on") return "1";
24749
+ return null;
24658
24750
  }
24659
24751
  const parseParagraphBorders = (pBdr) => {
24660
24752
  if (!pBdr || !pBdr.elements) return {};
@@ -24684,27 +24776,39 @@ const getParagraphIndent = (node, docx, styleId = "") => {
24684
24776
  right: 0,
24685
24777
  firstLine: 0,
24686
24778
  hanging: 0,
24687
- textIndent: 0
24779
+ textIndent: 0,
24780
+ explicitLeft: false,
24781
+ explicitRight: false,
24782
+ explicitFirstLine: false,
24783
+ explicitHanging: false
24688
24784
  };
24689
24785
  const { indent: pDefaultIndent = {} } = getDefaultParagraphStyle(docx, styleId);
24690
24786
  const pPr = node.elements?.find((el) => el.name === "w:pPr");
24691
24787
  const inLineIndentTag = pPr?.elements?.find((el) => el.name === "w:ind");
24692
24788
  const inLineIndent = inLineIndentTag?.attributes || {};
24693
- const leftIndent = inLineIndent?.["w:left"] || pDefaultIndent?.["w:left"];
24694
- const rightIndent = inLineIndent?.["w:right"] || pDefaultIndent?.["w:right"];
24695
- const firstLine = inLineIndent?.["w:firstLine"] || pDefaultIndent?.["w:firstLine"];
24696
- const hanging = inLineIndent?.["w:hanging"] || pDefaultIndent?.["w:hanging"];
24789
+ const inlineLeft = inLineIndent?.["w:left"];
24790
+ const inlineRight = inLineIndent?.["w:right"];
24791
+ const inlineFirstLine = inLineIndent?.["w:firstLine"];
24792
+ const inlineHanging = inLineIndent?.["w:hanging"];
24793
+ const leftIndent = inlineLeft ?? pDefaultIndent?.["w:left"];
24794
+ const rightIndent = inlineRight ?? pDefaultIndent?.["w:right"];
24795
+ const firstLine = inlineFirstLine ?? pDefaultIndent?.["w:firstLine"];
24796
+ const hanging = inlineHanging ?? pDefaultIndent?.["w:hanging"];
24697
24797
  if (leftIndent) {
24698
24798
  indent.left = twipsToPixels(leftIndent);
24799
+ indent.explicitLeft = inlineLeft !== void 0;
24699
24800
  }
24700
24801
  if (rightIndent) {
24701
24802
  indent.right = twipsToPixels(rightIndent);
24803
+ indent.explicitRight = inlineRight !== void 0;
24702
24804
  }
24703
24805
  if (firstLine) {
24704
24806
  indent.firstLine = twipsToPixels(firstLine);
24807
+ indent.explicitFirstLine = inlineFirstLine !== void 0;
24705
24808
  }
24706
24809
  if (hanging) {
24707
24810
  indent.hanging = twipsToPixels(hanging);
24811
+ indent.explicitHanging = inlineHanging !== void 0;
24708
24812
  }
24709
24813
  const textIndentValue = leftIndent - parseInt(hanging || 0) || 0;
24710
24814
  if (textIndentValue) {
@@ -25043,102 +25147,102 @@ const handleParagraphNode$1 = (params2) => {
25043
25147
  }
25044
25148
  return schemaNode;
25045
25149
  };
25046
- const encode$t = (attributes) => {
25150
+ const encode$_ = (attributes) => {
25047
25151
  return attributes["w:rsidDel"];
25048
25152
  };
25049
- const decode$t = (attrs) => {
25153
+ const decode$R = (attrs) => {
25050
25154
  return attrs.rsidDel;
25051
25155
  };
25052
- const attrConfig$d = Object.freeze({
25156
+ const attrConfig$z = Object.freeze({
25053
25157
  xmlName: "w:rsidDel",
25054
25158
  sdName: "rsidDel",
25055
- encode: encode$t,
25056
- decode: decode$t
25159
+ encode: encode$_,
25160
+ decode: decode$R
25057
25161
  });
25058
- const encode$s = (attributes) => {
25162
+ const encode$Z = (attributes) => {
25059
25163
  return attributes["w:rsidP"];
25060
25164
  };
25061
- const decode$s = (attrs) => {
25165
+ const decode$Q = (attrs) => {
25062
25166
  return attrs.rsidP;
25063
25167
  };
25064
- const attrConfig$c = Object.freeze({
25168
+ const attrConfig$y = Object.freeze({
25065
25169
  xmlName: "w:rsidP",
25066
25170
  sdName: "rsidP",
25067
- encode: encode$s,
25068
- decode: decode$s
25171
+ encode: encode$Z,
25172
+ decode: decode$Q
25069
25173
  });
25070
- const encode$r = (attributes) => {
25174
+ const encode$Y = (attributes) => {
25071
25175
  return attributes["w:rsidR"];
25072
25176
  };
25073
- const decode$r = (attrs) => {
25177
+ const decode$P = (attrs) => {
25074
25178
  return attrs.rsidR;
25075
25179
  };
25076
- const attrConfig$b = Object.freeze({
25180
+ const attrConfig$x = Object.freeze({
25077
25181
  xmlName: "w:rsidR",
25078
25182
  sdName: "rsidR",
25079
- encode: encode$r,
25080
- decode: decode$r
25183
+ encode: encode$Y,
25184
+ decode: decode$P
25081
25185
  });
25082
- const encode$q = (attributes) => {
25186
+ const encode$X = (attributes) => {
25083
25187
  return attributes["w:rsidRPr"];
25084
25188
  };
25085
- const decode$q = (attrs) => {
25189
+ const decode$O = (attrs) => {
25086
25190
  return attrs.rsidRPr;
25087
25191
  };
25088
- const attrConfig$a = Object.freeze({
25192
+ const attrConfig$w = Object.freeze({
25089
25193
  xmlName: "w:rsidRPr",
25090
25194
  sdName: "rsidRPr",
25091
- encode: encode$q,
25092
- decode: decode$q
25195
+ encode: encode$X,
25196
+ decode: decode$O
25093
25197
  });
25094
- const encode$p = (attributes) => {
25198
+ const encode$W = (attributes) => {
25095
25199
  return attributes["w:rsidRDefault"];
25096
25200
  };
25097
- const decode$p = (attrs) => {
25201
+ const decode$N = (attrs) => {
25098
25202
  return attrs.rsidRDefault;
25099
25203
  };
25100
- const attrConfig$9 = Object.freeze({
25204
+ const attrConfig$v = Object.freeze({
25101
25205
  xmlName: "w:rsidRDefault",
25102
25206
  sdName: "rsidRDefault",
25103
- encode: encode$p,
25104
- decode: decode$p
25207
+ encode: encode$W,
25208
+ decode: decode$N
25105
25209
  });
25106
- const encode$o = (attributes) => {
25210
+ const encode$V = (attributes) => {
25107
25211
  return attributes["w14:paraId"];
25108
25212
  };
25109
- const decode$o = (attrs) => {
25213
+ const decode$M = (attrs) => {
25110
25214
  return attrs.paraId;
25111
25215
  };
25112
- const attrConfig$8 = Object.freeze({
25216
+ const attrConfig$u = Object.freeze({
25113
25217
  xmlName: "w14:paraId",
25114
25218
  sdName: "paraId",
25115
- encode: encode$o,
25116
- decode: decode$o
25219
+ encode: encode$V,
25220
+ decode: decode$M
25117
25221
  });
25118
- const encode$n = (attributes) => {
25222
+ const encode$U = (attributes) => {
25119
25223
  return attributes["w14:textId"];
25120
25224
  };
25121
- const decode$n = (attrs) => {
25225
+ const decode$L = (attrs) => {
25122
25226
  return attrs.textId;
25123
25227
  };
25124
- const attrConfig$7 = Object.freeze({
25228
+ const attrConfig$t = Object.freeze({
25125
25229
  xmlName: "w14:textId",
25126
25230
  sdName: "textId",
25127
- encode: encode$n,
25128
- decode: decode$n
25231
+ encode: encode$U,
25232
+ decode: decode$L
25129
25233
  });
25130
- const validXmlAttributes$9 = [
25131
- attrConfig$8,
25132
- attrConfig$7,
25133
- attrConfig$b,
25134
- attrConfig$9,
25135
- attrConfig$c,
25136
- attrConfig$a,
25137
- attrConfig$d
25234
+ const validXmlAttributes$i = [
25235
+ attrConfig$u,
25236
+ attrConfig$t,
25237
+ attrConfig$x,
25238
+ attrConfig$v,
25239
+ attrConfig$y,
25240
+ attrConfig$w,
25241
+ attrConfig$z
25138
25242
  ];
25139
- const XML_NODE_NAME$f = "w:p";
25243
+ const XML_NODE_NAME$q = "w:p";
25140
25244
  const SD_NODE_NAME$a = "paragraph";
25141
- const encode$m = (params2, encodedAttrs = {}) => {
25245
+ const encode$T = (params2, encodedAttrs = {}) => {
25142
25246
  const node = handleParagraphNode$1(params2);
25143
25247
  if (!node) return void 0;
25144
25248
  if (encodedAttrs && Object.keys(encodedAttrs).length) {
@@ -25146,7 +25250,7 @@ const encode$m = (params2, encodedAttrs = {}) => {
25146
25250
  }
25147
25251
  return node;
25148
25252
  };
25149
- const decode$m = (params2, decodedAttrs = {}) => {
25253
+ const decode$K = (params2, decodedAttrs = {}) => {
25150
25254
  const translated = translateParagraphNode(params2);
25151
25255
  if (!translated) return void 0;
25152
25256
  if (decodedAttrs && Object.keys(decodedAttrs).length) {
@@ -25154,9 +25258,1164 @@ const decode$m = (params2, decodedAttrs = {}) => {
25154
25258
  }
25155
25259
  return translated;
25156
25260
  };
25261
+ const config$o = {
25262
+ xmlName: XML_NODE_NAME$q,
25263
+ sdNodeOrKeyName: SD_NODE_NAME$a,
25264
+ type: NodeTranslator.translatorTypes.NODE,
25265
+ encode: encode$T,
25266
+ decode: decode$K,
25267
+ attributes: validXmlAttributes$i
25268
+ };
25269
+ const translator$12 = NodeTranslator.from(config$o);
25270
+ const encode$S = (attributes) => {
25271
+ const raw = attributes?.["w:val"];
25272
+ if (raw === void 0 || raw === null) return void 0;
25273
+ if (typeof raw === "boolean") return raw;
25274
+ if (typeof raw === "number") return raw !== 0;
25275
+ const val = String(raw).trim().toLowerCase();
25276
+ if (val === "0" || val === "false" || val === "off") return false;
25277
+ if (val === "1" || val === "true" || val === "on") return true;
25278
+ return void 0;
25279
+ };
25280
+ const decode$J = (runProps) => {
25281
+ if (runProps?.bold === false) return "0";
25282
+ return void 0;
25283
+ };
25284
+ const attrConfig$s = Object.freeze({
25285
+ xmlName: "w:val",
25286
+ sdName: "bold",
25287
+ encode: encode$S,
25288
+ decode: decode$J
25289
+ });
25290
+ const validXmlAttributes$h = [attrConfig$s];
25291
+ const XML_NODE_NAME$p = "w:b";
25292
+ const SD_ATTR_KEY$e = "bold";
25293
+ const encode$R = (params2, encodedAttrs = {}) => {
25294
+ const { nodes } = params2;
25295
+ const node = nodes[0];
25296
+ if (!node) return void 0;
25297
+ const val = encodedAttrs?.[SD_ATTR_KEY$e];
25298
+ let attributes;
25299
+ if (val === false) attributes = { "w:val": "0" };
25300
+ else if (val === true)
25301
+ attributes = {};
25302
+ else attributes = node.attributes || {};
25303
+ return {
25304
+ type: "attr",
25305
+ xmlName: XML_NODE_NAME$p,
25306
+ sdNodeOrKeyName: SD_ATTR_KEY$e,
25307
+ attributes
25308
+ };
25309
+ };
25310
+ const config$n = {
25311
+ xmlName: XML_NODE_NAME$p,
25312
+ sdNodeOrKeyName: SD_ATTR_KEY$e,
25313
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25314
+ encode: encode$R,
25315
+ attributes: validXmlAttributes$h
25316
+ };
25317
+ const translator$11 = NodeTranslator.from(config$n);
25318
+ const XML_NODE_NAME$o = "w:i";
25319
+ const SD_ATTR_KEY$d = "italic";
25320
+ const encode$Q = (params2) => {
25321
+ const { nodes } = params2;
25322
+ const node = nodes?.[0];
25323
+ if (!node) return void 0;
25324
+ return {
25325
+ type: "attr",
25326
+ xmlName: XML_NODE_NAME$o,
25327
+ sdNodeOrKeyName: SD_ATTR_KEY$d,
25328
+ attributes: {
25329
+ "w:val": node.attributes?.["w:val"] ?? null
25330
+ }
25331
+ };
25332
+ };
25333
+ const config$m = {
25334
+ xmlName: XML_NODE_NAME$o,
25335
+ sdNodeOrKeyName: SD_ATTR_KEY$d,
25336
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25337
+ encode: encode$Q
25338
+ };
25339
+ const translator$10 = NodeTranslator.from(config$m);
25340
+ const encode$P = (attributes) => attributes?.["w:val"];
25341
+ const decode$I = (attrs) => attrs?.underline;
25342
+ const attrConfig$r = Object.freeze({
25343
+ xmlName: "w:val",
25344
+ sdName: "underline",
25345
+ encode: encode$P,
25346
+ decode: decode$I
25347
+ });
25348
+ const encode$O = (attributes) => attributes?.["w:color"];
25349
+ const decode$H = (attrs) => attrs?.color;
25350
+ const attrConfig$q = Object.freeze({
25351
+ xmlName: "w:color",
25352
+ sdName: "color",
25353
+ encode: encode$O,
25354
+ decode: decode$H
25355
+ });
25356
+ const encode$N = (attributes) => attributes?.["w:themeColor"];
25357
+ const decode$G = (attrs) => attrs?.themeColor;
25358
+ const attrConfig$p = Object.freeze({
25359
+ xmlName: "w:themeColor",
25360
+ sdName: "themeColor",
25361
+ encode: encode$N,
25362
+ decode: decode$G
25363
+ });
25364
+ const encode$M = (attributes) => attributes?.["w:themeTint"];
25365
+ const decode$F = (attrs) => attrs?.themeTint;
25366
+ const attrConfig$o = Object.freeze({
25367
+ xmlName: "w:themeTint",
25368
+ sdName: "themeTint",
25369
+ encode: encode$M,
25370
+ decode: decode$F
25371
+ });
25372
+ const encode$L = (attributes) => attributes?.["w:themeShade"];
25373
+ const decode$E = (attrs) => attrs?.themeShade;
25374
+ const attrConfig$n = Object.freeze({
25375
+ xmlName: "w:themeShade",
25376
+ sdName: "themeShade",
25377
+ encode: encode$L,
25378
+ decode: decode$E
25379
+ });
25380
+ const validXmlAttributes$g = [attrConfig$r, attrConfig$q, attrConfig$p, attrConfig$o, attrConfig$n];
25381
+ const XML_NODE_NAME$n = "w:u";
25382
+ const SD_ATTR_KEY$c = "underline";
25383
+ const encode$K = (params2, encodedAttrs = {}) => {
25384
+ const { nodes } = params2;
25385
+ const node = nodes?.[0];
25386
+ const sourceAttrs = node?.attributes || {};
25387
+ const underlineType = encodedAttrs.underline ?? sourceAttrs["w:val"];
25388
+ const color = encodedAttrs.color ?? sourceAttrs["w:color"];
25389
+ const themeColor = encodedAttrs.themeColor ?? sourceAttrs["w:themeColor"];
25390
+ const themeTint = encodedAttrs.themeTint ?? sourceAttrs["w:themeTint"];
25391
+ const themeShade = encodedAttrs.themeShade ?? sourceAttrs["w:themeShade"];
25392
+ const attributes = { "w:val": underlineType ?? null };
25393
+ if (color !== void 0 && color !== null) attributes["w:color"] = color;
25394
+ if (themeColor !== void 0 && themeColor !== null) attributes["w:themeColor"] = themeColor;
25395
+ if (themeTint !== void 0 && themeTint !== null) attributes["w:themeTint"] = themeTint;
25396
+ if (themeShade !== void 0 && themeShade !== null) attributes["w:themeShade"] = themeShade;
25397
+ return {
25398
+ type: "attr",
25399
+ xmlName: XML_NODE_NAME$n,
25400
+ sdNodeOrKeyName: SD_ATTR_KEY$c,
25401
+ attributes
25402
+ };
25403
+ };
25404
+ const decode$D = (params2) => {
25405
+ const attrs = params2?.node?.attrs || {};
25406
+ const underlineType = attrs.underlineType ?? attrs.underline ?? null;
25407
+ const color = attrs.underlineColor ?? attrs.color ?? null;
25408
+ const themeColor = attrs.underlineThemeColor ?? attrs.themeColor ?? null;
25409
+ const themeTint = attrs.underlineThemeTint ?? attrs.themeTint ?? null;
25410
+ const themeShade = attrs.underlineThemeShade ?? attrs.themeShade ?? null;
25411
+ if (!underlineType && !color && !themeColor && !themeTint && !themeShade) return void 0;
25412
+ const attributes = {};
25413
+ if (underlineType) attributes["w:val"] = underlineType;
25414
+ if (color) {
25415
+ const normalized = normalizeHexColor(color);
25416
+ if (normalized) attributes["w:color"] = normalized;
25417
+ }
25418
+ if (themeColor) attributes["w:themeColor"] = themeColor;
25419
+ if (themeTint) attributes["w:themeTint"] = themeTint;
25420
+ if (themeShade) attributes["w:themeShade"] = themeShade;
25421
+ return {
25422
+ name: XML_NODE_NAME$n,
25423
+ attributes
25424
+ };
25425
+ };
25426
+ const config$l = {
25427
+ xmlName: XML_NODE_NAME$n,
25428
+ sdNodeOrKeyName: SD_ATTR_KEY$c,
25429
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25430
+ encode: encode$K,
25431
+ decode: decode$D,
25432
+ attributes: validXmlAttributes$g
25433
+ };
25434
+ const translator$$ = NodeTranslator.from(config$l);
25435
+ const encode$J = (attributes) => {
25436
+ const raw = attributes?.["w:val"];
25437
+ if (raw === void 0 || raw === null) return void 0;
25438
+ if (typeof raw === "boolean") return raw;
25439
+ if (typeof raw === "number") return raw !== 0;
25440
+ const val = String(raw).trim().toLowerCase();
25441
+ if (val === "0" || val === "false" || val === "off") return false;
25442
+ if (val === "1" || val === "true" || val === "on") return true;
25443
+ return void 0;
25444
+ };
25445
+ const decode$C = (attrs) => {
25446
+ if (attrs?.strike === false) return "0";
25447
+ return void 0;
25448
+ };
25449
+ const attrConfig$m = Object.freeze({
25450
+ xmlName: "w:val",
25451
+ sdName: "strike",
25452
+ encode: encode$J,
25453
+ decode: decode$C
25454
+ });
25455
+ const validXmlAttributes$f = [attrConfig$m];
25456
+ const XML_NODE_NAME$m = "w:strike";
25457
+ const SD_ATTR_KEY$b = "strike";
25458
+ const encode$I = (params2, encodedAttrs = {}) => {
25459
+ const { nodes } = params2;
25460
+ const node = nodes?.[0];
25461
+ if (!node) return void 0;
25462
+ const val = encodedAttrs?.[SD_ATTR_KEY$b];
25463
+ let attributes;
25464
+ if (val === false) attributes = { "w:val": "0" };
25465
+ else if (val === true) attributes = {};
25466
+ else attributes = { ...node.attributes || {} };
25467
+ if (attributes["w:val"] === void 0 && val !== true) attributes["w:val"] = null;
25468
+ else if (val === true && attributes["w:val"] === void 0) delete attributes["w:val"];
25469
+ return {
25470
+ type: "attr",
25471
+ xmlName: XML_NODE_NAME$m,
25472
+ sdNodeOrKeyName: SD_ATTR_KEY$b,
25473
+ attributes
25474
+ };
25475
+ };
25476
+ const config$k = {
25477
+ xmlName: XML_NODE_NAME$m,
25478
+ sdNodeOrKeyName: SD_ATTR_KEY$b,
25479
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25480
+ encode: encode$I,
25481
+ attributes: validXmlAttributes$f
25482
+ };
25483
+ const translator$_ = NodeTranslator.from(config$k);
25484
+ const encode$H = (attributes) => attributes?.["w:val"];
25485
+ const decode$B = (attrs) => attrs?.color;
25486
+ const attrConfig$l = Object.freeze({
25487
+ xmlName: "w:val",
25488
+ sdName: "color",
25489
+ encode: encode$H,
25490
+ decode: decode$B
25491
+ });
25492
+ const encode$G = (attributes) => attributes?.["w:themeColor"];
25493
+ const decode$A = (attrs) => attrs?.themeColor;
25494
+ const attrConfig$k = Object.freeze({
25495
+ xmlName: "w:themeColor",
25496
+ sdName: "themeColor",
25497
+ encode: encode$G,
25498
+ decode: decode$A
25499
+ });
25500
+ const encode$F = (attributes) => attributes?.["w:themeTint"];
25501
+ const decode$z = (attrs) => attrs?.themeTint;
25502
+ const attrConfig$j = Object.freeze({
25503
+ xmlName: "w:themeTint",
25504
+ sdName: "themeTint",
25505
+ encode: encode$F,
25506
+ decode: decode$z
25507
+ });
25508
+ const encode$E = (attributes) => attributes?.["w:themeShade"];
25509
+ const decode$y = (attrs) => attrs?.themeShade;
25510
+ const attrConfig$i = Object.freeze({
25511
+ xmlName: "w:themeShade",
25512
+ sdName: "themeShade",
25513
+ encode: encode$E,
25514
+ decode: decode$y
25515
+ });
25516
+ const validXmlAttributes$e = [attrConfig$l, attrConfig$k, attrConfig$j, attrConfig$i];
25517
+ const XML_NODE_NAME$l = "w:color";
25518
+ const SD_ATTR_KEY$a = "color";
25519
+ const encode$D = (params2, encodedAttrs = {}) => {
25520
+ const { nodes } = params2;
25521
+ const node = nodes?.[0];
25522
+ const sourceAttrs = node?.attributes || {};
25523
+ const value = encodedAttrs.color ?? sourceAttrs["w:val"];
25524
+ const themeColor = encodedAttrs.themeColor ?? sourceAttrs["w:themeColor"];
25525
+ const themeTint = encodedAttrs.themeTint ?? sourceAttrs["w:themeTint"];
25526
+ const themeShade = encodedAttrs.themeShade ?? sourceAttrs["w:themeShade"];
25527
+ const attributes = {};
25528
+ attributes["w:val"] = value ?? null;
25529
+ if (themeColor !== void 0 && themeColor !== null) attributes["w:themeColor"] = themeColor;
25530
+ if (themeTint !== void 0 && themeTint !== null) attributes["w:themeTint"] = themeTint;
25531
+ if (themeShade !== void 0 && themeShade !== null) attributes["w:themeShade"] = themeShade;
25532
+ return {
25533
+ type: "attr",
25534
+ xmlName: XML_NODE_NAME$l,
25535
+ sdNodeOrKeyName: SD_ATTR_KEY$a,
25536
+ attributes
25537
+ };
25538
+ };
25539
+ const config$j = {
25540
+ xmlName: XML_NODE_NAME$l,
25541
+ sdNodeOrKeyName: SD_ATTR_KEY$a,
25542
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25543
+ encode: encode$D,
25544
+ attributes: validXmlAttributes$e
25545
+ };
25546
+ const translator$Z = NodeTranslator.from(config$j);
25547
+ const encode$C = (attributes) => attributes?.["w:eastAsia"];
25548
+ const decode$x = (attrs) => attrs?.eastAsia;
25549
+ const attrConfig$h = Object.freeze({
25550
+ xmlName: "w:eastAsia",
25551
+ sdName: "eastAsia",
25552
+ encode: encode$C,
25553
+ decode: decode$x
25554
+ });
25555
+ const encode$B = (attributes) => attributes?.["w:ascii"];
25556
+ const decode$w = (attrs) => attrs?.ascii;
25557
+ const attrConfig$g = Object.freeze({
25558
+ xmlName: "w:ascii",
25559
+ sdName: "ascii",
25560
+ encode: encode$B,
25561
+ decode: decode$w
25562
+ });
25563
+ const encode$A = (attributes) => attributes?.["w:hAnsi"];
25564
+ const decode$v = (attrs) => attrs?.hAnsi;
25565
+ const attrConfig$f = Object.freeze({
25566
+ xmlName: "w:hAnsi",
25567
+ sdName: "hAnsi",
25568
+ encode: encode$A,
25569
+ decode: decode$v
25570
+ });
25571
+ const encode$z = (attributes) => attributes?.["w:cs"];
25572
+ const decode$u = (attrs) => attrs?.cs;
25573
+ const attrConfig$e = Object.freeze({
25574
+ xmlName: "w:cs",
25575
+ sdName: "cs",
25576
+ encode: encode$z,
25577
+ decode: decode$u
25578
+ });
25579
+ const encode$y = (attributes) => attributes?.["w:val"];
25580
+ const decode$t = (attrs) => attrs?.value;
25581
+ const attrConfig$d = Object.freeze({
25582
+ xmlName: "w:val",
25583
+ sdName: "value",
25584
+ encode: encode$y,
25585
+ decode: decode$t
25586
+ });
25587
+ const validXmlAttributes$d = [attrConfig$h, attrConfig$g, attrConfig$f, attrConfig$e, attrConfig$d];
25588
+ const XML_NODE_NAME$k = "w:rFonts";
25589
+ const SD_ATTR_KEY$9 = "fontFamily";
25590
+ const encode$x = (params2, encodedAttrs = {}) => {
25591
+ const { nodes } = params2;
25592
+ const node = nodes?.[0];
25593
+ const sourceAttrs = node?.attributes || {};
25594
+ const attributes = {};
25595
+ const setAttr = (xmlName, sdName) => {
25596
+ if (encodedAttrs[sdName] !== void 0 && encodedAttrs[sdName] !== null) {
25597
+ attributes[xmlName] = encodedAttrs[sdName];
25598
+ } else if (sourceAttrs[xmlName] !== void 0) {
25599
+ attributes[xmlName] = sourceAttrs[xmlName];
25600
+ }
25601
+ };
25602
+ setAttr("w:eastAsia", "eastAsia");
25603
+ setAttr("w:ascii", "ascii");
25604
+ setAttr("w:hAnsi", "hAnsi");
25605
+ setAttr("w:cs", "cs");
25606
+ setAttr("w:val", "value");
25607
+ Object.keys(sourceAttrs).forEach((key2) => {
25608
+ if (attributes[key2] === void 0) attributes[key2] = sourceAttrs[key2];
25609
+ });
25610
+ if (attributes["w:val"] === void 0 && attributes["w:eastAsia"]) {
25611
+ attributes["w:val"] = attributes["w:eastAsia"];
25612
+ }
25613
+ if (attributes["w:val"] === void 0) delete attributes["w:val"];
25614
+ return {
25615
+ type: "attr",
25616
+ xmlName: XML_NODE_NAME$k,
25617
+ sdNodeOrKeyName: SD_ATTR_KEY$9,
25618
+ attributes
25619
+ };
25620
+ };
25621
+ const config$i = {
25622
+ xmlName: XML_NODE_NAME$k,
25623
+ sdNodeOrKeyName: SD_ATTR_KEY$9,
25624
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25625
+ encode: encode$x,
25626
+ attributes: validXmlAttributes$d
25627
+ };
25628
+ const translator$Y = NodeTranslator.from(config$i);
25629
+ const encode$w = (attributes) => attributes?.["w:val"];
25630
+ const decode$s = (attrs) => attrs?.styleId;
25631
+ const attrConfig$c = Object.freeze({
25632
+ xmlName: "w:val",
25633
+ sdName: "styleId",
25634
+ encode: encode$w,
25635
+ decode: decode$s
25636
+ });
25637
+ const validXmlAttributes$c = [attrConfig$c];
25638
+ const XML_NODE_NAME$j = "w:rStyle";
25639
+ const SD_ATTR_KEY$8 = "styleId";
25640
+ const encode$v = (params2, encodedAttrs = {}) => {
25641
+ const { nodes } = params2;
25642
+ const node = nodes?.[0];
25643
+ const value = encodedAttrs.styleId ?? node?.attributes?.["w:val"];
25644
+ return {
25645
+ type: "attr",
25646
+ xmlName: XML_NODE_NAME$j,
25647
+ sdNodeOrKeyName: SD_ATTR_KEY$8,
25648
+ attributes: { "w:val": value ?? null }
25649
+ };
25650
+ };
25651
+ const config$h = {
25652
+ xmlName: XML_NODE_NAME$j,
25653
+ sdNodeOrKeyName: SD_ATTR_KEY$8,
25654
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25655
+ encode: encode$v,
25656
+ attributes: validXmlAttributes$c
25657
+ };
25658
+ const translator$X = NodeTranslator.from(config$h);
25659
+ const encode$u = (attributes) => attributes?.["w:val"];
25660
+ const decode$r = (attrs) => attrs?.fontSize;
25661
+ const attrConfig$b = Object.freeze({
25662
+ xmlName: "w:val",
25663
+ sdName: "fontSize",
25664
+ encode: encode$u,
25665
+ decode: decode$r
25666
+ });
25667
+ const validXmlAttributes$b = [attrConfig$b];
25668
+ const XML_NODE_NAME$i = "w:sz";
25669
+ const SD_ATTR_KEY$7 = "fontSize";
25670
+ const encode$t = (params2, encodedAttrs = {}) => {
25671
+ const { nodes } = params2;
25672
+ const node = nodes?.[0];
25673
+ const value = encodedAttrs.fontSize ?? node?.attributes?.["w:val"];
25674
+ return {
25675
+ type: "attr",
25676
+ xmlName: XML_NODE_NAME$i,
25677
+ sdNodeOrKeyName: SD_ATTR_KEY$7,
25678
+ attributes: { "w:val": value ?? null }
25679
+ };
25680
+ };
25681
+ const config$g = {
25682
+ xmlName: XML_NODE_NAME$i,
25683
+ sdNodeOrKeyName: SD_ATTR_KEY$7,
25684
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25685
+ encode: encode$t,
25686
+ attributes: validXmlAttributes$b
25687
+ };
25688
+ const translator$W = NodeTranslator.from(config$g);
25689
+ const encode$s = (attributes) => attributes?.["w:val"];
25690
+ const decode$q = (attrs) => attrs?.fontSizeCs;
25691
+ const attrConfig$a = Object.freeze({
25692
+ xmlName: "w:val",
25693
+ sdName: "fontSizeCs",
25694
+ encode: encode$s,
25695
+ decode: decode$q
25696
+ });
25697
+ const validXmlAttributes$a = [attrConfig$a];
25698
+ const XML_NODE_NAME$h = "w:szCs";
25699
+ const SD_ATTR_KEY$6 = "fontSizeCs";
25700
+ const encode$r = (params2, encodedAttrs = {}) => {
25701
+ const { nodes } = params2;
25702
+ const node = nodes?.[0];
25703
+ const value = encodedAttrs.fontSizeCs ?? node?.attributes?.["w:val"];
25704
+ return {
25705
+ type: "attr",
25706
+ xmlName: XML_NODE_NAME$h,
25707
+ sdNodeOrKeyName: SD_ATTR_KEY$6,
25708
+ attributes: { "w:val": value ?? null }
25709
+ };
25710
+ };
25711
+ const config$f = {
25712
+ xmlName: XML_NODE_NAME$h,
25713
+ sdNodeOrKeyName: SD_ATTR_KEY$6,
25714
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25715
+ encode: encode$r,
25716
+ attributes: validXmlAttributes$a
25717
+ };
25718
+ const translator$V = NodeTranslator.from(config$f);
25719
+ const runPropertyTranslators = Object.freeze({
25720
+ "w:b": translator$11,
25721
+ "w:i": translator$10,
25722
+ "w:u": translator$$,
25723
+ "w:strike": translator$_,
25724
+ "w:color": translator$Z,
25725
+ "w:highlight": translator$14,
25726
+ "w:rFonts": translator$Y,
25727
+ "w:rStyle": translator$X,
25728
+ "w:sz": translator$W,
25729
+ "w:szCs": translator$V
25730
+ });
25731
+ const rawRunPropertyXmlNames = Object.freeze(["w:lang", "w:shd"]);
25732
+ const RAW_CHILD_NAME_SET = new Set(rawRunPropertyXmlNames);
25733
+ const KNOWN_CHILD_XML_NAMES = /* @__PURE__ */ new Set([...Object.keys(runPropertyTranslators), ...RAW_CHILD_NAME_SET]);
25734
+ const toRunPropertyEntry = (candidate) => {
25735
+ if (!candidate || candidate.type !== "attr") return null;
25736
+ const xmlName = candidate.xmlName || candidate.name;
25737
+ if (!xmlName) return null;
25738
+ return {
25739
+ xmlName,
25740
+ attributes: { ...candidate.attributes || {} }
25741
+ };
25742
+ };
25743
+ const XML_NODE_NAME$g = "w:rPr";
25744
+ const SD_ATTR_KEY$5 = "runProperties";
25745
+ const encode$q = (params2) => {
25746
+ const { nodes } = params2;
25747
+ const node = nodes?.[0] || {};
25748
+ const contents = Array.isArray(node.elements) ? node.elements : [];
25749
+ const runPropsArray = contents.reduce(
25750
+ (acc, child) => {
25751
+ if (!child || typeof child !== "object") return acc;
25752
+ const xmlName = child.name;
25753
+ if (!KNOWN_CHILD_XML_NAMES.has(xmlName)) return acc;
25754
+ const translator2 = runPropertyTranslators[xmlName];
25755
+ let entry = null;
25756
+ if (translator2) {
25757
+ const encoded = translator2.encode({ ...params2, nodes: [child] }) || null;
25758
+ entry = toRunPropertyEntry(encoded);
25759
+ } else if (RAW_CHILD_NAME_SET.has(xmlName)) {
25760
+ entry = toRunPropertyEntry({
25761
+ type: "attr",
25762
+ xmlName,
25763
+ attributes: { ...child.attributes || {} }
25764
+ });
25765
+ }
25766
+ if (entry) acc.push(entry);
25767
+ return acc;
25768
+ },
25769
+ /** @type {{ xmlName: string, attributes: Record<string, any> }[]} */
25770
+ []
25771
+ );
25772
+ return {
25773
+ type: "attr",
25774
+ xmlName: "w:rPr",
25775
+ sdNodeOrKeyName: "runProperties",
25776
+ attributes: runPropsArray
25777
+ };
25778
+ };
25779
+ const config$e = {
25780
+ xmlName: XML_NODE_NAME$g,
25781
+ sdNodeOrKeyName: SD_ATTR_KEY$5,
25782
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25783
+ encode: encode$q
25784
+ };
25785
+ const translator$U = NodeTranslator.from(config$e);
25786
+ const EAST_ASIAN_CHARACTER_REGEX = /[\u1100-\u11FF\u2E80-\u2EFF\u2F00-\u2FDF\u3040-\u30FF\u3100-\u312F\u3130-\u318F\u31A0-\u31BF\u3400-\u4DBF\u4E00-\u9FFF\uA960-\uA97F\uAC00-\uD7AF\uF900-\uFAFF\uFF00-\uFFEF]/u;
25787
+ const containsEastAsianCharacters = (text) => EAST_ASIAN_CHARACTER_REGEX.test(text);
25788
+ const collectRunProperties = (params2, rPrNode, translator2 = translator$U) => {
25789
+ if (!rPrNode) return { entries: [], hadRPr: false, styleChangeMarks: [] };
25790
+ const result = translator2.encode({ ...params2, nodes: [rPrNode] }) || {};
25791
+ let entries = [];
25792
+ if (Array.isArray(result.attributes) && result.attributes.length) {
25793
+ entries = result.attributes.map((attr) => ({
25794
+ xmlName: attr?.xmlName,
25795
+ attributes: { ...attr?.attributes || {} }
25796
+ }));
25797
+ } else if (Array.isArray(rPrNode.elements) && rPrNode.elements.length) {
25798
+ entries = rPrNode.elements.filter((el) => el && typeof el === "object").map((el) => ({
25799
+ xmlName: el.name,
25800
+ attributes: { ...el.attributes || {} }
25801
+ }));
25802
+ }
25803
+ const legacyMarks = parseMarks(rPrNode, [], params2?.docx) || [];
25804
+ const styleChangeMarks = handleStyleChangeMarks(rPrNode, legacyMarks) || [];
25805
+ return { entries, hadRPr: true, styleChangeMarks };
25806
+ };
25807
+ const buildRunAttrs = (encodedAttrs = {}, hadRPr, runProps) => {
25808
+ const base2 = { ...encodedAttrs || {} };
25809
+ if (hadRPr) {
25810
+ base2.runProperties = runProps.length ? runProps : null;
25811
+ }
25812
+ return base2;
25813
+ };
25814
+ const ensureInlineMarks = (marks, inlineMarks = []) => {
25815
+ inlineMarks.forEach(({ type: type2, attrs }) => {
25816
+ if (!type2) return;
25817
+ if (marks.some((mark) => mark?.type === type2)) return;
25818
+ marks.push(attrs ? { type: type2, attrs: { ...attrs } } : { type: type2 });
25819
+ });
25820
+ };
25821
+ const ensureTextStyleMark = (marks, textStyleAttrs) => {
25822
+ if (!textStyleAttrs) return;
25823
+ const existingTextStyle = marks.find((mark) => mark?.type === "textStyle");
25824
+ if (existingTextStyle) {
25825
+ existingTextStyle.attrs = { ...existingTextStyle.attrs || {}, ...textStyleAttrs };
25826
+ return;
25827
+ }
25828
+ marks.push({ type: "textStyle", attrs: { ...textStyleAttrs } });
25829
+ };
25830
+ const normalizeTextStyleAttrsForNode = (textStyleAttrs, node) => {
25831
+ if (!textStyleAttrs || typeof textStyleAttrs !== "object") return null;
25832
+ const normalized = { ...textStyleAttrs };
25833
+ const eastAsiaFont = normalized.eastAsiaFontFamily;
25834
+ if (eastAsiaFont) {
25835
+ delete normalized.eastAsiaFontFamily;
25836
+ const text = typeof node?.text === "string" ? node.text : null;
25837
+ const shouldUseEastAsia = typeof text === "string" && containsEastAsianCharacters(text);
25838
+ if (shouldUseEastAsia) {
25839
+ normalized.fontFamily = eastAsiaFont;
25840
+ }
25841
+ }
25842
+ return Object.keys(normalized).length ? normalized : null;
25843
+ };
25844
+ const applyRunMarks = (node, inlineMarks, textStyleAttrs) => {
25845
+ if (!node || typeof node !== "object") return node;
25846
+ const baseMarks = Array.isArray(node.marks) ? node.marks : [];
25847
+ const marks = baseMarks.map((mark) => cloneMark$1(mark));
25848
+ ensureInlineMarks(marks, inlineMarks);
25849
+ if (node.type === "text") {
25850
+ const normalizedTextStyle = normalizeTextStyleAttrsForNode(textStyleAttrs, node);
25851
+ ensureTextStyleMark(marks, normalizedTextStyle);
25852
+ }
25853
+ return { ...node, marks };
25854
+ };
25855
+ const deriveStyleMarks = ({ docx, paragraphStyleId, runStyleId }) => {
25856
+ const paragraphStyleMarks = collectStyleMarks(paragraphStyleId, docx);
25857
+ const runStyleMarks = collectStyleMarks(runStyleId, docx);
25858
+ const inlineMarks = mergeInlineMarkSets(paragraphStyleMarks.inlineMarks, runStyleMarks.inlineMarks);
25859
+ const textStyleAttrs = mergeTextStyleAttrs(paragraphStyleMarks.textStyleAttrs, runStyleMarks.textStyleAttrs);
25860
+ return { inlineMarks, textStyleAttrs };
25861
+ };
25862
+ const collectStyleMarks = (styleId, docx, seen = /* @__PURE__ */ new Set()) => {
25863
+ if (!styleId || !docx || seen.has(styleId)) return { inlineMarks: [], textStyleAttrs: null };
25864
+ seen.add(styleId);
25865
+ const chain = collectStyleChain(styleId, docx, seen);
25866
+ if (!chain.length) return { inlineMarks: [], textStyleAttrs: null };
25867
+ const inlineMap = /* @__PURE__ */ new Map();
25868
+ let textStyleAttrs = {};
25869
+ chain.forEach((styleTag) => {
25870
+ const marks = extractMarksFromStyle(styleTag, docx);
25871
+ marks.inlineMarks.forEach((mark) => {
25872
+ inlineMap.set(mark.type, mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
25873
+ });
25874
+ if (marks.textStyleAttrs) textStyleAttrs = { ...textStyleAttrs, ...marks.textStyleAttrs };
25875
+ });
25876
+ return {
25877
+ inlineMarks: Array.from(inlineMap.values()),
25878
+ textStyleAttrs: Object.keys(textStyleAttrs).length ? textStyleAttrs : null
25879
+ };
25880
+ };
25881
+ const collectStyleChain = (styleId, docx, seen) => {
25882
+ if (!styleId || !docx) return [];
25883
+ const styleTag = findStyleTag(docx, styleId);
25884
+ if (!styleTag || !styleTag.elements) return [];
25885
+ const basedOn = styleTag.elements?.find((el) => el.name === "w:basedOn")?.attributes?.["w:val"];
25886
+ let chain = [];
25887
+ if (basedOn && !seen.has(basedOn)) {
25888
+ seen.add(basedOn);
25889
+ chain = collectStyleChain(basedOn, docx, seen);
25890
+ }
25891
+ chain.push(styleTag);
25892
+ return chain;
25893
+ };
25894
+ const findStyleTag = (docx, styleId) => {
25895
+ const stylesFile = docx?.["word/styles.xml"];
25896
+ if (!stylesFile?.elements?.length) return null;
25897
+ const candidates = [];
25898
+ stylesFile.elements.forEach((el) => {
25899
+ if (!el) return;
25900
+ if (el.name === "w:styles" && Array.isArray(el.elements)) {
25901
+ el.elements.forEach((child) => {
25902
+ if (child?.name === "w:style") candidates.push(child);
25903
+ });
25904
+ return;
25905
+ }
25906
+ if (el.name === "w:style") {
25907
+ candidates.push(el);
25908
+ return;
25909
+ }
25910
+ if (Array.isArray(el.elements)) {
25911
+ el.elements.forEach((child) => {
25912
+ if (child?.name === "w:style") candidates.push(child);
25913
+ });
25914
+ }
25915
+ });
25916
+ return candidates.find((tag) => tag?.attributes?.["w:styleId"] === styleId) || null;
25917
+ };
25918
+ const extractMarksFromStyle = (styleTag, docx) => {
25919
+ const rPr = styleTag?.elements?.find((el) => el.name === "w:rPr");
25920
+ if (!rPr) return { inlineMarks: [], textStyleAttrs: null };
25921
+ const marks = parseMarks(rPr, [], docx) || [];
25922
+ const inlineMarks = [];
25923
+ let textStyleAttrs = {};
25924
+ marks.forEach((mark) => {
25925
+ if (!mark) return;
25926
+ if (mark.type === "textStyle") {
25927
+ const attrs = mark.attrs || {};
25928
+ if (Object.keys(attrs).length) textStyleAttrs = { ...textStyleAttrs, ...attrs };
25929
+ return;
25930
+ }
25931
+ if (mark.type) inlineMarks.push(mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
25932
+ });
25933
+ return {
25934
+ inlineMarks,
25935
+ textStyleAttrs: Object.keys(textStyleAttrs).length ? textStyleAttrs : null
25936
+ };
25937
+ };
25938
+ const mergeInlineMarkSets = (...markSets) => {
25939
+ const map3 = /* @__PURE__ */ new Map();
25940
+ markSets.filter(Boolean).forEach((marks) => {
25941
+ marks.forEach((mark) => {
25942
+ if (!mark || !mark.type) return;
25943
+ map3.set(mark.type, mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
25944
+ });
25945
+ });
25946
+ return Array.from(map3.values());
25947
+ };
25948
+ const mergeTextStyleAttrs = (...attrsList) => {
25949
+ const merged = attrsList.filter((attrs) => attrs && Object.keys(attrs).length).reduce((acc, attrs) => ({ ...acc, ...attrs }), {});
25950
+ return Object.keys(merged).length ? merged : null;
25951
+ };
25952
+ const cloneRunAttrs = (attrs) => {
25953
+ const clone = { ...attrs };
25954
+ if (Array.isArray(attrs?.runProperties)) {
25955
+ clone.runProperties = attrs.runProperties.map((entry) => ({
25956
+ xmlName: entry?.xmlName,
25957
+ attributes: { ...entry?.attributes || {} }
25958
+ }));
25959
+ }
25960
+ return clone;
25961
+ };
25962
+ const cloneMark$1 = (mark) => {
25963
+ if (!mark || typeof mark !== "object") return mark;
25964
+ const cloned = { ...mark };
25965
+ if (mark.attrs && typeof mark.attrs === "object") {
25966
+ cloned.attrs = { ...mark.attrs };
25967
+ if (Array.isArray(mark.attrs.runProperties)) {
25968
+ cloned.attrs.runProperties = mark.attrs.runProperties.map((entry) => ({
25969
+ xmlName: entry?.xmlName,
25970
+ attributes: { ...entry?.attributes || {} }
25971
+ }));
25972
+ }
25973
+ }
25974
+ return cloned;
25975
+ };
25976
+ const normalizeBool = (value) => {
25977
+ if (value === void 0 || value === null) return true;
25978
+ if (typeof value === "boolean") return value;
25979
+ if (typeof value === "number") return value !== 0;
25980
+ const normalized = String(value).trim().toLowerCase();
25981
+ if (normalized === "0" || normalized === "false" || normalized === "off") return false;
25982
+ if (normalized === "1" || normalized === "true" || normalized === "on") return true;
25983
+ return true;
25984
+ };
25985
+ const createRunPropertiesElement = (entries = []) => {
25986
+ if (!Array.isArray(entries) || !entries.length) return null;
25987
+ const elements = entries.map((entry) => {
25988
+ if (!entry || !entry.xmlName) return null;
25989
+ return {
25990
+ name: entry.xmlName,
25991
+ attributes: { ...entry.attributes || {} }
25992
+ };
25993
+ }).filter(Boolean);
25994
+ if (!elements.length) return null;
25995
+ return {
25996
+ name: "w:rPr",
25997
+ elements
25998
+ };
25999
+ };
26000
+ const cloneXmlNode = (nodeLike) => {
26001
+ if (!nodeLike || typeof nodeLike !== "object") return nodeLike;
26002
+ return {
26003
+ name: nodeLike.name,
26004
+ type: nodeLike.type,
26005
+ attributes: nodeLike.attributes ? { ...nodeLike.attributes } : void 0,
26006
+ elements: Array.isArray(nodeLike.elements) ? nodeLike.elements.map((el) => cloneXmlNode(el)) : void 0,
26007
+ text: nodeLike.text
26008
+ };
26009
+ };
26010
+ const applyRunPropertiesTemplate = (runNode, runPropertiesTemplate) => {
26011
+ if (!runNode || !runPropertiesTemplate) return;
26012
+ if (!Array.isArray(runNode.elements)) runNode.elements = [];
26013
+ let runProps = runNode.elements.find((el) => el?.name === "w:rPr");
26014
+ if (!runProps) {
26015
+ runProps = { name: "w:rPr", elements: [] };
26016
+ runNode.elements.unshift(runProps);
26017
+ }
26018
+ if (!Array.isArray(runProps.elements)) runProps.elements = [];
26019
+ if (runPropertiesTemplate.attributes) {
26020
+ runProps.attributes = {
26021
+ ...runProps.attributes || {},
26022
+ ...runPropertiesTemplate.attributes
26023
+ };
26024
+ }
26025
+ const isValidRunPropName = (name) => typeof name === "string" && name.includes(":");
26026
+ runProps.elements = runProps.elements.filter((entry) => isValidRunPropName(entry?.name));
26027
+ const existingNames = new Set(runProps.elements.map((el) => el?.name));
26028
+ (runPropertiesTemplate.elements || []).forEach((entry) => {
26029
+ if (!isValidRunPropName(entry?.name) || existingNames.has(entry.name)) return;
26030
+ runProps.elements.push(cloneXmlNode(entry));
26031
+ existingNames.add(entry.name);
26032
+ });
26033
+ };
26034
+ const splitRunProperties = (entries = [], docx = null) => {
26035
+ const remainingProps = [];
26036
+ const inlineMarks = [];
26037
+ const textStyleAttrs = {};
26038
+ let hasTextStyle = false;
26039
+ let highlightColor = null;
26040
+ let runStyleId = null;
26041
+ entries.forEach((entry) => {
26042
+ if (!entry || !entry.xmlName) return;
26043
+ const attributes = entry.attributes || {};
26044
+ switch (entry.xmlName) {
26045
+ case "w:b": {
26046
+ const val = normalizeBool(attributes["w:val"]);
26047
+ inlineMarks.push(val ? { type: "bold" } : { type: "bold", attrs: { value: "0" } });
26048
+ break;
26049
+ }
26050
+ case "w:i": {
26051
+ const val = normalizeBool(attributes["w:val"]);
26052
+ inlineMarks.push(val ? { type: "italic" } : { type: "italic", attrs: { value: "0" } });
26053
+ break;
26054
+ }
26055
+ case "w:u": {
26056
+ const rawVal = attributes["w:val"];
26057
+ const underlineType = rawVal == null || rawVal === "" ? "single" : String(rawVal);
26058
+ const attrs = {};
26059
+ if (underlineType.toLowerCase() === "none" || underlineType === "0") {
26060
+ attrs.underlineType = "none";
26061
+ } else {
26062
+ attrs.underlineType = underlineType;
26063
+ const colorRaw = attributes["w:color"];
26064
+ if (typeof colorRaw === "string" && colorRaw.toLowerCase() !== "auto") {
26065
+ const normalizedColor = normalizeHexColor(colorRaw);
26066
+ if (normalizedColor) attrs.underlineColor = `#${normalizedColor}`;
26067
+ }
26068
+ }
26069
+ if (attributes["w:themeColor"]) attrs.underlineThemeColor = attributes["w:themeColor"];
26070
+ if (attributes["w:themeTint"]) attrs.underlineThemeTint = attributes["w:themeTint"];
26071
+ if (attributes["w:themeShade"]) attrs.underlineThemeShade = attributes["w:themeShade"];
26072
+ inlineMarks.push({ type: "underline", attrs });
26073
+ break;
26074
+ }
26075
+ case "w:color": {
26076
+ const raw = attributes["w:val"];
26077
+ if (typeof raw === "string" && raw) {
26078
+ hasTextStyle = true;
26079
+ textStyleAttrs.color = `#${raw.replace("#", "").toUpperCase()}`;
26080
+ }
26081
+ break;
26082
+ }
26083
+ case "w:rFonts": {
26084
+ const asciiFamily = attributes["w:ascii"] || attributes["w:hAnsi"] || (attributes["w:eastAsia"] ? void 0 : attributes["w:val"]);
26085
+ const eastAsiaFamily = attributes["w:eastAsia"];
26086
+ if (asciiFamily) {
26087
+ hasTextStyle = true;
26088
+ textStyleAttrs.fontFamily = SuperConverter.toCssFontFamily(asciiFamily, docx);
26089
+ }
26090
+ if (eastAsiaFamily) {
26091
+ hasTextStyle = true;
26092
+ const eastAsiaCss = SuperConverter.toCssFontFamily(eastAsiaFamily, docx);
26093
+ if (!asciiFamily || eastAsiaCss !== textStyleAttrs.fontFamily) {
26094
+ textStyleAttrs.eastAsiaFontFamily = eastAsiaCss;
26095
+ }
26096
+ }
26097
+ break;
26098
+ }
26099
+ case "w:sz":
26100
+ case "w:szCs": {
26101
+ const rawSize = Number(attributes["w:val"]);
26102
+ if (Number.isFinite(rawSize) && rawSize > 0) {
26103
+ hasTextStyle = true;
26104
+ textStyleAttrs.fontSize = `${rawSize / 2}pt`;
26105
+ }
26106
+ break;
26107
+ }
26108
+ case "w:strike": {
26109
+ const val = normalizeBool(attributes["w:val"]);
26110
+ inlineMarks.push(val ? { type: "strike" } : { type: "strike", attrs: { value: "0" } });
26111
+ break;
26112
+ }
26113
+ case "w:highlight": {
26114
+ const color = attributes["w:val"];
26115
+ if (typeof color === "string" && color) {
26116
+ highlightColor = color.toLowerCase() === "none" ? "transparent" : color;
26117
+ }
26118
+ break;
26119
+ }
26120
+ case "w:shd": {
26121
+ const fill = attributes["w:fill"];
26122
+ const shdVal = attributes["w:val"];
26123
+ if (fill && String(fill).toLowerCase() !== "auto") {
26124
+ highlightColor = `#${String(fill).replace("#", "")}`;
26125
+ } else if (typeof shdVal === "string") {
26126
+ const normalized = shdVal.toLowerCase();
26127
+ if (normalized === "clear" || normalized === "nil" || normalized === "none") {
26128
+ highlightColor = "transparent";
26129
+ }
26130
+ }
26131
+ break;
26132
+ }
26133
+ case "w:rStyle": {
26134
+ if (typeof attributes["w:val"] === "string") runStyleId = attributes["w:val"];
26135
+ remainingProps.push({ xmlName: entry.xmlName, attributes: { ...attributes } });
26136
+ break;
26137
+ }
26138
+ default: {
26139
+ remainingProps.push({ xmlName: entry.xmlName, attributes: { ...attributes } });
26140
+ }
26141
+ }
26142
+ });
26143
+ if (highlightColor) inlineMarks.push({ type: "highlight", attrs: { color: highlightColor } });
26144
+ return {
26145
+ remainingProps,
26146
+ inlineMarks,
26147
+ textStyleAttrs: hasTextStyle ? textStyleAttrs : null,
26148
+ runStyleId
26149
+ };
26150
+ };
26151
+ const cloneMark = (mark) => {
26152
+ if (!mark) return mark;
26153
+ return {
26154
+ ...mark,
26155
+ attrs: mark.attrs ? { ...mark.attrs } : void 0
26156
+ };
26157
+ };
26158
+ const cloneNode = (node) => {
26159
+ if (!node || typeof node !== "object") return node;
26160
+ const cloned = { ...node };
26161
+ if (node.marks) cloned.marks = node.marks.map((mark) => cloneMark(mark));
26162
+ if (node.content) cloned.content = node.content.map((child) => cloneNode(child));
26163
+ if (node.elements) cloned.elements = node.elements.map((el) => cloneNode(el));
26164
+ if (node.attributes) cloned.attributes = { ...node.attributes };
26165
+ return cloned;
26166
+ };
26167
+ const cloneRuns = (runs = []) => runs.map((run2) => cloneNode(run2));
26168
+ const prepareRunTrackingContext = (node = {}) => {
26169
+ const marks = Array.isArray(node.marks) ? node.marks : [];
26170
+ const trackingMarks = marks.filter(
26171
+ (mark) => mark?.type === TrackInsertMarkName || mark?.type === TrackDeleteMarkName
26172
+ );
26173
+ if (!trackingMarks.length) {
26174
+ return { runNode: node, trackingMarksByType: /* @__PURE__ */ new Map() };
26175
+ }
26176
+ const trackingMarksByType = /* @__PURE__ */ new Map();
26177
+ trackingMarks.forEach((mark) => {
26178
+ if (mark?.type) trackingMarksByType.set(mark.type, cloneMark(mark));
26179
+ });
26180
+ const preservedMarks = marks.filter((mark) => mark?.type !== TrackInsertMarkName && mark?.type !== TrackDeleteMarkName).map((mark) => cloneMark(mark));
26181
+ const clonedContent = Array.isArray(node.content) ? node.content.map((child) => {
26182
+ const childClone = cloneNode(child);
26183
+ const childMarks = Array.isArray(childClone.marks) ? childClone.marks.slice() : [];
26184
+ trackingMarks.forEach((mark) => {
26185
+ childMarks.push(cloneMark(mark));
26186
+ });
26187
+ childClone.marks = childMarks;
26188
+ return childClone;
26189
+ }) : [];
26190
+ return {
26191
+ runNode: {
26192
+ ...cloneNode(node),
26193
+ marks: preservedMarks,
26194
+ content: clonedContent
26195
+ },
26196
+ trackingMarksByType
26197
+ };
26198
+ };
26199
+ const mapTrackingAttrs = (mark, attrMap) => {
26200
+ const source = mark?.attrs || {};
26201
+ const mapped = {};
26202
+ attrMap.forEach((targetKey, sourceKey) => {
26203
+ if (source[sourceKey] != null) mapped[targetKey] = source[sourceKey];
26204
+ });
26205
+ return mapped;
26206
+ };
26207
+ const renameTextElementsForDeletion = (node) => {
26208
+ if (!node || typeof node !== "object") return;
26209
+ if (node.name === "w:t") node.name = "w:delText";
26210
+ if (Array.isArray(node.elements)) node.elements.forEach(renameTextElementsForDeletion);
26211
+ };
26212
+ const ensureTrackedWrapper = (runs, trackingMarksByType = /* @__PURE__ */ new Map()) => {
26213
+ if (!Array.isArray(runs) || !runs.length) return runs;
26214
+ const firstRun = runs[0];
26215
+ if (firstRun?.name === "w:ins" || firstRun?.name === "w:del") {
26216
+ return runs;
26217
+ }
26218
+ if (!trackingMarksByType.size) return runs;
26219
+ if (trackingMarksByType.has(TrackInsertMarkName)) {
26220
+ const mark = trackingMarksByType.get(TrackInsertMarkName);
26221
+ const clonedRuns = cloneRuns(runs);
26222
+ const wrapper = {
26223
+ name: "w:ins",
26224
+ attributes: mapTrackingAttrs(
26225
+ mark,
26226
+ /* @__PURE__ */ new Map([
26227
+ ["id", "w:id"],
26228
+ ["author", "w:author"],
26229
+ ["authorEmail", "w:authorEmail"],
26230
+ ["date", "w:date"]
26231
+ ])
26232
+ ),
26233
+ elements: clonedRuns
26234
+ };
26235
+ return [wrapper];
26236
+ }
26237
+ if (trackingMarksByType.has(TrackDeleteMarkName)) {
26238
+ const mark = trackingMarksByType.get(TrackDeleteMarkName);
26239
+ const clonedRuns = cloneRuns(runs);
26240
+ clonedRuns.forEach(renameTextElementsForDeletion);
26241
+ const wrapper = {
26242
+ name: "w:del",
26243
+ attributes: mapTrackingAttrs(mark, /* @__PURE__ */ new Map([["id", "w:id"]])),
26244
+ elements: clonedRuns
26245
+ };
26246
+ return [wrapper];
26247
+ }
26248
+ return runs;
26249
+ };
26250
+ const encode$p = (attributes) => {
26251
+ return attributes["w:rsidR"];
26252
+ };
26253
+ const decode$p = (attrs) => {
26254
+ return attrs.rsidR;
26255
+ };
26256
+ const attrConfig$9 = Object.freeze({
26257
+ xmlName: "w:rsidR",
26258
+ sdName: "rsidR",
26259
+ encode: encode$p,
26260
+ decode: decode$p
26261
+ });
26262
+ const encode$o = (attributes) => {
26263
+ return attributes["w:rsidRPr"];
26264
+ };
26265
+ const decode$o = (attrs) => {
26266
+ return attrs.rsidRPr;
26267
+ };
26268
+ const attrConfig$8 = Object.freeze({
26269
+ xmlName: "w:rsidRPr",
26270
+ sdName: "rsidRPr",
26271
+ encode: encode$o,
26272
+ decode: decode$o
26273
+ });
26274
+ const encode$n = (attributes) => {
26275
+ return attributes["w:rsidDel"];
26276
+ };
26277
+ const decode$n = (attrs) => {
26278
+ return attrs.rsidDel;
26279
+ };
26280
+ const attrConfig$7 = Object.freeze({
26281
+ xmlName: "w:rsidDel",
26282
+ sdName: "rsidDel",
26283
+ encode: encode$n,
26284
+ decode: decode$n
26285
+ });
26286
+ const validXmlAttributes$9 = [attrConfig$9, attrConfig$8, attrConfig$7];
26287
+ const XML_NODE_NAME$f = "w:r";
26288
+ const SD_KEY_NAME = "run";
26289
+ const encode$m = (params2, encodedAttrs = {}) => {
26290
+ const { nodes = [], nodeListHandler } = params2 || {};
26291
+ const runNode = nodes[0];
26292
+ if (!runNode) return void 0;
26293
+ const elements = Array.isArray(runNode.elements) ? runNode.elements : [];
26294
+ const rPrNode = elements.find((child) => child?.name === "w:rPr");
26295
+ const contentElements = rPrNode ? elements.filter((el) => el !== rPrNode) : elements;
26296
+ const { entries: runPropEntries, hadRPr, styleChangeMarks } = collectRunProperties(params2, rPrNode);
26297
+ const { remainingProps, inlineMarks, textStyleAttrs, runStyleId } = splitRunProperties(runPropEntries, params2?.docx);
26298
+ const styleMarks = deriveStyleMarks({
26299
+ docx: params2?.docx,
26300
+ paragraphStyleId: params2?.parentStyleId,
26301
+ runStyleId
26302
+ });
26303
+ const mergedInlineMarks = mergeInlineMarkSets(styleMarks.inlineMarks, inlineMarks);
26304
+ let mergedTextStyleAttrs = mergeTextStyleAttrs(styleMarks.textStyleAttrs, textStyleAttrs);
26305
+ if (runStyleId) {
26306
+ mergedTextStyleAttrs = mergedTextStyleAttrs ? { ...mergedTextStyleAttrs, styleId: runStyleId } : { styleId: runStyleId };
26307
+ }
26308
+ const runAttrs = buildRunAttrs(encodedAttrs, hadRPr, remainingProps);
26309
+ let runLevelMarks = Array.isArray(runNode.marks) ? runNode.marks.map((mark) => cloneMark$1(mark)) : [];
26310
+ if (styleChangeMarks?.length) {
26311
+ runLevelMarks = [...runLevelMarks, ...styleChangeMarks.map((mark) => cloneMark$1(mark))];
26312
+ }
26313
+ const childParams = { ...params2, nodes: contentElements };
26314
+ const content = nodeListHandler?.handler(childParams) || [];
26315
+ const contentWithRunMarks = content.map((child) => {
26316
+ if (!child || typeof child !== "object") return child;
26317
+ const baseMarks = Array.isArray(child.marks) ? child.marks.map((mark) => cloneMark$1(mark)) : [];
26318
+ if (!runLevelMarks.length) return child;
26319
+ return { ...child, marks: [...baseMarks, ...runLevelMarks.map((mark) => cloneMark$1(mark))] };
26320
+ });
26321
+ const marked = contentWithRunMarks.map((child) => applyRunMarks(child, mergedInlineMarks, mergedTextStyleAttrs));
26322
+ const filtered = marked.filter(Boolean);
26323
+ const runNodeResult = {
26324
+ type: SD_KEY_NAME,
26325
+ content: filtered
26326
+ };
26327
+ const attrs = cloneRunAttrs(runAttrs);
26328
+ if (attrs && Object.keys(attrs).length) {
26329
+ if (attrs.runProperties == null) delete attrs.runProperties;
26330
+ if (Object.keys(attrs).length) runNodeResult.attrs = attrs;
26331
+ }
26332
+ if (runLevelMarks.length) {
26333
+ runNodeResult.marks = runLevelMarks.map((mark) => cloneMark$1(mark));
26334
+ }
26335
+ return runNodeResult;
26336
+ };
26337
+ const decode$m = (params2, decodedAttrs = {}) => {
26338
+ const { node } = params2 || {};
26339
+ if (!node) return void 0;
26340
+ const { runNode: runNodeForExport, trackingMarksByType } = prepareRunTrackingContext(node);
26341
+ const runAttrs = runNodeForExport.attrs || {};
26342
+ const runProperties = Array.isArray(runAttrs.runProperties) ? runAttrs.runProperties : [];
26343
+ const exportParams = { ...params2, node: runNodeForExport };
26344
+ if (!exportParams.editor) {
26345
+ exportParams.editor = { extensionService: { extensions: [] } };
26346
+ }
26347
+ const childElements = translateChildNodes(exportParams) || [];
26348
+ let runPropertiesElement = createRunPropertiesElement(runProperties);
26349
+ const markElements = processOutputMarks(Array.isArray(runNodeForExport.marks) ? runNodeForExport.marks : []);
26350
+ if (markElements.length) {
26351
+ if (!runPropertiesElement) {
26352
+ runPropertiesElement = generateRunProps(markElements);
26353
+ } else {
26354
+ if (!Array.isArray(runPropertiesElement.elements)) runPropertiesElement.elements = [];
26355
+ const existingNames = new Set(
26356
+ runPropertiesElement.elements.map((el) => el?.name).filter((name) => typeof name === "string")
26357
+ );
26358
+ markElements.forEach((element) => {
26359
+ if (!element || !element.name || existingNames.has(element.name)) return;
26360
+ runPropertiesElement.elements.push({ ...element, attributes: { ...element.attributes || {} } });
26361
+ existingNames.add(element.name);
26362
+ });
26363
+ }
26364
+ }
26365
+ const runPropsTemplate = runPropertiesElement ? cloneXmlNode(runPropertiesElement) : null;
26366
+ const applyBaseRunProps = (runNode) => applyRunPropertiesTemplate(runNode, runPropsTemplate);
26367
+ const runs = [];
26368
+ childElements.forEach((child) => {
26369
+ if (!child) return;
26370
+ if (child.name === "w:r") {
26371
+ const clonedRun = cloneXmlNode(child);
26372
+ applyBaseRunProps(clonedRun);
26373
+ runs.push(clonedRun);
26374
+ return;
26375
+ }
26376
+ if (child.name === "w:hyperlink") {
26377
+ const hyperlinkClone = cloneXmlNode(child);
26378
+ if (Array.isArray(hyperlinkClone.elements)) {
26379
+ hyperlinkClone.elements.forEach((run2) => applyBaseRunProps(run2));
26380
+ }
26381
+ runs.push(hyperlinkClone);
26382
+ return;
26383
+ }
26384
+ if (child.name === "w:ins" || child.name === "w:del") {
26385
+ const trackedClone = cloneXmlNode(child);
26386
+ if (Array.isArray(trackedClone.elements)) {
26387
+ trackedClone.elements.forEach((element) => {
26388
+ if (element?.name === "w:r") applyBaseRunProps(element);
26389
+ });
26390
+ }
26391
+ runs.push(trackedClone);
26392
+ return;
26393
+ }
26394
+ const runWrapper = { name: XML_NODE_NAME$f, elements: [] };
26395
+ applyBaseRunProps(runWrapper);
26396
+ if (!Array.isArray(runWrapper.elements)) runWrapper.elements = [];
26397
+ runWrapper.elements.push(cloneXmlNode(child));
26398
+ runs.push(runWrapper);
26399
+ });
26400
+ const trackedRuns = ensureTrackedWrapper(runs, trackingMarksByType);
26401
+ if (!trackedRuns.length) {
26402
+ const emptyRun = { name: XML_NODE_NAME$f, elements: [] };
26403
+ applyBaseRunProps(emptyRun);
26404
+ trackedRuns.push(emptyRun);
26405
+ }
26406
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
26407
+ trackedRuns.forEach((run2) => {
26408
+ run2.attributes = { ...run2.attributes || {}, ...decodedAttrs };
26409
+ });
26410
+ }
26411
+ if (trackedRuns.length === 1) {
26412
+ return trackedRuns[0];
26413
+ }
26414
+ return trackedRuns;
26415
+ };
25157
26416
  const config$d = {
25158
26417
  xmlName: XML_NODE_NAME$f,
25159
- sdNodeOrKeyName: SD_NODE_NAME$a,
26418
+ sdNodeOrKeyName: SD_KEY_NAME,
25160
26419
  type: NodeTranslator.translatorTypes.NODE,
25161
26420
  encode: encode$m,
25162
26421
  decode: decode$m,
@@ -26534,17 +27793,52 @@ const encode$d = (params2, encodedAttrs) => {
26534
27793
  const { nodes, docx, nodeListHandler } = params2;
26535
27794
  const node = nodes[0];
26536
27795
  let href = _resolveHref(docx, encodedAttrs);
26537
- const linkMark = { type: "link", attrs: { ...encodedAttrs, href } };
27796
+ const linkMark = { attrs: { ...encodedAttrs, href } };
26538
27797
  const runNodes = node.elements.filter((el) => el.name === "w:r");
26539
27798
  runNodes.forEach((runNode) => {
26540
- runNode.marks = [...runNode.marks || [], linkMark];
27799
+ const existingRunMarks = Array.isArray(runNode.marks) ? runNode.marks : [];
27800
+ const runMarksWithoutLink = existingRunMarks.filter((mark) => mark?.type !== "link");
27801
+ runNode.marks = runMarksWithoutLink;
26541
27802
  });
26542
27803
  const updatedNode = nodeListHandler.handler({
26543
27804
  ...params2,
26544
27805
  nodes: runNodes,
26545
27806
  path: [...params2.path || [], node]
26546
27807
  });
26547
- return updatedNode;
27808
+ const cloneMark2 = (mark) => {
27809
+ if (!mark || typeof mark !== "object") return mark;
27810
+ if (!mark.attrs) return { ...mark };
27811
+ return { ...mark, attrs: { ...mark.attrs } };
27812
+ };
27813
+ const ensureLinkMark = (child) => {
27814
+ if (!child || typeof child !== "object") return child;
27815
+ if (Array.isArray(child.content)) {
27816
+ const updatedContent = child.content.map((item) => ensureLinkMark(item));
27817
+ if (updatedContent !== child.content) {
27818
+ child = { ...child, content: updatedContent };
27819
+ }
27820
+ }
27821
+ if (child.type === "run") {
27822
+ const existingMarks2 = Array.isArray(child.marks) ? child.marks : [];
27823
+ const filteredMarks = existingMarks2.filter((mark) => mark?.type !== "link").map((mark) => cloneMark2(mark));
27824
+ if (filteredMarks.length !== existingMarks2.length) {
27825
+ if (filteredMarks.length) child = { ...child, marks: filteredMarks };
27826
+ else {
27827
+ const { marks, ...rest } = child;
27828
+ child = rest;
27829
+ }
27830
+ }
27831
+ return child;
27832
+ }
27833
+ if (child.type !== "text") return child;
27834
+ const existingMarks = Array.isArray(child.marks) ? child.marks.map((mark) => cloneMark2(mark)) : [];
27835
+ const hasLink = existingMarks.some((mark) => mark?.type === "link");
27836
+ if (hasLink) return child;
27837
+ const linkClone = { type: "link", attrs: { ...linkMark.attrs } };
27838
+ return { ...child, marks: [...existingMarks, linkClone] };
27839
+ };
27840
+ if (!Array.isArray(updatedNode)) return updatedNode;
27841
+ return updatedNode.map((child) => ensureLinkMark(child));
26548
27842
  };
26549
27843
  const _resolveHref = (docx, encodedAttrs) => {
26550
27844
  const rels = docx["word/_rels/document.xml.rels"];
@@ -27475,176 +28769,30 @@ const config$4 = {
27475
28769
  attributes: validXmlAttributes$4
27476
28770
  };
27477
28771
  const translator$4 = NodeTranslator.from(config$4);
27478
- const encode$a = (attributes) => {
27479
- return attributes["w:id"];
27480
- };
27481
- const decode$a = (attrs) => {
27482
- return attrs.id;
27483
- };
27484
- const attrConfig$6 = Object.freeze({
27485
- xmlName: "w:id",
27486
- sdName: "id",
27487
- encode: encode$a,
27488
- decode: decode$a
27489
- });
27490
- const encode$9 = (attributes) => {
27491
- return attributes["w:name"];
27492
- };
27493
- const decode$9 = (attrs) => {
27494
- return attrs.name;
27495
- };
27496
- const attrConfig$5 = Object.freeze({
27497
- xmlName: "w:name",
27498
- sdName: "name",
27499
- encode: encode$9,
27500
- decode: decode$9
27501
- });
27502
- const encode$8 = (attributes) => {
27503
- return attributes["w:colFirst"];
27504
- };
27505
- const decode$8 = (attrs) => {
27506
- return attrs.colFirst;
27507
- };
27508
- const attrConfig$4 = Object.freeze({
27509
- xmlName: "w:colFirst",
27510
- sdName: "colFirst",
27511
- encode: encode$8,
27512
- decode: decode$8
27513
- });
27514
- const encode$7 = (attributes) => {
27515
- return attributes["w:colLast"];
27516
- };
27517
- const decode$7 = (attrs) => {
27518
- return attrs.colLast;
27519
- };
27520
- const attrConfig$3 = Object.freeze({
27521
- xmlName: "w:colLast",
27522
- sdName: "colLast",
27523
- encode: encode$7,
27524
- decode: decode$7
27525
- });
27526
- const encode$6 = (attributes) => {
27527
- return attributes["w:displacedByCustomXml"];
27528
- };
27529
- const decode$6 = (attrs) => {
27530
- return attrs.displacedByCustomXml;
27531
- };
27532
- const attrConfig$2 = Object.freeze({
27533
- xmlName: "w:displacedByCustomXml",
27534
- sdName: "displacedByCustomXml",
27535
- encode: encode$6,
27536
- decode: decode$6
27537
- });
27538
- const validXmlAttributes$3 = [attrConfig$6, attrConfig$5, attrConfig$4, attrConfig$3, attrConfig$2];
27539
- const XML_NODE_NAME$3 = "w:bookmarkStart";
27540
- const SD_NODE_NAME$3 = "bookmarkStart";
27541
- const encode$5 = (params2, encodedAttrs = {}) => {
27542
- return {
27543
- type: "bookmarkStart",
27544
- attrs: encodedAttrs
27545
- };
27546
- };
27547
- const decode$5 = (params2, decodedAttrs = {}) => {
27548
- const result = {
27549
- name: "w:bookmarkStart",
27550
- elements: []
27551
- };
27552
- if (decodedAttrs && Object.keys(decodedAttrs).length) {
27553
- result.attributes = decodedAttrs;
27554
- }
27555
- return result;
27556
- };
27557
- const config$3 = {
27558
- xmlName: XML_NODE_NAME$3,
27559
- sdNodeOrKeyName: SD_NODE_NAME$3,
27560
- type: NodeTranslator.translatorTypes.NODE,
27561
- encode: encode$5,
27562
- decode: decode$5,
27563
- attributes: validXmlAttributes$3
27564
- };
27565
- const translator$3 = NodeTranslator.from(config$3);
27566
- const encode$4 = (attributes) => {
27567
- return attributes["w:id"];
27568
- };
27569
- const decode$4 = (attrs) => {
27570
- return attrs.id;
27571
- };
27572
- const attrConfig$1 = Object.freeze({
27573
- xmlName: "w:id",
27574
- sdName: "id",
27575
- encode: encode$4,
27576
- decode: decode$4
27577
- });
27578
- const encode$3 = (attributes) => {
27579
- return attributes["w:displacedByCustomXml"];
27580
- };
27581
- const decode$3 = (attrs) => {
27582
- return attrs.displacedByCustomXml;
27583
- };
27584
- const attrConfig = Object.freeze({
27585
- xmlName: "w:displacedByCustomXml",
27586
- sdName: "displacedByCustomXml",
27587
- encode: encode$3,
27588
- decode: decode$3
27589
- });
27590
- const validXmlAttributes$2 = [attrConfig$1, attrConfig];
27591
- const XML_NODE_NAME$2 = "w:bookmarkEnd";
27592
- const SD_NODE_NAME$2 = "bookmarkEnd";
27593
- const encode$2 = (params2, encodedAttrs = {}) => {
27594
- return {
27595
- type: "bookmarkEnd",
27596
- attrs: encodedAttrs
27597
- };
27598
- };
27599
- const decode$2 = (params2, decodedAttrs = {}) => {
27600
- const result = {
27601
- name: "w:bookmarkEnd",
27602
- elements: []
27603
- };
27604
- if (decodedAttrs && Object.keys(decodedAttrs).length) {
27605
- result.attributes = decodedAttrs;
27606
- }
27607
- return result;
27608
- };
27609
- const config$2 = {
27610
- xmlName: XML_NODE_NAME$2,
27611
- sdNodeOrKeyName: SD_NODE_NAME$2,
27612
- type: NodeTranslator.translatorTypes.NODE,
27613
- encode: encode$2,
27614
- decode: decode$2,
27615
- attributes: validXmlAttributes$2
27616
- };
27617
- const translator$2 = NodeTranslator.from(config$2);
27618
- const registeredHandlers = Object.freeze({
27619
- "w:br": translator$V,
27620
- "w:tab": translator$U,
27621
- "w:p": translator$T,
27622
- "wp:anchor": translator$5,
27623
- "wp:inline": translator$4,
27624
- "w:bookmarkStart": translator$3,
27625
- "w:bookmarkEnd": translator$2
27626
- });
27627
- const XML_NODE_NAME$1 = "w:drawing";
27628
- const SD_NODE_NAME$1 = [];
27629
- const validXmlAttributes$1 = [];
27630
- function encode$1(params2) {
28772
+ const XML_NODE_NAME$3 = "w:drawing";
28773
+ const SD_NODE_NAME$3 = [];
28774
+ const validXmlAttributes$3 = [];
28775
+ function encode$a(params2) {
27631
28776
  const nodes = params2.nodes;
27632
28777
  const node = nodes[0];
27633
- const validChildTranslators = ["wp:anchor", "wp:inline"];
28778
+ const translatorByChildName = {
28779
+ "wp:anchor": translator$5,
28780
+ "wp:inline": translator$4
28781
+ };
27634
28782
  return node.elements.reduce((acc, child) => {
27635
28783
  if (acc) return acc;
27636
- if (!validChildTranslators.includes(child.name)) return acc;
27637
- const translator2 = registeredHandlers[child.name];
28784
+ const translator2 = translatorByChildName[child.name];
28785
+ if (!translator2) return acc;
27638
28786
  return translator2.encode({ ...params2, extraParams: { node: child } }) || acc;
27639
28787
  }, null);
27640
28788
  }
27641
- function decode$1(params2) {
28789
+ function decode$a(params2) {
27642
28790
  const { node } = params2;
27643
28791
  if (!node || !node.type) {
27644
28792
  return null;
27645
28793
  }
27646
- const handlerName = node.attrs.isAnchor ? "wp:anchor" : "wp:inline";
27647
- const resultNode = registeredHandlers[handlerName].decode(params2);
28794
+ const childTranslator = node.attrs.isAnchor ? translator$5 : translator$4;
28795
+ const resultNode = childTranslator.decode(params2);
27648
28796
  return wrapTextInRun(
27649
28797
  {
27650
28798
  name: "w:drawing",
@@ -27653,15 +28801,15 @@ function decode$1(params2) {
27653
28801
  []
27654
28802
  );
27655
28803
  }
27656
- const config$1 = {
27657
- xmlName: XML_NODE_NAME$1,
27658
- sdNodeOrKeyName: SD_NODE_NAME$1,
28804
+ const config$3 = {
28805
+ xmlName: XML_NODE_NAME$3,
28806
+ sdNodeOrKeyName: SD_NODE_NAME$3,
27659
28807
  type: NodeTranslator.translatorTypes.NODE,
27660
- encode: encode$1,
27661
- decode: decode$1,
27662
- attributes: validXmlAttributes$1
28808
+ encode: encode$a,
28809
+ decode: decode$a,
28810
+ attributes: validXmlAttributes$3
27663
28811
  };
27664
- const translator$1 = NodeTranslator.from(config$1);
28812
+ const translator$3 = NodeTranslator.from(config$3);
27665
28813
  class CommandService {
27666
28814
  /**
27667
28815
  * @param {import('./commands/types/index.js').CommandServiceOptions} props
@@ -28999,7 +30147,7 @@ function prepareTextAnnotation(params2) {
28999
30147
  return getTextNodeForExport(attrs.displayLabel, [...marks, ...marksFromAttrs], params2);
29000
30148
  }
29001
30149
  function prepareImageAnnotation(params2, imageSize) {
29002
- return translator$1.decode({
30150
+ return translator$3.decode({
29003
30151
  ...params2,
29004
30152
  imageSize
29005
30153
  });
@@ -29236,10 +30384,10 @@ function translateStructuredContent(params2) {
29236
30384
  };
29237
30385
  return result;
29238
30386
  }
29239
- const XML_NODE_NAME = "w:sdt";
29240
- const SD_NODE_NAME = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
29241
- const validXmlAttributes = [];
29242
- function encode$B(params2) {
30387
+ const XML_NODE_NAME$2 = "w:sdt";
30388
+ const SD_NODE_NAME$2 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
30389
+ const validXmlAttributes$2 = [];
30390
+ function encode$9(params2) {
29243
30391
  const nodes = params2.nodes;
29244
30392
  const node = nodes[0];
29245
30393
  const { type: sdtType, handler: handler2 } = sdtNodeTypeStrategy(node);
@@ -29249,7 +30397,7 @@ function encode$B(params2) {
29249
30397
  const result = handler2(params2);
29250
30398
  return result;
29251
30399
  }
29252
- function decode(params2) {
30400
+ function decode$9(params2) {
29253
30401
  const { node } = params2;
29254
30402
  if (!node || !node.type) {
29255
30403
  return null;
@@ -29265,44 +30413,193 @@ function decode(params2) {
29265
30413
  const result = decoder();
29266
30414
  return result;
29267
30415
  }
30416
+ const config$2 = {
30417
+ xmlName: XML_NODE_NAME$2,
30418
+ sdNodeOrKeyName: SD_NODE_NAME$2,
30419
+ type: NodeTranslator.translatorTypes.NODE,
30420
+ encode: encode$9,
30421
+ decode: decode$9,
30422
+ attributes: validXmlAttributes$2
30423
+ };
30424
+ const translator$2 = NodeTranslator.from(config$2);
30425
+ const encode$8 = (attributes) => {
30426
+ return attributes["w:id"];
30427
+ };
30428
+ const decode$8 = (attrs) => {
30429
+ return attrs.id;
30430
+ };
30431
+ const attrConfig$6 = Object.freeze({
30432
+ xmlName: "w:id",
30433
+ sdName: "id",
30434
+ encode: encode$8,
30435
+ decode: decode$8
30436
+ });
30437
+ const encode$7 = (attributes) => {
30438
+ return attributes["w:name"];
30439
+ };
30440
+ const decode$7 = (attrs) => {
30441
+ return attrs.name;
30442
+ };
30443
+ const attrConfig$5 = Object.freeze({
30444
+ xmlName: "w:name",
30445
+ sdName: "name",
30446
+ encode: encode$7,
30447
+ decode: decode$7
30448
+ });
30449
+ const encode$6 = (attributes) => {
30450
+ return attributes["w:colFirst"];
30451
+ };
30452
+ const decode$6 = (attrs) => {
30453
+ return attrs.colFirst;
30454
+ };
30455
+ const attrConfig$4 = Object.freeze({
30456
+ xmlName: "w:colFirst",
30457
+ sdName: "colFirst",
30458
+ encode: encode$6,
30459
+ decode: decode$6
30460
+ });
30461
+ const encode$5 = (attributes) => {
30462
+ return attributes["w:colLast"];
30463
+ };
30464
+ const decode$5 = (attrs) => {
30465
+ return attrs.colLast;
30466
+ };
30467
+ const attrConfig$3 = Object.freeze({
30468
+ xmlName: "w:colLast",
30469
+ sdName: "colLast",
30470
+ encode: encode$5,
30471
+ decode: decode$5
30472
+ });
30473
+ const encode$4 = (attributes) => {
30474
+ return attributes["w:displacedByCustomXml"];
30475
+ };
30476
+ const decode$4 = (attrs) => {
30477
+ return attrs.displacedByCustomXml;
30478
+ };
30479
+ const attrConfig$2 = Object.freeze({
30480
+ xmlName: "w:displacedByCustomXml",
30481
+ sdName: "displacedByCustomXml",
30482
+ encode: encode$4,
30483
+ decode: decode$4
30484
+ });
30485
+ const validXmlAttributes$1 = [attrConfig$6, attrConfig$5, attrConfig$4, attrConfig$3, attrConfig$2];
30486
+ const XML_NODE_NAME$1 = "w:bookmarkStart";
30487
+ const SD_NODE_NAME$1 = "bookmarkStart";
30488
+ const encode$3 = (params2, encodedAttrs = {}) => {
30489
+ return {
30490
+ type: "bookmarkStart",
30491
+ attrs: encodedAttrs
30492
+ };
30493
+ };
30494
+ const decode$3 = (params2, decodedAttrs = {}) => {
30495
+ const result = {
30496
+ name: "w:bookmarkStart",
30497
+ elements: []
30498
+ };
30499
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
30500
+ result.attributes = decodedAttrs;
30501
+ }
30502
+ return result;
30503
+ };
30504
+ const config$1 = {
30505
+ xmlName: XML_NODE_NAME$1,
30506
+ sdNodeOrKeyName: SD_NODE_NAME$1,
30507
+ type: NodeTranslator.translatorTypes.NODE,
30508
+ encode: encode$3,
30509
+ decode: decode$3,
30510
+ attributes: validXmlAttributes$1
30511
+ };
30512
+ const translator$1 = NodeTranslator.from(config$1);
30513
+ const encode$2 = (attributes) => {
30514
+ return attributes["w:id"];
30515
+ };
30516
+ const decode$2 = (attrs) => {
30517
+ return attrs.id;
30518
+ };
30519
+ const attrConfig$1 = Object.freeze({
30520
+ xmlName: "w:id",
30521
+ sdName: "id",
30522
+ encode: encode$2,
30523
+ decode: decode$2
30524
+ });
30525
+ const encode$1 = (attributes) => {
30526
+ return attributes["w:displacedByCustomXml"];
30527
+ };
30528
+ const decode$1 = (attrs) => {
30529
+ return attrs.displacedByCustomXml;
30530
+ };
30531
+ const attrConfig = Object.freeze({
30532
+ xmlName: "w:displacedByCustomXml",
30533
+ sdName: "displacedByCustomXml",
30534
+ encode: encode$1,
30535
+ decode: decode$1
30536
+ });
30537
+ const validXmlAttributes = [attrConfig$1, attrConfig];
30538
+ const XML_NODE_NAME = "w:bookmarkEnd";
30539
+ const SD_NODE_NAME = "bookmarkEnd";
30540
+ const encode$18 = (params2, encodedAttrs = {}) => {
30541
+ return {
30542
+ type: "bookmarkEnd",
30543
+ attrs: encodedAttrs
30544
+ };
30545
+ };
30546
+ const decode = (params2, decodedAttrs = {}) => {
30547
+ const result = {
30548
+ name: "w:bookmarkEnd",
30549
+ elements: []
30550
+ };
30551
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
30552
+ result.attributes = decodedAttrs;
30553
+ }
30554
+ return result;
30555
+ };
29268
30556
  const config = {
29269
30557
  xmlName: XML_NODE_NAME,
29270
30558
  sdNodeOrKeyName: SD_NODE_NAME,
29271
30559
  type: NodeTranslator.translatorTypes.NODE,
29272
- encode: encode$B,
30560
+ encode: encode$18,
29273
30561
  decode,
29274
30562
  attributes: validXmlAttributes
29275
30563
  };
29276
30564
  const translator = NodeTranslator.from(config);
30565
+ const isLineBreakOnlyRun = (node) => {
30566
+ if (!node) return false;
30567
+ if (node.type === "lineBreak" || node.type === "hardBreak") return true;
30568
+ if (node.type !== "run") return false;
30569
+ const runContent = Array.isArray(node.content) ? node.content : [];
30570
+ if (!runContent.length) return false;
30571
+ return runContent.every((child) => child?.type === "lineBreak" || child?.type === "hardBreak");
30572
+ };
29277
30573
  function exportSchemaToJson(params2) {
29278
30574
  const { type: type2 } = params2.node || {};
29279
30575
  const router = {
29280
30576
  doc: translateDocumentNode,
29281
30577
  body: translateBodyNode,
29282
30578
  heading: translateHeadingNode,
29283
- paragraph: translator$T,
30579
+ paragraph: translator$12,
30580
+ run: translator$T,
29284
30581
  text: translateTextNode,
29285
30582
  bulletList: translateList,
29286
30583
  orderedList: translateList,
29287
- lineBreak: translator$V,
30584
+ lineBreak: translator$15,
29288
30585
  table: translator$8,
29289
30586
  tableRow: translator$F,
29290
30587
  tableCell: translator$7,
29291
- bookmarkStart: translator$3,
29292
- bookmarkEnd: translator$2,
29293
- fieldAnnotation: translator,
29294
- tab: translator$U,
29295
- image: translator$1,
29296
- hardBreak: translator$V,
30588
+ bookmarkStart: translator$1,
30589
+ bookmarkEnd: translator,
30590
+ fieldAnnotation: translator$2,
30591
+ tab: translator$13,
30592
+ image: translator$3,
30593
+ hardBreak: translator$15,
29297
30594
  commentRangeStart: () => translateCommentNode(params2, "Start"),
29298
30595
  commentRangeEnd: () => translateCommentNode(params2, "End"),
29299
30596
  commentReference: () => null,
29300
30597
  shapeContainer: translateShapeContainer,
29301
30598
  shapeTextbox: translateShapeTextbox,
29302
30599
  contentBlock: translateContentBlock,
29303
- structuredContent: translator,
29304
- structuredContentBlock: translator,
29305
- documentSection: translator,
30600
+ structuredContent: translator$2,
30601
+ structuredContentBlock: translator$2,
30602
+ documentSection: translator$2,
29306
30603
  "page-number": translatePageNumberNode,
29307
30604
  "total-page-number": translateTotalPageNumberNode
29308
30605
  };
@@ -29441,21 +30738,32 @@ function generateParagraphProperties(node) {
29441
30738
  };
29442
30739
  pPrElements.push(spacingElement);
29443
30740
  }
29444
- if (indent && Object.values(indent).some((v2) => v2 !== 0)) {
29445
- const { left: left2, right: right2, firstLine, hanging } = indent;
30741
+ const hasIndent = !!indent;
30742
+ if (hasIndent) {
30743
+ const { left: left2, right: right2, firstLine, hanging, explicitLeft, explicitRight, explicitFirstLine, explicitHanging } = indent;
29446
30744
  const attributes = {};
29447
- if (left2 || left2 === 0) attributes["w:left"] = pixelsToTwips(left2);
29448
- if (right2 || right2 === 0) attributes["w:right"] = pixelsToTwips(right2);
29449
- if (firstLine || firstLine === 0) attributes["w:firstLine"] = pixelsToTwips(firstLine);
29450
- if (hanging || hanging === 0) attributes["w:hanging"] = pixelsToTwips(hanging);
29451
- if (textIndent && !attributes["w:left"]) {
30745
+ if (left2 !== void 0 && (left2 !== 0 || explicitLeft || textIndent)) {
30746
+ attributes["w:left"] = pixelsToTwips(left2);
30747
+ }
30748
+ if (right2 !== void 0 && (right2 !== 0 || explicitRight)) {
30749
+ attributes["w:right"] = pixelsToTwips(right2);
30750
+ }
30751
+ if (firstLine !== void 0 && (firstLine !== 0 || explicitFirstLine)) {
30752
+ attributes["w:firstLine"] = pixelsToTwips(firstLine);
30753
+ }
30754
+ if (hanging !== void 0 && (hanging !== 0 || explicitHanging)) {
30755
+ attributes["w:hanging"] = pixelsToTwips(hanging);
30756
+ }
30757
+ if (textIndent && attributes["w:left"] === void 0) {
29452
30758
  attributes["w:left"] = getTextIndentExportValue(textIndent);
29453
30759
  }
29454
- const indentElement = {
29455
- name: "w:ind",
29456
- attributes
29457
- };
29458
- pPrElements.push(indentElement);
30760
+ if (Object.keys(attributes).length) {
30761
+ const indentElement = {
30762
+ name: "w:ind",
30763
+ attributes
30764
+ };
30765
+ pPrElements.push(indentElement);
30766
+ }
29459
30767
  } else if (textIndent && textIndent !== "0in") {
29460
30768
  const indentElement = {
29461
30769
  name: "w:ind",
@@ -29505,12 +30813,17 @@ function generateParagraphProperties(node) {
29505
30813
  if (sectPr) {
29506
30814
  pPrElements.push(sectPr);
29507
30815
  }
30816
+ const mapTabVal = (value) => {
30817
+ if (!value || value === "start") return "left";
30818
+ if (value === "end") return "right";
30819
+ return value;
30820
+ };
29508
30821
  const { tabStops } = attrs;
29509
30822
  if (tabStops && tabStops.length > 0) {
29510
30823
  const tabElements = tabStops.map((tab) => {
29511
30824
  const posValue = tab.originalPos !== void 0 ? tab.originalPos : pixelsToTwips(tab.pos).toString();
29512
30825
  const tabAttributes = {
29513
- "w:val": tab.val || "start",
30826
+ "w:val": mapTabVal(tab.val),
29514
30827
  "w:pos": posValue
29515
30828
  };
29516
30829
  if (tab.leader) {
@@ -29865,6 +31178,11 @@ const convertMultipleListItemsIntoSingleNode = (listItem) => {
29865
31178
  collapsedParagraph.content.push(item);
29866
31179
  }
29867
31180
  });
31181
+ collapsedParagraph.content = collapsedParagraph.content.filter((node, index2, nodes) => {
31182
+ if (!isLineBreakOnlyRun(node)) return true;
31183
+ const prevNode = nodes[index2 - 1];
31184
+ return !(prevNode && isLineBreakOnlyRun(prevNode));
31185
+ });
29868
31186
  return collapsedParagraph;
29869
31187
  };
29870
31188
  const restoreIndent = (indent) => {
@@ -29918,13 +31236,27 @@ function translateMark(mark) {
29918
31236
  markElement.type = "element";
29919
31237
  break;
29920
31238
  case "italic":
29921
- delete markElement.attributes;
29922
- markElement.type = "element";
29923
- break;
29924
- case "underline":
31239
+ if (attrs?.value && attrs.value !== "1" && attrs.value !== true) {
31240
+ markElement.attributes["w:val"] = attrs.value;
31241
+ } else {
31242
+ delete markElement.attributes;
31243
+ }
29925
31244
  markElement.type = "element";
29926
- markElement.attributes["w:val"] = attrs.underlineType;
29927
31245
  break;
31246
+ case "underline": {
31247
+ const translated = translator$$.decode({
31248
+ node: {
31249
+ attrs: {
31250
+ underlineType: attrs.underlineType ?? attrs.underline ?? null,
31251
+ underlineColor: attrs.underlineColor ?? attrs.color ?? null,
31252
+ underlineThemeColor: attrs.underlineThemeColor ?? attrs.themeColor ?? null,
31253
+ underlineThemeTint: attrs.underlineThemeTint ?? attrs.themeTint ?? null,
31254
+ underlineThemeShade: attrs.underlineThemeShade ?? attrs.themeShade ?? null
31255
+ }
31256
+ }
31257
+ });
31258
+ return translated || {};
31259
+ }
29928
31260
  // Text style cases
29929
31261
  case "fontSize":
29930
31262
  value = attrs.fontSize;
@@ -29942,13 +31274,21 @@ function translateMark(mark) {
29942
31274
  markElement.name = "w:rStyle";
29943
31275
  markElement.attributes["w:val"] = attrs.styleId;
29944
31276
  break;
29945
- case "color":
29946
- let processedColor = attrs.color.replace(/^#/, "").replace(/;$/, "");
31277
+ case "color": {
31278
+ const rawColor = attrs.color;
31279
+ if (!rawColor) break;
31280
+ const normalized = String(rawColor).trim().toLowerCase();
31281
+ if (normalized === "inherit") {
31282
+ markElement.attributes["w:val"] = "auto";
31283
+ break;
31284
+ }
31285
+ let processedColor = String(rawColor).replace(/^#/, "").replace(/;$/, "");
29947
31286
  if (processedColor.startsWith("rgb")) {
29948
31287
  processedColor = rgbToHex(processedColor);
29949
31288
  }
29950
31289
  markElement.attributes["w:val"] = processedColor;
29951
31290
  break;
31291
+ }
29952
31292
  case "textAlign":
29953
31293
  markElement.attributes["w:val"] = attrs.textAlign;
29954
31294
  break;
@@ -29966,12 +31306,11 @@ function translateMark(mark) {
29966
31306
  case "lineHeight":
29967
31307
  markElement.attributes["w:line"] = linesToTwips(attrs.lineHeight);
29968
31308
  break;
29969
- case "highlight":
29970
- markElement.attributes["w:fill"] = attrs.color?.substring(1);
29971
- markElement.attributes["w:color"] = "auto";
29972
- markElement.attributes["w:val"] = "clear";
29973
- markElement.name = "w:shd";
29974
- break;
31309
+ case "highlight": {
31310
+ const highlightValue = attrs.color ?? attrs.highlight ?? null;
31311
+ const translated = translator$14.decode({ node: { attrs: { highlight: highlightValue } } });
31312
+ return translated || {};
31313
+ }
29975
31314
  }
29976
31315
  return markElement;
29977
31316
  }
@@ -30102,8 +31441,8 @@ generate_xml_as_list_fn = function(data, debug = false) {
30102
31441
  return final;
30103
31442
  };
30104
31443
  replaceSpecialCharacters_fn = function(text) {
30105
- if (!text) return;
30106
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
31444
+ if (text === void 0 || text === null) return text;
31445
+ return String(text).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
30107
31446
  };
30108
31447
  generateXml_fn = function(node) {
30109
31448
  if (!node) return null;
@@ -30119,7 +31458,7 @@ generateXml_fn = function(node) {
30119
31458
  else tag += ">";
30120
31459
  let tags = [tag];
30121
31460
  if (!name && node.type === "text") {
30122
- return node.text;
31461
+ return __privateMethod$2(this, _DocxExporter_instances, replaceSpecialCharacters_fn).call(this, node.text ?? "");
30123
31462
  }
30124
31463
  if (elements) {
30125
31464
  if (name === "w:instrText") {
@@ -30245,7 +31584,7 @@ const handleDrawingNode = (params2) => {
30245
31584
  if (mainNode.name === "w:drawing") node = mainNode;
30246
31585
  else node = mainNode.elements.find((el) => el.name === "w:drawing");
30247
31586
  if (!node) return { nodes: [], consumed: 0 };
30248
- const schemaNode = translator$1.encode(params2);
31587
+ const schemaNode = translator$3.encode(params2);
30249
31588
  const newNodes = schemaNode ? [schemaNode] : [];
30250
31589
  return { nodes: newNodes, consumed: 1 };
30251
31590
  };
@@ -30348,81 +31687,7 @@ const trackChangeNodeHandlerEntity = {
30348
31687
  handler: handleTrackChangeNode
30349
31688
  };
30350
31689
  const hyperlinkNodeHandlerEntity = generateV2HandlerEntity("hyperlinkNodeHandler", translator$6);
30351
- const handleRunNode = (params2) => {
30352
- const { nodes, nodeListHandler, parentStyleId, docx } = params2;
30353
- if (nodes.length === 0 || nodes[0].name !== "w:r") {
30354
- return { nodes: [], consumed: 0 };
30355
- }
30356
- const node = nodes[0];
30357
- const childParams = { ...params2, nodes: node.elements, path: [...params2.path || [], node] };
30358
- let processedRun = nodeListHandler.handler(childParams)?.filter((n) => n) || [];
30359
- const hasRunProperties = node.elements?.some((el) => el.name === "w:rPr");
30360
- const defaultNodeStyles = getMarksFromStyles(docx, parentStyleId);
30361
- if (hasRunProperties) {
30362
- const { marks = [] } = parseProperties(node);
30363
- let runStyleAttributes = [];
30364
- const runStyleElement = node.elements?.find((el) => el.name === "w:rPr")?.elements?.find((el) => el.name === "w:rStyle");
30365
- let runStyleId;
30366
- if (runStyleElement && runStyleElement.attributes?.["w:val"] && docx) {
30367
- runStyleId = runStyleElement.attributes["w:val"];
30368
- const runStyleDefinition = getMarksFromStyles(docx, runStyleId);
30369
- if (runStyleDefinition.marks && runStyleDefinition.marks.length > 0) {
30370
- runStyleAttributes = runStyleDefinition.marks;
30371
- }
30372
- }
30373
- let paragraphStyleAttributes = [];
30374
- if (defaultNodeStyles.marks) {
30375
- paragraphStyleAttributes = defaultNodeStyles.marks.filter((mark) => {
30376
- if (["bold"].includes(mark.type) && marks.find((m2) => m2.type === "bold")?.attrs?.value === "0") {
30377
- return false;
30378
- }
30379
- return true;
30380
- });
30381
- }
30382
- const combinedMarks = [...paragraphStyleAttributes];
30383
- runStyleAttributes.forEach((runStyle) => {
30384
- const exists2 = combinedMarks.some(
30385
- (mark) => mark.type === runStyle.type && JSON.stringify(mark.attrs || {}) === JSON.stringify(runStyle.attrs || {})
30386
- );
30387
- if (!exists2) {
30388
- combinedMarks.push(runStyle);
30389
- }
30390
- });
30391
- marks.forEach((mark) => {
30392
- const exists2 = combinedMarks.some(
30393
- (existing) => existing.type === mark.type && JSON.stringify(existing.attrs || {}) === JSON.stringify(mark.attrs || {})
30394
- );
30395
- if (!exists2) {
30396
- combinedMarks.push(mark);
30397
- }
30398
- });
30399
- if (runStyleId) combinedMarks.push({ type: "textStyle", attrs: { styleId: runStyleId } });
30400
- if (node.marks) combinedMarks.push(...node.marks);
30401
- const newMarks = createImportMarks(combinedMarks);
30402
- processedRun = processedRun.map((n) => {
30403
- const existingMarks = n.marks || [];
30404
- return {
30405
- ...n,
30406
- marks: [...newMarks, ...existingMarks]
30407
- };
30408
- });
30409
- }
30410
- return { nodes: processedRun, consumed: 1 };
30411
- };
30412
- const getMarksFromStyles = (docx, styleId) => {
30413
- const styles = docx?.["word/styles.xml"];
30414
- if (!styles) {
30415
- return {};
30416
- }
30417
- const styleTags = styles.elements[0].elements.filter((style22) => style22.name === "w:style");
30418
- const style2 = styleTags.find((tag) => tag.attributes["w:styleId"] === styleId) || {};
30419
- if (!style2) return {};
30420
- return parseProperties(style2);
30421
- };
30422
- const runNodeHandlerEntity = {
30423
- handlerName: "runNodeHandler",
30424
- handler: handleRunNode
30425
- };
31690
+ const runNodeHandlerEntity = generateV2HandlerEntity("runNodeHandler", translator$T);
30426
31691
  const handleTextNode = (params2) => {
30427
31692
  const { nodes, insideTrackChange } = params2;
30428
31693
  if (nodes.length === 0 || !(nodes[0].name === "w:t" || insideTrackChange && nodes[0].name === "w:delText")) {
@@ -30434,6 +31699,10 @@ const handleTextNode = (params2) => {
30434
31699
  let text;
30435
31700
  if (elements.length === 1) {
30436
31701
  text = elements[0].text;
31702
+ const xmlSpace = node.attributes?.["xml:space"] ?? elements[0]?.attributes?.["xml:space"];
31703
+ if (xmlSpace !== "preserve" && typeof text === "string") {
31704
+ text = text.replace(/^\s+/, "").replace(/\s+$/, "");
31705
+ }
30437
31706
  text = text.replace(/\[\[sdspace\]\]/g, "");
30438
31707
  } else if (!elements.length && "attributes" in node && node.attributes["xml:space"] === "preserve") {
30439
31708
  text = " ";
@@ -30459,7 +31728,7 @@ const handleParagraphNode = (params2) => {
30459
31728
  if (nodes.length === 0 || nodes[0].name !== "w:p") {
30460
31729
  return { nodes: [], consumed: 0 };
30461
31730
  }
30462
- const schemaNode = translator$T.encode(params2);
31731
+ const schemaNode = translator$12.encode(params2);
30463
31732
  const newNodes = schemaNode ? [schemaNode] : [];
30464
31733
  return { nodes: newNodes, consumed: 1 };
30465
31734
  };
@@ -30472,7 +31741,7 @@ const handleSdtNode = (params2) => {
30472
31741
  if (nodes.length === 0 || nodes[0].name !== "w:sdt") {
30473
31742
  return { nodes: [], consumed: 0 };
30474
31743
  }
30475
- const result = translator.encode(params2);
31744
+ const result = translator$2.encode(params2);
30476
31745
  if (!result) {
30477
31746
  return { nodes: [], consumed: 0 };
30478
31747
  }
@@ -30562,7 +31831,7 @@ const handler = (params2) => {
30562
31831
  if (nodes.length === 0 || nodes[0].name !== "w:br") {
30563
31832
  return { nodes: [], consumed: 0 };
30564
31833
  }
30565
- const result = translator$V.encode(params2);
31834
+ const result = translator$15.encode(params2);
30566
31835
  if (!result) return { nodes: [], consumed: 0 };
30567
31836
  return {
30568
31837
  nodes: [result],
@@ -30634,7 +31903,7 @@ const handleBookmarkStartNode = (params2) => {
30634
31903
  if (isCustomMarkBookmark(nodes[0], params2.editor)) {
30635
31904
  return handleBookmarkNode(params2);
30636
31905
  }
30637
- const node = translator$3.encode(params2);
31906
+ const node = translator$1.encode(params2);
30638
31907
  if (!node) return { nodes: [], consumed: 0 };
30639
31908
  return { nodes: [node], consumed: 1 };
30640
31909
  };
@@ -30666,7 +31935,7 @@ const handleBookmarkEndNode = (params2) => {
30666
31935
  if (!nodes.length || nodes[0].name !== "w:bookmarkEnd") {
30667
31936
  return { nodes: [], consumed: 0 };
30668
31937
  }
30669
- const node = translator$2.encode(params2);
31938
+ const node = translator.encode(params2);
30670
31939
  if (!node) return { nodes: [], consumed: 0 };
30671
31940
  return { nodes: [node], consumed: 1 };
30672
31941
  };
@@ -31305,7 +32574,7 @@ const handleTabNode = (params2) => {
31305
32574
  if (!nodes.length || nodes[0].name !== "w:tab") {
31306
32575
  return { nodes: [], consumed: 0 };
31307
32576
  }
31308
- const node = translator$U.encode(params2);
32577
+ const node = translator$13.encode(params2);
31309
32578
  return { nodes: [node], consumed: 1 };
31310
32579
  };
31311
32580
  const tabNodeEntityHandler = {
@@ -31754,6 +33023,16 @@ const isAlternatingHeadersOddEven = (docx) => {
31754
33023
  };
31755
33024
  const HYPERLINK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
31756
33025
  const HEADER_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
33026
+ const FONT_FAMILY_FALLBACKS = Object.freeze({
33027
+ swiss: "Arial, sans-serif",
33028
+ roman: "Times New Roman, serif",
33029
+ modern: "Courier New, monospace",
33030
+ script: "cursive",
33031
+ decorative: "fantasy",
33032
+ system: "system-ui",
33033
+ auto: "sans-serif"
33034
+ });
33035
+ const DEFAULT_GENERIC_FALLBACK = "sans-serif";
31757
33036
  const _SuperConverter = class _SuperConverter2 {
31758
33037
  constructor(params2 = null) {
31759
33038
  __privateAdd$2(this, _SuperConverter_instances);
@@ -31789,6 +33068,31 @@ const _SuperConverter = class _SuperConverter2 {
31789
33068
  this.documentId = params2?.documentId || null;
31790
33069
  if (this.docx.length || this.xml) this.parseFromXml();
31791
33070
  }
33071
+ static getFontTableEntry(docx, fontName) {
33072
+ if (!docx || !fontName) return null;
33073
+ const fontTable = docx["word/fontTable.xml"];
33074
+ if (!fontTable?.elements?.length) return null;
33075
+ const fontsNode = fontTable.elements.find((el) => el.name === "w:fonts");
33076
+ if (!fontsNode?.elements?.length) return null;
33077
+ return fontsNode.elements.find((el) => el?.attributes?.["w:name"] === fontName) || null;
33078
+ }
33079
+ static getFallbackFromFontTable(docx, fontName) {
33080
+ const fontEntry = _SuperConverter2.getFontTableEntry(docx, fontName);
33081
+ const family = fontEntry?.elements?.find((child) => child.name === "w:family")?.attributes?.["w:val"];
33082
+ if (!family) return null;
33083
+ const mapped = FONT_FAMILY_FALLBACKS[family.toLowerCase()];
33084
+ return mapped || DEFAULT_GENERIC_FALLBACK;
33085
+ }
33086
+ static toCssFontFamily(fontName, docx) {
33087
+ if (!fontName) return fontName;
33088
+ if (fontName.includes(",")) return fontName;
33089
+ const fallback = _SuperConverter2.getFallbackFromFontTable(docx, fontName) || DEFAULT_GENERIC_FALLBACK;
33090
+ const normalizedFallbackParts = fallback.split(",").map((part) => part.trim().toLowerCase()).filter(Boolean);
33091
+ if (normalizedFallbackParts.includes(fontName.trim().toLowerCase())) {
33092
+ return fallback;
33093
+ }
33094
+ return `${fontName}, ${fallback}`;
33095
+ }
31792
33096
  /**
31793
33097
  * Get the DocxHelpers object that contains utility functions for working with docx files.
31794
33098
  * @returns {import('./docx-helpers/docx-helpers.js').DocxHelpers} The DocxHelpers object.
@@ -31885,13 +33189,19 @@ const _SuperConverter = class _SuperConverter2 {
31885
33189
  if (rPrDefaults) {
31886
33190
  const rPr = rPrDefaults.elements?.find((el) => el.name === "w:rPr");
31887
33191
  const fonts = rPr?.elements?.find((el) => el.name === "w:rFonts");
31888
- typeface = fonts?.attributes["w:ascii"];
31889
- const fontSize2 = typeface ?? rPr?.elements?.find((el) => el.name === "w:sz")?.attributes["w:val"];
31890
- fontSizeNormal = !fontSizeNormal && fontSize2 ? Number(fontSize2) / 2 : null;
33192
+ if (fonts?.attributes?.["w:ascii"]) {
33193
+ typeface = fonts.attributes["w:ascii"];
33194
+ }
33195
+ const fontSizeRaw = rPr?.elements?.find((el) => el.name === "w:sz")?.attributes?.["w:val"];
33196
+ if (!fontSizeNormal && fontSizeRaw) {
33197
+ fontSizeNormal = Number(fontSizeRaw) / 2;
33198
+ }
31891
33199
  }
31892
- const fontSizePt = fontSizeNormal || Number(rElements.find((el) => el.name === "w:sz")?.attributes["w:val"]) / 2 || 10;
33200
+ const fallbackSz = Number(rElements.find((el) => el.name === "w:sz")?.attributes?.["w:val"]);
33201
+ const fontSizePt = fontSizeNormal ?? (Number.isFinite(fallbackSz) ? fallbackSz / 2 : void 0) ?? 10;
31893
33202
  const kern = rElements.find((el) => el.name === "w:kern")?.attributes["w:val"];
31894
- return { fontSizePt, kern, typeface, panose };
33203
+ const fontFamilyCss = _SuperConverter2.toCssFontFamily(typeface, this.convertedXml);
33204
+ return { fontSizePt, kern, typeface, panose, fontFamilyCss };
31895
33205
  }
31896
33206
  }
31897
33207
  getDocumentFonts() {
@@ -43728,6 +45038,96 @@ const toggleMark = (typeOrName, attrs = {}, options = {}) => ({ state: state2, c
43728
45038
  if (isActive2) return commands2.unsetMark(type2, { extendEmptyMarkRange });
43729
45039
  return commands2.setMark(type2, attrs);
43730
45040
  };
45041
+ const toggleMarkCascade = (markName, options = {}) => ({ state: state2, chain, editor }) => {
45042
+ const {
45043
+ negationAttrs = { value: "0" },
45044
+ isNegation = (attrs) => attrs?.value === "0",
45045
+ styleDetector = defaultStyleDetector,
45046
+ extendEmptyMarkRange = true
45047
+ } = options;
45048
+ const selectionMarks = getMarksFromSelection(state2) || [];
45049
+ const inlineMarks = selectionMarks.filter((m2) => m2.type?.name === markName);
45050
+ const hasNegation = inlineMarks.some((m2) => isNegation(m2.attrs || {}));
45051
+ const hasInline = inlineMarks.some((m2) => !isNegation(m2.attrs || {}));
45052
+ const styleOn = styleDetector({ state: state2, selectionMarks, markName, editor });
45053
+ const cmdChain = chain();
45054
+ if (hasNegation) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
45055
+ if (hasInline && styleOn) {
45056
+ return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
45057
+ }
45058
+ if (hasInline) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
45059
+ if (styleOn) return cmdChain.setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
45060
+ return cmdChain.setMark(markName, {}, { extendEmptyMarkRange }).run();
45061
+ };
45062
+ function defaultStyleDetector({ state: state2, selectionMarks, markName, editor }) {
45063
+ try {
45064
+ const styleId = getEffectiveStyleId(state2, selectionMarks);
45065
+ if (!styleId || !editor?.converter?.linkedStyles) return false;
45066
+ const styles = editor.converter.linkedStyles;
45067
+ const seen = /* @__PURE__ */ new Set();
45068
+ let current = styleId;
45069
+ const key2 = mapMarkToStyleKey(markName);
45070
+ while (current && !seen.has(current)) {
45071
+ seen.add(current);
45072
+ const style2 = styles.find((s) => s.id === current);
45073
+ const def = style2?.definition?.styles || {};
45074
+ if (key2 in def) {
45075
+ const raw = def[key2];
45076
+ if (raw === void 0) return true;
45077
+ const val = raw?.value ?? raw;
45078
+ return isStyleTokenEnabled(val);
45079
+ }
45080
+ current = style2?.definition?.attrs?.basedOn || null;
45081
+ }
45082
+ return false;
45083
+ } catch {
45084
+ return false;
45085
+ }
45086
+ }
45087
+ function getEffectiveStyleId(state2, selectionMarks) {
45088
+ const sidFromMarks = getStyleIdFromMarks(selectionMarks);
45089
+ if (sidFromMarks) return sidFromMarks;
45090
+ const $from = state2.selection.$from;
45091
+ const before = $from.nodeBefore;
45092
+ const after = $from.nodeAfter;
45093
+ if (before && before.marks) {
45094
+ const sid = getStyleIdFromMarks(before.marks);
45095
+ if (sid) return sid;
45096
+ }
45097
+ if (after && after.marks) {
45098
+ const sid = getStyleIdFromMarks(after.marks);
45099
+ if (sid) return sid;
45100
+ }
45101
+ const ts = selectionMarks.find((m2) => m2.type?.name === "textStyle" && m2.attrs?.styleId);
45102
+ if (ts) return ts.attrs.styleId;
45103
+ const pos = state2.selection.$from.pos;
45104
+ const $pos = state2.doc.resolve(pos);
45105
+ for (let d2 = $pos.depth; d2 >= 0; d2--) {
45106
+ const n = $pos.node(d2);
45107
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
45108
+ }
45109
+ return null;
45110
+ }
45111
+ function getStyleIdFromMarks(marks) {
45112
+ if (!Array.isArray(marks)) return null;
45113
+ const textStyleMark = marks.find((m2) => m2.type?.name === "textStyle" && m2.attrs?.styleId);
45114
+ if (textStyleMark) return textStyleMark.attrs.styleId;
45115
+ return null;
45116
+ }
45117
+ function mapMarkToStyleKey(markName) {
45118
+ if (markName === "textStyle" || markName === "color") return "color";
45119
+ return markName;
45120
+ }
45121
+ function isStyleTokenEnabled(val) {
45122
+ if (val === false || val === 0) return false;
45123
+ if (typeof val === "string") {
45124
+ const normalized = val.trim().toLowerCase();
45125
+ if (!normalized) return false;
45126
+ if (["0", "false", "none", "inherit", "transparent"].includes(normalized)) return false;
45127
+ return true;
45128
+ }
45129
+ return !!val;
45130
+ }
43731
45131
  const clearNodes = () => ({ state: state2, tr, dispatch }) => {
43732
45132
  const { selection } = tr;
43733
45133
  const { ranges } = selection;
@@ -45073,11 +46473,14 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
45073
46473
  command,
45074
46474
  createParagraphNear,
45075
46475
  decreaseListIndent,
46476
+ defaultStyleDetector,
45076
46477
  deleteListItem,
45077
46478
  deleteSelection,
45078
46479
  exitCode,
45079
46480
  first,
46481
+ getEffectiveStyleId,
45080
46482
  getParaCtx,
46483
+ getStyleIdFromMarks,
45081
46484
  handleBackspaceNextToList,
45082
46485
  handleDeleteNextToList,
45083
46486
  increaseListIndent,
@@ -45086,12 +46489,14 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
45086
46489
  insertTabChar,
45087
46490
  insertTabCharacter,
45088
46491
  insertTabNode,
46492
+ isStyleTokenEnabled,
45089
46493
  joinBackward,
45090
46494
  joinDown,
45091
46495
  joinForward,
45092
46496
  joinUp,
45093
46497
  liftEmptyBlock,
45094
46498
  liftListItem,
46499
+ mapMarkToStyleKey,
45095
46500
  nearestListAt,
45096
46501
  newlineInCode,
45097
46502
  rebuildListNodeWithNewNum,
@@ -45111,6 +46516,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
45111
46516
  splitListItem,
45112
46517
  toggleList,
45113
46518
  toggleMark,
46519
+ toggleMarkCascade,
45114
46520
  toggleNode,
45115
46521
  undoInputRule,
45116
46522
  unsetAllMarks,
@@ -45126,6 +46532,7 @@ const Commands = Extension.create({
45126
46532
  });
45127
46533
  const handleEnter = (editor) => {
45128
46534
  return editor.commands.first(({ commands: commands2 }) => [
46535
+ () => commands2.splitRun(),
45129
46536
  () => commands2.newlineInCode(),
45130
46537
  () => commands2.createParagraphNear(),
45131
46538
  () => commands2.liftEmptyBlock(),
@@ -45159,6 +46566,7 @@ const Keymap = Extension.create({
45159
46566
  addShortcuts() {
45160
46567
  const baseKeymap = {
45161
46568
  Enter: () => handleEnter(this.editor),
46569
+ "Shift-Enter": () => this.editor.commands.insertLineBreak(),
45162
46570
  "Mod-Enter": () => this.editor.commands.exitCode(),
45163
46571
  Backspace: () => handleBackspace(this.editor),
45164
46572
  "Mod-Backspace": () => handleBackspace(this.editor),
@@ -46236,7 +47644,18 @@ const updateYdocDocxData = async (editor, ydoc) => {
46236
47644
  ydoc = ydoc || editor.options.ydoc;
46237
47645
  if (!ydoc) return;
46238
47646
  const metaMap = ydoc.getMap("meta");
46239
- const docx = [...metaMap.get("docx")];
47647
+ const docxValue = metaMap.get("docx");
47648
+ let docx = [];
47649
+ if (Array.isArray(docxValue)) {
47650
+ docx = [...docxValue];
47651
+ } else if (docxValue && typeof docxValue.toArray === "function") {
47652
+ docx = docxValue.toArray();
47653
+ } else if (docxValue && typeof docxValue[Symbol.iterator] === "function") {
47654
+ docx = Array.from(docxValue);
47655
+ }
47656
+ if (!docx.length && Array.isArray(editor.options.content)) {
47657
+ docx = [...editor.options.content];
47658
+ }
46240
47659
  const newXml = await editor.exportDocx({ getUpdatedDocs: true });
46241
47660
  Object.keys(newXml).forEach((key2) => {
46242
47661
  const fileIndex = docx.findIndex((item) => item.name === key2);
@@ -46314,7 +47733,7 @@ const createHeaderFooterEditor = ({
46314
47733
  currentPageNumber
46315
47734
  }) => {
46316
47735
  const parentStyles = editor.converter.getDocumentDefaultStyles();
46317
- const { fontSizePt, typeface } = parentStyles;
47736
+ const { fontSizePt, typeface, fontFamilyCss } = parentStyles;
46318
47737
  const fontSizeInPixles = fontSizePt * 1.3333;
46319
47738
  const lineHeight2 = fontSizeInPixles * 1.2;
46320
47739
  Object.assign(editorContainer.style, {
@@ -46327,7 +47746,7 @@ const createHeaderFooterEditor = ({
46327
47746
  left: "0",
46328
47747
  width: "auto",
46329
47748
  maxWidth: "none",
46330
- fontFamily: typeface,
47749
+ fontFamily: fontFamilyCss || typeface,
46331
47750
  fontSize: `${fontSizeInPixles}px`,
46332
47751
  lineHeight: `${lineHeight2}px`
46333
47752
  });
@@ -47157,7 +48576,6 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
47157
48576
  originalStep,
47158
48577
  originalStepIndex
47159
48578
  });
47160
- console.debug("[track-changes]: replaceStep");
47161
48579
  } else if (step instanceof AddMarkStep) {
47162
48580
  addMarkStep({
47163
48581
  state: state2,
@@ -47167,7 +48585,6 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
47167
48585
  user,
47168
48586
  date
47169
48587
  });
47170
- console.debug("[track-changes]: addMarkStep");
47171
48588
  } else if (step instanceof RemoveMarkStep) {
47172
48589
  removeMarkStep({
47173
48590
  state: state2,
@@ -47177,10 +48594,8 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
47177
48594
  user,
47178
48595
  date
47179
48596
  });
47180
- console.debug("[track-changes]: removeMarkStep");
47181
48597
  } else {
47182
48598
  newTr.step(step);
47183
- console.log("[track-changes]: otherStep");
47184
48599
  }
47185
48600
  });
47186
48601
  if (tr.getMeta("inputType")) {
@@ -49250,9 +50665,10 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
49250
50665
  element.style.isolation = "isolate";
49251
50666
  proseMirror.style.outline = "none";
49252
50667
  proseMirror.style.border = "none";
49253
- const { typeface, fontSizePt } = this.converter.getDocumentDefaultStyles() ?? {};
49254
- if (typeface) {
49255
- element.style.fontFamily = typeface;
50668
+ const { typeface, fontSizePt, fontFamilyCss } = this.converter.getDocumentDefaultStyles() ?? {};
50669
+ const resolvedFontFamily = fontFamilyCss || typeface;
50670
+ if (resolvedFontFamily) {
50671
+ element.style.fontFamily = resolvedFontFamily;
49256
50672
  }
49257
50673
  if (fontSizePt) {
49258
50674
  element.style.fontSize = `${fontSizePt}pt`;
@@ -49540,12 +50956,15 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
49540
50956
  }
49541
50957
  destroyHeaderFooterEditors() {
49542
50958
  try {
49543
- const editors = [...this.converter.headerEditors, ...this.converter.footerEditors];
50959
+ const headerEditors = this.converter?.headerEditors ?? [];
50960
+ const footerEditors = this.converter?.footerEditors ?? [];
50961
+ if (!headerEditors.length && !footerEditors.length) return;
50962
+ const editors = [...headerEditors, ...footerEditors].filter(Boolean);
49544
50963
  for (let editorData of editors) {
49545
- editorData.editor.destroy();
50964
+ editorData?.editor?.destroy?.();
49546
50965
  }
49547
- this.converter.headerEditors.length = 0;
49548
- this.converter.footerEditors.length = 0;
50966
+ if (headerEditors.length) headerEditors.length = 0;
50967
+ if (footerEditors.length) footerEditors.length = 0;
49549
50968
  } catch (error) {
49550
50969
  this.emit("exception", { error, editor: this });
49551
50970
  console.error(error);
@@ -50619,6 +52038,7 @@ const FormatCommands = Extension.create({
50619
52038
  },
50620
52039
  addCommands() {
50621
52040
  return {
52041
+ toggleMarkCascade,
50622
52042
  /**
50623
52043
  * Clear all formatting (nodes and marks)
50624
52044
  * @category Command
@@ -51598,27 +53018,69 @@ const Text = Node$1.create({
51598
53018
  return {};
51599
53019
  }
51600
53020
  });
51601
- const RunItem = Node$1.create({
53021
+ const splitRun = () => (props) => {
53022
+ const { state: state2, view, tr } = props;
53023
+ const { $from, empty: empty2 } = state2.selection;
53024
+ if (!empty2) return false;
53025
+ if ($from.parent.type.name !== "run") return false;
53026
+ const handled = splitBlock(state2, (transaction) => {
53027
+ view.dispatch(transaction);
53028
+ });
53029
+ if (handled) {
53030
+ tr.setMeta("preventDispatch", true);
53031
+ }
53032
+ return handled;
53033
+ };
53034
+ const Run = OxmlNode.create({
51602
53035
  name: "run",
53036
+ oXmlName: "w:r",
51603
53037
  group: "inline",
51604
- content: "text*",
51605
53038
  inline: true,
53039
+ content: "inline*",
53040
+ selectable: false,
53041
+ childToAttributes: ["runProperties"],
51606
53042
  addOptions() {
51607
- return {};
51608
- },
51609
- parseDOM() {
51610
- return [{ tag: "run" }];
51611
- },
51612
- renderDOM() {
51613
- return ["run", 0];
53043
+ return {
53044
+ htmlAttributes: {
53045
+ "data-run": "1"
53046
+ }
53047
+ };
51614
53048
  },
51615
53049
  addAttributes() {
51616
53050
  return {
51617
- attributes: {
53051
+ runProperties: {
53052
+ default: null,
51618
53053
  rendered: false,
51619
- "aria-label": "Run node"
53054
+ keepOnSplit: true
53055
+ },
53056
+ rsidR: {
53057
+ default: null,
53058
+ rendered: false,
53059
+ keepOnSplit: true
53060
+ },
53061
+ rsidRPr: {
53062
+ default: null,
53063
+ rendered: false,
53064
+ keepOnSplit: true
53065
+ },
53066
+ rsidDel: {
53067
+ default: null,
53068
+ rendered: false,
53069
+ keepOnSplit: true
51620
53070
  }
51621
53071
  };
53072
+ },
53073
+ addCommands() {
53074
+ return {
53075
+ splitRun
53076
+ };
53077
+ },
53078
+ parseDOM() {
53079
+ return [{ tag: "span[data-run]" }];
53080
+ },
53081
+ renderDOM({ htmlAttributes }) {
53082
+ const base2 = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
53083
+ return ["span", base2, 0];
51622
53084
  }
51623
53085
  });
51624
53086
  const inputRegex$1 = /^\s*([-+*])\s$/;
@@ -51893,6 +53355,115 @@ const OrderedList = Node$1.create({
51893
53355
  ];
51894
53356
  }
51895
53357
  });
53358
+ const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
53359
+ const handler2 = listIndexMap[listNumberingType];
53360
+ return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
53361
+ };
53362
+ const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
53363
+ const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
53364
+ const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
53365
+ const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
53366
+ const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
53367
+ const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
53368
+ const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
53369
+ const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
53370
+ const listIndexMap = {
53371
+ decimal: handleDecimal,
53372
+ lowerRoman: handleLowerRoman,
53373
+ upperRoman: handleRoman,
53374
+ lowerLetter: handleLowerAlpha,
53375
+ upperLetter: handleAlpha,
53376
+ ordinal: handleOrdinal,
53377
+ custom: handleCustom,
53378
+ japaneseCounting: handleJapaneseCounting
53379
+ };
53380
+ const createNumbering = (values, lvlText) => {
53381
+ return values.reduce((acc, value, index2) => {
53382
+ return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
53383
+ }, lvlText);
53384
+ };
53385
+ const generateNumbering = (path, lvlText, formatter) => {
53386
+ const formattedValues = path.map(formatter);
53387
+ return createNumbering(formattedValues, lvlText);
53388
+ };
53389
+ const ordinalFormatter = (level) => {
53390
+ const suffixes = ["th", "st", "nd", "rd"];
53391
+ const value = level % 100;
53392
+ const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
53393
+ const p = level + suffix2;
53394
+ return p;
53395
+ };
53396
+ const generateFromCustom = (path, lvlText, customFormat) => {
53397
+ if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
53398
+ const match = customFormat.match(/(\d+)/);
53399
+ if (!match) throw new Error("Invalid format string: no numeric pattern found");
53400
+ const sample = match[1];
53401
+ const digitCount = sample.length;
53402
+ const index2 = path.pop();
53403
+ return String(index2).padStart(digitCount, "0");
53404
+ };
53405
+ const intToRoman = (num) => {
53406
+ const romanNumeralMap = [
53407
+ { value: 1e3, numeral: "M" },
53408
+ { value: 900, numeral: "CM" },
53409
+ { value: 500, numeral: "D" },
53410
+ { value: 400, numeral: "CD" },
53411
+ { value: 100, numeral: "C" },
53412
+ { value: 90, numeral: "XC" },
53413
+ { value: 50, numeral: "L" },
53414
+ { value: 40, numeral: "XL" },
53415
+ { value: 10, numeral: "X" },
53416
+ { value: 9, numeral: "IX" },
53417
+ { value: 5, numeral: "V" },
53418
+ { value: 4, numeral: "IV" },
53419
+ { value: 1, numeral: "I" }
53420
+ ];
53421
+ let result = "";
53422
+ for (const { value, numeral } of romanNumeralMap) {
53423
+ while (num >= value) {
53424
+ result += numeral;
53425
+ num -= value;
53426
+ }
53427
+ }
53428
+ return result;
53429
+ };
53430
+ const intToAlpha = (num) => {
53431
+ let result = "";
53432
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
53433
+ while (num > 0) {
53434
+ let index2 = (num - 1) % 26;
53435
+ result = alphabet[index2] + result;
53436
+ num = Math.floor((num - 1) / 26);
53437
+ }
53438
+ return result;
53439
+ };
53440
+ const intToJapaneseCounting = (num) => {
53441
+ const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
53442
+ const units = ["", "十", "百", "千"];
53443
+ if (num === 0) return "零";
53444
+ if (num < 10) return digits[num];
53445
+ let result = "";
53446
+ let tempNum = num;
53447
+ let unitIndex = 0;
53448
+ while (tempNum > 0) {
53449
+ const digit = tempNum % 10;
53450
+ if (digit !== 0) {
53451
+ const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
53452
+ result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
53453
+ } else if (result && tempNum > 0) {
53454
+ if (!result.startsWith("零") && tempNum % 100 !== 0) {
53455
+ result = "零" + result;
53456
+ }
53457
+ }
53458
+ tempNum = Math.floor(tempNum / 10);
53459
+ unitIndex++;
53460
+ if (unitIndex > 3) break;
53461
+ }
53462
+ if (num >= 10 && num < 20) {
53463
+ result = result.replace(/^一十/, "十");
53464
+ }
53465
+ return result;
53466
+ };
51896
53467
  const CustomSelectionPluginKey = new PluginKey("CustomSelection");
51897
53468
  const handleClickOutside = (event, editor) => {
51898
53469
  const editorElem = editor?.options?.element;
@@ -52173,6 +53744,7 @@ const getMarksStyle = (attrs) => {
52173
53744
  case "textStyle":
52174
53745
  const { fontFamily: fontFamily2, fontSize: fontSize2 } = attr.attrs;
52175
53746
  styles += `${fontFamily2 ? `font-family: ${fontFamily2};` : ""} ${fontSize2 ? `font-size: ${fontSize2};` : ""}`;
53747
+ break;
52176
53748
  }
52177
53749
  }
52178
53750
  return styles.trim();
@@ -52191,12 +53763,22 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52191
53763
  const linkedDefinitionStyles = { ...linkedStyle.definition.styles };
52192
53764
  const basedOnDefinitionStyles = { ...basedOnStyle?.definition?.styles };
52193
53765
  const resultStyles = { ...linkedDefinitionStyles };
52194
- if (!linkedDefinitionStyles["font-size"] && basedOnDefinitionStyles["font-size"]) {
52195
- resultStyles["font-size"] = basedOnDefinitionStyles["font-size"];
52196
- }
52197
- if (!linkedDefinitionStyles["text-transform"] && basedOnDefinitionStyles["text-transform"]) {
52198
- resultStyles["text-transform"] = basedOnDefinitionStyles["text-transform"];
52199
- }
53766
+ const inheritKeys = [
53767
+ "font-size",
53768
+ "font-family",
53769
+ "text-transform",
53770
+ "bold",
53771
+ "italic",
53772
+ "underline",
53773
+ "strike",
53774
+ "color",
53775
+ "highlight"
53776
+ ];
53777
+ inheritKeys.forEach((k) => {
53778
+ if (!linkedDefinitionStyles[k] && basedOnDefinitionStyles[k]) {
53779
+ resultStyles[k] = basedOnDefinitionStyles[k];
53780
+ }
53781
+ });
52200
53782
  Object.entries(resultStyles).forEach(([k, value]) => {
52201
53783
  const key2 = kebabCase$1(k);
52202
53784
  const flattenedMarks = [];
@@ -52211,6 +53793,10 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52211
53793
  }
52212
53794
  flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
52213
53795
  });
53796
+ const underlineNone = node?.marks?.some((m2) => m2.type?.name === "underline" && m2.attrs?.underlineType === "none");
53797
+ if (underlineNone) {
53798
+ markValue["text-decoration"] = "none";
53799
+ }
52214
53800
  const mark = flattenedMarks.find((n) => n.key === key2);
52215
53801
  const hasParentIndent = Object.keys(parent?.attrs?.indent || {});
52216
53802
  const hasParentSpacing = Object.keys(parent?.attrs?.spacing || {});
@@ -52227,10 +53813,28 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52227
53813
  if (rightIndent) markValue["margin-right"] = rightIndent + "px";
52228
53814
  if (firstLine) markValue["text-indent"] = firstLine + "px";
52229
53815
  } else if (key2 === "bold" && node) {
52230
- const val = value?.value;
52231
- if (!listTypes.includes(node.type.name) && val !== "0") {
53816
+ const boldValue = typeof value === "object" && value !== null ? value.value : value;
53817
+ const hasInlineBoldOff = node.marks?.some((m2) => m2.type?.name === "bold" && m2.attrs?.value === "0");
53818
+ const hasInlineBoldOn = node.marks?.some((m2) => m2.type?.name === "bold" && m2.attrs?.value !== "0");
53819
+ if (!listTypes.includes(node.type.name) && !hasInlineBoldOff && !hasInlineBoldOn && boldValue !== "0" && boldValue !== false) {
52232
53820
  markValue["font-weight"] = "bold";
52233
53821
  }
53822
+ } else if (key2 === "italic" && node) {
53823
+ const italicValue = typeof value === "object" && value !== null ? value.value : value;
53824
+ const hasInlineItalicOff = node.marks?.some((m2) => m2.type?.name === "italic" && m2.attrs?.value === "0");
53825
+ const hasInlineItalicOn = node.marks?.some((m2) => m2.type?.name === "italic" && m2.attrs?.value !== "0");
53826
+ if (!listTypes.includes(node.type.name) && !hasInlineItalicOff && !hasInlineItalicOn && italicValue !== "0" && italicValue !== false) {
53827
+ markValue["font-style"] = "italic";
53828
+ }
53829
+ } else if (key2 === "strike" && node) {
53830
+ const strikeValue = typeof value === "object" && value !== null ? value.value : value;
53831
+ const hasInlineStrikeOff = node.marks?.some((m2) => m2.type?.name === "strike" && m2.attrs?.value === "0");
53832
+ const hasInlineStrikeOn = node.marks?.some(
53833
+ (m2) => m2.type?.name === "strike" && (m2.attrs?.value === void 0 || m2.attrs?.value !== "0")
53834
+ );
53835
+ if (!listTypes.includes(node.type.name) && !hasInlineStrikeOff && !hasInlineStrikeOn && strikeValue !== "0" && strikeValue !== false) {
53836
+ markValue["text-decoration"] = "line-through";
53837
+ }
52234
53838
  } else if (key2 === "text-transform" && node) {
52235
53839
  if (!listTypes.includes(node.type.name)) {
52236
53840
  markValue[key2] = value;
@@ -52239,10 +53843,44 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52239
53843
  if (!listTypes.includes(node.type.name)) {
52240
53844
  markValue[key2] = value;
52241
53845
  }
53846
+ } else if (key2 === "font-family" && node) {
53847
+ if (!listTypes.includes(node.type.name)) {
53848
+ markValue[key2] = value;
53849
+ }
52242
53850
  } else if (key2 === "color" && node) {
52243
53851
  if (!listTypes.includes(node.type.name)) {
52244
53852
  markValue[key2] = value;
52245
53853
  }
53854
+ } else if (key2 === "highlight" && node) {
53855
+ const hasInlineHighlight = node.marks?.some((m2) => m2.type?.name === "highlight");
53856
+ if (!listTypes.includes(node.type.name) && !hasInlineHighlight) {
53857
+ const color = typeof value === "string" ? value : value?.color;
53858
+ if (color) markValue["background-color"] = color;
53859
+ }
53860
+ } else if (key2 === "underline" && node) {
53861
+ const styleValRaw = value?.value ?? value ?? "";
53862
+ const styleVal = styleValRaw.toString().toLowerCase();
53863
+ const hasInlineUnderlineOff = node.marks?.some(
53864
+ (m2) => m2.type?.name === "underline" && m2.attrs?.underlineType === "none"
53865
+ );
53866
+ const hasInlineUnderlineOn = node.marks?.some(
53867
+ (m2) => m2.type?.name === "underline" && m2.attrs?.underlineType && m2.attrs.underlineType !== "none"
53868
+ );
53869
+ if (!listTypes.includes(node.type.name) && !hasInlineUnderlineOff && !hasInlineUnderlineOn) {
53870
+ if (styleVal && styleVal !== "none" && styleVal !== "0") {
53871
+ const colorVal = value && typeof value === "object" ? value.color || value.underlineColor || null : null;
53872
+ const css = getUnderlineCssString({ type: styleVal, color: colorVal });
53873
+ css.split(";").forEach((decl) => {
53874
+ const d2 = decl.trim();
53875
+ if (!d2) return;
53876
+ const idx = d2.indexOf(":");
53877
+ if (idx === -1) return;
53878
+ const k2 = d2.slice(0, idx).trim();
53879
+ const v2 = d2.slice(idx + 1).trim();
53880
+ markValue[k2] = v2;
53881
+ });
53882
+ }
53883
+ }
52246
53884
  } else if (typeof value === "string") {
52247
53885
  markValue[key2] = value;
52248
53886
  }
@@ -52375,23 +54013,51 @@ const createLinkedStylesPlugin = (editor) => {
52375
54013
  };
52376
54014
  const generateDecorations = (state2, styles) => {
52377
54015
  const decorations = [];
52378
- let lastStyleId = null;
52379
54016
  const doc2 = state2?.doc;
54017
+ const getParagraphStyleId = (pos) => {
54018
+ const $pos = state2.doc.resolve(pos);
54019
+ for (let d2 = $pos.depth; d2 >= 0; d2--) {
54020
+ const n = $pos.node(d2);
54021
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
54022
+ }
54023
+ return null;
54024
+ };
52380
54025
  doc2.descendants((node, pos) => {
52381
54026
  const { name } = node.type;
52382
- if (node?.attrs?.styleId) lastStyleId = node.attrs.styleId;
52383
- if (name === "paragraph" && !node.attrs?.styleId) lastStyleId = null;
52384
- if (name !== "text" && name !== "listItem" && name !== "orderedList") return;
54027
+ if (name !== "text") return;
54028
+ const paragraphStyleId = getParagraphStyleId(pos);
54029
+ let runStyleId = null;
54030
+ let inlineTextStyleId = null;
52385
54031
  for (const mark of node.marks) {
52386
- if (mark.type.name === "textStyle" && mark.attrs.styleId) {
52387
- lastStyleId = mark.attrs.styleId;
52388
- }
52389
- }
52390
- const { linkedStyle, basedOnStyle } = getLinkedStyle(lastStyleId, styles);
52391
- if (!linkedStyle) return;
54032
+ if (mark.type.name === "run") {
54033
+ const rp = mark.attrs?.runProperties;
54034
+ if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
54035
+ else if (Array.isArray(rp)) {
54036
+ const ent = rp.find((e) => e?.xmlName === "w:rStyle");
54037
+ const sid = ent?.attributes?.["w:val"];
54038
+ if (sid) runStyleId = sid;
54039
+ }
54040
+ } else if (mark.type.name === "textStyle" && mark.attrs?.styleId) {
54041
+ inlineTextStyleId = mark.attrs.styleId;
54042
+ }
54043
+ }
54044
+ const buildStyleMap = (sid) => {
54045
+ if (!sid) return {};
54046
+ const { linkedStyle, basedOnStyle: basedOnStyle2 } = getLinkedStyle(sid, styles);
54047
+ if (!linkedStyle) return {};
54048
+ const base2 = { ...basedOnStyle2?.definition?.styles || {} };
54049
+ return { ...base2, ...linkedStyle.definition?.styles || {} };
54050
+ };
54051
+ const pMap = buildStyleMap(paragraphStyleId);
54052
+ const tMap = buildStyleMap(inlineTextStyleId);
54053
+ const rMap = buildStyleMap(runStyleId);
54054
+ const finalStyles = { ...pMap, ...tMap, ...rMap };
54055
+ if (Object.keys(finalStyles).length === 0) return;
54056
+ const mergedLinkedStyle = { definition: { styles: finalStyles, attrs: {} } };
54057
+ const basedOnStyle = null;
52392
54058
  const $pos = state2.doc.resolve(pos);
52393
54059
  const parent = $pos.parent;
52394
- const styleString = generateLinkedStyleString(linkedStyle, basedOnStyle, node, parent);
54060
+ const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node, parent);
52395
54061
  if (!styleString) return;
52396
54062
  const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
52397
54063
  decorations.push(decoration);
@@ -52520,115 +54186,298 @@ const LinkedStyles = Extension.create({
52520
54186
  };
52521
54187
  }
52522
54188
  });
52523
- const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
52524
- const handler2 = listIndexMap[listNumberingType];
52525
- return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
52526
- };
52527
- const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
52528
- const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
52529
- const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
52530
- const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
52531
- const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
52532
- const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
52533
- const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
52534
- const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
52535
- const listIndexMap = {
52536
- decimal: handleDecimal,
52537
- lowerRoman: handleLowerRoman,
52538
- upperRoman: handleRoman,
52539
- lowerLetter: handleLowerAlpha,
52540
- upperLetter: handleAlpha,
52541
- ordinal: handleOrdinal,
52542
- custom: handleCustom,
52543
- japaneseCounting: handleJapaneseCounting
52544
- };
52545
- const createNumbering = (values, lvlText) => {
52546
- return values.reduce((acc, value, index2) => {
52547
- return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
52548
- }, lvlText);
52549
- };
52550
- const generateNumbering = (path, lvlText, formatter) => {
52551
- const formattedValues = path.map(formatter);
52552
- return createNumbering(formattedValues, lvlText);
52553
- };
52554
- const ordinalFormatter = (level) => {
52555
- const suffixes = ["th", "st", "nd", "rd"];
52556
- const value = level % 100;
52557
- const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
52558
- const p = level + suffix2;
52559
- return p;
52560
- };
52561
- const generateFromCustom = (path, lvlText, customFormat) => {
52562
- if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
52563
- const match = customFormat.match(/(\d+)/);
52564
- if (!match) throw new Error("Invalid format string: no numeric pattern found");
52565
- const sample = match[1];
52566
- const digitCount = sample.length;
52567
- const index2 = path.pop();
52568
- return String(index2).padStart(digitCount, "0");
52569
- };
52570
- const intToRoman = (num) => {
52571
- const romanNumeralMap = [
52572
- { value: 1e3, numeral: "M" },
52573
- { value: 900, numeral: "CM" },
52574
- { value: 500, numeral: "D" },
52575
- { value: 400, numeral: "CD" },
52576
- { value: 100, numeral: "C" },
52577
- { value: 90, numeral: "XC" },
52578
- { value: 50, numeral: "L" },
52579
- { value: 40, numeral: "XL" },
52580
- { value: 10, numeral: "X" },
52581
- { value: 9, numeral: "IX" },
52582
- { value: 5, numeral: "V" },
52583
- { value: 4, numeral: "IV" },
52584
- { value: 1, numeral: "I" }
52585
- ];
52586
- let result = "";
52587
- for (const { value, numeral } of romanNumeralMap) {
52588
- while (num >= value) {
52589
- result += numeral;
52590
- num -= value;
54189
+ function getUnderlineCssString({ type: type2 = "single", color = null, thickness = null, approximate = true } = {}) {
54190
+ const parts = [];
54191
+ const add = (k, v2) => {
54192
+ if (!v2) return;
54193
+ parts.push(`${k}: ${v2}`);
54194
+ };
54195
+ const lower = String(type2 || "single").toLowerCase();
54196
+ if (lower === "none" || lower === "0") {
54197
+ add("text-decoration", "none");
54198
+ return parts.join("; ");
54199
+ }
54200
+ add("text-decoration-line", "underline");
54201
+ const HEAVY = thickness || "0.2em";
54202
+ const THICK = thickness || "0.15em";
54203
+ switch (lower) {
54204
+ case "single":
54205
+ break;
54206
+ case "double":
54207
+ add("text-decoration-style", "double");
54208
+ break;
54209
+ case "thick":
54210
+ add("text-decoration-thickness", THICK);
54211
+ break;
54212
+ case "dotted":
54213
+ add("text-decoration-style", "dotted");
54214
+ break;
54215
+ case "dash":
54216
+ case "dashed":
54217
+ add("text-decoration-style", "dashed");
54218
+ break;
54219
+ case "dotdash":
54220
+ case "dotdotdash":
54221
+ case "dashlong":
54222
+ case "dashlongheavy":
54223
+ if (approximate) {
54224
+ add("text-decoration-style", "dashed");
54225
+ if (lower.includes("heavy")) add("text-decoration-thickness", HEAVY);
54226
+ }
54227
+ break;
54228
+ case "dottedheavy":
54229
+ add("text-decoration-style", "dotted");
54230
+ add("text-decoration-thickness", HEAVY);
54231
+ break;
54232
+ case "dashedheavy":
54233
+ add("text-decoration-style", "dashed");
54234
+ add("text-decoration-thickness", HEAVY);
54235
+ break;
54236
+ case "wavy":
54237
+ add("text-decoration-style", "wavy");
54238
+ break;
54239
+ case "wavyheavy":
54240
+ add("text-decoration-style", "wavy");
54241
+ add("text-decoration-thickness", HEAVY);
54242
+ break;
54243
+ case "wavydouble":
54244
+ if (approximate) {
54245
+ add("text-decoration-style", "wavy");
54246
+ add("text-decoration-thickness", HEAVY);
54247
+ }
54248
+ break;
54249
+ }
54250
+ if (color) add("text-decoration-color", color);
54251
+ return parts.join("; ");
54252
+ }
54253
+ function collectTextStyleMarks(listItem, markType) {
54254
+ const textStyleMarks = [];
54255
+ const seenMarks = /* @__PURE__ */ new Set();
54256
+ const attrs = {};
54257
+ if (!markType) {
54258
+ return {
54259
+ marks: textStyleMarks,
54260
+ attrs
54261
+ };
54262
+ }
54263
+ const collectMarks = (node) => {
54264
+ if (!node) return;
54265
+ const candidateMarks = Array.isArray(node.marks) ? node.marks : [];
54266
+ if (candidateMarks.length && typeof markType.isInSet === "function" && markType.isInSet(candidateMarks)) {
54267
+ candidateMarks.forEach((mark) => {
54268
+ if (mark.type === markType && !seenMarks.has(mark)) {
54269
+ seenMarks.add(mark);
54270
+ textStyleMarks.push(mark);
54271
+ }
54272
+ });
54273
+ }
54274
+ if (!node.isText && node.childCount) {
54275
+ node.forEach((child) => collectMarks(child));
54276
+ }
54277
+ };
54278
+ listItem.forEach((childNode) => {
54279
+ if (childNode.type?.name !== "paragraph") return;
54280
+ if (childNode.attrs?.lineHeight !== void 0) {
54281
+ attrs.lineHeight = childNode.attrs.lineHeight;
52591
54282
  }
54283
+ collectMarks(childNode);
54284
+ });
54285
+ return {
54286
+ marks: textStyleMarks,
54287
+ attrs
54288
+ };
54289
+ }
54290
+ function parseSizeFromRunProperties(listRunProperties) {
54291
+ const val = listRunProperties?.["w:val"] || listRunProperties?.["w:sz"];
54292
+ if (val == null) return null;
54293
+ const numeric = Number(val);
54294
+ if (Number.isNaN(numeric) || numeric <= 0) return null;
54295
+ const sizeInPoints = numeric / 2;
54296
+ return `${sizeInPoints}pt`;
54297
+ }
54298
+ function parseFontFamilyFromRunProperties(listRunProperties) {
54299
+ const ascii = listRunProperties?.["w:ascii"];
54300
+ const hAnsi = listRunProperties?.["w:hAnsi"];
54301
+ const eastAsia = listRunProperties?.["w:eastAsia"];
54302
+ return ascii || hAnsi || eastAsia || null;
54303
+ }
54304
+ function readNodeViewStyles(view) {
54305
+ const fallback = { fontSize: null, fontFamily: null, lineHeight: null };
54306
+ if (!view?.dom) return fallback;
54307
+ const inline = {
54308
+ fontSize: view.dom.style?.fontSize || null,
54309
+ fontFamily: view.dom.style?.fontFamily || null,
54310
+ lineHeight: view.dom.style?.lineHeight || null
54311
+ };
54312
+ if (inline.fontSize && inline.fontFamily && inline.lineHeight) return inline;
54313
+ const globalWindow = typeof window !== "undefined" ? window : void 0;
54314
+ if (globalWindow?.getComputedStyle) {
54315
+ const computed2 = globalWindow.getComputedStyle(view.dom);
54316
+ return {
54317
+ fontSize: inline.fontSize || computed2.fontSize,
54318
+ fontFamily: inline.fontFamily || computed2.fontFamily,
54319
+ lineHeight: inline.lineHeight || computed2.lineHeight
54320
+ };
52592
54321
  }
52593
- return result;
52594
- };
52595
- const intToAlpha = (num) => {
52596
- let result = "";
52597
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
52598
- while (num > 0) {
52599
- let index2 = (num - 1) % 26;
52600
- result = alphabet[index2] + result;
52601
- num = Math.floor((num - 1) / 26);
54322
+ return inline;
54323
+ }
54324
+ function getAdjacentListItemNodeView({ nodeView, pos, direction, activeNodeViews }) {
54325
+ if (!activeNodeViews) return null;
54326
+ let candidate = null;
54327
+ activeNodeViews.forEach((view) => {
54328
+ if (view === nodeView) return;
54329
+ let viewPos;
54330
+ try {
54331
+ viewPos = view.getPos();
54332
+ } catch {
54333
+ return;
54334
+ }
54335
+ if (typeof viewPos !== "number") return;
54336
+ if (viewPos < pos) {
54337
+ if (!candidate || viewPos > candidate.pos) candidate = { view, pos: viewPos };
54338
+ }
54339
+ });
54340
+ return candidate?.view ?? null;
54341
+ }
54342
+ function findSiblingListItem({ editor, pos, direction }) {
54343
+ if (typeof pos !== "number" || !editor?.view) return null;
54344
+ const { state: state2 } = editor.view;
54345
+ const $pos = state2.doc.resolve(pos);
54346
+ const parentDepth = $pos.depth - 1;
54347
+ if (parentDepth < 0) return null;
54348
+ const parent = $pos.node(parentDepth);
54349
+ if (!parent) return null;
54350
+ const indexInsideParent = $pos.index(parentDepth);
54351
+ const siblingIndex = indexInsideParent + direction;
54352
+ if (siblingIndex < 0 || siblingIndex >= parent.childCount) return null;
54353
+ const sibling = parent.child(siblingIndex);
54354
+ return sibling?.type?.name === "listItem" ? sibling : null;
54355
+ }
54356
+ function deriveFontStylesFromNode({ node, textStyleType, defaultFont, defaultSize, listRunProperties }) {
54357
+ const { marks: allMarks, attrs } = collectTextStyleMarks(node, textStyleType);
54358
+ const styleMarks = textStyleType ? allMarks.filter((m2) => m2.type === textStyleType) : [];
54359
+ const sizeMark = styleMarks.find((m2) => m2.attrs?.fontSize);
54360
+ const familyMark = styleMarks.find((m2) => m2.attrs?.fontFamily);
54361
+ let fontSize2 = defaultSize;
54362
+ if (sizeMark) {
54363
+ const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
54364
+ if (!Number.isNaN(value)) {
54365
+ fontSize2 = `${value}${unit}`;
54366
+ }
52602
54367
  }
52603
- return result;
52604
- };
52605
- const intToJapaneseCounting = (num) => {
52606
- const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
52607
- const units = ["", "十", "百", "千"];
52608
- if (num === 0) return "零";
52609
- if (num < 10) return digits[num];
52610
- let result = "";
52611
- let tempNum = num;
52612
- let unitIndex = 0;
52613
- while (tempNum > 0) {
52614
- const digit = tempNum % 10;
52615
- if (digit !== 0) {
52616
- const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
52617
- result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
52618
- } else if (result && tempNum > 0) {
52619
- if (!result.startsWith("零") && tempNum % 100 !== 0) {
52620
- result = "零" + result;
52621
- }
54368
+ let hasSize = Boolean(sizeMark);
54369
+ if (!hasSize && listRunProperties) {
54370
+ const sizeFromList = parseSizeFromRunProperties(listRunProperties);
54371
+ if (sizeFromList) {
54372
+ fontSize2 = sizeFromList;
54373
+ hasSize = true;
52622
54374
  }
52623
- tempNum = Math.floor(tempNum / 10);
52624
- unitIndex++;
52625
- if (unitIndex > 3) break;
52626
54375
  }
52627
- if (num >= 10 && num < 20) {
52628
- result = result.replace(/^一十/, "十");
54376
+ let fontFamily2 = familyMark?.attrs?.fontFamily ?? defaultFont;
54377
+ let hasFamily = Boolean(familyMark);
54378
+ if (!hasFamily && listRunProperties) {
54379
+ const fontFromList = parseFontFamilyFromRunProperties(listRunProperties);
54380
+ if (fontFromList) {
54381
+ fontFamily2 = fontFromList;
54382
+ hasFamily = true;
54383
+ }
52629
54384
  }
52630
- return result;
52631
- };
54385
+ let lineHeight2 = attrs.lineHeight;
54386
+ const firstChild = node.firstChild;
54387
+ const hasOnlyOnePar = node.childCount === 1 && firstChild?.type?.name === "paragraph";
54388
+ if (hasOnlyOnePar) {
54389
+ const par = firstChild;
54390
+ const parFirstChild = par?.firstChild;
54391
+ if (par?.childCount === 1 && parFirstChild?.type?.name === "fieldAnnotation") {
54392
+ const aFontSize = parFirstChild.attrs?.fontSize;
54393
+ const aFontFamily = parFirstChild.attrs?.fontFamily;
54394
+ if (!sizeMark && aFontSize) fontSize2 = aFontSize;
54395
+ if (!familyMark && aFontFamily) fontFamily2 = aFontFamily;
54396
+ }
54397
+ }
54398
+ return {
54399
+ fontSize: fontSize2,
54400
+ fontFamily: fontFamily2,
54401
+ lineHeight: lineHeight2,
54402
+ hasSize,
54403
+ hasFamily
54404
+ };
54405
+ }
54406
+ function getStylesFromLinkedStyles({ node, pos, editor }) {
54407
+ const { state: state2 } = editor.view;
54408
+ const linkedStyles = LinkedStylesPluginKey.getState(state2)?.decorations;
54409
+ const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
54410
+ const predicates = [
54411
+ (style22) => style22.includes("font-size") && style22.includes("font-family"),
54412
+ (style22) => style22.includes("font-size"),
54413
+ (style22) => style22.includes("font-family")
54414
+ ];
54415
+ let styleDeco;
54416
+ for (const predicateFn of predicates) {
54417
+ styleDeco = decorationsInPlace?.find((dec) => {
54418
+ const style22 = dec.type?.attrs?.style || "";
54419
+ return style22 && predicateFn(style22);
54420
+ });
54421
+ if (styleDeco) break;
54422
+ }
54423
+ const style2 = styleDeco?.type?.attrs?.style;
54424
+ const stylesArray = style2?.split(";") || [];
54425
+ const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1]?.trim();
54426
+ const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1]?.trim();
54427
+ return {
54428
+ font: fontFamilyFromStyles,
54429
+ size: fontSizeFromStyles
54430
+ };
54431
+ }
54432
+ function resolveListItemTypography({ node, pos, editor, nodeView, activeNodeViews }) {
54433
+ const defaults = getStylesFromLinkedStyles({ node, pos, editor });
54434
+ const textStyleType = getMarkType("textStyle", editor.schema);
54435
+ const currentStyles = deriveFontStylesFromNode({
54436
+ node,
54437
+ textStyleType,
54438
+ defaultFont: defaults.font,
54439
+ defaultSize: defaults.size,
54440
+ listRunProperties: node.attrs?.listRunProperties
54441
+ });
54442
+ if ((!currentStyles.hasSize || !currentStyles.hasFamily || !currentStyles.lineHeight) && editor?.view) {
54443
+ const previousListItem = findSiblingListItem({ editor, pos, direction: -1 });
54444
+ if (previousListItem) {
54445
+ const previousStyles = deriveFontStylesFromNode({
54446
+ node: previousListItem,
54447
+ textStyleType,
54448
+ defaultFont: defaults.font,
54449
+ defaultSize: defaults.size,
54450
+ listRunProperties: previousListItem.attrs?.listRunProperties
54451
+ });
54452
+ if (!currentStyles.hasSize && previousStyles.fontSize) currentStyles.fontSize = previousStyles.fontSize;
54453
+ if (!currentStyles.hasFamily && previousStyles.fontFamily) currentStyles.fontFamily = previousStyles.fontFamily;
54454
+ if (!currentStyles.lineHeight && previousStyles.lineHeight) currentStyles.lineHeight = previousStyles.lineHeight;
54455
+ }
54456
+ }
54457
+ if ((!currentStyles.fontSize || !currentStyles.fontFamily || !currentStyles.lineHeight) && nodeView) {
54458
+ const previousView = getAdjacentListItemNodeView({
54459
+ nodeView,
54460
+ pos,
54461
+ direction: -1,
54462
+ activeNodeViews
54463
+ });
54464
+ if (previousView) {
54465
+ const {
54466
+ fontSize: prevSize,
54467
+ fontFamily: prevFamily,
54468
+ lineHeight: prevLineHeight
54469
+ } = readNodeViewStyles(previousView);
54470
+ if (!currentStyles.fontSize && prevSize) currentStyles.fontSize = prevSize;
54471
+ if (!currentStyles.fontFamily && prevFamily) currentStyles.fontFamily = prevFamily;
54472
+ if (!currentStyles.lineHeight && prevLineHeight) currentStyles.lineHeight = prevLineHeight;
54473
+ }
54474
+ }
54475
+ return {
54476
+ fontSize: currentStyles.fontSize,
54477
+ fontFamily: currentStyles.fontFamily,
54478
+ lineHeight: currentStyles.lineHeight
54479
+ };
54480
+ }
52632
54481
  const MARKER_PADDING = 6;
52633
54482
  const MARKER_OFFSET_RIGHT = 4;
52634
54483
  const MIN_MARKER_WIDTH = 20;
@@ -52646,8 +54495,8 @@ class ListItemNodeView {
52646
54495
  this.decorations = decorations;
52647
54496
  this.view = editor.view;
52648
54497
  this.getPos = getPos;
52649
- activeListItemNodeViews.add(this);
52650
54498
  __privateMethod$1(this, _ListItemNodeView_instances, init_fn2).call(this);
54499
+ activeListItemNodeViews.add(this);
52651
54500
  }
52652
54501
  refreshIndentStyling() {
52653
54502
  const { attrs } = this.node;
@@ -52690,10 +54539,12 @@ class ListItemNodeView {
52690
54539
  update(node, decorations) {
52691
54540
  this.node = node;
52692
54541
  this.decorations = decorations;
52693
- const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = getTextStyleMarksFromLinkedStyles({
54542
+ const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = resolveListItemTypography({
52694
54543
  node,
52695
54544
  pos: this.getPos(),
52696
- editor: this.editor
54545
+ editor: this.editor,
54546
+ nodeView: this,
54547
+ activeNodeViews: activeListItemNodeViews
52697
54548
  });
52698
54549
  this.dom.style.fontSize = fontSize2;
52699
54550
  this.dom.style.fontFamily = fontFamily2 || "inherit";
@@ -52722,10 +54573,12 @@ init_fn2 = function() {
52722
54573
  }
52723
54574
  }
52724
54575
  const pos = this.getPos();
52725
- const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = getTextStyleMarksFromLinkedStyles({
54576
+ const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = resolveListItemTypography({
52726
54577
  node: this.node,
52727
54578
  pos,
52728
- editor: this.editor
54579
+ editor: this.editor,
54580
+ nodeView: this,
54581
+ activeNodeViews: activeListItemNodeViews
52729
54582
  });
52730
54583
  this.dom = document.createElement("li");
52731
54584
  this.dom.className = "sd-editor-list-item-node-view";
@@ -52758,79 +54611,6 @@ function refreshAllListItemNodeViews() {
52758
54611
  }
52759
54612
  });
52760
54613
  }
52761
- function getListItemTextStyleMarks(listItem, markType) {
52762
- let textStyleMarks = [];
52763
- let attrs = {};
52764
- listItem.forEach((childNode) => {
52765
- if (childNode.type.name !== "paragraph") return;
52766
- attrs.lineHeight = childNode.attrs.lineHeight;
52767
- childNode.forEach((textNode) => {
52768
- let isTextNode = textNode.type.name === "text";
52769
- let hasTextStyleMarks = markType.isInSet(textNode.marks);
52770
- if (isTextNode && hasTextStyleMarks) {
52771
- let marks = textNode.marks.filter((mark) => mark.type === markType);
52772
- textStyleMarks.push(...marks);
52773
- }
52774
- });
52775
- });
52776
- return {
52777
- marks: textStyleMarks,
52778
- attrs
52779
- };
52780
- }
52781
- function getTextStyleMarksFromLinkedStyles({ node, pos, editor }) {
52782
- const { font: defaultFont, size: defaultSize } = getStylesFromLinkedStyles({ node, pos, editor });
52783
- const textStyleType = getMarkType("textStyle", editor.schema);
52784
- const { marks: allMarks, attrs: allAttrs } = getListItemTextStyleMarks(node, textStyleType);
52785
- const styleMarks = allMarks.filter((m2) => m2.type === textStyleType);
52786
- const sizeMark = styleMarks.find((m2) => m2.attrs.fontSize);
52787
- const familyMark = styleMarks.find((m2) => m2.attrs.fontFamily);
52788
- const lineHeight2 = allAttrs.lineHeight;
52789
- let fontSize2 = sizeMark ? (() => {
52790
- const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
52791
- return Number.isNaN(value) ? defaultSize : `${value}${unit}`;
52792
- })() : defaultSize;
52793
- let fontFamily2 = familyMark?.attrs.fontFamily ?? defaultFont;
52794
- const firstChild = node.firstChild;
52795
- const hasOnlyOnePar = node.childCount === 1 && firstChild?.type.name === "paragraph";
52796
- if (hasOnlyOnePar) {
52797
- const par = firstChild;
52798
- const parFirstChild = par?.firstChild;
52799
- if (par?.childCount === 1 && parFirstChild?.type.name === "fieldAnnotation") {
52800
- const aFontSize = parFirstChild.attrs.fontSize;
52801
- const aFontFamily = parFirstChild.attrs.fontFamily;
52802
- if (!sizeMark && aFontSize) fontSize2 = aFontSize;
52803
- if (!familyMark && aFontFamily) fontFamily2 = aFontFamily;
52804
- }
52805
- }
52806
- return { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 };
52807
- }
52808
- const getStylesFromLinkedStyles = ({ node, pos, editor }) => {
52809
- const { state: state2 } = editor.view;
52810
- const linkedStyles = LinkedStylesPluginKey.getState(state2)?.decorations;
52811
- const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
52812
- const predicates = [
52813
- (style22) => style22.includes("font-size") && style22.includes("font-family"),
52814
- (style22) => style22.includes("font-size"),
52815
- (style22) => style22.includes("font-family")
52816
- ];
52817
- let styleDeco;
52818
- for (const predicateFn of predicates) {
52819
- styleDeco = decorationsInPlace?.find((dec) => {
52820
- const style22 = dec.type.attrs?.style || "";
52821
- return style22 && predicateFn(style22);
52822
- });
52823
- if (styleDeco) break;
52824
- }
52825
- const style2 = styleDeco?.type.attrs?.style;
52826
- const stylesArray = style2?.split(";") || [];
52827
- const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1].trim();
52828
- const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1].trim();
52829
- return {
52830
- font: fontFamilyFromStyles,
52831
- size: fontSizeFromStyles
52832
- };
52833
- };
52834
54614
  const getVisibleIndent = (stylePpr, numDefPpr, inlineIndent) => {
52835
54615
  const styleIndentTag = stylePpr?.elements?.find((el) => el.name === "w:ind") || {};
52836
54616
  const styleIndent = parseIndentElement(styleIndentTag);
@@ -53564,6 +55344,211 @@ const CommentsMark = Mark2.create({
53564
55344
  return [CommentMarkName, Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
53565
55345
  }
53566
55346
  });
55347
+ const defaultTabDistance = 48;
55348
+ const defaultLineLength = 816;
55349
+ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
55350
+ const decorations = [];
55351
+ const paragraphCache = /* @__PURE__ */ new Map();
55352
+ const end2 = to ?? doc2.content.size;
55353
+ doc2.nodesBetween(from2, end2, (node, pos) => {
55354
+ if (node.type.name !== "tab") return;
55355
+ let extraStyles = "";
55356
+ const $pos = doc2.resolve(pos);
55357
+ const paragraphContext = getParagraphContext($pos, paragraphCache);
55358
+ if (!paragraphContext) return;
55359
+ try {
55360
+ const { tabStops, flattened, startPos } = paragraphContext;
55361
+ const entryIndex = flattened.findIndex((entry) => entry.pos === pos);
55362
+ if (entryIndex === -1) return;
55363
+ const indentWidth = getIndentWidth(view, startPos, paragraphContext.indent);
55364
+ const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
55365
+ const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos) + accumulatedTabWidth;
55366
+ let tabWidth;
55367
+ if (tabStops.length) {
55368
+ const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
55369
+ if (tabStop) {
55370
+ tabWidth = tabStop.pos - currentWidth;
55371
+ if (tabStop.val === "center" || tabStop.val === "end" || tabStop.val === "right") {
55372
+ const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
55373
+ const segmentStartPos = pos + node.nodeSize;
55374
+ const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
55375
+ const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos);
55376
+ tabWidth -= tabStop.val === "center" ? segmentWidth / 2 : segmentWidth;
55377
+ } else if (tabStop.val === "decimal" || tabStop.val === "num") {
55378
+ const breakChar = tabStop.decimalChar || ".";
55379
+ const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
55380
+ const integralWidth = decimalPos ? measureRangeWidth(view, pos + node.nodeSize, decimalPos) : measureRangeWidth(view, pos + node.nodeSize, startPos + paragraphContext.paragraph.nodeSize - 1);
55381
+ tabWidth -= integralWidth;
55382
+ }
55383
+ if (tabStop.leader) {
55384
+ const leaderStyles = {
55385
+ dot: "border-bottom: 1px dotted black;",
55386
+ heavy: "border-bottom: 2px solid black;",
55387
+ hyphen: "border-bottom: 1px solid black;",
55388
+ middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
55389
+ underscore: "border-bottom: 1px solid black;"
55390
+ };
55391
+ extraStyles += leaderStyles[tabStop.leader] || "";
55392
+ }
55393
+ }
55394
+ }
55395
+ if (!tabWidth || tabWidth < 1) {
55396
+ tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
55397
+ if (tabWidth === 0) tabWidth = defaultTabDistance;
55398
+ }
55399
+ const tabHeight = calcTabHeight($pos);
55400
+ decorations.push(
55401
+ Decoration.node(pos, pos + node.nodeSize, {
55402
+ style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
55403
+ })
55404
+ );
55405
+ paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
55406
+ } catch (error) {
55407
+ console.error("tab decoration error", error);
55408
+ }
55409
+ });
55410
+ return decorations;
55411
+ };
55412
+ function getParagraphContext($pos, cache2) {
55413
+ for (let depth = $pos.depth; depth >= 0; depth--) {
55414
+ const node = $pos.node(depth);
55415
+ if (node?.type?.name === "paragraph") {
55416
+ const startPos = $pos.start(depth);
55417
+ if (!cache2.has(startPos)) {
55418
+ cache2.set(startPos, {
55419
+ paragraph: node,
55420
+ paragraphDepth: depth,
55421
+ startPos,
55422
+ indent: node.attrs?.indent || {},
55423
+ tabStops: Array.isArray(node.attrs?.tabStops) ? node.attrs.tabStops : [],
55424
+ flattened: flattenParagraph(node, startPos),
55425
+ accumulatedTabWidth: 0
55426
+ });
55427
+ }
55428
+ return cache2.get(startPos);
55429
+ }
55430
+ }
55431
+ return null;
55432
+ }
55433
+ function flattenParagraph(paragraph, paragraphStartPos) {
55434
+ const entries = [];
55435
+ const walk = (node, basePos) => {
55436
+ if (!node) return;
55437
+ if (node.type?.name === "run") {
55438
+ node.forEach((child, offset2) => {
55439
+ const childPos = basePos + offset2 + 1;
55440
+ walk(child, childPos);
55441
+ });
55442
+ return;
55443
+ }
55444
+ entries.push({ node, pos: basePos - 1 });
55445
+ };
55446
+ paragraph.forEach((child, offset2) => {
55447
+ const childPos = paragraphStartPos + offset2 + 1;
55448
+ walk(child, childPos);
55449
+ });
55450
+ return entries;
55451
+ }
55452
+ function findNextTabIndex(flattened, fromIndex) {
55453
+ for (let i = fromIndex; i < flattened.length; i++) {
55454
+ if (flattened[i]?.node?.type?.name === "tab") {
55455
+ return i;
55456
+ }
55457
+ }
55458
+ return -1;
55459
+ }
55460
+ function findDecimalBreakPos(flattened, startIndex, breakChar) {
55461
+ for (let i = startIndex; i < flattened.length; i++) {
55462
+ const entry = flattened[i];
55463
+ if (!entry) break;
55464
+ if (entry.node.type?.name === "tab") break;
55465
+ if (entry.node.type?.name === "text") {
55466
+ const index2 = entry.node.text?.indexOf(breakChar);
55467
+ if (index2 !== void 0 && index2 !== -1) {
55468
+ return entry.pos + index2 + 1;
55469
+ }
55470
+ }
55471
+ }
55472
+ return null;
55473
+ }
55474
+ function measureRangeWidth(view, from2, to) {
55475
+ if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
55476
+ try {
55477
+ const range2 = document.createRange();
55478
+ const fromRef = view.domAtPos(from2);
55479
+ const toRef = view.domAtPos(to);
55480
+ range2.setStart(fromRef.node, fromRef.offset);
55481
+ range2.setEnd(toRef.node, toRef.offset);
55482
+ const rect = range2.getBoundingClientRect();
55483
+ range2.detach?.();
55484
+ return rect.width || 0;
55485
+ } catch {
55486
+ const startLeft = getLeftCoord(view, from2);
55487
+ const endLeft = getLeftCoord(view, to);
55488
+ if (startLeft == null || endLeft == null) return 0;
55489
+ return Math.max(0, endLeft - startLeft);
55490
+ }
55491
+ }
55492
+ function getIndentWidth(view, paragraphStartPos, indentAttrs = {}) {
55493
+ const marginLeft = getLeftCoord(view, paragraphStartPos);
55494
+ const lineLeft = getLeftCoord(view, paragraphStartPos + 1);
55495
+ if (marginLeft != null && lineLeft != null) {
55496
+ const diff = lineLeft - marginLeft;
55497
+ if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
55498
+ return diff;
55499
+ }
55500
+ }
55501
+ return calculateIndentFallback(indentAttrs);
55502
+ }
55503
+ function calculateIndentFallback(indentAttrs = {}) {
55504
+ if (!indentAttrs) return 0;
55505
+ const left2 = Number(indentAttrs.left) || 0;
55506
+ const firstLine = Number(indentAttrs.firstLine) || 0;
55507
+ const hanging = Number(indentAttrs.hanging) || 0;
55508
+ let textIndent = 0;
55509
+ if (firstLine && hanging) {
55510
+ textIndent = firstLine - hanging;
55511
+ } else if (firstLine) {
55512
+ textIndent = firstLine;
55513
+ } else if (hanging) {
55514
+ textIndent = -hanging;
55515
+ } else if (typeof indentAttrs.textIndent === "string") {
55516
+ const match = indentAttrs.textIndent.match(/(-?\d*\.?\d+)in$/);
55517
+ if (match) {
55518
+ textIndent = Number(match[1]) * 96;
55519
+ }
55520
+ }
55521
+ if (textIndent) return left2 + textIndent;
55522
+ if (left2) return left2;
55523
+ return 0;
55524
+ }
55525
+ function getLeftCoord(view, pos) {
55526
+ if (!Number.isFinite(pos)) return null;
55527
+ try {
55528
+ return view.coordsAtPos(pos).left;
55529
+ } catch {
55530
+ try {
55531
+ const ref2 = view.domAtPos(pos);
55532
+ const range2 = document.createRange();
55533
+ range2.setStart(ref2.node, ref2.offset);
55534
+ range2.setEnd(ref2.node, ref2.offset);
55535
+ const rect = range2.getBoundingClientRect();
55536
+ range2.detach?.();
55537
+ return rect.left;
55538
+ } catch {
55539
+ return null;
55540
+ }
55541
+ }
55542
+ }
55543
+ function calcTabHeight(pos) {
55544
+ const ptToPxRatio = 1.333;
55545
+ const defaultFontSize = 16;
55546
+ const defaultLineHeight = 1.1;
55547
+ const blockParent2 = pos.node(1);
55548
+ const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
55549
+ const fontSize2 = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
55550
+ return `${fontSize2 * defaultLineHeight}px`;
55551
+ }
53567
55552
  const TabNode = Node$1.create({
53568
55553
  name: "tab",
53569
55554
  group: "inline",
@@ -53601,8 +55586,7 @@ const TabNode = Node$1.create({
53601
55586
  };
53602
55587
  },
53603
55588
  addPmPlugins() {
53604
- const { view, schema } = this.editor;
53605
- const domSerializer = DOMSerializer.fromSchema(schema);
55589
+ const { view } = this.editor;
53606
55590
  const tabPlugin = new Plugin({
53607
55591
  name: "tabPlugin",
53608
55592
  key: new PluginKey("tabPlugin"),
@@ -53612,10 +55596,7 @@ const TabNode = Node$1.create({
53612
55596
  },
53613
55597
  apply(tr, { decorations }, _oldState, newState) {
53614
55598
  if (!decorations) {
53615
- decorations = DecorationSet.create(
53616
- newState.doc,
53617
- getTabDecorations(newState.doc, StepMap.empty, view, domSerializer)
53618
- );
55599
+ decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view));
53619
55600
  }
53620
55601
  if (!tr.docChanged) {
53621
55602
  return { decorations };
@@ -53655,8 +55636,7 @@ const TabNode = Node$1.create({
53655
55636
  rangesToRecalculate.forEach(([start2, end2]) => {
53656
55637
  const oldDecorations = decorations.find(start2, end2);
53657
55638
  decorations = decorations.remove(oldDecorations);
53658
- const invertMapping = tr.mapping.invert();
53659
- const newDecorations = getTabDecorations(newState.doc, invertMapping, view, domSerializer, start2, end2);
55639
+ const newDecorations = getTabDecorations(newState.doc, view, start2, end2);
53660
55640
  decorations = decorations.add(newState.doc, newDecorations);
53661
55641
  });
53662
55642
  return { decorations };
@@ -53671,156 +55651,6 @@ const TabNode = Node$1.create({
53671
55651
  return [tabPlugin];
53672
55652
  }
53673
55653
  });
53674
- const defaultTabDistance = 48;
53675
- const defaultLineLength = 816;
53676
- const getTabDecorations = (doc2, invertMapping, view, domSerializer, from2 = 0, to = null) => {
53677
- if (!to) {
53678
- to = doc2.content.size;
53679
- }
53680
- const nodeWidthCache = {};
53681
- let decorations = [];
53682
- doc2.nodesBetween(from2, to, (node, pos, parent) => {
53683
- if (node.type.name === "tab") {
53684
- let extraStyles = "";
53685
- const $pos = doc2.resolve(pos);
53686
- const tabIndex = $pos.index($pos.depth);
53687
- const fistlineIndent = parent.attrs?.indent?.firstLine || 0;
53688
- const currentWidth = calcChildNodesWidth(
53689
- parent,
53690
- pos - $pos.parentOffset,
53691
- 0,
53692
- tabIndex,
53693
- domSerializer,
53694
- view,
53695
- invertMapping,
53696
- nodeWidthCache
53697
- ) + fistlineIndent;
53698
- let tabWidth;
53699
- if ($pos.depth === 1 && parent.attrs.tabStops && parent.attrs.tabStops.length > 0) {
53700
- const tabStop = parent.attrs.tabStops.find((tabStop2) => tabStop2.pos > currentWidth && tabStop2.val !== "clear");
53701
- if (tabStop) {
53702
- tabWidth = tabStop.pos - currentWidth;
53703
- if (["end", "center"].includes(tabStop.val)) {
53704
- let nextTabIndex = tabIndex + 1;
53705
- while (nextTabIndex < parent.childCount && parent.child(nextTabIndex).type.name !== "tab") {
53706
- nextTabIndex++;
53707
- }
53708
- const tabSectionWidth = calcChildNodesWidth(
53709
- parent,
53710
- pos - $pos.parentOffset,
53711
- tabIndex,
53712
- nextTabIndex,
53713
- domSerializer,
53714
- view,
53715
- invertMapping,
53716
- nodeWidthCache
53717
- );
53718
- tabWidth -= tabStop.val === "end" ? tabSectionWidth : tabSectionWidth / 2;
53719
- } else if (["decimal", "num"].includes(tabStop.val)) {
53720
- const breakChar = ".";
53721
- let nodeIndex = tabIndex + 1;
53722
- let integralWidth = 0;
53723
- let nodePos = pos - $pos.parentOffset;
53724
- while (nodeIndex < parent.childCount) {
53725
- const node2 = parent.child(nodeIndex);
53726
- if (node2.type.name === "tab") {
53727
- break;
53728
- }
53729
- const oldPos = invertMapping.map(nodePos);
53730
- if (node2.type.name === "text" && node2.text.includes(breakChar)) {
53731
- const modifiedNode = node2.cut(0, node2.text.indexOf(breakChar));
53732
- integralWidth += calcNodeWidth(domSerializer, modifiedNode, view, oldPos);
53733
- break;
53734
- }
53735
- integralWidth += calcNodeWidth(domSerializer, node2, view, oldPos);
53736
- nodeWidthCache[nodePos] = integralWidth;
53737
- nodePos += node2.nodeSize;
53738
- nodeIndex += 1;
53739
- }
53740
- tabWidth -= integralWidth;
53741
- }
53742
- if (tabStop.leader) {
53743
- if (tabStop.leader === "dot") {
53744
- extraStyles += `border-bottom: 1px dotted black;`;
53745
- } else if (tabStop.leader === "heavy") {
53746
- extraStyles += `border-bottom: 2px solid black;`;
53747
- } else if (tabStop.leader === "hyphen") {
53748
- extraStyles += `border-bottom: 1px solid black;`;
53749
- } else if (tabStop.leader === "middleDot") {
53750
- extraStyles += `border-bottom: 1px dotted black; margin-bottom: 2px;`;
53751
- } else if (tabStop.leader === "underscore") {
53752
- extraStyles += `border-bottom: 1px solid black;`;
53753
- }
53754
- }
53755
- }
53756
- }
53757
- if (!tabWidth || tabWidth < 1) {
53758
- tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
53759
- if (tabWidth === 0) {
53760
- tabWidth = defaultTabDistance;
53761
- }
53762
- }
53763
- nodeWidthCache[pos] = tabWidth;
53764
- const tabHeight = calcTabHeight($pos);
53765
- decorations.push(
53766
- Decoration.node(pos, pos + node.nodeSize, {
53767
- style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
53768
- })
53769
- );
53770
- }
53771
- });
53772
- return decorations;
53773
- };
53774
- function calcNodeWidth(domSerializer, node, view, oldPos) {
53775
- const oldDomNode = view.nodeDOM(oldPos);
53776
- const styleReference = oldDomNode ? oldDomNode.nodeName === "#text" ? oldDomNode.parentNode : oldDomNode : view.dom;
53777
- const temp = document.createElement("div");
53778
- const style2 = window.getComputedStyle(styleReference);
53779
- temp.style.cssText = `
53780
- position: absolute;
53781
- top: -9999px;
53782
- left: -9999px;
53783
- white-space: nowrap;
53784
- font-family: ${style2.fontFamily};
53785
- font-size: ${style2.fontSize};
53786
- font-weight: ${style2.fontWeight};
53787
- font-style: ${style2.fontStyle};
53788
- letter-spacing: ${style2.letterSpacing};
53789
- word-spacing: ${style2.wordSpacing};
53790
- text-transform: ${style2.textTransform};
53791
- display: inline-block;
53792
- `;
53793
- const domNode = domSerializer.serializeNode(node);
53794
- temp.appendChild(domNode);
53795
- document.body.appendChild(temp);
53796
- const width = temp.offsetWidth;
53797
- document.body.removeChild(temp);
53798
- return width;
53799
- }
53800
- function calcChildNodesWidth(parent, parentPos, startIndex, endIndex, domSerializer, view, invertMapping, nodeWidthCache) {
53801
- let pos = parentPos;
53802
- let width = 0;
53803
- for (let i = 0; i < endIndex; i++) {
53804
- const node = parent.child(i);
53805
- if (i >= startIndex) {
53806
- if (!nodeWidthCache[pos]) {
53807
- nodeWidthCache[pos] = calcNodeWidth(domSerializer, node, view, invertMapping.map(pos));
53808
- }
53809
- width += nodeWidthCache[pos];
53810
- }
53811
- pos += node.nodeSize;
53812
- }
53813
- return width;
53814
- }
53815
- function calcTabHeight(pos) {
53816
- const ptToPxRatio = 1.333;
53817
- const defaultFontSize = 16;
53818
- const defaultLineHeight = 1.1;
53819
- const blockParent2 = pos.node(1);
53820
- const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
53821
- const fontSize2 = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
53822
- return `${fontSize2 * defaultLineHeight}px`;
53823
- }
53824
55654
  const LineBreak = Node$1.create({
53825
55655
  name: "lineBreak",
53826
55656
  group: "inline",
@@ -59487,10 +61317,10 @@ const Image = Node$1.create({
59487
61317
  },
59488
61318
  padding: {
59489
61319
  default: {},
59490
- renderDOM: ({ size: size2 = {}, padding, marginOffset, transformData }) => {
61320
+ renderDOM: ({ size: size2 = {}, padding, marginOffset, transformData = {} }) => {
59491
61321
  let { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
59492
- const { rotation } = transformData ?? {};
59493
- const { height, width } = size2 ?? {};
61322
+ const { rotation } = transformData;
61323
+ const { height, width } = size2;
59494
61324
  if (rotation && height && width) {
59495
61325
  const { horizontal, vertical } = getRotationMargins(width, height, rotation);
59496
61326
  left2 += horizontal;
@@ -61281,6 +63111,30 @@ const TextStyle = Mark2.create({
61281
63111
  };
61282
63112
  }
61283
63113
  });
63114
+ function createCascadeToggleCommands({
63115
+ markName,
63116
+ setCommand,
63117
+ unsetCommand,
63118
+ toggleCommand,
63119
+ negationAttrs,
63120
+ isNegation,
63121
+ extendEmptyMarkRange
63122
+ } = {}) {
63123
+ if (!markName) throw new Error("createCascadeToggleCommands requires a markName");
63124
+ const capitalized = markName.charAt(0).toUpperCase() + markName.slice(1);
63125
+ const setName = setCommand ?? `set${capitalized}`;
63126
+ const unsetName = unsetCommand ?? `unset${capitalized}`;
63127
+ const toggleName = toggleCommand ?? `toggle${capitalized}`;
63128
+ const cascadeOptions = {};
63129
+ if (negationAttrs) cascadeOptions.negationAttrs = negationAttrs;
63130
+ if (typeof isNegation === "function") cascadeOptions.isNegation = isNegation;
63131
+ if (extendEmptyMarkRange !== void 0) cascadeOptions.extendEmptyMarkRange = extendEmptyMarkRange;
63132
+ return {
63133
+ [setName]: () => ({ commands: commands2 }) => commands2.setMark(markName),
63134
+ [unsetName]: () => ({ commands: commands2 }) => commands2.unsetMark(markName),
63135
+ [toggleName]: () => ({ commands: commands2 }) => commands2.toggleMarkCascade(markName, cascadeOptions)
63136
+ };
63137
+ }
61284
63138
  const Bold = Mark2.create({
61285
63139
  name: "bold",
61286
63140
  addOptions() {
@@ -61311,9 +63165,18 @@ const Bold = Mark2.create({
61311
63165
  ];
61312
63166
  },
61313
63167
  renderDOM({ htmlAttributes }) {
61314
- return ["strong", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63168
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63169
+ const { value, ...rest } = merged || {};
63170
+ if (value === "0") {
63171
+ return ["span", rest, 0];
63172
+ }
63173
+ return ["strong", rest, 0];
61315
63174
  },
61316
63175
  addCommands() {
63176
+ const { setBold, unsetBold, toggleBold } = createCascadeToggleCommands({
63177
+ markName: this.name,
63178
+ negationAttrs: { value: "0" }
63179
+ });
61317
63180
  return {
61318
63181
  /**
61319
63182
  * Apply bold formatting
@@ -61322,21 +63185,21 @@ const Bold = Mark2.create({
61322
63185
  * editor.commands.setBold()
61323
63186
  * @note '0' renders as normal weight
61324
63187
  */
61325
- setBold: () => ({ commands: commands2 }) => commands2.setMark(this.name),
63188
+ setBold,
61326
63189
  /**
61327
63190
  * Remove bold formatting
61328
63191
  * @category Command
61329
63192
  * @example
61330
63193
  * editor.commands.unsetBold()
61331
63194
  */
61332
- unsetBold: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
63195
+ unsetBold,
61333
63196
  /**
61334
63197
  * Toggle bold formatting
61335
63198
  * @category Command
61336
63199
  * @example
61337
63200
  * editor.commands.toggleBold()
61338
63201
  */
61339
- toggleBold: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
63202
+ toggleBold
61340
63203
  };
61341
63204
  },
61342
63205
  addShortcuts() {
@@ -61353,6 +63216,22 @@ const Italic = Mark2.create({
61353
63216
  htmlAttributes: {}
61354
63217
  };
61355
63218
  },
63219
+ addAttributes() {
63220
+ return {
63221
+ /**
63222
+ * @category Attribute
63223
+ * @param {string} [value] - Italic toggle value ('0' renders as normal)
63224
+ */
63225
+ value: {
63226
+ default: null,
63227
+ renderDOM: (attrs) => {
63228
+ if (!attrs.value) return {};
63229
+ if (attrs.value === "0") return { style: "font-style: normal" };
63230
+ return {};
63231
+ }
63232
+ }
63233
+ };
63234
+ },
61356
63235
  parseDOM() {
61357
63236
  return [
61358
63237
  { tag: "i" },
@@ -61362,9 +63241,18 @@ const Italic = Mark2.create({
61362
63241
  ];
61363
63242
  },
61364
63243
  renderDOM({ htmlAttributes }) {
61365
- return ["em", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63244
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63245
+ const { value, ...rest } = merged || {};
63246
+ if (value === "0") {
63247
+ return ["span", rest, 0];
63248
+ }
63249
+ return ["em", rest, 0];
61366
63250
  },
61367
63251
  addCommands() {
63252
+ const { setItalic, unsetItalic, toggleItalic } = createCascadeToggleCommands({
63253
+ markName: this.name,
63254
+ negationAttrs: { value: "0" }
63255
+ });
61368
63256
  return {
61369
63257
  /**
61370
63258
  * Apply italic formatting
@@ -61372,21 +63260,21 @@ const Italic = Mark2.create({
61372
63260
  * @example
61373
63261
  * editor.commands.setItalic()
61374
63262
  */
61375
- setItalic: () => ({ commands: commands2 }) => commands2.setMark(this.name),
63263
+ setItalic,
61376
63264
  /**
61377
63265
  * Remove italic formatting
61378
63266
  * @category Command
61379
63267
  * @example
61380
63268
  * editor.commands.unsetItalic()
61381
63269
  */
61382
- unsetItalic: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
63270
+ unsetItalic,
61383
63271
  /**
61384
63272
  * Toggle italic formatting
61385
63273
  * @category Command
61386
63274
  * @example
61387
63275
  * editor.commands.toggleItalic()
61388
63276
  */
61389
- toggleItalic: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
63277
+ toggleItalic
61390
63278
  };
61391
63279
  },
61392
63280
  addShortcuts() {
@@ -61411,7 +63299,16 @@ const Underline = Mark2.create({
61411
63299
  ];
61412
63300
  },
61413
63301
  renderDOM({ htmlAttributes }) {
61414
- return ["u", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63302
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63303
+ const type2 = merged?.underlineType;
63304
+ const color = merged?.underlineColor;
63305
+ const css = getUnderlineCssString({ type: type2, color });
63306
+ const { style: style2, ...rest } = merged || {};
63307
+ const styleString = [style2, css].filter(Boolean).join("; ");
63308
+ if (type2 === "none") {
63309
+ return ["span", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
63310
+ }
63311
+ return ["u", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
61415
63312
  },
61416
63313
  addAttributes() {
61417
63314
  return {
@@ -61421,10 +63318,18 @@ const Underline = Mark2.create({
61421
63318
  */
61422
63319
  underlineType: {
61423
63320
  default: "single"
63321
+ },
63322
+ underlineColor: {
63323
+ default: null
61424
63324
  }
61425
63325
  };
61426
63326
  },
61427
63327
  addCommands() {
63328
+ const { setUnderline, unsetUnderline, toggleUnderline } = createCascadeToggleCommands({
63329
+ markName: this.name,
63330
+ negationAttrs: { underlineType: "none" },
63331
+ isNegation: (attrs) => attrs?.underlineType === "none"
63332
+ });
61428
63333
  return {
61429
63334
  /**
61430
63335
  * Apply underline formatting
@@ -61433,7 +63338,7 @@ const Underline = Mark2.create({
61433
63338
  * @example
61434
63339
  * setUnderline()
61435
63340
  */
61436
- setUnderline: () => ({ commands: commands2 }) => commands2.setMark(this.name),
63341
+ setUnderline,
61437
63342
  /**
61438
63343
  * Remove underline formatting
61439
63344
  * @category Command
@@ -61441,7 +63346,7 @@ const Underline = Mark2.create({
61441
63346
  * @example
61442
63347
  * unsetUnderline()
61443
63348
  */
61444
- unsetUnderline: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
63349
+ unsetUnderline,
61445
63350
  /**
61446
63351
  * Toggle underline formatting
61447
63352
  * @category Command
@@ -61449,7 +63354,7 @@ const Underline = Mark2.create({
61449
63354
  * @example
61450
63355
  * toggleUnderline()
61451
63356
  */
61452
- toggleUnderline: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
63357
+ toggleUnderline
61453
63358
  };
61454
63359
  },
61455
63360
  addShortcuts() {
@@ -61537,9 +63442,18 @@ const Strike = Mark2.create({
61537
63442
  ];
61538
63443
  },
61539
63444
  renderDOM({ htmlAttributes }) {
61540
- return ["s", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63445
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63446
+ const { value, ...rest } = merged || {};
63447
+ if (value === "0") {
63448
+ return ["span", rest, 0];
63449
+ }
63450
+ return ["s", rest, 0];
61541
63451
  },
61542
63452
  addCommands() {
63453
+ const { setStrike, unsetStrike, toggleStrike } = createCascadeToggleCommands({
63454
+ markName: this.name,
63455
+ negationAttrs: { value: "0" }
63456
+ });
61543
63457
  return {
61544
63458
  /**
61545
63459
  * Apply strikethrough formatting
@@ -61547,26 +63461,38 @@ const Strike = Mark2.create({
61547
63461
  * @example
61548
63462
  * editor.commands.setStrike()
61549
63463
  */
61550
- setStrike: () => ({ commands: commands2 }) => {
61551
- return commands2.setMark(this.name);
61552
- },
63464
+ setStrike,
61553
63465
  /**
61554
63466
  * Remove strikethrough formatting
61555
63467
  * @category Command
61556
63468
  * @example
61557
63469
  * editor.commands.unsetStrike()
61558
63470
  */
61559
- unsetStrike: () => ({ commands: commands2 }) => {
61560
- return commands2.unsetMark(this.name);
61561
- },
63471
+ unsetStrike,
61562
63472
  /**
61563
63473
  * Toggle strikethrough formatting
61564
63474
  * @category Command
61565
63475
  * @example
61566
63476
  * editor.commands.toggleStrike()
61567
63477
  */
61568
- toggleStrike: () => ({ commands: commands2 }) => {
61569
- return commands2.toggleMark(this.name);
63478
+ toggleStrike
63479
+ };
63480
+ },
63481
+ addAttributes() {
63482
+ return {
63483
+ /**
63484
+ * @category Attribute
63485
+ * @param {string} [value] - Strike toggle value ('0' renders as normal)
63486
+ */
63487
+ value: {
63488
+ default: null,
63489
+ renderDOM: (attrs) => {
63490
+ if (!attrs.value) return {};
63491
+ if (attrs.value === "0") {
63492
+ return { style: "text-decoration: none" };
63493
+ }
63494
+ return {};
63495
+ }
61570
63496
  }
61571
63497
  };
61572
63498
  },
@@ -67707,7 +69633,7 @@ const getStarterExtensions = () => {
67707
69633
  Paragraph,
67708
69634
  LineBreak,
67709
69635
  HardBreak,
67710
- RunItem,
69636
+ Run,
67711
69637
  SlashMenu,
67712
69638
  Strike,
67713
69639
  TabNode,
@@ -80935,6 +82861,38 @@ const toolbarTexts = {
80935
82861
  documentViewingModeDescription: "View clean version of document only",
80936
82862
  linkedStyles: "Linked styles"
80937
82863
  };
82864
+ const isOffValue = (value) => {
82865
+ if (value == null) return false;
82866
+ const normalized = String(value).toLowerCase();
82867
+ return normalized === "0" || normalized === "false" || normalized === "off";
82868
+ };
82869
+ const negationChecks = {
82870
+ bold: (attrs = {}) => isOffValue(attrs.value),
82871
+ italic: (attrs = {}) => isOffValue(attrs.value),
82872
+ strike: (attrs = {}) => isOffValue(attrs.value),
82873
+ underline: (attrs = {}) => {
82874
+ const type2 = attrs.underlineType ?? attrs.value;
82875
+ if (type2 == null) return false;
82876
+ const normalized = String(type2).toLowerCase();
82877
+ return normalized === "none" || isOffValue(normalized);
82878
+ },
82879
+ color: (attrs = {}) => {
82880
+ const value = attrs.color;
82881
+ if (value == null) return true;
82882
+ return String(value).toLowerCase() === "inherit";
82883
+ },
82884
+ highlight: (attrs = {}) => {
82885
+ const value = attrs.color;
82886
+ if (value == null) return true;
82887
+ const normalized = String(value).toLowerCase();
82888
+ return normalized === "transparent" || normalized === "none";
82889
+ }
82890
+ };
82891
+ const isNegatedMark = (name, attrs = {}) => {
82892
+ const checker = negationChecks[name];
82893
+ if (typeof checker !== "function") return false;
82894
+ return Boolean(checker(attrs));
82895
+ };
80938
82896
  class SuperToolbar extends EventEmitter2 {
80939
82897
  /**
80940
82898
  * Creates a new SuperToolbar instance
@@ -81028,10 +82986,14 @@ class SuperToolbar extends EventEmitter2 {
81028
82986
  * @param {string} params.argument - The color to set
81029
82987
  * @returns {void}
81030
82988
  */
81031
- setColor: ({ item, argument }) => {
81032
- __privateMethod(this, _SuperToolbar_instances, runCommandWithArgumentOnly_fn).call(this, { item, argument }, () => {
81033
- this.activeEditor?.commands.setFieldAnnotationsTextColor(argument, true);
81034
- });
82989
+ setColor: ({ argument }) => {
82990
+ if (!argument || !this.activeEditor) return;
82991
+ const isNone = argument === "none";
82992
+ const value = isNone ? "inherit" : argument;
82993
+ if (this.activeEditor?.commands?.setColor) this.activeEditor.commands.setColor(value);
82994
+ const argValue = isNone ? null : argument;
82995
+ this.activeEditor?.commands.setFieldAnnotationsTextColor(argValue, true);
82996
+ this.updateToolbarState();
81035
82997
  },
81036
82998
  /**
81037
82999
  * Sets the highlight color for text
@@ -81040,12 +83002,14 @@ class SuperToolbar extends EventEmitter2 {
81040
83002
  * @param {string} params.argument - The highlight color to set
81041
83003
  * @returns {void}
81042
83004
  */
81043
- setHighlight: ({ item, argument }) => {
81044
- __privateMethod(this, _SuperToolbar_instances, runCommandWithArgumentOnly_fn).call(this, { item, argument, noArgumentCallback: true }, () => {
81045
- let arg = argument !== "none" ? argument : null;
81046
- this.activeEditor?.commands.setFieldAnnotationsTextHighlight(arg, true);
81047
- this.activeEditor?.commands.setCellBackground(arg);
81048
- });
83005
+ setHighlight: ({ argument }) => {
83006
+ if (!argument || !this.activeEditor) return;
83007
+ const inlineColor = argument !== "none" ? argument : "transparent";
83008
+ if (this.activeEditor?.commands?.setHighlight) this.activeEditor.commands.setHighlight(inlineColor);
83009
+ const argValue = argument !== "none" ? argument : null;
83010
+ this.activeEditor?.commands.setFieldAnnotationsTextHighlight(argValue, true);
83011
+ this.activeEditor?.commands.setCellBackground(argValue);
83012
+ this.updateToolbarState();
81049
83013
  },
81050
83014
  /**
81051
83015
  * Toggles the ruler visibility
@@ -81362,14 +83326,16 @@ class SuperToolbar extends EventEmitter2 {
81362
83326
  return item.activate();
81363
83327
  }
81364
83328
  }
81365
- const activeMark = marks.find((mark) => mark.name === item.name.value);
83329
+ const rawActiveMark = marks.find((mark) => mark.name === item.name.value);
83330
+ const markNegated = rawActiveMark ? isNegatedMark(rawActiveMark.name, rawActiveMark.attrs) : false;
83331
+ const activeMark = markNegated ? null : rawActiveMark;
81366
83332
  if (activeMark) {
81367
83333
  item.activate(activeMark.attrs);
81368
83334
  } else {
81369
83335
  item.deactivate();
81370
83336
  }
81371
83337
  const styleIdMark = marks.find((mark) => mark.name === "styleId");
81372
- if (!activeMark && styleIdMark?.attrs.styleId) {
83338
+ if (!activeMark && !markNegated && styleIdMark?.attrs.styleId) {
81373
83339
  const markToStyleMap = {
81374
83340
  fontSize: "font-size",
81375
83341
  fontFamily: "font-family",
@@ -81427,7 +83393,6 @@ class SuperToolbar extends EventEmitter2 {
81427
83393
  if (!command2) {
81428
83394
  return;
81429
83395
  }
81430
- this.log("(emmitCommand) Command:", command2, "\n item:", item, "\n argument:", argument, "\n option:", option);
81431
83396
  if (command2 in __privateGet(this, _interceptedCommands)) {
81432
83397
  return __privateGet(this, _interceptedCommands)[command2]({ item, argument });
81433
83398
  }
@@ -82990,6 +84955,36 @@ const _sfc_main = {
82990
84955
  }
82991
84956
  };
82992
84957
  const SuperInput = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4d5cff52"]]);
84958
+ const baseHandlers = {
84959
+ ...runPropertyTranslators,
84960
+ "w:br": translator$15,
84961
+ "w:cantSplit": translator$S,
84962
+ "w:cnfStyle": translator$R,
84963
+ "w:divId": translator$Q,
84964
+ "w:gridAfter": translator$P,
84965
+ "w:gridBefore": translator$O,
84966
+ "w:hidden": translator$N,
84967
+ "w:hyperlink": translator$6,
84968
+ "w:jc": translator$M,
84969
+ "w:p": translator$12,
84970
+ "w:r": translator$T,
84971
+ "w:rPr": translator$U,
84972
+ "w:sdt": translator$2,
84973
+ "w:tab": translator$13,
84974
+ "w:tblCellSpacing": translator$L,
84975
+ "w:tblHeader": translator$K,
84976
+ "w:tc": translator$7,
84977
+ "w:tr": translator$F,
84978
+ "w:trHeight": translator$J,
84979
+ "w:trPr": translator$G,
84980
+ "w:wAfter": translator$I,
84981
+ "w:wBefore": translator$H,
84982
+ "wp:anchor": translator$5,
84983
+ "wp:inline": translator$4,
84984
+ "w:bookmarkStart": translator$1,
84985
+ "w:bookmarkEnd": translator
84986
+ };
84987
+ const registeredHandlers = Object.freeze(baseHandlers);
82993
84988
  const Extensions = {
82994
84989
  Node: Node$1,
82995
84990
  Attribute: Attribute2,