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/index.js CHANGED
@@ -7088,26 +7088,49 @@ function applyScene3dStyle(shapeProps, style) {
7088
7088
  const camera = scene3dNode["a:camera"];
7089
7089
  const lightRig = scene3dNode["a:lightRig"];
7090
7090
  const cameraRot = camera?.["a:rot"];
7091
+ const lightRigRot = lightRig?.["a:rot"];
7091
7092
  style.scene3d = {
7092
7093
  cameraPreset: String(camera?.["@_prst"] || "").trim() || void 0,
7093
- cameraRotX: cameraRot?.["@_lat"] !== void 0 ? parseInt(String(cameraRot["@_lat"]), 10) : void 0,
7094
- cameraRotY: cameraRot?.["@_lon"] !== void 0 ? parseInt(String(cameraRot["@_lon"]), 10) : void 0,
7095
- cameraRotZ: cameraRot?.["@_rev"] !== void 0 ? parseInt(String(cameraRot["@_rev"]), 10) : void 0,
7094
+ cameraFieldOfView: intAttr(camera?.["@_fov"]),
7095
+ cameraZoom: floatAttr(camera?.["@_zoom"]),
7096
+ cameraRotX: intAttr(cameraRot?.["@_lat"]),
7097
+ cameraRotY: intAttr(cameraRot?.["@_lon"]),
7098
+ cameraRotZ: intAttr(cameraRot?.["@_rev"]),
7096
7099
  lightRigType: String(lightRig?.["@_rig"] || "").trim() || void 0,
7097
- lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0
7100
+ lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0,
7101
+ lightRigRotX: intAttr(lightRigRot?.["@_lat"]),
7102
+ lightRigRotY: intAttr(lightRigRot?.["@_lon"]),
7103
+ lightRigRotZ: intAttr(lightRigRot?.["@_rev"])
7098
7104
  };
7099
7105
  const backdrop = scene3dNode["a:backdrop"];
7100
7106
  if (backdrop) {
7101
7107
  style.scene3d.hasBackdrop = true;
7102
7108
  const anchor = backdrop["a:anchor"];
7103
- const anchorAttrs = anchor;
7104
- if (anchorAttrs) {
7105
- style.scene3d.backdropAnchorX = parseInt(String(anchorAttrs["@_x"] || "0"), 10);
7106
- style.scene3d.backdropAnchorY = parseInt(String(anchorAttrs["@_y"] || "0"), 10);
7107
- style.scene3d.backdropAnchorZ = parseInt(String(anchorAttrs["@_z"] || "0"), 10);
7109
+ if (anchor) {
7110
+ style.scene3d.backdropAnchorX = intAttr(anchor["@_x"]) ?? 0;
7111
+ style.scene3d.backdropAnchorY = intAttr(anchor["@_y"]) ?? 0;
7112
+ style.scene3d.backdropAnchorZ = intAttr(anchor["@_z"]) ?? 0;
7113
+ }
7114
+ const norm = backdrop["a:norm"];
7115
+ if (norm) {
7116
+ style.scene3d.backdropNormalX = intAttr(norm["@_dx"]) ?? 0;
7117
+ style.scene3d.backdropNormalY = intAttr(norm["@_dy"]) ?? 0;
7118
+ style.scene3d.backdropNormalZ = intAttr(norm["@_dz"]) ?? 0;
7119
+ }
7120
+ const up = backdrop["a:up"];
7121
+ if (up) {
7122
+ style.scene3d.backdropUpX = intAttr(up["@_dx"]) ?? 0;
7123
+ style.scene3d.backdropUpY = intAttr(up["@_dy"]) ?? 0;
7124
+ style.scene3d.backdropUpZ = intAttr(up["@_dz"]) ?? 0;
7108
7125
  }
7109
7126
  }
7110
7127
  }
7128
+ function intAttr(value) {
7129
+ return value !== void 0 ? parseInt(String(value), 10) : void 0;
7130
+ }
7131
+ function floatAttr(value) {
7132
+ return value !== void 0 ? parseFloat(String(value)) : void 0;
7133
+ }
7111
7134
  function applyShape3dStyle(shapeProps, style, context) {
7112
7135
  const shape3dNode = shapeProps["a:sp3d"];
7113
7136
  if (!shape3dNode) {
@@ -7989,7 +8012,7 @@ var MEDIA_REFERENCE_NAMES = [
7989
8012
  "videoFile",
7990
8013
  "quickTimeFile"
7991
8014
  ];
7992
- function parseDrawingMediaReference(container) {
8015
+ function parseDrawingMediaReference(container, externalRelIds) {
7993
8016
  if (!container) {
7994
8017
  return void 0;
7995
8018
  }
@@ -7998,11 +8021,17 @@ function parseDrawingMediaReference(container) {
7998
8021
  if (!node) {
7999
8022
  continue;
8000
8023
  }
8024
+ const linkId = String(attribute2(node, "link") ?? "").trim() || void 0;
8025
+ const embedId = String(attribute2(node, "embed") ?? "").trim() || void 0;
8001
8026
  return {
8002
8027
  kind,
8003
8028
  mediaType: kind === "videoFile" || kind === "quickTimeFile" ? "video" : "audio",
8004
- relationshipId: String(attribute2(node, "link") ?? attribute2(node, "embed") ?? "").trim() || void 0,
8005
- isLinked: attribute2(node, "link") !== void 0,
8029
+ relationshipId: linkId ?? embedId,
8030
+ // Embedded media legitimately uses r:link pointing at an INTERNAL
8031
+ // media part, so link presence alone does not imply a linked clip.
8032
+ // It is only truly linked when the referenced relationship is
8033
+ // external (TargetMode="External"), mirroring the OLE parser.
8034
+ isLinked: linkId !== void 0 && externalRelIds?.has(linkId) === true,
8006
8035
  name: kind === "wavAudioFile" ? String(attribute2(node, "name") ?? "") || void 0 : void 0,
8007
8036
  contentType: kind === "audioFile" ? String(attribute2(node, "contentType") ?? "") || void 0 : void 0,
8008
8037
  audioCdStart: kind === "audioCd" ? parseAudioCdPosition(child2(node, "st")) : void 0,
@@ -8133,7 +8162,10 @@ var PptxMediaDataParser = class {
8133
8162
  parseMediaData(graphicData, slidePath) {
8134
8163
  const result = {};
8135
8164
  try {
8136
- const reference = parseDrawingMediaReference(graphicData);
8165
+ const reference = parseDrawingMediaReference(
8166
+ graphicData,
8167
+ this.context.externalRelsMap.get(slidePath)
8168
+ );
8137
8169
  if (reference) {
8138
8170
  result.mediaType = reference.mediaType;
8139
8171
  result.mediaReferenceKind = reference.kind;
@@ -13090,6 +13122,7 @@ var PptxNativeAnimationService = class {
13090
13122
  const nodeType = String(cTn["@_nodeType"] || "");
13091
13123
  const presetClass = cTn["@_presetClass"];
13092
13124
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
13125
+ const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
13093
13126
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
13094
13127
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
13095
13128
  let trigger = currentTrigger;
@@ -13141,6 +13174,7 @@ var PptxNativeAnimationService = class {
13141
13174
  trigger,
13142
13175
  presetClass: validPresetClass,
13143
13176
  presetId,
13177
+ presetSubtype,
13144
13178
  durationMs,
13145
13179
  delayMs,
13146
13180
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
@@ -13451,6 +13485,74 @@ function buildP14ExtLst(transitionType, direction, orient, pattern, rawExtLst, x
13451
13485
  return { "p:ext": transitionExt };
13452
13486
  }
13453
13487
 
13488
+ // src/core/services/p15-transition-parser.ts
13489
+ var P15_TRANSITION_PRESETS = /* @__PURE__ */ new Set([
13490
+ "fallOver",
13491
+ "drape",
13492
+ "curtains",
13493
+ "wind",
13494
+ "prestige",
13495
+ "fracture",
13496
+ "crush",
13497
+ "peelOff",
13498
+ "pageCurlDouble",
13499
+ "pageCurlSingle",
13500
+ "airplane",
13501
+ "origami"
13502
+ ]);
13503
+ var PRSTTRANS_EXT_URI = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}";
13504
+ function optionalBoolean(value) {
13505
+ const valueToken = value === void 0 || value === null ? "" : String(value).trim().toLowerCase();
13506
+ if (valueToken === "1" || valueToken === "true") {
13507
+ return true;
13508
+ }
13509
+ if (valueToken === "0" || valueToken === "false") {
13510
+ return false;
13511
+ }
13512
+ return void 0;
13513
+ }
13514
+ function parseP15FromExtLst(extLstNode, xmlLookupService, getXmlLocalName) {
13515
+ const extEntries = xmlLookupService.getChildrenArrayByLocalName(extLstNode, "ext");
13516
+ for (const ext of extEntries) {
13517
+ if (!ext) {
13518
+ continue;
13519
+ }
13520
+ for (const [key, value] of Object.entries(ext)) {
13521
+ if (key.startsWith("@_")) {
13522
+ continue;
13523
+ }
13524
+ if (getXmlLocalName(key) !== "prstTrans") {
13525
+ continue;
13526
+ }
13527
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
13528
+ continue;
13529
+ }
13530
+ const detail = value;
13531
+ const prst = String(detail["@_prst"] || "").trim();
13532
+ if (!P15_TRANSITION_PRESETS.has(prst)) {
13533
+ continue;
13534
+ }
13535
+ return {
13536
+ type: prst,
13537
+ invX: optionalBoolean(detail["@_invX"]),
13538
+ invY: optionalBoolean(detail["@_invY"])
13539
+ };
13540
+ }
13541
+ }
13542
+ return void 0;
13543
+ }
13544
+ function buildP15ExtLst(transitionType, invX, invY) {
13545
+ const prstTrans = {
13546
+ "@_xmlns:p15": "http://schemas.microsoft.com/office/powerpoint/2012/main",
13547
+ "@_prst": transitionType
13548
+ };
13549
+ const ext = {
13550
+ "@_uri": PRSTTRANS_EXT_URI,
13551
+ "p15:prstTrans": prstTrans
13552
+ };
13553
+ return { "p:ext": ext };
13554
+ }
13555
+
13454
13556
  // src/core/services/slide-transition-xml.ts
13455
13557
  var STANDARD_TRANSITION_TYPES = /* @__PURE__ */ new Set([
13456
13558
  "fade",
@@ -13516,7 +13618,7 @@ function parseTransitionDetails(node, localName22) {
13516
13618
  if (pattern) {
13517
13619
  result.pattern = pattern;
13518
13620
  }
13519
- const thruBlk = optionalBoolean(detail["@_thruBlk"]);
13621
+ const thruBlk = optionalBoolean2(detail["@_thruBlk"]);
13520
13622
  if (thruBlk !== void 0) {
13521
13623
  result.thruBlk = thruBlk;
13522
13624
  }
@@ -13527,7 +13629,7 @@ function parseTransitionAttributes(node) {
13527
13629
  const speedToken = token(node["@_spd"]);
13528
13630
  const speed = SPEEDS.has(speedToken) ? speedToken : void 0;
13529
13631
  const durationMs = unsignedInteger2(node["@_dur"] ?? node["@_p14:dur"], 1);
13530
- const advanceOnClick = optionalBoolean(node["@_advClick"]);
13632
+ const advanceOnClick = optionalBoolean2(node["@_advClick"]);
13531
13633
  const advanceAfterMs = unsignedInteger2(node["@_advTm"]);
13532
13634
  return { speed, durationMs, advanceOnClick, advanceAfterMs };
13533
13635
  }
@@ -13541,7 +13643,7 @@ function parseTransitionSound(raw, lookup, localName22) {
13541
13643
  return {
13542
13644
  soundRId: sound ? attributeByLocalName(sound, "embed", localName22) : void 0,
13543
13645
  soundName: sound ? attributeByLocalName(sound, "name", localName22) : void 0,
13544
- soundLoop: optionalBoolean(start["@_loop"])
13646
+ soundLoop: optionalBoolean2(start["@_loop"])
13545
13647
  };
13546
13648
  }
13547
13649
  const stopSound = Object.keys(raw).some(
@@ -13650,7 +13752,7 @@ function attributeByLocalName(node, name, localName22) {
13650
13752
  function token(value) {
13651
13753
  return value === void 0 || value === null ? "" : String(value).trim();
13652
13754
  }
13653
- function optionalBoolean(value) {
13755
+ function optionalBoolean2(value) {
13654
13756
  const valueToken = token(value).toLowerCase();
13655
13757
  if (!valueToken) {
13656
13758
  return void 0;
@@ -13696,6 +13798,7 @@ var PptxSlideTransitionService = class {
13696
13798
  const { spokes, thruBlk, rawSoundAction, rawExtLst } = details;
13697
13799
  if (rawExtLst && transitionType === "cut") {
13698
13800
  const p14Result = parseP14FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
13801
+ const p15Result = p14Result ? void 0 : parseP15FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
13699
13802
  if (p14Result) {
13700
13803
  transitionType = p14Result.type;
13701
13804
  if (p14Result.direction) {
@@ -13707,6 +13810,8 @@ var PptxSlideTransitionService = class {
13707
13810
  if (p14Result.pattern) {
13708
13811
  pattern = p14Result.pattern;
13709
13812
  }
13813
+ } else if (p15Result) {
13814
+ transitionType = p15Result.type;
13710
13815
  } else if (this.parseMorphFromExtLst(rawExtLst)) {
13711
13816
  transitionType = "morph";
13712
13817
  }
@@ -13788,6 +13893,7 @@ var PptxSlideTransitionService = class {
13788
13893
  }
13789
13894
  const transitionType = transition.type || "cut";
13790
13895
  const isP14Type = P14_TRANSITION_TYPES.has(transitionType);
13896
+ const isP15Type = P15_TRANSITION_PRESETS.has(transitionType);
13791
13897
  const isMorphType = transitionType === "morph";
13792
13898
  const node = createPreservedTransitionNode(transition.rawTransition, this.getXmlLocalName);
13793
13899
  if (isP14Type) {
@@ -13800,6 +13906,8 @@ var PptxSlideTransitionService = class {
13800
13906
  this.xmlLookupService,
13801
13907
  this.getXmlLocalName
13802
13908
  );
13909
+ } else if (isP15Type) {
13910
+ node["p:extLst"] = transition.rawExtLst ?? buildP15ExtLst(transitionType);
13803
13911
  } else if (isMorphType) {
13804
13912
  node["p:extLst"] = this.buildMorphExtLst(transition.rawExtLst);
13805
13913
  } else {
@@ -13810,7 +13918,7 @@ var PptxSlideTransitionService = class {
13810
13918
  if (soundAction) {
13811
13919
  node["p:sndAc"] = soundAction;
13812
13920
  }
13813
- if (transition.rawExtLst && !isP14Type && !isMorphType) {
13921
+ if (transition.rawExtLst && !isP14Type && !isP15Type && !isMorphType) {
13814
13922
  node["p:extLst"] = transition.rawExtLst;
13815
13923
  }
13816
13924
  return node;
@@ -29820,36 +29928,200 @@ async function fetchUrlToBytes(url, options = {}) {
29820
29928
  }
29821
29929
  }
29822
29930
 
29931
+ // src/core/utils/inkml-trace-decode.ts
29932
+ function resolveChannelOrder(root) {
29933
+ const traceFormat = findFirstByLocalName(root, "traceFormat");
29934
+ if (!traceFormat) {
29935
+ return ["X", "Y"];
29936
+ }
29937
+ const channels = ensureArray5(nsGet(traceFormat, "channel"));
29938
+ const names = channels.map(
29939
+ (channel) => String(nsAttr(channel, "name") ?? "").trim().toUpperCase()
29940
+ ).filter((name) => name.length > 0);
29941
+ return names.length > 0 ? names : ["X", "Y"];
29942
+ }
29943
+ function decodeTracePoints(text2, channelOrder) {
29944
+ const points3 = [];
29945
+ const modes = channelOrder.map(() => "explicit");
29946
+ const lastValue = channelOrder.map(() => 0);
29947
+ const lastVelocity = channelOrder.map(() => 0);
29948
+ for (const rawPoint of text2.split(",")) {
29949
+ const tokens = rawPoint.trim().split(/\s+/u).filter((token2) => token2.length > 0);
29950
+ if (tokens.length === 0) {
29951
+ continue;
29952
+ }
29953
+ const decoded = [];
29954
+ for (let i = 0; i < tokens.length && i < channelOrder.length; i++) {
29955
+ const parsed = parseValueToken(tokens[i], modes[i]);
29956
+ if (parsed === void 0) {
29957
+ decoded.push(lastValue[i]);
29958
+ continue;
29959
+ }
29960
+ modes[i] = parsed.mode;
29961
+ const value = applyDiffMode(parsed, i, lastValue, lastVelocity);
29962
+ decoded.push(value);
29963
+ }
29964
+ if (decoded.length >= 2) {
29965
+ points3.push(decoded);
29966
+ }
29967
+ }
29968
+ return points3;
29969
+ }
29970
+ function parseValueToken(token2, currentMode) {
29971
+ let mode = currentMode;
29972
+ let body = token2;
29973
+ const prefix = token2[0];
29974
+ if (prefix === "!") {
29975
+ mode = "explicit";
29976
+ body = token2.slice(1);
29977
+ } else if (prefix === "'") {
29978
+ mode = "single";
29979
+ body = token2.slice(1);
29980
+ } else if (prefix === '"') {
29981
+ mode = "double";
29982
+ body = token2.slice(1);
29983
+ }
29984
+ if (body.length === 0) {
29985
+ return void 0;
29986
+ }
29987
+ const value = Number(body);
29988
+ return Number.isFinite(value) ? { value, mode } : void 0;
29989
+ }
29990
+ function applyDiffMode(parsed, index, lastValue, lastVelocity) {
29991
+ if (parsed.mode === "single") {
29992
+ lastVelocity[index] = parsed.value;
29993
+ lastValue[index] += parsed.value;
29994
+ } else if (parsed.mode === "double") {
29995
+ lastVelocity[index] += parsed.value;
29996
+ lastValue[index] += lastVelocity[index];
29997
+ } else {
29998
+ lastValue[index] = parsed.value;
29999
+ lastVelocity[index] = 0;
30000
+ }
30001
+ return lastValue[index];
30002
+ }
30003
+ function pointsToSvgPath(points3, channelOrder) {
30004
+ const xi = channelOrder.indexOf("X");
30005
+ const yi = channelOrder.indexOf("Y");
30006
+ const xIndex = xi >= 0 ? xi : 0;
30007
+ const yIndex = yi >= 0 ? yi : 1;
30008
+ const segments = [];
30009
+ for (const point of points3) {
30010
+ const x = point[xIndex];
30011
+ const y = point[yIndex];
30012
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
30013
+ continue;
30014
+ }
30015
+ segments.push(`${segments.length === 0 ? "M" : "L"} ${x} ${y}`);
30016
+ }
30017
+ return segments.join(" ");
30018
+ }
30019
+ function pointsToPressures(points3, channelOrder) {
30020
+ const fIndex = channelOrder.indexOf("F");
30021
+ if (fIndex < 0) {
30022
+ return [];
30023
+ }
30024
+ const pressures = [];
30025
+ for (const point of points3) {
30026
+ const raw = point[fIndex];
30027
+ if (Number.isFinite(raw)) {
30028
+ const normalised = raw > 1 ? raw / 32767 : raw;
30029
+ pressures.push(Math.max(0, Math.min(1, normalised)));
30030
+ }
30031
+ }
30032
+ return pressures;
30033
+ }
30034
+ function nsGet(obj, localName22) {
30035
+ if (localName22 in obj) {
30036
+ return obj[localName22];
30037
+ }
30038
+ for (const key of Object.keys(obj)) {
30039
+ if (localNameOf(key) === localName22 && !key.startsWith("@_")) {
30040
+ return obj[key];
30041
+ }
30042
+ }
30043
+ return void 0;
30044
+ }
30045
+ function nsAttr(obj, localName22) {
30046
+ const direct = obj[`@_${localName22}`];
30047
+ if (direct !== void 0) {
30048
+ return direct;
30049
+ }
30050
+ for (const key of Object.keys(obj)) {
30051
+ if (key.startsWith("@_") && localNameOf(key.slice(2)) === localName22) {
30052
+ return obj[key];
30053
+ }
30054
+ }
30055
+ return void 0;
30056
+ }
30057
+ function localNameOf(key) {
30058
+ const colon = key.indexOf(":");
30059
+ return colon >= 0 ? key.slice(colon + 1) : key;
30060
+ }
30061
+ function findFirstByLocalName(node, localName22) {
30062
+ const direct = nsGet(node, localName22);
30063
+ if (direct && typeof direct === "object") {
30064
+ return Array.isArray(direct) ? direct[0] : direct;
30065
+ }
30066
+ for (const key of Object.keys(node)) {
30067
+ if (key.startsWith("@_") || key === "#text") {
30068
+ continue;
30069
+ }
30070
+ for (const child20 of ensureArray5(node[key])) {
30071
+ if (typeof child20 !== "object") {
30072
+ continue;
30073
+ }
30074
+ const found = findFirstByLocalName(child20, localName22);
30075
+ if (found) {
30076
+ return found;
30077
+ }
30078
+ }
30079
+ }
30080
+ return void 0;
30081
+ }
30082
+ function ensureArray5(value) {
30083
+ if (value === void 0 || value === null) {
30084
+ return [];
30085
+ }
30086
+ return Array.isArray(value) ? value : [value];
30087
+ }
30088
+
29823
30089
  // src/core/utils/inkml-content-part.ts
29824
30090
  var INKML_NAMESPACE = "http://www.w3.org/2003/InkML";
29825
30091
  var METADATA_NAMESPACE = "https://pptx-viewer.dev/inkml/metadata";
29826
30092
  function parseInkMlContent(data) {
29827
- const root = data["ink:ink"] ?? data["ink"];
30093
+ const root = nsGet(data, "ink") ?? data["ink"];
29828
30094
  if (!root) {
29829
30095
  return { strokes: [], rawXml: data };
29830
30096
  }
29831
30097
  const brushes = /* @__PURE__ */ new Map();
29832
- for (const brush of ensureArray5(root["ink:brush"] ?? root["brush"])) {
29833
- const properties = ensureArray5(brush["ink:brushProperty"] ?? brush["brushProperty"]);
30098
+ for (const brush of ensureArray5(nsGet(root, "brush"))) {
30099
+ const properties = ensureArray5(nsGet(brush, "brushProperty"));
29834
30100
  const valueByName = new Map(
29835
- properties.map((property) => [String(property["@_name"] ?? ""), property["@_value"]])
30101
+ properties.map((property) => [
30102
+ String(nsAttr(property, "name") ?? ""),
30103
+ nsAttr(property, "value")
30104
+ ])
29836
30105
  );
29837
- brushes.set(String(brush["@_id"] ?? ""), {
30106
+ brushes.set(String(nsAttr(brush, "id") ?? ""), {
29838
30107
  color: String(valueByName.get("color") ?? "#000000"),
29839
30108
  width: finiteNumber(valueByName.get("width"), 1),
29840
30109
  opacity: finiteNumber(valueByName.get("opacity"), 1)
29841
30110
  });
29842
30111
  }
30112
+ const channelOrder = resolveChannelOrder(root);
29843
30113
  const strokes = [];
29844
- for (const trace of ensureArray5(root["ink:trace"] ?? root["trace"])) {
30114
+ for (const trace of ensureArray5(nsGet(root, "trace"))) {
29845
30115
  const text2 = typeof trace === "string" ? trace : String(trace["#text"] ?? "").trim();
29846
- const path = typeof trace === "string" ? text2 : String(trace["@_pva:path"] ?? "").trim() || text2;
30116
+ const authored = typeof trace === "string" ? "" : String(nsAttr(trace, "path") ?? "").trim();
30117
+ const points3 = authored ? [] : decodeTracePoints(text2, channelOrder);
30118
+ const path = authored || pointsToSvgPath(points3, channelOrder);
29847
30119
  if (!path) {
29848
30120
  continue;
29849
30121
  }
29850
- const brushRef = typeof trace === "string" ? "" : String(trace["@_brushRef"] ?? "").replace("#", "");
30122
+ const brushRef = typeof trace === "string" ? "" : String(nsAttr(trace, "brushRef") ?? "").replace("#", "");
29851
30123
  const brush = brushes.get(brushRef) ?? { color: "#000000", width: 1, opacity: 1 };
29852
- const pressures = tracePressures(text2);
30124
+ const pressures = authored ? tracePressures(text2) : pointsToPressures(points3, channelOrder);
29853
30125
  strokes.push({ ...brush, path, ...pressures.length > 0 ? { pressures } : {} });
29854
30126
  }
29855
30127
  return { strokes, rawXml: data };
@@ -29908,12 +30180,6 @@ function finiteNumber(value, fallback) {
29908
30180
  const parsed = Number(value);
29909
30181
  return Number.isFinite(parsed) ? parsed : fallback;
29910
30182
  }
29911
- function ensureArray5(value) {
29912
- if (value === void 0 || value === null) {
29913
- return [];
29914
- }
29915
- return Array.isArray(value) ? value : [value];
29916
- }
29917
30183
 
29918
30184
  // src/core/utils/smartart-helpers.ts
29919
30185
  var DEFAULT_ACCENT_COLORS = [
@@ -47335,6 +47601,93 @@ var PptxHandlerRuntime = class {
47335
47601
  }
47336
47602
  };
47337
47603
 
47604
+ // src/core/core/runtime/table-style-border-parse.ts
47605
+ var EMU_PER_PIXEL = 9525;
47606
+ var BORDER_SIDES = [
47607
+ "left",
47608
+ "right",
47609
+ "top",
47610
+ "bottom",
47611
+ "insideH",
47612
+ "insideV",
47613
+ "tl2br",
47614
+ "bl2tr"
47615
+ ];
47616
+ function parseSolidFillStyle(solidFill2) {
47617
+ if (!solidFill2) {
47618
+ return void 0;
47619
+ }
47620
+ const schemeClr = solidFill2["a:schemeClr"];
47621
+ if (!schemeClr) {
47622
+ return void 0;
47623
+ }
47624
+ const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
47625
+ if (!schemeColor) {
47626
+ return void 0;
47627
+ }
47628
+ const tintRaw = schemeClr["a:tint"];
47629
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
47630
+ const shadeRaw = schemeClr["a:shade"];
47631
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
47632
+ return { schemeColor, tint, shade };
47633
+ }
47634
+ function parseBorderSide(side) {
47635
+ if (!side) {
47636
+ return void 0;
47637
+ }
47638
+ const ln = side["a:ln"];
47639
+ if (!ln) {
47640
+ return void 0;
47641
+ }
47642
+ const border = {};
47643
+ let has = false;
47644
+ if (ln["a:noFill"] !== void 0) {
47645
+ border.noFill = true;
47646
+ has = true;
47647
+ }
47648
+ const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
47649
+ if (widthEmu > 0) {
47650
+ border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL));
47651
+ has = true;
47652
+ }
47653
+ const prstDash = ln["a:prstDash"];
47654
+ const dashVal = prstDash ? String(prstDash["@_val"] || "").trim() : "";
47655
+ if (dashVal) {
47656
+ border.dash = dashVal;
47657
+ has = true;
47658
+ }
47659
+ const solidFill2 = ln["a:solidFill"];
47660
+ const fill = parseSolidFillStyle(solidFill2);
47661
+ if (fill) {
47662
+ border.fill = fill;
47663
+ has = true;
47664
+ } else {
47665
+ const srgb = solidFill2?.["a:srgbClr"];
47666
+ const hex10 = srgb ? String(srgb["@_val"] || "").trim() : "";
47667
+ if (hex10) {
47668
+ border.color = hex10.startsWith("#") ? hex10 : `#${hex10}`;
47669
+ has = true;
47670
+ }
47671
+ }
47672
+ return has ? border : void 0;
47673
+ }
47674
+ function parseTableStyleBorders(tcStyle) {
47675
+ const tcBdr = tcStyle?.["a:tcBdr"];
47676
+ if (!tcBdr) {
47677
+ return void 0;
47678
+ }
47679
+ const result = {};
47680
+ let has = false;
47681
+ for (const name of BORDER_SIDES) {
47682
+ const border = parseBorderSide(tcBdr[`a:${name}`]);
47683
+ if (border) {
47684
+ result[name] = border;
47685
+ has = true;
47686
+ }
47687
+ }
47688
+ return has ? result : void 0;
47689
+ }
47690
+
47338
47691
  // src/core/core/runtime/PptxHandlerRuntimeTableStyles.ts
47339
47692
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47340
47693
  /**
@@ -47419,30 +47772,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47419
47772
  return void 0;
47420
47773
  }
47421
47774
  const tcStyle = section["a:tcStyle"];
47422
- if (!tcStyle) {
47423
- return void 0;
47424
- }
47425
- const fill = tcStyle["a:fill"];
47426
- if (!fill) {
47427
- return void 0;
47428
- }
47429
- const solidFill2 = fill["a:solidFill"];
47430
- if (!solidFill2) {
47431
- return void 0;
47432
- }
47433
- const schemeClr = solidFill2["a:schemeClr"];
47434
- if (!schemeClr) {
47435
- return void 0;
47436
- }
47437
- const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
47438
- if (!schemeColor) {
47439
- return void 0;
47440
- }
47441
- const tintRaw = schemeClr["a:tint"];
47442
- const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
47443
- const shadeRaw = schemeClr["a:shade"];
47444
- const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
47445
- return { schemeColor, tint, shade };
47775
+ const fill = tcStyle?.["a:fill"];
47776
+ return parseSolidFillStyle(fill?.["a:solidFill"]);
47777
+ }
47778
+ /**
47779
+ * Extract border styling from a table style section's
47780
+ * `a:tcStyle/a:tcBdr` (per-side line width, dash, and colour).
47781
+ */
47782
+ extractTableStyleSectionBorders(section) {
47783
+ return parseTableStyleBorders(section?.["a:tcStyle"]);
47446
47784
  }
47447
47785
  /**
47448
47786
  * Extract text properties from a:tcTxStyle in a table style section.
@@ -47589,6 +47927,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47589
47927
  textProps[`${name}Text`] = text2;
47590
47928
  }
47591
47929
  }
47930
+ const borderProps = {};
47931
+ for (const name of sectionNames) {
47932
+ const borders = this.extractTableStyleSectionBorders(
47933
+ style[`a:${name}`]
47934
+ );
47935
+ if (borders) {
47936
+ borderProps[`${name}Borders`] = borders;
47937
+ }
47938
+ }
47592
47939
  const entry = {
47593
47940
  styleId,
47594
47941
  styleName,
@@ -47607,7 +47954,8 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47607
47954
  ...swCellFill ? { swCellFill } : {},
47608
47955
  ...neCellFill ? { neCellFill } : {},
47609
47956
  ...nwCellFill ? { nwCellFill } : {},
47610
- ...textProps
47957
+ ...textProps,
47958
+ ...borderProps
47611
47959
  };
47612
47960
  map[styleId] = entry;
47613
47961
  }
@@ -49418,6 +49766,15 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
49418
49766
  if (align === "justify") {
49419
49767
  return "just";
49420
49768
  }
49769
+ if (align === "justLow") {
49770
+ return "justLow";
49771
+ }
49772
+ if (align === "dist") {
49773
+ return "dist";
49774
+ }
49775
+ if (align === "thaiDist") {
49776
+ return "thaiDist";
49777
+ }
49421
49778
  return void 0;
49422
49779
  }
49423
49780
  pixelsToPoints(px2) {
@@ -50472,6 +50829,16 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
50472
50829
  const chOffY = 0;
50473
50830
  const chExtCx = extCx;
50474
50831
  const chExtCy = extCy;
50832
+ const xfrmAttrs = {};
50833
+ if (typeof group.rotation === "number" && group.rotation !== 0) {
50834
+ xfrmAttrs["@_rot"] = String(Math.round(group.rotation * 6e4));
50835
+ }
50836
+ if (group.flipHorizontal) {
50837
+ xfrmAttrs["@_flipH"] = "1";
50838
+ }
50839
+ if (group.flipVertical) {
50840
+ xfrmAttrs["@_flipV"] = "1";
50841
+ }
50475
50842
  const grpXml = {
50476
50843
  "p:nvGrpSpPr": {
50477
50844
  "p:cNvPr": { "@_id": "0", "@_name": group.id },
@@ -50480,6 +50847,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
50480
50847
  },
50481
50848
  "p:grpSpPr": {
50482
50849
  "a:xfrm": {
50850
+ ...xfrmAttrs,
50483
50851
  "a:off": {
50484
50852
  "@_x": String(offX),
50485
50853
  "@_y": String(offY)
@@ -56668,45 +57036,18 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56668
57036
  const s3d = shapeStyle.scene3d;
56669
57037
  const hasData = s3d.cameraPreset || s3d.lightRigType;
56670
57038
  if (hasData) {
56671
- const cameraObj = {};
56672
- if (s3d.cameraPreset) {
56673
- cameraObj["@_prst"] = s3d.cameraPreset;
56674
- }
56675
- if (s3d.cameraRotX !== void 0 || s3d.cameraRotY !== void 0 || s3d.cameraRotZ !== void 0) {
56676
- const rot = {};
56677
- if (s3d.cameraRotX !== void 0) {
56678
- rot["@_lat"] = String(s3d.cameraRotX);
56679
- }
56680
- if (s3d.cameraRotY !== void 0) {
56681
- rot["@_lon"] = String(s3d.cameraRotY);
56682
- }
56683
- if (s3d.cameraRotZ !== void 0) {
56684
- rot["@_rev"] = String(s3d.cameraRotZ);
56685
- }
56686
- cameraObj["a:rot"] = rot;
56687
- }
56688
- const lightRigObj = {};
56689
- if (s3d.lightRigType) {
56690
- lightRigObj["@_rig"] = s3d.lightRigType;
56691
- }
56692
- if (s3d.lightRigDirection) {
56693
- lightRigObj["@_dir"] = s3d.lightRigDirection;
56694
- }
56695
- const scene3dXml = {};
56696
- scene3dXml["a:camera"] = cameraObj;
56697
- if (Object.keys(lightRigObj).length > 0) {
56698
- scene3dXml["a:lightRig"] = lightRigObj;
56699
- }
56700
- if (s3d.hasBackdrop) {
56701
- const backdropObj = {};
56702
- if (s3d.backdropAnchorX !== void 0 || s3d.backdropAnchorY !== void 0 || s3d.backdropAnchorZ !== void 0) {
56703
- backdropObj["a:anchor"] = {
56704
- "@_x": String(s3d.backdropAnchorX ?? 0),
56705
- "@_y": String(s3d.backdropAnchorY ?? 0),
56706
- "@_z": String(s3d.backdropAnchorZ ?? 0)
56707
- };
56708
- }
56709
- scene3dXml["a:backdrop"] = backdropObj;
57039
+ const source = spPr["a:scene3d"] ?? {};
57040
+ const scene3dXml = { ...source };
57041
+ scene3dXml["a:camera"] = buildScene3dCamera(s3d, source);
57042
+ const lightRig = buildScene3dLightRig(s3d, source);
57043
+ if (lightRig) {
57044
+ scene3dXml["a:lightRig"] = lightRig;
57045
+ }
57046
+ const backdrop = buildScene3dBackdrop(s3d);
57047
+ if (backdrop) {
57048
+ scene3dXml["a:backdrop"] = backdrop;
57049
+ } else {
57050
+ delete scene3dXml["a:backdrop"];
56710
57051
  }
56711
57052
  spPr["a:scene3d"] = scene3dXml;
56712
57053
  } else {
@@ -56751,12 +57092,12 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56751
57092
  }
56752
57093
  if (sh3d.extrusionColor) {
56753
57094
  sp3dXml["a:extrusionClr"] = {
56754
- "a:srgbClr": { "@_val": sh3d.extrusionColor }
57095
+ "a:srgbClr": { "@_val": sh3d.extrusionColor.replace("#", "") }
56755
57096
  };
56756
57097
  }
56757
57098
  if (sh3d.contourColor) {
56758
57099
  sp3dXml["a:contourClr"] = {
56759
- "a:srgbClr": { "@_val": sh3d.contourColor }
57100
+ "a:srgbClr": { "@_val": sh3d.contourColor.replace("#", "") }
56760
57101
  };
56761
57102
  }
56762
57103
  spPr["a:sp3d"] = sp3dXml;
@@ -56768,6 +57109,77 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56768
57109
  }
56769
57110
  }
56770
57111
  };
57112
+ function buildSphereRot(lat, lon, rev) {
57113
+ if (lat === void 0 && lon === void 0 && rev === void 0) {
57114
+ return void 0;
57115
+ }
57116
+ const rot = {};
57117
+ if (lat !== void 0) {
57118
+ rot["@_lat"] = String(lat);
57119
+ }
57120
+ if (lon !== void 0) {
57121
+ rot["@_lon"] = String(lon);
57122
+ }
57123
+ if (rev !== void 0) {
57124
+ rot["@_rev"] = String(rev);
57125
+ }
57126
+ return rot;
57127
+ }
57128
+ function buildScene3dCamera(s3d, source) {
57129
+ const camera = { ...source["a:camera"] ?? {} };
57130
+ if (s3d.cameraPreset) {
57131
+ camera["@_prst"] = s3d.cameraPreset;
57132
+ }
57133
+ if (s3d.cameraFieldOfView !== void 0) {
57134
+ camera["@_fov"] = String(s3d.cameraFieldOfView);
57135
+ }
57136
+ if (s3d.cameraZoom !== void 0) {
57137
+ camera["@_zoom"] = String(s3d.cameraZoom);
57138
+ }
57139
+ const rot = buildSphereRot(s3d.cameraRotX, s3d.cameraRotY, s3d.cameraRotZ);
57140
+ if (rot) {
57141
+ camera["a:rot"] = rot;
57142
+ }
57143
+ return camera;
57144
+ }
57145
+ function buildScene3dLightRig(s3d, source) {
57146
+ const lightRig = { ...source["a:lightRig"] ?? {} };
57147
+ if (s3d.lightRigType) {
57148
+ lightRig["@_rig"] = s3d.lightRigType;
57149
+ }
57150
+ if (s3d.lightRigDirection) {
57151
+ lightRig["@_dir"] = s3d.lightRigDirection;
57152
+ }
57153
+ const rot = buildSphereRot(s3d.lightRigRotX, s3d.lightRigRotY, s3d.lightRigRotZ);
57154
+ if (rot) {
57155
+ lightRig["a:rot"] = rot;
57156
+ }
57157
+ return Object.keys(lightRig).length > 0 ? lightRig : void 0;
57158
+ }
57159
+ function buildScene3dBackdrop(s3d) {
57160
+ const hasNorm = s3d.backdropNormalX !== void 0 || s3d.backdropNormalY !== void 0 || s3d.backdropNormalZ !== void 0;
57161
+ const hasUp = s3d.backdropUpX !== void 0 || s3d.backdropUpY !== void 0 || s3d.backdropUpZ !== void 0;
57162
+ if (!s3d.hasBackdrop || !hasNorm || !hasUp) {
57163
+ return void 0;
57164
+ }
57165
+ return {
57166
+ "a:anchor": {
57167
+ "@_x": String(s3d.backdropAnchorX ?? 0),
57168
+ "@_y": String(s3d.backdropAnchorY ?? 0),
57169
+ "@_z": String(s3d.backdropAnchorZ ?? 0)
57170
+ },
57171
+ "a:norm": {
57172
+ "@_dx": String(s3d.backdropNormalX ?? 0),
57173
+ "@_dy": String(s3d.backdropNormalY ?? 0),
57174
+ "@_dz": String(s3d.backdropNormalZ ?? 0)
57175
+ },
57176
+ "a:up": {
57177
+ "@_dx": String(s3d.backdropUpX ?? 0),
57178
+ "@_dy": String(s3d.backdropUpY ?? 0),
57179
+ "@_dz": String(s3d.backdropUpZ ?? 0)
57180
+ }
57181
+ };
57182
+ }
56771
57183
 
56772
57184
  // src/core/core/runtime/PptxHandlerRuntimeSaveTextWriter.ts
56773
57185
  var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime29 {
@@ -63197,7 +63609,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63197
63609
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
63198
63610
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
63199
63611
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
63200
- const mediaReference = parseDrawingMediaReference(nvPr);
63612
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
63201
63613
  if (mediaReference) {
63202
63614
  this.compatibilityService.inspectMediaReferenceCompatibility(
63203
63615
  mediaReference.kind,
@@ -63965,6 +64377,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63965
64377
  const grpSpPr = group["p:grpSpPr"];
63966
64378
  const xfrm = grpSpPr?.["a:xfrm"];
63967
64379
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
64380
+ let groupRotation;
64381
+ let flipHorizontal = false;
64382
+ let flipVertical = false;
63968
64383
  if (xfrm) {
63969
64384
  const off = xfrm["a:off"];
63970
64385
  if (off) {
@@ -63976,6 +64391,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63976
64391
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63977
64392
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63978
64393
  }
64394
+ if (xfrm["@_rot"] !== void 0 && xfrm["@_rot"] !== null) {
64395
+ const rot = parseInt(String(xfrm["@_rot"]), 10) / 6e4;
64396
+ groupRotation = Number.isFinite(rot) && rot !== 0 ? rot : void 0;
64397
+ }
64398
+ flipHorizontal = this.parseBooleanAttr(xfrm["@_flipH"]);
64399
+ flipVertical = this.parseBooleanAttr(xfrm["@_flipV"]);
63979
64400
  }
63980
64401
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
63981
64402
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -64021,6 +64442,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
64021
64442
  y: parentY,
64022
64443
  width: parentW || Math.max(...children10.map((c) => c.x + c.width)),
64023
64444
  height: parentH || Math.max(...children10.map((c) => c.y + c.height)),
64445
+ rotation: groupRotation,
64446
+ flipHorizontal: flipHorizontal || void 0,
64447
+ flipVertical: flipVertical || void 0,
64024
64448
  children: children10,
64025
64449
  rawXml: group,
64026
64450
  actionClick: grpActionClick,
@@ -65037,9 +65461,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
65037
65461
  }
65038
65462
  const buClr = levelProps["a:buClr"];
65039
65463
  if (buClr) {
65040
- const srgb = buClr["a:srgbClr"];
65041
- if (srgb?.["@_val"]) {
65042
- style.bulletColor = String(srgb["@_val"]);
65464
+ const bulletColor = this.parseColor(buClr);
65465
+ if (bulletColor) {
65466
+ style.bulletColor = bulletColor;
65043
65467
  }
65044
65468
  }
65045
65469
  const buSzPts = levelProps["a:buSzPts"];
@@ -67541,6 +67965,89 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
67541
67965
  }
67542
67966
  };
67543
67967
 
67968
+ // src/core/core/runtime/smartart-drawing-shape-style.ts
67969
+ function extractDrawingShapeFill(spPr, deps) {
67970
+ const result = {};
67971
+ const solidFill2 = deps.getChild(spPr, "solidFill");
67972
+ if (solidFill2) {
67973
+ result.fillColor = deps.parseColor(solidFill2) ?? void 0;
67974
+ }
67975
+ const gradFill = !solidFill2 ? deps.getChild(spPr, "gradFill") : void 0;
67976
+ if (gradFill) {
67977
+ const stops = deps.extractGradientStops(gradFill).map((stop) => ({
67978
+ color: stop.color,
67979
+ position: stop.position,
67980
+ ...stop.opacity !== void 0 ? { opacity: stop.opacity } : {}
67981
+ }));
67982
+ if (stops.length > 0) {
67983
+ result.fillGradientStops = stops;
67984
+ result.fillGradientType = deps.extractGradientType(gradFill);
67985
+ result.fillGradientAngle = deps.extractGradientAngle(gradFill);
67986
+ result.fillColor ??= stops[Math.floor(stops.length / 2)]?.color;
67987
+ }
67988
+ }
67989
+ const pattFill = !solidFill2 && !gradFill ? deps.getChild(spPr, "pattFill") : void 0;
67990
+ if (pattFill) {
67991
+ const preset = String(pattFill["@_prst"] || "").trim();
67992
+ if (preset) {
67993
+ result.fillPatternPreset = preset;
67994
+ }
67995
+ const fg = deps.parseColor(deps.getChild(pattFill, "fgClr"));
67996
+ const bg = deps.parseColor(deps.getChild(pattFill, "bgClr"));
67997
+ if (fg) {
67998
+ result.fillPatternForegroundColor = fg;
67999
+ }
68000
+ if (bg) {
68001
+ result.fillPatternBackgroundColor = bg;
68002
+ }
68003
+ result.fillColor ??= fg ?? bg;
68004
+ }
68005
+ const blipFill = !solidFill2 && !gradFill && !pattFill ? deps.getChild(spPr, "blipFill") : void 0;
68006
+ if (blipFill) {
68007
+ const blip = deps.getChild(blipFill, "blip");
68008
+ const embed = String(
68009
+ blip?.["@_r:embed"] || blip?.["@_embed"] || blip?.["@_r:link"] || ""
68010
+ ).trim();
68011
+ if (embed) {
68012
+ result.fillBlipEmbedId = embed;
68013
+ }
68014
+ }
68015
+ const shadowColor = deps.extractShadowColor(spPr);
68016
+ if (shadowColor) {
68017
+ result.hasShadow = true;
68018
+ result.shadowColor = shadowColor;
68019
+ }
68020
+ return result;
68021
+ }
68022
+ function extractDrawingShapeTextStyle(txBody, deps) {
68023
+ let fontSize;
68024
+ let fontColor;
68025
+ if (!txBody) {
68026
+ return { fontSize, fontColor };
68027
+ }
68028
+ const paragraphs = deps.getChildren(txBody, "p");
68029
+ for (const p of paragraphs) {
68030
+ const runs = deps.getChildren(p, "r");
68031
+ for (const r of runs) {
68032
+ const rPr = deps.getChild(r, "rPr");
68033
+ if (rPr && !fontSize) {
68034
+ const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
68035
+ if (Number.isFinite(szRaw) && szRaw > 0) {
68036
+ fontSize = szRaw / 100;
68037
+ }
68038
+ fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
68039
+ }
68040
+ if (fontSize) {
68041
+ break;
68042
+ }
68043
+ }
68044
+ if (fontSize) {
68045
+ break;
68046
+ }
68047
+ }
68048
+ return { fontSize, fontColor };
68049
+ }
68050
+
67544
68051
  // src/core/core/runtime/smartart-text-style-resolution.ts
67545
68052
  function resolveSmartArtTextStyles(paragraphs, resolve) {
67546
68053
  for (const paragraph of paragraphs ?? []) {
@@ -67716,8 +68223,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67716
68223
  };
67717
68224
  }
67718
68225
  }
67719
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
67720
- const fillColor = this.parseColor(solidFill2);
68226
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
67721
68227
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
67722
68228
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
67723
68229
  const strokeColor = this.parseColor(lnFill);
@@ -67729,7 +68235,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67729
68235
  this.collectLocalTextValues(txBody, "t", textValues2);
67730
68236
  }
67731
68237
  const text2 = textValues2.join("").trim() || void 0;
67732
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
68238
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
68239
+ txBody,
68240
+ this.drawingShapeStyleDeps()
68241
+ );
67733
68242
  const paragraphs = txBody ? resolveSmartArtTextStyles(
67734
68243
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
67735
68244
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -67755,7 +68264,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67755
68264
  rotation,
67756
68265
  skewX,
67757
68266
  skewY,
67758
- fillColor: fillColor ?? void 0,
68267
+ ...fill,
68268
+ fillColor: fill.fillColor ?? void 0,
67759
68269
  strokeColor: strokeColor ?? void 0,
67760
68270
  strokeWidth,
67761
68271
  text: structuredText,
@@ -67765,34 +68275,21 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67765
68275
  ...customGeometry
67766
68276
  };
67767
68277
  }
67768
- extractDrawingShapeTextStyle(txBody) {
67769
- let fontSize;
67770
- let fontColor;
67771
- if (!txBody) {
67772
- return { fontSize, fontColor };
67773
- }
67774
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
67775
- for (const p of paragraphs) {
67776
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
67777
- for (const r of runs) {
67778
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
67779
- if (rPr && !fontSize) {
67780
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
67781
- if (Number.isFinite(szRaw) && szRaw > 0) {
67782
- fontSize = szRaw / 100;
67783
- }
67784
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
67785
- fontColor = this.parseColor(rprFill) ?? void 0;
67786
- }
67787
- if (fontSize) {
67788
- break;
67789
- }
67790
- }
67791
- if (fontSize) {
67792
- break;
67793
- }
67794
- }
67795
- return { fontSize, fontColor };
68278
+ /**
68279
+ * Build the injected accessor bundle used by the pure drawing-shape style
68280
+ * helpers, binding the shared XML-lookup / colour / gradient / shadow codec
68281
+ * methods so no new colour logic is duplicated here.
68282
+ */
68283
+ drawingShapeStyleDeps() {
68284
+ return {
68285
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
68286
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
68287
+ parseColor: (node) => this.parseColor(node),
68288
+ extractGradientStops: (gradFill) => this.extractGradientStops(gradFill),
68289
+ extractGradientType: (gradFill) => this.extractGradientType(gradFill),
68290
+ extractGradientAngle: (gradFill) => this.extractGradientAngle(gradFill),
68291
+ extractShadowColor: (spPr) => this.extractShadowStyle(spPr).shadowColor
68292
+ };
67796
68293
  }
67797
68294
  };
67798
68295
 
@@ -70266,6 +70763,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime extends PptxHandlerRuntime9
70266
70763
  });
70267
70764
  this.mediaDataParser = new PptxMediaDataParser({
70268
70765
  slideRelsMap: this.slideRelsMap,
70766
+ externalRelsMap: this.externalRelsMap,
70269
70767
  resolvePath: (base, relative) => this.resolvePath(base, relative),
70270
70768
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
70271
70769
  });
@@ -72956,9 +73454,9 @@ function removeEmptyDataPoint(series, pointIndex) {
72956
73454
  }
72957
73455
  }
72958
73456
  }
72959
- var EMU_PER_PIXEL = 9525;
73457
+ var EMU_PER_PIXEL2 = 9525;
72960
73458
  function pxToEmu(px2) {
72961
- return Math.round(px2 * EMU_PER_PIXEL);
73459
+ return Math.round(px2 * EMU_PER_PIXEL2);
72962
73460
  }
72963
73461
  function placeholderSpXml(ph, shapeId) {
72964
73462
  const name = ph.name ?? `${ph.type.charAt(0).toUpperCase() + ph.type.slice(1)} Placeholder ${shapeId - 1}`;
@@ -74712,7 +75210,7 @@ var GroupBuilder = class _GroupBuilder {
74712
75210
  // src/core/builders/sdk/units.ts
74713
75211
  var PPI = 96;
74714
75212
  var POINTS_PER_INCH = 72;
74715
- var EMU_PER_PIXEL2 = 9525;
75213
+ var EMU_PER_PIXEL3 = 9525;
74716
75214
  var EMU_PER_INCH = 914400;
74717
75215
  var EMU_PER_POINT = 12700;
74718
75216
  function inches(value) {
@@ -74728,10 +75226,10 @@ function pt(value) {
74728
75226
  return Math.round(value / POINTS_PER_INCH * PPI);
74729
75227
  }
74730
75228
  function emuToPixels(emu) {
74731
- return Math.round(emu / EMU_PER_PIXEL2);
75229
+ return Math.round(emu / EMU_PER_PIXEL3);
74732
75230
  }
74733
75231
  function pixelsToEmu(px2) {
74734
- return Math.round(px2 * EMU_PER_PIXEL2);
75232
+ return Math.round(px2 * EMU_PER_PIXEL3);
74735
75233
  }
74736
75234
  function inchesToEmu(value) {
74737
75235
  return Math.round(value * EMU_PER_INCH);
@@ -85077,7 +85575,7 @@ exports.EFFECT_LST_ORDER = EFFECT_LST_ORDER;
85077
85575
  exports.ELEMENT_FIELD_KIND = ELEMENT_FIELD_KIND;
85078
85576
  exports.EMPHASIS_PRESETS = EMPHASIS_PRESETS;
85079
85577
  exports.EMU_PER_INCH = EMU_PER_INCH;
85080
- exports.EMU_PER_PIXEL = EMU_PER_PIXEL2;
85578
+ exports.EMU_PER_PIXEL = EMU_PER_PIXEL3;
85081
85579
  exports.EMU_PER_POINT = EMU_PER_POINT;
85082
85580
  exports.EMU_PER_PX = EMU_PER_PX;
85083
85581
  exports.ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV = ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV;