pptx-viewer-core 1.6.9 → 1.6.10

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.
package/dist/cli/index.js CHANGED
@@ -5191,6 +5191,11 @@ function parseDrawingPercent(value) {
5191
5191
  }
5192
5192
  return clampUnitInterval(parsed / 1e5);
5193
5193
  }
5194
+ function scrgbLinearToSrgb8(linear) {
5195
+ const l = Math.min(1, Math.max(0, linear));
5196
+ const companded = l <= 31308e-7 ? 12.92 * l : 1.055 * l ** (1 / 2.4) - 0.055;
5197
+ return Math.min(255, Math.max(0, Math.round(companded * 255)));
5198
+ }
5194
5199
  function toHex(value) {
5195
5200
  return Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
5196
5201
  }
@@ -6558,6 +6563,21 @@ function cloneXmlObject(value) {
6558
6563
 
6559
6564
  // src/core/utils/presentation-collections.ts
6560
6565
  var SECTION_EXTENSION_URI = "{521415D9-36F7-43E2-AB2F-B90AF26B5E84}";
6566
+ function remapReferenceList(references, mapping, removed) {
6567
+ const result = [];
6568
+ for (const reference of references) {
6569
+ const mapped = mapping.get(reference);
6570
+ if (mapped !== void 0) {
6571
+ result.push(mapped);
6572
+ continue;
6573
+ }
6574
+ if (removed.has(reference)) {
6575
+ continue;
6576
+ }
6577
+ result.push(reference);
6578
+ }
6579
+ return result;
6580
+ }
6561
6581
  function localName2(key) {
6562
6582
  return key.split(":").pop() ?? key;
6563
6583
  }
@@ -6624,7 +6644,7 @@ function updateCustomShow(show, existing) {
6624
6644
  replaceChildren(node, "sldLst", slideList, "p:sldLst");
6625
6645
  return node;
6626
6646
  }
6627
- function applyCustomShows(presentation, shows, lookup) {
6647
+ function applyCustomShows(presentation, shows, lookup, remap) {
6628
6648
  if (shows === void 0) {
6629
6649
  return;
6630
6650
  }
@@ -6638,14 +6658,18 @@ function applyCustomShows(presentation, shows, lookup) {
6638
6658
  const oldList = key ? presentation[key] : void 0;
6639
6659
  const list = cloneXmlObject(oldList) ?? {};
6640
6660
  const oldShows = lookup.getChildrenArrayByLocalName(oldList, "custShow");
6641
- const updated = shows.map(
6642
- (show) => updateCustomShow(
6643
- show,
6661
+ const updated = shows.map((show) => {
6662
+ const effective = remap && remap.changed ? {
6663
+ ...show,
6664
+ slideRIds: remapReferenceList(show.slideRIds, remap.rIdByOldRId, remap.removedRIds)
6665
+ } : show;
6666
+ return updateCustomShow(
6667
+ effective,
6644
6668
  oldShows.find(
6645
6669
  (node) => String(node[attributeKey(node, "id") ?? ""]) === show.id || String(node[attributeKey(node, "name") ?? ""]) === show.name
6646
6670
  )
6647
- )
6648
- );
6671
+ );
6672
+ });
6649
6673
  replaceChildren(list, "custShow", updated, "p:custShow");
6650
6674
  presentation[key ?? "p:custShowLst"] = list;
6651
6675
  }
@@ -6694,7 +6718,7 @@ function updateSection(section) {
6694
6718
  }
6695
6719
  return node;
6696
6720
  }
6697
- function applySections(presentation, sections, lookup) {
6721
+ function applySections(presentation, sections, lookup, remap) {
6698
6722
  if (sections === void 0) {
6699
6723
  return;
6700
6724
  }
@@ -6716,7 +6740,15 @@ function applySections(presentation, sections, lookup) {
6716
6740
  location = { parent: ext, key: "p14:sectionLst", list: ext["p14:sectionLst"] };
6717
6741
  }
6718
6742
  const list = cloneXmlObject(location.list) ?? {};
6719
- replaceChildren(list, "section", sections.map(updateSection), "p14:section");
6743
+ const effectiveSections = remap && remap.changed ? sections.map((section) => ({
6744
+ ...section,
6745
+ slideIds: remapReferenceList(
6746
+ section.slideIds,
6747
+ remap.sldIdByOldSldId,
6748
+ remap.removedSldIds
6749
+ )
6750
+ })) : sections;
6751
+ replaceChildren(list, "section", effectiveSections.map(updateSection), "p14:section");
6720
6752
  location.parent[location.key] = list;
6721
6753
  }
6722
6754
 
@@ -10711,6 +10743,122 @@ function applyNodeStylesToElements(elements, nodes) {
10711
10743
  });
10712
10744
  }
10713
10745
 
10746
+ // src/core/utils/smartart-pres-layout-vars.ts
10747
+ var CONTAINER_LOCAL_NAMES = /* @__PURE__ */ new Set(["presLayoutVars", "varLst"]);
10748
+ function localNameOf2(key) {
10749
+ const idx = key.indexOf(":");
10750
+ return idx >= 0 ? key.slice(idx + 1) : key;
10751
+ }
10752
+ function findVarsContainer(node) {
10753
+ if (!node || typeof node !== "object") {
10754
+ return void 0;
10755
+ }
10756
+ if (Array.isArray(node)) {
10757
+ for (const entry of node) {
10758
+ const found = findVarsContainer(entry);
10759
+ if (found) {
10760
+ return found;
10761
+ }
10762
+ }
10763
+ return void 0;
10764
+ }
10765
+ for (const [key, value] of Object.entries(node)) {
10766
+ if (key.startsWith("@_")) {
10767
+ continue;
10768
+ }
10769
+ if (CONTAINER_LOCAL_NAMES.has(localNameOf2(key))) {
10770
+ const container = Array.isArray(value) ? value[0] : value;
10771
+ if (container && typeof container === "object") {
10772
+ return container;
10773
+ }
10774
+ }
10775
+ const nested = findVarsContainer(value);
10776
+ if (nested) {
10777
+ return nested;
10778
+ }
10779
+ }
10780
+ return void 0;
10781
+ }
10782
+ function varValue(container, name) {
10783
+ for (const [key, value] of Object.entries(container)) {
10784
+ if (key.startsWith("@_") || localNameOf2(key) !== name) {
10785
+ continue;
10786
+ }
10787
+ const node = Array.isArray(value) ? value[0] : value;
10788
+ if (node && typeof node === "object") {
10789
+ const raw = node["@_val"];
10790
+ const str = String(raw ?? "").trim();
10791
+ return str.length > 0 ? str : void 0;
10792
+ }
10793
+ }
10794
+ return void 0;
10795
+ }
10796
+ function boolValue(container, name) {
10797
+ const raw = varValue(container, name);
10798
+ if (raw === void 0) {
10799
+ return void 0;
10800
+ }
10801
+ const lower = raw.toLowerCase();
10802
+ return lower === "1" || lower === "true" || lower === "on";
10803
+ }
10804
+ function intValue(container, name) {
10805
+ const raw = varValue(container, name);
10806
+ if (raw === void 0) {
10807
+ return void 0;
10808
+ }
10809
+ const parsed = Number.parseInt(raw, 10);
10810
+ return Number.isFinite(parsed) ? parsed : void 0;
10811
+ }
10812
+ var DIRECTIONS = /* @__PURE__ */ new Set(["norm", "rev"]);
10813
+ var HIER_BRANCHES = /* @__PURE__ */ new Set(["std", "init", "l", "r", "hang"]);
10814
+ function parseSmartArtPresLayoutVars(container) {
10815
+ if (!container) {
10816
+ return void 0;
10817
+ }
10818
+ const vars = findVarsContainer(container);
10819
+ if (!vars) {
10820
+ return void 0;
10821
+ }
10822
+ const result = {};
10823
+ const direction = varValue(vars, "dir");
10824
+ if (direction && DIRECTIONS.has(direction)) {
10825
+ result.direction = direction;
10826
+ }
10827
+ const hierBranch = varValue(vars, "hierBranch");
10828
+ if (hierBranch && HIER_BRANCHES.has(hierBranch)) {
10829
+ result.hierarchyBranch = hierBranch;
10830
+ }
10831
+ const orgChart = boolValue(vars, "orgChart");
10832
+ if (orgChart !== void 0) {
10833
+ result.orgChart = orgChart;
10834
+ }
10835
+ const chMax = intValue(vars, "chMax");
10836
+ if (chMax !== void 0) {
10837
+ result.childMax = chMax;
10838
+ }
10839
+ const chPref = intValue(vars, "chPref");
10840
+ if (chPref !== void 0) {
10841
+ result.childPreferred = chPref;
10842
+ }
10843
+ const bulletEnabled = boolValue(vars, "bulletEnabled");
10844
+ if (bulletEnabled !== void 0) {
10845
+ result.bulletEnabled = bulletEnabled;
10846
+ }
10847
+ const animLvl = varValue(vars, "animLvl");
10848
+ if (animLvl !== void 0) {
10849
+ result.animationLevel = animLvl;
10850
+ }
10851
+ const animOne = varValue(vars, "animOne");
10852
+ if (animOne !== void 0) {
10853
+ result.animateOne = animOne;
10854
+ }
10855
+ const resizeHandles = varValue(vars, "resizeHandles");
10856
+ if (resizeHandles !== void 0) {
10857
+ result.resizeHandles = resizeHandles;
10858
+ }
10859
+ return Object.keys(result).length > 0 ? result : void 0;
10860
+ }
10861
+
10714
10862
  // src/core/utils/smartart-decompose.ts
10715
10863
  function quickStyleStrokeScale(quickStyle) {
10716
10864
  if (!quickStyle?.effectIntensity) {
@@ -10816,15 +10964,27 @@ function decomposeSmartArt(smartArtData, containerBounds, themeColorMap, layoutD
10816
10964
  smartArtData.colorTransform?.fillColors
10817
10965
  );
10818
10966
  const layoutType = resolveEffectiveLayoutType(smartArtData);
10967
+ const layoutVars = smartArtData.presLayoutVars ?? parseSmartArtPresLayoutVars(smartArtData.layoutDefinition?.rawXml);
10968
+ const orderedNodes = layoutVars?.direction === "rev" ? [...nodes].reverse() : nodes;
10819
10969
  const namedLayout = smartArtData.layout;
10820
10970
  if (namedLayout) {
10821
- const namedResult = dispatchNamedLayout(namedLayout, nodes, containerBounds, effectiveThemeMap);
10971
+ const namedResult = dispatchNamedLayout(
10972
+ namedLayout,
10973
+ orderedNodes,
10974
+ containerBounds,
10975
+ effectiveThemeMap
10976
+ );
10822
10977
  if (namedResult) {
10823
- return applyNodeStylesToElements(namedResult, nodes);
10978
+ return applyNodeStylesToElements(namedResult, orderedNodes);
10824
10979
  }
10825
10980
  }
10826
- const algorithmic = dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap);
10827
- return algorithmic ? applyNodeStylesToElements(algorithmic, nodes) : algorithmic;
10981
+ const algorithmic = dispatchLayoutByType(
10982
+ layoutType,
10983
+ orderedNodes,
10984
+ containerBounds,
10985
+ effectiveThemeMap
10986
+ );
10987
+ return algorithmic ? applyNodeStylesToElements(algorithmic, orderedNodes) : algorithmic;
10828
10988
  }
10829
10989
  function dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap) {
10830
10990
  switch (layoutType) {
@@ -17042,6 +17202,19 @@ function xmlChild(node, key) {
17042
17202
  }
17043
17203
  return isXmlObject2(value) ? value : void 0;
17044
17204
  }
17205
+ function xmlChildren(node, key) {
17206
+ if (!isXmlObject2(node)) {
17207
+ return [];
17208
+ }
17209
+ const value = node[key];
17210
+ if (value === void 0 || value === null) {
17211
+ return [];
17212
+ }
17213
+ if (Array.isArray(value)) {
17214
+ return value.filter(isXmlObject2);
17215
+ }
17216
+ return isXmlObject2(value) ? [value] : [];
17217
+ }
17045
17218
  function xmlHasChild(node, key) {
17046
17219
  return isXmlObject2(node) && Object.hasOwn(node, key);
17047
17220
  }
@@ -17069,6 +17242,9 @@ function xmlPath(node, ...keys) {
17069
17242
  }
17070
17243
  return current;
17071
17244
  }
17245
+ function isXmlNode(value) {
17246
+ return isXmlObject2(value);
17247
+ }
17072
17248
 
17073
17249
  // src/core/utils/chart-bubble-options.ts
17074
17250
  var ORDER2 = [
@@ -17085,7 +17261,7 @@ var ORDER2 = [
17085
17261
  function findKey4(node, name, localName21) {
17086
17262
  return Object.keys(node).find((key) => localName21(key) === name);
17087
17263
  }
17088
- function boolValue(node) {
17264
+ function boolValue2(node) {
17089
17265
  if (!node) {
17090
17266
  return void 0;
17091
17267
  }
@@ -17101,7 +17277,7 @@ function parseBubbleChartOptions(container, localName21) {
17101
17277
  return key ? container[key] : void 0;
17102
17278
  };
17103
17279
  const options = {};
17104
- const bubble3D = boolValue(node("bubble3D"));
17280
+ const bubble3D = boolValue2(node("bubble3D"));
17105
17281
  if (bubble3D !== void 0) {
17106
17282
  options.bubble3D = bubble3D;
17107
17283
  }
@@ -17112,7 +17288,7 @@ function parseBubbleChartOptions(container, localName21) {
17112
17288
  options.bubbleScale = scale;
17113
17289
  }
17114
17290
  }
17115
- const showNegative = boolValue(node("showNegBubbles"));
17291
+ const showNegative = boolValue2(node("showNegBubbles"));
17116
17292
  if (showNegative !== void 0) {
17117
17293
  options.showNegativeBubbles = showNegative;
17118
17294
  }
@@ -17600,6 +17776,45 @@ function withThemePlaceholderColor(themeColorMap, placeholderColor, operation) {
17600
17776
  }
17601
17777
  }
17602
17778
 
17779
+ // src/core/utils/slide-title.ts
17780
+ var TITLE_PLACEHOLDER_TYPES = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
17781
+ function getElementPlaceholderType(element) {
17782
+ const explicit = element.placeholderType;
17783
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
17784
+ return explicit.trim().toLowerCase();
17785
+ }
17786
+ const ph = xmlPath(element.rawXml, "p:nvSpPr", "p:nvPr", "p:ph");
17787
+ const type = xmlAttr(ph, "type");
17788
+ return type ? type.trim().toLowerCase() : void 0;
17789
+ }
17790
+ function getElementPlainText(element) {
17791
+ const maybe = element;
17792
+ if (typeof maybe.text === "string" && maybe.text.trim().length > 0) {
17793
+ return maybe.text.trim();
17794
+ }
17795
+ if (Array.isArray(maybe.textSegments)) {
17796
+ const joined = maybe.textSegments.map((segment) => typeof segment?.text === "string" ? segment.text : "").join("");
17797
+ return joined.trim();
17798
+ }
17799
+ return "";
17800
+ }
17801
+ function deriveSlideTitle(slide) {
17802
+ const elements = slide.elements ?? [];
17803
+ for (const element of elements) {
17804
+ const phType = getElementPlaceholderType(element);
17805
+ if (phType && TITLE_PLACEHOLDER_TYPES.has(phType)) {
17806
+ const text2 = getElementPlainText(element);
17807
+ if (text2) {
17808
+ return text2;
17809
+ }
17810
+ }
17811
+ }
17812
+ return "";
17813
+ }
17814
+ function deriveSlideTitles(slides) {
17815
+ return slides.map((slide) => deriveSlideTitle(slide));
17816
+ }
17817
+
17603
17818
  // src/converter/svg-chart-extended.ts
17604
17819
  var DEFAULT_COLORS = ["#4472C4", "#ED7D31", "#A5A5A5", "#FFC000", "#5B9BD5", "#70AD47"];
17605
17820
  function esc(value) {
@@ -20175,6 +20390,7 @@ var TextShapeXmlFactory = class {
20175
20390
  createXmlElement(init) {
20176
20391
  const { element } = init;
20177
20392
  const isText = element.type === "text";
20393
+ const isTextBox = element.locks?.txBox ?? isText;
20178
20394
  const name = isText ? "TextBox" : "Rectangle";
20179
20395
  const geometry = this.context.normalizePresetGeometry(element.shapeType);
20180
20396
  const adjustmentEntries = Object.entries(element.shapeAdjustments || {}).filter(
@@ -20194,7 +20410,7 @@ var TextShapeXmlFactory = class {
20194
20410
  "@_name": `${name} ${elementId}`
20195
20411
  },
20196
20412
  "p:cNvSpPr": {
20197
- "@_txBox": isText ? "1" : "0"
20413
+ "@_txBox": isTextBox ? "1" : "0"
20198
20414
  },
20199
20415
  "p:nvPr": {}
20200
20416
  },
@@ -20652,8 +20868,18 @@ var PptxPresentationSaveBuilder = class {
20652
20868
  init.rawSlideHeightEmu,
20653
20869
  init.rawSlideSizeType
20654
20870
  );
20655
- applyCustomShows(presentation, init.options?.customShows, init.xmlLookupService);
20656
- applySections(presentation, init.options?.sections, init.xmlLookupService);
20871
+ applyCustomShows(
20872
+ presentation,
20873
+ init.options?.customShows,
20874
+ init.xmlLookupService,
20875
+ init.slideReferenceRemap
20876
+ );
20877
+ applySections(
20878
+ presentation,
20879
+ init.options?.sections,
20880
+ init.xmlLookupService,
20881
+ init.slideReferenceRemap
20882
+ );
20657
20883
  this.applyPhotoAlbum(presentation, init.options?.photoAlbum);
20658
20884
  presentation = this.applyKinsoku(presentation, init.options?.kinsoku);
20659
20885
  this.applyModifyVerifier(presentation, init.options?.modifyVerifier);
@@ -20748,6 +20974,53 @@ var PptxPresentationSaveBuilder = class {
20748
20974
  }
20749
20975
  };
20750
20976
 
20977
+ // src/core/core/builders/slide-reference-remap.ts
20978
+ function buildSlideReferenceRemap(init) {
20979
+ const pathToNewRId = /* @__PURE__ */ new Map();
20980
+ for (const slide of init.slides) {
20981
+ pathToNewRId.set(slide.id, slide.rId);
20982
+ }
20983
+ const newRIdToNumeric = /* @__PURE__ */ new Map();
20984
+ for (const entry of init.rebuiltSlideIds) {
20985
+ const relationshipId2 = String(entry?.["@_r:id"] ?? "");
20986
+ const numericSlideId = String(entry?.["@_id"] ?? "");
20987
+ if (relationshipId2.length > 0 && numericSlideId.length > 0) {
20988
+ newRIdToNumeric.set(relationshipId2, numericSlideId);
20989
+ }
20990
+ }
20991
+ const rIdByOldRId = /* @__PURE__ */ new Map();
20992
+ const removedRIds = /* @__PURE__ */ new Set();
20993
+ let changed = false;
20994
+ for (const [oldRId, path2] of init.originalRIdToPath.entries()) {
20995
+ const newRId = pathToNewRId.get(path2);
20996
+ if (newRId === void 0) {
20997
+ removedRIds.add(oldRId);
20998
+ changed = true;
20999
+ continue;
21000
+ }
21001
+ rIdByOldRId.set(oldRId, newRId);
21002
+ if (newRId !== oldRId) {
21003
+ changed = true;
21004
+ }
21005
+ }
21006
+ const sldIdByOldSldId = /* @__PURE__ */ new Map();
21007
+ const removedSldIds = /* @__PURE__ */ new Set();
21008
+ for (const [oldSldId, path2] of init.originalSldIdToPath.entries()) {
21009
+ const newRId = pathToNewRId.get(path2);
21010
+ const newSldId = newRId === void 0 ? void 0 : newRIdToNumeric.get(newRId);
21011
+ if (newSldId === void 0) {
21012
+ removedSldIds.add(oldSldId);
21013
+ changed = true;
21014
+ continue;
21015
+ }
21016
+ sldIdByOldSldId.set(oldSldId, newSldId);
21017
+ if (newSldId !== oldSldId) {
21018
+ changed = true;
21019
+ }
21020
+ }
21021
+ return { rIdByOldRId, sldIdByOldSldId, removedRIds, removedSldIds, changed };
21022
+ }
21023
+
20751
21024
  // src/core/core/builders/PptxPresentationSlidesReconciler.ts
20752
21025
  var PptxPresentationSlidesReconciler = class {
20753
21026
  async reconcile(input) {
@@ -20793,6 +21066,10 @@ var PptxPresentationSlidesReconciler = class {
20793
21066
  const existingSlideIds = slideIdList ? this.ensureArray(slideIdList["p:sldId"]) : [];
20794
21067
  const slideIdByRid = /* @__PURE__ */ new Map();
20795
21068
  let maxNumericSlideId = 255;
21069
+ const originalRIdToPath = /* @__PURE__ */ new Map();
21070
+ for (const [relationshipId2, target] of slideTargetByRid.entries()) {
21071
+ originalRIdToPath.set(relationshipId2, input.toSlidePathFromTarget(target));
21072
+ }
20796
21073
  for (const slideIdEntry of existingSlideIds) {
20797
21074
  const relationshipId2 = slideIdEntry?.["@_r:id"];
20798
21075
  if (typeof relationshipId2 === "string" && relationshipId2.length > 0) {
@@ -20803,6 +21080,15 @@ var PptxPresentationSlidesReconciler = class {
20803
21080
  maxNumericSlideId = Math.max(maxNumericSlideId, numericSlideId);
20804
21081
  }
20805
21082
  }
21083
+ const originalSldIdToPath = /* @__PURE__ */ new Map();
21084
+ for (const slideIdEntry of existingSlideIds) {
21085
+ const relationshipId2 = String(slideIdEntry?.["@_r:id"] ?? "");
21086
+ const numericSlideId = String(slideIdEntry?.["@_id"] ?? "");
21087
+ const slidePath = originalRIdToPath.get(relationshipId2);
21088
+ if (numericSlideId.length > 0 && slidePath !== void 0) {
21089
+ originalSldIdToPath.set(numericSlideId, slidePath);
21090
+ }
21091
+ }
20806
21092
  for (let index = 0; index < input.slides.length; index++) {
20807
21093
  const slide = input.slides[index];
20808
21094
  slide.slideNumber = index + 1;
@@ -20839,6 +21125,7 @@ var PptxPresentationSlidesReconciler = class {
20839
21125
  ];
20840
21126
  presentationRelsData["Relationships"] = relRoot;
20841
21127
  input.zip.file("ppt/_rels/presentation.xml.rels", input.xmlBuilder.build(presentationRelsData));
21128
+ const rebuiltSlideIds = [];
20842
21129
  if (presentation && slideIdList && input.presentationData) {
20843
21130
  slideIdList["p:sldId"] = input.slides.map((slide) => {
20844
21131
  const existing = slideIdByRid.get(slide.rId);
@@ -20851,11 +21138,18 @@ var PptxPresentationSlidesReconciler = class {
20851
21138
  "@_r:id": slide.rId
20852
21139
  };
20853
21140
  });
21141
+ rebuiltSlideIds.push(...slideIdList["p:sldId"]);
20854
21142
  input.presentationData["p:presentation"] = this.insertSlideIdListInOrder(
20855
21143
  presentation,
20856
21144
  slideIdList
20857
21145
  );
20858
21146
  }
21147
+ return buildSlideReferenceRemap({
21148
+ slides: input.slides,
21149
+ originalRIdToPath,
21150
+ originalSldIdToPath,
21151
+ rebuiltSlideIds
21152
+ });
20859
21153
  }
20860
21154
  /**
20861
21155
  * Return a new presentation XML object whose `p:sldIdLst` child sits in the
@@ -21441,7 +21735,7 @@ var PptxSlideNotesPartUpdater = class {
21441
21735
 
21442
21736
  // src/core/core/builders/PptxSlideBackgroundBuilder.ts
21443
21737
  var PptxSlideBackgroundBuilder = class {
21444
- applyBackground(init) {
21738
+ async applyBackground(init) {
21445
21739
  const hasBackgroundColor = typeof init.slide.backgroundColor === "string" && init.slide.backgroundColor.length > 0 && init.slide.backgroundColor !== "transparent";
21446
21740
  const rawBackgroundImage = typeof init.slide.backgroundImage === "string" ? init.slide.backgroundImage : "";
21447
21741
  const hasBackgroundImage = rawBackgroundImage.length > 0;
@@ -21462,8 +21756,8 @@ var PptxSlideBackgroundBuilder = class {
21462
21756
  return;
21463
21757
  }
21464
21758
  const backgroundProperties = {};
21465
- if (hasDataUrlBackgroundImage) {
21466
- const parsedBackgroundImage = init.parseDataUrlToBytes(rawBackgroundImage);
21759
+ if (hasBackgroundImage) {
21760
+ const parsedBackgroundImage = await init.resolveImageToBytes(rawBackgroundImage);
21467
21761
  if (parsedBackgroundImage) {
21468
21762
  const backgroundImagePath = init.saveState.nextMediaPath(parsedBackgroundImage.extension);
21469
21763
  init.zip.file(backgroundImagePath, parsedBackgroundImage.bytes);
@@ -21481,8 +21775,11 @@ var PptxSlideBackgroundBuilder = class {
21481
21775
  },
21482
21776
  BLIP_FILL_ORDER
21483
21777
  );
21778
+ } else {
21779
+ init.reportUnsupportedBackground?.(rawBackgroundImage);
21484
21780
  }
21485
- } else if (hasBackgroundColor && init.slide.backgroundColor) {
21781
+ }
21782
+ if (backgroundProperties["a:blipFill"] === void 0 && hasBackgroundColor && init.slide.backgroundColor) {
21486
21783
  backgroundProperties["a:solidFill"] = {
21487
21784
  "a:srgbClr": {
21488
21785
  "@_val": init.slide.backgroundColor.replace("#", "").toUpperCase()
@@ -21499,6 +21796,11 @@ var PptxSlideBackgroundBuilder = class {
21499
21796
  backgroundProperties["@_shadeToTitle"] = "0";
21500
21797
  }
21501
21798
  if (!hasFillChild) {
21799
+ if (existingBg !== void 0) {
21800
+ this.reorderCSldBgFirst(cSld, existingBg);
21801
+ init.slideNode["p:cSld"] = cSld;
21802
+ return;
21803
+ }
21502
21804
  delete cSld["p:bg"];
21503
21805
  init.slideNode["p:cSld"] = cSld;
21504
21806
  return;
@@ -21708,11 +22010,15 @@ var PptxColorTransformCodec = class {
21708
22010
  }
21709
22011
  if (colorChoice["a:scrgbClr"]) {
21710
22012
  const scrgb = colorChoice["a:scrgbClr"];
21711
- const red = this.percentAttrToUnit(scrgb["@_r"]);
21712
- const green = this.percentAttrToUnit(scrgb["@_g"]);
21713
- const blue = this.percentAttrToUnit(scrgb["@_b"]);
22013
+ const red = parseDrawingFraction(scrgb["@_r"]);
22014
+ const green = parseDrawingFraction(scrgb["@_g"]);
22015
+ const blue = parseDrawingFraction(scrgb["@_b"]);
21714
22016
  if (red !== void 0 && green !== void 0 && blue !== void 0) {
21715
- const base = this.rgbToHex(red * 255, green * 255, blue * 255);
22017
+ const base = this.rgbToHex(
22018
+ scrgbLinearToSrgb8(red),
22019
+ scrgbLinearToSrgb8(green),
22020
+ scrgbLinearToSrgb8(blue)
22021
+ );
21716
22022
  return this.applyColorTransforms(base, scrgb);
21717
22023
  }
21718
22024
  }
@@ -21803,8 +22109,8 @@ var PptxColorTransformCodec = class {
21803
22109
  };
21804
22110
  }
21805
22111
  rgbToHex(r, g, b) {
21806
- const toHex3 = (channelValue) => this.clampColorChannel(channelValue).toString(16).padStart(2, "0").toUpperCase();
21807
- return `#${toHex3(r)}${toHex3(g)}${toHex3(b)}`;
22112
+ const toHex4 = (channelValue) => this.clampColorChannel(channelValue).toString(16).padStart(2, "0").toUpperCase();
22113
+ return `#${toHex4(r)}${toHex4(g)}${toHex4(b)}`;
21808
22114
  }
21809
22115
  applyColorTransforms(baseColor, colorNode) {
21810
22116
  return applyDrawingColorTransforms(baseColor, colorNode);
@@ -21892,6 +22198,22 @@ function mergeDrawingFillXml(original, generated, modeledChildren, childOrder2)
21892
22198
  }
21893
22199
 
21894
22200
  // src/core/core/builders/PptxGradientStyleCodec.ts
22201
+ function extractGradientTileRect(gradFill) {
22202
+ const tileRect = drawingChild(gradFill, "tileRect");
22203
+ if (!tileRect) {
22204
+ return void 0;
22205
+ }
22206
+ const toFraction = (raw) => {
22207
+ const parsed = Number.parseInt(String(raw ?? "0"), 10);
22208
+ return Number.isFinite(parsed) ? parsed / 1e5 : 0;
22209
+ };
22210
+ return {
22211
+ l: toFraction(tileRect["@_l"]),
22212
+ t: toFraction(tileRect["@_t"]),
22213
+ r: toFraction(tileRect["@_r"]),
22214
+ b: toFraction(tileRect["@_b"])
22215
+ };
22216
+ }
21895
22217
  var PptxGradientStyleCodec = class {
21896
22218
  context;
21897
22219
  constructor(context) {
@@ -22002,6 +22324,9 @@ var PptxGradientStyleCodec = class {
22002
22324
  b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
22003
22325
  };
22004
22326
  }
22327
+ extractGradientTileRect(gradFill) {
22328
+ return extractGradientTileRect(gradFill);
22329
+ }
22005
22330
  extractGradientFlip(gradFill) {
22006
22331
  const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
22007
22332
  if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
@@ -22173,6 +22498,15 @@ var PptxGradientStyleCodec = class {
22173
22498
  }
22174
22499
  gradientXml["a:lin"] = linNode;
22175
22500
  }
22501
+ if (shapeStyle.fillGradientTileRect) {
22502
+ const tr = shapeStyle.fillGradientTileRect;
22503
+ gradientXml["a:tileRect"] = {
22504
+ "@_l": String(Math.round(tr.l * 1e5)),
22505
+ "@_t": String(Math.round(tr.t * 1e5)),
22506
+ "@_r": String(Math.round(tr.r * 1e5)),
22507
+ "@_b": String(Math.round(tr.b * 1e5))
22508
+ };
22509
+ }
22176
22510
  return mergeDrawingFillXml(
22177
22511
  shapeStyle.fillGradientXml,
22178
22512
  gradientXml,
@@ -23651,7 +23985,7 @@ var PptxColorStyleCodec = class {
23651
23985
  const alphaMod = this.percentAttrToUnit(
23652
23986
  choiceNode["a:alphaMod"]?.["@_val"]
23653
23987
  );
23654
- const alphaOff = this.percentAttrToUnit(
23988
+ const alphaOff = this.signedPercentToUnit(
23655
23989
  choiceNode["a:alphaOff"]?.["@_val"]
23656
23990
  );
23657
23991
  if (alpha === void 0 && alphaMod === void 0 && alphaOff === void 0) {
@@ -23666,6 +24000,18 @@ var PptxColorStyleCodec = class {
23666
24000
  }
23667
24001
  return this.clampUnitInterval(opacity2);
23668
24002
  }
24003
+ /**
24004
+ * Parse an OOXML percentage (thousandths, `100000` = 100%) into a fraction
24005
+ * WITHOUT clamping to [0, 1]. Used for additive offsets like `a:alphaOff`
24006
+ * that legitimately carry negative values.
24007
+ */
24008
+ signedPercentToUnit(value) {
24009
+ const parsed = Number.parseFloat(String(value ?? "").trim());
24010
+ if (!Number.isFinite(parsed)) {
24011
+ return void 0;
24012
+ }
24013
+ return parsed / 1e5;
24014
+ }
23669
24015
  colorWithOpacity(color2, opacity2) {
23670
24016
  if (opacity2 === void 0) {
23671
24017
  return color2;
@@ -23849,10 +24195,12 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
23849
24195
  }
23850
24196
  const hiddenLineFill = hiddenLineProps["a:solidFill"];
23851
24197
  if (hiddenLineFill) {
24198
+ style.strokeFillMode = "solid";
23852
24199
  style.strokeColor = context.parseColor(hiddenLineFill);
23853
24200
  style.strokeOpacity = context.extractColorOpacity(hiddenLineFill);
23854
24201
  }
23855
24202
  } else {
24203
+ style.strokeFillMode = "none";
23856
24204
  style.strokeWidth = 0;
23857
24205
  style.strokeColor = "transparent";
23858
24206
  }
@@ -23870,6 +24218,7 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
23870
24218
  }
23871
24219
  function applyStrokeColor(lineNode, style, context) {
23872
24220
  if (lineNode["a:solidFill"]) {
24221
+ style.strokeFillMode = "solid";
23873
24222
  const lineFill = lineNode["a:solidFill"];
23874
24223
  style.strokeColor = context.parseColor(lineFill);
23875
24224
  style.strokeOpacity = context.extractColorOpacity(lineFill);
@@ -23878,10 +24227,15 @@ function applyStrokeColor(lineNode, style, context) {
23878
24227
  style.strokeColorXml = strokeColorXml;
23879
24228
  }
23880
24229
  } else if (lineNode["a:gradFill"]) {
23881
- style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
23882
- style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
24230
+ style.strokeFillMode = "gradient";
24231
+ const lineGradFill = lineNode["a:gradFill"];
24232
+ style.strokeGradientXml = lineGradFill;
24233
+ style.strokeColor = context.extractGradientFillColor(lineGradFill);
24234
+ style.strokeOpacity = context.extractGradientOpacity(lineGradFill);
23883
24235
  } else if (lineNode["a:pattFill"]) {
24236
+ style.strokeFillMode = "pattern";
23884
24237
  const linePatternFill = lineNode["a:pattFill"];
24238
+ style.strokePatternXml = linePatternFill;
23885
24239
  style.strokeColor = context.parseColor(linePatternFill["a:fgClr"]) || context.parseColor(linePatternFill["a:bgClr"]);
23886
24240
  style.strokeOpacity = context.extractColorOpacity(linePatternFill["a:fgClr"]) || context.extractColorOpacity(linePatternFill["a:bgClr"]);
23887
24241
  }
@@ -24010,6 +24364,10 @@ var PptxShapeStyleExtractor = class {
24010
24364
  style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
24011
24365
  style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
24012
24366
  style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
24367
+ const gradTileRect = extractGradientTileRect(gradFill);
24368
+ if (gradTileRect) {
24369
+ style.fillGradientTileRect = gradTileRect;
24370
+ }
24013
24371
  const gradFlip = this.context.extractGradientFlip(gradFill);
24014
24372
  if (gradFlip) {
24015
24373
  style.fillGradientFlip = gradFlip;
@@ -25203,6 +25561,7 @@ var PptxLoadDataBuilder = class {
25203
25561
  layoutOptions = [];
25204
25562
  headerFooter;
25205
25563
  presentationProperties;
25564
+ viewProperties;
25206
25565
  customShows;
25207
25566
  sections;
25208
25567
  warnings = [];
@@ -25262,6 +25621,10 @@ var PptxLoadDataBuilder = class {
25262
25621
  this.presentationProperties = presentationProperties;
25263
25622
  return this;
25264
25623
  }
25624
+ withViewProperties(viewProperties) {
25625
+ this.viewProperties = viewProperties;
25626
+ return this;
25627
+ }
25265
25628
  withCustomShows(customShows) {
25266
25629
  this.customShows = customShows;
25267
25630
  return this;
@@ -25399,6 +25762,7 @@ var PptxLoadDataBuilder = class {
25399
25762
  layoutOptions: this.layoutOptions,
25400
25763
  headerFooter: this.headerFooter,
25401
25764
  presentationProperties: this.presentationProperties,
25765
+ viewProperties: this.viewProperties,
25402
25766
  customShows: this.customShows,
25403
25767
  sections: this.sections,
25404
25768
  warnings: this.warnings,
@@ -25781,7 +26145,7 @@ var PptxSlideCommentsXmlFactory = class {
25781
26145
  const createdAtIso = this.resolveCreatedAt(comment.createdAt);
25782
26146
  const x = init.saveState.toEmu(comment.x, 0);
25783
26147
  const y = init.saveState.toEmu(comment.y, 0);
25784
- return {
26148
+ const node = {
25785
26149
  ...withoutChildrenByLocalName(comment.rawXml ?? {}, /* @__PURE__ */ new Set(["pos", "text"])),
25786
26150
  "@_authorId": authorId,
25787
26151
  "@_dt": createdAtIso,
@@ -25792,6 +26156,28 @@ var PptxSlideCommentsXmlFactory = class {
25792
26156
  },
25793
26157
  "p:text": String(comment.text || "")
25794
26158
  };
26159
+ this.applyResolvedState(node, comment);
26160
+ return node;
26161
+ }
26162
+ /**
26163
+ * Reflect the (possibly edited) `resolved` flag onto the legacy comment
26164
+ * node. PowerPoint's legacy comment schema has no standard resolved marker,
26165
+ * but the parser reads a non-standard `@_done` / `@_resolved` attribute, so
26166
+ * we re-emit the current state rather than leaving the stale value carried
26167
+ * over from `rawXml`. The original attribute name is preserved when present.
26168
+ */
26169
+ applyResolvedState(node, comment) {
26170
+ const raw = comment.rawXml;
26171
+ const hadResolvedAttr = raw?.["@_resolved"] !== void 0;
26172
+ const hadDoneAttr = raw?.["@_done"] !== void 0;
26173
+ const key = hadResolvedAttr && !hadDoneAttr ? "@_resolved" : "@_done";
26174
+ delete node["@_done"];
26175
+ delete node["@_resolved"];
26176
+ if (comment.resolved === true) {
26177
+ node[key] = "1";
26178
+ } else if (hadResolvedAttr || hadDoneAttr) {
26179
+ node[key] = "0";
26180
+ }
25795
26181
  }
25796
26182
  resolveCreatedAt(createdAt) {
25797
26183
  const candidate = String(createdAt || "").trim();
@@ -26153,6 +26539,94 @@ var PptxCompatibilityService = class {
26153
26539
  }
26154
26540
  };
26155
26541
 
26542
+ // src/core/utils/app-properties-titles.ts
26543
+ var SLIDE_TITLES_NAME = "Slide Titles";
26544
+ function coerceText(value) {
26545
+ if (typeof value === "string") {
26546
+ return value;
26547
+ }
26548
+ if (typeof value === "number" || typeof value === "boolean") {
26549
+ return String(value);
26550
+ }
26551
+ if (isXmlNode(value)) {
26552
+ const text2 = value["#text"];
26553
+ return text2 === void 0 || text2 === null ? "" : String(text2);
26554
+ }
26555
+ return "";
26556
+ }
26557
+ function coerceCount(value) {
26558
+ const parsed = Number.parseInt(coerceText(value), 10);
26559
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
26560
+ }
26561
+ function readLpstrList(vector) {
26562
+ if (!vector) {
26563
+ return [];
26564
+ }
26565
+ const raw = vector["vt:lpstr"];
26566
+ if (raw === void 0 || raw === null) {
26567
+ return [];
26568
+ }
26569
+ return (Array.isArray(raw) ? raw : [raw]).map(coerceText);
26570
+ }
26571
+ function isSlideTitlesCategory(name) {
26572
+ const normalized = name.trim().toLowerCase();
26573
+ return normalized === "slide titles" || normalized.includes("slide") && normalized.includes("title");
26574
+ }
26575
+ function readCategories(headingPairs, titlesOfParts) {
26576
+ const variants = xmlChildren(xmlChild(headingPairs, "vt:vector"), "vt:variant");
26577
+ const entries = readLpstrList(xmlChild(titlesOfParts, "vt:vector"));
26578
+ const categories = [];
26579
+ let offset = 0;
26580
+ for (let i = 0; i + 1 < variants.length; i += 2) {
26581
+ const name = coerceText(variants[i]["vt:lpstr"]);
26582
+ const count = coerceCount(variants[i + 1]["vt:i4"]);
26583
+ categories.push({ name, entries: entries.slice(offset, offset + count) });
26584
+ offset += count;
26585
+ }
26586
+ return categories;
26587
+ }
26588
+ function writeHeadingPairs(appProps, categories) {
26589
+ const variants = [];
26590
+ for (const category of categories) {
26591
+ variants.push({ "vt:lpstr": category.name });
26592
+ variants.push({ "vt:i4": String(category.entries.length) });
26593
+ }
26594
+ appProps["HeadingPairs"] = {
26595
+ "vt:vector": {
26596
+ "@_size": String(variants.length),
26597
+ "@_baseType": "variant",
26598
+ "vt:variant": variants
26599
+ }
26600
+ };
26601
+ }
26602
+ function writeTitlesOfParts(appProps, categories) {
26603
+ const allEntries = categories.flatMap((category) => category.entries);
26604
+ const lpstr = allEntries.map((entry) => ({ "#text": entry }));
26605
+ appProps["TitlesOfParts"] = {
26606
+ "vt:vector": {
26607
+ "@_size": String(allEntries.length),
26608
+ "@_baseType": "lpstr",
26609
+ "vt:lpstr": lpstr
26610
+ }
26611
+ };
26612
+ }
26613
+ function applySlideTitlesToAppProps(appProps, titles) {
26614
+ const headingPairs = xmlChild(appProps, "HeadingPairs");
26615
+ if (!headingPairs) {
26616
+ return;
26617
+ }
26618
+ const titlesOfParts = xmlChild(appProps, "TitlesOfParts");
26619
+ const categories = readCategories(headingPairs, titlesOfParts);
26620
+ const slideCategory = categories.find((category) => isSlideTitlesCategory(category.name));
26621
+ if (slideCategory) {
26622
+ slideCategory.entries = titles;
26623
+ } else {
26624
+ categories.push({ name: SLIDE_TITLES_NAME, entries: titles });
26625
+ }
26626
+ writeHeadingPairs(appProps, categories);
26627
+ writeTitlesOfParts(appProps, categories);
26628
+ }
26629
+
26156
26630
  // src/core/services/PptxDocumentPropertiesUpdater.ts
26157
26631
  var PptxDocumentPropertiesUpdater = class {
26158
26632
  context;
@@ -26216,6 +26690,7 @@ var PptxDocumentPropertiesUpdater = class {
26216
26690
  appProps["Slides"] = String(slides.length);
26217
26691
  appProps["HiddenSlides"] = String(hiddenSlidesCount);
26218
26692
  appProps["Notes"] = String(notesCount);
26693
+ this.updateSlideTitleProperties(appProps, slides);
26219
26694
  appData["Properties"] = appProps;
26220
26695
  this.context.zip.file("docProps/app.xml", this.context.builder.build(appData));
26221
26696
  } catch (error) {
@@ -26258,6 +26733,15 @@ var PptxDocumentPropertiesUpdater = class {
26258
26733
  }
26259
26734
  }
26260
26735
  }
26736
+ /**
26737
+ * Recompute `TitlesOfParts` / `HeadingPairs` from the current slide set so
26738
+ * the per-slide title list in `app.xml` stays consistent after slides are
26739
+ * added, removed, or retitled. Delegates the vector rebuild to a pure
26740
+ * helper; here we only derive the ordered titles.
26741
+ */
26742
+ updateSlideTitleProperties(appProps, slides) {
26743
+ applySlideTitlesToAppProps(appProps, deriveSlideTitles(slides));
26744
+ }
26261
26745
  applyAppPropertiesOverrides(appProps, overrides) {
26262
26746
  if (!overrides) {
26263
26747
  return;
@@ -27877,6 +28361,16 @@ function extractChildKeyframes(childTnList) {
27877
28361
  }
27878
28362
  return void 0;
27879
28363
  }
28364
+ function parseTimingPercentFraction(raw) {
28365
+ if (raw === void 0 || raw === null) {
28366
+ return void 0;
28367
+ }
28368
+ const parsed = Number.parseInt(String(raw), 10);
28369
+ if (!Number.isFinite(parsed) || parsed <= 0) {
28370
+ return void 0;
28371
+ }
28372
+ return Math.min(1, parsed / 1e5);
28373
+ }
27880
28374
  function extractRepeatInfo(cTn) {
27881
28375
  let repeatCount;
27882
28376
  let autoReverse;
@@ -28358,6 +28852,8 @@ var PptxNativeAnimationService = class {
28358
28852
  const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
28359
28853
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
28360
28854
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
28855
+ const accel = parseTimingPercentFraction(cTn["@_accel"]);
28856
+ const decel = parseTimingPercentFraction(cTn["@_decel"]);
28361
28857
  let trigger = currentTrigger;
28362
28858
  if (nodeType === "afterPrevious" || nodeType === "afterPrev") {
28363
28859
  trigger = "afterPrevious";
@@ -28410,6 +28906,8 @@ var PptxNativeAnimationService = class {
28410
28906
  presetSubtype,
28411
28907
  durationMs,
28412
28908
  delayMs,
28909
+ accel,
28910
+ decel,
28413
28911
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
28414
28912
  motionPath: childMotion.motionPath,
28415
28913
  motionOrigin: childMotion.motionOrigin,
@@ -32168,6 +32666,128 @@ function applySmartArtConnectionAttributes(xml, connection, fallbackModelId) {
32168
32666
  applyNullableAttribute(xml, "@_presId", connection.presentationId);
32169
32667
  }
32170
32668
 
32669
+ // src/core/utils/smartart-color-lists.ts
32670
+ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
32671
+ "srgbClr",
32672
+ "schemeClr",
32673
+ "scrgbClr",
32674
+ "sysClr",
32675
+ "prstClr",
32676
+ "hslClr"
32677
+ ]);
32678
+ var COLOR_METHODS2 = /* @__PURE__ */ new Set(["span", "cycle", "repeat"]);
32679
+ var HUE_DIRECTIONS2 = /* @__PURE__ */ new Set(["cw", "ccw"]);
32680
+ var PRIMARY_LABEL_PRIORITY = ["node0", "node1", "node2", "node3", "node4", "node"];
32681
+ function localNameOf3(key) {
32682
+ const idx = key.indexOf(":");
32683
+ return idx >= 0 ? key.slice(idx + 1) : key;
32684
+ }
32685
+ function parseSmartArtColorListHexes(list, deps) {
32686
+ if (!list) {
32687
+ return [];
32688
+ }
32689
+ const out = [];
32690
+ for (const [key, value] of Object.entries(list)) {
32691
+ if (key.startsWith("@_")) {
32692
+ continue;
32693
+ }
32694
+ const local = localNameOf3(key);
32695
+ if (!COLOR_LOCAL_NAMES.has(local)) {
32696
+ continue;
32697
+ }
32698
+ const nodes = Array.isArray(value) ? value : [value];
32699
+ for (const node of nodes) {
32700
+ if (!node || typeof node !== "object") {
32701
+ continue;
32702
+ }
32703
+ const wrapper = { [`a:${local}`]: node };
32704
+ const hex10 = deps.parseColorChoice(wrapper) ?? deps.resolveScheme(node);
32705
+ if (hex10) {
32706
+ out.push(hex10);
32707
+ }
32708
+ }
32709
+ }
32710
+ return out;
32711
+ }
32712
+ function listInterpolation(list) {
32713
+ if (!list) {
32714
+ return void 0;
32715
+ }
32716
+ const method = String(list["@_meth"] ?? "").trim();
32717
+ const hueDir = String(list["@_hueDir"] ?? "").trim();
32718
+ const meta = {};
32719
+ if (COLOR_METHODS2.has(method)) {
32720
+ meta.method = method;
32721
+ }
32722
+ if (HUE_DIRECTIONS2.has(hueDir)) {
32723
+ meta.hueDirection = hueDir;
32724
+ }
32725
+ return meta.method || meta.hueDirection ? meta : void 0;
32726
+ }
32727
+ function parseLabel(lbl, deps) {
32728
+ const fillList = deps.getChild(lbl, "fillClrLst");
32729
+ const lineList = deps.getChild(lbl, "linClrLst");
32730
+ return {
32731
+ name: String(lbl["@_name"] ?? "").trim(),
32732
+ fill: parseSmartArtColorListHexes(fillList, deps),
32733
+ line: parseSmartArtColorListHexes(lineList, deps),
32734
+ textFill: parseSmartArtColorListHexes(deps.getChild(lbl, "txFillClrLst"), deps),
32735
+ textLine: parseSmartArtColorListHexes(deps.getChild(lbl, "txLinClrLst"), deps),
32736
+ effect: parseSmartArtColorListHexes(deps.getChild(lbl, "effectClrLst"), deps),
32737
+ textEffect: parseSmartArtColorListHexes(deps.getChild(lbl, "txEffectClrLst"), deps),
32738
+ fillInterpolation: listInterpolation(fillList),
32739
+ lineInterpolation: listInterpolation(lineList)
32740
+ };
32741
+ }
32742
+ function selectPrimary(parsed) {
32743
+ const byName = new Map(parsed.map((p) => [p.name, p]));
32744
+ for (const name of PRIMARY_LABEL_PRIORITY) {
32745
+ const candidate = byName.get(name);
32746
+ if (candidate && candidate.fill.length > 0) {
32747
+ return candidate;
32748
+ }
32749
+ }
32750
+ for (const name of PRIMARY_LABEL_PRIORITY) {
32751
+ const candidate = byName.get(name);
32752
+ if (candidate && (candidate.line.length > 0 || candidate.fill.length > 0)) {
32753
+ return candidate;
32754
+ }
32755
+ }
32756
+ return parsed.find((p) => p.fill.length > 0) ?? parsed.find((p) => p.line.length > 0);
32757
+ }
32758
+ function buildSmartArtColorLists(styleLbls, deps) {
32759
+ const parsed = styleLbls.map((lbl) => parseLabel(lbl, deps));
32760
+ const primary = selectPrimary(parsed);
32761
+ let fillColors = primary?.fill ?? [];
32762
+ let lineColors = primary?.line ?? [];
32763
+ if (fillColors.length === 0) {
32764
+ fillColors = parsed.map((p) => p.fill[0]).filter((c) => Boolean(c));
32765
+ }
32766
+ if (lineColors.length === 0) {
32767
+ lineColors = parsed.map((p) => p.line[0]).filter((c) => Boolean(c));
32768
+ }
32769
+ const result = { fillColors, lineColors };
32770
+ if (primary?.textFill.length) {
32771
+ result.textFillColors = primary.textFill;
32772
+ }
32773
+ if (primary?.textLine.length) {
32774
+ result.textLineColors = primary.textLine;
32775
+ }
32776
+ if (primary?.effect.length) {
32777
+ result.effectColors = primary.effect;
32778
+ }
32779
+ if (primary?.textEffect.length) {
32780
+ result.textEffectColors = primary.textEffect;
32781
+ }
32782
+ if (primary?.fillInterpolation) {
32783
+ result.fillInterpolation = primary.fillInterpolation;
32784
+ }
32785
+ if (primary?.lineInterpolation) {
32786
+ result.lineInterpolation = primary.lineInterpolation;
32787
+ }
32788
+ return result;
32789
+ }
32790
+
32171
32791
  // src/core/utils/modern-comment-constants.ts
32172
32792
  var MODERN_COMMENT_NAMESPACE = "http://schemas.microsoft.com/office/powerpoint/2018/8/main";
32173
32793
  var MODERN_COMMENT_RELATIONSHIP = "http://schemas.microsoft.com/office/2018/10/relationships/comments";
@@ -34474,6 +35094,28 @@ function buildGeneratedChartAxis(axId, crossId, pos2, formatting) {
34474
35094
  return axis;
34475
35095
  }
34476
35096
 
35097
+ // src/core/utils/chart-xml-container-map.ts
35098
+ var CONTAINER_MAP = {
35099
+ pie: { tag: "c:pieChart", family: "pie" },
35100
+ pie3D: { tag: "c:pie3DChart", family: "pie" },
35101
+ ofPie: { tag: "c:ofPieChart", family: "ofPie" },
35102
+ doughnut: { tag: "c:doughnutChart", family: "doughnut" },
35103
+ scatter: { tag: "c:scatterChart", family: "scatter" },
35104
+ bubble: { tag: "c:bubbleChart", family: "bubble" },
35105
+ line: { tag: "c:lineChart", family: "line" },
35106
+ line3D: { tag: "c:line3DChart", family: "line" },
35107
+ area: { tag: "c:areaChart", family: "area" },
35108
+ area3D: { tag: "c:area3DChart", family: "area" },
35109
+ radar: { tag: "c:radarChart", family: "radar" },
35110
+ stock: { tag: "c:stockChart", family: "stock" },
35111
+ surface: { tag: "c:surfaceChart", family: "surface" },
35112
+ bar: { tag: "c:barChart", family: "bar" },
35113
+ bar3D: { tag: "c:bar3DChart", family: "bar" }
35114
+ };
35115
+ function resolveChartContainerType(type) {
35116
+ return CONTAINER_MAP[type] ?? { tag: "c:barChart", family: "bar" };
35117
+ }
35118
+
34477
35119
  // src/core/utils/chart-xml-generator.ts
34478
35120
  var NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
34479
35121
  var NS_A2 = "http://schemas.openxmlformats.org/drawingml/2006/main";
@@ -34504,29 +35146,6 @@ function strLit(values) {
34504
35146
  }
34505
35147
  };
34506
35148
  }
34507
- function resolveType(type) {
34508
- switch (type) {
34509
- case "pie":
34510
- case "pie3D":
34511
- return { tag: "c:pieChart", family: "pie" };
34512
- case "doughnut":
34513
- return { tag: "c:doughnutChart", family: "doughnut" };
34514
- case "scatter":
34515
- return { tag: "c:scatterChart", family: "scatter" };
34516
- case "bubble":
34517
- return { tag: "c:bubbleChart", family: "bubble" };
34518
- case "line":
34519
- case "line3D":
34520
- return { tag: "c:lineChart", family: "line" };
34521
- case "area":
34522
- case "area3D":
34523
- return { tag: "c:areaChart", family: "area" };
34524
- case "radar":
34525
- return { tag: "c:radarChart", family: "radar" };
34526
- default:
34527
- return { tag: "c:barChart", family: "bar" };
34528
- }
34529
- }
34530
35149
  function fillSpPr(color2, asLine) {
34531
35150
  const h = hex6(color2);
34532
35151
  if (!h) {
@@ -34594,7 +35213,10 @@ function buildChartTypeContainer(chartData, family) {
34594
35213
  } else if (family === "scatter") {
34595
35214
  container["c:scatterStyle"] = { "@_val": "lineMarker" };
34596
35215
  container["c:varyColors"] = { "@_val": "0" };
34597
- } else {
35216
+ } else if (family === "ofPie") {
35217
+ container["c:ofPieType"] = { "@_val": "pie" };
35218
+ container["c:varyColors"] = { "@_val": "1" };
35219
+ } else if (family === "stock" || family === "surface") ; else {
34598
35220
  container["c:varyColors"] = { "@_val": family === "bubble" ? "0" : "1" };
34599
35221
  }
34600
35222
  container["c:ser"] = chartData.series.map(
@@ -34606,12 +35228,13 @@ function buildChartTypeContainer(chartData, family) {
34606
35228
  if (family === "line" && chartData.upDownBars !== void 0) {
34607
35229
  applyChartUpDownBars(container, chartData.upDownBars, (key) => key.replace(/^.*:/u, ""));
34608
35230
  }
34609
- if (family === "bar") {
35231
+ if (family === "bar" || family === "ofPie") {
34610
35232
  container["c:gapWidth"] = { "@_val": "150" };
34611
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
34612
- } else if (family === "line" || family === "area" || family === "radar") {
34613
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
34614
- } else if (family === "scatter" || family === "bubble") {
35233
+ }
35234
+ if (family === "stock") {
35235
+ container["c:hiLowLines"] = {};
35236
+ }
35237
+ if (family === "bar" || family === "line" || family === "area" || family === "radar" || family === "scatter" || family === "bubble" || family === "stock" || family === "surface") {
34615
35238
  container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
34616
35239
  } else if (family === "doughnut") {
34617
35240
  container["c:holeSize"] = { "@_val": "50" };
@@ -34624,7 +35247,8 @@ function buildPlotArea(chartData, tag, family) {
34624
35247
  if (chartData.style) {
34625
35248
  applyChartDataLabelsToXml(plotArea, chartData.style, (key) => key.replace(/^.*:/u, ""));
34626
35249
  }
34627
- if (family !== "pie" && family !== "doughnut" && SCATTER_LIKE.has(chartData.chartType)) {
35250
+ const hasAxes = family !== "pie" && family !== "doughnut" && family !== "ofPie";
35251
+ if (hasAxes && SCATTER_LIKE.has(chartData.chartType)) {
34628
35252
  plotArea["c:valAx"] = [
34629
35253
  buildGeneratedChartAxis(
34630
35254
  CAT_AX_ID,
@@ -34639,7 +35263,7 @@ function buildPlotArea(chartData, tag, family) {
34639
35263
  axisFormatting(chartData, "valAx", VAL_AX_ID, 1)
34640
35264
  )
34641
35265
  ];
34642
- } else if (family !== "pie" && family !== "doughnut") {
35266
+ } else if (hasAxes) {
34643
35267
  const dateAxis = chartData.dateCategories ? axisFormatting(chartData, "dateAx", CAT_AX_ID) : void 0;
34644
35268
  plotArea[dateAxis ? "c:dateAx" : "c:catAx"] = buildGeneratedChartAxis(
34645
35269
  CAT_AX_ID,
@@ -34658,7 +35282,7 @@ function buildPlotArea(chartData, tag, family) {
34658
35282
  return plotArea;
34659
35283
  }
34660
35284
  function buildChartSpaceXml(chartData) {
34661
- const { tag, family } = resolveType(chartData.chartType);
35285
+ const { tag, family } = resolveChartContainerType(chartData.chartType);
34662
35286
  const chart = {};
34663
35287
  if (chartData.title) {
34664
35288
  chart["c:title"] = {
@@ -36590,6 +37214,7 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
36590
37214
  let playbackSpeed;
36591
37215
  let trimStartMs;
36592
37216
  let trimEndMs;
37217
+ let embedRId;
36593
37218
  const bookmarks = [];
36594
37219
  const extLst = mediaNode["p:extLst"] ?? cMediaNode["p:extLst"];
36595
37220
  if (extLst) {
@@ -36597,6 +37222,13 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
36597
37222
  for (const ext of exts) {
36598
37223
  const p14Media = ext["p14:media"];
36599
37224
  if (p14Media) {
37225
+ if (embedRId === void 0) {
37226
+ const embedRaw = p14Media["@_r:embed"] ?? p14Media["@_embed"];
37227
+ const embedStr = embedRaw === void 0 ? "" : String(embedRaw).trim();
37228
+ if (embedStr.length > 0) {
37229
+ embedRId = embedStr;
37230
+ }
37231
+ }
36600
37232
  const p14Trim = p14Media["p14:trim"];
36601
37233
  if (p14Trim) {
36602
37234
  const st = p14Trim["@_st"];
@@ -36666,7 +37298,8 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
36666
37298
  fadeInDuration,
36667
37299
  fadeOutDuration,
36668
37300
  playbackSpeed,
36669
- bookmarks
37301
+ bookmarks,
37302
+ embedRId
36670
37303
  };
36671
37304
  }
36672
37305
 
@@ -36896,6 +37529,12 @@ var PptxHandlerRuntime = class {
36896
37529
  loadedEmbeddedFonts = [];
36897
37530
  /** Typed source metadata for lossless embedded-font list round trips. */
36898
37531
  loadedEmbeddedFontList;
37532
+ /**
37533
+ * View properties parsed from `ppt/viewProps.xml` during load, preserved so
37534
+ * an unmodified load -> save round-trips the typed model and callers that do
37535
+ * not override `saveOptions.viewProperties` still persist the loaded state.
37536
+ */
37537
+ loadedViewProperties;
36899
37538
  /** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
36900
37539
  commentAuthorMap = /* @__PURE__ */ new Map();
36901
37540
  /** Full comment author details keyed by author ID, preserving initials/lastIdx/clrIdx for round-trip. */
@@ -37122,19 +37761,179 @@ function parseTableStyleBorders(tcStyle) {
37122
37761
  return has ? result : void 0;
37123
37762
  }
37124
37763
 
37764
+ // src/core/core/runtime/table-style-fill-parse.ts
37765
+ function toHex3(raw) {
37766
+ const hex10 = String(raw ?? "").trim();
37767
+ if (!hex10) {
37768
+ return void 0;
37769
+ }
37770
+ return hex10.startsWith("#") ? hex10 : `#${hex10}`;
37771
+ }
37772
+ function parseColorChoiceFill(node) {
37773
+ if (!node) {
37774
+ return void 0;
37775
+ }
37776
+ const scheme = parseSolidFillStyle(node);
37777
+ if (scheme) {
37778
+ return scheme;
37779
+ }
37780
+ const srgb = node["a:srgbClr"];
37781
+ const color2 = toHex3(srgb?.["@_val"]);
37782
+ if (!color2) {
37783
+ return void 0;
37784
+ }
37785
+ const fill = { schemeColor: "", color: color2 };
37786
+ const tintRaw = srgb?.["a:tint"];
37787
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
37788
+ if (tint !== void 0) {
37789
+ fill.tint = tint;
37790
+ }
37791
+ const shadeRaw = srgb?.["a:shade"];
37792
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
37793
+ if (shade !== void 0) {
37794
+ fill.shade = shade;
37795
+ }
37796
+ return fill;
37797
+ }
37798
+ function parseGradientFill(gradFill) {
37799
+ const gsLst = gradFill["a:gsLst"];
37800
+ const rawStops = gsLst?.["a:gs"];
37801
+ const gsNodes = Array.isArray(rawStops) ? rawStops : rawStops ? [rawStops] : [];
37802
+ const stops = [];
37803
+ for (const gs of gsNodes) {
37804
+ const fill = parseColorChoiceFill(gs);
37805
+ if (!fill) {
37806
+ continue;
37807
+ }
37808
+ const position2 = (parseInt(String(gs["@_pos"] || "0"), 10) || 0) / 1e3;
37809
+ stops.push({ position: position2, fill });
37810
+ }
37811
+ if (stops.length === 0) {
37812
+ return void 0;
37813
+ }
37814
+ const lin = gradFill["a:lin"];
37815
+ if (lin) {
37816
+ const angRaw = parseInt(String(lin["@_ang"] || "0"), 10) || 0;
37817
+ const angle = (angRaw / 6e4 % 360 + 360) % 360;
37818
+ return { stops, angle, type: "linear" };
37819
+ }
37820
+ if (gradFill["a:path"] !== void 0) {
37821
+ return { stops, type: "radial" };
37822
+ }
37823
+ return { stops, type: "linear" };
37824
+ }
37825
+ function parsePatternFill(pattFill) {
37826
+ const preset = String(pattFill["@_prst"] || "").trim();
37827
+ if (!preset) {
37828
+ return void 0;
37829
+ }
37830
+ const pattern = { preset };
37831
+ const foreground = parseColorChoiceFill(pattFill["a:fgClr"]);
37832
+ if (foreground) {
37833
+ pattern.foreground = foreground;
37834
+ }
37835
+ const background = parseColorChoiceFill(pattFill["a:bgClr"]);
37836
+ if (background) {
37837
+ pattern.background = background;
37838
+ }
37839
+ return pattern;
37840
+ }
37841
+ function parseTableStyleSectionFill(section) {
37842
+ if (!section) {
37843
+ return void 0;
37844
+ }
37845
+ const tcStyle = section["a:tcStyle"];
37846
+ const fillWrap = tcStyle?.["a:fill"];
37847
+ if (!fillWrap) {
37848
+ return void 0;
37849
+ }
37850
+ if (fillWrap["a:noFill"] !== void 0) {
37851
+ return { schemeColor: "", noFill: true };
37852
+ }
37853
+ const solid = fillWrap["a:solidFill"];
37854
+ if (solid) {
37855
+ return parseColorChoiceFill(solid);
37856
+ }
37857
+ const grad = fillWrap["a:gradFill"];
37858
+ if (grad) {
37859
+ const gradient = parseGradientFill(grad);
37860
+ if (gradient) {
37861
+ return { schemeColor: "", gradient };
37862
+ }
37863
+ }
37864
+ const patt = fillWrap["a:pattFill"];
37865
+ if (patt) {
37866
+ const pattern = parsePatternFill(patt);
37867
+ if (pattern) {
37868
+ return { schemeColor: "", pattern };
37869
+ }
37870
+ }
37871
+ return void 0;
37872
+ }
37873
+ function parseTableStyleSectionText(section) {
37874
+ const tcTxStyle = section?.["a:tcTxStyle"];
37875
+ if (!tcTxStyle) {
37876
+ return void 0;
37877
+ }
37878
+ const result = {};
37879
+ let hasProps = false;
37880
+ if (tcTxStyle["@_b"] === "on") {
37881
+ result.bold = true;
37882
+ hasProps = true;
37883
+ }
37884
+ if (tcTxStyle["@_i"] === "on") {
37885
+ result.italic = true;
37886
+ hasProps = true;
37887
+ }
37888
+ const underline = String(tcTxStyle["@_u"] || "").trim();
37889
+ if (underline && underline !== "none") {
37890
+ result.underline = true;
37891
+ hasProps = true;
37892
+ }
37893
+ const font = tcTxStyle["a:font"];
37894
+ const face = font ? String(font["@_typeface"] || "").trim() : "";
37895
+ if (face) {
37896
+ result.fontFace = face;
37897
+ hasProps = true;
37898
+ }
37899
+ const fontRef = tcTxStyle["a:fontRef"];
37900
+ const idx = fontRef ? String(fontRef["@_idx"] || "").trim() : "";
37901
+ if (idx) {
37902
+ result.fontRefIdx = idx;
37903
+ hasProps = true;
37904
+ }
37905
+ const schemeClr = fontRef?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
37906
+ if (schemeClr) {
37907
+ const val = String(schemeClr["@_val"] || "").trim();
37908
+ if (val) {
37909
+ result.fontSchemeColor = val;
37910
+ hasProps = true;
37911
+ const tintNode = schemeClr["a:tint"];
37912
+ if (tintNode) {
37913
+ result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
37914
+ }
37915
+ const shadeNode = schemeClr["a:shade"];
37916
+ if (shadeNode) {
37917
+ result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
37918
+ }
37919
+ }
37920
+ } else {
37921
+ const srgb = fontRef?.["a:srgbClr"] ?? tcTxStyle["a:srgbClr"];
37922
+ const hex10 = toHex3(srgb?.["@_val"]);
37923
+ if (hex10) {
37924
+ result.fontColor = hex10;
37925
+ hasProps = true;
37926
+ }
37927
+ }
37928
+ return hasProps ? result : void 0;
37929
+ }
37930
+
37125
37931
  // src/core/core/runtime/PptxHandlerRuntimeTableStyles.ts
37126
37932
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
37127
37933
  /**
37128
- * Export slides to a raster/vector format.
37129
- *
37130
- * This is a stub that signals export intent. Actual rendering requires a
37131
- * platform-specific canvas or PDF library (e.g. Puppeteer, node-canvas,
37132
- * pdfkit). Host applications should override or extend this method with
37133
- * their own rendering pipeline.
37134
- *
37135
- * @param _slides The slides to export.
37136
- * @param _options Export options (format, DPI, slide indices, etc.).
37137
- * @returns A map of slide index → exported binary data.
37934
+ * Export slides to a raster/vector format. This is a stub that signals
37935
+ * export intent; actual rendering requires a platform-specific canvas or
37936
+ * PDF backend that host applications wire in by overriding this method.
37138
37937
  */
37139
37938
  async exportSlides(slides, options) {
37140
37939
  this.compatibilityService.reportWarning({
@@ -37199,15 +37998,11 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
37199
37998
  }
37200
37999
  /**
37201
38000
  * Extract fill information from a table style section element
37202
- * (e.g. `a:wholeTbl`, `a:band1H`, `a:firstRow`).
38001
+ * (e.g. `a:wholeTbl`, `a:band1H`, `a:firstRow`). Handles scheme + sRGB
38002
+ * solids, gradients, preset patterns, and `a:noFill` (issue #95).
37203
38003
  */
37204
38004
  extractTableStyleSectionFill(section) {
37205
- if (!section) {
37206
- return void 0;
37207
- }
37208
- const tcStyle = section["a:tcStyle"];
37209
- const fill = tcStyle?.["a:fill"];
37210
- return parseSolidFillStyle(fill?.["a:solidFill"]);
38005
+ return parseTableStyleSectionFill(section);
37211
38006
  }
37212
38007
  /**
37213
38008
  * Extract border styling from a table style section's
@@ -37217,44 +38012,12 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
37217
38012
  return parseTableStyleBorders(section?.["a:tcStyle"]);
37218
38013
  }
37219
38014
  /**
37220
- * Extract text properties from a:tcTxStyle in a table style section.
38015
+ * Extract text properties from `a:tcTxStyle` in a table style section.
38016
+ * Captures bold/italic/underline, typeface, font-collection index, and the
38017
+ * font colour (scheme or sRGB) (issue #95).
37221
38018
  */
37222
38019
  extractTableStyleSectionText(section) {
37223
- if (!section) {
37224
- return void 0;
37225
- }
37226
- const tcTxStyle = section["a:tcTxStyle"];
37227
- if (!tcTxStyle) {
37228
- return void 0;
37229
- }
37230
- const result = {};
37231
- let hasProps = false;
37232
- if (tcTxStyle["@_b"] === "on") {
37233
- result.bold = true;
37234
- hasProps = true;
37235
- }
37236
- if (tcTxStyle["@_i"] === "on") {
37237
- result.italic = true;
37238
- hasProps = true;
37239
- }
37240
- const fontClr = tcTxStyle["a:fontRef"];
37241
- const schemeClr = fontClr?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
37242
- if (schemeClr) {
37243
- const val = String(schemeClr["@_val"] || "").trim();
37244
- if (val) {
37245
- result.fontSchemeColor = val;
37246
- hasProps = true;
37247
- const tintNode = schemeClr["a:tint"];
37248
- if (tintNode) {
37249
- result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
37250
- }
37251
- const shadeNode = schemeClr["a:shade"];
37252
- if (shadeNode) {
37253
- result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
37254
- }
37255
- }
37256
- }
37257
- return hasProps ? result : void 0;
38020
+ return parseTableStyleSectionText(section);
37258
38021
  }
37259
38022
  ensureArray(val) {
37260
38023
  if (!val) {
@@ -37934,6 +38697,7 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
37934
38697
  );
37935
38698
  const trimStartMs = timing.trimStartMs ?? extData.trimStartMs;
37936
38699
  const trimEndMs = timing.trimEndMs ?? extData.trimEndMs;
38700
+ const mediaEmbedPath = extData.embedRId ? this.resolveRelationshipTarget(slidePath, extData.embedRId) : void 0;
37937
38701
  result.set(shapeId, {
37938
38702
  trimStartMs: trimStartMs !== void 0 && !isNaN(trimStartMs) ? trimStartMs : void 0,
37939
38703
  trimEndMs: trimEndMs !== void 0 && !isNaN(trimEndMs) ? trimEndMs : void 0,
@@ -37947,7 +38711,8 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
37947
38711
  playAcrossSlides: timing.playAcrossSlides || void 0,
37948
38712
  hideWhenNotPlaying: hideWhenNotPlaying || void 0,
37949
38713
  bookmarks: extData.bookmarks.length > 0 ? extData.bookmarks : void 0,
37950
- playbackSpeed: extData.playbackSpeed
38714
+ playbackSpeed: extData.playbackSpeed,
38715
+ mediaEmbedPath
37951
38716
  });
37952
38717
  }
37953
38718
  }
@@ -38123,6 +38888,10 @@ var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
38123
38888
  if (!timing) {
38124
38889
  continue;
38125
38890
  }
38891
+ if (timing.mediaEmbedPath && (typeof el.mediaPath !== "string" || el.mediaPath.length === 0)) {
38892
+ el.mediaPath = timing.mediaEmbedPath;
38893
+ el.mediaMimeType = this.getImageMimeType(timing.mediaEmbedPath);
38894
+ }
38126
38895
  if (timing.trimStartMs !== void 0) {
38127
38896
  el.trimStartMs = timing.trimStartMs;
38128
38897
  }
@@ -39129,7 +39898,7 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
39129
39898
  }
39130
39899
  }
39131
39900
  async reconcilePresentationSlidesForSave(params) {
39132
- await this.presentationSlidesReconciler.reconcile({
39901
+ return await this.presentationSlidesReconciler.reconcile({
39133
39902
  ...params,
39134
39903
  zip: this.zip,
39135
39904
  parser: this.parser,
@@ -39422,6 +40191,31 @@ function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
39422
40191
  }
39423
40192
  return fontNode;
39424
40193
  }
40194
+ function buildUnderlineLineXml(line2) {
40195
+ const uln = {};
40196
+ if (typeof line2.widthEmu === "number" && Number.isFinite(line2.widthEmu)) {
40197
+ uln["@_w"] = String(Math.round(line2.widthEmu));
40198
+ }
40199
+ if (line2.compound) {
40200
+ uln["@_cmpd"] = line2.compound;
40201
+ }
40202
+ if (line2.cap) {
40203
+ uln["@_cap"] = line2.cap;
40204
+ }
40205
+ if (line2.algn) {
40206
+ uln["@_algn"] = line2.algn;
40207
+ }
40208
+ if (line2.prstDash) {
40209
+ uln["a:prstDash"] = { "@_val": line2.prstDash };
40210
+ }
40211
+ if (line2.headEndXml) {
40212
+ uln["a:headEnd"] = line2.headEndXml;
40213
+ }
40214
+ if (line2.tailEndXml) {
40215
+ uln["a:tailEnd"] = line2.tailEndXml;
40216
+ }
40217
+ return uln;
40218
+ }
39425
40219
  var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime11 {
39426
40220
  createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
39427
40221
  const runProps = {
@@ -39442,6 +40236,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39442
40236
  }
39443
40237
  if (style.underline) {
39444
40238
  runProps["@_u"] = style.underlineStyle || "sng";
40239
+ } else if (style.underlineExplicitNone) {
40240
+ runProps["@_u"] = "none";
39445
40241
  }
39446
40242
  if (style.strikethrough !== void 0) {
39447
40243
  runProps["@_strike"] = style.strikethrough ? style.strikeType || "sngStrike" : "noStrike";
@@ -39457,6 +40253,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39457
40253
  }
39458
40254
  if (style.textCaps && style.textCaps !== "none") {
39459
40255
  runProps["@_cap"] = style.textCaps;
40256
+ } else if (style.textCapsExplicitNone) {
40257
+ runProps["@_cap"] = "none";
39460
40258
  }
39461
40259
  if (style.kumimoji !== void 0) {
39462
40260
  runProps["@_kumimoji"] = style.kumimoji ? "1" : "0";
@@ -39565,13 +40363,21 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39565
40363
  runProps["a:effectDag"] = style.textEffectDagXml;
39566
40364
  }
39567
40365
  if (style.highlightColor) {
39568
- runProps["a:highlight"] = {
39569
- "a:srgbClr": {
39570
- "@_val": style.highlightColor.replace("#", "")
39571
- }
39572
- };
40366
+ const resolvedHighlight = style.highlightColorXml ? this.parseColor(style.highlightColorXml) : void 0;
40367
+ runProps["a:highlight"] = serializeColorChoice(
40368
+ style.highlightColorXml,
40369
+ resolvedHighlight,
40370
+ style.highlightColor
40371
+ );
40372
+ }
40373
+ if (style.underlineLineFollowsText) {
40374
+ runProps["a:uLnTx"] = {};
40375
+ } else if (style.underlineLine) {
40376
+ runProps["a:uLn"] = buildUnderlineLineXml(style.underlineLine);
39573
40377
  }
39574
- if (style.underline && style.underlineColor) {
40378
+ if (style.underlineFillFollowsText) {
40379
+ runProps["a:uFillTx"] = {};
40380
+ } else if (style.underline && style.underlineColor) {
39575
40381
  runProps["a:uFill"] = {
39576
40382
  "a:solidFill": {
39577
40383
  "a:srgbClr": {
@@ -39580,21 +40386,28 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39580
40386
  }
39581
40387
  };
39582
40388
  }
39583
- if (style.fontFamily) {
40389
+ const latinFace = style.latinFontThemeToken ?? style.fontFamily;
40390
+ if (latinFace) {
39584
40391
  runProps["a:latin"] = applyFontMetadata(
39585
- { "@_typeface": style.fontFamily },
40392
+ { "@_typeface": latinFace },
39586
40393
  style.latinFontPanose,
39587
40394
  style.latinFontPitchFamily,
39588
40395
  style.latinFontCharset
39589
40396
  );
40397
+ }
40398
+ const eastAsiaFace = style.eastAsiaFontThemeToken ?? style.eastAsiaFont;
40399
+ if (eastAsiaFace) {
39590
40400
  runProps["a:ea"] = applyFontMetadata(
39591
- { "@_typeface": style.eastAsiaFont || style.fontFamily },
40401
+ { "@_typeface": eastAsiaFace },
39592
40402
  style.eastAsiaFontPanose,
39593
40403
  style.eastAsiaFontPitchFamily,
39594
40404
  style.eastAsiaFontCharset
39595
40405
  );
40406
+ }
40407
+ const complexScriptFace = style.complexScriptFontThemeToken ?? style.complexScriptFont;
40408
+ if (complexScriptFace) {
39596
40409
  runProps["a:cs"] = applyFontMetadata(
39597
- { "@_typeface": style.complexScriptFont || style.fontFamily },
40410
+ { "@_typeface": complexScriptFace },
39598
40411
  style.complexScriptFontPanose,
39599
40412
  style.complexScriptFontPitchFamily,
39600
40413
  style.complexScriptFontCharset
@@ -39644,12 +40457,17 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39644
40457
  if (mouseOverTarget.length > 0) {
39645
40458
  const mouseOverRelId = resolveHyperlinkRelationshipId(mouseOverTarget);
39646
40459
  if (mouseOverRelId) {
39647
- runProps["a:hlinkMouseOver"] = {
39648
- "@_r:id": mouseOverRelId
39649
- };
40460
+ const mouseOverNode = { "@_r:id": mouseOverRelId };
40461
+ if (style.hyperlinkMouseOverSoundXml && typeof style.hyperlinkMouseOverSoundXml === "object") {
40462
+ mouseOverNode["a:snd"] = style.hyperlinkMouseOverSoundXml;
40463
+ }
40464
+ runProps["a:hlinkMouseOver"] = mouseOverNode;
39650
40465
  }
39651
40466
  }
39652
40467
  }
40468
+ if (style.runPropertiesExtLstXml && typeof style.runPropertiesExtLstXml === "object") {
40469
+ runProps["a:extLst"] = style.runPropertiesExtLstXml;
40470
+ }
39653
40471
  return runProps;
39654
40472
  }
39655
40473
  applyHyperlinkExtraAttrs(hlinkNode, style) {
@@ -39668,22 +40486,26 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39668
40486
  if (style.hyperlinkEndSound !== void 0) {
39669
40487
  hlinkNode["@_endSnd"] = style.hyperlinkEndSound ? "1" : "0";
39670
40488
  }
40489
+ if (style.hyperlinkSoundXml && typeof style.hyperlinkSoundXml === "object") {
40490
+ hlinkNode["a:snd"] = style.hyperlinkSoundXml;
40491
+ }
39671
40492
  }
39672
40493
  };
39673
40494
 
39674
40495
  // src/core/core/runtime/PptxHandlerRuntimeSaveParagraphs.ts
39675
40496
  var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
39676
40497
  createParagraphsFromTextContent(text2, textStyle, textSegments, resolveHyperlinkRelationshipId) {
39677
- const paragraphAlign = this.textAlignToDrawingValue(textStyle?.align);
39678
- const spacing = {
39679
- spacingBefore: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingBefore),
39680
- spacingAfter: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingAfter),
39681
- lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
39682
- lineSpacingExactPt: textStyle?.lineSpacingExactPt
39683
- };
39684
- const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
40498
+ const createParagraph = (runs, bulletInfo, level, endParaRunProperties, paragraphProperties2) => {
40499
+ const effectiveStyle = paragraphProperties2 ? { ...textStyle, ...paragraphProperties2 } : textStyle;
40500
+ const paragraphAlign = this.textAlignToDrawingValue(effectiveStyle?.align);
40501
+ const spacing = {
40502
+ spacingBefore: this.createParagraphSpacingXmlFromPx(effectiveStyle?.paragraphSpacingBefore),
40503
+ spacingAfter: this.createParagraphSpacingXmlFromPx(effectiveStyle?.paragraphSpacingAfter),
40504
+ lineSpacing: this.createLineSpacingXmlFromMultiplier(effectiveStyle?.lineSpacing),
40505
+ lineSpacingExactPt: effectiveStyle?.lineSpacingExactPt
40506
+ };
39685
40507
  const paragraphProps = buildParagraphPropertiesXml(
39686
- textStyle,
40508
+ effectiveStyle,
39687
40509
  paragraphAlign,
39688
40510
  bulletInfo,
39689
40511
  spacing,
@@ -39695,12 +40517,22 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
39695
40517
  "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
39696
40518
  "a:t": runText
39697
40519
  });
39698
- const createFieldRun = (runText, style, fieldType, fieldGuid) => ({
39699
- "@_type": fieldType,
39700
- ...fieldGuid ? { "@_id": fieldGuid } : {},
39701
- "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
39702
- "a:t": runText
39703
- });
40520
+ const createFieldRun = (runText, style, fieldType, fieldGuid, fieldGuidAttr, fieldParagraphPropertiesXml) => {
40521
+ const fld = { "@_type": fieldType };
40522
+ if (fieldGuid) {
40523
+ if (fieldGuidAttr === "uuid") {
40524
+ fld["@_uuid"] = fieldGuid;
40525
+ } else {
40526
+ fld["@_id"] = fieldGuid;
40527
+ }
40528
+ }
40529
+ fld["a:rPr"] = this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId);
40530
+ if (fieldParagraphPropertiesXml && typeof fieldParagraphPropertiesXml === "object") {
40531
+ fld["a:pPr"] = fieldParagraphPropertiesXml;
40532
+ }
40533
+ fld["a:t"] = runText;
40534
+ return fld;
40535
+ };
39704
40536
  const createRubyRun = (segment, style) => {
39705
40537
  const rubyPr = {};
39706
40538
  if (segment.rubyAlignment) {
@@ -39739,17 +40571,27 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
39739
40571
  let currentBulletInfo;
39740
40572
  let currentLevel;
39741
40573
  let currentEndParaRunProperties;
40574
+ let currentParagraphProperties;
40575
+ let capturedParagraphMeta = false;
39742
40576
  const pushParagraph = () => {
39743
40577
  if (currentRuns.length === 0) {
39744
40578
  currentRuns.push(createRun("", textStyle));
39745
40579
  }
39746
40580
  paragraphs.push(
39747
- createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
40581
+ createParagraph(
40582
+ currentRuns,
40583
+ currentBulletInfo,
40584
+ currentLevel,
40585
+ currentEndParaRunProperties,
40586
+ currentParagraphProperties
40587
+ )
39748
40588
  );
39749
40589
  currentRuns = [];
39750
40590
  currentBulletInfo = void 0;
39751
40591
  currentLevel = void 0;
39752
40592
  currentEndParaRunProperties = void 0;
40593
+ currentParagraphProperties = void 0;
40594
+ capturedParagraphMeta = false;
39753
40595
  };
39754
40596
  if (textSegments && textSegments.length > 0) {
39755
40597
  const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
@@ -39759,7 +40601,7 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
39759
40601
  ...segment.style,
39760
40602
  ...uniformSegmentOverrides
39761
40603
  };
39762
- if (currentRuns.length === 0) {
40604
+ if (!capturedParagraphMeta) {
39763
40605
  if (segment.bulletInfo) {
39764
40606
  currentBulletInfo = segment.bulletInfo;
39765
40607
  }
@@ -39769,6 +40611,10 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
39769
40611
  if (segment.endParaRunProperties) {
39770
40612
  currentEndParaRunProperties = segment.endParaRunProperties;
39771
40613
  }
40614
+ if (segment.paragraphProperties) {
40615
+ currentParagraphProperties = segment.paragraphProperties;
40616
+ }
40617
+ capturedParagraphMeta = true;
39772
40618
  }
39773
40619
  if (segment.isLineBreak) {
39774
40620
  const brNode = {};
@@ -39803,7 +40649,9 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
39803
40649
  linePart,
39804
40650
  segmentStyle,
39805
40651
  segment.fieldType,
39806
- segment.fieldGuid
40652
+ segment.fieldGuid,
40653
+ segment.fieldGuidAttr,
40654
+ segment.fieldParagraphPropertiesXml
39807
40655
  );
39808
40656
  fieldRun.__isField = true;
39809
40657
  currentRuns.push(fieldRun);
@@ -40568,7 +41416,95 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
40568
41416
  };
40569
41417
 
40570
41418
  // src/core/core/runtime/PptxHandlerRuntimeTextStyleUtils.ts
41419
+ var SCRIPT_CANDIDATES = {
41420
+ cjk: ["Hans", "Hant", "Jpan", "Hang"],
41421
+ kana: ["Jpan", "Hans", "Hant"],
41422
+ hangul: ["Hang"],
41423
+ arabic: ["Arab"],
41424
+ hebrew: ["Hebr"],
41425
+ thai: ["Thai"]
41426
+ };
41427
+ function aggregateFontScriptOverrides(perPathMap) {
41428
+ const aggregate = {};
41429
+ for (const overrides of perPathMap.values()) {
41430
+ for (const [script, typeface] of Object.entries(overrides)) {
41431
+ if (!(script in aggregate)) {
41432
+ aggregate[script] = typeface;
41433
+ }
41434
+ }
41435
+ }
41436
+ return aggregate;
41437
+ }
41438
+ function detectDominantScript(text2) {
41439
+ const counts = {};
41440
+ for (const ch of text2) {
41441
+ const code = ch.codePointAt(0) ?? 0;
41442
+ let cat;
41443
+ if (code >= 4352 && code <= 4607) {
41444
+ cat = "hangul";
41445
+ } else if (code >= 44032 && code <= 55215) {
41446
+ cat = "hangul";
41447
+ } else if (code >= 12352 && code <= 12543) {
41448
+ cat = "kana";
41449
+ } else if (code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903 || code >= 63744 && code <= 64255) {
41450
+ cat = "cjk";
41451
+ } else if (code >= 1536 && code <= 1791) {
41452
+ cat = "arabic";
41453
+ } else if (code >= 1424 && code <= 1535) {
41454
+ cat = "hebrew";
41455
+ } else if (code >= 3584 && code <= 3711) {
41456
+ cat = "thai";
41457
+ }
41458
+ if (cat) {
41459
+ counts[cat] = (counts[cat] ?? 0) + 1;
41460
+ }
41461
+ }
41462
+ let best;
41463
+ let bestCount = 0;
41464
+ for (const [cat, count] of Object.entries(counts)) {
41465
+ if (count > bestCount) {
41466
+ best = cat;
41467
+ bestCount = count;
41468
+ }
41469
+ }
41470
+ return best;
41471
+ }
40571
41472
  var PptxHandlerRuntime17 = class extends PptxHandlerRuntime16 {
41473
+ /**
41474
+ * Resolve the automatic per-script fallback face for a run's text from the
41475
+ * theme's `<a:font script="...">` overrides (#83). Body (minor) fonts win
41476
+ * over heading (major) fonts. Returns `undefined` when the deck declares no
41477
+ * script overrides or the text needs no fallback.
41478
+ */
41479
+ resolveScriptFallbackFont(text2) {
41480
+ if (!text2) {
41481
+ return void 0;
41482
+ }
41483
+ if (this.masterThemeMinorFontScripts.size === 0 && this.masterThemeMajorFontScripts.size === 0) {
41484
+ return void 0;
41485
+ }
41486
+ const category = detectDominantScript(text2);
41487
+ if (!category) {
41488
+ return void 0;
41489
+ }
41490
+ const candidates = SCRIPT_CANDIDATES[category];
41491
+ if (!candidates) {
41492
+ return void 0;
41493
+ }
41494
+ const minor = aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
41495
+ for (const key of candidates) {
41496
+ if (minor[key]) {
41497
+ return minor[key];
41498
+ }
41499
+ }
41500
+ const major = aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
41501
+ for (const key of candidates) {
41502
+ if (major[key]) {
41503
+ return major[key];
41504
+ }
41505
+ }
41506
+ return void 0;
41507
+ }
40572
41508
  textStylesEqual(left, right) {
40573
41509
  const keys = [
40574
41510
  "fontFamily",
@@ -40729,6 +41665,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
40729
41665
  const esVal = String(endSnd).trim().toLowerCase();
40730
41666
  style.hyperlinkEndSound = esVal === "1" || esVal === "true";
40731
41667
  }
41668
+ const clickSnd = hyperlinkNode["a:snd"];
41669
+ if (clickSnd && typeof clickSnd === "object") {
41670
+ style.hyperlinkSoundXml = clickSnd;
41671
+ }
40732
41672
  }
40733
41673
  const actionStr = String(hyperlinkNode?.["@_action"] || "").trim();
40734
41674
  if (actionStr) {
@@ -40758,6 +41698,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
40758
41698
  } else {
40759
41699
  style.hyperlinkMouseOver = mouseOverRelId;
40760
41700
  }
41701
+ const mouseOverSnd = hlinkMouseOver["a:snd"];
41702
+ if (mouseOverSnd && typeof mouseOverSnd === "object") {
41703
+ style.hyperlinkMouseOverSoundXml = mouseOverSnd;
41704
+ }
40761
41705
  }
40762
41706
  }
40763
41707
  }
@@ -40984,6 +41928,8 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
40984
41928
  if (rawU.length > 0 && rawU !== "none") {
40985
41929
  style.underlineStyle = rawU;
40986
41930
  }
41931
+ } else if (underlineToken === "none") {
41932
+ style.underlineExplicitNone = true;
40987
41933
  }
40988
41934
  }
40989
41935
  const uFill = runProperties2["a:uFill"];
@@ -40995,6 +41941,46 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
40995
41941
  style.underlineColor = underlineColor;
40996
41942
  }
40997
41943
  }
41944
+ if (uLn) {
41945
+ const line2 = {};
41946
+ const widthEmu = Number.parseInt(String(uLn["@_w"] ?? ""), 10);
41947
+ if (Number.isFinite(widthEmu)) {
41948
+ line2.widthEmu = widthEmu;
41949
+ }
41950
+ const compound = String(uLn["@_cmpd"] ?? "").trim();
41951
+ if (compound) {
41952
+ line2.compound = compound;
41953
+ }
41954
+ const cap = String(uLn["@_cap"] ?? "").trim();
41955
+ if (cap) {
41956
+ line2.cap = cap;
41957
+ }
41958
+ const algn = String(uLn["@_algn"] ?? "").trim();
41959
+ if (algn) {
41960
+ line2.algn = algn;
41961
+ }
41962
+ const prstDash = String(uLn["a:prstDash"]?.["@_val"] ?? "").trim();
41963
+ if (prstDash) {
41964
+ line2.prstDash = prstDash;
41965
+ }
41966
+ const headEnd = uLn["a:headEnd"];
41967
+ if (headEnd && typeof headEnd === "object") {
41968
+ line2.headEndXml = headEnd;
41969
+ }
41970
+ const tailEnd = uLn["a:tailEnd"];
41971
+ if (tailEnd && typeof tailEnd === "object") {
41972
+ line2.tailEndXml = tailEnd;
41973
+ }
41974
+ if (Object.keys(line2).length > 0) {
41975
+ style.underlineLine = line2;
41976
+ }
41977
+ }
41978
+ if (runProperties2["a:uLnTx"] !== void 0) {
41979
+ style.underlineLineFollowsText = true;
41980
+ }
41981
+ if (runProperties2["a:uFillTx"] !== void 0) {
41982
+ style.underlineFillFollowsText = true;
41983
+ }
40998
41984
  if (runProperties2["@_strike"] !== void 0) {
40999
41985
  const strikeToken = String(runProperties2["@_strike"] || "").trim().toLowerCase();
41000
41986
  style.strikethrough = strikeToken.length > 0 && strikeToken !== "nostrike" && strikeToken !== "none" && strikeToken !== "0" && strikeToken !== "false";
@@ -41038,10 +42024,15 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
41038
42024
  }
41039
42025
  }
41040
42026
  if (runProperties2["a:highlight"]) {
41041
- const highlightHex = this.parseColor(xmlChild(runProperties2, "a:highlight"));
42027
+ const highlightNode = xmlChild(runProperties2, "a:highlight");
42028
+ const highlightHex = this.parseColor(highlightNode);
41042
42029
  if (highlightHex) {
41043
42030
  style.highlightColor = highlightHex;
41044
42031
  }
42032
+ const highlightXml = extractColorChoiceXml(highlightNode);
42033
+ if (highlightXml) {
42034
+ style.highlightColorXml = highlightXml;
42035
+ }
41045
42036
  }
41046
42037
  const textFillVariants = this.extractTextFillVariants(runProperties2);
41047
42038
  if (textFillVariants.textFillGradient) {
@@ -41062,16 +42053,28 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
41062
42053
  const latin = xmlChild(runProperties2, "a:latin");
41063
42054
  const eastAsian = xmlChild(runProperties2, "a:ea");
41064
42055
  const complexScript = xmlChild(runProperties2, "a:cs");
41065
- const chosenTypeface = xmlAttr(latin, "typeface") || xmlAttr(eastAsian, "typeface") || xmlAttr(complexScript, "typeface");
42056
+ const latinTypefaceToken = xmlAttr(latin, "typeface");
42057
+ const eaTypefaceToken = xmlAttr(eastAsian, "typeface");
42058
+ const csTypefaceToken = xmlAttr(complexScript, "typeface");
42059
+ const chosenTypeface = latinTypefaceToken || eaTypefaceToken || csTypefaceToken;
41066
42060
  const resolvedTypeface = this.resolveThemeTypeface(chosenTypeface);
41067
42061
  if (resolvedTypeface) {
41068
42062
  style.fontFamily = resolvedTypeface;
41069
42063
  }
41070
- const eaTypeface = this.resolveThemeTypeface(xmlAttr(eastAsian, "typeface"));
42064
+ if (latinTypefaceToken && latinTypefaceToken.startsWith("+")) {
42065
+ style.latinFontThemeToken = latinTypefaceToken;
42066
+ }
42067
+ if (eaTypefaceToken && eaTypefaceToken.startsWith("+")) {
42068
+ style.eastAsiaFontThemeToken = eaTypefaceToken;
42069
+ }
42070
+ if (csTypefaceToken && csTypefaceToken.startsWith("+")) {
42071
+ style.complexScriptFontThemeToken = csTypefaceToken;
42072
+ }
42073
+ const eaTypeface = this.resolveThemeTypeface(eaTypefaceToken);
41071
42074
  if (eaTypeface) {
41072
42075
  style.eastAsiaFont = eaTypeface;
41073
42076
  }
41074
- const csTypeface = this.resolveThemeTypeface(xmlAttr(complexScript, "typeface"));
42077
+ const csTypeface = this.resolveThemeTypeface(csTypefaceToken);
41075
42078
  if (csTypeface) {
41076
42079
  style.complexScriptFont = csTypeface;
41077
42080
  }
@@ -41087,6 +42090,9 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
41087
42090
  const capAttr = String(runProperties2["@_cap"] || "").trim().toLowerCase();
41088
42091
  if (capAttr === "all" || capAttr === "small") {
41089
42092
  style.textCaps = capAttr;
42093
+ } else if (capAttr === "none") {
42094
+ style.textCaps = "none";
42095
+ style.textCapsExplicitNone = true;
41090
42096
  }
41091
42097
  const symNode = xmlChild(runProperties2, "a:sym");
41092
42098
  if (symNode) {
@@ -41146,6 +42152,12 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
41146
42152
  this.applyTextRunEffects(style, runEffectList);
41147
42153
  }
41148
42154
  this.applyTextRunEffectDag(style, runProperties2);
42155
+ if (includeDefaultAlignment) {
42156
+ const runExtLst = runProperties2["a:extLst"];
42157
+ if (runExtLst && typeof runExtLst === "object") {
42158
+ style.runPropertiesExtLstXml = runExtLst;
42159
+ }
42160
+ }
41149
42161
  return style;
41150
42162
  }
41151
42163
  /**
@@ -41817,12 +42829,63 @@ function writeCellTextFormatting(xmlCell, style, ensureArray16) {
41817
42829
  }
41818
42830
 
41819
42831
  // src/core/core/runtime/PptxHandlerRuntimeSaveTableStyles.ts
42832
+ function flattenCellTxBodyText(txBody, ensureArray16) {
42833
+ if (!txBody) {
42834
+ return "";
42835
+ }
42836
+ const paragraphs = ensureArray16(txBody["a:p"]);
42837
+ const lines = [];
42838
+ for (const paragraph of paragraphs) {
42839
+ const runs = ensureArray16(paragraph?.["a:r"]);
42840
+ const fields = ensureArray16(paragraph?.["a:fld"]);
42841
+ let lineText = "";
42842
+ for (const run of runs) {
42843
+ lineText += String(run?.["a:t"] ?? "");
42844
+ }
42845
+ for (const field of fields) {
42846
+ lineText += String(field?.["a:t"] ?? "");
42847
+ }
42848
+ lines.push(lineText);
42849
+ }
42850
+ return lines.join("\n");
42851
+ }
42852
+ function isRichCellTxBody(txBody, ensureArray16) {
42853
+ if (!txBody) {
42854
+ return false;
42855
+ }
42856
+ const paragraphs = ensureArray16(txBody["a:p"]);
42857
+ let totalRuns = 0;
42858
+ for (const paragraph of paragraphs) {
42859
+ const runs = ensureArray16(paragraph?.["a:r"]);
42860
+ totalRuns += runs.length;
42861
+ if (totalRuns > 1) {
42862
+ return true;
42863
+ }
42864
+ if (ensureArray16(paragraph?.["a:fld"]).length > 0) {
42865
+ return true;
42866
+ }
42867
+ for (const run of runs) {
42868
+ const rPr = run?.["a:rPr"];
42869
+ if (rPr?.["a:hlinkClick"] !== void 0) {
42870
+ return true;
42871
+ }
42872
+ }
42873
+ }
42874
+ return false;
42875
+ }
41820
42876
  var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime21 {
41821
42877
  /**
41822
42878
  * Write plain text into a table cell's txBody, preserving
41823
42879
  * existing run properties where possible.
41824
42880
  */
41825
42881
  writeTableCellText(xmlCell, text2) {
42882
+ const ensureArray16 = this.ensureArray.bind(this);
42883
+ const existingTxBody = xmlCell["a:txBody"];
42884
+ if (existingTxBody && ensureArray16(existingTxBody["a:p"]).length > 0) {
42885
+ if (flattenCellTxBodyText(existingTxBody, ensureArray16) === text2) {
42886
+ return;
42887
+ }
42888
+ }
41826
42889
  if (!xmlCell["a:txBody"]) {
41827
42890
  xmlCell["a:txBody"] = { "a:bodyPr": {}, "a:p": {} };
41828
42891
  }
@@ -41950,7 +43013,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
41950
43013
  }
41951
43014
  delete tcPr["a:tcMar"];
41952
43015
  writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime.EMU_PER_PX);
41953
- writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
43016
+ if (!isRichCellTxBody(xmlCell["a:txBody"], this.ensureArray.bind(this))) {
43017
+ writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
43018
+ }
41954
43019
  const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
41955
43020
  for (const key of Object.keys(tcPr)) {
41956
43021
  delete tcPr[key];
@@ -43194,7 +44259,7 @@ function findKey19(obj, name, getLocalName2) {
43194
44259
  function hex9(value) {
43195
44260
  return value.replace("#", "");
43196
44261
  }
43197
- var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
44262
+ var COLOR_LOCAL_NAMES2 = /* @__PURE__ */ new Set([
43198
44263
  "srgbClr",
43199
44264
  "schemeClr",
43200
44265
  "sysClr",
@@ -43203,7 +44268,7 @@ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
43203
44268
  "hslClr"
43204
44269
  ]);
43205
44270
  function applyColorToList(list, value, getLocalName2) {
43206
- const colorKey = Object.keys(list).find((k) => COLOR_LOCAL_NAMES.has(getLocalName2(k)));
44271
+ const colorKey = Object.keys(list).find((k) => COLOR_LOCAL_NAMES2.has(getLocalName2(k)));
43207
44272
  const srgb = { "@_val": hex9(value) };
43208
44273
  if (!colorKey) {
43209
44274
  list["a:srgbClr"] = srgb;
@@ -45695,6 +46760,33 @@ var PptxHandlerRuntime27 = class extends PptxHandlerRuntime26 {
45695
46760
  }
45696
46761
  };
45697
46762
 
46763
+ // src/core/core/runtime/save-line-fill.ts
46764
+ function writeLineFill(lineNode, shapeStyle, parseColor) {
46765
+ delete lineNode["a:noFill"];
46766
+ delete lineNode["a:solidFill"];
46767
+ delete lineNode["a:gradFill"];
46768
+ delete lineNode["a:pattFill"];
46769
+ if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
46770
+ lineNode["a:noFill"] = {};
46771
+ return;
46772
+ }
46773
+ if (shapeStyle.strokeFillMode === "gradient" && shapeStyle.strokeGradientXml) {
46774
+ lineNode["a:gradFill"] = shapeStyle.strokeGradientXml;
46775
+ return;
46776
+ }
46777
+ if (shapeStyle.strokeFillMode === "pattern" && shapeStyle.strokePatternXml) {
46778
+ lineNode["a:pattFill"] = shapeStyle.strokePatternXml;
46779
+ return;
46780
+ }
46781
+ const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? parseColor(shapeStyle.strokeColorXml) : void 0;
46782
+ lineNode["a:solidFill"] = serializeColorChoice(
46783
+ shapeStyle.strokeColorXml,
46784
+ resolvedStrokeOriginal,
46785
+ shapeStyle.strokeColor ?? "#000000",
46786
+ shapeStyle.strokeOpacity
46787
+ );
46788
+ }
46789
+
45698
46790
  // src/core/core/runtime/PptxHandlerRuntimeSaveShapeStyleWriter.ts
45699
46791
  var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime27 {
45700
46792
  /**
@@ -45765,26 +46857,14 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
45765
46857
  );
45766
46858
  }
45767
46859
  }
45768
- if (shapeStyle.strokeColor !== void 0) {
46860
+ if (shapeStyle.strokeColor !== void 0 || shapeStyle.strokeFillMode === "gradient" || shapeStyle.strokeFillMode === "pattern") {
45769
46861
  if (!spPr["a:ln"]) {
45770
46862
  spPr["a:ln"] = {};
45771
46863
  }
45772
46864
  const lineNode = spPr["a:ln"];
45773
46865
  const w = Math.round((shapeStyle.strokeWidth || 1) * _PptxHandlerRuntime.EMU_PER_PX);
45774
46866
  lineNode["@_w"] = String(w);
45775
- if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
45776
- lineNode["a:noFill"] = {};
45777
- delete lineNode["a:solidFill"];
45778
- } else {
45779
- delete lineNode["a:noFill"];
45780
- const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
45781
- lineNode["a:solidFill"] = serializeColorChoice(
45782
- shapeStyle.strokeColorXml,
45783
- resolvedStrokeOriginal,
45784
- shapeStyle.strokeColor,
45785
- shapeStyle.strokeOpacity
45786
- );
45787
- }
46867
+ this.applyLineFill(lineNode, shapeStyle);
45788
46868
  }
45789
46869
  if (shapeStyle.strokeDash !== void 0) {
45790
46870
  if (!spPr["a:ln"]) {
@@ -45874,6 +46954,15 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
45874
46954
  spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
45875
46955
  }
45876
46956
  }
46957
+ /**
46958
+ * Emit the single fill child of an `<a:ln>` (CT_LineProperties allows at
46959
+ * most one of noFill/solidFill/gradFill/pattFill). Delegates to
46960
+ * {@link writeLineFill} so the logic stays unit-testable without the full
46961
+ * save runtime (issue #87).
46962
+ */
46963
+ applyLineFill(lineNode, shapeStyle) {
46964
+ writeLineFill(lineNode, shapeStyle, (colorNode) => this.parseColor(colorNode));
46965
+ }
45877
46966
  /**
45878
46967
  * Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
45879
46968
  * from the persisted ref indices/colour XML. Emits children in spec
@@ -48213,14 +49302,20 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
48213
49302
  relationshipType: constants.slideSyncRelationshipType,
48214
49303
  contentType: constants.slideSyncContentType
48215
49304
  });
48216
- this.slideBackgroundBuilder.applyBackground({
49305
+ await this.slideBackgroundBuilder.applyBackground({
48217
49306
  slideNode,
48218
49307
  slide,
48219
49308
  zip: this.zip,
48220
49309
  saveState: saveSession,
48221
49310
  relationshipRegistry: slideRelationshipRegistry,
48222
49311
  slideImageRelationshipType: constants.slideImageRelationshipType,
48223
- parseDataUrlToBytes: (dataUrl) => this.parseDataUrlToBytes(dataUrl)
49312
+ resolveImageToBytes: (url) => this.resolveMediaToBytes(url),
49313
+ reportUnsupportedBackground: (imageUrl) => this.compatibilityService.reportWarning({
49314
+ code: "SAVE_BACKGROUND_IMAGE_UNSUPPORTED",
49315
+ message: `Slide background image could not be embedded and was preserved as-is or omitted: ${imageUrl.slice(0, 120)}`,
49316
+ scope: "save",
49317
+ slideId: slide.id
49318
+ })
48224
49319
  });
48225
49320
  this.slideCommentPartWriter.writeComments({
48226
49321
  slide,
@@ -49725,7 +50820,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
49725
50820
  } = saveConstants;
49726
50821
  this.compatibilityService.resetWarnings();
49727
50822
  const saveSession = new PptxSaveStateBuilder().withZip(this.zip).withCommentAuthorMap(this.commentAuthorMap).withCommentAuthorDetails(this.commentAuthorDetails).withCommentAuthorsRootXml(this.commentAuthorsRootXml).withEmuPerPx(_PptxHandlerRuntime.EMU_PER_PX).build();
49728
- await this.reconcilePresentationSlidesForSave({
50823
+ const slideReferenceRemap = await this.reconcilePresentationSlidesForSave({
49729
50824
  slides,
49730
50825
  saveSession,
49731
50826
  slideRelationshipType,
@@ -49820,7 +50915,8 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
49820
50915
  rawSlideWidthEmu: this.rawSlideWidthEmu,
49821
50916
  rawSlideHeightEmu: this.rawSlideHeightEmu,
49822
50917
  rawSlideSizeType: this.rawSlideSizeType,
49823
- xmlLookupService: this.xmlLookupService
50918
+ xmlLookupService: this.xmlLookupService,
50919
+ slideReferenceRemap
49824
50920
  });
49825
50921
  this.deduplicateExtensionLists(this.presentationData);
49826
50922
  if (effectiveConformance === "transitional") {
@@ -49837,7 +50933,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
49837
50933
  printSlidesPerPage: options.handoutMaster.slidesPerPage
49838
50934
  } : options?.presentationProperties;
49839
50935
  await this.applyPresentationPropertiesPart(presentationProperties);
49840
- await this.applyViewPropertiesPart(options?.viewProperties);
50936
+ await this.applyViewPropertiesPart(options?.viewProperties ?? this.loadedViewProperties);
49841
50937
  await this.applyTableStylesPart(options?.tableStyles);
49842
50938
  await this.documentPropertiesUpdater.updateOnSave(slides, {
49843
50939
  coreProperties: options?.coreProperties,
@@ -50125,26 +51221,16 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
50125
51221
  return true;
50126
51222
  }
50127
51223
  const typesMatch = source.type === target.type || source.type === "ctrtitle" && target.type === "title" || source.type === "subtitle" && target.type === "body";
50128
- if (source.idx !== void 0 && target.idx !== void 0) {
50129
- if (source.idx !== target.idx) {
50130
- return false;
50131
- }
50132
- if (source.type && target.type && !typesMatch) {
50133
- return false;
50134
- }
50135
- return true;
50136
- }
50137
- if (source.idx !== void 0 && target.idx === void 0) {
50138
- const singletonTypes = /* @__PURE__ */ new Set(["title", "ctrtitle", "subtitle", "dt", "ftr", "sldnum"]);
50139
- if (source.type && singletonTypes.has(source.type)) {
50140
- return typesMatch;
50141
- }
51224
+ const sourceIdx = source.idx ?? "0";
51225
+ const targetIdx = target.idx ?? "0";
51226
+ if (sourceIdx !== targetIdx) {
50142
51227
  return false;
50143
51228
  }
50144
51229
  if (source.type && target.type && !typesMatch) {
50145
51230
  return false;
50146
51231
  }
50147
- if (source.type && !target.type) {
51232
+ const bothHaveExplicitIdx = source.idx !== void 0 && target.idx !== void 0;
51233
+ if (!bothHaveExplicitIdx && source.type && !target.type) {
50148
51234
  return false;
50149
51235
  }
50150
51236
  return true;
@@ -51590,6 +52676,19 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
51590
52676
  });
51591
52677
  return hasAny ? locks : void 0;
51592
52678
  }
52679
+ /**
52680
+ * Parse the `@txBox` attribute from a `p:cNvSpPr` node. Returns `true` /
52681
+ * `false` when the attribute is present, or `undefined` when absent so
52682
+ * callers can distinguish "not a text box" from "unspecified".
52683
+ */
52684
+ parseTxBoxFlag(cNvSpPr) {
52685
+ const raw = cNvSpPr?.["@_txBox"];
52686
+ if (raw === void 0) {
52687
+ return void 0;
52688
+ }
52689
+ const val = String(raw).trim().toLowerCase();
52690
+ return val === "1" || val === "true";
52691
+ }
51593
52692
  /**
51594
52693
  * Extract body-level text properties from `a:bodyPr` and apply them to the
51595
52694
  * provided {@link TextStyle}. Returns linked-textbox info when present.
@@ -51772,6 +52871,62 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
51772
52871
 
51773
52872
  // src/core/core/runtime/PptxHandlerRuntimeShapeTextParsing.ts
51774
52873
  var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime61 {
52874
+ /**
52875
+ * Extract a paragraph's OWN `a:pPr` geometry (align, spacing, margins,
52876
+ * indent, tabs, rtl) as a partial {@link TextStyle} so per-paragraph
52877
+ * formatting round-trips rather than collapsing to one shape-level pPr
52878
+ * (#69). Inherited layout/master values are not re-stamped.
52879
+ */
52880
+ extractParagraphOwnProperties(p, basisFontSize) {
52881
+ const pPr = p["a:pPr"];
52882
+ if (!pPr) {
52883
+ return void 0;
52884
+ }
52885
+ const pp = { ...parseParagraphMargins(pPr) };
52886
+ const align = pPr["@_algn"] !== void 0 ? parseAlignmentAttr(String(pPr["@_algn"])) : void 0;
52887
+ if (align) {
52888
+ pp.align = align;
52889
+ }
52890
+ const rtl = parseParagraphRtl(pPr);
52891
+ if (rtl !== void 0) {
52892
+ pp.rtl = rtl;
52893
+ }
52894
+ const spcBef = this.parseParagraphSpacingPx(
52895
+ pPr["a:spcBef"],
52896
+ basisFontSize
52897
+ );
52898
+ if (spcBef !== void 0) {
52899
+ pp.paragraphSpacingBefore = spcBef;
52900
+ }
52901
+ const spcAft = this.parseParagraphSpacingPx(
52902
+ pPr["a:spcAft"],
52903
+ basisFontSize
52904
+ );
52905
+ if (spcAft !== void 0) {
52906
+ pp.paragraphSpacingAfter = spcAft;
52907
+ }
52908
+ const lnSpcNode = pPr["a:lnSpc"];
52909
+ const lineSpacing = this.parseLineSpacingMultiplier(lnSpcNode);
52910
+ const exactPt = lineSpacing === void 0 ? this.parseLineSpacingExactPt(lnSpcNode) : void 0;
52911
+ if (lineSpacing !== void 0) {
52912
+ pp.lineSpacing = lineSpacing;
52913
+ } else if (exactPt !== void 0) {
52914
+ pp.lineSpacingExactPt = exactPt;
52915
+ }
52916
+ const tabStops = parseTabStops(pPr);
52917
+ if (tabStops && tabStops.length > 0) {
52918
+ pp.tabStops = tabStops;
52919
+ }
52920
+ const defRPr = pPr["a:defRPr"];
52921
+ if (defRPr && typeof defRPr === "object") {
52922
+ pp.paragraphDefaultRunPropertiesXml = defRPr;
52923
+ }
52924
+ const pPrExtLst = pPr["a:extLst"];
52925
+ if (pPrExtLst && typeof pPrExtLst === "object") {
52926
+ pp.paragraphPropertiesExtLstXml = pPrExtLst;
52927
+ }
52928
+ return Object.keys(pp).length > 0 ? pp : void 0;
52929
+ }
51775
52930
  /**
51776
52931
  * Resolve paragraph-level styles (alignment, spacing, margins, tabs,
51777
52932
  * level styles) for a single paragraph. Modifies `textStyle` in place
@@ -52020,6 +53175,12 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
52020
53175
  ...mergedDefaultRunStyle,
52021
53176
  ...this.extractTextRunStyle(runProps, paraAlign, ctx.slideRelationshipMap)
52022
53177
  };
53178
+ if (!runStyle2.scriptFallbackFont) {
53179
+ const fallback = this.resolveScriptFallbackFont(runText);
53180
+ if (fallback) {
53181
+ runStyle2.scriptFallbackFont = fallback;
53182
+ }
53183
+ }
52023
53184
  parts.push(runText);
52024
53185
  segments.push({ text: runText, style: runStyle2 });
52025
53186
  maybeSeed(runStyle2);
@@ -52061,14 +53222,25 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
52061
53222
  )
52062
53223
  };
52063
53224
  const fldType = String(field["@_type"] || "").trim() || void 0;
52064
- const fldGuid = String(field["@_uuid"] || field["@_id"] || "").trim() || void 0;
53225
+ const uuidAttr = String(field["@_uuid"] || "").trim();
53226
+ const idAttr = String(field["@_id"] || "").trim();
53227
+ const fldGuid = uuidAttr || idAttr || void 0;
53228
+ const fldGuidAttr = uuidAttr ? "uuid" : idAttr ? "id" : void 0;
52065
53229
  parts.push(fieldText);
52066
- segments.push({
53230
+ const fieldSegment = {
52067
53231
  text: fieldText,
52068
53232
  style: fieldRunStyle,
52069
53233
  fieldType: fldType,
52070
53234
  fieldGuid: fldGuid
52071
- });
53235
+ };
53236
+ if (fldGuidAttr) {
53237
+ fieldSegment.fieldGuidAttr = fldGuidAttr;
53238
+ }
53239
+ const fieldPPr = field["a:pPr"];
53240
+ if (fieldPPr && typeof fieldPPr === "object") {
53241
+ fieldSegment.fieldParagraphPropertiesXml = fieldPPr;
53242
+ }
53243
+ segments.push(fieldSegment);
52072
53244
  maybeSeed(fieldRunStyle);
52073
53245
  };
52074
53246
  const processMathElement = (mathEl) => {
@@ -52195,6 +53367,11 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
52195
53367
  ...endParaRPrRaw
52196
53368
  };
52197
53369
  }
53370
+ const basisFontSize = typeof mergedDefaultRunStyle.fontSize === "number" ? mergedDefaultRunStyle.fontSize : void 0;
53371
+ const paragraphOwnProps = this.extractParagraphOwnProperties(p, basisFontSize);
53372
+ if (paragraphOwnProps) {
53373
+ segments[firstSegmentIndex].paragraphProperties = paragraphOwnProps;
53374
+ }
52198
53375
  }
52199
53376
  return { parts, segments, seedStyle };
52200
53377
  }
@@ -52503,7 +53680,11 @@ var PptxHandlerRuntime64 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52503
53680
  const inheritedCNvSpPr = xmlPath(inheritedPlaceholder?.shape, "p:nvSpPr", "p:cNvSpPr") ?? xmlPath(inheritedPlaceholder?.picture, "p:nvPicPr", "p:cNvPicPr");
52504
53681
  const inheritedLockNode = inheritedCNvSpPr?.["a:spLocks"] ?? inheritedCNvSpPr?.["a:picLocks"];
52505
53682
  const inheritedLocks = this.parseShapeLocks(inheritedLockNode);
52506
- const locks = inheritedLocks ? { ...inheritedLocks, ...slideLocks } : slideLocks;
53683
+ let locks = inheritedLocks ? { ...inheritedLocks, ...slideLocks } : slideLocks;
53684
+ const txBox = this.parseTxBoxFlag(cNvSpPr);
53685
+ if (txBox !== void 0) {
53686
+ locks = { ...locks ?? {}, txBox };
53687
+ }
52507
53688
  const promptText = !hasText && phDefaults?.promptText ? phDefaults.promptText : void 0;
52508
53689
  const opaqueExtLstXml = this.extractOpaqueSpPrExtLst(effectiveSpPr);
52509
53690
  const commonProps = {
@@ -56056,16 +57237,20 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
56056
57237
  }
56057
57238
  let fontScheme;
56058
57239
  if (hasFonts) {
57240
+ const majorByScript = this.aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
57241
+ const minorByScript = this.aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
56059
57242
  fontScheme = {
56060
57243
  majorFont: {
56061
57244
  latin: this.themeFontMap["mj-lt"],
56062
57245
  eastAsia: this.themeFontMap["mj-ea"],
56063
- complexScript: this.themeFontMap["mj-cs"]
57246
+ complexScript: this.themeFontMap["mj-cs"],
57247
+ ...Object.keys(majorByScript).length > 0 ? { byScript: majorByScript } : {}
56064
57248
  },
56065
57249
  minorFont: {
56066
57250
  latin: this.themeFontMap["mn-lt"],
56067
57251
  eastAsia: this.themeFontMap["mn-ea"],
56068
- complexScript: this.themeFontMap["mn-cs"]
57252
+ complexScript: this.themeFontMap["mn-cs"],
57253
+ ...Object.keys(minorByScript).length > 0 ? { byScript: minorByScript } : {}
56069
57254
  }
56070
57255
  };
56071
57256
  }
@@ -56273,6 +57458,23 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
56273
57458
  *
56274
57459
  * Phase 4 Stream A / M4.
56275
57460
  */
57461
+ /**
57462
+ * Flatten a per-theme-path script-override map (`themePath -> {script ->
57463
+ * typeface}`) into a single `{script -> typeface}` lookup for
57464
+ * {@link buildThemeObject}. Earlier entries win on collision, which matches
57465
+ * the primary-theme-first parse order. Phase 4 Stream A / M4 (#83).
57466
+ */
57467
+ aggregateFontScriptOverrides(perPathMap) {
57468
+ const aggregate = {};
57469
+ for (const overrides of perPathMap.values()) {
57470
+ for (const [script, typeface] of Object.entries(overrides)) {
57471
+ if (!(script in aggregate)) {
57472
+ aggregate[script] = typeface;
57473
+ }
57474
+ }
57475
+ }
57476
+ return aggregate;
57477
+ }
56276
57478
  collectFontScriptOverrides(fontNode) {
56277
57479
  const overrides = {};
56278
57480
  if (!fontNode) {
@@ -56908,33 +58110,16 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
56908
58110
  const metadata = parseSmartArtDefinitionMetadata(colorsDef, localName21);
56909
58111
  const labels = parseSmartArtColorStyleLabels(colorsDef, localName21);
56910
58112
  const name = metadata.titles?.[0]?.value || String(colorsDef["@_title"] || colorsDef["@_uniqueId"] || "").trim() || void 0;
56911
- const fillColors = [];
56912
- const lineColors = [];
56913
58113
  const styleLbls = this.xmlLookupService.getChildrenArrayByLocalName(colorsDef, "styleLbl");
56914
- for (const lbl of styleLbls) {
56915
- const fillClrLst = this.xmlLookupService.getChildByLocalName(lbl, "fillClrLst");
56916
- const linClrLst = this.xmlLookupService.getChildByLocalName(lbl, "linClrLst");
56917
- if (fillClrLst) {
56918
- const color2 = this.parseColor(fillClrLst) ?? this.resolveSmartArtSchemeColor(
56919
- this.xmlLookupService.getChildByLocalName(fillClrLst, "schemeClr")
56920
- );
56921
- if (color2) {
56922
- fillColors.push(color2);
56923
- }
56924
- }
56925
- if (linClrLst) {
56926
- const color2 = this.parseColor(linClrLst) ?? this.resolveSmartArtSchemeColor(
56927
- this.xmlLookupService.getChildByLocalName(linClrLst, "schemeClr")
56928
- );
56929
- if (color2) {
56930
- lineColors.push(color2);
56931
- }
56932
- }
56933
- }
56934
- if (fillColors.length === 0 && lineColors.length === 0) {
58114
+ const colorLists = buildSmartArtColorLists(styleLbls, {
58115
+ getChild: (node, childName) => this.xmlLookupService.getChildByLocalName(node, childName),
58116
+ parseColorChoice: (colorChoice) => this.parseColor(colorChoice),
58117
+ resolveScheme: (colorNode) => this.resolveSmartArtSchemeColor(colorNode)
58118
+ });
58119
+ if (colorLists.fillColors.length === 0 && colorLists.lineColors.length === 0) {
56935
58120
  return void 0;
56936
58121
  }
56937
- return { ...metadata, name, fillColors, lineColors, labels };
58122
+ return { ...metadata, name, ...colorLists, labels };
56938
58123
  } catch {
56939
58124
  return void 0;
56940
58125
  }
@@ -57286,6 +58471,109 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
57286
58471
  }
57287
58472
  };
57288
58473
 
58474
+ // src/core/core/runtime/smartart-drawing-blip.ts
58475
+ function collectDrawingShapeNodes(root, getChildren) {
58476
+ const out = [];
58477
+ const walk = (container) => {
58478
+ if (!container) {
58479
+ return;
58480
+ }
58481
+ for (const sp of getChildren(container, "sp")) {
58482
+ out.push({ node: sp, isPic: false });
58483
+ }
58484
+ for (const pic of getChildren(container, "pic")) {
58485
+ out.push({ node: pic, isPic: true });
58486
+ }
58487
+ for (const grp of getChildren(container, "grpSp")) {
58488
+ walk(grp);
58489
+ }
58490
+ };
58491
+ walk(root);
58492
+ return out;
58493
+ }
58494
+ function picBlipEmbedId(pic, getChild) {
58495
+ const blip = getChild(getChild(pic, "blipFill"), "blip");
58496
+ if (!blip) {
58497
+ return void 0;
58498
+ }
58499
+ const embed = String(blip["@_r:embed"] || blip["@_embed"] || blip["@_r:link"] || "").trim();
58500
+ return embed.length > 0 ? embed : void 0;
58501
+ }
58502
+ function parseDrawingRelTargets(relsXml, parse, ensureArray16) {
58503
+ const map = /* @__PURE__ */ new Map();
58504
+ try {
58505
+ const relsRoot = parse(relsXml)["Relationships"];
58506
+ if (!relsRoot) {
58507
+ return map;
58508
+ }
58509
+ for (const rel of ensureArray16(relsRoot["Relationship"])) {
58510
+ const id = String(rel?.["@_Id"] || "").trim();
58511
+ const target = String(rel?.["@_Target"] || "").trim();
58512
+ if (id.length > 0 && target.length > 0) {
58513
+ map.set(id, target);
58514
+ }
58515
+ }
58516
+ } catch {
58517
+ }
58518
+ return map;
58519
+ }
58520
+ async function resolveDrawingBlipFills(shapes, drawingPath, deps) {
58521
+ const pending = shapes.filter((shape) => shape.fillBlipEmbedId && !shape.fillImageUrl);
58522
+ if (pending.length === 0) {
58523
+ return;
58524
+ }
58525
+ const dir = drawingPath.replace(/\/[^/]+$/u, "");
58526
+ const file = drawingPath.split("/").pop() ?? "";
58527
+ const relsXml = await deps.readText(`${dir}/_rels/${file}.rels`);
58528
+ if (!relsXml) {
58529
+ return;
58530
+ }
58531
+ const targets = parseDrawingRelTargets(relsXml, deps.parse, deps.ensureArray);
58532
+ for (const shape of pending) {
58533
+ const target = targets.get(shape.fillBlipEmbedId ?? "");
58534
+ if (!target) {
58535
+ continue;
58536
+ }
58537
+ const source = /^(?:https?:|data:)/u.test(target) ? target : deps.resolveImagePath(drawingPath, target);
58538
+ const resolved = await deps.getImageData(source);
58539
+ if (resolved) {
58540
+ shape.fillImageUrl = resolved;
58541
+ }
58542
+ }
58543
+ }
58544
+ async function parseDrawingShapesFromPart(drawingPath, deps) {
58545
+ const xmlString = await deps.readText(drawingPath);
58546
+ if (!xmlString) {
58547
+ return [];
58548
+ }
58549
+ try {
58550
+ const xml = deps.parse(xmlString);
58551
+ const drawing = deps.getChild(xml, "drawing");
58552
+ const spTree = deps.getChild(drawing || xml, "spTree");
58553
+ if (!spTree) {
58554
+ return [];
58555
+ }
58556
+ const shapes = [];
58557
+ collectDrawingShapeNodes(spTree, deps.getChildren).forEach(({ node, isPic }, index) => {
58558
+ const shape = deps.parseDrawingShape(node, index, deps.emuPerPx);
58559
+ if (!shape) {
58560
+ return;
58561
+ }
58562
+ if (isPic && !shape.fillBlipEmbedId) {
58563
+ const embed = picBlipEmbedId(node, deps.getChild);
58564
+ if (embed) {
58565
+ shape.fillBlipEmbedId = embed;
58566
+ }
58567
+ }
58568
+ shapes.push(shape);
58569
+ });
58570
+ await resolveDrawingBlipFills(shapes, drawingPath, deps);
58571
+ return shapes;
58572
+ } catch {
58573
+ return [];
58574
+ }
58575
+ }
58576
+
57289
58577
  // src/core/core/runtime/smartart-layout-category.ts
57290
58578
  var CATEGORY_FAMILY = {
57291
58579
  list: "list",
@@ -57421,6 +58709,7 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
57421
58709
  layoutDefinition,
57422
58710
  nodes,
57423
58711
  connections: parsedConnections.length > 0 ? parsedConnections : void 0,
58712
+ presLayoutVars: parseSmartArtPresLayoutVars(dataModel),
57424
58713
  drawingShapes: drawingShapes.length > 0 ? drawingShapes : void 0,
57425
58714
  chrome,
57426
58715
  colorTransform,
@@ -57499,30 +58788,28 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
57499
58788
  }
57500
58789
  }
57501
58790
  /**
57502
- * Parse SmartArt drawing shapes given an absolute part path.
58791
+ * Parse cached SmartArt drawing shapes from an absolute part path.
57503
58792
  *
57504
- * Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
57505
- * relationship id) with a path-based lookup so the resolution layer
57506
- * can pull the part from anywhere in the package.
58793
+ * Enumerates `dsp:sp` / bare `dsp:pic` (incl. nested `dsp:grpSp`) and
58794
+ * resolves picture (blip) fills to data URLs via the drawing part's own
58795
+ * relationships. Delegates to a pure helper with an injected dep bundle.
57507
58796
  */
57508
58797
  async parseSmartArtDrawingShapesFromPath(drawingPath) {
57509
- const xmlString = await this.zip.file(drawingPath)?.async("string");
57510
- if (!xmlString) {
57511
- return [];
57512
- }
57513
- try {
57514
- const xml = this.parser.parse(xmlString);
57515
- const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
57516
- const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
57517
- if (!spTree) {
57518
- return [];
57519
- }
57520
- const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
57521
- const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
57522
- return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
57523
- } catch {
57524
- return [];
57525
- }
58798
+ return parseDrawingShapesFromPart(drawingPath, this.drawingBlipDeps());
58799
+ }
58800
+ /** Bind runtime zip / parser / lookup / image helpers for the drawing parser. */
58801
+ drawingBlipDeps() {
58802
+ return {
58803
+ readText: (path2) => this.zip.file(path2)?.async("string") ?? Promise.resolve(void 0),
58804
+ parse: (xml) => this.parser.parse(xml),
58805
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
58806
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
58807
+ parseDrawingShape: (sp, index, emuPerPx) => this.parseDrawingShape(sp, index, emuPerPx),
58808
+ emuPerPx: _PptxHandlerRuntime.EMU_PER_PX,
58809
+ ensureArray: (value) => this.ensureArray(value),
58810
+ resolveImagePath: (base, target) => this.resolveImagePath(base, target),
58811
+ getImageData: (path2) => this.getImageData(path2)
58812
+ };
57526
58813
  }
57527
58814
  };
57528
58815
 
@@ -58220,6 +59507,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
58220
59507
  grouping = "clustered";
58221
59508
  }
58222
59509
  }
59510
+ const varyColors = this.parseChartBoolVal(seriesContainer, "varyColors");
59511
+ const firstSliceAngle = this.parseChartNumberVal(seriesContainer, "firstSliceAng");
59512
+ const doughnutHoleSize = this.parseChartNumberVal(seriesContainer, "holeSize");
59513
+ const barGapWidth = this.parseChartNumberVal(seriesContainer, "gapWidth");
59514
+ const barOverlap = this.parseChartNumberVal(seriesContainer, "overlap");
58223
59515
  const chartPartPath = chartPart.partPath;
58224
59516
  const dataTable = parseDataTable(plotArea, this.xmlLookupService);
58225
59517
  const dropLines = parseLineStyle(
@@ -58296,6 +59588,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
58296
59588
  title: titleTextValues[0],
58297
59589
  style: chartStyle,
58298
59590
  grouping,
59591
+ ...varyColors !== void 0 ? { varyColors } : {},
59592
+ ...firstSliceAngle !== void 0 ? { firstSliceAngle } : {},
59593
+ ...doughnutHoleSize !== void 0 ? { doughnutHoleSize } : {},
59594
+ ...barGapWidth !== void 0 ? { barGapWidth } : {},
59595
+ ...barOverlap !== void 0 ? { barOverlap } : {},
58299
59596
  chartPartPath,
58300
59597
  chartRelationshipId,
58301
59598
  ...dataTable ? { dataTable } : {},
@@ -58372,6 +59669,35 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
58372
59669
  }
58373
59670
  return { categories, series };
58374
59671
  }
59672
+ /**
59673
+ * Read a numeric `@val` from a named child of a chart-type container.
59674
+ * Returns `undefined` when the child or its `@val` is absent/non-finite.
59675
+ */
59676
+ parseChartNumberVal(container, localName21) {
59677
+ const node = this.xmlLookupService.getChildByLocalName(container, localName21);
59678
+ const raw = node?.["@_val"];
59679
+ if (raw === void 0 || raw === null || raw === "") {
59680
+ return void 0;
59681
+ }
59682
+ const num = Number.parseFloat(String(raw));
59683
+ return Number.isFinite(num) ? num : void 0;
59684
+ }
59685
+ /**
59686
+ * Read a boolean `@val` from a named child of a chart-type container.
59687
+ * A present element with no `@val` follows the OOXML `CT_Boolean` default
59688
+ * of `true`; `undefined` when the child is absent.
59689
+ */
59690
+ parseChartBoolVal(container, localName21) {
59691
+ const node = this.xmlLookupService.getChildByLocalName(container, localName21);
59692
+ if (!node) {
59693
+ return void 0;
59694
+ }
59695
+ const raw = node["@_val"];
59696
+ if (raw === void 0 || raw === null || raw === "") {
59697
+ return true;
59698
+ }
59699
+ return !(raw === "0" || raw === "false");
59700
+ }
58375
59701
  /**
58376
59702
  * Build the series array from raw OOXML `c:ser` nodes.
58377
59703
  *
@@ -58415,6 +59741,10 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
58415
59741
  );
58416
59742
  const dataLabels = parseSeriesDataLabels(seriesNode, this.xmlLookupService);
58417
59743
  const explosion = parseSeriesExplosion(seriesNode, this.xmlLookupService);
59744
+ const smoothNode = this.xmlLookupService.getChildByLocalName(seriesNode, "smooth");
59745
+ const smooth = smoothNode ? !(smoothNode["@_val"] === "0" || smoothNode["@_val"] === "false") : void 0;
59746
+ const invertNode = this.xmlLookupService.getChildByLocalName(seriesNode, "invertIfNegative");
59747
+ const invertIfNegative = invertNode ? !(invertNode["@_val"] === "0" || invertNode["@_val"] === "false") : void 0;
58418
59748
  return {
58419
59749
  name: seriesName.trim().length > 0 ? seriesName : `Series ${seriesIndex + 1}`,
58420
59750
  values: fallbackValues,
@@ -58425,6 +59755,8 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
58425
59755
  ...seriesMarker ? { marker: seriesMarker } : {},
58426
59756
  ...dataLabels.length > 0 ? { dataLabels } : {},
58427
59757
  ...explosion !== void 0 ? { explosion } : {},
59758
+ ...invertIfNegative !== void 0 ? { invertIfNegative } : {},
59759
+ ...smooth !== void 0 ? { smooth } : {},
58428
59760
  ...axisId !== void 0 ? { axisId } : {},
58429
59761
  ...seriesChartType ? { seriesChartType } : {}
58430
59762
  };
@@ -59251,6 +60583,8 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
59251
60583
  async buildLoadData(presentationState, slidesWithWarnings, slideMasters) {
59252
60584
  const headerFooter = this.extractHeaderFooter();
59253
60585
  const presentationProperties = await this.parsePresentationProperties();
60586
+ const viewProperties = await this.parseViewProperties();
60587
+ this.loadedViewProperties = viewProperties;
59254
60588
  const customShows = this.parseCustomShows();
59255
60589
  const tableStyleMap = await this.parseTableStyles();
59256
60590
  const embeddedFontList = parseEmbeddedFontList(this.presentationData);
@@ -59280,7 +60614,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
59280
60614
  presentationState.height,
59281
60615
  this.rawSlideWidthEmu,
59282
60616
  this.rawSlideHeightEmu
59283
- ).withNotesDimensions(presentationState.notesWidthEmu, presentationState.notesHeightEmu).withSlides(slidesWithWarnings).withLayoutOptions(this.getLayoutOptions()).withHeaderFooter(headerFooter).withPresentationProperties(presentationProperties).withCustomShows(customShows).withSections(
60617
+ ).withNotesDimensions(presentationState.notesWidthEmu, presentationState.notesHeightEmu).withSlides(slidesWithWarnings).withLayoutOptions(this.getLayoutOptions()).withHeaderFooter(headerFooter).withPresentationProperties(presentationProperties).withViewProperties(viewProperties).withCustomShows(customShows).withSections(
59284
60618
  presentationState.orderedSections.length > 0 ? presentationState.orderedSections : void 0
59285
60619
  ).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(
59286
60620
  this.signatureDetection?.signatureCount && this.signatureDetection.signatureCount > 0 ? this.signatureDetection.signatureCount : void 0
@@ -59411,6 +60745,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
59411
60745
  this.customXmlParts = [];
59412
60746
  this.loadedEmbeddedFonts = [];
59413
60747
  this.loadedEmbeddedFontList = void 0;
60748
+ this.loadedViewProperties = void 0;
59414
60749
  this.orderedSlidePaths = [];
59415
60750
  this.zip = null;
59416
60751
  }