pptx-viewer-core 1.6.7 → 1.6.9

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
@@ -7253,36 +7253,200 @@ async function fetchUrlToBytes(url, options = {}) {
7253
7253
  }
7254
7254
  }
7255
7255
 
7256
+ // src/core/utils/inkml-trace-decode.ts
7257
+ function resolveChannelOrder(root) {
7258
+ const traceFormat = findFirstByLocalName(root, "traceFormat");
7259
+ if (!traceFormat) {
7260
+ return ["X", "Y"];
7261
+ }
7262
+ const channels = ensureArray(nsGet(traceFormat, "channel"));
7263
+ const names = channels.map(
7264
+ (channel) => String(nsAttr(channel, "name") ?? "").trim().toUpperCase()
7265
+ ).filter((name) => name.length > 0);
7266
+ return names.length > 0 ? names : ["X", "Y"];
7267
+ }
7268
+ function decodeTracePoints(text2, channelOrder) {
7269
+ const points3 = [];
7270
+ const modes = channelOrder.map(() => "explicit");
7271
+ const lastValue = channelOrder.map(() => 0);
7272
+ const lastVelocity = channelOrder.map(() => 0);
7273
+ for (const rawPoint of text2.split(",")) {
7274
+ const tokens = rawPoint.trim().split(/\s+/u).filter((token2) => token2.length > 0);
7275
+ if (tokens.length === 0) {
7276
+ continue;
7277
+ }
7278
+ const decoded = [];
7279
+ for (let i = 0; i < tokens.length && i < channelOrder.length; i++) {
7280
+ const parsed = parseValueToken(tokens[i], modes[i]);
7281
+ if (parsed === void 0) {
7282
+ decoded.push(lastValue[i]);
7283
+ continue;
7284
+ }
7285
+ modes[i] = parsed.mode;
7286
+ const value = applyDiffMode(parsed, i, lastValue, lastVelocity);
7287
+ decoded.push(value);
7288
+ }
7289
+ if (decoded.length >= 2) {
7290
+ points3.push(decoded);
7291
+ }
7292
+ }
7293
+ return points3;
7294
+ }
7295
+ function parseValueToken(token2, currentMode) {
7296
+ let mode = currentMode;
7297
+ let body = token2;
7298
+ const prefix = token2[0];
7299
+ if (prefix === "!") {
7300
+ mode = "explicit";
7301
+ body = token2.slice(1);
7302
+ } else if (prefix === "'") {
7303
+ mode = "single";
7304
+ body = token2.slice(1);
7305
+ } else if (prefix === '"') {
7306
+ mode = "double";
7307
+ body = token2.slice(1);
7308
+ }
7309
+ if (body.length === 0) {
7310
+ return void 0;
7311
+ }
7312
+ const value = Number(body);
7313
+ return Number.isFinite(value) ? { value, mode } : void 0;
7314
+ }
7315
+ function applyDiffMode(parsed, index, lastValue, lastVelocity) {
7316
+ if (parsed.mode === "single") {
7317
+ lastVelocity[index] = parsed.value;
7318
+ lastValue[index] += parsed.value;
7319
+ } else if (parsed.mode === "double") {
7320
+ lastVelocity[index] += parsed.value;
7321
+ lastValue[index] += lastVelocity[index];
7322
+ } else {
7323
+ lastValue[index] = parsed.value;
7324
+ lastVelocity[index] = 0;
7325
+ }
7326
+ return lastValue[index];
7327
+ }
7328
+ function pointsToSvgPath(points3, channelOrder) {
7329
+ const xi = channelOrder.indexOf("X");
7330
+ const yi = channelOrder.indexOf("Y");
7331
+ const xIndex = xi >= 0 ? xi : 0;
7332
+ const yIndex = yi >= 0 ? yi : 1;
7333
+ const segments = [];
7334
+ for (const point of points3) {
7335
+ const x = point[xIndex];
7336
+ const y = point[yIndex];
7337
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
7338
+ continue;
7339
+ }
7340
+ segments.push(`${segments.length === 0 ? "M" : "L"} ${x} ${y}`);
7341
+ }
7342
+ return segments.join(" ");
7343
+ }
7344
+ function pointsToPressures(points3, channelOrder) {
7345
+ const fIndex = channelOrder.indexOf("F");
7346
+ if (fIndex < 0) {
7347
+ return [];
7348
+ }
7349
+ const pressures = [];
7350
+ for (const point of points3) {
7351
+ const raw = point[fIndex];
7352
+ if (Number.isFinite(raw)) {
7353
+ const normalised = raw > 1 ? raw / 32767 : raw;
7354
+ pressures.push(Math.max(0, Math.min(1, normalised)));
7355
+ }
7356
+ }
7357
+ return pressures;
7358
+ }
7359
+ function nsGet(obj, localName21) {
7360
+ if (localName21 in obj) {
7361
+ return obj[localName21];
7362
+ }
7363
+ for (const key of Object.keys(obj)) {
7364
+ if (localNameOf(key) === localName21 && !key.startsWith("@_")) {
7365
+ return obj[key];
7366
+ }
7367
+ }
7368
+ return void 0;
7369
+ }
7370
+ function nsAttr(obj, localName21) {
7371
+ const direct = obj[`@_${localName21}`];
7372
+ if (direct !== void 0) {
7373
+ return direct;
7374
+ }
7375
+ for (const key of Object.keys(obj)) {
7376
+ if (key.startsWith("@_") && localNameOf(key.slice(2)) === localName21) {
7377
+ return obj[key];
7378
+ }
7379
+ }
7380
+ return void 0;
7381
+ }
7382
+ function localNameOf(key) {
7383
+ const colon = key.indexOf(":");
7384
+ return colon >= 0 ? key.slice(colon + 1) : key;
7385
+ }
7386
+ function findFirstByLocalName(node, localName21) {
7387
+ const direct = nsGet(node, localName21);
7388
+ if (direct && typeof direct === "object") {
7389
+ return Array.isArray(direct) ? direct[0] : direct;
7390
+ }
7391
+ for (const key of Object.keys(node)) {
7392
+ if (key.startsWith("@_") || key === "#text") {
7393
+ continue;
7394
+ }
7395
+ for (const child20 of ensureArray(node[key])) {
7396
+ if (typeof child20 !== "object") {
7397
+ continue;
7398
+ }
7399
+ const found = findFirstByLocalName(child20, localName21);
7400
+ if (found) {
7401
+ return found;
7402
+ }
7403
+ }
7404
+ }
7405
+ return void 0;
7406
+ }
7407
+ function ensureArray(value) {
7408
+ if (value === void 0 || value === null) {
7409
+ return [];
7410
+ }
7411
+ return Array.isArray(value) ? value : [value];
7412
+ }
7413
+
7256
7414
  // src/core/utils/inkml-content-part.ts
7257
7415
  var INKML_NAMESPACE = "http://www.w3.org/2003/InkML";
7258
7416
  var METADATA_NAMESPACE = "https://pptx-viewer.dev/inkml/metadata";
7259
7417
  function parseInkMlContent(data) {
7260
- const root = data["ink:ink"] ?? data["ink"];
7418
+ const root = nsGet(data, "ink") ?? data["ink"];
7261
7419
  if (!root) {
7262
7420
  return { strokes: [], rawXml: data };
7263
7421
  }
7264
7422
  const brushes = /* @__PURE__ */ new Map();
7265
- for (const brush of ensureArray(root["ink:brush"] ?? root["brush"])) {
7266
- const properties = ensureArray(brush["ink:brushProperty"] ?? brush["brushProperty"]);
7423
+ for (const brush of ensureArray(nsGet(root, "brush"))) {
7424
+ const properties = ensureArray(nsGet(brush, "brushProperty"));
7267
7425
  const valueByName = new Map(
7268
- properties.map((property) => [String(property["@_name"] ?? ""), property["@_value"]])
7426
+ properties.map((property) => [
7427
+ String(nsAttr(property, "name") ?? ""),
7428
+ nsAttr(property, "value")
7429
+ ])
7269
7430
  );
7270
- brushes.set(String(brush["@_id"] ?? ""), {
7431
+ brushes.set(String(nsAttr(brush, "id") ?? ""), {
7271
7432
  color: String(valueByName.get("color") ?? "#000000"),
7272
7433
  width: finiteNumber(valueByName.get("width"), 1),
7273
7434
  opacity: finiteNumber(valueByName.get("opacity"), 1)
7274
7435
  });
7275
7436
  }
7437
+ const channelOrder = resolveChannelOrder(root);
7276
7438
  const strokes = [];
7277
- for (const trace of ensureArray(root["ink:trace"] ?? root["trace"])) {
7439
+ for (const trace of ensureArray(nsGet(root, "trace"))) {
7278
7440
  const text2 = typeof trace === "string" ? trace : String(trace["#text"] ?? "").trim();
7279
- const path2 = typeof trace === "string" ? text2 : String(trace["@_pva:path"] ?? "").trim() || text2;
7441
+ const authored = typeof trace === "string" ? "" : String(nsAttr(trace, "path") ?? "").trim();
7442
+ const points3 = authored ? [] : decodeTracePoints(text2, channelOrder);
7443
+ const path2 = authored || pointsToSvgPath(points3, channelOrder);
7280
7444
  if (!path2) {
7281
7445
  continue;
7282
7446
  }
7283
- const brushRef = typeof trace === "string" ? "" : String(trace["@_brushRef"] ?? "").replace("#", "");
7447
+ const brushRef = typeof trace === "string" ? "" : String(nsAttr(trace, "brushRef") ?? "").replace("#", "");
7284
7448
  const brush = brushes.get(brushRef) ?? { color: "#000000", width: 1, opacity: 1 };
7285
- const pressures = tracePressures(text2);
7449
+ const pressures = authored ? tracePressures(text2) : pointsToPressures(points3, channelOrder);
7286
7450
  strokes.push({ ...brush, path: path2, ...pressures.length > 0 ? { pressures } : {} });
7287
7451
  }
7288
7452
  return { strokes, rawXml: data };
@@ -7341,12 +7505,6 @@ function finiteNumber(value, fallback) {
7341
7505
  const parsed = Number(value);
7342
7506
  return Number.isFinite(parsed) ? parsed : fallback;
7343
7507
  }
7344
- function ensureArray(value) {
7345
- if (value === void 0 || value === null) {
7346
- return [];
7347
- }
7348
- return Array.isArray(value) ? value : [value];
7349
- }
7350
7508
 
7351
7509
  // src/core/utils/strip-parent-dir-segments.ts
7352
7510
  function stripParentDirSegments(path2) {
@@ -17266,7 +17424,7 @@ var MEDIA_REFERENCE_NAMES = [
17266
17424
  "videoFile",
17267
17425
  "quickTimeFile"
17268
17426
  ];
17269
- function parseDrawingMediaReference(container) {
17427
+ function parseDrawingMediaReference(container, externalRelIds) {
17270
17428
  if (!container) {
17271
17429
  return void 0;
17272
17430
  }
@@ -17275,11 +17433,17 @@ function parseDrawingMediaReference(container) {
17275
17433
  if (!node) {
17276
17434
  continue;
17277
17435
  }
17436
+ const linkId = String(attribute2(node, "link") ?? "").trim() || void 0;
17437
+ const embedId = String(attribute2(node, "embed") ?? "").trim() || void 0;
17278
17438
  return {
17279
17439
  kind,
17280
17440
  mediaType: kind === "videoFile" || kind === "quickTimeFile" ? "video" : "audio",
17281
- relationshipId: String(attribute2(node, "link") ?? attribute2(node, "embed") ?? "").trim() || void 0,
17282
- isLinked: attribute2(node, "link") !== void 0,
17441
+ relationshipId: linkId ?? embedId,
17442
+ // Embedded media legitimately uses r:link pointing at an INTERNAL
17443
+ // media part, so link presence alone does not imply a linked clip.
17444
+ // It is only truly linked when the referenced relationship is
17445
+ // external (TargetMode="External"), mirroring the OLE parser.
17446
+ isLinked: linkId !== void 0 && externalRelIds?.has(linkId) === true,
17283
17447
  name: kind === "wavAudioFile" ? String(attribute2(node, "name") ?? "") || void 0 : void 0,
17284
17448
  contentType: kind === "audioFile" ? String(attribute2(node, "contentType") ?? "") || void 0 : void 0,
17285
17449
  audioCdStart: kind === "audioCd" ? parseAudioCdPosition(child11(node, "st")) : void 0,
@@ -23610,26 +23774,49 @@ function applyScene3dStyle(shapeProps, style) {
23610
23774
  const camera = scene3dNode["a:camera"];
23611
23775
  const lightRig = scene3dNode["a:lightRig"];
23612
23776
  const cameraRot = camera?.["a:rot"];
23777
+ const lightRigRot = lightRig?.["a:rot"];
23613
23778
  style.scene3d = {
23614
23779
  cameraPreset: String(camera?.["@_prst"] || "").trim() || void 0,
23615
- cameraRotX: cameraRot?.["@_lat"] !== void 0 ? parseInt(String(cameraRot["@_lat"]), 10) : void 0,
23616
- cameraRotY: cameraRot?.["@_lon"] !== void 0 ? parseInt(String(cameraRot["@_lon"]), 10) : void 0,
23617
- cameraRotZ: cameraRot?.["@_rev"] !== void 0 ? parseInt(String(cameraRot["@_rev"]), 10) : void 0,
23780
+ cameraFieldOfView: intAttr(camera?.["@_fov"]),
23781
+ cameraZoom: floatAttr(camera?.["@_zoom"]),
23782
+ cameraRotX: intAttr(cameraRot?.["@_lat"]),
23783
+ cameraRotY: intAttr(cameraRot?.["@_lon"]),
23784
+ cameraRotZ: intAttr(cameraRot?.["@_rev"]),
23618
23785
  lightRigType: String(lightRig?.["@_rig"] || "").trim() || void 0,
23619
- lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0
23786
+ lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0,
23787
+ lightRigRotX: intAttr(lightRigRot?.["@_lat"]),
23788
+ lightRigRotY: intAttr(lightRigRot?.["@_lon"]),
23789
+ lightRigRotZ: intAttr(lightRigRot?.["@_rev"])
23620
23790
  };
23621
23791
  const backdrop = scene3dNode["a:backdrop"];
23622
23792
  if (backdrop) {
23623
23793
  style.scene3d.hasBackdrop = true;
23624
23794
  const anchor = backdrop["a:anchor"];
23625
- const anchorAttrs = anchor;
23626
- if (anchorAttrs) {
23627
- style.scene3d.backdropAnchorX = parseInt(String(anchorAttrs["@_x"] || "0"), 10);
23628
- style.scene3d.backdropAnchorY = parseInt(String(anchorAttrs["@_y"] || "0"), 10);
23629
- style.scene3d.backdropAnchorZ = parseInt(String(anchorAttrs["@_z"] || "0"), 10);
23795
+ if (anchor) {
23796
+ style.scene3d.backdropAnchorX = intAttr(anchor["@_x"]) ?? 0;
23797
+ style.scene3d.backdropAnchorY = intAttr(anchor["@_y"]) ?? 0;
23798
+ style.scene3d.backdropAnchorZ = intAttr(anchor["@_z"]) ?? 0;
23799
+ }
23800
+ const norm = backdrop["a:norm"];
23801
+ if (norm) {
23802
+ style.scene3d.backdropNormalX = intAttr(norm["@_dx"]) ?? 0;
23803
+ style.scene3d.backdropNormalY = intAttr(norm["@_dy"]) ?? 0;
23804
+ style.scene3d.backdropNormalZ = intAttr(norm["@_dz"]) ?? 0;
23805
+ }
23806
+ const up = backdrop["a:up"];
23807
+ if (up) {
23808
+ style.scene3d.backdropUpX = intAttr(up["@_dx"]) ?? 0;
23809
+ style.scene3d.backdropUpY = intAttr(up["@_dy"]) ?? 0;
23810
+ style.scene3d.backdropUpZ = intAttr(up["@_dz"]) ?? 0;
23630
23811
  }
23631
23812
  }
23632
23813
  }
23814
+ function intAttr(value) {
23815
+ return value !== void 0 ? parseInt(String(value), 10) : void 0;
23816
+ }
23817
+ function floatAttr(value) {
23818
+ return value !== void 0 ? parseFloat(String(value)) : void 0;
23819
+ }
23633
23820
  function applyShape3dStyle(shapeProps, style, context) {
23634
23821
  const shape3dNode = shapeProps["a:sp3d"];
23635
23822
  if (!shape3dNode) {
@@ -24512,7 +24699,10 @@ var PptxMediaDataParser = class {
24512
24699
  parseMediaData(graphicData, slidePath) {
24513
24700
  const result = {};
24514
24701
  try {
24515
- const reference = parseDrawingMediaReference(graphicData);
24702
+ const reference = parseDrawingMediaReference(
24703
+ graphicData,
24704
+ this.context.externalRelsMap.get(slidePath)
24705
+ );
24516
24706
  if (reference) {
24517
24707
  result.mediaType = reference.mediaType;
24518
24708
  result.mediaReferenceKind = reference.kind;
@@ -28165,6 +28355,7 @@ var PptxNativeAnimationService = class {
28165
28355
  const nodeType = String(cTn["@_nodeType"] || "");
28166
28356
  const presetClass = cTn["@_presetClass"];
28167
28357
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
28358
+ const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
28168
28359
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
28169
28360
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
28170
28361
  let trigger = currentTrigger;
@@ -28216,6 +28407,7 @@ var PptxNativeAnimationService = class {
28216
28407
  trigger,
28217
28408
  presetClass: validPresetClass,
28218
28409
  presetId,
28410
+ presetSubtype,
28219
28411
  durationMs,
28220
28412
  delayMs,
28221
28413
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
@@ -28526,6 +28718,74 @@ function buildP14ExtLst(transitionType, direction, orient, pattern, rawExtLst, x
28526
28718
  return { "p:ext": transitionExt };
28527
28719
  }
28528
28720
 
28721
+ // src/core/services/p15-transition-parser.ts
28722
+ var P15_TRANSITION_PRESETS = /* @__PURE__ */ new Set([
28723
+ "fallOver",
28724
+ "drape",
28725
+ "curtains",
28726
+ "wind",
28727
+ "prestige",
28728
+ "fracture",
28729
+ "crush",
28730
+ "peelOff",
28731
+ "pageCurlDouble",
28732
+ "pageCurlSingle",
28733
+ "airplane",
28734
+ "origami"
28735
+ ]);
28736
+ var PRSTTRANS_EXT_URI = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}";
28737
+ function optionalBoolean(value) {
28738
+ const valueToken = value === void 0 || value === null ? "" : String(value).trim().toLowerCase();
28739
+ if (valueToken === "1" || valueToken === "true") {
28740
+ return true;
28741
+ }
28742
+ if (valueToken === "0" || valueToken === "false") {
28743
+ return false;
28744
+ }
28745
+ return void 0;
28746
+ }
28747
+ function parseP15FromExtLst(extLstNode, xmlLookupService, getXmlLocalName) {
28748
+ const extEntries = xmlLookupService.getChildrenArrayByLocalName(extLstNode, "ext");
28749
+ for (const ext of extEntries) {
28750
+ if (!ext) {
28751
+ continue;
28752
+ }
28753
+ for (const [key, value] of Object.entries(ext)) {
28754
+ if (key.startsWith("@_")) {
28755
+ continue;
28756
+ }
28757
+ if (getXmlLocalName(key) !== "prstTrans") {
28758
+ continue;
28759
+ }
28760
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
28761
+ continue;
28762
+ }
28763
+ const detail = value;
28764
+ const prst = String(detail["@_prst"] || "").trim();
28765
+ if (!P15_TRANSITION_PRESETS.has(prst)) {
28766
+ continue;
28767
+ }
28768
+ return {
28769
+ type: prst,
28770
+ invX: optionalBoolean(detail["@_invX"]),
28771
+ invY: optionalBoolean(detail["@_invY"])
28772
+ };
28773
+ }
28774
+ }
28775
+ return void 0;
28776
+ }
28777
+ function buildP15ExtLst(transitionType, invX, invY) {
28778
+ const prstTrans = {
28779
+ "@_xmlns:p15": "http://schemas.microsoft.com/office/powerpoint/2012/main",
28780
+ "@_prst": transitionType
28781
+ };
28782
+ const ext = {
28783
+ "@_uri": PRSTTRANS_EXT_URI,
28784
+ "p15:prstTrans": prstTrans
28785
+ };
28786
+ return { "p:ext": ext };
28787
+ }
28788
+
28529
28789
  // src/core/services/slide-transition-xml.ts
28530
28790
  var STANDARD_TRANSITION_TYPES = /* @__PURE__ */ new Set([
28531
28791
  "fade",
@@ -28591,7 +28851,7 @@ function parseTransitionDetails(node, localName21) {
28591
28851
  if (pattern) {
28592
28852
  result.pattern = pattern;
28593
28853
  }
28594
- const thruBlk = optionalBoolean(detail["@_thruBlk"]);
28854
+ const thruBlk = optionalBoolean2(detail["@_thruBlk"]);
28595
28855
  if (thruBlk !== void 0) {
28596
28856
  result.thruBlk = thruBlk;
28597
28857
  }
@@ -28602,7 +28862,7 @@ function parseTransitionAttributes(node) {
28602
28862
  const speedToken = token(node["@_spd"]);
28603
28863
  const speed = SPEEDS.has(speedToken) ? speedToken : void 0;
28604
28864
  const durationMs = unsignedInteger2(node["@_dur"] ?? node["@_p14:dur"], 1);
28605
- const advanceOnClick = optionalBoolean(node["@_advClick"]);
28865
+ const advanceOnClick = optionalBoolean2(node["@_advClick"]);
28606
28866
  const advanceAfterMs = unsignedInteger2(node["@_advTm"]);
28607
28867
  return { speed, durationMs, advanceOnClick, advanceAfterMs };
28608
28868
  }
@@ -28616,7 +28876,7 @@ function parseTransitionSound(raw, lookup, localName21) {
28616
28876
  return {
28617
28877
  soundRId: sound ? attributeByLocalName(sound, "embed", localName21) : void 0,
28618
28878
  soundName: sound ? attributeByLocalName(sound, "name", localName21) : void 0,
28619
- soundLoop: optionalBoolean(start["@_loop"])
28879
+ soundLoop: optionalBoolean2(start["@_loop"])
28620
28880
  };
28621
28881
  }
28622
28882
  const stopSound = Object.keys(raw).some(
@@ -28725,7 +28985,7 @@ function attributeByLocalName(node, name, localName21) {
28725
28985
  function token(value) {
28726
28986
  return value === void 0 || value === null ? "" : String(value).trim();
28727
28987
  }
28728
- function optionalBoolean(value) {
28988
+ function optionalBoolean2(value) {
28729
28989
  const valueToken = token(value).toLowerCase();
28730
28990
  if (!valueToken) {
28731
28991
  return void 0;
@@ -28771,6 +29031,7 @@ var PptxSlideTransitionService = class {
28771
29031
  const { spokes, thruBlk, rawSoundAction, rawExtLst } = details;
28772
29032
  if (rawExtLst && transitionType === "cut") {
28773
29033
  const p14Result = parseP14FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
29034
+ const p15Result = p14Result ? void 0 : parseP15FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
28774
29035
  if (p14Result) {
28775
29036
  transitionType = p14Result.type;
28776
29037
  if (p14Result.direction) {
@@ -28782,6 +29043,8 @@ var PptxSlideTransitionService = class {
28782
29043
  if (p14Result.pattern) {
28783
29044
  pattern = p14Result.pattern;
28784
29045
  }
29046
+ } else if (p15Result) {
29047
+ transitionType = p15Result.type;
28785
29048
  } else if (this.parseMorphFromExtLst(rawExtLst)) {
28786
29049
  transitionType = "morph";
28787
29050
  }
@@ -28863,6 +29126,7 @@ var PptxSlideTransitionService = class {
28863
29126
  }
28864
29127
  const transitionType = transition.type || "cut";
28865
29128
  const isP14Type = P14_TRANSITION_TYPES.has(transitionType);
29129
+ const isP15Type = P15_TRANSITION_PRESETS.has(transitionType);
28866
29130
  const isMorphType = transitionType === "morph";
28867
29131
  const node = createPreservedTransitionNode(transition.rawTransition, this.getXmlLocalName);
28868
29132
  if (isP14Type) {
@@ -28875,6 +29139,8 @@ var PptxSlideTransitionService = class {
28875
29139
  this.xmlLookupService,
28876
29140
  this.getXmlLocalName
28877
29141
  );
29142
+ } else if (isP15Type) {
29143
+ node["p:extLst"] = transition.rawExtLst ?? buildP15ExtLst(transitionType);
28878
29144
  } else if (isMorphType) {
28879
29145
  node["p:extLst"] = this.buildMorphExtLst(transition.rawExtLst);
28880
29146
  } else {
@@ -28885,7 +29151,7 @@ var PptxSlideTransitionService = class {
28885
29151
  if (soundAction) {
28886
29152
  node["p:sndAc"] = soundAction;
28887
29153
  }
28888
- if (transition.rawExtLst && !isP14Type && !isMorphType) {
29154
+ if (transition.rawExtLst && !isP14Type && !isP15Type && !isMorphType) {
28889
29155
  node["p:extLst"] = transition.rawExtLst;
28890
29156
  }
28891
29157
  return node;
@@ -36769,6 +37035,93 @@ var PptxHandlerRuntime = class {
36769
37035
  }
36770
37036
  };
36771
37037
 
37038
+ // src/core/core/runtime/table-style-border-parse.ts
37039
+ var EMU_PER_PIXEL = 9525;
37040
+ var BORDER_SIDES = [
37041
+ "left",
37042
+ "right",
37043
+ "top",
37044
+ "bottom",
37045
+ "insideH",
37046
+ "insideV",
37047
+ "tl2br",
37048
+ "bl2tr"
37049
+ ];
37050
+ function parseSolidFillStyle(solidFill2) {
37051
+ if (!solidFill2) {
37052
+ return void 0;
37053
+ }
37054
+ const schemeClr = solidFill2["a:schemeClr"];
37055
+ if (!schemeClr) {
37056
+ return void 0;
37057
+ }
37058
+ const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
37059
+ if (!schemeColor) {
37060
+ return void 0;
37061
+ }
37062
+ const tintRaw = schemeClr["a:tint"];
37063
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
37064
+ const shadeRaw = schemeClr["a:shade"];
37065
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
37066
+ return { schemeColor, tint, shade };
37067
+ }
37068
+ function parseBorderSide(side) {
37069
+ if (!side) {
37070
+ return void 0;
37071
+ }
37072
+ const ln = side["a:ln"];
37073
+ if (!ln) {
37074
+ return void 0;
37075
+ }
37076
+ const border = {};
37077
+ let has = false;
37078
+ if (ln["a:noFill"] !== void 0) {
37079
+ border.noFill = true;
37080
+ has = true;
37081
+ }
37082
+ const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
37083
+ if (widthEmu > 0) {
37084
+ border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL));
37085
+ has = true;
37086
+ }
37087
+ const prstDash = ln["a:prstDash"];
37088
+ const dashVal = prstDash ? String(prstDash["@_val"] || "").trim() : "";
37089
+ if (dashVal) {
37090
+ border.dash = dashVal;
37091
+ has = true;
37092
+ }
37093
+ const solidFill2 = ln["a:solidFill"];
37094
+ const fill = parseSolidFillStyle(solidFill2);
37095
+ if (fill) {
37096
+ border.fill = fill;
37097
+ has = true;
37098
+ } else {
37099
+ const srgb = solidFill2?.["a:srgbClr"];
37100
+ const hex10 = srgb ? String(srgb["@_val"] || "").trim() : "";
37101
+ if (hex10) {
37102
+ border.color = hex10.startsWith("#") ? hex10 : `#${hex10}`;
37103
+ has = true;
37104
+ }
37105
+ }
37106
+ return has ? border : void 0;
37107
+ }
37108
+ function parseTableStyleBorders(tcStyle) {
37109
+ const tcBdr = tcStyle?.["a:tcBdr"];
37110
+ if (!tcBdr) {
37111
+ return void 0;
37112
+ }
37113
+ const result = {};
37114
+ let has = false;
37115
+ for (const name of BORDER_SIDES) {
37116
+ const border = parseBorderSide(tcBdr[`a:${name}`]);
37117
+ if (border) {
37118
+ result[name] = border;
37119
+ has = true;
37120
+ }
37121
+ }
37122
+ return has ? result : void 0;
37123
+ }
37124
+
36772
37125
  // src/core/core/runtime/PptxHandlerRuntimeTableStyles.ts
36773
37126
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
36774
37127
  /**
@@ -36853,30 +37206,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
36853
37206
  return void 0;
36854
37207
  }
36855
37208
  const tcStyle = section["a:tcStyle"];
36856
- if (!tcStyle) {
36857
- return void 0;
36858
- }
36859
- const fill = tcStyle["a:fill"];
36860
- if (!fill) {
36861
- return void 0;
36862
- }
36863
- const solidFill2 = fill["a:solidFill"];
36864
- if (!solidFill2) {
36865
- return void 0;
36866
- }
36867
- const schemeClr = solidFill2["a:schemeClr"];
36868
- if (!schemeClr) {
36869
- return void 0;
36870
- }
36871
- const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
36872
- if (!schemeColor) {
36873
- return void 0;
36874
- }
36875
- const tintRaw = schemeClr["a:tint"];
36876
- const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
36877
- const shadeRaw = schemeClr["a:shade"];
36878
- const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
36879
- return { schemeColor, tint, shade };
37209
+ const fill = tcStyle?.["a:fill"];
37210
+ return parseSolidFillStyle(fill?.["a:solidFill"]);
37211
+ }
37212
+ /**
37213
+ * Extract border styling from a table style section's
37214
+ * `a:tcStyle/a:tcBdr` (per-side line width, dash, and colour).
37215
+ */
37216
+ extractTableStyleSectionBorders(section) {
37217
+ return parseTableStyleBorders(section?.["a:tcStyle"]);
36880
37218
  }
36881
37219
  /**
36882
37220
  * Extract text properties from a:tcTxStyle in a table style section.
@@ -37023,6 +37361,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
37023
37361
  textProps[`${name}Text`] = text2;
37024
37362
  }
37025
37363
  }
37364
+ const borderProps = {};
37365
+ for (const name of sectionNames) {
37366
+ const borders = this.extractTableStyleSectionBorders(
37367
+ style[`a:${name}`]
37368
+ );
37369
+ if (borders) {
37370
+ borderProps[`${name}Borders`] = borders;
37371
+ }
37372
+ }
37026
37373
  const entry = {
37027
37374
  styleId,
37028
37375
  styleName,
@@ -37041,7 +37388,8 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
37041
37388
  ...swCellFill ? { swCellFill } : {},
37042
37389
  ...neCellFill ? { neCellFill } : {},
37043
37390
  ...nwCellFill ? { nwCellFill } : {},
37044
- ...textProps
37391
+ ...textProps,
37392
+ ...borderProps
37045
37393
  };
37046
37394
  map[styleId] = entry;
37047
37395
  }
@@ -38852,6 +39200,15 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
38852
39200
  if (align === "justify") {
38853
39201
  return "just";
38854
39202
  }
39203
+ if (align === "justLow") {
39204
+ return "justLow";
39205
+ }
39206
+ if (align === "dist") {
39207
+ return "dist";
39208
+ }
39209
+ if (align === "thaiDist") {
39210
+ return "thaiDist";
39211
+ }
38855
39212
  return void 0;
38856
39213
  }
38857
39214
  pixelsToPoints(px) {
@@ -39906,6 +40263,16 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39906
40263
  const chOffY = 0;
39907
40264
  const chExtCx = extCx;
39908
40265
  const chExtCy = extCy;
40266
+ const xfrmAttrs = {};
40267
+ if (typeof group.rotation === "number" && group.rotation !== 0) {
40268
+ xfrmAttrs["@_rot"] = String(Math.round(group.rotation * 6e4));
40269
+ }
40270
+ if (group.flipHorizontal) {
40271
+ xfrmAttrs["@_flipH"] = "1";
40272
+ }
40273
+ if (group.flipVertical) {
40274
+ xfrmAttrs["@_flipV"] = "1";
40275
+ }
39909
40276
  const grpXml = {
39910
40277
  "p:nvGrpSpPr": {
39911
40278
  "p:cNvPr": { "@_id": "0", "@_name": group.id },
@@ -39914,6 +40281,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39914
40281
  },
39915
40282
  "p:grpSpPr": {
39916
40283
  "a:xfrm": {
40284
+ ...xfrmAttrs,
39917
40285
  "a:off": {
39918
40286
  "@_x": String(offX),
39919
40287
  "@_y": String(offY)
@@ -45661,45 +46029,18 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
45661
46029
  const s3d = shapeStyle.scene3d;
45662
46030
  const hasData = s3d.cameraPreset || s3d.lightRigType;
45663
46031
  if (hasData) {
45664
- const cameraObj = {};
45665
- if (s3d.cameraPreset) {
45666
- cameraObj["@_prst"] = s3d.cameraPreset;
45667
- }
45668
- if (s3d.cameraRotX !== void 0 || s3d.cameraRotY !== void 0 || s3d.cameraRotZ !== void 0) {
45669
- const rot = {};
45670
- if (s3d.cameraRotX !== void 0) {
45671
- rot["@_lat"] = String(s3d.cameraRotX);
45672
- }
45673
- if (s3d.cameraRotY !== void 0) {
45674
- rot["@_lon"] = String(s3d.cameraRotY);
45675
- }
45676
- if (s3d.cameraRotZ !== void 0) {
45677
- rot["@_rev"] = String(s3d.cameraRotZ);
45678
- }
45679
- cameraObj["a:rot"] = rot;
45680
- }
45681
- const lightRigObj = {};
45682
- if (s3d.lightRigType) {
45683
- lightRigObj["@_rig"] = s3d.lightRigType;
45684
- }
45685
- if (s3d.lightRigDirection) {
45686
- lightRigObj["@_dir"] = s3d.lightRigDirection;
45687
- }
45688
- const scene3dXml = {};
45689
- scene3dXml["a:camera"] = cameraObj;
45690
- if (Object.keys(lightRigObj).length > 0) {
45691
- scene3dXml["a:lightRig"] = lightRigObj;
45692
- }
45693
- if (s3d.hasBackdrop) {
45694
- const backdropObj = {};
45695
- if (s3d.backdropAnchorX !== void 0 || s3d.backdropAnchorY !== void 0 || s3d.backdropAnchorZ !== void 0) {
45696
- backdropObj["a:anchor"] = {
45697
- "@_x": String(s3d.backdropAnchorX ?? 0),
45698
- "@_y": String(s3d.backdropAnchorY ?? 0),
45699
- "@_z": String(s3d.backdropAnchorZ ?? 0)
45700
- };
45701
- }
45702
- scene3dXml["a:backdrop"] = backdropObj;
46032
+ const source = spPr["a:scene3d"] ?? {};
46033
+ const scene3dXml = { ...source };
46034
+ scene3dXml["a:camera"] = buildScene3dCamera(s3d, source);
46035
+ const lightRig = buildScene3dLightRig(s3d, source);
46036
+ if (lightRig) {
46037
+ scene3dXml["a:lightRig"] = lightRig;
46038
+ }
46039
+ const backdrop = buildScene3dBackdrop(s3d);
46040
+ if (backdrop) {
46041
+ scene3dXml["a:backdrop"] = backdrop;
46042
+ } else {
46043
+ delete scene3dXml["a:backdrop"];
45703
46044
  }
45704
46045
  spPr["a:scene3d"] = scene3dXml;
45705
46046
  } else {
@@ -45744,12 +46085,12 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
45744
46085
  }
45745
46086
  if (sh3d.extrusionColor) {
45746
46087
  sp3dXml["a:extrusionClr"] = {
45747
- "a:srgbClr": { "@_val": sh3d.extrusionColor }
46088
+ "a:srgbClr": { "@_val": sh3d.extrusionColor.replace("#", "") }
45748
46089
  };
45749
46090
  }
45750
46091
  if (sh3d.contourColor) {
45751
46092
  sp3dXml["a:contourClr"] = {
45752
- "a:srgbClr": { "@_val": sh3d.contourColor }
46093
+ "a:srgbClr": { "@_val": sh3d.contourColor.replace("#", "") }
45753
46094
  };
45754
46095
  }
45755
46096
  spPr["a:sp3d"] = sp3dXml;
@@ -45761,6 +46102,77 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
45761
46102
  }
45762
46103
  }
45763
46104
  };
46105
+ function buildSphereRot(lat, lon, rev) {
46106
+ if (lat === void 0 && lon === void 0 && rev === void 0) {
46107
+ return void 0;
46108
+ }
46109
+ const rot = {};
46110
+ if (lat !== void 0) {
46111
+ rot["@_lat"] = String(lat);
46112
+ }
46113
+ if (lon !== void 0) {
46114
+ rot["@_lon"] = String(lon);
46115
+ }
46116
+ if (rev !== void 0) {
46117
+ rot["@_rev"] = String(rev);
46118
+ }
46119
+ return rot;
46120
+ }
46121
+ function buildScene3dCamera(s3d, source) {
46122
+ const camera = { ...source["a:camera"] ?? {} };
46123
+ if (s3d.cameraPreset) {
46124
+ camera["@_prst"] = s3d.cameraPreset;
46125
+ }
46126
+ if (s3d.cameraFieldOfView !== void 0) {
46127
+ camera["@_fov"] = String(s3d.cameraFieldOfView);
46128
+ }
46129
+ if (s3d.cameraZoom !== void 0) {
46130
+ camera["@_zoom"] = String(s3d.cameraZoom);
46131
+ }
46132
+ const rot = buildSphereRot(s3d.cameraRotX, s3d.cameraRotY, s3d.cameraRotZ);
46133
+ if (rot) {
46134
+ camera["a:rot"] = rot;
46135
+ }
46136
+ return camera;
46137
+ }
46138
+ function buildScene3dLightRig(s3d, source) {
46139
+ const lightRig = { ...source["a:lightRig"] ?? {} };
46140
+ if (s3d.lightRigType) {
46141
+ lightRig["@_rig"] = s3d.lightRigType;
46142
+ }
46143
+ if (s3d.lightRigDirection) {
46144
+ lightRig["@_dir"] = s3d.lightRigDirection;
46145
+ }
46146
+ const rot = buildSphereRot(s3d.lightRigRotX, s3d.lightRigRotY, s3d.lightRigRotZ);
46147
+ if (rot) {
46148
+ lightRig["a:rot"] = rot;
46149
+ }
46150
+ return Object.keys(lightRig).length > 0 ? lightRig : void 0;
46151
+ }
46152
+ function buildScene3dBackdrop(s3d) {
46153
+ const hasNorm = s3d.backdropNormalX !== void 0 || s3d.backdropNormalY !== void 0 || s3d.backdropNormalZ !== void 0;
46154
+ const hasUp = s3d.backdropUpX !== void 0 || s3d.backdropUpY !== void 0 || s3d.backdropUpZ !== void 0;
46155
+ if (!s3d.hasBackdrop || !hasNorm || !hasUp) {
46156
+ return void 0;
46157
+ }
46158
+ return {
46159
+ "a:anchor": {
46160
+ "@_x": String(s3d.backdropAnchorX ?? 0),
46161
+ "@_y": String(s3d.backdropAnchorY ?? 0),
46162
+ "@_z": String(s3d.backdropAnchorZ ?? 0)
46163
+ },
46164
+ "a:norm": {
46165
+ "@_dx": String(s3d.backdropNormalX ?? 0),
46166
+ "@_dy": String(s3d.backdropNormalY ?? 0),
46167
+ "@_dz": String(s3d.backdropNormalZ ?? 0)
46168
+ },
46169
+ "a:up": {
46170
+ "@_dx": String(s3d.backdropUpX ?? 0),
46171
+ "@_dy": String(s3d.backdropUpY ?? 0),
46172
+ "@_dz": String(s3d.backdropUpZ ?? 0)
46173
+ }
46174
+ };
46175
+ }
45764
46176
 
45765
46177
  // src/core/core/runtime/PptxHandlerRuntimeSaveTextWriter.ts
45766
46178
  var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime29 {
@@ -50768,7 +51180,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50768
51180
  pointsToPixels(points3) {
50769
51181
  return points3 * (96 / 72);
50770
51182
  }
50771
- parseParagraphSpacingPx(spacingNode) {
51183
+ parseParagraphSpacingPx(spacingNode, basisFontSizePx) {
50772
51184
  if (!spacingNode) {
50773
51185
  return void 0;
50774
51186
  }
@@ -50779,6 +51191,13 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50779
51191
  if (Number.isFinite(spacingPointsRaw)) {
50780
51192
  return this.pointsToPixels(spacingPointsRaw / 100);
50781
51193
  }
51194
+ const spacingPercentRaw = Number.parseInt(
51195
+ String(spacingNode["a:spcPct"]?.["@_val"] || ""),
51196
+ 10
51197
+ );
51198
+ if (Number.isFinite(spacingPercentRaw) && typeof basisFontSizePx === "number" && basisFontSizePx > 0) {
51199
+ return spacingPercentRaw / 1e5 * basisFontSizePx;
51200
+ }
50782
51201
  return void 0;
50783
51202
  }
50784
51203
  parseLineSpacingMultiplier(lineSpacingNode) {
@@ -50858,7 +51277,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50858
51277
 
50859
51278
  // src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
50860
51279
  var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50861
- resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
51280
+ resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath, effectiveLevelStyles) {
50862
51281
  if (!paragraph) {
50863
51282
  return null;
50864
51283
  }
@@ -50894,11 +51313,8 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50894
51313
  }
50895
51314
  }
50896
51315
  if (!resolvedBulletProps) {
50897
- if (isBodyPlaceholder) {
50898
- const presentationLevelStyle = this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1];
50899
- return this.createBulletInfoFromLevelStyle(presentationLevelStyle, paragraphIndex);
50900
- }
50901
- return null;
51316
+ const fallbackLevelStyle = effectiveLevelStyles?.[normalizedLevel - 1] ?? effectiveLevelStyles?.[-1] ?? (isBodyPlaceholder ? this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1] : void 0);
51317
+ return this.createBulletInfoFromLevelStyle(fallbackLevelStyle, paragraphIndex);
50902
51318
  }
50903
51319
  const buFont = resolvedBulletProps["a:buFont"];
50904
51320
  const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
@@ -51388,16 +51804,21 @@ var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
51388
51804
  textStyle.align = paraAlign;
51389
51805
  }
51390
51806
  }
51807
+ const spacingBasisPx = typeof textStyle.fontSize === "number" ? textStyle.fontSize : void 0;
51391
51808
  if (textStyle.paragraphSpacingBefore === void 0) {
51392
51809
  const spacingBefore = this.parseParagraphSpacingPx(
51393
- pPr?.["a:spcBef"]
51810
+ pPr?.["a:spcBef"],
51811
+ spacingBasisPx
51394
51812
  );
51395
51813
  if (spacingBefore !== void 0) {
51396
51814
  textStyle.paragraphSpacingBefore = spacingBefore;
51397
51815
  }
51398
51816
  }
51399
51817
  if (textStyle.paragraphSpacingAfter === void 0) {
51400
- const spacingAfter = this.parseParagraphSpacingPx(pPr?.["a:spcAft"]);
51818
+ const spacingAfter = this.parseParagraphSpacingPx(
51819
+ pPr?.["a:spcAft"],
51820
+ spacingBasisPx
51821
+ );
51401
51822
  if (spacingAfter !== void 0) {
51402
51823
  textStyle.paragraphSpacingAfter = spacingAfter;
51403
51824
  }
@@ -51571,7 +51992,8 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
51571
51992
  ctx.txBody,
51572
51993
  ctx.inheritedTxBody,
51573
51994
  isBodyPlaceholder,
51574
- ctx.slidePath
51995
+ ctx.slidePath,
51996
+ ctx.effectiveLevelStyles
51575
51997
  );
51576
51998
  if (paragraphBulletInfo && !paragraphBulletInfo.none) {
51577
51999
  let bulletText;
@@ -52180,7 +52602,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52180
52602
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
52181
52603
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
52182
52604
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
52183
- const mediaReference = parseDrawingMediaReference(nvPr);
52605
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
52184
52606
  if (mediaReference) {
52185
52607
  this.compatibilityService.inspectMediaReferenceCompatibility(
52186
52608
  mediaReference.kind,
@@ -52948,6 +53370,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52948
53370
  const grpSpPr = group["p:grpSpPr"];
52949
53371
  const xfrm = grpSpPr?.["a:xfrm"];
52950
53372
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
53373
+ let groupRotation;
53374
+ let flipHorizontal = false;
53375
+ let flipVertical = false;
52951
53376
  if (xfrm) {
52952
53377
  const off = xfrm["a:off"];
52953
53378
  if (off) {
@@ -52959,6 +53384,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52959
53384
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52960
53385
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52961
53386
  }
53387
+ if (xfrm["@_rot"] !== void 0 && xfrm["@_rot"] !== null) {
53388
+ const rot = parseInt(String(xfrm["@_rot"]), 10) / 6e4;
53389
+ groupRotation = Number.isFinite(rot) && rot !== 0 ? rot : void 0;
53390
+ }
53391
+ flipHorizontal = this.parseBooleanAttr(xfrm["@_flipH"]);
53392
+ flipVertical = this.parseBooleanAttr(xfrm["@_flipV"]);
52962
53393
  }
52963
53394
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
52964
53395
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -53004,6 +53435,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
53004
53435
  y: parentY,
53005
53436
  width: parentW || Math.max(...children9.map((c) => c.x + c.width)),
53006
53437
  height: parentH || Math.max(...children9.map((c) => c.y + c.height)),
53438
+ rotation: groupRotation,
53439
+ flipHorizontal: flipHorizontal || void 0,
53440
+ flipVertical: flipVertical || void 0,
53007
53441
  children: children9,
53008
53442
  rawXml: group,
53009
53443
  actionClick: grpActionClick,
@@ -53174,6 +53608,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53174
53608
  if (!normalized) {
53175
53609
  return void 0;
53176
53610
  }
53611
+ const canon = (key) => key.toLowerCase() === "folhlink" ? "folHlink" : key;
53177
53612
  if (normalized === "phclr") {
53178
53613
  const injected = this.themeColorMap["phclr"];
53179
53614
  if (injected) {
@@ -53183,17 +53618,18 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53183
53618
  }
53184
53619
  const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
53185
53620
  if (overrideMap) {
53186
- const remapped = overrideMap[normalized];
53621
+ const remapped = overrideMap[canon(normalized)];
53187
53622
  if (remapped) {
53188
- return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
53623
+ const target = canon(remapped);
53624
+ return this.themeColorMap[target] || this.getDefaultSchemeColorMap()[target];
53189
53625
  }
53190
53626
  } else {
53191
53627
  const defaultAliasTarget = DEFAULT_CLR_MAP_ALIAS[normalized];
53192
53628
  if (defaultAliasTarget) {
53193
- return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53629
+ return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53194
53630
  }
53195
53631
  }
53196
- return this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53632
+ return this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53197
53633
  }
53198
53634
  normalizeStrokeDashType(value) {
53199
53635
  const normalized = String(value ?? "").trim();
@@ -53976,11 +54412,24 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
53976
54412
  }
53977
54413
  }
53978
54414
  }
53979
- const spcBef = this.parseParagraphSpacingPx(levelProps["a:spcBef"]);
54415
+ const defRPrSzRaw = Number.parseInt(
54416
+ String(
54417
+ levelProps["a:defRPr"]?.["@_sz"] || ""
54418
+ ),
54419
+ 10
54420
+ );
54421
+ const basisFontSizePx = Number.isFinite(defRPrSzRaw) ? this.pointsToPixels(defRPrSzRaw / 100) : void 0;
54422
+ const spcBef = this.parseParagraphSpacingPx(
54423
+ levelProps["a:spcBef"],
54424
+ basisFontSizePx
54425
+ );
53980
54426
  if (spcBef !== void 0) {
53981
54427
  style.spaceBefore = spcBef;
53982
54428
  }
53983
- const spcAft = this.parseParagraphSpacingPx(levelProps["a:spcAft"]);
54429
+ const spcAft = this.parseParagraphSpacingPx(
54430
+ levelProps["a:spcAft"],
54431
+ basisFontSizePx
54432
+ );
53984
54433
  if (spcAft !== void 0) {
53985
54434
  style.spaceAfter = spcAft;
53986
54435
  }
@@ -54005,9 +54454,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
54005
54454
  }
54006
54455
  const buClr = levelProps["a:buClr"];
54007
54456
  if (buClr) {
54008
- const srgb = buClr["a:srgbClr"];
54009
- if (srgb?.["@_val"]) {
54010
- style.bulletColor = String(srgb["@_val"]);
54457
+ const bulletColor = this.parseColor(buClr);
54458
+ if (bulletColor) {
54459
+ style.bulletColor = bulletColor;
54011
54460
  }
54012
54461
  }
54013
54462
  const buSzPts = levelProps["a:buSzPts"];
@@ -56509,6 +56958,89 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
56509
56958
  }
56510
56959
  };
56511
56960
 
56961
+ // src/core/core/runtime/smartart-drawing-shape-style.ts
56962
+ function extractDrawingShapeFill(spPr, deps) {
56963
+ const result = {};
56964
+ const solidFill2 = deps.getChild(spPr, "solidFill");
56965
+ if (solidFill2) {
56966
+ result.fillColor = deps.parseColor(solidFill2) ?? void 0;
56967
+ }
56968
+ const gradFill = !solidFill2 ? deps.getChild(spPr, "gradFill") : void 0;
56969
+ if (gradFill) {
56970
+ const stops = deps.extractGradientStops(gradFill).map((stop) => ({
56971
+ color: stop.color,
56972
+ position: stop.position,
56973
+ ...stop.opacity !== void 0 ? { opacity: stop.opacity } : {}
56974
+ }));
56975
+ if (stops.length > 0) {
56976
+ result.fillGradientStops = stops;
56977
+ result.fillGradientType = deps.extractGradientType(gradFill);
56978
+ result.fillGradientAngle = deps.extractGradientAngle(gradFill);
56979
+ result.fillColor ??= stops[Math.floor(stops.length / 2)]?.color;
56980
+ }
56981
+ }
56982
+ const pattFill = !solidFill2 && !gradFill ? deps.getChild(spPr, "pattFill") : void 0;
56983
+ if (pattFill) {
56984
+ const preset = String(pattFill["@_prst"] || "").trim();
56985
+ if (preset) {
56986
+ result.fillPatternPreset = preset;
56987
+ }
56988
+ const fg = deps.parseColor(deps.getChild(pattFill, "fgClr"));
56989
+ const bg = deps.parseColor(deps.getChild(pattFill, "bgClr"));
56990
+ if (fg) {
56991
+ result.fillPatternForegroundColor = fg;
56992
+ }
56993
+ if (bg) {
56994
+ result.fillPatternBackgroundColor = bg;
56995
+ }
56996
+ result.fillColor ??= fg ?? bg;
56997
+ }
56998
+ const blipFill = !solidFill2 && !gradFill && !pattFill ? deps.getChild(spPr, "blipFill") : void 0;
56999
+ if (blipFill) {
57000
+ const blip = deps.getChild(blipFill, "blip");
57001
+ const embed = String(
57002
+ blip?.["@_r:embed"] || blip?.["@_embed"] || blip?.["@_r:link"] || ""
57003
+ ).trim();
57004
+ if (embed) {
57005
+ result.fillBlipEmbedId = embed;
57006
+ }
57007
+ }
57008
+ const shadowColor = deps.extractShadowColor(spPr);
57009
+ if (shadowColor) {
57010
+ result.hasShadow = true;
57011
+ result.shadowColor = shadowColor;
57012
+ }
57013
+ return result;
57014
+ }
57015
+ function extractDrawingShapeTextStyle(txBody, deps) {
57016
+ let fontSize;
57017
+ let fontColor;
57018
+ if (!txBody) {
57019
+ return { fontSize, fontColor };
57020
+ }
57021
+ const paragraphs = deps.getChildren(txBody, "p");
57022
+ for (const p of paragraphs) {
57023
+ const runs = deps.getChildren(p, "r");
57024
+ for (const r of runs) {
57025
+ const rPr = deps.getChild(r, "rPr");
57026
+ if (rPr && !fontSize) {
57027
+ const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
57028
+ if (Number.isFinite(szRaw) && szRaw > 0) {
57029
+ fontSize = szRaw / 100;
57030
+ }
57031
+ fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
57032
+ }
57033
+ if (fontSize) {
57034
+ break;
57035
+ }
57036
+ }
57037
+ if (fontSize) {
57038
+ break;
57039
+ }
57040
+ }
57041
+ return { fontSize, fontColor };
57042
+ }
57043
+
56512
57044
  // src/core/core/runtime/smartart-text-style-resolution.ts
56513
57045
  function resolveSmartArtTextStyles(paragraphs, resolve2) {
56514
57046
  for (const paragraph of paragraphs ?? []) {
@@ -56684,8 +57216,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56684
57216
  };
56685
57217
  }
56686
57218
  }
56687
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
56688
- const fillColor = this.parseColor(solidFill2);
57219
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
56689
57220
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
56690
57221
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
56691
57222
  const strokeColor = this.parseColor(lnFill);
@@ -56697,7 +57228,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56697
57228
  this.collectLocalTextValues(txBody, "t", textValues2);
56698
57229
  }
56699
57230
  const text2 = textValues2.join("").trim() || void 0;
56700
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
57231
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
57232
+ txBody,
57233
+ this.drawingShapeStyleDeps()
57234
+ );
56701
57235
  const paragraphs = txBody ? resolveSmartArtTextStyles(
56702
57236
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
56703
57237
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -56723,7 +57257,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56723
57257
  rotation,
56724
57258
  skewX,
56725
57259
  skewY,
56726
- fillColor: fillColor ?? void 0,
57260
+ ...fill,
57261
+ fillColor: fill.fillColor ?? void 0,
56727
57262
  strokeColor: strokeColor ?? void 0,
56728
57263
  strokeWidth,
56729
57264
  text: structuredText,
@@ -56733,34 +57268,21 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56733
57268
  ...customGeometry
56734
57269
  };
56735
57270
  }
56736
- extractDrawingShapeTextStyle(txBody) {
56737
- let fontSize;
56738
- let fontColor;
56739
- if (!txBody) {
56740
- return { fontSize, fontColor };
56741
- }
56742
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
56743
- for (const p of paragraphs) {
56744
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
56745
- for (const r of runs) {
56746
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
56747
- if (rPr && !fontSize) {
56748
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
56749
- if (Number.isFinite(szRaw) && szRaw > 0) {
56750
- fontSize = szRaw / 100;
56751
- }
56752
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
56753
- fontColor = this.parseColor(rprFill) ?? void 0;
56754
- }
56755
- if (fontSize) {
56756
- break;
56757
- }
56758
- }
56759
- if (fontSize) {
56760
- break;
56761
- }
56762
- }
56763
- return { fontSize, fontColor };
57271
+ /**
57272
+ * Build the injected accessor bundle used by the pure drawing-shape style
57273
+ * helpers, binding the shared XML-lookup / colour / gradient / shadow codec
57274
+ * methods so no new colour logic is duplicated here.
57275
+ */
57276
+ drawingShapeStyleDeps() {
57277
+ return {
57278
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
57279
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
57280
+ parseColor: (node) => this.parseColor(node),
57281
+ extractGradientStops: (gradFill) => this.extractGradientStops(gradFill),
57282
+ extractGradientType: (gradFill) => this.extractGradientType(gradFill),
57283
+ extractGradientAngle: (gradFill) => this.extractGradientAngle(gradFill),
57284
+ extractShadowColor: (spPr) => this.extractShadowStyle(spPr).shadowColor
57285
+ };
56764
57286
  }
56765
57287
  };
56766
57288
 
@@ -59234,6 +59756,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime extends PptxHandlerRuntime9
59234
59756
  });
59235
59757
  this.mediaDataParser = new PptxMediaDataParser({
59236
59758
  slideRelsMap: this.slideRelsMap,
59759
+ externalRelsMap: this.externalRelsMap,
59237
59760
  resolvePath: (base, relative) => this.resolvePath(base, relative),
59238
59761
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
59239
59762
  });