pptx-react-viewer 1.25.3 → 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 (97) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/{Model3DScene-IQLE5JLL.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-F2GUSTZI.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-JG26PJ7O.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-4OMD7LWR.js → SurfaceChart3DScene-WMY5JTW4.js} +3 -3
  12. package/dist/{SurfaceChart3DScene-4OMD7LWR.js.br → SurfaceChart3DScene-WMY5JTW4.js.br} +0 -0
  13. package/dist/SurfaceChart3DScene-WMY5JTW4.js.gz +0 -0
  14. package/dist/{chunk-5G3SPYQE.js → chunk-7CSBUYRN.js} +849 -808
  15. package/dist/chunk-7CSBUYRN.js.br +0 -0
  16. package/dist/chunk-7CSBUYRN.js.gz +0 -0
  17. package/dist/{chunk-ZUJHFLOR.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-NYBERTS7.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-DAI4KM5W.mjs → chunk-FOMF7POV.mjs} +2285 -490
  24. package/dist/chunk-FOMF7POV.mjs.br +0 -0
  25. package/dist/chunk-FOMF7POV.mjs.gz +0 -0
  26. package/dist/{chunk-DVM75RMN.mjs → chunk-FVQDRA5N.mjs} +1100 -126
  27. package/dist/chunk-FVQDRA5N.mjs.br +0 -0
  28. package/dist/chunk-FVQDRA5N.mjs.gz +0 -0
  29. package/dist/{chunk-2V6BD4JQ.js → chunk-IPYAN574.js} +2288 -490
  30. package/dist/chunk-IPYAN574.js.br +0 -0
  31. package/dist/chunk-IPYAN574.js.gz +0 -0
  32. package/dist/{chunk-GNXWU7UG.mjs → chunk-L4ZADJOM.mjs} +48 -7
  33. package/dist/chunk-L4ZADJOM.mjs.br +0 -0
  34. package/dist/chunk-L4ZADJOM.mjs.gz +0 -0
  35. package/dist/{chunk-UXVFNGJH.js → chunk-TEN35NUX.js} +1133 -159
  36. package/dist/chunk-TEN35NUX.js.br +0 -0
  37. package/dist/chunk-TEN35NUX.js.gz +0 -0
  38. package/dist/{dist-ZA77P2O5.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 +350 -5
  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 +330 -2
  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 +330 -2
  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-F2GUSTZI.js.br +0 -0
  70. package/dist/Model3DScene-F2GUSTZI.js.gz +0 -0
  71. package/dist/Model3DScene-IQLE5JLL.mjs.br +0 -0
  72. package/dist/Model3DScene-IQLE5JLL.mjs.gz +0 -0
  73. package/dist/SurfaceChart3DScene-4OMD7LWR.js.gz +0 -0
  74. package/dist/SurfaceChart3DScene-JG26PJ7O.mjs.br +0 -0
  75. package/dist/SurfaceChart3DScene-JG26PJ7O.mjs.gz +0 -0
  76. package/dist/chunk-2V6BD4JQ.js.br +0 -0
  77. package/dist/chunk-2V6BD4JQ.js.gz +0 -0
  78. package/dist/chunk-5G3SPYQE.js.br +0 -0
  79. package/dist/chunk-5G3SPYQE.js.gz +0 -0
  80. package/dist/chunk-DAI4KM5W.mjs.br +0 -0
  81. package/dist/chunk-DAI4KM5W.mjs.gz +0 -0
  82. package/dist/chunk-DVM75RMN.mjs.br +0 -0
  83. package/dist/chunk-DVM75RMN.mjs.gz +0 -0
  84. package/dist/chunk-GNXWU7UG.mjs.br +0 -0
  85. package/dist/chunk-GNXWU7UG.mjs.gz +0 -0
  86. package/dist/chunk-NYBERTS7.mjs.br +0 -0
  87. package/dist/chunk-NYBERTS7.mjs.gz +0 -0
  88. package/dist/chunk-UXVFNGJH.js.br +0 -0
  89. package/dist/chunk-UXVFNGJH.js.gz +0 -0
  90. package/dist/chunk-ZUJHFLOR.js.br +0 -0
  91. package/dist/chunk-ZUJHFLOR.js.gz +0 -0
  92. package/dist/dist-E3IHM3OU.mjs +0 -2
  93. package/dist/dist-E3IHM3OU.mjs.br +0 -0
  94. package/dist/dist-E3IHM3OU.mjs.gz +0 -0
  95. package/dist/dist-ZA77P2O5.js.br +0 -0
  96. package/dist/dist-ZA77P2O5.js.gz +0 -0
  97. 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;
@@ -13597,26 +13758,49 @@ function applyScene3dStyle(shapeProps, style) {
13597
13758
  const camera = scene3dNode["a:camera"];
13598
13759
  const lightRig = scene3dNode["a:lightRig"];
13599
13760
  const cameraRot = camera?.["a:rot"];
13761
+ const lightRigRot = lightRig?.["a:rot"];
13600
13762
  style.scene3d = {
13601
13763
  cameraPreset: String(camera?.["@_prst"] || "").trim() || void 0,
13602
- cameraRotX: cameraRot?.["@_lat"] !== void 0 ? parseInt(String(cameraRot["@_lat"]), 10) : void 0,
13603
- cameraRotY: cameraRot?.["@_lon"] !== void 0 ? parseInt(String(cameraRot["@_lon"]), 10) : void 0,
13604
- cameraRotZ: cameraRot?.["@_rev"] !== void 0 ? parseInt(String(cameraRot["@_rev"]), 10) : void 0,
13764
+ cameraFieldOfView: intAttr(camera?.["@_fov"]),
13765
+ cameraZoom: floatAttr(camera?.["@_zoom"]),
13766
+ cameraRotX: intAttr(cameraRot?.["@_lat"]),
13767
+ cameraRotY: intAttr(cameraRot?.["@_lon"]),
13768
+ cameraRotZ: intAttr(cameraRot?.["@_rev"]),
13605
13769
  lightRigType: String(lightRig?.["@_rig"] || "").trim() || void 0,
13606
- lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0
13770
+ lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0,
13771
+ lightRigRotX: intAttr(lightRigRot?.["@_lat"]),
13772
+ lightRigRotY: intAttr(lightRigRot?.["@_lon"]),
13773
+ lightRigRotZ: intAttr(lightRigRot?.["@_rev"])
13607
13774
  };
13608
13775
  const backdrop = scene3dNode["a:backdrop"];
13609
13776
  if (backdrop) {
13610
13777
  style.scene3d.hasBackdrop = true;
13611
13778
  const anchor = backdrop["a:anchor"];
13612
- const anchorAttrs = anchor;
13613
- if (anchorAttrs) {
13614
- style.scene3d.backdropAnchorX = parseInt(String(anchorAttrs["@_x"] || "0"), 10);
13615
- style.scene3d.backdropAnchorY = parseInt(String(anchorAttrs["@_y"] || "0"), 10);
13616
- style.scene3d.backdropAnchorZ = parseInt(String(anchorAttrs["@_z"] || "0"), 10);
13779
+ if (anchor) {
13780
+ style.scene3d.backdropAnchorX = intAttr(anchor["@_x"]) ?? 0;
13781
+ style.scene3d.backdropAnchorY = intAttr(anchor["@_y"]) ?? 0;
13782
+ style.scene3d.backdropAnchorZ = intAttr(anchor["@_z"]) ?? 0;
13783
+ }
13784
+ const norm = backdrop["a:norm"];
13785
+ if (norm) {
13786
+ style.scene3d.backdropNormalX = intAttr(norm["@_dx"]) ?? 0;
13787
+ style.scene3d.backdropNormalY = intAttr(norm["@_dy"]) ?? 0;
13788
+ style.scene3d.backdropNormalZ = intAttr(norm["@_dz"]) ?? 0;
13789
+ }
13790
+ const up = backdrop["a:up"];
13791
+ if (up) {
13792
+ style.scene3d.backdropUpX = intAttr(up["@_dx"]) ?? 0;
13793
+ style.scene3d.backdropUpY = intAttr(up["@_dy"]) ?? 0;
13794
+ style.scene3d.backdropUpZ = intAttr(up["@_dz"]) ?? 0;
13617
13795
  }
13618
13796
  }
13619
13797
  }
13798
+ function intAttr(value) {
13799
+ return value !== void 0 ? parseInt(String(value), 10) : void 0;
13800
+ }
13801
+ function floatAttr(value) {
13802
+ return value !== void 0 ? parseFloat(String(value)) : void 0;
13803
+ }
13620
13804
  function applyShape3dStyle(shapeProps, style, context) {
13621
13805
  const shape3dNode = shapeProps["a:sp3d"];
13622
13806
  if (!shape3dNode) {
@@ -13647,10 +13831,12 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
13647
13831
  }
13648
13832
  const hiddenLineFill = hiddenLineProps["a:solidFill"];
13649
13833
  if (hiddenLineFill) {
13834
+ style.strokeFillMode = "solid";
13650
13835
  style.strokeColor = context.parseColor(hiddenLineFill);
13651
13836
  style.strokeOpacity = context.extractColorOpacity(hiddenLineFill);
13652
13837
  }
13653
13838
  } else {
13839
+ style.strokeFillMode = "none";
13654
13840
  style.strokeWidth = 0;
13655
13841
  style.strokeColor = "transparent";
13656
13842
  }
@@ -13668,6 +13854,7 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
13668
13854
  }
13669
13855
  function applyStrokeColor(lineNode, style, context) {
13670
13856
  if (lineNode["a:solidFill"]) {
13857
+ style.strokeFillMode = "solid";
13671
13858
  const lineFill = lineNode["a:solidFill"];
13672
13859
  style.strokeColor = context.parseColor(lineFill);
13673
13860
  style.strokeOpacity = context.extractColorOpacity(lineFill);
@@ -13676,10 +13863,15 @@ function applyStrokeColor(lineNode, style, context) {
13676
13863
  style.strokeColorXml = strokeColorXml;
13677
13864
  }
13678
13865
  } else if (lineNode["a:gradFill"]) {
13679
- style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
13680
- 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);
13681
13871
  } else if (lineNode["a:pattFill"]) {
13872
+ style.strokeFillMode = "pattern";
13682
13873
  const linePatternFill = lineNode["a:pattFill"];
13874
+ style.strokePatternXml = linePatternFill;
13683
13875
  style.strokeColor = context.parseColor(linePatternFill["a:fgClr"]) || context.parseColor(linePatternFill["a:bgClr"]);
13684
13876
  style.strokeOpacity = context.extractColorOpacity(linePatternFill["a:fgClr"]) || context.extractColorOpacity(linePatternFill["a:bgClr"]);
13685
13877
  }
@@ -13806,6 +13998,10 @@ var PptxShapeStyleExtractor = class {
13806
13998
  style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
13807
13999
  style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
13808
14000
  style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
14001
+ const gradTileRect = extractGradientTileRect(gradFill);
14002
+ if (gradTileRect) {
14003
+ style.fillGradientTileRect = gradTileRect;
14004
+ }
13809
14005
  const gradFlip = this.context.extractGradientFlip(gradFill);
13810
14006
  if (gradFlip) {
13811
14007
  style.fillGradientFlip = gradFlip;
@@ -14486,7 +14682,7 @@ var MEDIA_REFERENCE_NAMES = [
14486
14682
  "videoFile",
14487
14683
  "quickTimeFile"
14488
14684
  ];
14489
- function parseDrawingMediaReference(container) {
14685
+ function parseDrawingMediaReference(container, externalRelIds) {
14490
14686
  if (!container) {
14491
14687
  return void 0;
14492
14688
  }
@@ -14495,11 +14691,17 @@ function parseDrawingMediaReference(container) {
14495
14691
  if (!node) {
14496
14692
  continue;
14497
14693
  }
14694
+ const linkId = String(attribute2(node, "link") ?? "").trim() || void 0;
14695
+ const embedId = String(attribute2(node, "embed") ?? "").trim() || void 0;
14498
14696
  return {
14499
14697
  kind,
14500
14698
  mediaType: kind === "videoFile" || kind === "quickTimeFile" ? "video" : "audio",
14501
- relationshipId: String(attribute2(node, "link") ?? attribute2(node, "embed") ?? "").trim() || void 0,
14502
- isLinked: attribute2(node, "link") !== void 0,
14699
+ relationshipId: linkId ?? embedId,
14700
+ // Embedded media legitimately uses r:link pointing at an INTERNAL
14701
+ // media part, so link presence alone does not imply a linked clip.
14702
+ // It is only truly linked when the referenced relationship is
14703
+ // external (TargetMode="External"), mirroring the OLE parser.
14704
+ isLinked: linkId !== void 0 && externalRelIds?.has(linkId) === true,
14503
14705
  name: kind === "wavAudioFile" ? String(attribute2(node, "name") ?? "") || void 0 : void 0,
14504
14706
  contentType: kind === "audioFile" ? String(attribute2(node, "contentType") ?? "") || void 0 : void 0,
14505
14707
  audioCdStart: kind === "audioCd" ? parseAudioCdPosition(child2(node, "st")) : void 0,
@@ -14628,7 +14830,10 @@ var PptxMediaDataParser = class {
14628
14830
  parseMediaData(graphicData, slidePath) {
14629
14831
  const result = {};
14630
14832
  try {
14631
- const reference = parseDrawingMediaReference(graphicData);
14833
+ const reference = parseDrawingMediaReference(
14834
+ graphicData,
14835
+ this.context.externalRelsMap.get(slidePath)
14836
+ );
14632
14837
  if (reference) {
14633
14838
  result.mediaType = reference.mediaType;
14634
14839
  result.mediaReferenceKind = reference.kind;
@@ -15231,6 +15436,7 @@ var PptxLoadDataBuilder = class {
15231
15436
  layoutOptions = [];
15232
15437
  headerFooter;
15233
15438
  presentationProperties;
15439
+ viewProperties;
15234
15440
  customShows;
15235
15441
  sections;
15236
15442
  warnings = [];
@@ -15290,6 +15496,10 @@ var PptxLoadDataBuilder = class {
15290
15496
  this.presentationProperties = presentationProperties;
15291
15497
  return this;
15292
15498
  }
15499
+ withViewProperties(viewProperties) {
15500
+ this.viewProperties = viewProperties;
15501
+ return this;
15502
+ }
15293
15503
  withCustomShows(customShows) {
15294
15504
  this.customShows = customShows;
15295
15505
  return this;
@@ -15427,6 +15637,7 @@ var PptxLoadDataBuilder = class {
15427
15637
  layoutOptions: this.layoutOptions,
15428
15638
  headerFooter: this.headerFooter,
15429
15639
  presentationProperties: this.presentationProperties,
15640
+ viewProperties: this.viewProperties,
15430
15641
  customShows: this.customShows,
15431
15642
  sections: this.sections,
15432
15643
  warnings: this.warnings,
@@ -15801,7 +16012,7 @@ var PptxSlideCommentsXmlFactory = class {
15801
16012
  const createdAtIso = this.resolveCreatedAt(comment.createdAt);
15802
16013
  const x = init.saveState.toEmu(comment.x, 0);
15803
16014
  const y = init.saveState.toEmu(comment.y, 0);
15804
- return {
16015
+ const node = {
15805
16016
  ...withoutChildrenByLocalName(comment.rawXml ?? {}, /* @__PURE__ */ new Set(["pos", "text"])),
15806
16017
  "@_authorId": authorId,
15807
16018
  "@_dt": createdAtIso,
@@ -15812,6 +16023,28 @@ var PptxSlideCommentsXmlFactory = class {
15812
16023
  },
15813
16024
  "p:text": String(comment.text || "")
15814
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
+ }
15815
16048
  }
15816
16049
  resolveCreatedAt(createdAt) {
15817
16050
  const candidate = String(createdAt || "").trim();
@@ -17095,6 +17328,220 @@ var PptxCompatibilityService = class {
17095
17328
  ].join("|");
17096
17329
  }
17097
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
+ }
17098
17545
  var PptxDocumentPropertiesUpdater = class {
17099
17546
  context;
17100
17547
  constructor(context) {
@@ -17157,6 +17604,7 @@ var PptxDocumentPropertiesUpdater = class {
17157
17604
  appProps["Slides"] = String(slides.length);
17158
17605
  appProps["HiddenSlides"] = String(hiddenSlidesCount);
17159
17606
  appProps["Notes"] = String(notesCount);
17607
+ this.updateSlideTitleProperties(appProps, slides);
17160
17608
  appData["Properties"] = appProps;
17161
17609
  this.context.zip.file("docProps/app.xml", this.context.builder.build(appData));
17162
17610
  } catch (error) {
@@ -17199,6 +17647,15 @@ var PptxDocumentPropertiesUpdater = class {
17199
17647
  }
17200
17648
  }
17201
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
+ }
17202
17659
  applyAppPropertiesOverrides(appProps, overrides10) {
17203
17660
  if (!overrides10) {
17204
17661
  return;
@@ -19005,6 +19462,16 @@ function extractChildKeyframes(childTnList) {
19005
19462
  }
19006
19463
  return void 0;
19007
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
+ }
19008
19475
  function extractRepeatInfo(cTn) {
19009
19476
  let repeatCount;
19010
19477
  let autoReverse;
@@ -19148,11 +19615,11 @@ function ensureArray4(value) {
19148
19615
  return [];
19149
19616
  }
19150
19617
  if (!Array.isArray(value)) {
19151
- return isXmlObject(value) ? [value] : [];
19618
+ return isXmlObject2(value) ? [value] : [];
19152
19619
  }
19153
- return value.filter((entry) => isXmlObject(entry));
19620
+ return value.filter((entry) => isXmlObject2(entry));
19154
19621
  }
19155
- function isXmlObject(value) {
19622
+ function isXmlObject2(value) {
19156
19623
  return typeof value === "object" && value !== null && !Array.isArray(value);
19157
19624
  }
19158
19625
  var VALID_CONDITION_EVENTS = /* @__PURE__ */ new Set([
@@ -19513,8 +19980,11 @@ var PptxNativeAnimationService = class {
19513
19980
  const nodeType = String(cTn["@_nodeType"] || "");
19514
19981
  const presetClass = cTn["@_presetClass"];
19515
19982
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
19983
+ const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
19516
19984
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
19517
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"]);
19518
19988
  let trigger = currentTrigger;
19519
19989
  if (nodeType === "afterPrevious" || nodeType === "afterPrev") {
19520
19990
  trigger = "afterPrevious";
@@ -19564,8 +20034,11 @@ var PptxNativeAnimationService = class {
19564
20034
  trigger,
19565
20035
  presetClass: validPresetClass,
19566
20036
  presetId,
20037
+ presetSubtype,
19567
20038
  durationMs,
19568
20039
  delayMs,
20040
+ accel,
20041
+ decel,
19569
20042
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
19570
20043
  motionPath: childMotion.motionPath,
19571
20044
  motionOrigin: childMotion.motionOrigin,
@@ -19871,6 +20344,72 @@ function buildP14ExtLst(transitionType, direction, orient, pattern, rawExtLst, x
19871
20344
  }
19872
20345
  return { "p:ext": transitionExt };
19873
20346
  }
20347
+ var P15_TRANSITION_PRESETS = /* @__PURE__ */ new Set([
20348
+ "fallOver",
20349
+ "drape",
20350
+ "curtains",
20351
+ "wind",
20352
+ "prestige",
20353
+ "fracture",
20354
+ "crush",
20355
+ "peelOff",
20356
+ "pageCurlDouble",
20357
+ "pageCurlSingle",
20358
+ "airplane",
20359
+ "origami"
20360
+ ]);
20361
+ var PRSTTRANS_EXT_URI = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}";
20362
+ function optionalBoolean(value) {
20363
+ const valueToken = value === void 0 || value === null ? "" : String(value).trim().toLowerCase();
20364
+ if (valueToken === "1" || valueToken === "true") {
20365
+ return true;
20366
+ }
20367
+ if (valueToken === "0" || valueToken === "false") {
20368
+ return false;
20369
+ }
20370
+ return void 0;
20371
+ }
20372
+ function parseP15FromExtLst(extLstNode, xmlLookupService, getXmlLocalName) {
20373
+ const extEntries = xmlLookupService.getChildrenArrayByLocalName(extLstNode, "ext");
20374
+ for (const ext of extEntries) {
20375
+ if (!ext) {
20376
+ continue;
20377
+ }
20378
+ for (const [key, value] of Object.entries(ext)) {
20379
+ if (key.startsWith("@_")) {
20380
+ continue;
20381
+ }
20382
+ if (getXmlLocalName(key) !== "prstTrans") {
20383
+ continue;
20384
+ }
20385
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
20386
+ continue;
20387
+ }
20388
+ const detail = value;
20389
+ const prst = String(detail["@_prst"] || "").trim();
20390
+ if (!P15_TRANSITION_PRESETS.has(prst)) {
20391
+ continue;
20392
+ }
20393
+ return {
20394
+ type: prst,
20395
+ invX: optionalBoolean(detail["@_invX"]),
20396
+ invY: optionalBoolean(detail["@_invY"])
20397
+ };
20398
+ }
20399
+ }
20400
+ return void 0;
20401
+ }
20402
+ function buildP15ExtLst(transitionType, invX, invY) {
20403
+ const prstTrans = {
20404
+ "@_xmlns:p15": "http://schemas.microsoft.com/office/powerpoint/2012/main",
20405
+ "@_prst": transitionType
20406
+ };
20407
+ const ext = {
20408
+ "@_uri": PRSTTRANS_EXT_URI,
20409
+ "p15:prstTrans": prstTrans
20410
+ };
20411
+ return { "p:ext": ext };
20412
+ }
19874
20413
  var STANDARD_TRANSITION_TYPES = /* @__PURE__ */ new Set([
19875
20414
  "fade",
19876
20415
  "push",
@@ -19935,7 +20474,7 @@ function parseTransitionDetails(node, localName22) {
19935
20474
  if (pattern) {
19936
20475
  result.pattern = pattern;
19937
20476
  }
19938
- const thruBlk = optionalBoolean(detail["@_thruBlk"]);
20477
+ const thruBlk = optionalBoolean2(detail["@_thruBlk"]);
19939
20478
  if (thruBlk !== void 0) {
19940
20479
  result.thruBlk = thruBlk;
19941
20480
  }
@@ -19946,7 +20485,7 @@ function parseTransitionAttributes(node) {
19946
20485
  const speedToken = token(node["@_spd"]);
19947
20486
  const speed = SPEEDS.has(speedToken) ? speedToken : void 0;
19948
20487
  const durationMs = unsignedInteger2(node["@_dur"] ?? node["@_p14:dur"], 1);
19949
- const advanceOnClick = optionalBoolean(node["@_advClick"]);
20488
+ const advanceOnClick = optionalBoolean2(node["@_advClick"]);
19950
20489
  const advanceAfterMs = unsignedInteger2(node["@_advTm"]);
19951
20490
  return { speed, durationMs, advanceOnClick, advanceAfterMs };
19952
20491
  }
@@ -19960,7 +20499,7 @@ function parseTransitionSound(raw, lookup, localName22) {
19960
20499
  return {
19961
20500
  soundRId: sound ? attributeByLocalName(sound, "embed", localName22) : void 0,
19962
20501
  soundName: sound ? attributeByLocalName(sound, "name", localName22) : void 0,
19963
- soundLoop: optionalBoolean(start["@_loop"])
20502
+ soundLoop: optionalBoolean2(start["@_loop"])
19964
20503
  };
19965
20504
  }
19966
20505
  const stopSound = Object.keys(raw).some(
@@ -20069,7 +20608,7 @@ function attributeByLocalName(node, name, localName22) {
20069
20608
  function token(value) {
20070
20609
  return value === void 0 || value === null ? "" : String(value).trim();
20071
20610
  }
20072
- function optionalBoolean(value) {
20611
+ function optionalBoolean2(value) {
20073
20612
  const valueToken = token(value).toLowerCase();
20074
20613
  if (!valueToken) {
20075
20614
  return void 0;
@@ -20113,6 +20652,7 @@ var PptxSlideTransitionService = class {
20113
20652
  const { spokes, thruBlk, rawSoundAction, rawExtLst } = details;
20114
20653
  if (rawExtLst && transitionType === "cut") {
20115
20654
  const p14Result = parseP14FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
20655
+ const p15Result = p14Result ? void 0 : parseP15FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
20116
20656
  if (p14Result) {
20117
20657
  transitionType = p14Result.type;
20118
20658
  if (p14Result.direction) {
@@ -20124,6 +20664,8 @@ var PptxSlideTransitionService = class {
20124
20664
  if (p14Result.pattern) {
20125
20665
  pattern = p14Result.pattern;
20126
20666
  }
20667
+ } else if (p15Result) {
20668
+ transitionType = p15Result.type;
20127
20669
  } else if (this.parseMorphFromExtLst(rawExtLst)) {
20128
20670
  transitionType = "morph";
20129
20671
  }
@@ -20205,6 +20747,7 @@ var PptxSlideTransitionService = class {
20205
20747
  }
20206
20748
  const transitionType = transition.type || "cut";
20207
20749
  const isP14Type = P14_TRANSITION_TYPES.has(transitionType);
20750
+ const isP15Type = P15_TRANSITION_PRESETS.has(transitionType);
20208
20751
  const isMorphType = transitionType === "morph";
20209
20752
  const node = createPreservedTransitionNode(transition.rawTransition, this.getXmlLocalName);
20210
20753
  if (isP14Type) {
@@ -20217,6 +20760,8 @@ var PptxSlideTransitionService = class {
20217
20760
  this.xmlLookupService,
20218
20761
  this.getXmlLocalName
20219
20762
  );
20763
+ } else if (isP15Type) {
20764
+ node["p:extLst"] = transition.rawExtLst ?? buildP15ExtLst(transitionType);
20220
20765
  } else if (isMorphType) {
20221
20766
  node["p:extLst"] = this.buildMorphExtLst(transition.rawExtLst);
20222
20767
  } else {
@@ -20227,7 +20772,7 @@ var PptxSlideTransitionService = class {
20227
20772
  if (soundAction) {
20228
20773
  node["p:sndAc"] = soundAction;
20229
20774
  }
20230
- if (transition.rawExtLst && !isP14Type && !isMorphType) {
20775
+ if (transition.rawExtLst && !isP14Type && !isP15Type && !isMorphType) {
20231
20776
  node["p:extLst"] = transition.rawExtLst;
20232
20777
  }
20233
20778
  return node;
@@ -20722,7 +21267,7 @@ function updateEffectNodeAttributes(cTn, anim, currentPresetClass) {
20722
21267
  if (stCondList && anim.delayMs !== void 0) {
20723
21268
  const conditions = ensureArray4(stCondList["p:cond"]);
20724
21269
  for (const cond of conditions) {
20725
- if (isXmlObject(cond)) {
21270
+ if (isXmlObject2(cond)) {
20726
21271
  cond["@_delay"] = String(anim.delayMs);
20727
21272
  }
20728
21273
  }
@@ -30740,7 +31285,7 @@ function getCalloutViewBoxBounds(width, height, geometry, padding = 2) {
30740
31285
  viewHeight: maxY - minY + padding * 2
30741
31286
  };
30742
31287
  }
30743
- function isXmlObject2(value) {
31288
+ function isXmlObject3(value) {
30744
31289
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
30745
31290
  }
30746
31291
  function ensureItems(value) {
@@ -30843,7 +31388,7 @@ function collectParsedOmathNodes(root) {
30843
31388
  }
30844
31389
  if (localName9(key) === "oMath") {
30845
31390
  for (const item of ensureItems(value)) {
30846
- if (isXmlObject2(item)) {
31391
+ if (isXmlObject3(item)) {
30847
31392
  result.push(item);
30848
31393
  }
30849
31394
  }
@@ -30906,7 +31451,7 @@ function reorderContainer(node, rawInner) {
30906
31451
  occurrence.set(child20.tag, index + 1);
30907
31452
  const value = ensureItems(node[child20.tag])[index];
30908
31453
  resolved.push({ tag: child20.tag, value });
30909
- if (isXmlObject2(value) && child20.inner) {
31454
+ if (isXmlObject3(value) && child20.inner) {
30910
31455
  reorderContainer(value, child20.inner);
30911
31456
  }
30912
31457
  }
@@ -30948,7 +31493,7 @@ function localName10(name) {
30948
31493
  const colon = name.indexOf(":");
30949
31494
  return colon >= 0 ? name.slice(colon + 1) : name;
30950
31495
  }
30951
- function isXmlObject3(value) {
31496
+ function isXmlObject4(value) {
30952
31497
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
30953
31498
  }
30954
31499
  function collectParsedParagraphs(root) {
@@ -30973,7 +31518,7 @@ function collectParsedParagraphs(root) {
30973
31518
  continue;
30974
31519
  }
30975
31520
  paragraphs.push(
30976
- ...(Array.isArray(childValue) ? childValue : [childValue]).filter(isXmlObject3)
31521
+ ...(Array.isArray(childValue) ? childValue : [childValue]).filter(isXmlObject4)
30977
31522
  );
30978
31523
  }
30979
31524
  } else {
@@ -31020,7 +31565,7 @@ function directChildrenByLocalName(paragraphs, name) {
31020
31565
  return [];
31021
31566
  }
31022
31567
  const values = Array.isArray(value) ? value : [value];
31023
- return values.filter(isXmlObject3);
31568
+ return values.filter(isXmlObject4);
31024
31569
  })
31025
31570
  );
31026
31571
  }
@@ -32408,97 +32953,6 @@ function detectFontFormat(data) {
32408
32953
  }
32409
32954
  return "truetype";
32410
32955
  }
32411
- var ATTR_PREFIX = "@_";
32412
- var TEXT_KEY = "#text";
32413
- function isXmlObject4(value) {
32414
- return typeof value === "object" && value !== null && !Array.isArray(value);
32415
- }
32416
- function coerceString(value) {
32417
- if (typeof value === "string") {
32418
- return value;
32419
- }
32420
- if (typeof value === "number" || typeof value === "boolean") {
32421
- return String(value);
32422
- }
32423
- return void 0;
32424
- }
32425
- function xmlChild(node, key) {
32426
- if (!isXmlObject4(node)) {
32427
- return void 0;
32428
- }
32429
- const value = node[key];
32430
- if (Array.isArray(value)) {
32431
- const first = value[0];
32432
- return isXmlObject4(first) ? first : void 0;
32433
- }
32434
- return isXmlObject4(value) ? value : void 0;
32435
- }
32436
- function xmlChildren(node, key) {
32437
- if (!isXmlObject4(node)) {
32438
- return [];
32439
- }
32440
- const value = node[key];
32441
- if (value === void 0 || value === null) {
32442
- return [];
32443
- }
32444
- if (Array.isArray(value)) {
32445
- return value.filter(isXmlObject4);
32446
- }
32447
- return isXmlObject4(value) ? [value] : [];
32448
- }
32449
- function xmlHasChild(node, key) {
32450
- return isXmlObject4(node) && Object.hasOwn(node, key);
32451
- }
32452
- function xmlAttr(node, name) {
32453
- if (!isXmlObject4(node)) {
32454
- return void 0;
32455
- }
32456
- return coerceString(node[ATTR_PREFIX + name]);
32457
- }
32458
- function xmlAttrNumber(node, name) {
32459
- const raw = xmlAttr(node, name);
32460
- if (raw === void 0) {
32461
- return void 0;
32462
- }
32463
- const parsed = Number(raw);
32464
- return Number.isFinite(parsed) ? parsed : void 0;
32465
- }
32466
- function xmlAttrBool(node, name) {
32467
- const raw = xmlAttr(node, name);
32468
- if (raw === void 0) {
32469
- return void 0;
32470
- }
32471
- const normalized = raw.trim().toLowerCase();
32472
- if (normalized === "1" || normalized === "true") {
32473
- return true;
32474
- }
32475
- if (normalized === "0" || normalized === "false") {
32476
- return false;
32477
- }
32478
- return void 0;
32479
- }
32480
- function xmlText(node) {
32481
- if (typeof node === "string") {
32482
- return node;
32483
- }
32484
- if (!isXmlObject4(node)) {
32485
- return void 0;
32486
- }
32487
- return coerceString(node[TEXT_KEY]);
32488
- }
32489
- function xmlPath(node, ...keys) {
32490
- let current = isXmlObject4(node) ? node : void 0;
32491
- for (const key of keys) {
32492
- if (!current) {
32493
- return void 0;
32494
- }
32495
- current = xmlChild(current, key);
32496
- }
32497
- return current;
32498
- }
32499
- function isXmlNode(value) {
32500
- return isXmlObject4(value);
32501
- }
32502
32956
  function findSectionList2(presentation, lookup) {
32503
32957
  const direct = lookup.getChildByLocalName(presentation, "sectionLst");
32504
32958
  if (direct) {
@@ -35775,6 +36229,7 @@ function getSvgStrokeDasharray(dashType, strokeWidth, customDashSegments) {
35775
36229
  }
35776
36230
  function createTemplateShapeRawXml(element) {
35777
36231
  const isText = element.type === "text";
36232
+ const isTextBox = element.locks?.txBox ?? isText;
35778
36233
  const name = isText ? "TextBox" : "Rectangle";
35779
36234
  const geometry = element.shapeType === "cylinder" ? "can" : element.shapeType || "rect";
35780
36235
  const adjustmentEntries = Object.entries(element.shapeAdjustments || {}).filter(
@@ -35793,7 +36248,7 @@ function createTemplateShapeRawXml(element) {
35793
36248
  "@_name": `${name} ${Math.floor(Math.random() * 100)}`
35794
36249
  },
35795
36250
  "p:cNvSpPr": {
35796
- "@_txBox": isText ? "1" : "0"
36251
+ "@_txBox": isTextBox ? "1" : "0"
35797
36252
  },
35798
36253
  "p:nvPr": {}
35799
36254
  },
@@ -36065,35 +36520,197 @@ async function fetchUrlToBytes(url, options = {}) {
36065
36520
  return null;
36066
36521
  }
36067
36522
  }
36523
+ function resolveChannelOrder(root) {
36524
+ const traceFormat = findFirstByLocalName(root, "traceFormat");
36525
+ if (!traceFormat) {
36526
+ return ["X", "Y"];
36527
+ }
36528
+ const channels = ensureArray5(nsGet(traceFormat, "channel"));
36529
+ const names = channels.map(
36530
+ (channel) => String(nsAttr(channel, "name") ?? "").trim().toUpperCase()
36531
+ ).filter((name) => name.length > 0);
36532
+ return names.length > 0 ? names : ["X", "Y"];
36533
+ }
36534
+ function decodeTracePoints(text2, channelOrder) {
36535
+ const points3 = [];
36536
+ const modes = channelOrder.map(() => "explicit");
36537
+ const lastValue = channelOrder.map(() => 0);
36538
+ const lastVelocity = channelOrder.map(() => 0);
36539
+ for (const rawPoint of text2.split(",")) {
36540
+ const tokens = rawPoint.trim().split(/\s+/u).filter((token2) => token2.length > 0);
36541
+ if (tokens.length === 0) {
36542
+ continue;
36543
+ }
36544
+ const decoded = [];
36545
+ for (let i = 0; i < tokens.length && i < channelOrder.length; i++) {
36546
+ const parsed = parseValueToken(tokens[i], modes[i]);
36547
+ if (parsed === void 0) {
36548
+ decoded.push(lastValue[i]);
36549
+ continue;
36550
+ }
36551
+ modes[i] = parsed.mode;
36552
+ const value = applyDiffMode(parsed, i, lastValue, lastVelocity);
36553
+ decoded.push(value);
36554
+ }
36555
+ if (decoded.length >= 2) {
36556
+ points3.push(decoded);
36557
+ }
36558
+ }
36559
+ return points3;
36560
+ }
36561
+ function parseValueToken(token2, currentMode) {
36562
+ let mode = currentMode;
36563
+ let body = token2;
36564
+ const prefix = token2[0];
36565
+ if (prefix === "!") {
36566
+ mode = "explicit";
36567
+ body = token2.slice(1);
36568
+ } else if (prefix === "'") {
36569
+ mode = "single";
36570
+ body = token2.slice(1);
36571
+ } else if (prefix === '"') {
36572
+ mode = "double";
36573
+ body = token2.slice(1);
36574
+ }
36575
+ if (body.length === 0) {
36576
+ return void 0;
36577
+ }
36578
+ const value = Number(body);
36579
+ return Number.isFinite(value) ? { value, mode } : void 0;
36580
+ }
36581
+ function applyDiffMode(parsed, index, lastValue, lastVelocity) {
36582
+ if (parsed.mode === "single") {
36583
+ lastVelocity[index] = parsed.value;
36584
+ lastValue[index] += parsed.value;
36585
+ } else if (parsed.mode === "double") {
36586
+ lastVelocity[index] += parsed.value;
36587
+ lastValue[index] += lastVelocity[index];
36588
+ } else {
36589
+ lastValue[index] = parsed.value;
36590
+ lastVelocity[index] = 0;
36591
+ }
36592
+ return lastValue[index];
36593
+ }
36594
+ function pointsToSvgPath(points3, channelOrder) {
36595
+ const xi = channelOrder.indexOf("X");
36596
+ const yi = channelOrder.indexOf("Y");
36597
+ const xIndex = xi >= 0 ? xi : 0;
36598
+ const yIndex = yi >= 0 ? yi : 1;
36599
+ const segments = [];
36600
+ for (const point of points3) {
36601
+ const x = point[xIndex];
36602
+ const y = point[yIndex];
36603
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
36604
+ continue;
36605
+ }
36606
+ segments.push(`${segments.length === 0 ? "M" : "L"} ${x} ${y}`);
36607
+ }
36608
+ return segments.join(" ");
36609
+ }
36610
+ function pointsToPressures(points3, channelOrder) {
36611
+ const fIndex = channelOrder.indexOf("F");
36612
+ if (fIndex < 0) {
36613
+ return [];
36614
+ }
36615
+ const pressures = [];
36616
+ for (const point of points3) {
36617
+ const raw = point[fIndex];
36618
+ if (Number.isFinite(raw)) {
36619
+ const normalised = raw > 1 ? raw / 32767 : raw;
36620
+ pressures.push(Math.max(0, Math.min(1, normalised)));
36621
+ }
36622
+ }
36623
+ return pressures;
36624
+ }
36625
+ function nsGet(obj, localName22) {
36626
+ if (localName22 in obj) {
36627
+ return obj[localName22];
36628
+ }
36629
+ for (const key of Object.keys(obj)) {
36630
+ if (localNameOf(key) === localName22 && !key.startsWith("@_")) {
36631
+ return obj[key];
36632
+ }
36633
+ }
36634
+ return void 0;
36635
+ }
36636
+ function nsAttr(obj, localName22) {
36637
+ const direct = obj[`@_${localName22}`];
36638
+ if (direct !== void 0) {
36639
+ return direct;
36640
+ }
36641
+ for (const key of Object.keys(obj)) {
36642
+ if (key.startsWith("@_") && localNameOf(key.slice(2)) === localName22) {
36643
+ return obj[key];
36644
+ }
36645
+ }
36646
+ return void 0;
36647
+ }
36648
+ function localNameOf(key) {
36649
+ const colon = key.indexOf(":");
36650
+ return colon >= 0 ? key.slice(colon + 1) : key;
36651
+ }
36652
+ function findFirstByLocalName(node, localName22) {
36653
+ const direct = nsGet(node, localName22);
36654
+ if (direct && typeof direct === "object") {
36655
+ return Array.isArray(direct) ? direct[0] : direct;
36656
+ }
36657
+ for (const key of Object.keys(node)) {
36658
+ if (key.startsWith("@_") || key === "#text") {
36659
+ continue;
36660
+ }
36661
+ for (const child20 of ensureArray5(node[key])) {
36662
+ if (typeof child20 !== "object") {
36663
+ continue;
36664
+ }
36665
+ const found = findFirstByLocalName(child20, localName22);
36666
+ if (found) {
36667
+ return found;
36668
+ }
36669
+ }
36670
+ }
36671
+ return void 0;
36672
+ }
36673
+ function ensureArray5(value) {
36674
+ if (value === void 0 || value === null) {
36675
+ return [];
36676
+ }
36677
+ return Array.isArray(value) ? value : [value];
36678
+ }
36068
36679
  var INKML_NAMESPACE = "http://www.w3.org/2003/InkML";
36069
36680
  var METADATA_NAMESPACE = "https://pptx-viewer.dev/inkml/metadata";
36070
36681
  function parseInkMlContent(data) {
36071
- const root = data["ink:ink"] ?? data["ink"];
36682
+ const root = nsGet(data, "ink") ?? data["ink"];
36072
36683
  if (!root) {
36073
36684
  return { strokes: [], rawXml: data };
36074
36685
  }
36075
36686
  const brushes = /* @__PURE__ */ new Map();
36076
- for (const brush of ensureArray5(root["ink:brush"] ?? root["brush"])) {
36077
- const properties = ensureArray5(brush["ink:brushProperty"] ?? brush["brushProperty"]);
36687
+ for (const brush of ensureArray5(nsGet(root, "brush"))) {
36688
+ const properties = ensureArray5(nsGet(brush, "brushProperty"));
36078
36689
  const valueByName = new Map(
36079
- properties.map((property) => [String(property["@_name"] ?? ""), property["@_value"]])
36690
+ properties.map((property) => [
36691
+ String(nsAttr(property, "name") ?? ""),
36692
+ nsAttr(property, "value")
36693
+ ])
36080
36694
  );
36081
- brushes.set(String(brush["@_id"] ?? ""), {
36695
+ brushes.set(String(nsAttr(brush, "id") ?? ""), {
36082
36696
  color: String(valueByName.get("color") ?? "#000000"),
36083
36697
  width: finiteNumber(valueByName.get("width"), 1),
36084
36698
  opacity: finiteNumber(valueByName.get("opacity"), 1)
36085
36699
  });
36086
36700
  }
36701
+ const channelOrder = resolveChannelOrder(root);
36087
36702
  const strokes = [];
36088
- for (const trace of ensureArray5(root["ink:trace"] ?? root["trace"])) {
36703
+ for (const trace of ensureArray5(nsGet(root, "trace"))) {
36089
36704
  const text2 = typeof trace === "string" ? trace : String(trace["#text"] ?? "").trim();
36090
- const path = typeof trace === "string" ? text2 : String(trace["@_pva:path"] ?? "").trim() || text2;
36705
+ const authored = typeof trace === "string" ? "" : String(nsAttr(trace, "path") ?? "").trim();
36706
+ const points3 = authored ? [] : decodeTracePoints(text2, channelOrder);
36707
+ const path = authored || pointsToSvgPath(points3, channelOrder);
36091
36708
  if (!path) {
36092
36709
  continue;
36093
36710
  }
36094
- const brushRef = typeof trace === "string" ? "" : String(trace["@_brushRef"] ?? "").replace("#", "");
36711
+ const brushRef = typeof trace === "string" ? "" : String(nsAttr(trace, "brushRef") ?? "").replace("#", "");
36095
36712
  const brush = brushes.get(brushRef) ?? { color: "#000000", width: 1, opacity: 1 };
36096
- const pressures = tracePressures(text2);
36713
+ const pressures = authored ? tracePressures(text2) : pointsToPressures(points3, channelOrder);
36097
36714
  strokes.push({ ...brush, path, ...pressures.length > 0 ? { pressures } : {} });
36098
36715
  }
36099
36716
  return { strokes, rawXml: data };
@@ -36152,12 +36769,6 @@ function finiteNumber(value, fallback) {
36152
36769
  const parsed = Number(value);
36153
36770
  return Number.isFinite(parsed) ? parsed : fallback;
36154
36771
  }
36155
- function ensureArray5(value) {
36156
- if (value === void 0 || value === null) {
36157
- return [];
36158
- }
36159
- return Array.isArray(value) ? value : [value];
36160
- }
36161
36772
  var DEFAULT_ACCENT_COLORS = [
36162
36773
  "#4472C4",
36163
36774
  "#ED7D31",
@@ -38789,6 +39400,120 @@ function applyNodeStylesToElements(elements2, nodes) {
38789
39400
  };
38790
39401
  });
38791
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
+ }
38792
39517
  function quickStyleStrokeScale(quickStyle) {
38793
39518
  if (!quickStyle?.effectIntensity) {
38794
39519
  return 1;
@@ -38893,15 +39618,27 @@ function decomposeSmartArt(smartArtData, containerBounds, themeColorMap, layoutD
38893
39618
  smartArtData.colorTransform?.fillColors
38894
39619
  );
38895
39620
  const layoutType = resolveEffectiveLayoutType(smartArtData);
39621
+ const layoutVars = smartArtData.presLayoutVars ?? parseSmartArtPresLayoutVars(smartArtData.layoutDefinition?.rawXml);
39622
+ const orderedNodes = layoutVars?.direction === "rev" ? [...nodes].reverse() : nodes;
38896
39623
  const namedLayout = smartArtData.layout;
38897
39624
  if (namedLayout) {
38898
- const namedResult = dispatchNamedLayout(namedLayout, nodes, containerBounds, effectiveThemeMap);
39625
+ const namedResult = dispatchNamedLayout(
39626
+ namedLayout,
39627
+ orderedNodes,
39628
+ containerBounds,
39629
+ effectiveThemeMap
39630
+ );
38899
39631
  if (namedResult) {
38900
- return applyNodeStylesToElements(namedResult, nodes);
39632
+ return applyNodeStylesToElements(namedResult, orderedNodes);
38901
39633
  }
38902
39634
  }
38903
- const algorithmic = dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap);
38904
- 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;
38905
39642
  }
38906
39643
  function dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap) {
38907
39644
  switch (layoutType) {
@@ -48559,6 +49296,126 @@ function applySmartArtConnectionAttributes(xml, connection, fallbackModelId) {
48559
49296
  applyNullableAttribute(xml, "@_sibTransId", connection.siblingTransitionId);
48560
49297
  applyNullableAttribute(xml, "@_presId", connection.presentationId);
48561
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
+ }
48562
49419
  var MODERN_COMMENT_NAMESPACE = "http://schemas.microsoft.com/office/powerpoint/2018/8/main";
48563
49420
  var MODERN_COMMENT_RELATIONSHIP = "http://schemas.microsoft.com/office/2018/10/relationships/comments";
48564
49421
  var MODERN_AUTHOR_RELATIONSHIP = "http://schemas.microsoft.com/office/2018/10/relationships/authors";
@@ -50825,6 +51682,26 @@ function buildGeneratedChartAxis(axId, crossId, pos2, formatting) {
50825
51682
  }
50826
51683
  return axis;
50827
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
+ }
50828
51705
  var NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
50829
51706
  var NS_A2 = "http://schemas.openxmlformats.org/drawingml/2006/main";
50830
51707
  var NS_R2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
@@ -50854,29 +51731,6 @@ function strLit(values) {
50854
51731
  }
50855
51732
  };
50856
51733
  }
50857
- function resolveType(type) {
50858
- switch (type) {
50859
- case "pie":
50860
- case "pie3D":
50861
- return { tag: "c:pieChart", family: "pie" };
50862
- case "doughnut":
50863
- return { tag: "c:doughnutChart", family: "doughnut" };
50864
- case "scatter":
50865
- return { tag: "c:scatterChart", family: "scatter" };
50866
- case "bubble":
50867
- return { tag: "c:bubbleChart", family: "bubble" };
50868
- case "line":
50869
- case "line3D":
50870
- return { tag: "c:lineChart", family: "line" };
50871
- case "area":
50872
- case "area3D":
50873
- return { tag: "c:areaChart", family: "area" };
50874
- case "radar":
50875
- return { tag: "c:radarChart", family: "radar" };
50876
- default:
50877
- return { tag: "c:barChart", family: "bar" };
50878
- }
50879
- }
50880
51734
  function fillSpPr(color2, asLine) {
50881
51735
  const h = hex6(color2);
50882
51736
  if (!h) {
@@ -50944,7 +51798,11 @@ function buildChartTypeContainer(chartData, family) {
50944
51798
  } else if (family === "scatter") {
50945
51799
  container["c:scatterStyle"] = { "@_val": "lineMarker" };
50946
51800
  container["c:varyColors"] = { "@_val": "0" };
50947
- } 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 {
50948
51806
  container["c:varyColors"] = { "@_val": family === "bubble" ? "0" : "1" };
50949
51807
  }
50950
51808
  container["c:ser"] = chartData.series.map(
@@ -50956,12 +51814,13 @@ function buildChartTypeContainer(chartData, family) {
50956
51814
  if (family === "line" && chartData.upDownBars !== void 0) {
50957
51815
  applyChartUpDownBars(container, chartData.upDownBars, (key) => key.replace(/^.*:/u, ""));
50958
51816
  }
50959
- if (family === "bar") {
51817
+ if (family === "bar" || family === "ofPie") {
50960
51818
  container["c:gapWidth"] = { "@_val": "150" };
50961
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
50962
- } else if (family === "line" || family === "area" || family === "radar") {
50963
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
50964
- } 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") {
50965
51824
  container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
50966
51825
  } else if (family === "doughnut") {
50967
51826
  container["c:holeSize"] = { "@_val": "50" };
@@ -50974,7 +51833,8 @@ function buildPlotArea(chartData, tag, family) {
50974
51833
  if (chartData.style) {
50975
51834
  applyChartDataLabelsToXml(plotArea, chartData.style, (key) => key.replace(/^.*:/u, ""));
50976
51835
  }
50977
- 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)) {
50978
51838
  plotArea["c:valAx"] = [
50979
51839
  buildGeneratedChartAxis(
50980
51840
  CAT_AX_ID,
@@ -50989,7 +51849,7 @@ function buildPlotArea(chartData, tag, family) {
50989
51849
  axisFormatting(chartData, "valAx", VAL_AX_ID, 1)
50990
51850
  )
50991
51851
  ];
50992
- } else if (family !== "pie" && family !== "doughnut") {
51852
+ } else if (hasAxes) {
50993
51853
  const dateAxis = chartData.dateCategories ? axisFormatting(chartData, "dateAx", CAT_AX_ID) : void 0;
50994
51854
  plotArea[dateAxis ? "c:dateAx" : "c:catAx"] = buildGeneratedChartAxis(
50995
51855
  CAT_AX_ID,
@@ -51008,7 +51868,7 @@ function buildPlotArea(chartData, tag, family) {
51008
51868
  return plotArea;
51009
51869
  }
51010
51870
  function buildChartSpaceXml(chartData) {
51011
- const { tag, family } = resolveType(chartData.chartType);
51871
+ const { tag, family } = resolveChartContainerType(chartData.chartType);
51012
51872
  const chart = {};
51013
51873
  if (chartData.title) {
51014
51874
  chart["c:title"] = {
@@ -52914,6 +53774,7 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
52914
53774
  let playbackSpeed;
52915
53775
  let trimStartMs;
52916
53776
  let trimEndMs;
53777
+ let embedRId;
52917
53778
  const bookmarks = [];
52918
53779
  const extLst = mediaNode["p:extLst"] ?? cMediaNode["p:extLst"];
52919
53780
  if (extLst) {
@@ -52921,6 +53782,13 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
52921
53782
  for (const ext of exts) {
52922
53783
  const p14Media = ext["p14:media"];
52923
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
+ }
52924
53792
  const p14Trim = p14Media["p14:trim"];
52925
53793
  if (p14Trim) {
52926
53794
  const st = p14Trim["@_st"];
@@ -52990,7 +53858,8 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
52990
53858
  fadeInDuration,
52991
53859
  fadeOutDuration,
52992
53860
  playbackSpeed,
52993
- bookmarks
53861
+ bookmarks,
53862
+ embedRId
52994
53863
  };
52995
53864
  }
52996
53865
  var PptxHandlerRuntime = class {
@@ -53218,6 +54087,12 @@ var PptxHandlerRuntime = class {
53218
54087
  loadedEmbeddedFonts = [];
53219
54088
  /** Typed source metadata for lossless embedded-font list round trips. */
53220
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;
53221
54096
  /** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
53222
54097
  commentAuthorMap = /* @__PURE__ */ new Map();
53223
54098
  /** Full comment author details keyed by author ID, preserving initials/lastIdx/clrIdx for round-trip. */
@@ -53356,18 +54231,261 @@ var PptxHandlerRuntime = class {
53356
54231
  }
53357
54232
  }
53358
54233
  };
54234
+ var EMU_PER_PIXEL = 9525;
54235
+ var BORDER_SIDES = [
54236
+ "left",
54237
+ "right",
54238
+ "top",
54239
+ "bottom",
54240
+ "insideH",
54241
+ "insideV",
54242
+ "tl2br",
54243
+ "bl2tr"
54244
+ ];
54245
+ function parseSolidFillStyle(solidFill2) {
54246
+ if (!solidFill2) {
54247
+ return void 0;
54248
+ }
54249
+ const schemeClr = solidFill2["a:schemeClr"];
54250
+ if (!schemeClr) {
54251
+ return void 0;
54252
+ }
54253
+ const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
54254
+ if (!schemeColor) {
54255
+ return void 0;
54256
+ }
54257
+ const tintRaw = schemeClr["a:tint"];
54258
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
54259
+ const shadeRaw = schemeClr["a:shade"];
54260
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
54261
+ return { schemeColor, tint, shade };
54262
+ }
54263
+ function parseBorderSide(side) {
54264
+ if (!side) {
54265
+ return void 0;
54266
+ }
54267
+ const ln = side["a:ln"];
54268
+ if (!ln) {
54269
+ return void 0;
54270
+ }
54271
+ const border = {};
54272
+ let has = false;
54273
+ if (ln["a:noFill"] !== void 0) {
54274
+ border.noFill = true;
54275
+ has = true;
54276
+ }
54277
+ const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
54278
+ if (widthEmu > 0) {
54279
+ border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL));
54280
+ has = true;
54281
+ }
54282
+ const prstDash = ln["a:prstDash"];
54283
+ const dashVal = prstDash ? String(prstDash["@_val"] || "").trim() : "";
54284
+ if (dashVal) {
54285
+ border.dash = dashVal;
54286
+ has = true;
54287
+ }
54288
+ const solidFill2 = ln["a:solidFill"];
54289
+ const fill = parseSolidFillStyle(solidFill2);
54290
+ if (fill) {
54291
+ border.fill = fill;
54292
+ has = true;
54293
+ } else {
54294
+ const srgb = solidFill2?.["a:srgbClr"];
54295
+ const hex10 = srgb ? String(srgb["@_val"] || "").trim() : "";
54296
+ if (hex10) {
54297
+ border.color = hex10.startsWith("#") ? hex10 : `#${hex10}`;
54298
+ has = true;
54299
+ }
54300
+ }
54301
+ return has ? border : void 0;
54302
+ }
54303
+ function parseTableStyleBorders(tcStyle) {
54304
+ const tcBdr = tcStyle?.["a:tcBdr"];
54305
+ if (!tcBdr) {
54306
+ return void 0;
54307
+ }
54308
+ const result = {};
54309
+ let has = false;
54310
+ for (const name of BORDER_SIDES) {
54311
+ const border = parseBorderSide(tcBdr[`a:${name}`]);
54312
+ if (border) {
54313
+ result[name] = border;
54314
+ has = true;
54315
+ }
54316
+ }
54317
+ return has ? result : void 0;
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
+ }
53359
54484
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53360
54485
  /**
53361
- * Export slides to a raster/vector format.
53362
- *
53363
- * This is a stub that signals export intent. Actual rendering requires a
53364
- * platform-specific canvas or PDF library (e.g. Puppeteer, node-canvas,
53365
- * pdfkit). Host applications should override or extend this method with
53366
- * their own rendering pipeline.
53367
- *
53368
- * @param _slides The slides to export.
53369
- * @param _options Export options (format, DPI, slide indices, etc.).
53370
- * @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.
53371
54489
  */
53372
54490
  async exportSlides(slides, options) {
53373
54491
  this.compatibilityService.reportWarning({
@@ -53432,77 +54550,26 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53432
54550
  }
53433
54551
  /**
53434
54552
  * Extract fill information from a table style section element
53435
- * (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).
53436
54555
  */
53437
54556
  extractTableStyleSectionFill(section) {
53438
- if (!section) {
53439
- return void 0;
53440
- }
53441
- const tcStyle = section["a:tcStyle"];
53442
- if (!tcStyle) {
53443
- return void 0;
53444
- }
53445
- const fill = tcStyle["a:fill"];
53446
- if (!fill) {
53447
- return void 0;
53448
- }
53449
- const solidFill2 = fill["a:solidFill"];
53450
- if (!solidFill2) {
53451
- return void 0;
53452
- }
53453
- const schemeClr = solidFill2["a:schemeClr"];
53454
- if (!schemeClr) {
53455
- return void 0;
53456
- }
53457
- const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
53458
- if (!schemeColor) {
53459
- return void 0;
53460
- }
53461
- const tintRaw = schemeClr["a:tint"];
53462
- const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
53463
- const shadeRaw = schemeClr["a:shade"];
53464
- const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
53465
- return { schemeColor, tint, shade };
54557
+ return parseTableStyleSectionFill(section);
54558
+ }
54559
+ /**
54560
+ * Extract border styling from a table style section's
54561
+ * `a:tcStyle/a:tcBdr` (per-side line width, dash, and colour).
54562
+ */
54563
+ extractTableStyleSectionBorders(section) {
54564
+ return parseTableStyleBorders(section?.["a:tcStyle"]);
53466
54565
  }
53467
54566
  /**
53468
- * 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).
53469
54570
  */
53470
54571
  extractTableStyleSectionText(section) {
53471
- if (!section) {
53472
- return void 0;
53473
- }
53474
- const tcTxStyle = section["a:tcTxStyle"];
53475
- if (!tcTxStyle) {
53476
- return void 0;
53477
- }
53478
- const result = {};
53479
- let hasProps = false;
53480
- if (tcTxStyle["@_b"] === "on") {
53481
- result.bold = true;
53482
- hasProps = true;
53483
- }
53484
- if (tcTxStyle["@_i"] === "on") {
53485
- result.italic = true;
53486
- hasProps = true;
53487
- }
53488
- const fontClr = tcTxStyle["a:fontRef"];
53489
- const schemeClr = fontClr?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
53490
- if (schemeClr) {
53491
- const val = String(schemeClr["@_val"] || "").trim();
53492
- if (val) {
53493
- result.fontSchemeColor = val;
53494
- hasProps = true;
53495
- const tintNode = schemeClr["a:tint"];
53496
- if (tintNode) {
53497
- result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
53498
- }
53499
- const shadeNode = schemeClr["a:shade"];
53500
- if (shadeNode) {
53501
- result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
53502
- }
53503
- }
53504
- }
53505
- return hasProps ? result : void 0;
54572
+ return parseTableStyleSectionText(section);
53506
54573
  }
53507
54574
  ensureArray(val) {
53508
54575
  if (!val) {
@@ -53609,6 +54676,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53609
54676
  textProps[`${name}Text`] = text2;
53610
54677
  }
53611
54678
  }
54679
+ const borderProps = {};
54680
+ for (const name of sectionNames) {
54681
+ const borders = this.extractTableStyleSectionBorders(
54682
+ style[`a:${name}`]
54683
+ );
54684
+ if (borders) {
54685
+ borderProps[`${name}Borders`] = borders;
54686
+ }
54687
+ }
53612
54688
  const entry = {
53613
54689
  styleId,
53614
54690
  styleName,
@@ -53627,7 +54703,8 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
53627
54703
  ...swCellFill ? { swCellFill } : {},
53628
54704
  ...neCellFill ? { neCellFill } : {},
53629
54705
  ...nwCellFill ? { nwCellFill } : {},
53630
- ...textProps
54706
+ ...textProps,
54707
+ ...borderProps
53631
54708
  };
53632
54709
  map[styleId] = entry;
53633
54710
  }
@@ -54164,6 +55241,7 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
54164
55241
  );
54165
55242
  const trimStartMs = timing.trimStartMs ?? extData.trimStartMs;
54166
55243
  const trimEndMs = timing.trimEndMs ?? extData.trimEndMs;
55244
+ const mediaEmbedPath = extData.embedRId ? this.resolveRelationshipTarget(slidePath, extData.embedRId) : void 0;
54167
55245
  result.set(shapeId, {
54168
55246
  trimStartMs: trimStartMs !== void 0 && !isNaN(trimStartMs) ? trimStartMs : void 0,
54169
55247
  trimEndMs: trimEndMs !== void 0 && !isNaN(trimEndMs) ? trimEndMs : void 0,
@@ -54177,7 +55255,8 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
54177
55255
  playAcrossSlides: timing.playAcrossSlides || void 0,
54178
55256
  hideWhenNotPlaying: hideWhenNotPlaying || void 0,
54179
55257
  bookmarks: extData.bookmarks.length > 0 ? extData.bookmarks : void 0,
54180
- playbackSpeed: extData.playbackSpeed
55258
+ playbackSpeed: extData.playbackSpeed,
55259
+ mediaEmbedPath
54181
55260
  });
54182
55261
  }
54183
55262
  }
@@ -54351,6 +55430,10 @@ var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
54351
55430
  if (!timing) {
54352
55431
  continue;
54353
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
+ }
54354
55437
  if (timing.trimStartMs !== void 0) {
54355
55438
  el.trimStartMs = timing.trimStartMs;
54356
55439
  }
@@ -55349,7 +56432,7 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
55349
56432
  }
55350
56433
  }
55351
56434
  async reconcilePresentationSlidesForSave(params) {
55352
- await this.presentationSlidesReconciler.reconcile({
56435
+ return await this.presentationSlidesReconciler.reconcile({
55353
56436
  ...params,
55354
56437
  zip: this.zip,
55355
56438
  parser: this.parser,
@@ -55420,6 +56503,15 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
55420
56503
  if (align === "justify") {
55421
56504
  return "just";
55422
56505
  }
56506
+ if (align === "justLow") {
56507
+ return "justLow";
56508
+ }
56509
+ if (align === "dist") {
56510
+ return "dist";
56511
+ }
56512
+ if (align === "thaiDist") {
56513
+ return "thaiDist";
56514
+ }
55423
56515
  return void 0;
55424
56516
  }
55425
56517
  pixelsToPoints(px2) {
@@ -55629,6 +56721,31 @@ function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
55629
56721
  }
55630
56722
  return fontNode;
55631
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
+ }
55632
56749
  var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime11 {
55633
56750
  createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
55634
56751
  const runProps = {
@@ -55649,6 +56766,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
55649
56766
  }
55650
56767
  if (style.underline) {
55651
56768
  runProps["@_u"] = style.underlineStyle || "sng";
56769
+ } else if (style.underlineExplicitNone) {
56770
+ runProps["@_u"] = "none";
55652
56771
  }
55653
56772
  if (style.strikethrough !== void 0) {
55654
56773
  runProps["@_strike"] = style.strikethrough ? style.strikeType || "sngStrike" : "noStrike";
@@ -55664,6 +56783,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
55664
56783
  }
55665
56784
  if (style.textCaps && style.textCaps !== "none") {
55666
56785
  runProps["@_cap"] = style.textCaps;
56786
+ } else if (style.textCapsExplicitNone) {
56787
+ runProps["@_cap"] = "none";
55667
56788
  }
55668
56789
  if (style.kumimoji !== void 0) {
55669
56790
  runProps["@_kumimoji"] = style.kumimoji ? "1" : "0";
@@ -55772,13 +56893,21 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
55772
56893
  runProps["a:effectDag"] = style.textEffectDagXml;
55773
56894
  }
55774
56895
  if (style.highlightColor) {
55775
- runProps["a:highlight"] = {
55776
- "a:srgbClr": {
55777
- "@_val": style.highlightColor.replace("#", "")
55778
- }
55779
- };
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
+ );
55780
56902
  }
55781
- if (style.underline && style.underlineColor) {
56903
+ if (style.underlineLineFollowsText) {
56904
+ runProps["a:uLnTx"] = {};
56905
+ } else if (style.underlineLine) {
56906
+ runProps["a:uLn"] = buildUnderlineLineXml(style.underlineLine);
56907
+ }
56908
+ if (style.underlineFillFollowsText) {
56909
+ runProps["a:uFillTx"] = {};
56910
+ } else if (style.underline && style.underlineColor) {
55782
56911
  runProps["a:uFill"] = {
55783
56912
  "a:solidFill": {
55784
56913
  "a:srgbClr": {
@@ -55787,21 +56916,28 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
55787
56916
  }
55788
56917
  };
55789
56918
  }
55790
- if (style.fontFamily) {
56919
+ const latinFace = style.latinFontThemeToken ?? style.fontFamily;
56920
+ if (latinFace) {
55791
56921
  runProps["a:latin"] = applyFontMetadata(
55792
- { "@_typeface": style.fontFamily },
56922
+ { "@_typeface": latinFace },
55793
56923
  style.latinFontPanose,
55794
56924
  style.latinFontPitchFamily,
55795
56925
  style.latinFontCharset
55796
56926
  );
56927
+ }
56928
+ const eastAsiaFace = style.eastAsiaFontThemeToken ?? style.eastAsiaFont;
56929
+ if (eastAsiaFace) {
55797
56930
  runProps["a:ea"] = applyFontMetadata(
55798
- { "@_typeface": style.eastAsiaFont || style.fontFamily },
56931
+ { "@_typeface": eastAsiaFace },
55799
56932
  style.eastAsiaFontPanose,
55800
56933
  style.eastAsiaFontPitchFamily,
55801
56934
  style.eastAsiaFontCharset
55802
56935
  );
56936
+ }
56937
+ const complexScriptFace = style.complexScriptFontThemeToken ?? style.complexScriptFont;
56938
+ if (complexScriptFace) {
55803
56939
  runProps["a:cs"] = applyFontMetadata(
55804
- { "@_typeface": style.complexScriptFont || style.fontFamily },
56940
+ { "@_typeface": complexScriptFace },
55805
56941
  style.complexScriptFontPanose,
55806
56942
  style.complexScriptFontPitchFamily,
55807
56943
  style.complexScriptFontCharset
@@ -55851,12 +56987,17 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
55851
56987
  if (mouseOverTarget.length > 0) {
55852
56988
  const mouseOverRelId = resolveHyperlinkRelationshipId(mouseOverTarget);
55853
56989
  if (mouseOverRelId) {
55854
- runProps["a:hlinkMouseOver"] = {
55855
- "@_r:id": mouseOverRelId
55856
- };
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;
55857
56995
  }
55858
56996
  }
55859
56997
  }
56998
+ if (style.runPropertiesExtLstXml && typeof style.runPropertiesExtLstXml === "object") {
56999
+ runProps["a:extLst"] = style.runPropertiesExtLstXml;
57000
+ }
55860
57001
  return runProps;
55861
57002
  }
55862
57003
  applyHyperlinkExtraAttrs(hlinkNode, style) {
@@ -55875,20 +57016,24 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime2 extends PptxHandlerRuntime
55875
57016
  if (style.hyperlinkEndSound !== void 0) {
55876
57017
  hlinkNode["@_endSnd"] = style.hyperlinkEndSound ? "1" : "0";
55877
57018
  }
57019
+ if (style.hyperlinkSoundXml && typeof style.hyperlinkSoundXml === "object") {
57020
+ hlinkNode["a:snd"] = style.hyperlinkSoundXml;
57021
+ }
55878
57022
  }
55879
57023
  };
55880
57024
  var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
55881
57025
  createParagraphsFromTextContent(text2, textStyle, textSegments, resolveHyperlinkRelationshipId) {
55882
- const paragraphAlign = this.textAlignToDrawingValue(textStyle?.align);
55883
- const spacing = {
55884
- spacingBefore: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingBefore),
55885
- spacingAfter: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingAfter),
55886
- lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
55887
- lineSpacingExactPt: textStyle?.lineSpacingExactPt
55888
- };
55889
- 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
+ };
55890
57035
  const paragraphProps = buildParagraphPropertiesXml(
55891
- textStyle,
57036
+ effectiveStyle,
55892
57037
  paragraphAlign,
55893
57038
  bulletInfo,
55894
57039
  spacing,
@@ -55900,12 +57045,22 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
55900
57045
  "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
55901
57046
  "a:t": runText
55902
57047
  });
55903
- const createFieldRun = (runText, style, fieldType, fieldGuid) => ({
55904
- "@_type": fieldType,
55905
- ...fieldGuid ? { "@_id": fieldGuid } : {},
55906
- "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
55907
- "a:t": runText
55908
- });
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
+ };
55909
57064
  const createRubyRun = (segment, style) => {
55910
57065
  const rubyPr = {};
55911
57066
  if (segment.rubyAlignment) {
@@ -55944,17 +57099,27 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
55944
57099
  let currentBulletInfo;
55945
57100
  let currentLevel;
55946
57101
  let currentEndParaRunProperties;
57102
+ let currentParagraphProperties;
57103
+ let capturedParagraphMeta = false;
55947
57104
  const pushParagraph = () => {
55948
57105
  if (currentRuns.length === 0) {
55949
57106
  currentRuns.push(createRun("", textStyle));
55950
57107
  }
55951
57108
  paragraphs.push(
55952
- createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
57109
+ createParagraph(
57110
+ currentRuns,
57111
+ currentBulletInfo,
57112
+ currentLevel,
57113
+ currentEndParaRunProperties,
57114
+ currentParagraphProperties
57115
+ )
55953
57116
  );
55954
57117
  currentRuns = [];
55955
57118
  currentBulletInfo = void 0;
55956
57119
  currentLevel = void 0;
55957
57120
  currentEndParaRunProperties = void 0;
57121
+ currentParagraphProperties = void 0;
57122
+ capturedParagraphMeta = false;
55958
57123
  };
55959
57124
  if (textSegments && textSegments.length > 0) {
55960
57125
  const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
@@ -55964,7 +57129,7 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
55964
57129
  ...segment.style,
55965
57130
  ...uniformSegmentOverrides
55966
57131
  };
55967
- if (currentRuns.length === 0) {
57132
+ if (!capturedParagraphMeta) {
55968
57133
  if (segment.bulletInfo) {
55969
57134
  currentBulletInfo = segment.bulletInfo;
55970
57135
  }
@@ -55974,6 +57139,10 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
55974
57139
  if (segment.endParaRunProperties) {
55975
57140
  currentEndParaRunProperties = segment.endParaRunProperties;
55976
57141
  }
57142
+ if (segment.paragraphProperties) {
57143
+ currentParagraphProperties = segment.paragraphProperties;
57144
+ }
57145
+ capturedParagraphMeta = true;
55977
57146
  }
55978
57147
  if (segment.isLineBreak) {
55979
57148
  const brNode = {};
@@ -56008,7 +57177,9 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
56008
57177
  linePart,
56009
57178
  segmentStyle,
56010
57179
  segment.fieldType,
56011
- segment.fieldGuid
57180
+ segment.fieldGuid,
57181
+ segment.fieldGuidAttr,
57182
+ segment.fieldParagraphPropertiesXml
56012
57183
  );
56013
57184
  fieldRun.__isField = true;
56014
57185
  currentRuns.push(fieldRun);
@@ -56464,6 +57635,16 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime3 extends PptxHandlerRuntime
56464
57635
  const chOffY = 0;
56465
57636
  const chExtCx = extCx;
56466
57637
  const chExtCy = extCy;
57638
+ const xfrmAttrs = {};
57639
+ if (typeof group.rotation === "number" && group.rotation !== 0) {
57640
+ xfrmAttrs["@_rot"] = String(Math.round(group.rotation * 6e4));
57641
+ }
57642
+ if (group.flipHorizontal) {
57643
+ xfrmAttrs["@_flipH"] = "1";
57644
+ }
57645
+ if (group.flipVertical) {
57646
+ xfrmAttrs["@_flipV"] = "1";
57647
+ }
56467
57648
  const grpXml = {
56468
57649
  "p:nvGrpSpPr": {
56469
57650
  "p:cNvPr": { "@_id": "0", "@_name": group.id },
@@ -56472,6 +57653,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime3 extends PptxHandlerRuntime
56472
57653
  },
56473
57654
  "p:grpSpPr": {
56474
57655
  "a:xfrm": {
57656
+ ...xfrmAttrs,
56475
57657
  "a:off": {
56476
57658
  "@_x": String(offX),
56477
57659
  "@_y": String(offY)
@@ -56754,7 +57936,95 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
56754
57936
  );
56755
57937
  }
56756
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
+ }
56757
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
+ }
56758
58028
  textStylesEqual(left, right) {
56759
58029
  const keys = [
56760
58030
  "fontFamily",
@@ -56913,6 +58183,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
56913
58183
  const esVal = String(endSnd).trim().toLowerCase();
56914
58184
  style.hyperlinkEndSound = esVal === "1" || esVal === "true";
56915
58185
  }
58186
+ const clickSnd = hyperlinkNode["a:snd"];
58187
+ if (clickSnd && typeof clickSnd === "object") {
58188
+ style.hyperlinkSoundXml = clickSnd;
58189
+ }
56916
58190
  }
56917
58191
  const actionStr = String(hyperlinkNode?.["@_action"] || "").trim();
56918
58192
  if (actionStr) {
@@ -56942,6 +58216,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
56942
58216
  } else {
56943
58217
  style.hyperlinkMouseOver = mouseOverRelId;
56944
58218
  }
58219
+ const mouseOverSnd = hlinkMouseOver["a:snd"];
58220
+ if (mouseOverSnd && typeof mouseOverSnd === "object") {
58221
+ style.hyperlinkMouseOverSoundXml = mouseOverSnd;
58222
+ }
56945
58223
  }
56946
58224
  }
56947
58225
  }
@@ -57166,6 +58444,8 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57166
58444
  if (rawU.length > 0 && rawU !== "none") {
57167
58445
  style.underlineStyle = rawU;
57168
58446
  }
58447
+ } else if (underlineToken === "none") {
58448
+ style.underlineExplicitNone = true;
57169
58449
  }
57170
58450
  }
57171
58451
  const uFill = runProperties2["a:uFill"];
@@ -57177,6 +58457,46 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57177
58457
  style.underlineColor = underlineColor;
57178
58458
  }
57179
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
+ }
57180
58500
  if (runProperties2["@_strike"] !== void 0) {
57181
58501
  const strikeToken = String(runProperties2["@_strike"] || "").trim().toLowerCase();
57182
58502
  style.strikethrough = strikeToken.length > 0 && strikeToken !== "nostrike" && strikeToken !== "none" && strikeToken !== "0" && strikeToken !== "false";
@@ -57220,10 +58540,15 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57220
58540
  }
57221
58541
  }
57222
58542
  if (runProperties2["a:highlight"]) {
57223
- const highlightHex = this.parseColor(xmlChild(runProperties2, "a:highlight"));
58543
+ const highlightNode = xmlChild(runProperties2, "a:highlight");
58544
+ const highlightHex = this.parseColor(highlightNode);
57224
58545
  if (highlightHex) {
57225
58546
  style.highlightColor = highlightHex;
57226
58547
  }
58548
+ const highlightXml = extractColorChoiceXml(highlightNode);
58549
+ if (highlightXml) {
58550
+ style.highlightColorXml = highlightXml;
58551
+ }
57227
58552
  }
57228
58553
  const textFillVariants = this.extractTextFillVariants(runProperties2);
57229
58554
  if (textFillVariants.textFillGradient) {
@@ -57244,16 +58569,28 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57244
58569
  const latin = xmlChild(runProperties2, "a:latin");
57245
58570
  const eastAsian = xmlChild(runProperties2, "a:ea");
57246
58571
  const complexScript = xmlChild(runProperties2, "a:cs");
57247
- 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;
57248
58576
  const resolvedTypeface = this.resolveThemeTypeface(chosenTypeface);
57249
58577
  if (resolvedTypeface) {
57250
58578
  style.fontFamily = resolvedTypeface;
57251
58579
  }
57252
- 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);
57253
58590
  if (eaTypeface) {
57254
58591
  style.eastAsiaFont = eaTypeface;
57255
58592
  }
57256
- const csTypeface = this.resolveThemeTypeface(xmlAttr(complexScript, "typeface"));
58593
+ const csTypeface = this.resolveThemeTypeface(csTypefaceToken);
57257
58594
  if (csTypeface) {
57258
58595
  style.complexScriptFont = csTypeface;
57259
58596
  }
@@ -57269,6 +58606,9 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57269
58606
  const capAttr = String(runProperties2["@_cap"] || "").trim().toLowerCase();
57270
58607
  if (capAttr === "all" || capAttr === "small") {
57271
58608
  style.textCaps = capAttr;
58609
+ } else if (capAttr === "none") {
58610
+ style.textCaps = "none";
58611
+ style.textCapsExplicitNone = true;
57272
58612
  }
57273
58613
  const symNode = xmlChild(runProperties2, "a:sym");
57274
58614
  if (symNode) {
@@ -57328,6 +58668,12 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57328
58668
  this.applyTextRunEffects(style, runEffectList);
57329
58669
  }
57330
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
+ }
57331
58677
  return style;
57332
58678
  }
57333
58679
  /**
@@ -57991,12 +59337,63 @@ function writeCellTextFormatting(xmlCell, style, ensureArray16) {
57991
59337
  }
57992
59338
  }
57993
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
+ }
57994
59384
  var PptxHandlerRuntime22 = class _PptxHandlerRuntime5 extends PptxHandlerRuntime21 {
57995
59385
  /**
57996
59386
  * Write plain text into a table cell's txBody, preserving
57997
59387
  * existing run properties where possible.
57998
59388
  */
57999
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
+ }
58000
59397
  if (!xmlCell["a:txBody"]) {
58001
59398
  xmlCell["a:txBody"] = { "a:bodyPr": {}, "a:p": {} };
58002
59399
  }
@@ -58124,7 +59521,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime5 extends PptxHandlerRuntime
58124
59521
  }
58125
59522
  delete tcPr["a:tcMar"];
58126
59523
  writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime5.EMU_PER_PX);
58127
- 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
+ }
58128
59527
  const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
58129
59528
  for (const key of Object.keys(tcPr)) {
58130
59529
  delete tcPr[key];
@@ -59793,7 +61192,7 @@ function findKey19(obj, name, getLocalName2) {
59793
61192
  function hex9(value) {
59794
61193
  return value.replace("#", "");
59795
61194
  }
59796
- var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
61195
+ var COLOR_LOCAL_NAMES2 = /* @__PURE__ */ new Set([
59797
61196
  "srgbClr",
59798
61197
  "schemeClr",
59799
61198
  "sysClr",
@@ -59802,7 +61201,7 @@ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
59802
61201
  "hslClr"
59803
61202
  ]);
59804
61203
  function applyColorToList(list, value, getLocalName2) {
59805
- 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)));
59806
61205
  const srgb = { "@_val": hex9(value) };
59807
61206
  if (!colorKey) {
59808
61207
  list["a:srgbClr"] = srgb;
@@ -62265,6 +63664,31 @@ var PptxHandlerRuntime27 = class extends PptxHandlerRuntime26 {
62265
63664
  return shape;
62266
63665
  }
62267
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
+ }
62268
63692
  var PptxHandlerRuntime28 = class _PptxHandlerRuntime8 extends PptxHandlerRuntime27 {
62269
63693
  /**
62270
63694
  * Serialize shape fill, stroke, dash, arrows, line join/cap/compound,
@@ -62334,26 +63758,14 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime8 extends PptxHandlerRuntime
62334
63758
  );
62335
63759
  }
62336
63760
  }
62337
- if (shapeStyle.strokeColor !== void 0) {
63761
+ if (shapeStyle.strokeColor !== void 0 || shapeStyle.strokeFillMode === "gradient" || shapeStyle.strokeFillMode === "pattern") {
62338
63762
  if (!spPr["a:ln"]) {
62339
63763
  spPr["a:ln"] = {};
62340
63764
  }
62341
63765
  const lineNode = spPr["a:ln"];
62342
63766
  const w = Math.round((shapeStyle.strokeWidth || 1) * _PptxHandlerRuntime8.EMU_PER_PX);
62343
63767
  lineNode["@_w"] = String(w);
62344
- if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
62345
- lineNode["a:noFill"] = {};
62346
- delete lineNode["a:solidFill"];
62347
- } else {
62348
- delete lineNode["a:noFill"];
62349
- const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
62350
- lineNode["a:solidFill"] = serializeColorChoice(
62351
- shapeStyle.strokeColorXml,
62352
- resolvedStrokeOriginal,
62353
- shapeStyle.strokeColor,
62354
- shapeStyle.strokeOpacity
62355
- );
62356
- }
63768
+ this.applyLineFill(lineNode, shapeStyle);
62357
63769
  }
62358
63770
  if (shapeStyle.strokeDash !== void 0) {
62359
63771
  if (!spPr["a:ln"]) {
@@ -62443,6 +63855,15 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime8 extends PptxHandlerRuntime
62443
63855
  spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
62444
63856
  }
62445
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
+ }
62446
63867
  /**
62447
63868
  * Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
62448
63869
  * from the persisted ref indices/colour XML. Emits children in spec
@@ -62596,45 +64017,18 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
62596
64017
  const s3d = shapeStyle.scene3d;
62597
64018
  const hasData = s3d.cameraPreset || s3d.lightRigType;
62598
64019
  if (hasData) {
62599
- const cameraObj = {};
62600
- if (s3d.cameraPreset) {
62601
- cameraObj["@_prst"] = s3d.cameraPreset;
62602
- }
62603
- if (s3d.cameraRotX !== void 0 || s3d.cameraRotY !== void 0 || s3d.cameraRotZ !== void 0) {
62604
- const rot = {};
62605
- if (s3d.cameraRotX !== void 0) {
62606
- rot["@_lat"] = String(s3d.cameraRotX);
62607
- }
62608
- if (s3d.cameraRotY !== void 0) {
62609
- rot["@_lon"] = String(s3d.cameraRotY);
62610
- }
62611
- if (s3d.cameraRotZ !== void 0) {
62612
- rot["@_rev"] = String(s3d.cameraRotZ);
62613
- }
62614
- cameraObj["a:rot"] = rot;
62615
- }
62616
- const lightRigObj = {};
62617
- if (s3d.lightRigType) {
62618
- lightRigObj["@_rig"] = s3d.lightRigType;
62619
- }
62620
- if (s3d.lightRigDirection) {
62621
- lightRigObj["@_dir"] = s3d.lightRigDirection;
62622
- }
62623
- const scene3dXml = {};
62624
- scene3dXml["a:camera"] = cameraObj;
62625
- if (Object.keys(lightRigObj).length > 0) {
62626
- scene3dXml["a:lightRig"] = lightRigObj;
62627
- }
62628
- if (s3d.hasBackdrop) {
62629
- const backdropObj = {};
62630
- if (s3d.backdropAnchorX !== void 0 || s3d.backdropAnchorY !== void 0 || s3d.backdropAnchorZ !== void 0) {
62631
- backdropObj["a:anchor"] = {
62632
- "@_x": String(s3d.backdropAnchorX ?? 0),
62633
- "@_y": String(s3d.backdropAnchorY ?? 0),
62634
- "@_z": String(s3d.backdropAnchorZ ?? 0)
62635
- };
62636
- }
62637
- scene3dXml["a:backdrop"] = backdropObj;
64020
+ const source = spPr["a:scene3d"] ?? {};
64021
+ const scene3dXml = { ...source };
64022
+ scene3dXml["a:camera"] = buildScene3dCamera(s3d, source);
64023
+ const lightRig = buildScene3dLightRig(s3d, source);
64024
+ if (lightRig) {
64025
+ scene3dXml["a:lightRig"] = lightRig;
64026
+ }
64027
+ const backdrop = buildScene3dBackdrop(s3d);
64028
+ if (backdrop) {
64029
+ scene3dXml["a:backdrop"] = backdrop;
64030
+ } else {
64031
+ delete scene3dXml["a:backdrop"];
62638
64032
  }
62639
64033
  spPr["a:scene3d"] = scene3dXml;
62640
64034
  } else {
@@ -62679,12 +64073,12 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
62679
64073
  }
62680
64074
  if (sh3d.extrusionColor) {
62681
64075
  sp3dXml["a:extrusionClr"] = {
62682
- "a:srgbClr": { "@_val": sh3d.extrusionColor }
64076
+ "a:srgbClr": { "@_val": sh3d.extrusionColor.replace("#", "") }
62683
64077
  };
62684
64078
  }
62685
64079
  if (sh3d.contourColor) {
62686
64080
  sp3dXml["a:contourClr"] = {
62687
- "a:srgbClr": { "@_val": sh3d.contourColor }
64081
+ "a:srgbClr": { "@_val": sh3d.contourColor.replace("#", "") }
62688
64082
  };
62689
64083
  }
62690
64084
  spPr["a:sp3d"] = sp3dXml;
@@ -62696,6 +64090,77 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
62696
64090
  }
62697
64091
  }
62698
64092
  };
64093
+ function buildSphereRot(lat, lon, rev) {
64094
+ if (lat === void 0 && lon === void 0 && rev === void 0) {
64095
+ return void 0;
64096
+ }
64097
+ const rot = {};
64098
+ if (lat !== void 0) {
64099
+ rot["@_lat"] = String(lat);
64100
+ }
64101
+ if (lon !== void 0) {
64102
+ rot["@_lon"] = String(lon);
64103
+ }
64104
+ if (rev !== void 0) {
64105
+ rot["@_rev"] = String(rev);
64106
+ }
64107
+ return rot;
64108
+ }
64109
+ function buildScene3dCamera(s3d, source) {
64110
+ const camera = { ...source["a:camera"] ?? {} };
64111
+ if (s3d.cameraPreset) {
64112
+ camera["@_prst"] = s3d.cameraPreset;
64113
+ }
64114
+ if (s3d.cameraFieldOfView !== void 0) {
64115
+ camera["@_fov"] = String(s3d.cameraFieldOfView);
64116
+ }
64117
+ if (s3d.cameraZoom !== void 0) {
64118
+ camera["@_zoom"] = String(s3d.cameraZoom);
64119
+ }
64120
+ const rot = buildSphereRot(s3d.cameraRotX, s3d.cameraRotY, s3d.cameraRotZ);
64121
+ if (rot) {
64122
+ camera["a:rot"] = rot;
64123
+ }
64124
+ return camera;
64125
+ }
64126
+ function buildScene3dLightRig(s3d, source) {
64127
+ const lightRig = { ...source["a:lightRig"] ?? {} };
64128
+ if (s3d.lightRigType) {
64129
+ lightRig["@_rig"] = s3d.lightRigType;
64130
+ }
64131
+ if (s3d.lightRigDirection) {
64132
+ lightRig["@_dir"] = s3d.lightRigDirection;
64133
+ }
64134
+ const rot = buildSphereRot(s3d.lightRigRotX, s3d.lightRigRotY, s3d.lightRigRotZ);
64135
+ if (rot) {
64136
+ lightRig["a:rot"] = rot;
64137
+ }
64138
+ return Object.keys(lightRig).length > 0 ? lightRig : void 0;
64139
+ }
64140
+ function buildScene3dBackdrop(s3d) {
64141
+ const hasNorm = s3d.backdropNormalX !== void 0 || s3d.backdropNormalY !== void 0 || s3d.backdropNormalZ !== void 0;
64142
+ const hasUp = s3d.backdropUpX !== void 0 || s3d.backdropUpY !== void 0 || s3d.backdropUpZ !== void 0;
64143
+ if (!s3d.hasBackdrop || !hasNorm || !hasUp) {
64144
+ return void 0;
64145
+ }
64146
+ return {
64147
+ "a:anchor": {
64148
+ "@_x": String(s3d.backdropAnchorX ?? 0),
64149
+ "@_y": String(s3d.backdropAnchorY ?? 0),
64150
+ "@_z": String(s3d.backdropAnchorZ ?? 0)
64151
+ },
64152
+ "a:norm": {
64153
+ "@_dx": String(s3d.backdropNormalX ?? 0),
64154
+ "@_dy": String(s3d.backdropNormalY ?? 0),
64155
+ "@_dz": String(s3d.backdropNormalZ ?? 0)
64156
+ },
64157
+ "a:up": {
64158
+ "@_dx": String(s3d.backdropUpX ?? 0),
64159
+ "@_dy": String(s3d.backdropUpY ?? 0),
64160
+ "@_dz": String(s3d.backdropUpZ ?? 0)
64161
+ }
64162
+ };
64163
+ }
62699
64164
  var PptxHandlerRuntime30 = class _PptxHandlerRuntime9 extends PptxHandlerRuntime29 {
62700
64165
  /**
62701
64166
  * Build and write the text body (`p:txBody`) for shapes, text boxes,
@@ -64710,14 +66175,20 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime17 extends PptxHandlerRuntim
64710
66175
  relationshipType: constants.slideSyncRelationshipType,
64711
66176
  contentType: constants.slideSyncContentType
64712
66177
  });
64713
- this.slideBackgroundBuilder.applyBackground({
66178
+ await this.slideBackgroundBuilder.applyBackground({
64714
66179
  slideNode,
64715
66180
  slide,
64716
66181
  zip: this.zip,
64717
66182
  saveState: saveSession,
64718
66183
  relationshipRegistry: slideRelationshipRegistry,
64719
66184
  slideImageRelationshipType: constants.slideImageRelationshipType,
64720
- 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
+ })
64721
66192
  });
64722
66193
  this.slideCommentPartWriter.writeComments({
64723
66194
  slide,
@@ -66202,7 +67673,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
66202
67673
  } = saveConstants;
66203
67674
  this.compatibilityService.resetWarnings();
66204
67675
  const saveSession = new PptxSaveStateBuilder().withZip(this.zip).withCommentAuthorMap(this.commentAuthorMap).withCommentAuthorDetails(this.commentAuthorDetails).withCommentAuthorsRootXml(this.commentAuthorsRootXml).withEmuPerPx(_PptxHandlerRuntime18.EMU_PER_PX).build();
66205
- await this.reconcilePresentationSlidesForSave({
67676
+ const slideReferenceRemap = await this.reconcilePresentationSlidesForSave({
66206
67677
  slides,
66207
67678
  saveSession,
66208
67679
  slideRelationshipType,
@@ -66297,7 +67768,8 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
66297
67768
  rawSlideWidthEmu: this.rawSlideWidthEmu,
66298
67769
  rawSlideHeightEmu: this.rawSlideHeightEmu,
66299
67770
  rawSlideSizeType: this.rawSlideSizeType,
66300
- xmlLookupService: this.xmlLookupService
67771
+ xmlLookupService: this.xmlLookupService,
67772
+ slideReferenceRemap
66301
67773
  });
66302
67774
  this.deduplicateExtensionLists(this.presentationData);
66303
67775
  if (effectiveConformance === "transitional") {
@@ -66314,7 +67786,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
66314
67786
  printSlidesPerPage: options.handoutMaster.slidesPerPage
66315
67787
  } : options?.presentationProperties;
66316
67788
  await this.applyPresentationPropertiesPart(presentationProperties);
66317
- await this.applyViewPropertiesPart(options?.viewProperties);
67789
+ await this.applyViewPropertiesPart(options?.viewProperties ?? this.loadedViewProperties);
66318
67790
  await this.applyTableStylesPart(options?.tableStyles);
66319
67791
  await this.documentPropertiesUpdater.updateOnSave(slides, {
66320
67792
  coreProperties: options?.coreProperties,
@@ -66600,26 +68072,16 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime19 extends PptxHandlerRuntim
66600
68072
  return true;
66601
68073
  }
66602
68074
  const typesMatch = source.type === target.type || source.type === "ctrtitle" && target.type === "title" || source.type === "subtitle" && target.type === "body";
66603
- if (source.idx !== void 0 && target.idx !== void 0) {
66604
- if (source.idx !== target.idx) {
66605
- return false;
66606
- }
66607
- if (source.type && target.type && !typesMatch) {
66608
- return false;
66609
- }
66610
- return true;
66611
- }
66612
- if (source.idx !== void 0 && target.idx === void 0) {
66613
- const singletonTypes = /* @__PURE__ */ new Set(["title", "ctrtitle", "subtitle", "dt", "ftr", "sldnum"]);
66614
- if (source.type && singletonTypes.has(source.type)) {
66615
- return typesMatch;
66616
- }
68075
+ const sourceIdx = source.idx ?? "0";
68076
+ const targetIdx = target.idx ?? "0";
68077
+ if (sourceIdx !== targetIdx) {
66617
68078
  return false;
66618
68079
  }
66619
68080
  if (source.type && target.type && !typesMatch) {
66620
68081
  return false;
66621
68082
  }
66622
- if (source.type && !target.type) {
68083
+ const bothHaveExplicitIdx = source.idx !== void 0 && target.idx !== void 0;
68084
+ if (!bothHaveExplicitIdx && source.type && !target.type) {
66623
68085
  return false;
66624
68086
  }
66625
68087
  return true;
@@ -68047,6 +69509,19 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime25 extends PptxHandlerRuntim
68047
69509
  });
68048
69510
  return hasAny ? locks : void 0;
68049
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
+ }
68050
69525
  /**
68051
69526
  * Extract body-level text properties from `a:bodyPr` and apply them to the
68052
69527
  * provided {@link TextStyle}. Returns linked-textbox info when present.
@@ -68227,6 +69702,62 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime25 extends PptxHandlerRuntim
68227
69702
  }
68228
69703
  };
68229
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
+ }
68230
69761
  /**
68231
69762
  * Resolve paragraph-level styles (alignment, spacing, margins, tabs,
68232
69763
  * level styles) for a single paragraph. Modifies `textStyle` in place
@@ -68473,6 +70004,12 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
68473
70004
  ...mergedDefaultRunStyle,
68474
70005
  ...this.extractTextRunStyle(runProps, paraAlign, ctx.slideRelationshipMap)
68475
70006
  };
70007
+ if (!runStyle2.scriptFallbackFont) {
70008
+ const fallback = this.resolveScriptFallbackFont(runText);
70009
+ if (fallback) {
70010
+ runStyle2.scriptFallbackFont = fallback;
70011
+ }
70012
+ }
68476
70013
  parts.push(runText);
68477
70014
  segments.push({ text: runText, style: runStyle2 });
68478
70015
  maybeSeed(runStyle2);
@@ -68514,14 +70051,25 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
68514
70051
  )
68515
70052
  };
68516
70053
  const fldType = String(field["@_type"] || "").trim() || void 0;
68517
- 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;
68518
70058
  parts.push(fieldText);
68519
- segments.push({
70059
+ const fieldSegment = {
68520
70060
  text: fieldText,
68521
70061
  style: fieldRunStyle,
68522
70062
  fieldType: fldType,
68523
70063
  fieldGuid: fldGuid
68524
- });
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);
68525
70073
  maybeSeed(fieldRunStyle);
68526
70074
  };
68527
70075
  const processMathElement = (mathEl) => {
@@ -68648,6 +70196,11 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
68648
70196
  ...endParaRPrRaw
68649
70197
  };
68650
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
+ }
68651
70204
  }
68652
70205
  return { parts, segments, seedStyle };
68653
70206
  }
@@ -68954,7 +70507,11 @@ var PptxHandlerRuntime64 = class _PptxHandlerRuntime27 extends PptxHandlerRuntim
68954
70507
  const inheritedCNvSpPr = xmlPath(inheritedPlaceholder?.shape, "p:nvSpPr", "p:cNvSpPr") ?? xmlPath(inheritedPlaceholder?.picture, "p:nvPicPr", "p:cNvPicPr");
68955
70508
  const inheritedLockNode = inheritedCNvSpPr?.["a:spLocks"] ?? inheritedCNvSpPr?.["a:picLocks"];
68956
70509
  const inheritedLocks = this.parseShapeLocks(inheritedLockNode);
68957
- 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
+ }
68958
70515
  const promptText = !hasText && phDefaults?.promptText ? phDefaults.promptText : void 0;
68959
70516
  const opaqueExtLstXml = this.extractOpaqueSpPrExtLst(effectiveSpPr);
68960
70517
  const commonProps = {
@@ -69051,7 +70608,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime28 extends PptxHandlerRuntim
69051
70608
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
69052
70609
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
69053
70610
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
69054
- const mediaReference = parseDrawingMediaReference(nvPr);
70611
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
69055
70612
  if (mediaReference) {
69056
70613
  this.compatibilityService.inspectMediaReferenceCompatibility(
69057
70614
  mediaReference.kind,
@@ -69815,6 +71372,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime30 extends PptxHandlerRuntim
69815
71372
  const grpSpPr = group["p:grpSpPr"];
69816
71373
  const xfrm = grpSpPr?.["a:xfrm"];
69817
71374
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
71375
+ let groupRotation;
71376
+ let flipHorizontal = false;
71377
+ let flipVertical = false;
69818
71378
  if (xfrm) {
69819
71379
  const off = xfrm["a:off"];
69820
71380
  if (off) {
@@ -69826,6 +71386,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime30 extends PptxHandlerRuntim
69826
71386
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime30.EMU_PER_PX);
69827
71387
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime30.EMU_PER_PX);
69828
71388
  }
71389
+ if (xfrm["@_rot"] !== void 0 && xfrm["@_rot"] !== null) {
71390
+ const rot = parseInt(String(xfrm["@_rot"]), 10) / 6e4;
71391
+ groupRotation = Number.isFinite(rot) && rot !== 0 ? rot : void 0;
71392
+ }
71393
+ flipHorizontal = this.parseBooleanAttr(xfrm["@_flipH"]);
71394
+ flipVertical = this.parseBooleanAttr(xfrm["@_flipV"]);
69829
71395
  }
69830
71396
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
69831
71397
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -69871,6 +71437,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime30 extends PptxHandlerRuntim
69871
71437
  y: parentY,
69872
71438
  width: parentW || Math.max(...children10.map((c) => c.x + c.width)),
69873
71439
  height: parentH || Math.max(...children10.map((c) => c.y + c.height)),
71440
+ rotation: groupRotation,
71441
+ flipHorizontal: flipHorizontal || void 0,
71442
+ flipVertical: flipVertical || void 0,
69874
71443
  children: children10,
69875
71444
  rawXml: group,
69876
71445
  actionClick: grpActionClick,
@@ -70877,9 +72446,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime31 extends PptxHandlerRuntim
70877
72446
  }
70878
72447
  const buClr = levelProps["a:buClr"];
70879
72448
  if (buClr) {
70880
- const srgb = buClr["a:srgbClr"];
70881
- if (srgb?.["@_val"]) {
70882
- style.bulletColor = String(srgb["@_val"]);
72449
+ const bulletColor = this.parseColor(buClr);
72450
+ if (bulletColor) {
72451
+ style.bulletColor = bulletColor;
70883
72452
  }
70884
72453
  }
70885
72454
  const buSzPts = levelProps["a:buSzPts"];
@@ -72463,16 +74032,20 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
72463
74032
  }
72464
74033
  let fontScheme;
72465
74034
  if (hasFonts) {
74035
+ const majorByScript = this.aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
74036
+ const minorByScript = this.aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
72466
74037
  fontScheme = {
72467
74038
  majorFont: {
72468
74039
  latin: this.themeFontMap["mj-lt"],
72469
74040
  eastAsia: this.themeFontMap["mj-ea"],
72470
- complexScript: this.themeFontMap["mj-cs"]
74041
+ complexScript: this.themeFontMap["mj-cs"],
74042
+ ...Object.keys(majorByScript).length > 0 ? { byScript: majorByScript } : {}
72471
74043
  },
72472
74044
  minorFont: {
72473
74045
  latin: this.themeFontMap["mn-lt"],
72474
74046
  eastAsia: this.themeFontMap["mn-ea"],
72475
- complexScript: this.themeFontMap["mn-cs"]
74047
+ complexScript: this.themeFontMap["mn-cs"],
74048
+ ...Object.keys(minorByScript).length > 0 ? { byScript: minorByScript } : {}
72476
74049
  }
72477
74050
  };
72478
74051
  }
@@ -72680,6 +74253,23 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
72680
74253
  *
72681
74254
  * Phase 4 Stream A / M4.
72682
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
+ }
72683
74273
  collectFontScriptOverrides(fontNode) {
72684
74274
  const overrides10 = {};
72685
74275
  if (!fontNode) {
@@ -73309,33 +74899,16 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
73309
74899
  const metadata = parseSmartArtDefinitionMetadata(colorsDef, localName22);
73310
74900
  const labels = parseSmartArtColorStyleLabels(colorsDef, localName22);
73311
74901
  const name = metadata.titles?.[0]?.value || String(colorsDef["@_title"] || colorsDef["@_uniqueId"] || "").trim() || void 0;
73312
- const fillColors = [];
73313
- const lineColors = [];
73314
74902
  const styleLbls = this.xmlLookupService.getChildrenArrayByLocalName(colorsDef, "styleLbl");
73315
- for (const lbl of styleLbls) {
73316
- const fillClrLst = this.xmlLookupService.getChildByLocalName(lbl, "fillClrLst");
73317
- const linClrLst = this.xmlLookupService.getChildByLocalName(lbl, "linClrLst");
73318
- if (fillClrLst) {
73319
- const color2 = this.parseColor(fillClrLst) ?? this.resolveSmartArtSchemeColor(
73320
- this.xmlLookupService.getChildByLocalName(fillClrLst, "schemeClr")
73321
- );
73322
- if (color2) {
73323
- fillColors.push(color2);
73324
- }
73325
- }
73326
- if (linClrLst) {
73327
- const color2 = this.parseColor(linClrLst) ?? this.resolveSmartArtSchemeColor(
73328
- this.xmlLookupService.getChildByLocalName(linClrLst, "schemeClr")
73329
- );
73330
- if (color2) {
73331
- lineColors.push(color2);
73332
- }
73333
- }
73334
- }
73335
- 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) {
73336
74909
  return void 0;
73337
74910
  }
73338
- return { ...metadata, name, fillColors, lineColors, labels };
74911
+ return { ...metadata, name, ...colorLists, labels };
73339
74912
  } catch {
73340
74913
  return void 0;
73341
74914
  }
@@ -73358,6 +74931,87 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
73358
74931
  return void 0;
73359
74932
  }
73360
74933
  };
74934
+ function extractDrawingShapeFill(spPr, deps) {
74935
+ const result = {};
74936
+ const solidFill2 = deps.getChild(spPr, "solidFill");
74937
+ if (solidFill2) {
74938
+ result.fillColor = deps.parseColor(solidFill2) ?? void 0;
74939
+ }
74940
+ const gradFill = !solidFill2 ? deps.getChild(spPr, "gradFill") : void 0;
74941
+ if (gradFill) {
74942
+ const stops = deps.extractGradientStops(gradFill).map((stop) => ({
74943
+ color: stop.color,
74944
+ position: stop.position,
74945
+ ...stop.opacity !== void 0 ? { opacity: stop.opacity } : {}
74946
+ }));
74947
+ if (stops.length > 0) {
74948
+ result.fillGradientStops = stops;
74949
+ result.fillGradientType = deps.extractGradientType(gradFill);
74950
+ result.fillGradientAngle = deps.extractGradientAngle(gradFill);
74951
+ result.fillColor ??= stops[Math.floor(stops.length / 2)]?.color;
74952
+ }
74953
+ }
74954
+ const pattFill = !solidFill2 && !gradFill ? deps.getChild(spPr, "pattFill") : void 0;
74955
+ if (pattFill) {
74956
+ const preset = String(pattFill["@_prst"] || "").trim();
74957
+ if (preset) {
74958
+ result.fillPatternPreset = preset;
74959
+ }
74960
+ const fg = deps.parseColor(deps.getChild(pattFill, "fgClr"));
74961
+ const bg = deps.parseColor(deps.getChild(pattFill, "bgClr"));
74962
+ if (fg) {
74963
+ result.fillPatternForegroundColor = fg;
74964
+ }
74965
+ if (bg) {
74966
+ result.fillPatternBackgroundColor = bg;
74967
+ }
74968
+ result.fillColor ??= fg ?? bg;
74969
+ }
74970
+ const blipFill = !solidFill2 && !gradFill && !pattFill ? deps.getChild(spPr, "blipFill") : void 0;
74971
+ if (blipFill) {
74972
+ const blip = deps.getChild(blipFill, "blip");
74973
+ const embed = String(
74974
+ blip?.["@_r:embed"] || blip?.["@_embed"] || blip?.["@_r:link"] || ""
74975
+ ).trim();
74976
+ if (embed) {
74977
+ result.fillBlipEmbedId = embed;
74978
+ }
74979
+ }
74980
+ const shadowColor = deps.extractShadowColor(spPr);
74981
+ if (shadowColor) {
74982
+ result.hasShadow = true;
74983
+ result.shadowColor = shadowColor;
74984
+ }
74985
+ return result;
74986
+ }
74987
+ function extractDrawingShapeTextStyle(txBody, deps) {
74988
+ let fontSize;
74989
+ let fontColor;
74990
+ if (!txBody) {
74991
+ return { fontSize, fontColor };
74992
+ }
74993
+ const paragraphs = deps.getChildren(txBody, "p");
74994
+ for (const p of paragraphs) {
74995
+ const runs = deps.getChildren(p, "r");
74996
+ for (const r of runs) {
74997
+ const rPr = deps.getChild(r, "rPr");
74998
+ if (rPr && !fontSize) {
74999
+ const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
75000
+ if (Number.isFinite(szRaw) && szRaw > 0) {
75001
+ fontSize = szRaw / 100;
75002
+ }
75003
+ fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
75004
+ }
75005
+ if (fontSize) {
75006
+ break;
75007
+ }
75008
+ }
75009
+ if (fontSize) {
75010
+ break;
75011
+ }
75012
+ }
75013
+ return { fontSize, fontColor };
75014
+ }
73361
75015
  function resolveSmartArtTextStyles(paragraphs, resolve) {
73362
75016
  for (const paragraph of paragraphs ?? []) {
73363
75017
  if (paragraph.endParaRPr) {
@@ -73530,8 +75184,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
73530
75184
  };
73531
75185
  }
73532
75186
  }
73533
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
73534
- const fillColor = this.parseColor(solidFill2);
75187
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
73535
75188
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
73536
75189
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
73537
75190
  const strokeColor = this.parseColor(lnFill);
@@ -73543,7 +75196,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
73543
75196
  this.collectLocalTextValues(txBody, "t", textValues2);
73544
75197
  }
73545
75198
  const text2 = textValues2.join("").trim() || void 0;
73546
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
75199
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
75200
+ txBody,
75201
+ this.drawingShapeStyleDeps()
75202
+ );
73547
75203
  const paragraphs = txBody ? resolveSmartArtTextStyles(
73548
75204
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
73549
75205
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -73569,7 +75225,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
73569
75225
  rotation,
73570
75226
  skewX,
73571
75227
  skewY,
73572
- fillColor: fillColor ?? void 0,
75228
+ ...fill,
75229
+ fillColor: fill.fillColor ?? void 0,
73573
75230
  strokeColor: strokeColor ?? void 0,
73574
75231
  strokeWidth,
73575
75232
  text: structuredText,
@@ -73579,36 +75236,124 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
73579
75236
  ...customGeometry
73580
75237
  };
73581
75238
  }
73582
- extractDrawingShapeTextStyle(txBody) {
73583
- let fontSize;
73584
- let fontColor;
73585
- if (!txBody) {
73586
- return { fontSize, fontColor };
73587
- }
73588
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
73589
- for (const p of paragraphs) {
73590
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
73591
- for (const r of runs) {
73592
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
73593
- if (rPr && !fontSize) {
73594
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
73595
- if (Number.isFinite(szRaw) && szRaw > 0) {
73596
- fontSize = szRaw / 100;
73597
- }
73598
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
73599
- fontColor = this.parseColor(rprFill) ?? void 0;
73600
- }
73601
- if (fontSize) {
73602
- break;
73603
- }
73604
- }
73605
- if (fontSize) {
73606
- break;
75239
+ /**
75240
+ * Build the injected accessor bundle used by the pure drawing-shape style
75241
+ * helpers, binding the shared XML-lookup / colour / gradient / shadow codec
75242
+ * methods so no new colour logic is duplicated here.
75243
+ */
75244
+ drawingShapeStyleDeps() {
75245
+ return {
75246
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
75247
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
75248
+ parseColor: (node) => this.parseColor(node),
75249
+ extractGradientStops: (gradFill) => this.extractGradientStops(gradFill),
75250
+ extractGradientType: (gradFill) => this.extractGradientType(gradFill),
75251
+ extractGradientAngle: (gradFill) => this.extractGradientAngle(gradFill),
75252
+ extractShadowColor: (spPr) => this.extractShadowStyle(spPr).shadowColor
75253
+ };
75254
+ }
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);
73607
75295
  }
73608
75296
  }
73609
- return { fontSize, fontColor };
75297
+ } catch {
73610
75298
  }
73611
- };
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
+ }
73612
75357
  var CATEGORY_FAMILY = {
73613
75358
  list: "list",
73614
75359
  process: "process",
@@ -73741,6 +75486,7 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime36 extends PptxHandlerRuntim
73741
75486
  layoutDefinition,
73742
75487
  nodes,
73743
75488
  connections: parsedConnections.length > 0 ? parsedConnections : void 0,
75489
+ presLayoutVars: parseSmartArtPresLayoutVars(dataModel),
73744
75490
  drawingShapes: drawingShapes.length > 0 ? drawingShapes : void 0,
73745
75491
  chrome,
73746
75492
  colorTransform,
@@ -73819,30 +75565,28 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime36 extends PptxHandlerRuntim
73819
75565
  }
73820
75566
  }
73821
75567
  /**
73822
- * Parse SmartArt drawing shapes given an absolute part path.
75568
+ * Parse cached SmartArt drawing shapes from an absolute part path.
73823
75569
  *
73824
- * Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
73825
- * relationship id) with a path-based lookup so the resolution layer
73826
- * 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.
73827
75573
  */
73828
75574
  async parseSmartArtDrawingShapesFromPath(drawingPath) {
73829
- const xmlString = await this.zip.file(drawingPath)?.async("string");
73830
- if (!xmlString) {
73831
- return [];
73832
- }
73833
- try {
73834
- const xml = this.parser.parse(xmlString);
73835
- const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
73836
- const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
73837
- if (!spTree) {
73838
- return [];
73839
- }
73840
- const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
73841
- const emuPerPx = _PptxHandlerRuntime36.EMU_PER_PX;
73842
- return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
73843
- } catch {
73844
- return [];
73845
- }
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
+ };
73846
75590
  }
73847
75591
  };
73848
75592
  var PptxHandlerRuntime86 = class extends PptxHandlerRuntime85 {
@@ -74530,6 +76274,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
74530
76274
  grouping = "clustered";
74531
76275
  }
74532
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");
74533
76282
  const chartPartPath = chartPart.partPath;
74534
76283
  const dataTable = parseDataTable(plotArea, this.xmlLookupService);
74535
76284
  const dropLines = parseLineStyle(
@@ -74606,6 +76355,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
74606
76355
  title: titleTextValues[0],
74607
76356
  style: chartStyle,
74608
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 } : {},
74609
76363
  chartPartPath,
74610
76364
  chartRelationshipId,
74611
76365
  ...dataTable ? { dataTable } : {},
@@ -74682,6 +76436,35 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
74682
76436
  }
74683
76437
  return { categories, series };
74684
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
+ }
74685
76468
  /**
74686
76469
  * Build the series array from raw OOXML `c:ser` nodes.
74687
76470
  *
@@ -74725,6 +76508,10 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
74725
76508
  );
74726
76509
  const dataLabels = parseSeriesDataLabels(seriesNode, this.xmlLookupService);
74727
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;
74728
76515
  return {
74729
76516
  name: seriesName.trim().length > 0 ? seriesName : `Series ${seriesIndex + 1}`,
74730
76517
  values: fallbackValues,
@@ -74735,6 +76522,8 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
74735
76522
  ...seriesMarker ? { marker: seriesMarker } : {},
74736
76523
  ...dataLabels.length > 0 ? { dataLabels } : {},
74737
76524
  ...explosion !== void 0 ? { explosion } : {},
76525
+ ...invertIfNegative !== void 0 ? { invertIfNegative } : {},
76526
+ ...smooth !== void 0 ? { smooth } : {},
74738
76527
  ...axisId !== void 0 ? { axisId } : {},
74739
76528
  ...seriesChartType ? { seriesChartType } : {}
74740
76529
  };
@@ -75553,6 +77342,8 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
75553
77342
  async buildLoadData(presentationState, slidesWithWarnings, slideMasters) {
75554
77343
  const headerFooter = this.extractHeaderFooter();
75555
77344
  const presentationProperties = await this.parsePresentationProperties();
77345
+ const viewProperties = await this.parseViewProperties();
77346
+ this.loadedViewProperties = viewProperties;
75556
77347
  const customShows = this.parseCustomShows();
75557
77348
  const tableStyleMap = await this.parseTableStyles();
75558
77349
  const embeddedFontList = parseEmbeddedFontList(this.presentationData);
@@ -75582,7 +77373,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
75582
77373
  presentationState.height,
75583
77374
  this.rawSlideWidthEmu,
75584
77375
  this.rawSlideHeightEmu
75585
- ).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(
75586
77377
  presentationState.orderedSections.length > 0 ? presentationState.orderedSections : void 0
75587
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(
75588
77379
  this.signatureDetection?.signatureCount && this.signatureDetection.signatureCount > 0 ? this.signatureDetection.signatureCount : void 0
@@ -75713,6 +77504,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
75713
77504
  this.customXmlParts = [];
75714
77505
  this.loadedEmbeddedFonts = [];
75715
77506
  this.loadedEmbeddedFontList = void 0;
77507
+ this.loadedViewProperties = void 0;
75716
77508
  this.orderedSlidePaths = [];
75717
77509
  this.zip = null;
75718
77510
  }
@@ -76056,6 +77848,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime38 extends PptxHandlerRuntim
76056
77848
  });
76057
77849
  this.mediaDataParser = new PptxMediaDataParser({
76058
77850
  slideRelsMap: this.slideRelsMap,
77851
+ externalRelsMap: this.externalRelsMap,
76059
77852
  resolvePath: (base, relative) => this.resolvePath(base, relative),
76060
77853
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
76061
77854
  });
@@ -76657,11 +78450,13 @@ function parseDrawingColorChoice(colorNode) {
76657
78450
  }
76658
78451
  if (colorNode["a:scrgbClr"]) {
76659
78452
  const scrgb = colorNode["a:scrgbClr"];
76660
- const red = parseDrawingPercent(scrgb["@_r"]);
76661
- const green = parseDrawingPercent(scrgb["@_g"]);
76662
- const blue = parseDrawingPercent(scrgb["@_b"]);
78453
+ const red = parseDrawingFraction(scrgb["@_r"]);
78454
+ const green = parseDrawingFraction(scrgb["@_g"]);
78455
+ const blue = parseDrawingFraction(scrgb["@_b"]);
76663
78456
  if (red !== void 0 && green !== void 0 && blue !== void 0) {
76664
- 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
+ )}`;
76665
78460
  return applyDrawingColorTransforms(base, scrgb);
76666
78461
  }
76667
78462
  }
@@ -76746,7 +78541,7 @@ function parseDrawingColorOpacity(colorNode) {
76746
78541
  const alphaMod = parseDrawingPercent(
76747
78542
  colorChoice["a:alphaMod"]?.["@_val"]
76748
78543
  );
76749
- const alphaOff = parseDrawingPercent(
78544
+ const alphaOff = parseDrawingFraction(
76750
78545
  colorChoice["a:alphaOff"]?.["@_val"]
76751
78546
  );
76752
78547
  if (alpha === void 0 && alphaMod === void 0 && alphaOff === void 0) {
@@ -78710,9 +80505,9 @@ function removeEmptyDataPoint(series, pointIndex) {
78710
80505
  }
78711
80506
  }
78712
80507
  }
78713
- var EMU_PER_PIXEL = 9525;
80508
+ var EMU_PER_PIXEL2 = 9525;
78714
80509
  function pxToEmu(px2) {
78715
- return Math.round(px2 * EMU_PER_PIXEL);
80510
+ return Math.round(px2 * EMU_PER_PIXEL2);
78716
80511
  }
78717
80512
  function placeholderSpXml(ph, shapeId) {
78718
80513
  const name = ph.name ?? `${ph.type.charAt(0).toUpperCase() + ph.type.slice(1)} Placeholder ${shapeId - 1}`;
@@ -80444,7 +82239,7 @@ var GroupBuilder = class _GroupBuilder {
80444
82239
  };
80445
82240
  var PPI = 96;
80446
82241
  var POINTS_PER_INCH = 72;
80447
- var EMU_PER_PIXEL2 = 9525;
82242
+ var EMU_PER_PIXEL3 = 9525;
80448
82243
  var EMU_PER_INCH = 914400;
80449
82244
  var EMU_PER_POINT = 12700;
80450
82245
  function inches(value) {
@@ -80460,10 +82255,10 @@ function pt(value) {
80460
82255
  return Math.round(value / POINTS_PER_INCH * PPI);
80461
82256
  }
80462
82257
  function emuToPixels(emu) {
80463
- return Math.round(emu / EMU_PER_PIXEL2);
82258
+ return Math.round(emu / EMU_PER_PIXEL3);
80464
82259
  }
80465
82260
  function pixelsToEmu(px2) {
80466
- return Math.round(px2 * EMU_PER_PIXEL2);
82261
+ return Math.round(px2 * EMU_PER_PIXEL3);
80467
82262
  }
80468
82263
  function inchesToEmu(value) {
80469
82264
  return Math.round(value * EMU_PER_INCH);
@@ -90719,7 +92514,7 @@ exports.EFFECT_LST_ORDER = EFFECT_LST_ORDER;
90719
92514
  exports.ELEMENT_FIELD_KIND = ELEMENT_FIELD_KIND;
90720
92515
  exports.EMPHASIS_PRESETS = EMPHASIS_PRESETS;
90721
92516
  exports.EMU_PER_INCH = EMU_PER_INCH;
90722
- exports.EMU_PER_PIXEL2 = EMU_PER_PIXEL2;
92517
+ exports.EMU_PER_PIXEL3 = EMU_PER_PIXEL3;
90723
92518
  exports.EMU_PER_POINT = EMU_PER_POINT;
90724
92519
  exports.EMU_PER_PX = EMU_PER_PX;
90725
92520
  exports.ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV = ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV;
@@ -90868,6 +92663,7 @@ exports.buildInkMlContent = buildInkMlContent;
90868
92663
  exports.buildLinkedTextBoxChains = buildLinkedTextBoxChains;
90869
92664
  exports.buildOle2 = buildOle2;
90870
92665
  exports.buildSingleEffectNode = buildSingleEffectNode;
92666
+ exports.buildSlideReferenceRemap = buildSlideReferenceRemap;
90871
92667
  exports.buildSrgbColorChoice = buildSrgbColorChoice;
90872
92668
  exports.buildThemeColorMap = buildThemeColorMap;
90873
92669
  exports.catmullRomToBezier = catmullRomToBezier;
@@ -90941,6 +92737,8 @@ exports.decryptPptx = decryptPptx;
90941
92737
  exports.demoteSmartArtNode = demoteSmartArtNode;
90942
92738
  exports.deobfuscateFont = deobfuscateFont;
90943
92739
  exports.deriveOutputPath = deriveOutputPath;
92740
+ exports.deriveSlideTitle = deriveSlideTitle;
92741
+ exports.deriveSlideTitles = deriveSlideTitles;
90944
92742
  exports.detectDigitalSignatures = detectDigitalSignatures;
90945
92743
  exports.detectFileFormat = detectFileFormat;
90946
92744
  exports.detectFontFormat = detectFontFormat;