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/dist/index.js CHANGED
@@ -497,14 +497,52 @@ function extractSourceOrders(xml) {
497
497
  }
498
498
  return orders;
499
499
  }
500
+ function ensureArrayLocal(value) {
501
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
502
+ }
503
+ function countsSignature(counts) {
504
+ return [...counts.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1).map(([name, count]) => `${name}:${count}`).join(",");
505
+ }
506
+ function pathSignature(path) {
507
+ const counts = /* @__PURE__ */ new Map();
508
+ for (const key of Object.keys(path)) {
509
+ const name = localName(key);
510
+ if (!PATH_COMMANDS.has(name)) {
511
+ continue;
512
+ }
513
+ counts.set(name, (counts.get(name) ?? 0) + ensureArrayLocal(path[key]).length);
514
+ }
515
+ return countsSignature(counts);
516
+ }
517
+ function orderSignature(order) {
518
+ const counts = /* @__PURE__ */ new Map();
519
+ for (const name of order) {
520
+ counts.set(name, (counts.get(name) ?? 0) + 1);
521
+ }
522
+ return countsSignature(counts);
523
+ }
500
524
  function annotateCustomGeometryCommandOrder(xml, parsed) {
501
525
  const orders = extractSourceOrders(xml);
502
526
  if (orders.length === 0) {
503
527
  return;
504
528
  }
505
529
  const paths = collectParsedPaths(parsed);
506
- for (let index = 0; index < Math.min(paths.length, orders.length); index++) {
507
- commandOrder.set(paths[index], orders[index]);
530
+ const ordersBySignature = /* @__PURE__ */ new Map();
531
+ for (const order of orders) {
532
+ const signature = orderSignature(order);
533
+ const bucket = ordersBySignature.get(signature);
534
+ if (bucket) {
535
+ bucket.push(order);
536
+ } else {
537
+ ordersBySignature.set(signature, [order]);
538
+ }
539
+ }
540
+ for (const path of paths) {
541
+ const bucket = ordersBySignature.get(pathSignature(path));
542
+ const order = bucket?.shift();
543
+ if (order) {
544
+ commandOrder.set(path, order);
545
+ }
508
546
  }
509
547
  }
510
548
  function orderedPathCommandEntries(path, ensureArray16) {
@@ -61009,6 +61047,8 @@ var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
61009
61047
  const existing = merged[key];
61010
61048
  if (value && typeof value === "object" && !Array.isArray(value) && existing && typeof existing === "object" && !Array.isArray(existing)) {
61011
61049
  merged[key] = this.mergeXmlObjects(existing, value, depth + 1);
61050
+ } else if (value === "" && existing !== void 0 && existing !== "" && typeof existing === "object") {
61051
+ merged[key] = existing;
61012
61052
  } else {
61013
61053
  merged[key] = value;
61014
61054
  }
@@ -63791,32 +63831,56 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63791
63831
  }
63792
63832
  const grpSpPr = group["p:grpSpPr"];
63793
63833
  const xfrm = grpSpPr?.["a:xfrm"];
63834
+ const EMU_PX = _PptxHandlerRuntime.EMU_PER_PX;
63794
63835
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
63795
63836
  let chX = 0, chY = 0, chW = 0, chH = 0;
63796
63837
  if (xfrm) {
63797
63838
  const off = xfrm["a:off"];
63798
63839
  if (off) {
63799
- parentX = Math.round(parseEmuInt2(off["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
63800
- parentY = Math.round(parseEmuInt2(off["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
63840
+ parentX = parseEmuInt2(off["@_x"]) / EMU_PX;
63841
+ parentY = parseEmuInt2(off["@_y"]) / EMU_PX;
63801
63842
  }
63802
63843
  const ext = xfrm["a:ext"];
63803
63844
  if (ext) {
63804
- parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63805
- parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63845
+ parentW = parseEmuInt2(ext["@_cx"]) / EMU_PX;
63846
+ parentH = parseEmuInt2(ext["@_cy"]) / EMU_PX;
63806
63847
  }
63807
63848
  const chOff = xfrm["a:chOff"];
63808
63849
  if (chOff) {
63809
- chX = Math.round(parseEmuInt2(chOff["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
63810
- chY = Math.round(parseEmuInt2(chOff["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
63850
+ chX = parseEmuInt2(chOff["@_x"]) / EMU_PX;
63851
+ chY = parseEmuInt2(chOff["@_y"]) / EMU_PX;
63811
63852
  }
63812
63853
  const chExt = xfrm["a:chExt"];
63813
63854
  if (chExt) {
63814
- chW = Math.round(parseEmuInt2(chExt["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63815
- chH = Math.round(parseEmuInt2(chExt["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63855
+ chW = parseEmuInt2(chExt["@_cx"]) / EMU_PX;
63856
+ chH = parseEmuInt2(chExt["@_cy"]) / EMU_PX;
63816
63857
  }
63817
63858
  }
63818
63859
  const scaleX = chW > 0 ? parentW / chW : 1;
63819
63860
  const scaleY = chH > 0 ? parentH / chH : 1;
63861
+ const rawChildXfrm = (childNode) => {
63862
+ if (!childNode) {
63863
+ return void 0;
63864
+ }
63865
+ const childXfrm = childNode["p:spPr"]?.["a:xfrm"] ?? childNode["p:xfrm"];
63866
+ return childXfrm;
63867
+ };
63868
+ const applyRawChildGeometry = (el, childNode) => {
63869
+ const childXfrm = rawChildXfrm(childNode);
63870
+ if (!childXfrm) {
63871
+ return;
63872
+ }
63873
+ const off = childXfrm["a:off"];
63874
+ const ext = childXfrm["a:ext"];
63875
+ if (off) {
63876
+ el.x = parseEmuInt2(off["@_x"]) / EMU_PX;
63877
+ el.y = parseEmuInt2(off["@_y"]) / EMU_PX;
63878
+ }
63879
+ if (ext) {
63880
+ el.width = parseEmuInt2(ext["@_cx"]) / EMU_PX;
63881
+ el.height = parseEmuInt2(ext["@_cy"]) / EMU_PX;
63882
+ }
63883
+ };
63820
63884
  const transformElement = (el) => {
63821
63885
  const relativeX = el.x - chX;
63822
63886
  const relativeY = el.y - chY;
@@ -63874,6 +63938,8 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63874
63938
  `${baseId}-`
63875
63939
  );
63876
63940
  if (element) {
63941
+ const childNode = this.ensureArray(group[entry.tag])[entry.indexInType];
63942
+ applyRawChildGeometry(element, childNode);
63877
63943
  transformElement(element);
63878
63944
  elements2.push(element);
63879
63945
  }
@@ -64423,6 +64489,40 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64423
64489
  }
64424
64490
  return void 0;
64425
64491
  }
64492
+ /**
64493
+ * Reuse the cached parse of a layout XML part, parsing (and caching) on a
64494
+ * miss. Background resolution runs per slide but the layout/master parts are
64495
+ * large (a themed master can be ~200 KB); re-parsing them for every slide
64496
+ * dominated load time, so share the same parsed object `getLayoutElements`
64497
+ * already populated.
64498
+ */
64499
+ async resolveCachedLayoutXml(layoutPath) {
64500
+ const cached = this.layoutXmlMap.get(layoutPath);
64501
+ if (cached) {
64502
+ return cached;
64503
+ }
64504
+ const xml = await this.zip.file(layoutPath)?.async("string");
64505
+ if (!xml) {
64506
+ return void 0;
64507
+ }
64508
+ const parsed = this.parser.parse(xml);
64509
+ this.layoutXmlMap.set(layoutPath, parsed);
64510
+ return parsed;
64511
+ }
64512
+ /** Reuse the cached parse of a master XML part, parsing (and caching) on a miss. */
64513
+ async resolveCachedMasterXml(masterPath) {
64514
+ const cached = this.masterXmlMap.get(masterPath);
64515
+ if (cached) {
64516
+ return cached;
64517
+ }
64518
+ const xml = await this.zip.file(masterPath)?.async("string");
64519
+ if (!xml) {
64520
+ return void 0;
64521
+ }
64522
+ const parsed = this.parser.parse(xml);
64523
+ this.masterXmlMap.set(masterPath, parsed);
64524
+ return parsed;
64525
+ }
64426
64526
  async getMasterBackgroundImage(layoutPath) {
64427
64527
  const layoutRels = this.slideRelsMap.get(layoutPath);
64428
64528
  if (!layoutRels) {
@@ -64433,9 +64533,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64433
64533
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
64434
64534
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
64435
64535
  try {
64436
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
64437
- if (masterXmlStr) {
64438
- const masterXmlObj = this.parser.parse(masterXmlStr);
64536
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
64537
+ if (masterXmlObj) {
64439
64538
  const masterRelsPath = `${masterPath.replace("slideMasters/", "slideMasters/_rels/")}.rels`;
64440
64539
  await this.loadSlideRelationships(masterPath, masterRelsPath);
64441
64540
  return this.extractBackgroundImage(masterXmlObj, masterPath, "p:sldMaster");
@@ -64457,9 +64556,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64457
64556
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
64458
64557
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
64459
64558
  try {
64460
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
64461
- if (layoutXmlStr) {
64462
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
64559
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
64560
+ if (layoutXmlObj) {
64463
64561
  const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
64464
64562
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
64465
64563
  const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
@@ -64485,9 +64583,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64485
64583
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
64486
64584
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
64487
64585
  try {
64488
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
64489
- if (layoutXmlStr) {
64490
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
64586
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
64587
+ if (layoutXmlObj) {
64491
64588
  const layoutBg = this.extractBackgroundColor(layoutXmlObj, "p:sldLayout");
64492
64589
  if (layoutBg) {
64493
64590
  return layoutBg;
@@ -64514,9 +64611,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64514
64611
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
64515
64612
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
64516
64613
  try {
64517
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
64518
- if (masterXmlStr) {
64519
- const masterXmlObj = this.parser.parse(masterXmlStr);
64614
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
64615
+ if (masterXmlObj) {
64520
64616
  return this.extractBackgroundColor(masterXmlObj, "p:sldMaster");
64521
64617
  }
64522
64618
  } catch {
@@ -64543,9 +64639,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
64543
64639
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
64544
64640
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
64545
64641
  try {
64546
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
64547
- if (layoutXmlStr) {
64548
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
64642
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
64643
+ if (layoutXmlObj) {
64549
64644
  const layoutGrad = this.extractBackgroundGradient(layoutXmlObj, "p:sldLayout");
64550
64645
  if (layoutGrad) {
64551
64646
  return layoutGrad;
@@ -64572,9 +64667,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
64572
64667
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
64573
64668
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
64574
64669
  try {
64575
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
64576
- if (masterXmlStr) {
64577
- const masterXmlObj = this.parser.parse(masterXmlStr);
64670
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
64671
+ if (masterXmlObj) {
64578
64672
  return this.extractBackgroundGradient(masterXmlObj, "p:sldMaster");
64579
64673
  }
64580
64674
  } catch {
@@ -65382,6 +65476,21 @@ var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
65382
65476
  element.id = `master-${element.id}`;
65383
65477
  elements2.push(element);
65384
65478
  }
65479
+ } else if (entry.tag === "p:grpSp") {
65480
+ const groups = this.ensureArray(spTree["p:grpSp"]);
65481
+ const group = groups[entry.indexInType];
65482
+ if (!group) {
65483
+ continue;
65484
+ }
65485
+ const element = await this.parseGroupShapeAsGroup(
65486
+ group,
65487
+ `master-group-${masterToken}-${entry.indexInType}`,
65488
+ masterPath
65489
+ );
65490
+ if (element) {
65491
+ element.id = `master-${element.id}`;
65492
+ elements2.push(element);
65493
+ }
65385
65494
  }
65386
65495
  }
65387
65496
  this.masterCache.set(masterPath, elements2);
@@ -65593,6 +65702,21 @@ var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
65593
65702
  element.id = `layout-${element.id}`;
65594
65703
  elements2.push(element);
65595
65704
  }
65705
+ } else if (entry.tag === "p:grpSp") {
65706
+ const groups = this.ensureArray(spTree["p:grpSp"]);
65707
+ const group = groups[entry.indexInType];
65708
+ if (!group) {
65709
+ continue;
65710
+ }
65711
+ const element = await this.parseGroupShapeAsGroup(
65712
+ group,
65713
+ `layout-group-${layoutToken}-${entry.indexInType}`,
65714
+ layoutPath
65715
+ );
65716
+ if (element) {
65717
+ element.id = `layout-${element.id}`;
65718
+ elements2.push(element);
65719
+ }
65596
65720
  }
65597
65721
  }
65598
65722
  const layoutShowMasterSp = xmlAttr(
package/dist/index.mjs CHANGED
@@ -492,14 +492,52 @@ function extractSourceOrders(xml) {
492
492
  }
493
493
  return orders;
494
494
  }
495
+ function ensureArrayLocal(value) {
496
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
497
+ }
498
+ function countsSignature(counts) {
499
+ return [...counts.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1).map(([name, count]) => `${name}:${count}`).join(",");
500
+ }
501
+ function pathSignature(path) {
502
+ const counts = /* @__PURE__ */ new Map();
503
+ for (const key of Object.keys(path)) {
504
+ const name = localName(key);
505
+ if (!PATH_COMMANDS.has(name)) {
506
+ continue;
507
+ }
508
+ counts.set(name, (counts.get(name) ?? 0) + ensureArrayLocal(path[key]).length);
509
+ }
510
+ return countsSignature(counts);
511
+ }
512
+ function orderSignature(order) {
513
+ const counts = /* @__PURE__ */ new Map();
514
+ for (const name of order) {
515
+ counts.set(name, (counts.get(name) ?? 0) + 1);
516
+ }
517
+ return countsSignature(counts);
518
+ }
495
519
  function annotateCustomGeometryCommandOrder(xml, parsed) {
496
520
  const orders = extractSourceOrders(xml);
497
521
  if (orders.length === 0) {
498
522
  return;
499
523
  }
500
524
  const paths = collectParsedPaths(parsed);
501
- for (let index = 0; index < Math.min(paths.length, orders.length); index++) {
502
- commandOrder.set(paths[index], orders[index]);
525
+ const ordersBySignature = /* @__PURE__ */ new Map();
526
+ for (const order of orders) {
527
+ const signature = orderSignature(order);
528
+ const bucket = ordersBySignature.get(signature);
529
+ if (bucket) {
530
+ bucket.push(order);
531
+ } else {
532
+ ordersBySignature.set(signature, [order]);
533
+ }
534
+ }
535
+ for (const path of paths) {
536
+ const bucket = ordersBySignature.get(pathSignature(path));
537
+ const order = bucket?.shift();
538
+ if (order) {
539
+ commandOrder.set(path, order);
540
+ }
503
541
  }
504
542
  }
505
543
  function orderedPathCommandEntries(path, ensureArray16) {
@@ -61004,6 +61042,8 @@ var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
61004
61042
  const existing = merged[key];
61005
61043
  if (value && typeof value === "object" && !Array.isArray(value) && existing && typeof existing === "object" && !Array.isArray(existing)) {
61006
61044
  merged[key] = this.mergeXmlObjects(existing, value, depth + 1);
61045
+ } else if (value === "" && existing !== void 0 && existing !== "" && typeof existing === "object") {
61046
+ merged[key] = existing;
61007
61047
  } else {
61008
61048
  merged[key] = value;
61009
61049
  }
@@ -63786,32 +63826,56 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63786
63826
  }
63787
63827
  const grpSpPr = group["p:grpSpPr"];
63788
63828
  const xfrm = grpSpPr?.["a:xfrm"];
63829
+ const EMU_PX = _PptxHandlerRuntime.EMU_PER_PX;
63789
63830
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
63790
63831
  let chX = 0, chY = 0, chW = 0, chH = 0;
63791
63832
  if (xfrm) {
63792
63833
  const off = xfrm["a:off"];
63793
63834
  if (off) {
63794
- parentX = Math.round(parseEmuInt2(off["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
63795
- parentY = Math.round(parseEmuInt2(off["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
63835
+ parentX = parseEmuInt2(off["@_x"]) / EMU_PX;
63836
+ parentY = parseEmuInt2(off["@_y"]) / EMU_PX;
63796
63837
  }
63797
63838
  const ext = xfrm["a:ext"];
63798
63839
  if (ext) {
63799
- parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63800
- parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63840
+ parentW = parseEmuInt2(ext["@_cx"]) / EMU_PX;
63841
+ parentH = parseEmuInt2(ext["@_cy"]) / EMU_PX;
63801
63842
  }
63802
63843
  const chOff = xfrm["a:chOff"];
63803
63844
  if (chOff) {
63804
- chX = Math.round(parseEmuInt2(chOff["@_x"]) / _PptxHandlerRuntime.EMU_PER_PX);
63805
- chY = Math.round(parseEmuInt2(chOff["@_y"]) / _PptxHandlerRuntime.EMU_PER_PX);
63845
+ chX = parseEmuInt2(chOff["@_x"]) / EMU_PX;
63846
+ chY = parseEmuInt2(chOff["@_y"]) / EMU_PX;
63806
63847
  }
63807
63848
  const chExt = xfrm["a:chExt"];
63808
63849
  if (chExt) {
63809
- chW = Math.round(parseEmuInt2(chExt["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63810
- chH = Math.round(parseEmuInt2(chExt["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63850
+ chW = parseEmuInt2(chExt["@_cx"]) / EMU_PX;
63851
+ chH = parseEmuInt2(chExt["@_cy"]) / EMU_PX;
63811
63852
  }
63812
63853
  }
63813
63854
  const scaleX = chW > 0 ? parentW / chW : 1;
63814
63855
  const scaleY = chH > 0 ? parentH / chH : 1;
63856
+ const rawChildXfrm = (childNode) => {
63857
+ if (!childNode) {
63858
+ return void 0;
63859
+ }
63860
+ const childXfrm = childNode["p:spPr"]?.["a:xfrm"] ?? childNode["p:xfrm"];
63861
+ return childXfrm;
63862
+ };
63863
+ const applyRawChildGeometry = (el, childNode) => {
63864
+ const childXfrm = rawChildXfrm(childNode);
63865
+ if (!childXfrm) {
63866
+ return;
63867
+ }
63868
+ const off = childXfrm["a:off"];
63869
+ const ext = childXfrm["a:ext"];
63870
+ if (off) {
63871
+ el.x = parseEmuInt2(off["@_x"]) / EMU_PX;
63872
+ el.y = parseEmuInt2(off["@_y"]) / EMU_PX;
63873
+ }
63874
+ if (ext) {
63875
+ el.width = parseEmuInt2(ext["@_cx"]) / EMU_PX;
63876
+ el.height = parseEmuInt2(ext["@_cy"]) / EMU_PX;
63877
+ }
63878
+ };
63815
63879
  const transformElement = (el) => {
63816
63880
  const relativeX = el.x - chX;
63817
63881
  const relativeY = el.y - chY;
@@ -63869,6 +63933,8 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63869
63933
  `${baseId}-`
63870
63934
  );
63871
63935
  if (element) {
63936
+ const childNode = this.ensureArray(group[entry.tag])[entry.indexInType];
63937
+ applyRawChildGeometry(element, childNode);
63872
63938
  transformElement(element);
63873
63939
  elements2.push(element);
63874
63940
  }
@@ -64418,6 +64484,40 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64418
64484
  }
64419
64485
  return void 0;
64420
64486
  }
64487
+ /**
64488
+ * Reuse the cached parse of a layout XML part, parsing (and caching) on a
64489
+ * miss. Background resolution runs per slide but the layout/master parts are
64490
+ * large (a themed master can be ~200 KB); re-parsing them for every slide
64491
+ * dominated load time, so share the same parsed object `getLayoutElements`
64492
+ * already populated.
64493
+ */
64494
+ async resolveCachedLayoutXml(layoutPath) {
64495
+ const cached = this.layoutXmlMap.get(layoutPath);
64496
+ if (cached) {
64497
+ return cached;
64498
+ }
64499
+ const xml = await this.zip.file(layoutPath)?.async("string");
64500
+ if (!xml) {
64501
+ return void 0;
64502
+ }
64503
+ const parsed = this.parser.parse(xml);
64504
+ this.layoutXmlMap.set(layoutPath, parsed);
64505
+ return parsed;
64506
+ }
64507
+ /** Reuse the cached parse of a master XML part, parsing (and caching) on a miss. */
64508
+ async resolveCachedMasterXml(masterPath) {
64509
+ const cached = this.masterXmlMap.get(masterPath);
64510
+ if (cached) {
64511
+ return cached;
64512
+ }
64513
+ const xml = await this.zip.file(masterPath)?.async("string");
64514
+ if (!xml) {
64515
+ return void 0;
64516
+ }
64517
+ const parsed = this.parser.parse(xml);
64518
+ this.masterXmlMap.set(masterPath, parsed);
64519
+ return parsed;
64520
+ }
64421
64521
  async getMasterBackgroundImage(layoutPath) {
64422
64522
  const layoutRels = this.slideRelsMap.get(layoutPath);
64423
64523
  if (!layoutRels) {
@@ -64428,9 +64528,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64428
64528
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
64429
64529
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
64430
64530
  try {
64431
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
64432
- if (masterXmlStr) {
64433
- const masterXmlObj = this.parser.parse(masterXmlStr);
64531
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
64532
+ if (masterXmlObj) {
64434
64533
  const masterRelsPath = `${masterPath.replace("slideMasters/", "slideMasters/_rels/")}.rels`;
64435
64534
  await this.loadSlideRelationships(masterPath, masterRelsPath);
64436
64535
  return this.extractBackgroundImage(masterXmlObj, masterPath, "p:sldMaster");
@@ -64452,9 +64551,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64452
64551
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
64453
64552
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
64454
64553
  try {
64455
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
64456
- if (layoutXmlStr) {
64457
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
64554
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
64555
+ if (layoutXmlObj) {
64458
64556
  const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
64459
64557
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
64460
64558
  const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
@@ -64480,9 +64578,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64480
64578
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
64481
64579
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
64482
64580
  try {
64483
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
64484
- if (layoutXmlStr) {
64485
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
64581
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
64582
+ if (layoutXmlObj) {
64486
64583
  const layoutBg = this.extractBackgroundColor(layoutXmlObj, "p:sldLayout");
64487
64584
  if (layoutBg) {
64488
64585
  return layoutBg;
@@ -64509,9 +64606,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
64509
64606
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
64510
64607
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
64511
64608
  try {
64512
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
64513
- if (masterXmlStr) {
64514
- const masterXmlObj = this.parser.parse(masterXmlStr);
64609
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
64610
+ if (masterXmlObj) {
64515
64611
  return this.extractBackgroundColor(masterXmlObj, "p:sldMaster");
64516
64612
  }
64517
64613
  } catch {
@@ -64538,9 +64634,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
64538
64634
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
64539
64635
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
64540
64636
  try {
64541
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
64542
- if (layoutXmlStr) {
64543
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
64637
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
64638
+ if (layoutXmlObj) {
64544
64639
  const layoutGrad = this.extractBackgroundGradient(layoutXmlObj, "p:sldLayout");
64545
64640
  if (layoutGrad) {
64546
64641
  return layoutGrad;
@@ -64567,9 +64662,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
64567
64662
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
64568
64663
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
64569
64664
  try {
64570
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
64571
- if (masterXmlStr) {
64572
- const masterXmlObj = this.parser.parse(masterXmlStr);
64665
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
64666
+ if (masterXmlObj) {
64573
64667
  return this.extractBackgroundGradient(masterXmlObj, "p:sldMaster");
64574
64668
  }
64575
64669
  } catch {
@@ -65377,6 +65471,21 @@ var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
65377
65471
  element.id = `master-${element.id}`;
65378
65472
  elements2.push(element);
65379
65473
  }
65474
+ } else if (entry.tag === "p:grpSp") {
65475
+ const groups = this.ensureArray(spTree["p:grpSp"]);
65476
+ const group = groups[entry.indexInType];
65477
+ if (!group) {
65478
+ continue;
65479
+ }
65480
+ const element = await this.parseGroupShapeAsGroup(
65481
+ group,
65482
+ `master-group-${masterToken}-${entry.indexInType}`,
65483
+ masterPath
65484
+ );
65485
+ if (element) {
65486
+ element.id = `master-${element.id}`;
65487
+ elements2.push(element);
65488
+ }
65380
65489
  }
65381
65490
  }
65382
65491
  this.masterCache.set(masterPath, elements2);
@@ -65588,6 +65697,21 @@ var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
65588
65697
  element.id = `layout-${element.id}`;
65589
65698
  elements2.push(element);
65590
65699
  }
65700
+ } else if (entry.tag === "p:grpSp") {
65701
+ const groups = this.ensureArray(spTree["p:grpSp"]);
65702
+ const group = groups[entry.indexInType];
65703
+ if (!group) {
65704
+ continue;
65705
+ }
65706
+ const element = await this.parseGroupShapeAsGroup(
65707
+ group,
65708
+ `layout-group-${layoutToken}-${entry.indexInType}`,
65709
+ layoutPath
65710
+ );
65711
+ if (element) {
65712
+ element.id = `layout-${element.id}`;
65713
+ elements2.push(element);
65714
+ }
65591
65715
  }
65592
65716
  }
65593
65717
  const layoutShowMasterSp = xmlAttr(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptx-viewer-core",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "PowerPoint PPTX engine: parse, edit, serialize, and convert .pptx files. Framework-agnostic TypeScript SDK.",
5
5
  "keywords": [
6
6
  "angular",