pptx-react-viewer 1.25.4 → 1.25.5

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 (98) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/{Model3DScene-DZFYJPUH.mjs → Model3DScene-XVYOISVJ.mjs} +2 -2
  3. package/dist/Model3DScene-XVYOISVJ.mjs.br +0 -0
  4. package/dist/Model3DScene-XVYOISVJ.mjs.gz +0 -0
  5. package/dist/{Model3DScene-SP6WOKSX.js → Model3DScene-Y5ABLO7K.js} +3 -3
  6. package/dist/Model3DScene-Y5ABLO7K.js.br +0 -0
  7. package/dist/Model3DScene-Y5ABLO7K.js.gz +0 -0
  8. package/dist/{SurfaceChart3DScene-54BRNPQ5.mjs → SurfaceChart3DScene-RXZADECL.mjs} +2 -2
  9. package/dist/SurfaceChart3DScene-RXZADECL.mjs.br +0 -0
  10. package/dist/SurfaceChart3DScene-RXZADECL.mjs.gz +0 -0
  11. package/dist/{SurfaceChart3DScene-GISPZ4C2.js → SurfaceChart3DScene-WMY5JTW4.js} +3 -3
  12. package/dist/SurfaceChart3DScene-WMY5JTW4.js.br +0 -0
  13. package/dist/SurfaceChart3DScene-WMY5JTW4.js.gz +0 -0
  14. package/dist/{chunk-5VYVKFMS.js → chunk-7CSBUYRN.js} +808 -808
  15. package/dist/chunk-7CSBUYRN.js.br +0 -0
  16. package/dist/chunk-7CSBUYRN.js.gz +0 -0
  17. package/dist/{chunk-7FE27DDH.js → chunk-E55Q4AC7.js} +556 -476
  18. package/dist/chunk-E55Q4AC7.js.br +0 -0
  19. package/dist/chunk-E55Q4AC7.js.gz +0 -0
  20. package/dist/{chunk-P72VQ7WE.mjs → chunk-F4WPQRZU.mjs} +96 -16
  21. package/dist/chunk-F4WPQRZU.mjs.br +0 -0
  22. package/dist/chunk-F4WPQRZU.mjs.gz +0 -0
  23. package/dist/{chunk-UYNOPUSG.mjs → chunk-FOMF7POV.mjs} +1658 -353
  24. package/dist/chunk-FOMF7POV.mjs.br +0 -0
  25. package/dist/chunk-FOMF7POV.mjs.gz +0 -0
  26. package/dist/{chunk-VUC3UPLM.mjs → chunk-FVQDRA5N.mjs} +1044 -108
  27. package/dist/chunk-FVQDRA5N.mjs.br +0 -0
  28. package/dist/chunk-FVQDRA5N.mjs.gz +0 -0
  29. package/dist/{chunk-FWF2SP6N.js → chunk-IPYAN574.js} +1660 -352
  30. package/dist/chunk-IPYAN574.js.br +0 -0
  31. package/dist/chunk-IPYAN574.js.gz +0 -0
  32. package/dist/{chunk-TPG2WKHQ.mjs → chunk-L4ZADJOM.mjs} +6 -6
  33. package/dist/chunk-L4ZADJOM.mjs.br +0 -0
  34. package/dist/chunk-L4ZADJOM.mjs.gz +0 -0
  35. package/dist/{chunk-6F4WVHS3.js → chunk-TEN35NUX.js} +1077 -141
  36. package/dist/chunk-TEN35NUX.js.br +0 -0
  37. package/dist/chunk-TEN35NUX.js.gz +0 -0
  38. package/dist/{dist-QU6JIDAF.js → dist-755SJ3ZH.js} +574 -562
  39. package/dist/dist-755SJ3ZH.js.br +0 -0
  40. package/dist/dist-755SJ3ZH.js.gz +0 -0
  41. package/dist/dist-FFWP5NQZ.mjs +2 -0
  42. package/dist/dist-FFWP5NQZ.mjs.br +0 -0
  43. package/dist/dist-FFWP5NQZ.mjs.gz +0 -0
  44. package/dist/hooks-unstable.d.ts +243 -4
  45. package/dist/hooks-unstable.d.ts.map +1 -1
  46. package/dist/hooks-unstable.js +78 -78
  47. package/dist/hooks-unstable.js.br +0 -0
  48. package/dist/hooks-unstable.js.gz +0 -0
  49. package/dist/hooks-unstable.mjs +3 -3
  50. package/dist/hooks-unstable.mjs.br +0 -0
  51. package/dist/hooks-unstable.mjs.gz +0 -0
  52. package/dist/{index-DWvM1PBB.d.ts → index-J6IuHQ2_.d.ts} +21 -4
  53. package/dist/index-J6IuHQ2_.d.ts.map +1 -0
  54. package/dist/index.d.ts +223 -1
  55. package/dist/index.js +33 -33
  56. package/dist/index.js.br +0 -0
  57. package/dist/index.js.gz +0 -0
  58. package/dist/index.mjs +4 -4
  59. package/dist/index.mjs.br +0 -0
  60. package/dist/index.mjs.gz +0 -0
  61. package/dist/viewer/index.d.ts +223 -1
  62. package/dist/viewer/index.js +20 -20
  63. package/dist/viewer/index.js.br +0 -0
  64. package/dist/viewer/index.js.gz +0 -0
  65. package/dist/viewer/index.mjs +4 -4
  66. package/dist/viewer/index.mjs.br +0 -0
  67. package/dist/viewer/index.mjs.gz +0 -0
  68. package/package.json +1 -1
  69. package/dist/Model3DScene-DZFYJPUH.mjs.br +0 -0
  70. package/dist/Model3DScene-DZFYJPUH.mjs.gz +0 -0
  71. package/dist/Model3DScene-SP6WOKSX.js.br +0 -0
  72. package/dist/Model3DScene-SP6WOKSX.js.gz +0 -0
  73. package/dist/SurfaceChart3DScene-54BRNPQ5.mjs.br +0 -0
  74. package/dist/SurfaceChart3DScene-54BRNPQ5.mjs.gz +0 -0
  75. package/dist/SurfaceChart3DScene-GISPZ4C2.js.br +0 -0
  76. package/dist/SurfaceChart3DScene-GISPZ4C2.js.gz +0 -0
  77. package/dist/chunk-5VYVKFMS.js.br +0 -0
  78. package/dist/chunk-5VYVKFMS.js.gz +0 -0
  79. package/dist/chunk-6F4WVHS3.js.br +0 -0
  80. package/dist/chunk-6F4WVHS3.js.gz +0 -0
  81. package/dist/chunk-7FE27DDH.js.br +0 -0
  82. package/dist/chunk-7FE27DDH.js.gz +0 -0
  83. package/dist/chunk-FWF2SP6N.js.br +0 -0
  84. package/dist/chunk-FWF2SP6N.js.gz +0 -0
  85. package/dist/chunk-P72VQ7WE.mjs.br +0 -0
  86. package/dist/chunk-P72VQ7WE.mjs.gz +0 -0
  87. package/dist/chunk-TPG2WKHQ.mjs.br +0 -0
  88. package/dist/chunk-TPG2WKHQ.mjs.gz +0 -0
  89. package/dist/chunk-UYNOPUSG.mjs.br +0 -0
  90. package/dist/chunk-UYNOPUSG.mjs.gz +0 -0
  91. package/dist/chunk-VUC3UPLM.mjs.br +0 -0
  92. package/dist/chunk-VUC3UPLM.mjs.gz +0 -0
  93. package/dist/dist-QNYKM7YS.mjs +0 -2
  94. package/dist/dist-QNYKM7YS.mjs.br +0 -0
  95. package/dist/dist-QNYKM7YS.mjs.gz +0 -0
  96. package/dist/dist-QU6JIDAF.js.br +0 -0
  97. package/dist/dist-QU6JIDAF.js.gz +0 -0
  98. package/dist/index-DWvM1PBB.d.ts.map +0 -1
@@ -1634,8 +1634,8 @@ function decompressEotFont(fontData, compressed, encrypted) {
1634
1634
 
1635
1635
  // ../../node_modules/.bun/emf-converter@1.6.0/node_modules/emf-converter/dist/index.mjs
1636
1636
  function colorRefToHex(r, g, b) {
1637
- const toHex3 = (v) => v.toString(16).padStart(2, "0");
1638
- return `#${toHex3(r & 255)}${toHex3(g & 255)}${toHex3(b & 255)}`;
1637
+ const toHex4 = (v) => v.toString(16).padStart(2, "0");
1638
+ return `#${toHex4(r & 255)}${toHex4(g & 255)}${toHex4(b & 255)}`;
1639
1639
  }
1640
1640
  function readColorRef(view, offset) {
1641
1641
  const r = view.getUint8(offset);
@@ -1671,8 +1671,8 @@ function invertCssColor(color2) {
1671
1671
  const shortHex = /^#([0-9a-f]{3})$/i.exec(color2);
1672
1672
  if (shortHex) {
1673
1673
  const [r, g, b] = shortHex[1].split("").map((c) => parseInt(c + c, 16));
1674
- const toHex3 = (v) => (255 - v).toString(16).padStart(2, "0");
1675
- return `#${toHex3(r)}${toHex3(g)}${toHex3(b)}`;
1674
+ const toHex4 = (v) => (255 - v).toString(16).padStart(2, "0");
1675
+ return `#${toHex4(r)}${toHex4(g)}${toHex4(b)}`;
1676
1676
  }
1677
1677
  const rgba = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(color2);
1678
1678
  if (rgba) {
@@ -9177,6 +9177,7 @@ var TextShapeXmlFactory = class {
9177
9177
  createXmlElement(init) {
9178
9178
  const { element } = init;
9179
9179
  const isText = element.type === "text";
9180
+ const isTextBox = element.locks?.txBox ?? isText;
9180
9181
  const name = isText ? "TextBox" : "Rectangle";
9181
9182
  const geometry = this.context.normalizePresetGeometry(element.shapeType);
9182
9183
  const adjustmentEntries = Object.entries(element.shapeAdjustments || {}).filter(
@@ -9196,7 +9197,7 @@ var TextShapeXmlFactory = class {
9196
9197
  "@_name": `${name} ${elementId}`
9197
9198
  },
9198
9199
  "p:cNvSpPr": {
9199
- "@_txBox": isText ? "1" : "0"
9200
+ "@_txBox": isTextBox ? "1" : "0"
9200
9201
  },
9201
9202
  "p:nvPr": {}
9202
9203
  },
@@ -9810,6 +9811,21 @@ function cloneXmlObject(value) {
9810
9811
  }
9811
9812
  }
9812
9813
  var SECTION_EXTENSION_URI = "{521415D9-36F7-43E2-AB2F-B90AF26B5E84}";
9814
+ function remapReferenceList(references, mapping, removed) {
9815
+ const result = [];
9816
+ for (const reference of references) {
9817
+ const mapped = mapping.get(reference);
9818
+ if (mapped !== void 0) {
9819
+ result.push(mapped);
9820
+ continue;
9821
+ }
9822
+ if (removed.has(reference)) {
9823
+ continue;
9824
+ }
9825
+ result.push(reference);
9826
+ }
9827
+ return result;
9828
+ }
9813
9829
  function localName4(key) {
9814
9830
  return key.split(":").pop() ?? key;
9815
9831
  }
@@ -9876,7 +9892,7 @@ function updateCustomShow(show, existing) {
9876
9892
  replaceChildren(node, "sldLst", slideList, "p:sldLst");
9877
9893
  return node;
9878
9894
  }
9879
- function applyCustomShows(presentation, shows, lookup) {
9895
+ function applyCustomShows(presentation, shows, lookup, remap) {
9880
9896
  if (shows === void 0) {
9881
9897
  return;
9882
9898
  }
@@ -9890,14 +9906,18 @@ function applyCustomShows(presentation, shows, lookup) {
9890
9906
  const oldList = key ? presentation[key] : void 0;
9891
9907
  const list = cloneXmlObject(oldList) ?? {};
9892
9908
  const oldShows = lookup.getChildrenArrayByLocalName(oldList, "custShow");
9893
- const updated = shows.map(
9894
- (show) => updateCustomShow(
9895
- show,
9909
+ const updated = shows.map((show) => {
9910
+ const effective = remap && remap.changed ? {
9911
+ ...show,
9912
+ slideRIds: remapReferenceList(show.slideRIds, remap.rIdByOldRId, remap.removedRIds)
9913
+ } : show;
9914
+ return updateCustomShow(
9915
+ effective,
9896
9916
  oldShows.find(
9897
9917
  (node) => String(node[attributeKey(node, "id") ?? ""]) === show.id || String(node[attributeKey(node, "name") ?? ""]) === show.name
9898
9918
  )
9899
- )
9900
- );
9919
+ );
9920
+ });
9901
9921
  replaceChildren(list, "custShow", updated, "p:custShow");
9902
9922
  presentation[key ?? "p:custShowLst"] = list;
9903
9923
  }
@@ -9946,7 +9966,7 @@ function updateSection(section) {
9946
9966
  }
9947
9967
  return node;
9948
9968
  }
9949
- function applySections(presentation, sections, lookup) {
9969
+ function applySections(presentation, sections, lookup, remap) {
9950
9970
  if (sections === void 0) {
9951
9971
  return;
9952
9972
  }
@@ -9968,7 +9988,15 @@ function applySections(presentation, sections, lookup) {
9968
9988
  location = { parent: ext, key: "p14:sectionLst", list: ext["p14:sectionLst"] };
9969
9989
  }
9970
9990
  const list = cloneXmlObject(location.list) ?? {};
9971
- replaceChildren(list, "section", sections.map(updateSection), "p14:section");
9991
+ const effectiveSections = remap && remap.changed ? sections.map((section) => ({
9992
+ ...section,
9993
+ slideIds: remapReferenceList(
9994
+ section.slideIds,
9995
+ remap.sldIdByOldSldId,
9996
+ remap.removedSldIds
9997
+ )
9998
+ })) : sections;
9999
+ replaceChildren(list, "section", effectiveSections.map(updateSection), "p14:section");
9972
10000
  location.parent[location.key] = list;
9973
10001
  }
9974
10002
  var PptxPresentationSaveBuilder = class {
@@ -9987,8 +10015,18 @@ var PptxPresentationSaveBuilder = class {
9987
10015
  init.rawSlideHeightEmu,
9988
10016
  init.rawSlideSizeType
9989
10017
  );
9990
- applyCustomShows(presentation, init.options?.customShows, init.xmlLookupService);
9991
- applySections(presentation, init.options?.sections, init.xmlLookupService);
10018
+ applyCustomShows(
10019
+ presentation,
10020
+ init.options?.customShows,
10021
+ init.xmlLookupService,
10022
+ init.slideReferenceRemap
10023
+ );
10024
+ applySections(
10025
+ presentation,
10026
+ init.options?.sections,
10027
+ init.xmlLookupService,
10028
+ init.slideReferenceRemap
10029
+ );
9992
10030
  this.applyPhotoAlbum(presentation, init.options?.photoAlbum);
9993
10031
  presentation = this.applyKinsoku(presentation, init.options?.kinsoku);
9994
10032
  this.applyModifyVerifier(presentation, init.options?.modifyVerifier);
@@ -10082,6 +10120,51 @@ var PptxPresentationSaveBuilder = class {
10082
10120
  presentation["p:modifyVerifier"] = mv;
10083
10121
  }
10084
10122
  };
10123
+ function buildSlideReferenceRemap(init) {
10124
+ const pathToNewRId = /* @__PURE__ */ new Map();
10125
+ for (const slide of init.slides) {
10126
+ pathToNewRId.set(slide.id, slide.rId);
10127
+ }
10128
+ const newRIdToNumeric = /* @__PURE__ */ new Map();
10129
+ for (const entry of init.rebuiltSlideIds) {
10130
+ const relationshipId2 = String(entry?.["@_r:id"] ?? "");
10131
+ const numericSlideId = String(entry?.["@_id"] ?? "");
10132
+ if (relationshipId2.length > 0 && numericSlideId.length > 0) {
10133
+ newRIdToNumeric.set(relationshipId2, numericSlideId);
10134
+ }
10135
+ }
10136
+ const rIdByOldRId = /* @__PURE__ */ new Map();
10137
+ const removedRIds = /* @__PURE__ */ new Set();
10138
+ let changed = false;
10139
+ for (const [oldRId, path] of init.originalRIdToPath.entries()) {
10140
+ const newRId = pathToNewRId.get(path);
10141
+ if (newRId === void 0) {
10142
+ removedRIds.add(oldRId);
10143
+ changed = true;
10144
+ continue;
10145
+ }
10146
+ rIdByOldRId.set(oldRId, newRId);
10147
+ if (newRId !== oldRId) {
10148
+ changed = true;
10149
+ }
10150
+ }
10151
+ const sldIdByOldSldId = /* @__PURE__ */ new Map();
10152
+ const removedSldIds = /* @__PURE__ */ new Set();
10153
+ for (const [oldSldId, path] of init.originalSldIdToPath.entries()) {
10154
+ const newRId = pathToNewRId.get(path);
10155
+ const newSldId = newRId === void 0 ? void 0 : newRIdToNumeric.get(newRId);
10156
+ if (newSldId === void 0) {
10157
+ removedSldIds.add(oldSldId);
10158
+ changed = true;
10159
+ continue;
10160
+ }
10161
+ sldIdByOldSldId.set(oldSldId, newSldId);
10162
+ if (newSldId !== oldSldId) {
10163
+ changed = true;
10164
+ }
10165
+ }
10166
+ return { rIdByOldRId, sldIdByOldSldId, removedRIds, removedSldIds, changed };
10167
+ }
10085
10168
  var PptxPresentationSlidesReconciler = class {
10086
10169
  async reconcile(input) {
10087
10170
  const presentationRelsXml2 = await input.zip.file("ppt/_rels/presentation.xml.rels")?.async("string");
@@ -10126,6 +10209,10 @@ var PptxPresentationSlidesReconciler = class {
10126
10209
  const existingSlideIds = slideIdList ? this.ensureArray(slideIdList["p:sldId"]) : [];
10127
10210
  const slideIdByRid = /* @__PURE__ */ new Map();
10128
10211
  let maxNumericSlideId = 255;
10212
+ const originalRIdToPath = /* @__PURE__ */ new Map();
10213
+ for (const [relationshipId2, target] of slideTargetByRid.entries()) {
10214
+ originalRIdToPath.set(relationshipId2, input.toSlidePathFromTarget(target));
10215
+ }
10129
10216
  for (const slideIdEntry of existingSlideIds) {
10130
10217
  const relationshipId2 = slideIdEntry?.["@_r:id"];
10131
10218
  if (typeof relationshipId2 === "string" && relationshipId2.length > 0) {
@@ -10136,6 +10223,15 @@ var PptxPresentationSlidesReconciler = class {
10136
10223
  maxNumericSlideId = Math.max(maxNumericSlideId, numericSlideId);
10137
10224
  }
10138
10225
  }
10226
+ const originalSldIdToPath = /* @__PURE__ */ new Map();
10227
+ for (const slideIdEntry of existingSlideIds) {
10228
+ const relationshipId2 = String(slideIdEntry?.["@_r:id"] ?? "");
10229
+ const numericSlideId = String(slideIdEntry?.["@_id"] ?? "");
10230
+ const slidePath = originalRIdToPath.get(relationshipId2);
10231
+ if (numericSlideId.length > 0 && slidePath !== void 0) {
10232
+ originalSldIdToPath.set(numericSlideId, slidePath);
10233
+ }
10234
+ }
10139
10235
  for (let index = 0; index < input.slides.length; index++) {
10140
10236
  const slide = input.slides[index];
10141
10237
  slide.slideNumber = index + 1;
@@ -10172,6 +10268,7 @@ var PptxPresentationSlidesReconciler = class {
10172
10268
  ];
10173
10269
  presentationRelsData["Relationships"] = relRoot;
10174
10270
  input.zip.file("ppt/_rels/presentation.xml.rels", input.xmlBuilder.build(presentationRelsData));
10271
+ const rebuiltSlideIds = [];
10175
10272
  if (presentation && slideIdList && input.presentationData) {
10176
10273
  slideIdList["p:sldId"] = input.slides.map((slide) => {
10177
10274
  const existing = slideIdByRid.get(slide.rId);
@@ -10184,11 +10281,18 @@ var PptxPresentationSlidesReconciler = class {
10184
10281
  "@_r:id": slide.rId
10185
10282
  };
10186
10283
  });
10284
+ rebuiltSlideIds.push(...slideIdList["p:sldId"]);
10187
10285
  input.presentationData["p:presentation"] = this.insertSlideIdListInOrder(
10188
10286
  presentation,
10189
10287
  slideIdList
10190
10288
  );
10191
10289
  }
10290
+ return buildSlideReferenceRemap({
10291
+ slides: input.slides,
10292
+ originalRIdToPath,
10293
+ originalSldIdToPath,
10294
+ rebuiltSlideIds
10295
+ });
10192
10296
  }
10193
10297
  /**
10194
10298
  * Return a new presentation XML object whose `p:sldIdLst` child sits in the
@@ -10836,7 +10940,7 @@ var SHAPE_STYLE_ORDER = [
10836
10940
  "a:fontRef"
10837
10941
  ];
10838
10942
  var PptxSlideBackgroundBuilder = class {
10839
- applyBackground(init) {
10943
+ async applyBackground(init) {
10840
10944
  const hasBackgroundColor = typeof init.slide.backgroundColor === "string" && init.slide.backgroundColor.length > 0 && init.slide.backgroundColor !== "transparent";
10841
10945
  const rawBackgroundImage = typeof init.slide.backgroundImage === "string" ? init.slide.backgroundImage : "";
10842
10946
  const hasBackgroundImage = rawBackgroundImage.length > 0;
@@ -10857,8 +10961,8 @@ var PptxSlideBackgroundBuilder = class {
10857
10961
  return;
10858
10962
  }
10859
10963
  const backgroundProperties = {};
10860
- if (hasDataUrlBackgroundImage) {
10861
- const parsedBackgroundImage = init.parseDataUrlToBytes(rawBackgroundImage);
10964
+ if (hasBackgroundImage) {
10965
+ const parsedBackgroundImage = await init.resolveImageToBytes(rawBackgroundImage);
10862
10966
  if (parsedBackgroundImage) {
10863
10967
  const backgroundImagePath = init.saveState.nextMediaPath(parsedBackgroundImage.extension);
10864
10968
  init.zip.file(backgroundImagePath, parsedBackgroundImage.bytes);
@@ -10876,8 +10980,11 @@ var PptxSlideBackgroundBuilder = class {
10876
10980
  },
10877
10981
  BLIP_FILL_ORDER
10878
10982
  );
10983
+ } else {
10984
+ init.reportUnsupportedBackground?.(rawBackgroundImage);
10879
10985
  }
10880
- } else if (hasBackgroundColor && init.slide.backgroundColor) {
10986
+ }
10987
+ if (backgroundProperties["a:blipFill"] === void 0 && hasBackgroundColor && init.slide.backgroundColor) {
10881
10988
  backgroundProperties["a:solidFill"] = {
10882
10989
  "a:srgbClr": {
10883
10990
  "@_val": init.slide.backgroundColor.replace("#", "").toUpperCase()
@@ -10894,6 +11001,11 @@ var PptxSlideBackgroundBuilder = class {
10894
11001
  backgroundProperties["@_shadeToTitle"] = "0";
10895
11002
  }
10896
11003
  if (!hasFillChild) {
11004
+ if (existingBg !== void 0) {
11005
+ this.reorderCSldBgFirst(cSld, existingBg);
11006
+ init.slideNode["p:cSld"] = cSld;
11007
+ return;
11008
+ }
10897
11009
  delete cSld["p:bg"];
10898
11010
  init.slideNode["p:cSld"] = cSld;
10899
11011
  return;
@@ -10965,6 +11077,11 @@ function parseDrawingPercent(value) {
10965
11077
  }
10966
11078
  return clampUnitInterval(parsed / 1e5);
10967
11079
  }
11080
+ function scrgbLinearToSrgb8(linear) {
11081
+ const l = Math.min(1, Math.max(0, linear));
11082
+ const companded = l <= 31308e-7 ? 12.92 * l : 1.055 * l ** (1 / 2.4) - 0.055;
11083
+ return Math.min(255, Math.max(0, Math.round(companded * 255)));
11084
+ }
10968
11085
  function toHex(value) {
10969
11086
  return Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
10970
11087
  }
@@ -11510,11 +11627,15 @@ var PptxColorTransformCodec = class {
11510
11627
  }
11511
11628
  if (colorChoice["a:scrgbClr"]) {
11512
11629
  const scrgb = colorChoice["a:scrgbClr"];
11513
- const red = this.percentAttrToUnit(scrgb["@_r"]);
11514
- const green = this.percentAttrToUnit(scrgb["@_g"]);
11515
- const blue = this.percentAttrToUnit(scrgb["@_b"]);
11630
+ const red = parseDrawingFraction(scrgb["@_r"]);
11631
+ const green = parseDrawingFraction(scrgb["@_g"]);
11632
+ const blue = parseDrawingFraction(scrgb["@_b"]);
11516
11633
  if (red !== void 0 && green !== void 0 && blue !== void 0) {
11517
- const base = this.rgbToHex(red * 255, green * 255, blue * 255);
11634
+ const base = this.rgbToHex(
11635
+ scrgbLinearToSrgb8(red),
11636
+ scrgbLinearToSrgb8(green),
11637
+ scrgbLinearToSrgb8(blue)
11638
+ );
11518
11639
  return this.applyColorTransforms(base, scrgb);
11519
11640
  }
11520
11641
  }
@@ -11605,8 +11726,8 @@ var PptxColorTransformCodec = class {
11605
11726
  };
11606
11727
  }
11607
11728
  rgbToHex(r, g, b) {
11608
- const toHex3 = (channelValue) => this.clampColorChannel(channelValue).toString(16).padStart(2, "0").toUpperCase();
11609
- return `#${toHex3(r)}${toHex3(g)}${toHex3(b)}`;
11729
+ const toHex4 = (channelValue) => this.clampColorChannel(channelValue).toString(16).padStart(2, "0").toUpperCase();
11730
+ return `#${toHex4(r)}${toHex4(g)}${toHex4(b)}`;
11610
11731
  }
11611
11732
  applyColorTransforms(baseColor, colorNode) {
11612
11733
  return applyDrawingColorTransforms(baseColor, colorNode);
@@ -11690,6 +11811,22 @@ function mergeDrawingFillXml(original, generated, modeledChildren, childOrder2)
11690
11811
  }
11691
11812
  return result;
11692
11813
  }
11814
+ function extractGradientTileRect(gradFill) {
11815
+ const tileRect = drawingChild(gradFill, "tileRect");
11816
+ if (!tileRect) {
11817
+ return void 0;
11818
+ }
11819
+ const toFraction = (raw) => {
11820
+ const parsed = Number.parseInt(String(raw ?? "0"), 10);
11821
+ return Number.isFinite(parsed) ? parsed / 1e5 : 0;
11822
+ };
11823
+ return {
11824
+ l: toFraction(tileRect["@_l"]),
11825
+ t: toFraction(tileRect["@_t"]),
11826
+ r: toFraction(tileRect["@_r"]),
11827
+ b: toFraction(tileRect["@_b"])
11828
+ };
11829
+ }
11693
11830
  var PptxGradientStyleCodec = class {
11694
11831
  context;
11695
11832
  constructor(context) {
@@ -11800,6 +11937,9 @@ var PptxGradientStyleCodec = class {
11800
11937
  b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
11801
11938
  };
11802
11939
  }
11940
+ extractGradientTileRect(gradFill) {
11941
+ return extractGradientTileRect(gradFill);
11942
+ }
11803
11943
  extractGradientFlip(gradFill) {
11804
11944
  const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
11805
11945
  if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
@@ -11971,6 +12111,15 @@ var PptxGradientStyleCodec = class {
11971
12111
  }
11972
12112
  gradientXml["a:lin"] = linNode;
11973
12113
  }
12114
+ if (shapeStyle.fillGradientTileRect) {
12115
+ const tr = shapeStyle.fillGradientTileRect;
12116
+ gradientXml["a:tileRect"] = {
12117
+ "@_l": String(Math.round(tr.l * 1e5)),
12118
+ "@_t": String(Math.round(tr.t * 1e5)),
12119
+ "@_r": String(Math.round(tr.r * 1e5)),
12120
+ "@_b": String(Math.round(tr.b * 1e5))
12121
+ };
12122
+ }
11974
12123
  return mergeDrawingFillXml(
11975
12124
  shapeStyle.fillGradientXml,
11976
12125
  gradientXml,
@@ -13476,7 +13625,7 @@ var PptxColorStyleCodec = class {
13476
13625
  const alphaMod = this.percentAttrToUnit(
13477
13626
  choiceNode["a:alphaMod"]?.["@_val"]
13478
13627
  );
13479
- const alphaOff = this.percentAttrToUnit(
13628
+ const alphaOff = this.signedPercentToUnit(
13480
13629
  choiceNode["a:alphaOff"]?.["@_val"]
13481
13630
  );
13482
13631
  if (alpha === void 0 && alphaMod === void 0 && alphaOff === void 0) {
@@ -13491,6 +13640,18 @@ var PptxColorStyleCodec = class {
13491
13640
  }
13492
13641
  return this.clampUnitInterval(opacity2);
13493
13642
  }
13643
+ /**
13644
+ * Parse an OOXML percentage (thousandths, `100000` = 100%) into a fraction
13645
+ * WITHOUT clamping to [0, 1]. Used for additive offsets like `a:alphaOff`
13646
+ * that legitimately carry negative values.
13647
+ */
13648
+ signedPercentToUnit(value) {
13649
+ const parsed = Number.parseFloat(String(value ?? "").trim());
13650
+ if (!Number.isFinite(parsed)) {
13651
+ return void 0;
13652
+ }
13653
+ return parsed / 1e5;
13654
+ }
13494
13655
  colorWithOpacity(color2, opacity2) {
13495
13656
  if (opacity2 === void 0) {
13496
13657
  return color2;
@@ -13670,10 +13831,12 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
13670
13831
  }
13671
13832
  const hiddenLineFill = hiddenLineProps["a:solidFill"];
13672
13833
  if (hiddenLineFill) {
13834
+ style.strokeFillMode = "solid";
13673
13835
  style.strokeColor = context.parseColor(hiddenLineFill);
13674
13836
  style.strokeOpacity = context.extractColorOpacity(hiddenLineFill);
13675
13837
  }
13676
13838
  } else {
13839
+ style.strokeFillMode = "none";
13677
13840
  style.strokeWidth = 0;
13678
13841
  style.strokeColor = "transparent";
13679
13842
  }
@@ -13691,6 +13854,7 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
13691
13854
  }
13692
13855
  function applyStrokeColor(lineNode, style, context) {
13693
13856
  if (lineNode["a:solidFill"]) {
13857
+ style.strokeFillMode = "solid";
13694
13858
  const lineFill = lineNode["a:solidFill"];
13695
13859
  style.strokeColor = context.parseColor(lineFill);
13696
13860
  style.strokeOpacity = context.extractColorOpacity(lineFill);
@@ -13699,10 +13863,15 @@ function applyStrokeColor(lineNode, style, context) {
13699
13863
  style.strokeColorXml = strokeColorXml;
13700
13864
  }
13701
13865
  } else if (lineNode["a:gradFill"]) {
13702
- style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
13703
- style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
13866
+ style.strokeFillMode = "gradient";
13867
+ const lineGradFill = lineNode["a:gradFill"];
13868
+ style.strokeGradientXml = lineGradFill;
13869
+ style.strokeColor = context.extractGradientFillColor(lineGradFill);
13870
+ style.strokeOpacity = context.extractGradientOpacity(lineGradFill);
13704
13871
  } else if (lineNode["a:pattFill"]) {
13872
+ style.strokeFillMode = "pattern";
13705
13873
  const linePatternFill = lineNode["a:pattFill"];
13874
+ style.strokePatternXml = linePatternFill;
13706
13875
  style.strokeColor = context.parseColor(linePatternFill["a:fgClr"]) || context.parseColor(linePatternFill["a:bgClr"]);
13707
13876
  style.strokeOpacity = context.extractColorOpacity(linePatternFill["a:fgClr"]) || context.extractColorOpacity(linePatternFill["a:bgClr"]);
13708
13877
  }
@@ -13829,6 +13998,10 @@ var PptxShapeStyleExtractor = class {
13829
13998
  style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
13830
13999
  style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
13831
14000
  style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
14001
+ const gradTileRect = extractGradientTileRect(gradFill);
14002
+ if (gradTileRect) {
14003
+ style.fillGradientTileRect = gradTileRect;
14004
+ }
13832
14005
  const gradFlip = this.context.extractGradientFlip(gradFill);
13833
14006
  if (gradFlip) {
13834
14007
  style.fillGradientFlip = gradFlip;
@@ -15263,6 +15436,7 @@ var PptxLoadDataBuilder = class {
15263
15436
  layoutOptions = [];
15264
15437
  headerFooter;
15265
15438
  presentationProperties;
15439
+ viewProperties;
15266
15440
  customShows;
15267
15441
  sections;
15268
15442
  warnings = [];
@@ -15322,6 +15496,10 @@ var PptxLoadDataBuilder = class {
15322
15496
  this.presentationProperties = presentationProperties;
15323
15497
  return this;
15324
15498
  }
15499
+ withViewProperties(viewProperties) {
15500
+ this.viewProperties = viewProperties;
15501
+ return this;
15502
+ }
15325
15503
  withCustomShows(customShows) {
15326
15504
  this.customShows = customShows;
15327
15505
  return this;
@@ -15459,6 +15637,7 @@ var PptxLoadDataBuilder = class {
15459
15637
  layoutOptions: this.layoutOptions,
15460
15638
  headerFooter: this.headerFooter,
15461
15639
  presentationProperties: this.presentationProperties,
15640
+ viewProperties: this.viewProperties,
15462
15641
  customShows: this.customShows,
15463
15642
  sections: this.sections,
15464
15643
  warnings: this.warnings,
@@ -15833,7 +16012,7 @@ var PptxSlideCommentsXmlFactory = class {
15833
16012
  const createdAtIso = this.resolveCreatedAt(comment.createdAt);
15834
16013
  const x = init.saveState.toEmu(comment.x, 0);
15835
16014
  const y = init.saveState.toEmu(comment.y, 0);
15836
- return {
16015
+ const node = {
15837
16016
  ...withoutChildrenByLocalName(comment.rawXml ?? {}, /* @__PURE__ */ new Set(["pos", "text"])),
15838
16017
  "@_authorId": authorId,
15839
16018
  "@_dt": createdAtIso,
@@ -15844,6 +16023,28 @@ var PptxSlideCommentsXmlFactory = class {
15844
16023
  },
15845
16024
  "p:text": String(comment.text || "")
15846
16025
  };
16026
+ this.applyResolvedState(node, comment);
16027
+ return node;
16028
+ }
16029
+ /**
16030
+ * Reflect the (possibly edited) `resolved` flag onto the legacy comment
16031
+ * node. PowerPoint's legacy comment schema has no standard resolved marker,
16032
+ * but the parser reads a non-standard `@_done` / `@_resolved` attribute, so
16033
+ * we re-emit the current state rather than leaving the stale value carried
16034
+ * over from `rawXml`. The original attribute name is preserved when present.
16035
+ */
16036
+ applyResolvedState(node, comment) {
16037
+ const raw = comment.rawXml;
16038
+ const hadResolvedAttr = raw?.["@_resolved"] !== void 0;
16039
+ const hadDoneAttr = raw?.["@_done"] !== void 0;
16040
+ const key = hadResolvedAttr && !hadDoneAttr ? "@_resolved" : "@_done";
16041
+ delete node["@_done"];
16042
+ delete node["@_resolved"];
16043
+ if (comment.resolved === true) {
16044
+ node[key] = "1";
16045
+ } else if (hadResolvedAttr || hadDoneAttr) {
16046
+ node[key] = "0";
16047
+ }
15847
16048
  }
15848
16049
  resolveCreatedAt(createdAt) {
15849
16050
  const candidate = String(createdAt || "").trim();
@@ -17127,6 +17328,220 @@ var PptxCompatibilityService = class {
17127
17328
  ].join("|");
17128
17329
  }
17129
17330
  };
17331
+ var ATTR_PREFIX = "@_";
17332
+ var TEXT_KEY = "#text";
17333
+ function isXmlObject(value) {
17334
+ return typeof value === "object" && value !== null && !Array.isArray(value);
17335
+ }
17336
+ function coerceString(value) {
17337
+ if (typeof value === "string") {
17338
+ return value;
17339
+ }
17340
+ if (typeof value === "number" || typeof value === "boolean") {
17341
+ return String(value);
17342
+ }
17343
+ return void 0;
17344
+ }
17345
+ function xmlChild(node, key) {
17346
+ if (!isXmlObject(node)) {
17347
+ return void 0;
17348
+ }
17349
+ const value = node[key];
17350
+ if (Array.isArray(value)) {
17351
+ const first = value[0];
17352
+ return isXmlObject(first) ? first : void 0;
17353
+ }
17354
+ return isXmlObject(value) ? value : void 0;
17355
+ }
17356
+ function xmlChildren(node, key) {
17357
+ if (!isXmlObject(node)) {
17358
+ return [];
17359
+ }
17360
+ const value = node[key];
17361
+ if (value === void 0 || value === null) {
17362
+ return [];
17363
+ }
17364
+ if (Array.isArray(value)) {
17365
+ return value.filter(isXmlObject);
17366
+ }
17367
+ return isXmlObject(value) ? [value] : [];
17368
+ }
17369
+ function xmlHasChild(node, key) {
17370
+ return isXmlObject(node) && Object.hasOwn(node, key);
17371
+ }
17372
+ function xmlAttr(node, name) {
17373
+ if (!isXmlObject(node)) {
17374
+ return void 0;
17375
+ }
17376
+ return coerceString(node[ATTR_PREFIX + name]);
17377
+ }
17378
+ function xmlAttrNumber(node, name) {
17379
+ const raw = xmlAttr(node, name);
17380
+ if (raw === void 0) {
17381
+ return void 0;
17382
+ }
17383
+ const parsed = Number(raw);
17384
+ return Number.isFinite(parsed) ? parsed : void 0;
17385
+ }
17386
+ function xmlAttrBool(node, name) {
17387
+ const raw = xmlAttr(node, name);
17388
+ if (raw === void 0) {
17389
+ return void 0;
17390
+ }
17391
+ const normalized = raw.trim().toLowerCase();
17392
+ if (normalized === "1" || normalized === "true") {
17393
+ return true;
17394
+ }
17395
+ if (normalized === "0" || normalized === "false") {
17396
+ return false;
17397
+ }
17398
+ return void 0;
17399
+ }
17400
+ function xmlText(node) {
17401
+ if (typeof node === "string") {
17402
+ return node;
17403
+ }
17404
+ if (!isXmlObject(node)) {
17405
+ return void 0;
17406
+ }
17407
+ return coerceString(node[TEXT_KEY]);
17408
+ }
17409
+ function xmlPath(node, ...keys) {
17410
+ let current = isXmlObject(node) ? node : void 0;
17411
+ for (const key of keys) {
17412
+ if (!current) {
17413
+ return void 0;
17414
+ }
17415
+ current = xmlChild(current, key);
17416
+ }
17417
+ return current;
17418
+ }
17419
+ function isXmlNode(value) {
17420
+ return isXmlObject(value);
17421
+ }
17422
+ var SLIDE_TITLES_NAME = "Slide Titles";
17423
+ function coerceText(value) {
17424
+ if (typeof value === "string") {
17425
+ return value;
17426
+ }
17427
+ if (typeof value === "number" || typeof value === "boolean") {
17428
+ return String(value);
17429
+ }
17430
+ if (isXmlNode(value)) {
17431
+ const text2 = value["#text"];
17432
+ return text2 === void 0 || text2 === null ? "" : String(text2);
17433
+ }
17434
+ return "";
17435
+ }
17436
+ function coerceCount(value) {
17437
+ const parsed = Number.parseInt(coerceText(value), 10);
17438
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
17439
+ }
17440
+ function readLpstrList(vector) {
17441
+ if (!vector) {
17442
+ return [];
17443
+ }
17444
+ const raw = vector["vt:lpstr"];
17445
+ if (raw === void 0 || raw === null) {
17446
+ return [];
17447
+ }
17448
+ return (Array.isArray(raw) ? raw : [raw]).map(coerceText);
17449
+ }
17450
+ function isSlideTitlesCategory(name) {
17451
+ const normalized = name.trim().toLowerCase();
17452
+ return normalized === "slide titles" || normalized.includes("slide") && normalized.includes("title");
17453
+ }
17454
+ function readCategories(headingPairs, titlesOfParts) {
17455
+ const variants = xmlChildren(xmlChild(headingPairs, "vt:vector"), "vt:variant");
17456
+ const entries = readLpstrList(xmlChild(titlesOfParts, "vt:vector"));
17457
+ const categories = [];
17458
+ let offset = 0;
17459
+ for (let i = 0; i + 1 < variants.length; i += 2) {
17460
+ const name = coerceText(variants[i]["vt:lpstr"]);
17461
+ const count = coerceCount(variants[i + 1]["vt:i4"]);
17462
+ categories.push({ name, entries: entries.slice(offset, offset + count) });
17463
+ offset += count;
17464
+ }
17465
+ return categories;
17466
+ }
17467
+ function writeHeadingPairs(appProps, categories) {
17468
+ const variants = [];
17469
+ for (const category of categories) {
17470
+ variants.push({ "vt:lpstr": category.name });
17471
+ variants.push({ "vt:i4": String(category.entries.length) });
17472
+ }
17473
+ appProps["HeadingPairs"] = {
17474
+ "vt:vector": {
17475
+ "@_size": String(variants.length),
17476
+ "@_baseType": "variant",
17477
+ "vt:variant": variants
17478
+ }
17479
+ };
17480
+ }
17481
+ function writeTitlesOfParts(appProps, categories) {
17482
+ const allEntries = categories.flatMap((category) => category.entries);
17483
+ const lpstr = allEntries.map((entry) => ({ "#text": entry }));
17484
+ appProps["TitlesOfParts"] = {
17485
+ "vt:vector": {
17486
+ "@_size": String(allEntries.length),
17487
+ "@_baseType": "lpstr",
17488
+ "vt:lpstr": lpstr
17489
+ }
17490
+ };
17491
+ }
17492
+ function applySlideTitlesToAppProps(appProps, titles) {
17493
+ const headingPairs = xmlChild(appProps, "HeadingPairs");
17494
+ if (!headingPairs) {
17495
+ return;
17496
+ }
17497
+ const titlesOfParts = xmlChild(appProps, "TitlesOfParts");
17498
+ const categories = readCategories(headingPairs, titlesOfParts);
17499
+ const slideCategory = categories.find((category) => isSlideTitlesCategory(category.name));
17500
+ if (slideCategory) {
17501
+ slideCategory.entries = titles;
17502
+ } else {
17503
+ categories.push({ name: SLIDE_TITLES_NAME, entries: titles });
17504
+ }
17505
+ writeHeadingPairs(appProps, categories);
17506
+ writeTitlesOfParts(appProps, categories);
17507
+ }
17508
+ var TITLE_PLACEHOLDER_TYPES = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
17509
+ function getElementPlaceholderType(element) {
17510
+ const explicit = element.placeholderType;
17511
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
17512
+ return explicit.trim().toLowerCase();
17513
+ }
17514
+ const ph = xmlPath(element.rawXml, "p:nvSpPr", "p:nvPr", "p:ph");
17515
+ const type = xmlAttr(ph, "type");
17516
+ return type ? type.trim().toLowerCase() : void 0;
17517
+ }
17518
+ function getElementPlainText(element) {
17519
+ const maybe = element;
17520
+ if (typeof maybe.text === "string" && maybe.text.trim().length > 0) {
17521
+ return maybe.text.trim();
17522
+ }
17523
+ if (Array.isArray(maybe.textSegments)) {
17524
+ const joined = maybe.textSegments.map((segment) => typeof segment?.text === "string" ? segment.text : "").join("");
17525
+ return joined.trim();
17526
+ }
17527
+ return "";
17528
+ }
17529
+ function deriveSlideTitle(slide) {
17530
+ const elements2 = slide.elements ?? [];
17531
+ for (const element of elements2) {
17532
+ const phType = getElementPlaceholderType(element);
17533
+ if (phType && TITLE_PLACEHOLDER_TYPES.has(phType)) {
17534
+ const text2 = getElementPlainText(element);
17535
+ if (text2) {
17536
+ return text2;
17537
+ }
17538
+ }
17539
+ }
17540
+ return "";
17541
+ }
17542
+ function deriveSlideTitles(slides) {
17543
+ return slides.map((slide) => deriveSlideTitle(slide));
17544
+ }
17130
17545
  var PptxDocumentPropertiesUpdater = class {
17131
17546
  context;
17132
17547
  constructor(context) {
@@ -17189,6 +17604,7 @@ var PptxDocumentPropertiesUpdater = class {
17189
17604
  appProps["Slides"] = String(slides.length);
17190
17605
  appProps["HiddenSlides"] = String(hiddenSlidesCount);
17191
17606
  appProps["Notes"] = String(notesCount);
17607
+ this.updateSlideTitleProperties(appProps, slides);
17192
17608
  appData["Properties"] = appProps;
17193
17609
  this.context.zip.file("docProps/app.xml", this.context.builder.build(appData));
17194
17610
  } catch (error) {
@@ -17231,6 +17647,15 @@ var PptxDocumentPropertiesUpdater = class {
17231
17647
  }
17232
17648
  }
17233
17649
  }
17650
+ /**
17651
+ * Recompute `TitlesOfParts` / `HeadingPairs` from the current slide set so
17652
+ * the per-slide title list in `app.xml` stays consistent after slides are
17653
+ * added, removed, or retitled. Delegates the vector rebuild to a pure
17654
+ * helper; here we only derive the ordered titles.
17655
+ */
17656
+ updateSlideTitleProperties(appProps, slides) {
17657
+ applySlideTitlesToAppProps(appProps, deriveSlideTitles(slides));
17658
+ }
17234
17659
  applyAppPropertiesOverrides(appProps, overrides10) {
17235
17660
  if (!overrides10) {
17236
17661
  return;
@@ -19037,6 +19462,16 @@ function extractChildKeyframes(childTnList) {
19037
19462
  }
19038
19463
  return void 0;
19039
19464
  }
19465
+ function parseTimingPercentFraction(raw) {
19466
+ if (raw === void 0 || raw === null) {
19467
+ return void 0;
19468
+ }
19469
+ const parsed = Number.parseInt(String(raw), 10);
19470
+ if (!Number.isFinite(parsed) || parsed <= 0) {
19471
+ return void 0;
19472
+ }
19473
+ return Math.min(1, parsed / 1e5);
19474
+ }
19040
19475
  function extractRepeatInfo(cTn) {
19041
19476
  let repeatCount;
19042
19477
  let autoReverse;
@@ -19180,11 +19615,11 @@ function ensureArray4(value) {
19180
19615
  return [];
19181
19616
  }
19182
19617
  if (!Array.isArray(value)) {
19183
- return isXmlObject(value) ? [value] : [];
19618
+ return isXmlObject2(value) ? [value] : [];
19184
19619
  }
19185
- return value.filter((entry) => isXmlObject(entry));
19620
+ return value.filter((entry) => isXmlObject2(entry));
19186
19621
  }
19187
- function isXmlObject(value) {
19622
+ function isXmlObject2(value) {
19188
19623
  return typeof value === "object" && value !== null && !Array.isArray(value);
19189
19624
  }
19190
19625
  var VALID_CONDITION_EVENTS = /* @__PURE__ */ new Set([
@@ -19548,6 +19983,8 @@ var PptxNativeAnimationService = class {
19548
19983
  const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
19549
19984
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
19550
19985
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
19986
+ const accel = parseTimingPercentFraction(cTn["@_accel"]);
19987
+ const decel = parseTimingPercentFraction(cTn["@_decel"]);
19551
19988
  let trigger = currentTrigger;
19552
19989
  if (nodeType === "afterPrevious" || nodeType === "afterPrev") {
19553
19990
  trigger = "afterPrevious";
@@ -19600,6 +20037,8 @@ var PptxNativeAnimationService = class {
19600
20037
  presetSubtype,
19601
20038
  durationMs,
19602
20039
  delayMs,
20040
+ accel,
20041
+ decel,
19603
20042
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
19604
20043
  motionPath: childMotion.motionPath,
19605
20044
  motionOrigin: childMotion.motionOrigin,
@@ -20828,7 +21267,7 @@ function updateEffectNodeAttributes(cTn, anim, currentPresetClass) {
20828
21267
  if (stCondList && anim.delayMs !== void 0) {
20829
21268
  const conditions = ensureArray4(stCondList["p:cond"]);
20830
21269
  for (const cond of conditions) {
20831
- if (isXmlObject(cond)) {
21270
+ if (isXmlObject2(cond)) {
20832
21271
  cond["@_delay"] = String(anim.delayMs);
20833
21272
  }
20834
21273
  }
@@ -30846,7 +31285,7 @@ function getCalloutViewBoxBounds(width, height, geometry, padding = 2) {
30846
31285
  viewHeight: maxY - minY + padding * 2
30847
31286
  };
30848
31287
  }
30849
- function isXmlObject2(value) {
31288
+ function isXmlObject3(value) {
30850
31289
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
30851
31290
  }
30852
31291
  function ensureItems(value) {
@@ -30949,7 +31388,7 @@ function collectParsedOmathNodes(root) {
30949
31388
  }
30950
31389
  if (localName9(key) === "oMath") {
30951
31390
  for (const item of ensureItems(value)) {
30952
- if (isXmlObject2(item)) {
31391
+ if (isXmlObject3(item)) {
30953
31392
  result.push(item);
30954
31393
  }
30955
31394
  }
@@ -31012,7 +31451,7 @@ function reorderContainer(node, rawInner) {
31012
31451
  occurrence.set(child20.tag, index + 1);
31013
31452
  const value = ensureItems(node[child20.tag])[index];
31014
31453
  resolved.push({ tag: child20.tag, value });
31015
- if (isXmlObject2(value) && child20.inner) {
31454
+ if (isXmlObject3(value) && child20.inner) {
31016
31455
  reorderContainer(value, child20.inner);
31017
31456
  }
31018
31457
  }
@@ -31054,7 +31493,7 @@ function localName10(name) {
31054
31493
  const colon = name.indexOf(":");
31055
31494
  return colon >= 0 ? name.slice(colon + 1) : name;
31056
31495
  }
31057
- function isXmlObject3(value) {
31496
+ function isXmlObject4(value) {
31058
31497
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
31059
31498
  }
31060
31499
  function collectParsedParagraphs(root) {
@@ -31079,7 +31518,7 @@ function collectParsedParagraphs(root) {
31079
31518
  continue;
31080
31519
  }
31081
31520
  paragraphs.push(
31082
- ...(Array.isArray(childValue) ? childValue : [childValue]).filter(isXmlObject3)
31521
+ ...(Array.isArray(childValue) ? childValue : [childValue]).filter(isXmlObject4)
31083
31522
  );
31084
31523
  }
31085
31524
  } else {
@@ -31126,7 +31565,7 @@ function directChildrenByLocalName(paragraphs, name) {
31126
31565
  return [];
31127
31566
  }
31128
31567
  const values = Array.isArray(value) ? value : [value];
31129
- return values.filter(isXmlObject3);
31568
+ return values.filter(isXmlObject4);
31130
31569
  })
31131
31570
  );
31132
31571
  }
@@ -32514,97 +32953,6 @@ function detectFontFormat(data) {
32514
32953
  }
32515
32954
  return "truetype";
32516
32955
  }
32517
- var ATTR_PREFIX = "@_";
32518
- var TEXT_KEY = "#text";
32519
- function isXmlObject4(value) {
32520
- return typeof value === "object" && value !== null && !Array.isArray(value);
32521
- }
32522
- function coerceString(value) {
32523
- if (typeof value === "string") {
32524
- return value;
32525
- }
32526
- if (typeof value === "number" || typeof value === "boolean") {
32527
- return String(value);
32528
- }
32529
- return void 0;
32530
- }
32531
- function xmlChild(node, key) {
32532
- if (!isXmlObject4(node)) {
32533
- return void 0;
32534
- }
32535
- const value = node[key];
32536
- if (Array.isArray(value)) {
32537
- const first = value[0];
32538
- return isXmlObject4(first) ? first : void 0;
32539
- }
32540
- return isXmlObject4(value) ? value : void 0;
32541
- }
32542
- function xmlChildren(node, key) {
32543
- if (!isXmlObject4(node)) {
32544
- return [];
32545
- }
32546
- const value = node[key];
32547
- if (value === void 0 || value === null) {
32548
- return [];
32549
- }
32550
- if (Array.isArray(value)) {
32551
- return value.filter(isXmlObject4);
32552
- }
32553
- return isXmlObject4(value) ? [value] : [];
32554
- }
32555
- function xmlHasChild(node, key) {
32556
- return isXmlObject4(node) && Object.hasOwn(node, key);
32557
- }
32558
- function xmlAttr(node, name) {
32559
- if (!isXmlObject4(node)) {
32560
- return void 0;
32561
- }
32562
- return coerceString(node[ATTR_PREFIX + name]);
32563
- }
32564
- function xmlAttrNumber(node, name) {
32565
- const raw = xmlAttr(node, name);
32566
- if (raw === void 0) {
32567
- return void 0;
32568
- }
32569
- const parsed = Number(raw);
32570
- return Number.isFinite(parsed) ? parsed : void 0;
32571
- }
32572
- function xmlAttrBool(node, name) {
32573
- const raw = xmlAttr(node, name);
32574
- if (raw === void 0) {
32575
- return void 0;
32576
- }
32577
- const normalized = raw.trim().toLowerCase();
32578
- if (normalized === "1" || normalized === "true") {
32579
- return true;
32580
- }
32581
- if (normalized === "0" || normalized === "false") {
32582
- return false;
32583
- }
32584
- return void 0;
32585
- }
32586
- function xmlText(node) {
32587
- if (typeof node === "string") {
32588
- return node;
32589
- }
32590
- if (!isXmlObject4(node)) {
32591
- return void 0;
32592
- }
32593
- return coerceString(node[TEXT_KEY]);
32594
- }
32595
- function xmlPath(node, ...keys) {
32596
- let current = isXmlObject4(node) ? node : void 0;
32597
- for (const key of keys) {
32598
- if (!current) {
32599
- return void 0;
32600
- }
32601
- current = xmlChild(current, key);
32602
- }
32603
- return current;
32604
- }
32605
- function isXmlNode(value) {
32606
- return isXmlObject4(value);
32607
- }
32608
32956
  function findSectionList2(presentation, lookup) {
32609
32957
  const direct = lookup.getChildByLocalName(presentation, "sectionLst");
32610
32958
  if (direct) {
@@ -35881,6 +36229,7 @@ function getSvgStrokeDasharray(dashType, strokeWidth, customDashSegments) {
35881
36229
  }
35882
36230
  function createTemplateShapeRawXml(element) {
35883
36231
  const isText = element.type === "text";
36232
+ const isTextBox = element.locks?.txBox ?? isText;
35884
36233
  const name = isText ? "TextBox" : "Rectangle";
35885
36234
  const geometry = element.shapeType === "cylinder" ? "can" : element.shapeType || "rect";
35886
36235
  const adjustmentEntries = Object.entries(element.shapeAdjustments || {}).filter(
@@ -35899,7 +36248,7 @@ function createTemplateShapeRawXml(element) {
35899
36248
  "@_name": `${name} ${Math.floor(Math.random() * 100)}`
35900
36249
  },
35901
36250
  "p:cNvSpPr": {
35902
- "@_txBox": isText ? "1" : "0"
36251
+ "@_txBox": isTextBox ? "1" : "0"
35903
36252
  },
35904
36253
  "p:nvPr": {}
35905
36254
  },
@@ -39051,6 +39400,120 @@ function applyNodeStylesToElements(elements2, nodes) {
39051
39400
  };
39052
39401
  });
39053
39402
  }
39403
+ var CONTAINER_LOCAL_NAMES = /* @__PURE__ */ new Set(["presLayoutVars", "varLst"]);
39404
+ function localNameOf2(key) {
39405
+ const idx = key.indexOf(":");
39406
+ return idx >= 0 ? key.slice(idx + 1) : key;
39407
+ }
39408
+ function findVarsContainer(node) {
39409
+ if (!node || typeof node !== "object") {
39410
+ return void 0;
39411
+ }
39412
+ if (Array.isArray(node)) {
39413
+ for (const entry of node) {
39414
+ const found = findVarsContainer(entry);
39415
+ if (found) {
39416
+ return found;
39417
+ }
39418
+ }
39419
+ return void 0;
39420
+ }
39421
+ for (const [key, value] of Object.entries(node)) {
39422
+ if (key.startsWith("@_")) {
39423
+ continue;
39424
+ }
39425
+ if (CONTAINER_LOCAL_NAMES.has(localNameOf2(key))) {
39426
+ const container = Array.isArray(value) ? value[0] : value;
39427
+ if (container && typeof container === "object") {
39428
+ return container;
39429
+ }
39430
+ }
39431
+ const nested = findVarsContainer(value);
39432
+ if (nested) {
39433
+ return nested;
39434
+ }
39435
+ }
39436
+ return void 0;
39437
+ }
39438
+ function varValue(container, name) {
39439
+ for (const [key, value] of Object.entries(container)) {
39440
+ if (key.startsWith("@_") || localNameOf2(key) !== name) {
39441
+ continue;
39442
+ }
39443
+ const node = Array.isArray(value) ? value[0] : value;
39444
+ if (node && typeof node === "object") {
39445
+ const raw = node["@_val"];
39446
+ const str = String(raw ?? "").trim();
39447
+ return str.length > 0 ? str : void 0;
39448
+ }
39449
+ }
39450
+ return void 0;
39451
+ }
39452
+ function boolValue2(container, name) {
39453
+ const raw = varValue(container, name);
39454
+ if (raw === void 0) {
39455
+ return void 0;
39456
+ }
39457
+ const lower = raw.toLowerCase();
39458
+ return lower === "1" || lower === "true" || lower === "on";
39459
+ }
39460
+ function intValue(container, name) {
39461
+ const raw = varValue(container, name);
39462
+ if (raw === void 0) {
39463
+ return void 0;
39464
+ }
39465
+ const parsed = Number.parseInt(raw, 10);
39466
+ return Number.isFinite(parsed) ? parsed : void 0;
39467
+ }
39468
+ var DIRECTIONS = /* @__PURE__ */ new Set(["norm", "rev"]);
39469
+ var HIER_BRANCHES = /* @__PURE__ */ new Set(["std", "init", "l", "r", "hang"]);
39470
+ function parseSmartArtPresLayoutVars(container) {
39471
+ if (!container) {
39472
+ return void 0;
39473
+ }
39474
+ const vars = findVarsContainer(container);
39475
+ if (!vars) {
39476
+ return void 0;
39477
+ }
39478
+ const result = {};
39479
+ const direction = varValue(vars, "dir");
39480
+ if (direction && DIRECTIONS.has(direction)) {
39481
+ result.direction = direction;
39482
+ }
39483
+ const hierBranch = varValue(vars, "hierBranch");
39484
+ if (hierBranch && HIER_BRANCHES.has(hierBranch)) {
39485
+ result.hierarchyBranch = hierBranch;
39486
+ }
39487
+ const orgChart = boolValue2(vars, "orgChart");
39488
+ if (orgChart !== void 0) {
39489
+ result.orgChart = orgChart;
39490
+ }
39491
+ const chMax = intValue(vars, "chMax");
39492
+ if (chMax !== void 0) {
39493
+ result.childMax = chMax;
39494
+ }
39495
+ const chPref = intValue(vars, "chPref");
39496
+ if (chPref !== void 0) {
39497
+ result.childPreferred = chPref;
39498
+ }
39499
+ const bulletEnabled = boolValue2(vars, "bulletEnabled");
39500
+ if (bulletEnabled !== void 0) {
39501
+ result.bulletEnabled = bulletEnabled;
39502
+ }
39503
+ const animLvl = varValue(vars, "animLvl");
39504
+ if (animLvl !== void 0) {
39505
+ result.animationLevel = animLvl;
39506
+ }
39507
+ const animOne = varValue(vars, "animOne");
39508
+ if (animOne !== void 0) {
39509
+ result.animateOne = animOne;
39510
+ }
39511
+ const resizeHandles = varValue(vars, "resizeHandles");
39512
+ if (resizeHandles !== void 0) {
39513
+ result.resizeHandles = resizeHandles;
39514
+ }
39515
+ return Object.keys(result).length > 0 ? result : void 0;
39516
+ }
39054
39517
  function quickStyleStrokeScale(quickStyle) {
39055
39518
  if (!quickStyle?.effectIntensity) {
39056
39519
  return 1;
@@ -39155,15 +39618,27 @@ function decomposeSmartArt(smartArtData, containerBounds, themeColorMap, layoutD
39155
39618
  smartArtData.colorTransform?.fillColors
39156
39619
  );
39157
39620
  const layoutType = resolveEffectiveLayoutType(smartArtData);
39621
+ const layoutVars = smartArtData.presLayoutVars ?? parseSmartArtPresLayoutVars(smartArtData.layoutDefinition?.rawXml);
39622
+ const orderedNodes = layoutVars?.direction === "rev" ? [...nodes].reverse() : nodes;
39158
39623
  const namedLayout = smartArtData.layout;
39159
39624
  if (namedLayout) {
39160
- const namedResult = dispatchNamedLayout(namedLayout, nodes, containerBounds, effectiveThemeMap);
39625
+ const namedResult = dispatchNamedLayout(
39626
+ namedLayout,
39627
+ orderedNodes,
39628
+ containerBounds,
39629
+ effectiveThemeMap
39630
+ );
39161
39631
  if (namedResult) {
39162
- return applyNodeStylesToElements(namedResult, nodes);
39632
+ return applyNodeStylesToElements(namedResult, orderedNodes);
39163
39633
  }
39164
39634
  }
39165
- const algorithmic = dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap);
39166
- return algorithmic ? applyNodeStylesToElements(algorithmic, nodes) : algorithmic;
39635
+ const algorithmic = dispatchLayoutByType(
39636
+ layoutType,
39637
+ orderedNodes,
39638
+ containerBounds,
39639
+ effectiveThemeMap
39640
+ );
39641
+ return algorithmic ? applyNodeStylesToElements(algorithmic, orderedNodes) : algorithmic;
39167
39642
  }
39168
39643
  function dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap) {
39169
39644
  switch (layoutType) {
@@ -48821,6 +49296,126 @@ function applySmartArtConnectionAttributes(xml, connection, fallbackModelId) {
48821
49296
  applyNullableAttribute(xml, "@_sibTransId", connection.siblingTransitionId);
48822
49297
  applyNullableAttribute(xml, "@_presId", connection.presentationId);
48823
49298
  }
49299
+ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
49300
+ "srgbClr",
49301
+ "schemeClr",
49302
+ "scrgbClr",
49303
+ "sysClr",
49304
+ "prstClr",
49305
+ "hslClr"
49306
+ ]);
49307
+ var COLOR_METHODS2 = /* @__PURE__ */ new Set(["span", "cycle", "repeat"]);
49308
+ var HUE_DIRECTIONS2 = /* @__PURE__ */ new Set(["cw", "ccw"]);
49309
+ var PRIMARY_LABEL_PRIORITY = ["node0", "node1", "node2", "node3", "node4", "node"];
49310
+ function localNameOf3(key) {
49311
+ const idx = key.indexOf(":");
49312
+ return idx >= 0 ? key.slice(idx + 1) : key;
49313
+ }
49314
+ function parseSmartArtColorListHexes(list, deps) {
49315
+ if (!list) {
49316
+ return [];
49317
+ }
49318
+ const out = [];
49319
+ for (const [key, value] of Object.entries(list)) {
49320
+ if (key.startsWith("@_")) {
49321
+ continue;
49322
+ }
49323
+ const local = localNameOf3(key);
49324
+ if (!COLOR_LOCAL_NAMES.has(local)) {
49325
+ continue;
49326
+ }
49327
+ const nodes = Array.isArray(value) ? value : [value];
49328
+ for (const node of nodes) {
49329
+ if (!node || typeof node !== "object") {
49330
+ continue;
49331
+ }
49332
+ const wrapper = { [`a:${local}`]: node };
49333
+ const hex10 = deps.parseColorChoice(wrapper) ?? deps.resolveScheme(node);
49334
+ if (hex10) {
49335
+ out.push(hex10);
49336
+ }
49337
+ }
49338
+ }
49339
+ return out;
49340
+ }
49341
+ function listInterpolation(list) {
49342
+ if (!list) {
49343
+ return void 0;
49344
+ }
49345
+ const method = String(list["@_meth"] ?? "").trim();
49346
+ const hueDir = String(list["@_hueDir"] ?? "").trim();
49347
+ const meta = {};
49348
+ if (COLOR_METHODS2.has(method)) {
49349
+ meta.method = method;
49350
+ }
49351
+ if (HUE_DIRECTIONS2.has(hueDir)) {
49352
+ meta.hueDirection = hueDir;
49353
+ }
49354
+ return meta.method || meta.hueDirection ? meta : void 0;
49355
+ }
49356
+ function parseLabel(lbl, deps) {
49357
+ const fillList = deps.getChild(lbl, "fillClrLst");
49358
+ const lineList = deps.getChild(lbl, "linClrLst");
49359
+ return {
49360
+ name: String(lbl["@_name"] ?? "").trim(),
49361
+ fill: parseSmartArtColorListHexes(fillList, deps),
49362
+ line: parseSmartArtColorListHexes(lineList, deps),
49363
+ textFill: parseSmartArtColorListHexes(deps.getChild(lbl, "txFillClrLst"), deps),
49364
+ textLine: parseSmartArtColorListHexes(deps.getChild(lbl, "txLinClrLst"), deps),
49365
+ effect: parseSmartArtColorListHexes(deps.getChild(lbl, "effectClrLst"), deps),
49366
+ textEffect: parseSmartArtColorListHexes(deps.getChild(lbl, "txEffectClrLst"), deps),
49367
+ fillInterpolation: listInterpolation(fillList),
49368
+ lineInterpolation: listInterpolation(lineList)
49369
+ };
49370
+ }
49371
+ function selectPrimary(parsed) {
49372
+ const byName = new Map(parsed.map((p) => [p.name, p]));
49373
+ for (const name of PRIMARY_LABEL_PRIORITY) {
49374
+ const candidate = byName.get(name);
49375
+ if (candidate && candidate.fill.length > 0) {
49376
+ return candidate;
49377
+ }
49378
+ }
49379
+ for (const name of PRIMARY_LABEL_PRIORITY) {
49380
+ const candidate = byName.get(name);
49381
+ if (candidate && (candidate.line.length > 0 || candidate.fill.length > 0)) {
49382
+ return candidate;
49383
+ }
49384
+ }
49385
+ return parsed.find((p) => p.fill.length > 0) ?? parsed.find((p) => p.line.length > 0);
49386
+ }
49387
+ function buildSmartArtColorLists(styleLbls, deps) {
49388
+ const parsed = styleLbls.map((lbl) => parseLabel(lbl, deps));
49389
+ const primary = selectPrimary(parsed);
49390
+ let fillColors = primary?.fill ?? [];
49391
+ let lineColors = primary?.line ?? [];
49392
+ if (fillColors.length === 0) {
49393
+ fillColors = parsed.map((p) => p.fill[0]).filter((c) => Boolean(c));
49394
+ }
49395
+ if (lineColors.length === 0) {
49396
+ lineColors = parsed.map((p) => p.line[0]).filter((c) => Boolean(c));
49397
+ }
49398
+ const result = { fillColors, lineColors };
49399
+ if (primary?.textFill.length) {
49400
+ result.textFillColors = primary.textFill;
49401
+ }
49402
+ if (primary?.textLine.length) {
49403
+ result.textLineColors = primary.textLine;
49404
+ }
49405
+ if (primary?.effect.length) {
49406
+ result.effectColors = primary.effect;
49407
+ }
49408
+ if (primary?.textEffect.length) {
49409
+ result.textEffectColors = primary.textEffect;
49410
+ }
49411
+ if (primary?.fillInterpolation) {
49412
+ result.fillInterpolation = primary.fillInterpolation;
49413
+ }
49414
+ if (primary?.lineInterpolation) {
49415
+ result.lineInterpolation = primary.lineInterpolation;
49416
+ }
49417
+ return result;
49418
+ }
48824
49419
  var MODERN_COMMENT_NAMESPACE = "http://schemas.microsoft.com/office/powerpoint/2018/8/main";
48825
49420
  var MODERN_COMMENT_RELATIONSHIP = "http://schemas.microsoft.com/office/2018/10/relationships/comments";
48826
49421
  var MODERN_AUTHOR_RELATIONSHIP = "http://schemas.microsoft.com/office/2018/10/relationships/authors";
@@ -51087,6 +51682,26 @@ function buildGeneratedChartAxis(axId, crossId, pos2, formatting) {
51087
51682
  }
51088
51683
  return axis;
51089
51684
  }
51685
+ var CONTAINER_MAP = {
51686
+ pie: { tag: "c:pieChart", family: "pie" },
51687
+ pie3D: { tag: "c:pie3DChart", family: "pie" },
51688
+ ofPie: { tag: "c:ofPieChart", family: "ofPie" },
51689
+ doughnut: { tag: "c:doughnutChart", family: "doughnut" },
51690
+ scatter: { tag: "c:scatterChart", family: "scatter" },
51691
+ bubble: { tag: "c:bubbleChart", family: "bubble" },
51692
+ line: { tag: "c:lineChart", family: "line" },
51693
+ line3D: { tag: "c:line3DChart", family: "line" },
51694
+ area: { tag: "c:areaChart", family: "area" },
51695
+ area3D: { tag: "c:area3DChart", family: "area" },
51696
+ radar: { tag: "c:radarChart", family: "radar" },
51697
+ stock: { tag: "c:stockChart", family: "stock" },
51698
+ surface: { tag: "c:surfaceChart", family: "surface" },
51699
+ bar: { tag: "c:barChart", family: "bar" },
51700
+ bar3D: { tag: "c:bar3DChart", family: "bar" }
51701
+ };
51702
+ function resolveChartContainerType(type) {
51703
+ return CONTAINER_MAP[type] ?? { tag: "c:barChart", family: "bar" };
51704
+ }
51090
51705
  var NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
51091
51706
  var NS_A2 = "http://schemas.openxmlformats.org/drawingml/2006/main";
51092
51707
  var NS_R2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
@@ -51116,29 +51731,6 @@ function strLit(values) {
51116
51731
  }
51117
51732
  };
51118
51733
  }
51119
- function resolveType(type) {
51120
- switch (type) {
51121
- case "pie":
51122
- case "pie3D":
51123
- return { tag: "c:pieChart", family: "pie" };
51124
- case "doughnut":
51125
- return { tag: "c:doughnutChart", family: "doughnut" };
51126
- case "scatter":
51127
- return { tag: "c:scatterChart", family: "scatter" };
51128
- case "bubble":
51129
- return { tag: "c:bubbleChart", family: "bubble" };
51130
- case "line":
51131
- case "line3D":
51132
- return { tag: "c:lineChart", family: "line" };
51133
- case "area":
51134
- case "area3D":
51135
- return { tag: "c:areaChart", family: "area" };
51136
- case "radar":
51137
- return { tag: "c:radarChart", family: "radar" };
51138
- default:
51139
- return { tag: "c:barChart", family: "bar" };
51140
- }
51141
- }
51142
51734
  function fillSpPr(color2, asLine) {
51143
51735
  const h = hex6(color2);
51144
51736
  if (!h) {
@@ -51206,7 +51798,11 @@ function buildChartTypeContainer(chartData, family) {
51206
51798
  } else if (family === "scatter") {
51207
51799
  container["c:scatterStyle"] = { "@_val": "lineMarker" };
51208
51800
  container["c:varyColors"] = { "@_val": "0" };
51209
- } else {
51801
+ } else if (family === "ofPie") {
51802
+ container["c:ofPieType"] = { "@_val": "pie" };
51803
+ container["c:varyColors"] = { "@_val": "1" };
51804
+ } else if (family === "stock" || family === "surface") ;
51805
+ else {
51210
51806
  container["c:varyColors"] = { "@_val": family === "bubble" ? "0" : "1" };
51211
51807
  }
51212
51808
  container["c:ser"] = chartData.series.map(
@@ -51218,12 +51814,13 @@ function buildChartTypeContainer(chartData, family) {
51218
51814
  if (family === "line" && chartData.upDownBars !== void 0) {
51219
51815
  applyChartUpDownBars(container, chartData.upDownBars, (key) => key.replace(/^.*:/u, ""));
51220
51816
  }
51221
- if (family === "bar") {
51817
+ if (family === "bar" || family === "ofPie") {
51222
51818
  container["c:gapWidth"] = { "@_val": "150" };
51223
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
51224
- } else if (family === "line" || family === "area" || family === "radar") {
51225
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
51226
- } else if (family === "scatter" || family === "bubble") {
51819
+ }
51820
+ if (family === "stock") {
51821
+ container["c:hiLowLines"] = {};
51822
+ }
51823
+ if (family === "bar" || family === "line" || family === "area" || family === "radar" || family === "scatter" || family === "bubble" || family === "stock" || family === "surface") {
51227
51824
  container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
51228
51825
  } else if (family === "doughnut") {
51229
51826
  container["c:holeSize"] = { "@_val": "50" };
@@ -51236,7 +51833,8 @@ function buildPlotArea(chartData, tag, family) {
51236
51833
  if (chartData.style) {
51237
51834
  applyChartDataLabelsToXml(plotArea, chartData.style, (key) => key.replace(/^.*:/u, ""));
51238
51835
  }
51239
- if (family !== "pie" && family !== "doughnut" && SCATTER_LIKE.has(chartData.chartType)) {
51836
+ const hasAxes = family !== "pie" && family !== "doughnut" && family !== "ofPie";
51837
+ if (hasAxes && SCATTER_LIKE.has(chartData.chartType)) {
51240
51838
  plotArea["c:valAx"] = [
51241
51839
  buildGeneratedChartAxis(
51242
51840
  CAT_AX_ID,
@@ -51251,7 +51849,7 @@ function buildPlotArea(chartData, tag, family) {
51251
51849
  axisFormatting(chartData, "valAx", VAL_AX_ID, 1)
51252
51850
  )
51253
51851
  ];
51254
- } else if (family !== "pie" && family !== "doughnut") {
51852
+ } else if (hasAxes) {
51255
51853
  const dateAxis = chartData.dateCategories ? axisFormatting(chartData, "dateAx", CAT_AX_ID) : void 0;
51256
51854
  plotArea[dateAxis ? "c:dateAx" : "c:catAx"] = buildGeneratedChartAxis(
51257
51855
  CAT_AX_ID,
@@ -51270,7 +51868,7 @@ function buildPlotArea(chartData, tag, family) {
51270
51868
  return plotArea;
51271
51869
  }
51272
51870
  function buildChartSpaceXml(chartData) {
51273
- const { tag, family } = resolveType(chartData.chartType);
51871
+ const { tag, family } = resolveChartContainerType(chartData.chartType);
51274
51872
  const chart = {};
51275
51873
  if (chartData.title) {
51276
51874
  chart["c:title"] = {
@@ -53176,6 +53774,7 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
53176
53774
  let playbackSpeed;
53177
53775
  let trimStartMs;
53178
53776
  let trimEndMs;
53777
+ let embedRId;
53179
53778
  const bookmarks = [];
53180
53779
  const extLst = mediaNode["p:extLst"] ?? cMediaNode["p:extLst"];
53181
53780
  if (extLst) {
@@ -53183,6 +53782,13 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
53183
53782
  for (const ext of exts) {
53184
53783
  const p14Media = ext["p14:media"];
53185
53784
  if (p14Media) {
53785
+ if (embedRId === void 0) {
53786
+ const embedRaw = p14Media["@_r:embed"] ?? p14Media["@_embed"];
53787
+ const embedStr = embedRaw === void 0 ? "" : String(embedRaw).trim();
53788
+ if (embedStr.length > 0) {
53789
+ embedRId = embedStr;
53790
+ }
53791
+ }
53186
53792
  const p14Trim = p14Media["p14:trim"];
53187
53793
  if (p14Trim) {
53188
53794
  const st = p14Trim["@_st"];
@@ -53252,7 +53858,8 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
53252
53858
  fadeInDuration,
53253
53859
  fadeOutDuration,
53254
53860
  playbackSpeed,
53255
- bookmarks
53861
+ bookmarks,
53862
+ embedRId
53256
53863
  };
53257
53864
  }
53258
53865
  var PptxHandlerRuntime = class {
@@ -53480,6 +54087,12 @@ var PptxHandlerRuntime = class {
53480
54087
  loadedEmbeddedFonts = [];
53481
54088
  /** Typed source metadata for lossless embedded-font list round trips. */
53482
54089
  loadedEmbeddedFontList;
54090
+ /**
54091
+ * View properties parsed from `ppt/viewProps.xml` during load, preserved so
54092
+ * an unmodified load -> save round-trips the typed model and callers that do
54093
+ * not override `saveOptions.viewProperties` still persist the loaded state.
54094
+ */
54095
+ loadedViewProperties;
53483
54096
  /** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
53484
54097
  commentAuthorMap = /* @__PURE__ */ new Map();
53485
54098
  /** Full comment author details keyed by author ID, preserving initials/lastIdx/clrIdx for round-trip. */
@@ -53703,18 +54316,176 @@ function parseTableStyleBorders(tcStyle) {
53703
54316
  }
53704
54317
  return has ? result : void 0;
53705
54318
  }
54319
+ function toHex3(raw) {
54320
+ const hex10 = String(raw ?? "").trim();
54321
+ if (!hex10) {
54322
+ return void 0;
54323
+ }
54324
+ return hex10.startsWith("#") ? hex10 : `#${hex10}`;
54325
+ }
54326
+ function parseColorChoiceFill(node) {
54327
+ if (!node) {
54328
+ return void 0;
54329
+ }
54330
+ const scheme = parseSolidFillStyle(node);
54331
+ if (scheme) {
54332
+ return scheme;
54333
+ }
54334
+ const srgb = node["a:srgbClr"];
54335
+ const color2 = toHex3(srgb?.["@_val"]);
54336
+ if (!color2) {
54337
+ return void 0;
54338
+ }
54339
+ const fill = { schemeColor: "", color: color2 };
54340
+ const tintRaw = srgb?.["a:tint"];
54341
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
54342
+ if (tint !== void 0) {
54343
+ fill.tint = tint;
54344
+ }
54345
+ const shadeRaw = srgb?.["a:shade"];
54346
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
54347
+ if (shade !== void 0) {
54348
+ fill.shade = shade;
54349
+ }
54350
+ return fill;
54351
+ }
54352
+ function parseGradientFill(gradFill) {
54353
+ const gsLst = gradFill["a:gsLst"];
54354
+ const rawStops = gsLst?.["a:gs"];
54355
+ const gsNodes = Array.isArray(rawStops) ? rawStops : rawStops ? [rawStops] : [];
54356
+ const stops = [];
54357
+ for (const gs of gsNodes) {
54358
+ const fill = parseColorChoiceFill(gs);
54359
+ if (!fill) {
54360
+ continue;
54361
+ }
54362
+ const position2 = (parseInt(String(gs["@_pos"] || "0"), 10) || 0) / 1e3;
54363
+ stops.push({ position: position2, fill });
54364
+ }
54365
+ if (stops.length === 0) {
54366
+ return void 0;
54367
+ }
54368
+ const lin = gradFill["a:lin"];
54369
+ if (lin) {
54370
+ const angRaw = parseInt(String(lin["@_ang"] || "0"), 10) || 0;
54371
+ const angle = (angRaw / 6e4 % 360 + 360) % 360;
54372
+ return { stops, angle, type: "linear" };
54373
+ }
54374
+ if (gradFill["a:path"] !== void 0) {
54375
+ return { stops, type: "radial" };
54376
+ }
54377
+ return { stops, type: "linear" };
54378
+ }
54379
+ function parsePatternFill(pattFill) {
54380
+ const preset = String(pattFill["@_prst"] || "").trim();
54381
+ if (!preset) {
54382
+ return void 0;
54383
+ }
54384
+ const pattern = { preset };
54385
+ const foreground = parseColorChoiceFill(pattFill["a:fgClr"]);
54386
+ if (foreground) {
54387
+ pattern.foreground = foreground;
54388
+ }
54389
+ const background = parseColorChoiceFill(pattFill["a:bgClr"]);
54390
+ if (background) {
54391
+ pattern.background = background;
54392
+ }
54393
+ return pattern;
54394
+ }
54395
+ function parseTableStyleSectionFill(section) {
54396
+ if (!section) {
54397
+ return void 0;
54398
+ }
54399
+ const tcStyle = section["a:tcStyle"];
54400
+ const fillWrap = tcStyle?.["a:fill"];
54401
+ if (!fillWrap) {
54402
+ return void 0;
54403
+ }
54404
+ if (fillWrap["a:noFill"] !== void 0) {
54405
+ return { schemeColor: "", noFill: true };
54406
+ }
54407
+ const solid = fillWrap["a:solidFill"];
54408
+ if (solid) {
54409
+ return parseColorChoiceFill(solid);
54410
+ }
54411
+ const grad = fillWrap["a:gradFill"];
54412
+ if (grad) {
54413
+ const gradient = parseGradientFill(grad);
54414
+ if (gradient) {
54415
+ return { schemeColor: "", gradient };
54416
+ }
54417
+ }
54418
+ const patt = fillWrap["a:pattFill"];
54419
+ if (patt) {
54420
+ const pattern = parsePatternFill(patt);
54421
+ if (pattern) {
54422
+ return { schemeColor: "", pattern };
54423
+ }
54424
+ }
54425
+ return void 0;
54426
+ }
54427
+ function parseTableStyleSectionText(section) {
54428
+ const tcTxStyle = section?.["a:tcTxStyle"];
54429
+ if (!tcTxStyle) {
54430
+ return void 0;
54431
+ }
54432
+ const result = {};
54433
+ let hasProps = false;
54434
+ if (tcTxStyle["@_b"] === "on") {
54435
+ result.bold = true;
54436
+ hasProps = true;
54437
+ }
54438
+ if (tcTxStyle["@_i"] === "on") {
54439
+ result.italic = true;
54440
+ hasProps = true;
54441
+ }
54442
+ const underline = String(tcTxStyle["@_u"] || "").trim();
54443
+ if (underline && underline !== "none") {
54444
+ result.underline = true;
54445
+ hasProps = true;
54446
+ }
54447
+ const font = tcTxStyle["a:font"];
54448
+ const face = font ? String(font["@_typeface"] || "").trim() : "";
54449
+ if (face) {
54450
+ result.fontFace = face;
54451
+ hasProps = true;
54452
+ }
54453
+ const fontRef = tcTxStyle["a:fontRef"];
54454
+ const idx = fontRef ? String(fontRef["@_idx"] || "").trim() : "";
54455
+ if (idx) {
54456
+ result.fontRefIdx = idx;
54457
+ hasProps = true;
54458
+ }
54459
+ const schemeClr = fontRef?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
54460
+ if (schemeClr) {
54461
+ const val = String(schemeClr["@_val"] || "").trim();
54462
+ if (val) {
54463
+ result.fontSchemeColor = val;
54464
+ hasProps = true;
54465
+ const tintNode = schemeClr["a:tint"];
54466
+ if (tintNode) {
54467
+ result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
54468
+ }
54469
+ const shadeNode = schemeClr["a:shade"];
54470
+ if (shadeNode) {
54471
+ result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
54472
+ }
54473
+ }
54474
+ } else {
54475
+ const srgb = fontRef?.["a:srgbClr"] ?? tcTxStyle["a:srgbClr"];
54476
+ const hex10 = toHex3(srgb?.["@_val"]);
54477
+ if (hex10) {
54478
+ result.fontColor = hex10;
54479
+ hasProps = true;
54480
+ }
54481
+ }
54482
+ return hasProps ? result : void 0;
54483
+ }
53706
54484
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53707
54485
  /**
53708
- * Export slides to a raster/vector format.
53709
- *
53710
- * This is a stub that signals export intent. Actual rendering requires a
53711
- * platform-specific canvas or PDF library (e.g. Puppeteer, node-canvas,
53712
- * pdfkit). Host applications should override or extend this method with
53713
- * their own rendering pipeline.
53714
- *
53715
- * @param _slides The slides to export.
53716
- * @param _options Export options (format, DPI, slide indices, etc.).
53717
- * @returns A map of slide index → exported binary data.
54486
+ * Export slides to a raster/vector format. This is a stub that signals
54487
+ * export intent; actual rendering requires a platform-specific canvas or
54488
+ * PDF backend that host applications wire in by overriding this method.
53718
54489
  */
53719
54490
  async exportSlides(slides, options) {
53720
54491
  this.compatibilityService.reportWarning({
@@ -53779,15 +54550,11 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53779
54550
  }
53780
54551
  /**
53781
54552
  * Extract fill information from a table style section element
53782
- * (e.g. `a:wholeTbl`, `a:band1H`, `a:firstRow`).
54553
+ * (e.g. `a:wholeTbl`, `a:band1H`, `a:firstRow`). Handles scheme + sRGB
54554
+ * solids, gradients, preset patterns, and `a:noFill` (issue #95).
53783
54555
  */
53784
54556
  extractTableStyleSectionFill(section) {
53785
- if (!section) {
53786
- return void 0;
53787
- }
53788
- const tcStyle = section["a:tcStyle"];
53789
- const fill = tcStyle?.["a:fill"];
53790
- return parseSolidFillStyle(fill?.["a:solidFill"]);
54557
+ return parseTableStyleSectionFill(section);
53791
54558
  }
53792
54559
  /**
53793
54560
  * Extract border styling from a table style section's
@@ -53797,44 +54564,12 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53797
54564
  return parseTableStyleBorders(section?.["a:tcStyle"]);
53798
54565
  }
53799
54566
  /**
53800
- * Extract text properties from a:tcTxStyle in a table style section.
54567
+ * Extract text properties from `a:tcTxStyle` in a table style section.
54568
+ * Captures bold/italic/underline, typeface, font-collection index, and the
54569
+ * font colour (scheme or sRGB) (issue #95).
53801
54570
  */
53802
54571
  extractTableStyleSectionText(section) {
53803
- if (!section) {
53804
- return void 0;
53805
- }
53806
- const tcTxStyle = section["a:tcTxStyle"];
53807
- if (!tcTxStyle) {
53808
- return void 0;
53809
- }
53810
- const result = {};
53811
- let hasProps = false;
53812
- if (tcTxStyle["@_b"] === "on") {
53813
- result.bold = true;
53814
- hasProps = true;
53815
- }
53816
- if (tcTxStyle["@_i"] === "on") {
53817
- result.italic = true;
53818
- hasProps = true;
53819
- }
53820
- const fontClr = tcTxStyle["a:fontRef"];
53821
- const schemeClr = fontClr?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
53822
- if (schemeClr) {
53823
- const val = String(schemeClr["@_val"] || "").trim();
53824
- if (val) {
53825
- result.fontSchemeColor = val;
53826
- hasProps = true;
53827
- const tintNode = schemeClr["a:tint"];
53828
- if (tintNode) {
53829
- result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
53830
- }
53831
- const shadeNode = schemeClr["a:shade"];
53832
- if (shadeNode) {
53833
- result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
53834
- }
53835
- }
53836
- }
53837
- return hasProps ? result : void 0;
54572
+ return parseTableStyleSectionText(section);
53838
54573
  }
53839
54574
  ensureArray(val) {
53840
54575
  if (!val) {
@@ -54506,6 +55241,7 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
54506
55241
  );
54507
55242
  const trimStartMs = timing.trimStartMs ?? extData.trimStartMs;
54508
55243
  const trimEndMs = timing.trimEndMs ?? extData.trimEndMs;
55244
+ const mediaEmbedPath = extData.embedRId ? this.resolveRelationshipTarget(slidePath, extData.embedRId) : void 0;
54509
55245
  result.set(shapeId, {
54510
55246
  trimStartMs: trimStartMs !== void 0 && !isNaN(trimStartMs) ? trimStartMs : void 0,
54511
55247
  trimEndMs: trimEndMs !== void 0 && !isNaN(trimEndMs) ? trimEndMs : void 0,
@@ -54519,7 +55255,8 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
54519
55255
  playAcrossSlides: timing.playAcrossSlides || void 0,
54520
55256
  hideWhenNotPlaying: hideWhenNotPlaying || void 0,
54521
55257
  bookmarks: extData.bookmarks.length > 0 ? extData.bookmarks : void 0,
54522
- playbackSpeed: extData.playbackSpeed
55258
+ playbackSpeed: extData.playbackSpeed,
55259
+ mediaEmbedPath
54523
55260
  });
54524
55261
  }
54525
55262
  }
@@ -54693,6 +55430,10 @@ var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
54693
55430
  if (!timing) {
54694
55431
  continue;
54695
55432
  }
55433
+ if (timing.mediaEmbedPath && (typeof el.mediaPath !== "string" || el.mediaPath.length === 0)) {
55434
+ el.mediaPath = timing.mediaEmbedPath;
55435
+ el.mediaMimeType = this.getImageMimeType(timing.mediaEmbedPath);
55436
+ }
54696
55437
  if (timing.trimStartMs !== void 0) {
54697
55438
  el.trimStartMs = timing.trimStartMs;
54698
55439
  }
@@ -55691,7 +56432,7 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
55691
56432
  }
55692
56433
  }
55693
56434
  async reconcilePresentationSlidesForSave(params) {
55694
- await this.presentationSlidesReconciler.reconcile({
56435
+ return await this.presentationSlidesReconciler.reconcile({
55695
56436
  ...params,
55696
56437
  zip: this.zip,
55697
56438
  parser: this.parser,
@@ -55980,6 +56721,31 @@ function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
55980
56721
  }
55981
56722
  return fontNode;
55982
56723
  }
56724
+ function buildUnderlineLineXml(line2) {
56725
+ const uln = {};
56726
+ if (typeof line2.widthEmu === "number" && Number.isFinite(line2.widthEmu)) {
56727
+ uln["@_w"] = String(Math.round(line2.widthEmu));
56728
+ }
56729
+ if (line2.compound) {
56730
+ uln["@_cmpd"] = line2.compound;
56731
+ }
56732
+ if (line2.cap) {
56733
+ uln["@_cap"] = line2.cap;
56734
+ }
56735
+ if (line2.algn) {
56736
+ uln["@_algn"] = line2.algn;
56737
+ }
56738
+ if (line2.prstDash) {
56739
+ uln["a:prstDash"] = { "@_val": line2.prstDash };
56740
+ }
56741
+ if (line2.headEndXml) {
56742
+ uln["a:headEnd"] = line2.headEndXml;
56743
+ }
56744
+ if (line2.tailEndXml) {
56745
+ uln["a:tailEnd"] = line2.tailEndXml;
56746
+ }
56747
+ return uln;
56748
+ }
55983
56749
  var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime11 {
55984
56750
  createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
55985
56751
  const runProps = {
@@ -56000,6 +56766,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
56000
56766
  }
56001
56767
  if (style.underline) {
56002
56768
  runProps["@_u"] = style.underlineStyle || "sng";
56769
+ } else if (style.underlineExplicitNone) {
56770
+ runProps["@_u"] = "none";
56003
56771
  }
56004
56772
  if (style.strikethrough !== void 0) {
56005
56773
  runProps["@_strike"] = style.strikethrough ? style.strikeType || "sngStrike" : "noStrike";
@@ -56015,6 +56783,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
56015
56783
  }
56016
56784
  if (style.textCaps && style.textCaps !== "none") {
56017
56785
  runProps["@_cap"] = style.textCaps;
56786
+ } else if (style.textCapsExplicitNone) {
56787
+ runProps["@_cap"] = "none";
56018
56788
  }
56019
56789
  if (style.kumimoji !== void 0) {
56020
56790
  runProps["@_kumimoji"] = style.kumimoji ? "1" : "0";
@@ -56123,13 +56893,21 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
56123
56893
  runProps["a:effectDag"] = style.textEffectDagXml;
56124
56894
  }
56125
56895
  if (style.highlightColor) {
56126
- runProps["a:highlight"] = {
56127
- "a:srgbClr": {
56128
- "@_val": style.highlightColor.replace("#", "")
56129
- }
56130
- };
56896
+ const resolvedHighlight = style.highlightColorXml ? this.parseColor(style.highlightColorXml) : void 0;
56897
+ runProps["a:highlight"] = serializeColorChoice(
56898
+ style.highlightColorXml,
56899
+ resolvedHighlight,
56900
+ style.highlightColor
56901
+ );
56902
+ }
56903
+ if (style.underlineLineFollowsText) {
56904
+ runProps["a:uLnTx"] = {};
56905
+ } else if (style.underlineLine) {
56906
+ runProps["a:uLn"] = buildUnderlineLineXml(style.underlineLine);
56131
56907
  }
56132
- if (style.underline && style.underlineColor) {
56908
+ if (style.underlineFillFollowsText) {
56909
+ runProps["a:uFillTx"] = {};
56910
+ } else if (style.underline && style.underlineColor) {
56133
56911
  runProps["a:uFill"] = {
56134
56912
  "a:solidFill": {
56135
56913
  "a:srgbClr": {
@@ -56138,21 +56916,28 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
56138
56916
  }
56139
56917
  };
56140
56918
  }
56141
- if (style.fontFamily) {
56919
+ const latinFace = style.latinFontThemeToken ?? style.fontFamily;
56920
+ if (latinFace) {
56142
56921
  runProps["a:latin"] = applyFontMetadata(
56143
- { "@_typeface": style.fontFamily },
56922
+ { "@_typeface": latinFace },
56144
56923
  style.latinFontPanose,
56145
56924
  style.latinFontPitchFamily,
56146
56925
  style.latinFontCharset
56147
56926
  );
56927
+ }
56928
+ const eastAsiaFace = style.eastAsiaFontThemeToken ?? style.eastAsiaFont;
56929
+ if (eastAsiaFace) {
56148
56930
  runProps["a:ea"] = applyFontMetadata(
56149
- { "@_typeface": style.eastAsiaFont || style.fontFamily },
56931
+ { "@_typeface": eastAsiaFace },
56150
56932
  style.eastAsiaFontPanose,
56151
56933
  style.eastAsiaFontPitchFamily,
56152
56934
  style.eastAsiaFontCharset
56153
56935
  );
56936
+ }
56937
+ const complexScriptFace = style.complexScriptFontThemeToken ?? style.complexScriptFont;
56938
+ if (complexScriptFace) {
56154
56939
  runProps["a:cs"] = applyFontMetadata(
56155
- { "@_typeface": style.complexScriptFont || style.fontFamily },
56940
+ { "@_typeface": complexScriptFace },
56156
56941
  style.complexScriptFontPanose,
56157
56942
  style.complexScriptFontPitchFamily,
56158
56943
  style.complexScriptFontCharset
@@ -56202,12 +56987,17 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
56202
56987
  if (mouseOverTarget.length > 0) {
56203
56988
  const mouseOverRelId = resolveHyperlinkRelationshipId(mouseOverTarget);
56204
56989
  if (mouseOverRelId) {
56205
- runProps["a:hlinkMouseOver"] = {
56206
- "@_r:id": mouseOverRelId
56207
- };
56990
+ const mouseOverNode = { "@_r:id": mouseOverRelId };
56991
+ if (style.hyperlinkMouseOverSoundXml && typeof style.hyperlinkMouseOverSoundXml === "object") {
56992
+ mouseOverNode["a:snd"] = style.hyperlinkMouseOverSoundXml;
56993
+ }
56994
+ runProps["a:hlinkMouseOver"] = mouseOverNode;
56208
56995
  }
56209
56996
  }
56210
56997
  }
56998
+ if (style.runPropertiesExtLstXml && typeof style.runPropertiesExtLstXml === "object") {
56999
+ runProps["a:extLst"] = style.runPropertiesExtLstXml;
57000
+ }
56211
57001
  return runProps;
56212
57002
  }
56213
57003
  applyHyperlinkExtraAttrs(hlinkNode, style) {
@@ -56226,20 +57016,24 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
56226
57016
  if (style.hyperlinkEndSound !== void 0) {
56227
57017
  hlinkNode["@_endSnd"] = style.hyperlinkEndSound ? "1" : "0";
56228
57018
  }
57019
+ if (style.hyperlinkSoundXml && typeof style.hyperlinkSoundXml === "object") {
57020
+ hlinkNode["a:snd"] = style.hyperlinkSoundXml;
57021
+ }
56229
57022
  }
56230
57023
  };
56231
57024
  var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56232
57025
  createParagraphsFromTextContent(text2, textStyle, textSegments, resolveHyperlinkRelationshipId) {
56233
- const paragraphAlign = this.textAlignToDrawingValue(textStyle?.align);
56234
- const spacing = {
56235
- spacingBefore: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingBefore),
56236
- spacingAfter: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingAfter),
56237
- lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
56238
- lineSpacingExactPt: textStyle?.lineSpacingExactPt
56239
- };
56240
- const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
57026
+ const createParagraph = (runs, bulletInfo, level, endParaRunProperties, paragraphProperties2) => {
57027
+ const effectiveStyle = paragraphProperties2 ? { ...textStyle, ...paragraphProperties2 } : textStyle;
57028
+ const paragraphAlign = this.textAlignToDrawingValue(effectiveStyle?.align);
57029
+ const spacing = {
57030
+ spacingBefore: this.createParagraphSpacingXmlFromPx(effectiveStyle?.paragraphSpacingBefore),
57031
+ spacingAfter: this.createParagraphSpacingXmlFromPx(effectiveStyle?.paragraphSpacingAfter),
57032
+ lineSpacing: this.createLineSpacingXmlFromMultiplier(effectiveStyle?.lineSpacing),
57033
+ lineSpacingExactPt: effectiveStyle?.lineSpacingExactPt
57034
+ };
56241
57035
  const paragraphProps = buildParagraphPropertiesXml(
56242
- textStyle,
57036
+ effectiveStyle,
56243
57037
  paragraphAlign,
56244
57038
  bulletInfo,
56245
57039
  spacing,
@@ -56251,12 +57045,22 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56251
57045
  "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
56252
57046
  "a:t": runText
56253
57047
  });
56254
- const createFieldRun = (runText, style, fieldType, fieldGuid) => ({
56255
- "@_type": fieldType,
56256
- ...fieldGuid ? { "@_id": fieldGuid } : {},
56257
- "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
56258
- "a:t": runText
56259
- });
57048
+ const createFieldRun = (runText, style, fieldType, fieldGuid, fieldGuidAttr, fieldParagraphPropertiesXml) => {
57049
+ const fld = { "@_type": fieldType };
57050
+ if (fieldGuid) {
57051
+ if (fieldGuidAttr === "uuid") {
57052
+ fld["@_uuid"] = fieldGuid;
57053
+ } else {
57054
+ fld["@_id"] = fieldGuid;
57055
+ }
57056
+ }
57057
+ fld["a:rPr"] = this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId);
57058
+ if (fieldParagraphPropertiesXml && typeof fieldParagraphPropertiesXml === "object") {
57059
+ fld["a:pPr"] = fieldParagraphPropertiesXml;
57060
+ }
57061
+ fld["a:t"] = runText;
57062
+ return fld;
57063
+ };
56260
57064
  const createRubyRun = (segment, style) => {
56261
57065
  const rubyPr = {};
56262
57066
  if (segment.rubyAlignment) {
@@ -56295,17 +57099,27 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56295
57099
  let currentBulletInfo;
56296
57100
  let currentLevel;
56297
57101
  let currentEndParaRunProperties;
57102
+ let currentParagraphProperties;
57103
+ let capturedParagraphMeta = false;
56298
57104
  const pushParagraph = () => {
56299
57105
  if (currentRuns.length === 0) {
56300
57106
  currentRuns.push(createRun("", textStyle));
56301
57107
  }
56302
57108
  paragraphs.push(
56303
- createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
57109
+ createParagraph(
57110
+ currentRuns,
57111
+ currentBulletInfo,
57112
+ currentLevel,
57113
+ currentEndParaRunProperties,
57114
+ currentParagraphProperties
57115
+ )
56304
57116
  );
56305
57117
  currentRuns = [];
56306
57118
  currentBulletInfo = void 0;
56307
57119
  currentLevel = void 0;
56308
57120
  currentEndParaRunProperties = void 0;
57121
+ currentParagraphProperties = void 0;
57122
+ capturedParagraphMeta = false;
56309
57123
  };
56310
57124
  if (textSegments && textSegments.length > 0) {
56311
57125
  const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
@@ -56315,7 +57129,7 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56315
57129
  ...segment.style,
56316
57130
  ...uniformSegmentOverrides
56317
57131
  };
56318
- if (currentRuns.length === 0) {
57132
+ if (!capturedParagraphMeta) {
56319
57133
  if (segment.bulletInfo) {
56320
57134
  currentBulletInfo = segment.bulletInfo;
56321
57135
  }
@@ -56325,6 +57139,10 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56325
57139
  if (segment.endParaRunProperties) {
56326
57140
  currentEndParaRunProperties = segment.endParaRunProperties;
56327
57141
  }
57142
+ if (segment.paragraphProperties) {
57143
+ currentParagraphProperties = segment.paragraphProperties;
57144
+ }
57145
+ capturedParagraphMeta = true;
56328
57146
  }
56329
57147
  if (segment.isLineBreak) {
56330
57148
  const brNode = {};
@@ -56359,7 +57177,9 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56359
57177
  linePart,
56360
57178
  segmentStyle,
56361
57179
  segment.fieldType,
56362
- segment.fieldGuid
57180
+ segment.fieldGuid,
57181
+ segment.fieldGuidAttr,
57182
+ segment.fieldParagraphPropertiesXml
56363
57183
  );
56364
57184
  fieldRun.__isField = true;
56365
57185
  currentRuns.push(fieldRun);
@@ -57116,7 +57936,95 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
57116
57936
  );
57117
57937
  }
57118
57938
  };
57939
+ var SCRIPT_CANDIDATES = {
57940
+ cjk: ["Hans", "Hant", "Jpan", "Hang"],
57941
+ kana: ["Jpan", "Hans", "Hant"],
57942
+ hangul: ["Hang"],
57943
+ arabic: ["Arab"],
57944
+ hebrew: ["Hebr"],
57945
+ thai: ["Thai"]
57946
+ };
57947
+ function aggregateFontScriptOverrides(perPathMap) {
57948
+ const aggregate = {};
57949
+ for (const overrides10 of perPathMap.values()) {
57950
+ for (const [script, typeface] of Object.entries(overrides10)) {
57951
+ if (!(script in aggregate)) {
57952
+ aggregate[script] = typeface;
57953
+ }
57954
+ }
57955
+ }
57956
+ return aggregate;
57957
+ }
57958
+ function detectDominantScript(text2) {
57959
+ const counts = {};
57960
+ for (const ch of text2) {
57961
+ const code = ch.codePointAt(0) ?? 0;
57962
+ let cat;
57963
+ if (code >= 4352 && code <= 4607) {
57964
+ cat = "hangul";
57965
+ } else if (code >= 44032 && code <= 55215) {
57966
+ cat = "hangul";
57967
+ } else if (code >= 12352 && code <= 12543) {
57968
+ cat = "kana";
57969
+ } else if (code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903 || code >= 63744 && code <= 64255) {
57970
+ cat = "cjk";
57971
+ } else if (code >= 1536 && code <= 1791) {
57972
+ cat = "arabic";
57973
+ } else if (code >= 1424 && code <= 1535) {
57974
+ cat = "hebrew";
57975
+ } else if (code >= 3584 && code <= 3711) {
57976
+ cat = "thai";
57977
+ }
57978
+ if (cat) {
57979
+ counts[cat] = (counts[cat] ?? 0) + 1;
57980
+ }
57981
+ }
57982
+ let best;
57983
+ let bestCount = 0;
57984
+ for (const [cat, count] of Object.entries(counts)) {
57985
+ if (count > bestCount) {
57986
+ best = cat;
57987
+ bestCount = count;
57988
+ }
57989
+ }
57990
+ return best;
57991
+ }
57119
57992
  var PptxHandlerRuntime17 = class extends PptxHandlerRuntime16 {
57993
+ /**
57994
+ * Resolve the automatic per-script fallback face for a run's text from the
57995
+ * theme's `<a:font script="...">` overrides (#83). Body (minor) fonts win
57996
+ * over heading (major) fonts. Returns `undefined` when the deck declares no
57997
+ * script overrides or the text needs no fallback.
57998
+ */
57999
+ resolveScriptFallbackFont(text2) {
58000
+ if (!text2) {
58001
+ return void 0;
58002
+ }
58003
+ if (this.masterThemeMinorFontScripts.size === 0 && this.masterThemeMajorFontScripts.size === 0) {
58004
+ return void 0;
58005
+ }
58006
+ const category = detectDominantScript(text2);
58007
+ if (!category) {
58008
+ return void 0;
58009
+ }
58010
+ const candidates = SCRIPT_CANDIDATES[category];
58011
+ if (!candidates) {
58012
+ return void 0;
58013
+ }
58014
+ const minor = aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
58015
+ for (const key of candidates) {
58016
+ if (minor[key]) {
58017
+ return minor[key];
58018
+ }
58019
+ }
58020
+ const major = aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
58021
+ for (const key of candidates) {
58022
+ if (major[key]) {
58023
+ return major[key];
58024
+ }
58025
+ }
58026
+ return void 0;
58027
+ }
57120
58028
  textStylesEqual(left, right) {
57121
58029
  const keys = [
57122
58030
  "fontFamily",
@@ -57275,6 +58183,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
57275
58183
  const esVal = String(endSnd).trim().toLowerCase();
57276
58184
  style.hyperlinkEndSound = esVal === "1" || esVal === "true";
57277
58185
  }
58186
+ const clickSnd = hyperlinkNode["a:snd"];
58187
+ if (clickSnd && typeof clickSnd === "object") {
58188
+ style.hyperlinkSoundXml = clickSnd;
58189
+ }
57278
58190
  }
57279
58191
  const actionStr = String(hyperlinkNode?.["@_action"] || "").trim();
57280
58192
  if (actionStr) {
@@ -57304,6 +58216,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
57304
58216
  } else {
57305
58217
  style.hyperlinkMouseOver = mouseOverRelId;
57306
58218
  }
58219
+ const mouseOverSnd = hlinkMouseOver["a:snd"];
58220
+ if (mouseOverSnd && typeof mouseOverSnd === "object") {
58221
+ style.hyperlinkMouseOverSoundXml = mouseOverSnd;
58222
+ }
57307
58223
  }
57308
58224
  }
57309
58225
  }
@@ -57528,6 +58444,8 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57528
58444
  if (rawU.length > 0 && rawU !== "none") {
57529
58445
  style.underlineStyle = rawU;
57530
58446
  }
58447
+ } else if (underlineToken === "none") {
58448
+ style.underlineExplicitNone = true;
57531
58449
  }
57532
58450
  }
57533
58451
  const uFill = runProperties2["a:uFill"];
@@ -57539,6 +58457,46 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57539
58457
  style.underlineColor = underlineColor;
57540
58458
  }
57541
58459
  }
58460
+ if (uLn) {
58461
+ const line2 = {};
58462
+ const widthEmu = Number.parseInt(String(uLn["@_w"] ?? ""), 10);
58463
+ if (Number.isFinite(widthEmu)) {
58464
+ line2.widthEmu = widthEmu;
58465
+ }
58466
+ const compound = String(uLn["@_cmpd"] ?? "").trim();
58467
+ if (compound) {
58468
+ line2.compound = compound;
58469
+ }
58470
+ const cap = String(uLn["@_cap"] ?? "").trim();
58471
+ if (cap) {
58472
+ line2.cap = cap;
58473
+ }
58474
+ const algn = String(uLn["@_algn"] ?? "").trim();
58475
+ if (algn) {
58476
+ line2.algn = algn;
58477
+ }
58478
+ const prstDash = String(uLn["a:prstDash"]?.["@_val"] ?? "").trim();
58479
+ if (prstDash) {
58480
+ line2.prstDash = prstDash;
58481
+ }
58482
+ const headEnd = uLn["a:headEnd"];
58483
+ if (headEnd && typeof headEnd === "object") {
58484
+ line2.headEndXml = headEnd;
58485
+ }
58486
+ const tailEnd = uLn["a:tailEnd"];
58487
+ if (tailEnd && typeof tailEnd === "object") {
58488
+ line2.tailEndXml = tailEnd;
58489
+ }
58490
+ if (Object.keys(line2).length > 0) {
58491
+ style.underlineLine = line2;
58492
+ }
58493
+ }
58494
+ if (runProperties2["a:uLnTx"] !== void 0) {
58495
+ style.underlineLineFollowsText = true;
58496
+ }
58497
+ if (runProperties2["a:uFillTx"] !== void 0) {
58498
+ style.underlineFillFollowsText = true;
58499
+ }
57542
58500
  if (runProperties2["@_strike"] !== void 0) {
57543
58501
  const strikeToken = String(runProperties2["@_strike"] || "").trim().toLowerCase();
57544
58502
  style.strikethrough = strikeToken.length > 0 && strikeToken !== "nostrike" && strikeToken !== "none" && strikeToken !== "0" && strikeToken !== "false";
@@ -57582,10 +58540,15 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57582
58540
  }
57583
58541
  }
57584
58542
  if (runProperties2["a:highlight"]) {
57585
- const highlightHex = this.parseColor(xmlChild(runProperties2, "a:highlight"));
58543
+ const highlightNode = xmlChild(runProperties2, "a:highlight");
58544
+ const highlightHex = this.parseColor(highlightNode);
57586
58545
  if (highlightHex) {
57587
58546
  style.highlightColor = highlightHex;
57588
58547
  }
58548
+ const highlightXml = extractColorChoiceXml(highlightNode);
58549
+ if (highlightXml) {
58550
+ style.highlightColorXml = highlightXml;
58551
+ }
57589
58552
  }
57590
58553
  const textFillVariants = this.extractTextFillVariants(runProperties2);
57591
58554
  if (textFillVariants.textFillGradient) {
@@ -57606,16 +58569,28 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57606
58569
  const latin = xmlChild(runProperties2, "a:latin");
57607
58570
  const eastAsian = xmlChild(runProperties2, "a:ea");
57608
58571
  const complexScript = xmlChild(runProperties2, "a:cs");
57609
- const chosenTypeface = xmlAttr(latin, "typeface") || xmlAttr(eastAsian, "typeface") || xmlAttr(complexScript, "typeface");
58572
+ const latinTypefaceToken = xmlAttr(latin, "typeface");
58573
+ const eaTypefaceToken = xmlAttr(eastAsian, "typeface");
58574
+ const csTypefaceToken = xmlAttr(complexScript, "typeface");
58575
+ const chosenTypeface = latinTypefaceToken || eaTypefaceToken || csTypefaceToken;
57610
58576
  const resolvedTypeface = this.resolveThemeTypeface(chosenTypeface);
57611
58577
  if (resolvedTypeface) {
57612
58578
  style.fontFamily = resolvedTypeface;
57613
58579
  }
57614
- const eaTypeface = this.resolveThemeTypeface(xmlAttr(eastAsian, "typeface"));
58580
+ if (latinTypefaceToken && latinTypefaceToken.startsWith("+")) {
58581
+ style.latinFontThemeToken = latinTypefaceToken;
58582
+ }
58583
+ if (eaTypefaceToken && eaTypefaceToken.startsWith("+")) {
58584
+ style.eastAsiaFontThemeToken = eaTypefaceToken;
58585
+ }
58586
+ if (csTypefaceToken && csTypefaceToken.startsWith("+")) {
58587
+ style.complexScriptFontThemeToken = csTypefaceToken;
58588
+ }
58589
+ const eaTypeface = this.resolveThemeTypeface(eaTypefaceToken);
57615
58590
  if (eaTypeface) {
57616
58591
  style.eastAsiaFont = eaTypeface;
57617
58592
  }
57618
- const csTypeface = this.resolveThemeTypeface(xmlAttr(complexScript, "typeface"));
58593
+ const csTypeface = this.resolveThemeTypeface(csTypefaceToken);
57619
58594
  if (csTypeface) {
57620
58595
  style.complexScriptFont = csTypeface;
57621
58596
  }
@@ -57631,6 +58606,9 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57631
58606
  const capAttr = String(runProperties2["@_cap"] || "").trim().toLowerCase();
57632
58607
  if (capAttr === "all" || capAttr === "small") {
57633
58608
  style.textCaps = capAttr;
58609
+ } else if (capAttr === "none") {
58610
+ style.textCaps = "none";
58611
+ style.textCapsExplicitNone = true;
57634
58612
  }
57635
58613
  const symNode = xmlChild(runProperties2, "a:sym");
57636
58614
  if (symNode) {
@@ -57690,6 +58668,12 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57690
58668
  this.applyTextRunEffects(style, runEffectList);
57691
58669
  }
57692
58670
  this.applyTextRunEffectDag(style, runProperties2);
58671
+ if (includeDefaultAlignment) {
58672
+ const runExtLst = runProperties2["a:extLst"];
58673
+ if (runExtLst && typeof runExtLst === "object") {
58674
+ style.runPropertiesExtLstXml = runExtLst;
58675
+ }
58676
+ }
57693
58677
  return style;
57694
58678
  }
57695
58679
  /**
@@ -58353,12 +59337,63 @@ function writeCellTextFormatting(xmlCell, style, ensureArray16) {
58353
59337
  }
58354
59338
  }
58355
59339
  }
59340
+ function flattenCellTxBodyText(txBody, ensureArray16) {
59341
+ if (!txBody) {
59342
+ return "";
59343
+ }
59344
+ const paragraphs = ensureArray16(txBody["a:p"]);
59345
+ const lines = [];
59346
+ for (const paragraph of paragraphs) {
59347
+ const runs = ensureArray16(paragraph?.["a:r"]);
59348
+ const fields = ensureArray16(paragraph?.["a:fld"]);
59349
+ let lineText = "";
59350
+ for (const run of runs) {
59351
+ lineText += String(run?.["a:t"] ?? "");
59352
+ }
59353
+ for (const field of fields) {
59354
+ lineText += String(field?.["a:t"] ?? "");
59355
+ }
59356
+ lines.push(lineText);
59357
+ }
59358
+ return lines.join("\n");
59359
+ }
59360
+ function isRichCellTxBody(txBody, ensureArray16) {
59361
+ if (!txBody) {
59362
+ return false;
59363
+ }
59364
+ const paragraphs = ensureArray16(txBody["a:p"]);
59365
+ let totalRuns = 0;
59366
+ for (const paragraph of paragraphs) {
59367
+ const runs = ensureArray16(paragraph?.["a:r"]);
59368
+ totalRuns += runs.length;
59369
+ if (totalRuns > 1) {
59370
+ return true;
59371
+ }
59372
+ if (ensureArray16(paragraph?.["a:fld"]).length > 0) {
59373
+ return true;
59374
+ }
59375
+ for (const run of runs) {
59376
+ const rPr = run?.["a:rPr"];
59377
+ if (rPr?.["a:hlinkClick"] !== void 0) {
59378
+ return true;
59379
+ }
59380
+ }
59381
+ }
59382
+ return false;
59383
+ }
58356
59384
  var PptxHandlerRuntime22 = class _PptxHandlerRuntime5 extends PptxHandlerRuntime21 {
58357
59385
  /**
58358
59386
  * Write plain text into a table cell's txBody, preserving
58359
59387
  * existing run properties where possible.
58360
59388
  */
58361
59389
  writeTableCellText(xmlCell, text2) {
59390
+ const ensureArray16 = this.ensureArray.bind(this);
59391
+ const existingTxBody = xmlCell["a:txBody"];
59392
+ if (existingTxBody && ensureArray16(existingTxBody["a:p"]).length > 0) {
59393
+ if (flattenCellTxBodyText(existingTxBody, ensureArray16) === text2) {
59394
+ return;
59395
+ }
59396
+ }
58362
59397
  if (!xmlCell["a:txBody"]) {
58363
59398
  xmlCell["a:txBody"] = { "a:bodyPr": {}, "a:p": {} };
58364
59399
  }
@@ -58486,7 +59521,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime5 extends PptxHandlerRuntime
58486
59521
  }
58487
59522
  delete tcPr["a:tcMar"];
58488
59523
  writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime5.EMU_PER_PX);
58489
- writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
59524
+ if (!isRichCellTxBody(xmlCell["a:txBody"], this.ensureArray.bind(this))) {
59525
+ writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
59526
+ }
58490
59527
  const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
58491
59528
  for (const key of Object.keys(tcPr)) {
58492
59529
  delete tcPr[key];
@@ -60155,7 +61192,7 @@ function findKey19(obj, name, getLocalName2) {
60155
61192
  function hex9(value) {
60156
61193
  return value.replace("#", "");
60157
61194
  }
60158
- var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
61195
+ var COLOR_LOCAL_NAMES2 = /* @__PURE__ */ new Set([
60159
61196
  "srgbClr",
60160
61197
  "schemeClr",
60161
61198
  "sysClr",
@@ -60164,7 +61201,7 @@ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
60164
61201
  "hslClr"
60165
61202
  ]);
60166
61203
  function applyColorToList(list, value, getLocalName2) {
60167
- const colorKey = Object.keys(list).find((k) => COLOR_LOCAL_NAMES.has(getLocalName2(k)));
61204
+ const colorKey = Object.keys(list).find((k) => COLOR_LOCAL_NAMES2.has(getLocalName2(k)));
60168
61205
  const srgb = { "@_val": hex9(value) };
60169
61206
  if (!colorKey) {
60170
61207
  list["a:srgbClr"] = srgb;
@@ -62627,6 +63664,31 @@ var PptxHandlerRuntime27 = class extends PptxHandlerRuntime26 {
62627
63664
  return shape;
62628
63665
  }
62629
63666
  };
63667
+ function writeLineFill(lineNode, shapeStyle, parseColor) {
63668
+ delete lineNode["a:noFill"];
63669
+ delete lineNode["a:solidFill"];
63670
+ delete lineNode["a:gradFill"];
63671
+ delete lineNode["a:pattFill"];
63672
+ if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
63673
+ lineNode["a:noFill"] = {};
63674
+ return;
63675
+ }
63676
+ if (shapeStyle.strokeFillMode === "gradient" && shapeStyle.strokeGradientXml) {
63677
+ lineNode["a:gradFill"] = shapeStyle.strokeGradientXml;
63678
+ return;
63679
+ }
63680
+ if (shapeStyle.strokeFillMode === "pattern" && shapeStyle.strokePatternXml) {
63681
+ lineNode["a:pattFill"] = shapeStyle.strokePatternXml;
63682
+ return;
63683
+ }
63684
+ const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? parseColor(shapeStyle.strokeColorXml) : void 0;
63685
+ lineNode["a:solidFill"] = serializeColorChoice(
63686
+ shapeStyle.strokeColorXml,
63687
+ resolvedStrokeOriginal,
63688
+ shapeStyle.strokeColor ?? "#000000",
63689
+ shapeStyle.strokeOpacity
63690
+ );
63691
+ }
62630
63692
  var PptxHandlerRuntime28 = class _PptxHandlerRuntime8 extends PptxHandlerRuntime27 {
62631
63693
  /**
62632
63694
  * Serialize shape fill, stroke, dash, arrows, line join/cap/compound,
@@ -62696,26 +63758,14 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime8 extends PptxHandlerRuntime
62696
63758
  );
62697
63759
  }
62698
63760
  }
62699
- if (shapeStyle.strokeColor !== void 0) {
63761
+ if (shapeStyle.strokeColor !== void 0 || shapeStyle.strokeFillMode === "gradient" || shapeStyle.strokeFillMode === "pattern") {
62700
63762
  if (!spPr["a:ln"]) {
62701
63763
  spPr["a:ln"] = {};
62702
63764
  }
62703
63765
  const lineNode = spPr["a:ln"];
62704
63766
  const w = Math.round((shapeStyle.strokeWidth || 1) * _PptxHandlerRuntime8.EMU_PER_PX);
62705
63767
  lineNode["@_w"] = String(w);
62706
- if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
62707
- lineNode["a:noFill"] = {};
62708
- delete lineNode["a:solidFill"];
62709
- } else {
62710
- delete lineNode["a:noFill"];
62711
- const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
62712
- lineNode["a:solidFill"] = serializeColorChoice(
62713
- shapeStyle.strokeColorXml,
62714
- resolvedStrokeOriginal,
62715
- shapeStyle.strokeColor,
62716
- shapeStyle.strokeOpacity
62717
- );
62718
- }
63768
+ this.applyLineFill(lineNode, shapeStyle);
62719
63769
  }
62720
63770
  if (shapeStyle.strokeDash !== void 0) {
62721
63771
  if (!spPr["a:ln"]) {
@@ -62805,6 +63855,15 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime8 extends PptxHandlerRuntime
62805
63855
  spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
62806
63856
  }
62807
63857
  }
63858
+ /**
63859
+ * Emit the single fill child of an `<a:ln>` (CT_LineProperties allows at
63860
+ * most one of noFill/solidFill/gradFill/pattFill). Delegates to
63861
+ * {@link writeLineFill} so the logic stays unit-testable without the full
63862
+ * save runtime (issue #87).
63863
+ */
63864
+ applyLineFill(lineNode, shapeStyle) {
63865
+ writeLineFill(lineNode, shapeStyle, (colorNode) => this.parseColor(colorNode));
63866
+ }
62808
63867
  /**
62809
63868
  * Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
62810
63869
  * from the persisted ref indices/colour XML. Emits children in spec
@@ -65116,14 +66175,20 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime17 extends PptxHandlerRuntim
65116
66175
  relationshipType: constants.slideSyncRelationshipType,
65117
66176
  contentType: constants.slideSyncContentType
65118
66177
  });
65119
- this.slideBackgroundBuilder.applyBackground({
66178
+ await this.slideBackgroundBuilder.applyBackground({
65120
66179
  slideNode,
65121
66180
  slide,
65122
66181
  zip: this.zip,
65123
66182
  saveState: saveSession,
65124
66183
  relationshipRegistry: slideRelationshipRegistry,
65125
66184
  slideImageRelationshipType: constants.slideImageRelationshipType,
65126
- parseDataUrlToBytes: (dataUrl) => this.parseDataUrlToBytes(dataUrl)
66185
+ resolveImageToBytes: (url) => this.resolveMediaToBytes(url),
66186
+ reportUnsupportedBackground: (imageUrl) => this.compatibilityService.reportWarning({
66187
+ code: "SAVE_BACKGROUND_IMAGE_UNSUPPORTED",
66188
+ message: `Slide background image could not be embedded and was preserved as-is or omitted: ${imageUrl.slice(0, 120)}`,
66189
+ scope: "save",
66190
+ slideId: slide.id
66191
+ })
65127
66192
  });
65128
66193
  this.slideCommentPartWriter.writeComments({
65129
66194
  slide,
@@ -66608,7 +67673,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
66608
67673
  } = saveConstants;
66609
67674
  this.compatibilityService.resetWarnings();
66610
67675
  const saveSession = new PptxSaveStateBuilder().withZip(this.zip).withCommentAuthorMap(this.commentAuthorMap).withCommentAuthorDetails(this.commentAuthorDetails).withCommentAuthorsRootXml(this.commentAuthorsRootXml).withEmuPerPx(_PptxHandlerRuntime18.EMU_PER_PX).build();
66611
- await this.reconcilePresentationSlidesForSave({
67676
+ const slideReferenceRemap = await this.reconcilePresentationSlidesForSave({
66612
67677
  slides,
66613
67678
  saveSession,
66614
67679
  slideRelationshipType,
@@ -66703,7 +67768,8 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
66703
67768
  rawSlideWidthEmu: this.rawSlideWidthEmu,
66704
67769
  rawSlideHeightEmu: this.rawSlideHeightEmu,
66705
67770
  rawSlideSizeType: this.rawSlideSizeType,
66706
- xmlLookupService: this.xmlLookupService
67771
+ xmlLookupService: this.xmlLookupService,
67772
+ slideReferenceRemap
66707
67773
  });
66708
67774
  this.deduplicateExtensionLists(this.presentationData);
66709
67775
  if (effectiveConformance === "transitional") {
@@ -66720,7 +67786,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
66720
67786
  printSlidesPerPage: options.handoutMaster.slidesPerPage
66721
67787
  } : options?.presentationProperties;
66722
67788
  await this.applyPresentationPropertiesPart(presentationProperties);
66723
- await this.applyViewPropertiesPart(options?.viewProperties);
67789
+ await this.applyViewPropertiesPart(options?.viewProperties ?? this.loadedViewProperties);
66724
67790
  await this.applyTableStylesPart(options?.tableStyles);
66725
67791
  await this.documentPropertiesUpdater.updateOnSave(slides, {
66726
67792
  coreProperties: options?.coreProperties,
@@ -67006,26 +68072,16 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime19 extends PptxHandlerRuntim
67006
68072
  return true;
67007
68073
  }
67008
68074
  const typesMatch = source.type === target.type || source.type === "ctrtitle" && target.type === "title" || source.type === "subtitle" && target.type === "body";
67009
- if (source.idx !== void 0 && target.idx !== void 0) {
67010
- if (source.idx !== target.idx) {
67011
- return false;
67012
- }
67013
- if (source.type && target.type && !typesMatch) {
67014
- return false;
67015
- }
67016
- return true;
67017
- }
67018
- if (source.idx !== void 0 && target.idx === void 0) {
67019
- const singletonTypes = /* @__PURE__ */ new Set(["title", "ctrtitle", "subtitle", "dt", "ftr", "sldnum"]);
67020
- if (source.type && singletonTypes.has(source.type)) {
67021
- return typesMatch;
67022
- }
68075
+ const sourceIdx = source.idx ?? "0";
68076
+ const targetIdx = target.idx ?? "0";
68077
+ if (sourceIdx !== targetIdx) {
67023
68078
  return false;
67024
68079
  }
67025
68080
  if (source.type && target.type && !typesMatch) {
67026
68081
  return false;
67027
68082
  }
67028
- if (source.type && !target.type) {
68083
+ const bothHaveExplicitIdx = source.idx !== void 0 && target.idx !== void 0;
68084
+ if (!bothHaveExplicitIdx && source.type && !target.type) {
67029
68085
  return false;
67030
68086
  }
67031
68087
  return true;
@@ -68453,6 +69509,19 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime25 extends PptxHandlerRuntim
68453
69509
  });
68454
69510
  return hasAny ? locks : void 0;
68455
69511
  }
69512
+ /**
69513
+ * Parse the `@txBox` attribute from a `p:cNvSpPr` node. Returns `true` /
69514
+ * `false` when the attribute is present, or `undefined` when absent so
69515
+ * callers can distinguish "not a text box" from "unspecified".
69516
+ */
69517
+ parseTxBoxFlag(cNvSpPr) {
69518
+ const raw = cNvSpPr?.["@_txBox"];
69519
+ if (raw === void 0) {
69520
+ return void 0;
69521
+ }
69522
+ const val = String(raw).trim().toLowerCase();
69523
+ return val === "1" || val === "true";
69524
+ }
68456
69525
  /**
68457
69526
  * Extract body-level text properties from `a:bodyPr` and apply them to the
68458
69527
  * provided {@link TextStyle}. Returns linked-textbox info when present.
@@ -68633,6 +69702,62 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime25 extends PptxHandlerRuntim
68633
69702
  }
68634
69703
  };
68635
69704
  var PptxHandlerRuntime62 = class _PptxHandlerRuntime26 extends PptxHandlerRuntime61 {
69705
+ /**
69706
+ * Extract a paragraph's OWN `a:pPr` geometry (align, spacing, margins,
69707
+ * indent, tabs, rtl) as a partial {@link TextStyle} so per-paragraph
69708
+ * formatting round-trips rather than collapsing to one shape-level pPr
69709
+ * (#69). Inherited layout/master values are not re-stamped.
69710
+ */
69711
+ extractParagraphOwnProperties(p, basisFontSize) {
69712
+ const pPr = p["a:pPr"];
69713
+ if (!pPr) {
69714
+ return void 0;
69715
+ }
69716
+ const pp = { ...parseParagraphMargins(pPr) };
69717
+ const align = pPr["@_algn"] !== void 0 ? parseAlignmentAttr2(String(pPr["@_algn"])) : void 0;
69718
+ if (align) {
69719
+ pp.align = align;
69720
+ }
69721
+ const rtl = parseParagraphRtl(pPr);
69722
+ if (rtl !== void 0) {
69723
+ pp.rtl = rtl;
69724
+ }
69725
+ const spcBef = this.parseParagraphSpacingPx(
69726
+ pPr["a:spcBef"],
69727
+ basisFontSize
69728
+ );
69729
+ if (spcBef !== void 0) {
69730
+ pp.paragraphSpacingBefore = spcBef;
69731
+ }
69732
+ const spcAft = this.parseParagraphSpacingPx(
69733
+ pPr["a:spcAft"],
69734
+ basisFontSize
69735
+ );
69736
+ if (spcAft !== void 0) {
69737
+ pp.paragraphSpacingAfter = spcAft;
69738
+ }
69739
+ const lnSpcNode = pPr["a:lnSpc"];
69740
+ const lineSpacing = this.parseLineSpacingMultiplier(lnSpcNode);
69741
+ const exactPt = lineSpacing === void 0 ? this.parseLineSpacingExactPt(lnSpcNode) : void 0;
69742
+ if (lineSpacing !== void 0) {
69743
+ pp.lineSpacing = lineSpacing;
69744
+ } else if (exactPt !== void 0) {
69745
+ pp.lineSpacingExactPt = exactPt;
69746
+ }
69747
+ const tabStops = parseTabStops(pPr);
69748
+ if (tabStops && tabStops.length > 0) {
69749
+ pp.tabStops = tabStops;
69750
+ }
69751
+ const defRPr = pPr["a:defRPr"];
69752
+ if (defRPr && typeof defRPr === "object") {
69753
+ pp.paragraphDefaultRunPropertiesXml = defRPr;
69754
+ }
69755
+ const pPrExtLst = pPr["a:extLst"];
69756
+ if (pPrExtLst && typeof pPrExtLst === "object") {
69757
+ pp.paragraphPropertiesExtLstXml = pPrExtLst;
69758
+ }
69759
+ return Object.keys(pp).length > 0 ? pp : void 0;
69760
+ }
68636
69761
  /**
68637
69762
  * Resolve paragraph-level styles (alignment, spacing, margins, tabs,
68638
69763
  * level styles) for a single paragraph. Modifies `textStyle` in place
@@ -68879,6 +70004,12 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
68879
70004
  ...mergedDefaultRunStyle,
68880
70005
  ...this.extractTextRunStyle(runProps, paraAlign, ctx.slideRelationshipMap)
68881
70006
  };
70007
+ if (!runStyle2.scriptFallbackFont) {
70008
+ const fallback = this.resolveScriptFallbackFont(runText);
70009
+ if (fallback) {
70010
+ runStyle2.scriptFallbackFont = fallback;
70011
+ }
70012
+ }
68882
70013
  parts.push(runText);
68883
70014
  segments.push({ text: runText, style: runStyle2 });
68884
70015
  maybeSeed(runStyle2);
@@ -68920,14 +70051,25 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
68920
70051
  )
68921
70052
  };
68922
70053
  const fldType = String(field["@_type"] || "").trim() || void 0;
68923
- const fldGuid = String(field["@_uuid"] || field["@_id"] || "").trim() || void 0;
70054
+ const uuidAttr = String(field["@_uuid"] || "").trim();
70055
+ const idAttr = String(field["@_id"] || "").trim();
70056
+ const fldGuid = uuidAttr || idAttr || void 0;
70057
+ const fldGuidAttr = uuidAttr ? "uuid" : idAttr ? "id" : void 0;
68924
70058
  parts.push(fieldText);
68925
- segments.push({
70059
+ const fieldSegment = {
68926
70060
  text: fieldText,
68927
70061
  style: fieldRunStyle,
68928
70062
  fieldType: fldType,
68929
70063
  fieldGuid: fldGuid
68930
- });
70064
+ };
70065
+ if (fldGuidAttr) {
70066
+ fieldSegment.fieldGuidAttr = fldGuidAttr;
70067
+ }
70068
+ const fieldPPr = field["a:pPr"];
70069
+ if (fieldPPr && typeof fieldPPr === "object") {
70070
+ fieldSegment.fieldParagraphPropertiesXml = fieldPPr;
70071
+ }
70072
+ segments.push(fieldSegment);
68931
70073
  maybeSeed(fieldRunStyle);
68932
70074
  };
68933
70075
  const processMathElement = (mathEl) => {
@@ -69054,6 +70196,11 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
69054
70196
  ...endParaRPrRaw
69055
70197
  };
69056
70198
  }
70199
+ const basisFontSize = typeof mergedDefaultRunStyle.fontSize === "number" ? mergedDefaultRunStyle.fontSize : void 0;
70200
+ const paragraphOwnProps = this.extractParagraphOwnProperties(p, basisFontSize);
70201
+ if (paragraphOwnProps) {
70202
+ segments[firstSegmentIndex].paragraphProperties = paragraphOwnProps;
70203
+ }
69057
70204
  }
69058
70205
  return { parts, segments, seedStyle };
69059
70206
  }
@@ -69360,7 +70507,11 @@ var PptxHandlerRuntime64 = class _PptxHandlerRuntime27 extends PptxHandlerRuntim
69360
70507
  const inheritedCNvSpPr = xmlPath(inheritedPlaceholder?.shape, "p:nvSpPr", "p:cNvSpPr") ?? xmlPath(inheritedPlaceholder?.picture, "p:nvPicPr", "p:cNvPicPr");
69361
70508
  const inheritedLockNode = inheritedCNvSpPr?.["a:spLocks"] ?? inheritedCNvSpPr?.["a:picLocks"];
69362
70509
  const inheritedLocks = this.parseShapeLocks(inheritedLockNode);
69363
- const locks = inheritedLocks ? { ...inheritedLocks, ...slideLocks } : slideLocks;
70510
+ let locks = inheritedLocks ? { ...inheritedLocks, ...slideLocks } : slideLocks;
70511
+ const txBox = this.parseTxBoxFlag(cNvSpPr);
70512
+ if (txBox !== void 0) {
70513
+ locks = { ...locks ?? {}, txBox };
70514
+ }
69364
70515
  const promptText = !hasText && phDefaults?.promptText ? phDefaults.promptText : void 0;
69365
70516
  const opaqueExtLstXml = this.extractOpaqueSpPrExtLst(effectiveSpPr);
69366
70517
  const commonProps = {
@@ -72881,16 +74032,20 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
72881
74032
  }
72882
74033
  let fontScheme;
72883
74034
  if (hasFonts) {
74035
+ const majorByScript = this.aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
74036
+ const minorByScript = this.aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
72884
74037
  fontScheme = {
72885
74038
  majorFont: {
72886
74039
  latin: this.themeFontMap["mj-lt"],
72887
74040
  eastAsia: this.themeFontMap["mj-ea"],
72888
- complexScript: this.themeFontMap["mj-cs"]
74041
+ complexScript: this.themeFontMap["mj-cs"],
74042
+ ...Object.keys(majorByScript).length > 0 ? { byScript: majorByScript } : {}
72889
74043
  },
72890
74044
  minorFont: {
72891
74045
  latin: this.themeFontMap["mn-lt"],
72892
74046
  eastAsia: this.themeFontMap["mn-ea"],
72893
- complexScript: this.themeFontMap["mn-cs"]
74047
+ complexScript: this.themeFontMap["mn-cs"],
74048
+ ...Object.keys(minorByScript).length > 0 ? { byScript: minorByScript } : {}
72894
74049
  }
72895
74050
  };
72896
74051
  }
@@ -73098,6 +74253,23 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
73098
74253
  *
73099
74254
  * Phase 4 Stream A / M4.
73100
74255
  */
74256
+ /**
74257
+ * Flatten a per-theme-path script-override map (`themePath -> {script ->
74258
+ * typeface}`) into a single `{script -> typeface}` lookup for
74259
+ * {@link buildThemeObject}. Earlier entries win on collision, which matches
74260
+ * the primary-theme-first parse order. Phase 4 Stream A / M4 (#83).
74261
+ */
74262
+ aggregateFontScriptOverrides(perPathMap) {
74263
+ const aggregate = {};
74264
+ for (const overrides10 of perPathMap.values()) {
74265
+ for (const [script, typeface] of Object.entries(overrides10)) {
74266
+ if (!(script in aggregate)) {
74267
+ aggregate[script] = typeface;
74268
+ }
74269
+ }
74270
+ }
74271
+ return aggregate;
74272
+ }
73101
74273
  collectFontScriptOverrides(fontNode) {
73102
74274
  const overrides10 = {};
73103
74275
  if (!fontNode) {
@@ -73727,33 +74899,16 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
73727
74899
  const metadata = parseSmartArtDefinitionMetadata(colorsDef, localName22);
73728
74900
  const labels = parseSmartArtColorStyleLabels(colorsDef, localName22);
73729
74901
  const name = metadata.titles?.[0]?.value || String(colorsDef["@_title"] || colorsDef["@_uniqueId"] || "").trim() || void 0;
73730
- const fillColors = [];
73731
- const lineColors = [];
73732
74902
  const styleLbls = this.xmlLookupService.getChildrenArrayByLocalName(colorsDef, "styleLbl");
73733
- for (const lbl of styleLbls) {
73734
- const fillClrLst = this.xmlLookupService.getChildByLocalName(lbl, "fillClrLst");
73735
- const linClrLst = this.xmlLookupService.getChildByLocalName(lbl, "linClrLst");
73736
- if (fillClrLst) {
73737
- const color2 = this.parseColor(fillClrLst) ?? this.resolveSmartArtSchemeColor(
73738
- this.xmlLookupService.getChildByLocalName(fillClrLst, "schemeClr")
73739
- );
73740
- if (color2) {
73741
- fillColors.push(color2);
73742
- }
73743
- }
73744
- if (linClrLst) {
73745
- const color2 = this.parseColor(linClrLst) ?? this.resolveSmartArtSchemeColor(
73746
- this.xmlLookupService.getChildByLocalName(linClrLst, "schemeClr")
73747
- );
73748
- if (color2) {
73749
- lineColors.push(color2);
73750
- }
73751
- }
73752
- }
73753
- if (fillColors.length === 0 && lineColors.length === 0) {
74903
+ const colorLists = buildSmartArtColorLists(styleLbls, {
74904
+ getChild: (node, childName) => this.xmlLookupService.getChildByLocalName(node, childName),
74905
+ parseColorChoice: (colorChoice) => this.parseColor(colorChoice),
74906
+ resolveScheme: (colorNode) => this.resolveSmartArtSchemeColor(colorNode)
74907
+ });
74908
+ if (colorLists.fillColors.length === 0 && colorLists.lineColors.length === 0) {
73754
74909
  return void 0;
73755
74910
  }
73756
- return { ...metadata, name, fillColors, lineColors, labels };
74911
+ return { ...metadata, name, ...colorLists, labels };
73757
74912
  } catch {
73758
74913
  return void 0;
73759
74914
  }
@@ -74098,6 +75253,107 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
74098
75253
  };
74099
75254
  }
74100
75255
  };
75256
+ function collectDrawingShapeNodes(root, getChildren) {
75257
+ const out = [];
75258
+ const walk = (container) => {
75259
+ if (!container) {
75260
+ return;
75261
+ }
75262
+ for (const sp of getChildren(container, "sp")) {
75263
+ out.push({ node: sp, isPic: false });
75264
+ }
75265
+ for (const pic of getChildren(container, "pic")) {
75266
+ out.push({ node: pic, isPic: true });
75267
+ }
75268
+ for (const grp of getChildren(container, "grpSp")) {
75269
+ walk(grp);
75270
+ }
75271
+ };
75272
+ walk(root);
75273
+ return out;
75274
+ }
75275
+ function picBlipEmbedId(pic, getChild) {
75276
+ const blip = getChild(getChild(pic, "blipFill"), "blip");
75277
+ if (!blip) {
75278
+ return void 0;
75279
+ }
75280
+ const embed = String(blip["@_r:embed"] || blip["@_embed"] || blip["@_r:link"] || "").trim();
75281
+ return embed.length > 0 ? embed : void 0;
75282
+ }
75283
+ function parseDrawingRelTargets(relsXml, parse, ensureArray16) {
75284
+ const map = /* @__PURE__ */ new Map();
75285
+ try {
75286
+ const relsRoot = parse(relsXml)["Relationships"];
75287
+ if (!relsRoot) {
75288
+ return map;
75289
+ }
75290
+ for (const rel of ensureArray16(relsRoot["Relationship"])) {
75291
+ const id = String(rel?.["@_Id"] || "").trim();
75292
+ const target = String(rel?.["@_Target"] || "").trim();
75293
+ if (id.length > 0 && target.length > 0) {
75294
+ map.set(id, target);
75295
+ }
75296
+ }
75297
+ } catch {
75298
+ }
75299
+ return map;
75300
+ }
75301
+ async function resolveDrawingBlipFills(shapes, drawingPath, deps) {
75302
+ const pending = shapes.filter((shape) => shape.fillBlipEmbedId && !shape.fillImageUrl);
75303
+ if (pending.length === 0) {
75304
+ return;
75305
+ }
75306
+ const dir = drawingPath.replace(/\/[^/]+$/u, "");
75307
+ const file = drawingPath.split("/").pop() ?? "";
75308
+ const relsXml = await deps.readText(`${dir}/_rels/${file}.rels`);
75309
+ if (!relsXml) {
75310
+ return;
75311
+ }
75312
+ const targets = parseDrawingRelTargets(relsXml, deps.parse, deps.ensureArray);
75313
+ for (const shape of pending) {
75314
+ const target = targets.get(shape.fillBlipEmbedId ?? "");
75315
+ if (!target) {
75316
+ continue;
75317
+ }
75318
+ const source = /^(?:https?:|data:)/u.test(target) ? target : deps.resolveImagePath(drawingPath, target);
75319
+ const resolved = await deps.getImageData(source);
75320
+ if (resolved) {
75321
+ shape.fillImageUrl = resolved;
75322
+ }
75323
+ }
75324
+ }
75325
+ async function parseDrawingShapesFromPart(drawingPath, deps) {
75326
+ const xmlString = await deps.readText(drawingPath);
75327
+ if (!xmlString) {
75328
+ return [];
75329
+ }
75330
+ try {
75331
+ const xml = deps.parse(xmlString);
75332
+ const drawing = deps.getChild(xml, "drawing");
75333
+ const spTree = deps.getChild(drawing || xml, "spTree");
75334
+ if (!spTree) {
75335
+ return [];
75336
+ }
75337
+ const shapes = [];
75338
+ collectDrawingShapeNodes(spTree, deps.getChildren).forEach(({ node, isPic }, index) => {
75339
+ const shape = deps.parseDrawingShape(node, index, deps.emuPerPx);
75340
+ if (!shape) {
75341
+ return;
75342
+ }
75343
+ if (isPic && !shape.fillBlipEmbedId) {
75344
+ const embed = picBlipEmbedId(node, deps.getChild);
75345
+ if (embed) {
75346
+ shape.fillBlipEmbedId = embed;
75347
+ }
75348
+ }
75349
+ shapes.push(shape);
75350
+ });
75351
+ await resolveDrawingBlipFills(shapes, drawingPath, deps);
75352
+ return shapes;
75353
+ } catch {
75354
+ return [];
75355
+ }
75356
+ }
74101
75357
  var CATEGORY_FAMILY = {
74102
75358
  list: "list",
74103
75359
  process: "process",
@@ -74230,6 +75486,7 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime36 extends PptxHandlerRuntim
74230
75486
  layoutDefinition,
74231
75487
  nodes,
74232
75488
  connections: parsedConnections.length > 0 ? parsedConnections : void 0,
75489
+ presLayoutVars: parseSmartArtPresLayoutVars(dataModel),
74233
75490
  drawingShapes: drawingShapes.length > 0 ? drawingShapes : void 0,
74234
75491
  chrome,
74235
75492
  colorTransform,
@@ -74308,30 +75565,28 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime36 extends PptxHandlerRuntim
74308
75565
  }
74309
75566
  }
74310
75567
  /**
74311
- * Parse SmartArt drawing shapes given an absolute part path.
75568
+ * Parse cached SmartArt drawing shapes from an absolute part path.
74312
75569
  *
74313
- * Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
74314
- * relationship id) with a path-based lookup so the resolution layer
74315
- * can pull the part from anywhere in the package.
75570
+ * Enumerates `dsp:sp` / bare `dsp:pic` (incl. nested `dsp:grpSp`) and
75571
+ * resolves picture (blip) fills to data URLs via the drawing part's own
75572
+ * relationships. Delegates to a pure helper with an injected dep bundle.
74316
75573
  */
74317
75574
  async parseSmartArtDrawingShapesFromPath(drawingPath) {
74318
- const xmlString = await this.zip.file(drawingPath)?.async("string");
74319
- if (!xmlString) {
74320
- return [];
74321
- }
74322
- try {
74323
- const xml = this.parser.parse(xmlString);
74324
- const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
74325
- const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
74326
- if (!spTree) {
74327
- return [];
74328
- }
74329
- const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
74330
- const emuPerPx = _PptxHandlerRuntime36.EMU_PER_PX;
74331
- return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
74332
- } catch {
74333
- return [];
74334
- }
75575
+ return parseDrawingShapesFromPart(drawingPath, this.drawingBlipDeps());
75576
+ }
75577
+ /** Bind runtime zip / parser / lookup / image helpers for the drawing parser. */
75578
+ drawingBlipDeps() {
75579
+ return {
75580
+ readText: (path) => this.zip.file(path)?.async("string") ?? Promise.resolve(void 0),
75581
+ parse: (xml) => this.parser.parse(xml),
75582
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
75583
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
75584
+ parseDrawingShape: (sp, index, emuPerPx) => this.parseDrawingShape(sp, index, emuPerPx),
75585
+ emuPerPx: _PptxHandlerRuntime36.EMU_PER_PX,
75586
+ ensureArray: (value) => this.ensureArray(value),
75587
+ resolveImagePath: (base, target) => this.resolveImagePath(base, target),
75588
+ getImageData: (path) => this.getImageData(path)
75589
+ };
74335
75590
  }
74336
75591
  };
74337
75592
  var PptxHandlerRuntime86 = class extends PptxHandlerRuntime85 {
@@ -75019,6 +76274,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
75019
76274
  grouping = "clustered";
75020
76275
  }
75021
76276
  }
76277
+ const varyColors = this.parseChartBoolVal(seriesContainer, "varyColors");
76278
+ const firstSliceAngle = this.parseChartNumberVal(seriesContainer, "firstSliceAng");
76279
+ const doughnutHoleSize = this.parseChartNumberVal(seriesContainer, "holeSize");
76280
+ const barGapWidth = this.parseChartNumberVal(seriesContainer, "gapWidth");
76281
+ const barOverlap = this.parseChartNumberVal(seriesContainer, "overlap");
75022
76282
  const chartPartPath = chartPart.partPath;
75023
76283
  const dataTable = parseDataTable(plotArea, this.xmlLookupService);
75024
76284
  const dropLines = parseLineStyle(
@@ -75095,6 +76355,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
75095
76355
  title: titleTextValues[0],
75096
76356
  style: chartStyle,
75097
76357
  grouping,
76358
+ ...varyColors !== void 0 ? { varyColors } : {},
76359
+ ...firstSliceAngle !== void 0 ? { firstSliceAngle } : {},
76360
+ ...doughnutHoleSize !== void 0 ? { doughnutHoleSize } : {},
76361
+ ...barGapWidth !== void 0 ? { barGapWidth } : {},
76362
+ ...barOverlap !== void 0 ? { barOverlap } : {},
75098
76363
  chartPartPath,
75099
76364
  chartRelationshipId,
75100
76365
  ...dataTable ? { dataTable } : {},
@@ -75171,6 +76436,35 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
75171
76436
  }
75172
76437
  return { categories, series };
75173
76438
  }
76439
+ /**
76440
+ * Read a numeric `@val` from a named child of a chart-type container.
76441
+ * Returns `undefined` when the child or its `@val` is absent/non-finite.
76442
+ */
76443
+ parseChartNumberVal(container, localName22) {
76444
+ const node = this.xmlLookupService.getChildByLocalName(container, localName22);
76445
+ const raw = node?.["@_val"];
76446
+ if (raw === void 0 || raw === null || raw === "") {
76447
+ return void 0;
76448
+ }
76449
+ const num = Number.parseFloat(String(raw));
76450
+ return Number.isFinite(num) ? num : void 0;
76451
+ }
76452
+ /**
76453
+ * Read a boolean `@val` from a named child of a chart-type container.
76454
+ * A present element with no `@val` follows the OOXML `CT_Boolean` default
76455
+ * of `true`; `undefined` when the child is absent.
76456
+ */
76457
+ parseChartBoolVal(container, localName22) {
76458
+ const node = this.xmlLookupService.getChildByLocalName(container, localName22);
76459
+ if (!node) {
76460
+ return void 0;
76461
+ }
76462
+ const raw = node["@_val"];
76463
+ if (raw === void 0 || raw === null || raw === "") {
76464
+ return true;
76465
+ }
76466
+ return !(raw === "0" || raw === "false");
76467
+ }
75174
76468
  /**
75175
76469
  * Build the series array from raw OOXML `c:ser` nodes.
75176
76470
  *
@@ -75214,6 +76508,10 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
75214
76508
  );
75215
76509
  const dataLabels = parseSeriesDataLabels(seriesNode, this.xmlLookupService);
75216
76510
  const explosion = parseSeriesExplosion(seriesNode, this.xmlLookupService);
76511
+ const smoothNode = this.xmlLookupService.getChildByLocalName(seriesNode, "smooth");
76512
+ const smooth = smoothNode ? !(smoothNode["@_val"] === "0" || smoothNode["@_val"] === "false") : void 0;
76513
+ const invertNode = this.xmlLookupService.getChildByLocalName(seriesNode, "invertIfNegative");
76514
+ const invertIfNegative = invertNode ? !(invertNode["@_val"] === "0" || invertNode["@_val"] === "false") : void 0;
75217
76515
  return {
75218
76516
  name: seriesName.trim().length > 0 ? seriesName : `Series ${seriesIndex + 1}`,
75219
76517
  values: fallbackValues,
@@ -75224,6 +76522,8 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
75224
76522
  ...seriesMarker ? { marker: seriesMarker } : {},
75225
76523
  ...dataLabels.length > 0 ? { dataLabels } : {},
75226
76524
  ...explosion !== void 0 ? { explosion } : {},
76525
+ ...invertIfNegative !== void 0 ? { invertIfNegative } : {},
76526
+ ...smooth !== void 0 ? { smooth } : {},
75227
76527
  ...axisId !== void 0 ? { axisId } : {},
75228
76528
  ...seriesChartType ? { seriesChartType } : {}
75229
76529
  };
@@ -76042,6 +77342,8 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
76042
77342
  async buildLoadData(presentationState, slidesWithWarnings, slideMasters) {
76043
77343
  const headerFooter = this.extractHeaderFooter();
76044
77344
  const presentationProperties = await this.parsePresentationProperties();
77345
+ const viewProperties = await this.parseViewProperties();
77346
+ this.loadedViewProperties = viewProperties;
76045
77347
  const customShows = this.parseCustomShows();
76046
77348
  const tableStyleMap = await this.parseTableStyles();
76047
77349
  const embeddedFontList = parseEmbeddedFontList(this.presentationData);
@@ -76071,7 +77373,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
76071
77373
  presentationState.height,
76072
77374
  this.rawSlideWidthEmu,
76073
77375
  this.rawSlideHeightEmu
76074
- ).withNotesDimensions(presentationState.notesWidthEmu, presentationState.notesHeightEmu).withSlides(slidesWithWarnings).withLayoutOptions(this.getLayoutOptions()).withHeaderFooter(headerFooter).withPresentationProperties(presentationProperties).withCustomShows(customShows).withSections(
77376
+ ).withNotesDimensions(presentationState.notesWidthEmu, presentationState.notesHeightEmu).withSlides(slidesWithWarnings).withLayoutOptions(this.getLayoutOptions()).withHeaderFooter(headerFooter).withPresentationProperties(presentationProperties).withViewProperties(viewProperties).withCustomShows(customShows).withSections(
76075
77377
  presentationState.orderedSections.length > 0 ? presentationState.orderedSections : void 0
76076
77378
  ).withWarnings(this.compatibilityService.getWarnings()).withThemeColorMap({ ...this.themeColorMap }).withTheme(this.buildThemeObject()).withThemeOptions(themeOptions.length > 0 ? themeOptions : void 0).withTableStyleMap(tableStyleMap).withEmbeddedFonts(embeddedFonts.length > 0 ? embeddedFonts : void 0).withEmbeddedFontList(embeddedFontList).withMruColors(presentationProperties?.mruColors).withNotesMaster(notesMaster).withHandoutMaster(handoutMaster).withSlideMasters(slideMasters.length > 0 ? slideMasters : void 0).withTags(tags.length > 0 ? tags : void 0).withCustomProperties(customProperties.length > 0 ? customProperties : void 0).withCoreProperties(coreProperties).withAppProperties(appProperties).withHasMacros(this.vbaProjectBin !== null ? true : void 0).withHasDigitalSignatures(this.signatureDetection?.hasSignatures || void 0).withDigitalSignatureCount(
76077
77379
  this.signatureDetection?.signatureCount && this.signatureDetection.signatureCount > 0 ? this.signatureDetection.signatureCount : void 0
@@ -76202,6 +77504,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
76202
77504
  this.customXmlParts = [];
76203
77505
  this.loadedEmbeddedFonts = [];
76204
77506
  this.loadedEmbeddedFontList = void 0;
77507
+ this.loadedViewProperties = void 0;
76205
77508
  this.orderedSlidePaths = [];
76206
77509
  this.zip = null;
76207
77510
  }
@@ -77147,11 +78450,13 @@ function parseDrawingColorChoice(colorNode) {
77147
78450
  }
77148
78451
  if (colorNode["a:scrgbClr"]) {
77149
78452
  const scrgb = colorNode["a:scrgbClr"];
77150
- const red = parseDrawingPercent(scrgb["@_r"]);
77151
- const green = parseDrawingPercent(scrgb["@_g"]);
77152
- const blue = parseDrawingPercent(scrgb["@_b"]);
78453
+ const red = parseDrawingFraction(scrgb["@_r"]);
78454
+ const green = parseDrawingFraction(scrgb["@_g"]);
78455
+ const blue = parseDrawingFraction(scrgb["@_b"]);
77153
78456
  if (red !== void 0 && green !== void 0 && blue !== void 0) {
77154
- const base = `#${toHex(red * 255)}${toHex(green * 255)}${toHex(blue * 255)}`;
78457
+ const base = `#${toHex(scrgbLinearToSrgb8(red))}${toHex(scrgbLinearToSrgb8(green))}${toHex(
78458
+ scrgbLinearToSrgb8(blue)
78459
+ )}`;
77155
78460
  return applyDrawingColorTransforms(base, scrgb);
77156
78461
  }
77157
78462
  }
@@ -77236,7 +78541,7 @@ function parseDrawingColorOpacity(colorNode) {
77236
78541
  const alphaMod = parseDrawingPercent(
77237
78542
  colorChoice["a:alphaMod"]?.["@_val"]
77238
78543
  );
77239
- const alphaOff = parseDrawingPercent(
78544
+ const alphaOff = parseDrawingFraction(
77240
78545
  colorChoice["a:alphaOff"]?.["@_val"]
77241
78546
  );
77242
78547
  if (alpha === void 0 && alphaMod === void 0 && alphaOff === void 0) {
@@ -91358,6 +92663,7 @@ exports.buildInkMlContent = buildInkMlContent;
91358
92663
  exports.buildLinkedTextBoxChains = buildLinkedTextBoxChains;
91359
92664
  exports.buildOle2 = buildOle2;
91360
92665
  exports.buildSingleEffectNode = buildSingleEffectNode;
92666
+ exports.buildSlideReferenceRemap = buildSlideReferenceRemap;
91361
92667
  exports.buildSrgbColorChoice = buildSrgbColorChoice;
91362
92668
  exports.buildThemeColorMap = buildThemeColorMap;
91363
92669
  exports.catmullRomToBezier = catmullRomToBezier;
@@ -91431,6 +92737,8 @@ exports.decryptPptx = decryptPptx;
91431
92737
  exports.demoteSmartArtNode = demoteSmartArtNode;
91432
92738
  exports.deobfuscateFont = deobfuscateFont;
91433
92739
  exports.deriveOutputPath = deriveOutputPath;
92740
+ exports.deriveSlideTitle = deriveSlideTitle;
92741
+ exports.deriveSlideTitles = deriveSlideTitles;
91434
92742
  exports.detectDigitalSignatures = detectDigitalSignatures;
91435
92743
  exports.detectFileFormat = detectFileFormat;
91436
92744
  exports.detectFontFormat = detectFontFormat;