pptx-viewer-core 1.6.8 → 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 {
@@ -52190,7 +52602,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52190
52602
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
52191
52603
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
52192
52604
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
52193
- const mediaReference = parseDrawingMediaReference(nvPr);
52605
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
52194
52606
  if (mediaReference) {
52195
52607
  this.compatibilityService.inspectMediaReferenceCompatibility(
52196
52608
  mediaReference.kind,
@@ -52958,6 +53370,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52958
53370
  const grpSpPr = group["p:grpSpPr"];
52959
53371
  const xfrm = grpSpPr?.["a:xfrm"];
52960
53372
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
53373
+ let groupRotation;
53374
+ let flipHorizontal = false;
53375
+ let flipVertical = false;
52961
53376
  if (xfrm) {
52962
53377
  const off = xfrm["a:off"];
52963
53378
  if (off) {
@@ -52969,6 +53384,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52969
53384
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52970
53385
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52971
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"]);
52972
53393
  }
52973
53394
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
52974
53395
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -53014,6 +53435,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
53014
53435
  y: parentY,
53015
53436
  width: parentW || Math.max(...children9.map((c) => c.x + c.width)),
53016
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,
53017
53441
  children: children9,
53018
53442
  rawXml: group,
53019
53443
  actionClick: grpActionClick,
@@ -54030,9 +54454,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
54030
54454
  }
54031
54455
  const buClr = levelProps["a:buClr"];
54032
54456
  if (buClr) {
54033
- const srgb = buClr["a:srgbClr"];
54034
- if (srgb?.["@_val"]) {
54035
- style.bulletColor = String(srgb["@_val"]);
54457
+ const bulletColor = this.parseColor(buClr);
54458
+ if (bulletColor) {
54459
+ style.bulletColor = bulletColor;
54036
54460
  }
54037
54461
  }
54038
54462
  const buSzPts = levelProps["a:buSzPts"];
@@ -56534,6 +56958,89 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
56534
56958
  }
56535
56959
  };
56536
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
+
56537
57044
  // src/core/core/runtime/smartart-text-style-resolution.ts
56538
57045
  function resolveSmartArtTextStyles(paragraphs, resolve2) {
56539
57046
  for (const paragraph of paragraphs ?? []) {
@@ -56709,8 +57216,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56709
57216
  };
56710
57217
  }
56711
57218
  }
56712
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
56713
- const fillColor = this.parseColor(solidFill2);
57219
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
56714
57220
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
56715
57221
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
56716
57222
  const strokeColor = this.parseColor(lnFill);
@@ -56722,7 +57228,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56722
57228
  this.collectLocalTextValues(txBody, "t", textValues2);
56723
57229
  }
56724
57230
  const text2 = textValues2.join("").trim() || void 0;
56725
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
57231
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
57232
+ txBody,
57233
+ this.drawingShapeStyleDeps()
57234
+ );
56726
57235
  const paragraphs = txBody ? resolveSmartArtTextStyles(
56727
57236
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
56728
57237
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -56748,7 +57257,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56748
57257
  rotation,
56749
57258
  skewX,
56750
57259
  skewY,
56751
- fillColor: fillColor ?? void 0,
57260
+ ...fill,
57261
+ fillColor: fill.fillColor ?? void 0,
56752
57262
  strokeColor: strokeColor ?? void 0,
56753
57263
  strokeWidth,
56754
57264
  text: structuredText,
@@ -56758,34 +57268,21 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56758
57268
  ...customGeometry
56759
57269
  };
56760
57270
  }
56761
- extractDrawingShapeTextStyle(txBody) {
56762
- let fontSize;
56763
- let fontColor;
56764
- if (!txBody) {
56765
- return { fontSize, fontColor };
56766
- }
56767
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
56768
- for (const p of paragraphs) {
56769
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
56770
- for (const r of runs) {
56771
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
56772
- if (rPr && !fontSize) {
56773
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
56774
- if (Number.isFinite(szRaw) && szRaw > 0) {
56775
- fontSize = szRaw / 100;
56776
- }
56777
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
56778
- fontColor = this.parseColor(rprFill) ?? void 0;
56779
- }
56780
- if (fontSize) {
56781
- break;
56782
- }
56783
- }
56784
- if (fontSize) {
56785
- break;
56786
- }
56787
- }
56788
- 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
+ };
56789
57286
  }
56790
57287
  };
56791
57288
 
@@ -59259,6 +59756,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime extends PptxHandlerRuntime9
59259
59756
  });
59260
59757
  this.mediaDataParser = new PptxMediaDataParser({
59261
59758
  slideRelsMap: this.slideRelsMap,
59759
+ externalRelsMap: this.externalRelsMap,
59262
59760
  resolvePath: (base, relative) => this.resolvePath(base, relative),
59263
59761
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
59264
59762
  });