pptx-viewer-core 1.6.5 → 1.6.7

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/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ All notable changes to this project are documented here.
4
4
  This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
5
5
  by [git-cliff](https://git-cliff.org); do not edit it by hand.
6
6
 
7
+ ## [1.6.6](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.6) - 2026-07-18
8
+
9
+ ## [1.6.5](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.5) - 2026-07-18
10
+
11
+ ### Documentation
12
+
13
+ - Correct and expand the per-package npm readmes (by @ChristopherVR) ([46f7c57](https://github.com/ChristopherVR/pptx-viewer/commit/46f7c573701a19e91c507d41ebdc956c64699c38))
14
+
7
15
  ## [1.6.4](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.4) - 2026-07-18
8
16
 
9
17
  ## [1.6.3](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.3) - 2026-07-18
package/dist/cli/index.js CHANGED
@@ -2713,14 +2713,52 @@ function extractSourceOrders(xml) {
2713
2713
  }
2714
2714
  return orders;
2715
2715
  }
2716
+ function ensureArrayLocal(value) {
2717
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
2718
+ }
2719
+ function countsSignature(counts) {
2720
+ return [...counts.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1).map(([name, count]) => `${name}:${count}`).join(",");
2721
+ }
2722
+ function pathSignature(path2) {
2723
+ const counts = /* @__PURE__ */ new Map();
2724
+ for (const key of Object.keys(path2)) {
2725
+ const name = localName(key);
2726
+ if (!PATH_COMMANDS.has(name)) {
2727
+ continue;
2728
+ }
2729
+ counts.set(name, (counts.get(name) ?? 0) + ensureArrayLocal(path2[key]).length);
2730
+ }
2731
+ return countsSignature(counts);
2732
+ }
2733
+ function orderSignature(order) {
2734
+ const counts = /* @__PURE__ */ new Map();
2735
+ for (const name of order) {
2736
+ counts.set(name, (counts.get(name) ?? 0) + 1);
2737
+ }
2738
+ return countsSignature(counts);
2739
+ }
2716
2740
  function annotateCustomGeometryCommandOrder(xml, parsed) {
2717
2741
  const orders = extractSourceOrders(xml);
2718
2742
  if (orders.length === 0) {
2719
2743
  return;
2720
2744
  }
2721
2745
  const paths = collectParsedPaths(parsed);
2722
- for (let index = 0; index < Math.min(paths.length, orders.length); index++) {
2723
- commandOrder.set(paths[index], orders[index]);
2746
+ const ordersBySignature = /* @__PURE__ */ new Map();
2747
+ for (const order of orders) {
2748
+ const signature = orderSignature(order);
2749
+ const bucket = ordersBySignature.get(signature);
2750
+ if (bucket) {
2751
+ bucket.push(order);
2752
+ } else {
2753
+ ordersBySignature.set(signature, [order]);
2754
+ }
2755
+ }
2756
+ for (const path2 of paths) {
2757
+ const bucket = ordersBySignature.get(pathSignature(path2));
2758
+ const order = bucket?.shift();
2759
+ if (order) {
2760
+ commandOrder.set(path2, order);
2761
+ }
2724
2762
  }
2725
2763
  }
2726
2764
  function orderedPathCommandEntries(path2, ensureArray16) {
@@ -50002,6 +50040,8 @@ var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
50002
50040
  const existing = merged[key];
50003
50041
  if (value && typeof value === "object" && !Array.isArray(value) && existing && typeof existing === "object" && !Array.isArray(existing)) {
50004
50042
  merged[key] = this.mergeXmlObjects(existing, value, depth + 1);
50043
+ } else if (value === "" && existing !== void 0 && existing !== "" && typeof existing === "object") {
50044
+ merged[key] = existing;
50005
50045
  } else {
50006
50046
  merged[key] = value;
50007
50047
  }
@@ -52784,32 +52824,56 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52784
52824
  }
52785
52825
  const grpSpPr = group["p:grpSpPr"];
52786
52826
  const xfrm = grpSpPr?.["a:xfrm"];
52827
+ const EMU_PX = _PptxHandlerRuntime.EMU_PER_PX;
52787
52828
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
52788
52829
  let chX = 0, chY = 0, chW = 0, chH = 0;
52789
52830
  if (xfrm) {
52790
52831
  const off = xfrm["a:off"];
52791
52832
  if (off) {
52792
- parentX = Math.round(parseEmuInt2(off["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
52793
- parentY = Math.round(parseEmuInt2(off["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
52833
+ parentX = parseEmuInt2(off["@_x"]) / EMU_PX;
52834
+ parentY = parseEmuInt2(off["@_y"]) / EMU_PX;
52794
52835
  }
52795
52836
  const ext = xfrm["a:ext"];
52796
52837
  if (ext) {
52797
- parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52798
- parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52838
+ parentW = parseEmuInt2(ext["@_cx"]) / EMU_PX;
52839
+ parentH = parseEmuInt2(ext["@_cy"]) / EMU_PX;
52799
52840
  }
52800
52841
  const chOff = xfrm["a:chOff"];
52801
52842
  if (chOff) {
52802
- chX = Math.round(parseEmuInt2(chOff["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
52803
- chY = Math.round(parseEmuInt2(chOff["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
52843
+ chX = parseEmuInt2(chOff["@_x"]) / EMU_PX;
52844
+ chY = parseEmuInt2(chOff["@_y"]) / EMU_PX;
52804
52845
  }
52805
52846
  const chExt = xfrm["a:chExt"];
52806
52847
  if (chExt) {
52807
- chW = Math.round(parseEmuInt2(chExt["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52808
- chH = Math.round(parseEmuInt2(chExt["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52848
+ chW = parseEmuInt2(chExt["@_cx"]) / EMU_PX;
52849
+ chH = parseEmuInt2(chExt["@_cy"]) / EMU_PX;
52809
52850
  }
52810
52851
  }
52811
52852
  const scaleX = chW > 0 ? parentW / chW : 1;
52812
52853
  const scaleY = chH > 0 ? parentH / chH : 1;
52854
+ const rawChildXfrm = (childNode) => {
52855
+ if (!childNode) {
52856
+ return void 0;
52857
+ }
52858
+ const childXfrm = childNode["p:spPr"]?.["a:xfrm"] ?? childNode["p:xfrm"];
52859
+ return childXfrm;
52860
+ };
52861
+ const applyRawChildGeometry = (el, childNode) => {
52862
+ const childXfrm = rawChildXfrm(childNode);
52863
+ if (!childXfrm) {
52864
+ return;
52865
+ }
52866
+ const off = childXfrm["a:off"];
52867
+ const ext = childXfrm["a:ext"];
52868
+ if (off) {
52869
+ el.x = parseEmuInt2(off["@_x"]) / EMU_PX;
52870
+ el.y = parseEmuInt2(off["@_y"]) / EMU_PX;
52871
+ }
52872
+ if (ext) {
52873
+ el.width = parseEmuInt2(ext["@_cx"]) / EMU_PX;
52874
+ el.height = parseEmuInt2(ext["@_cy"]) / EMU_PX;
52875
+ }
52876
+ };
52813
52877
  const transformElement = (el) => {
52814
52878
  const relativeX = el.x - chX;
52815
52879
  const relativeY = el.y - chY;
@@ -52867,6 +52931,8 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52867
52931
  `${baseId}-`
52868
52932
  );
52869
52933
  if (element) {
52934
+ const childNode = this.ensureArray(group[entry.tag])[entry.indexInType];
52935
+ applyRawChildGeometry(element, childNode);
52870
52936
  transformElement(element);
52871
52937
  elements.push(element);
52872
52938
  }
@@ -53416,6 +53482,40 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53416
53482
  }
53417
53483
  return void 0;
53418
53484
  }
53485
+ /**
53486
+ * Reuse the cached parse of a layout XML part, parsing (and caching) on a
53487
+ * miss. Background resolution runs per slide but the layout/master parts are
53488
+ * large (a themed master can be ~200 KB); re-parsing them for every slide
53489
+ * dominated load time, so share the same parsed object `getLayoutElements`
53490
+ * already populated.
53491
+ */
53492
+ async resolveCachedLayoutXml(layoutPath) {
53493
+ const cached = this.layoutXmlMap.get(layoutPath);
53494
+ if (cached) {
53495
+ return cached;
53496
+ }
53497
+ const xml = await this.zip.file(layoutPath)?.async("string");
53498
+ if (!xml) {
53499
+ return void 0;
53500
+ }
53501
+ const parsed = this.parser.parse(xml);
53502
+ this.layoutXmlMap.set(layoutPath, parsed);
53503
+ return parsed;
53504
+ }
53505
+ /** Reuse the cached parse of a master XML part, parsing (and caching) on a miss. */
53506
+ async resolveCachedMasterXml(masterPath) {
53507
+ const cached = this.masterXmlMap.get(masterPath);
53508
+ if (cached) {
53509
+ return cached;
53510
+ }
53511
+ const xml = await this.zip.file(masterPath)?.async("string");
53512
+ if (!xml) {
53513
+ return void 0;
53514
+ }
53515
+ const parsed = this.parser.parse(xml);
53516
+ this.masterXmlMap.set(masterPath, parsed);
53517
+ return parsed;
53518
+ }
53419
53519
  async getMasterBackgroundImage(layoutPath) {
53420
53520
  const layoutRels = this.slideRelsMap.get(layoutPath);
53421
53521
  if (!layoutRels) {
@@ -53426,9 +53526,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53426
53526
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53427
53527
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53428
53528
  try {
53429
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53430
- if (masterXmlStr) {
53431
- const masterXmlObj = this.parser.parse(masterXmlStr);
53529
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53530
+ if (masterXmlObj) {
53432
53531
  const masterRelsPath = `${masterPath.replace("slideMasters/", "slideMasters/_rels/")}.rels`;
53433
53532
  await this.loadSlideRelationships(masterPath, masterRelsPath);
53434
53533
  return this.extractBackgroundImage(masterXmlObj, masterPath, "p:sldMaster");
@@ -53450,9 +53549,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53450
53549
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53451
53550
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53452
53551
  try {
53453
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53454
- if (layoutXmlStr) {
53455
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53552
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53553
+ if (layoutXmlObj) {
53456
53554
  const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
53457
53555
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
53458
53556
  const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
@@ -53478,9 +53576,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53478
53576
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53479
53577
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53480
53578
  try {
53481
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53482
- if (layoutXmlStr) {
53483
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53579
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53580
+ if (layoutXmlObj) {
53484
53581
  const layoutBg = this.extractBackgroundColor(layoutXmlObj, "p:sldLayout");
53485
53582
  if (layoutBg) {
53486
53583
  return layoutBg;
@@ -53507,9 +53604,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53507
53604
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53508
53605
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53509
53606
  try {
53510
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53511
- if (masterXmlStr) {
53512
- const masterXmlObj = this.parser.parse(masterXmlStr);
53607
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53608
+ if (masterXmlObj) {
53513
53609
  return this.extractBackgroundColor(masterXmlObj, "p:sldMaster");
53514
53610
  }
53515
53611
  } catch {
@@ -53536,9 +53632,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53536
53632
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53537
53633
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53538
53634
  try {
53539
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53540
- if (layoutXmlStr) {
53541
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53635
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53636
+ if (layoutXmlObj) {
53542
53637
  const layoutGrad = this.extractBackgroundGradient(layoutXmlObj, "p:sldLayout");
53543
53638
  if (layoutGrad) {
53544
53639
  return layoutGrad;
@@ -53565,9 +53660,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53565
53660
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53566
53661
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53567
53662
  try {
53568
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53569
- if (masterXmlStr) {
53570
- const masterXmlObj = this.parser.parse(masterXmlStr);
53663
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53664
+ if (masterXmlObj) {
53571
53665
  return this.extractBackgroundGradient(masterXmlObj, "p:sldMaster");
53572
53666
  }
53573
53667
  } catch {
@@ -54375,6 +54469,21 @@ var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
54375
54469
  element.id = `master-${element.id}`;
54376
54470
  elements.push(element);
54377
54471
  }
54472
+ } else if (entry.tag === "p:grpSp") {
54473
+ const groups = this.ensureArray(spTree["p:grpSp"]);
54474
+ const group = groups[entry.indexInType];
54475
+ if (!group) {
54476
+ continue;
54477
+ }
54478
+ const element = await this.parseGroupShapeAsGroup(
54479
+ group,
54480
+ `master-group-${masterToken}-${entry.indexInType}`,
54481
+ masterPath
54482
+ );
54483
+ if (element) {
54484
+ element.id = `master-${element.id}`;
54485
+ elements.push(element);
54486
+ }
54378
54487
  }
54379
54488
  }
54380
54489
  this.masterCache.set(masterPath, elements);
@@ -54586,6 +54695,21 @@ var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
54586
54695
  element.id = `layout-${element.id}`;
54587
54696
  elements.push(element);
54588
54697
  }
54698
+ } else if (entry.tag === "p:grpSp") {
54699
+ const groups = this.ensureArray(spTree["p:grpSp"]);
54700
+ const group = groups[entry.indexInType];
54701
+ if (!group) {
54702
+ continue;
54703
+ }
54704
+ const element = await this.parseGroupShapeAsGroup(
54705
+ group,
54706
+ `layout-group-${layoutToken}-${entry.indexInType}`,
54707
+ layoutPath
54708
+ );
54709
+ if (element) {
54710
+ element.id = `layout-${element.id}`;
54711
+ elements.push(element);
54712
+ }
54589
54713
  }
54590
54714
  }
54591
54715
  const layoutShowMasterSp = xmlAttr(
@@ -2687,14 +2687,52 @@ function extractSourceOrders(xml) {
2687
2687
  }
2688
2688
  return orders;
2689
2689
  }
2690
+ function ensureArrayLocal(value) {
2691
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
2692
+ }
2693
+ function countsSignature(counts) {
2694
+ return [...counts.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1).map(([name, count]) => `${name}:${count}`).join(",");
2695
+ }
2696
+ function pathSignature(path2) {
2697
+ const counts = /* @__PURE__ */ new Map();
2698
+ for (const key of Object.keys(path2)) {
2699
+ const name = localName(key);
2700
+ if (!PATH_COMMANDS.has(name)) {
2701
+ continue;
2702
+ }
2703
+ counts.set(name, (counts.get(name) ?? 0) + ensureArrayLocal(path2[key]).length);
2704
+ }
2705
+ return countsSignature(counts);
2706
+ }
2707
+ function orderSignature(order) {
2708
+ const counts = /* @__PURE__ */ new Map();
2709
+ for (const name of order) {
2710
+ counts.set(name, (counts.get(name) ?? 0) + 1);
2711
+ }
2712
+ return countsSignature(counts);
2713
+ }
2690
2714
  function annotateCustomGeometryCommandOrder(xml, parsed) {
2691
2715
  const orders = extractSourceOrders(xml);
2692
2716
  if (orders.length === 0) {
2693
2717
  return;
2694
2718
  }
2695
2719
  const paths = collectParsedPaths(parsed);
2696
- for (let index = 0; index < Math.min(paths.length, orders.length); index++) {
2697
- commandOrder.set(paths[index], orders[index]);
2720
+ const ordersBySignature = /* @__PURE__ */ new Map();
2721
+ for (const order of orders) {
2722
+ const signature = orderSignature(order);
2723
+ const bucket = ordersBySignature.get(signature);
2724
+ if (bucket) {
2725
+ bucket.push(order);
2726
+ } else {
2727
+ ordersBySignature.set(signature, [order]);
2728
+ }
2729
+ }
2730
+ for (const path2 of paths) {
2731
+ const bucket = ordersBySignature.get(pathSignature(path2));
2732
+ const order = bucket?.shift();
2733
+ if (order) {
2734
+ commandOrder.set(path2, order);
2735
+ }
2698
2736
  }
2699
2737
  }
2700
2738
  function orderedPathCommandEntries(path2, ensureArray16) {
@@ -49976,6 +50014,8 @@ var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
49976
50014
  const existing = merged[key];
49977
50015
  if (value && typeof value === "object" && !Array.isArray(value) && existing && typeof existing === "object" && !Array.isArray(existing)) {
49978
50016
  merged[key] = this.mergeXmlObjects(existing, value, depth + 1);
50017
+ } else if (value === "" && existing !== void 0 && existing !== "" && typeof existing === "object") {
50018
+ merged[key] = existing;
49979
50019
  } else {
49980
50020
  merged[key] = value;
49981
50021
  }
@@ -52758,32 +52798,56 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52758
52798
  }
52759
52799
  const grpSpPr = group["p:grpSpPr"];
52760
52800
  const xfrm = grpSpPr?.["a:xfrm"];
52801
+ const EMU_PX = _PptxHandlerRuntime.EMU_PER_PX;
52761
52802
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
52762
52803
  let chX = 0, chY = 0, chW = 0, chH = 0;
52763
52804
  if (xfrm) {
52764
52805
  const off = xfrm["a:off"];
52765
52806
  if (off) {
52766
- parentX = Math.round(parseEmuInt2(off["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
52767
- parentY = Math.round(parseEmuInt2(off["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
52807
+ parentX = parseEmuInt2(off["@_x"]) / EMU_PX;
52808
+ parentY = parseEmuInt2(off["@_y"]) / EMU_PX;
52768
52809
  }
52769
52810
  const ext = xfrm["a:ext"];
52770
52811
  if (ext) {
52771
- parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52772
- parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52812
+ parentW = parseEmuInt2(ext["@_cx"]) / EMU_PX;
52813
+ parentH = parseEmuInt2(ext["@_cy"]) / EMU_PX;
52773
52814
  }
52774
52815
  const chOff = xfrm["a:chOff"];
52775
52816
  if (chOff) {
52776
- chX = Math.round(parseEmuInt2(chOff["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
52777
- chY = Math.round(parseEmuInt2(chOff["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
52817
+ chX = parseEmuInt2(chOff["@_x"]) / EMU_PX;
52818
+ chY = parseEmuInt2(chOff["@_y"]) / EMU_PX;
52778
52819
  }
52779
52820
  const chExt = xfrm["a:chExt"];
52780
52821
  if (chExt) {
52781
- chW = Math.round(parseEmuInt2(chExt["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52782
- chH = Math.round(parseEmuInt2(chExt["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52822
+ chW = parseEmuInt2(chExt["@_cx"]) / EMU_PX;
52823
+ chH = parseEmuInt2(chExt["@_cy"]) / EMU_PX;
52783
52824
  }
52784
52825
  }
52785
52826
  const scaleX = chW > 0 ? parentW / chW : 1;
52786
52827
  const scaleY = chH > 0 ? parentH / chH : 1;
52828
+ const rawChildXfrm = (childNode) => {
52829
+ if (!childNode) {
52830
+ return void 0;
52831
+ }
52832
+ const childXfrm = childNode["p:spPr"]?.["a:xfrm"] ?? childNode["p:xfrm"];
52833
+ return childXfrm;
52834
+ };
52835
+ const applyRawChildGeometry = (el, childNode) => {
52836
+ const childXfrm = rawChildXfrm(childNode);
52837
+ if (!childXfrm) {
52838
+ return;
52839
+ }
52840
+ const off = childXfrm["a:off"];
52841
+ const ext = childXfrm["a:ext"];
52842
+ if (off) {
52843
+ el.x = parseEmuInt2(off["@_x"]) / EMU_PX;
52844
+ el.y = parseEmuInt2(off["@_y"]) / EMU_PX;
52845
+ }
52846
+ if (ext) {
52847
+ el.width = parseEmuInt2(ext["@_cx"]) / EMU_PX;
52848
+ el.height = parseEmuInt2(ext["@_cy"]) / EMU_PX;
52849
+ }
52850
+ };
52787
52851
  const transformElement = (el) => {
52788
52852
  const relativeX = el.x - chX;
52789
52853
  const relativeY = el.y - chY;
@@ -52841,6 +52905,8 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52841
52905
  `${baseId}-`
52842
52906
  );
52843
52907
  if (element) {
52908
+ const childNode = this.ensureArray(group[entry.tag])[entry.indexInType];
52909
+ applyRawChildGeometry(element, childNode);
52844
52910
  transformElement(element);
52845
52911
  elements.push(element);
52846
52912
  }
@@ -53390,6 +53456,40 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53390
53456
  }
53391
53457
  return void 0;
53392
53458
  }
53459
+ /**
53460
+ * Reuse the cached parse of a layout XML part, parsing (and caching) on a
53461
+ * miss. Background resolution runs per slide but the layout/master parts are
53462
+ * large (a themed master can be ~200 KB); re-parsing them for every slide
53463
+ * dominated load time, so share the same parsed object `getLayoutElements`
53464
+ * already populated.
53465
+ */
53466
+ async resolveCachedLayoutXml(layoutPath) {
53467
+ const cached = this.layoutXmlMap.get(layoutPath);
53468
+ if (cached) {
53469
+ return cached;
53470
+ }
53471
+ const xml = await this.zip.file(layoutPath)?.async("string");
53472
+ if (!xml) {
53473
+ return void 0;
53474
+ }
53475
+ const parsed = this.parser.parse(xml);
53476
+ this.layoutXmlMap.set(layoutPath, parsed);
53477
+ return parsed;
53478
+ }
53479
+ /** Reuse the cached parse of a master XML part, parsing (and caching) on a miss. */
53480
+ async resolveCachedMasterXml(masterPath) {
53481
+ const cached = this.masterXmlMap.get(masterPath);
53482
+ if (cached) {
53483
+ return cached;
53484
+ }
53485
+ const xml = await this.zip.file(masterPath)?.async("string");
53486
+ if (!xml) {
53487
+ return void 0;
53488
+ }
53489
+ const parsed = this.parser.parse(xml);
53490
+ this.masterXmlMap.set(masterPath, parsed);
53491
+ return parsed;
53492
+ }
53393
53493
  async getMasterBackgroundImage(layoutPath) {
53394
53494
  const layoutRels = this.slideRelsMap.get(layoutPath);
53395
53495
  if (!layoutRels) {
@@ -53400,9 +53500,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53400
53500
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53401
53501
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53402
53502
  try {
53403
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53404
- if (masterXmlStr) {
53405
- const masterXmlObj = this.parser.parse(masterXmlStr);
53503
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53504
+ if (masterXmlObj) {
53406
53505
  const masterRelsPath = `${masterPath.replace("slideMasters/", "slideMasters/_rels/")}.rels`;
53407
53506
  await this.loadSlideRelationships(masterPath, masterRelsPath);
53408
53507
  return this.extractBackgroundImage(masterXmlObj, masterPath, "p:sldMaster");
@@ -53424,9 +53523,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53424
53523
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53425
53524
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53426
53525
  try {
53427
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53428
- if (layoutXmlStr) {
53429
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53526
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53527
+ if (layoutXmlObj) {
53430
53528
  const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
53431
53529
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
53432
53530
  const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
@@ -53452,9 +53550,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53452
53550
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53453
53551
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53454
53552
  try {
53455
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53456
- if (layoutXmlStr) {
53457
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53553
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53554
+ if (layoutXmlObj) {
53458
53555
  const layoutBg = this.extractBackgroundColor(layoutXmlObj, "p:sldLayout");
53459
53556
  if (layoutBg) {
53460
53557
  return layoutBg;
@@ -53481,9 +53578,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53481
53578
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53482
53579
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53483
53580
  try {
53484
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53485
- if (masterXmlStr) {
53486
- const masterXmlObj = this.parser.parse(masterXmlStr);
53581
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53582
+ if (masterXmlObj) {
53487
53583
  return this.extractBackgroundColor(masterXmlObj, "p:sldMaster");
53488
53584
  }
53489
53585
  } catch {
@@ -53510,9 +53606,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53510
53606
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53511
53607
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53512
53608
  try {
53513
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53514
- if (layoutXmlStr) {
53515
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53609
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53610
+ if (layoutXmlObj) {
53516
53611
  const layoutGrad = this.extractBackgroundGradient(layoutXmlObj, "p:sldLayout");
53517
53612
  if (layoutGrad) {
53518
53613
  return layoutGrad;
@@ -53539,9 +53634,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53539
53634
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53540
53635
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53541
53636
  try {
53542
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53543
- if (masterXmlStr) {
53544
- const masterXmlObj = this.parser.parse(masterXmlStr);
53637
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53638
+ if (masterXmlObj) {
53545
53639
  return this.extractBackgroundGradient(masterXmlObj, "p:sldMaster");
53546
53640
  }
53547
53641
  } catch {
@@ -54349,6 +54443,21 @@ var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
54349
54443
  element.id = `master-${element.id}`;
54350
54444
  elements.push(element);
54351
54445
  }
54446
+ } else if (entry.tag === "p:grpSp") {
54447
+ const groups = this.ensureArray(spTree["p:grpSp"]);
54448
+ const group = groups[entry.indexInType];
54449
+ if (!group) {
54450
+ continue;
54451
+ }
54452
+ const element = await this.parseGroupShapeAsGroup(
54453
+ group,
54454
+ `master-group-${masterToken}-${entry.indexInType}`,
54455
+ masterPath
54456
+ );
54457
+ if (element) {
54458
+ element.id = `master-${element.id}`;
54459
+ elements.push(element);
54460
+ }
54352
54461
  }
54353
54462
  }
54354
54463
  this.masterCache.set(masterPath, elements);
@@ -54560,6 +54669,21 @@ var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
54560
54669
  element.id = `layout-${element.id}`;
54561
54670
  elements.push(element);
54562
54671
  }
54672
+ } else if (entry.tag === "p:grpSp") {
54673
+ const groups = this.ensureArray(spTree["p:grpSp"]);
54674
+ const group = groups[entry.indexInType];
54675
+ if (!group) {
54676
+ continue;
54677
+ }
54678
+ const element = await this.parseGroupShapeAsGroup(
54679
+ group,
54680
+ `layout-group-${layoutToken}-${entry.indexInType}`,
54681
+ layoutPath
54682
+ );
54683
+ if (element) {
54684
+ element.id = `layout-${element.id}`;
54685
+ elements.push(element);
54686
+ }
54563
54687
  }
54564
54688
  }
54565
54689
  const layoutShowMasterSp = xmlAttr(
@@ -1,2 +1,2 @@
1
- import { _ as FileSystemAdapter, a as SlideProcessorOptions, c as DocumentConverter, d as normalizePath, f as MediaContext, g as ConversionResult, h as ConversionOptions, i as SlideProcessor, l as deriveOutputPath, m as generateMediaFilename, n as SvgExporter, o as PptxConverterOptions, p as dataUrlToMediaBytes, r as SlideMetadataRenderer, s as PptxMarkdownConverter, t as SvgExportOptions, u as getDirectory } from "../index-BmCX2W7T.js";
1
+ import { _ as FileSystemAdapter, a as SlideProcessorOptions, c as DocumentConverter, d as normalizePath, f as MediaContext, g as ConversionResult, h as ConversionOptions, i as SlideProcessor, l as deriveOutputPath, m as generateMediaFilename, n as SvgExporter, o as PptxConverterOptions, p as dataUrlToMediaBytes, r as SlideMetadataRenderer, s as PptxMarkdownConverter, t as SvgExportOptions, u as getDirectory } from "../index-jDlq3aEH.js";
2
2
  export { type ConversionOptions, type ConversionResult, DocumentConverter, type FileSystemAdapter, MediaContext, type PptxConverterOptions, PptxMarkdownConverter, SlideMetadataRenderer, SlideProcessor, type SlideProcessorOptions, type SvgExportOptions, SvgExporter, dataUrlToMediaBytes, deriveOutputPath, generateMediaFilename, getDirectory, normalizePath };