pptx-react-viewer 1.1.3 → 1.1.4
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 +587 -288
- package/dist/index.mjs +587 -288
- package/dist/pptx-viewer.css +1 -1
- package/dist/viewer/index.js +587 -288
- package/dist/viewer/index.mjs +587 -288
- package/node_modules/emf-converter/package.json +2 -2
- package/node_modules/mtx-decompressor/package.json +2 -2
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-BMjoxMDV.d.ts → SvgExporter-0TxiiorD.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-z6AbXRQg.d.mts → SvgExporter-BQ4KbRO9.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.js +2711 -304
- package/node_modules/pptx-viewer-core/dist/cli/index.mjs +2711 -304
- package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
- package/node_modules/pptx-viewer-core/dist/index.d.mts +692 -44
- package/node_modules/pptx-viewer-core/dist/index.d.ts +692 -44
- package/node_modules/pptx-viewer-core/dist/index.js +2794 -373
- package/node_modules/pptx-viewer-core/dist/index.mjs +2785 -373
- package/node_modules/pptx-viewer-core/dist/{presentation-CchuDGfU.d.mts → presentation-ArhfImJ5.d.mts} +225 -8
- package/node_modules/pptx-viewer-core/dist/{presentation-CchuDGfU.d.ts → presentation-ArhfImJ5.d.ts} +225 -8
- package/node_modules/pptx-viewer-core/dist/{text-operations-CeukUztU.d.mts → text-operations-CLj-sJyk.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{text-operations-e7JxgI5l.d.ts → text-operations-rhJV-A_W.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/package.json +5 -5
- package/package.json +20 -20
|
@@ -4426,12 +4426,25 @@ function svgToCustomGeometryPaths(pathData, width, height) {
|
|
|
4426
4426
|
function pointToXml(pt) {
|
|
4427
4427
|
return { "@_x": String(Math.round(pt.x)), "@_y": String(Math.round(pt.y)) };
|
|
4428
4428
|
}
|
|
4429
|
-
function customGeometryPathsToXml(paths) {
|
|
4429
|
+
function customGeometryPathsToXml(paths, rawData) {
|
|
4430
4430
|
const xmlPaths = paths.map((path2) => {
|
|
4431
4431
|
const pathXml = {
|
|
4432
4432
|
"@_w": String(Math.round(path2.width)),
|
|
4433
4433
|
"@_h": String(Math.round(path2.height))
|
|
4434
4434
|
};
|
|
4435
|
+
if (path2.fillMode) {
|
|
4436
|
+
pathXml["@_fill"] = path2.fillMode;
|
|
4437
|
+
}
|
|
4438
|
+
if (path2.stroke === false) {
|
|
4439
|
+
pathXml["@_stroke"] = "0";
|
|
4440
|
+
} else if (path2.stroke === true) {
|
|
4441
|
+
pathXml["@_stroke"] = "1";
|
|
4442
|
+
}
|
|
4443
|
+
if (path2.extrusionOk === true) {
|
|
4444
|
+
pathXml["@_extrusionOk"] = "1";
|
|
4445
|
+
} else if (path2.extrusionOk === false) {
|
|
4446
|
+
pathXml["@_extrusionOk"] = "0";
|
|
4447
|
+
}
|
|
4435
4448
|
const moveToList = [];
|
|
4436
4449
|
const lnToList = [];
|
|
4437
4450
|
const cubicBezToList = [];
|
|
@@ -4489,12 +4502,12 @@ function customGeometryPathsToXml(paths) {
|
|
|
4489
4502
|
}
|
|
4490
4503
|
return pathXml;
|
|
4491
4504
|
});
|
|
4492
|
-
|
|
4505
|
+
const result = {
|
|
4493
4506
|
"a:avLst": {},
|
|
4494
|
-
"a:gdLst": {},
|
|
4495
|
-
"a:ahLst": {},
|
|
4496
|
-
"a:cxnLst": {},
|
|
4497
|
-
"a:rect": {
|
|
4507
|
+
"a:gdLst": rawData?.gdLstXml ?? {},
|
|
4508
|
+
"a:ahLst": rawData?.ahLstXml ?? {},
|
|
4509
|
+
"a:cxnLst": rawData?.cxnLstXml ?? {},
|
|
4510
|
+
"a:rect": rawData?.rectXml ?? {
|
|
4498
4511
|
"@_l": "l",
|
|
4499
4512
|
"@_t": "t",
|
|
4500
4513
|
"@_r": "r",
|
|
@@ -4504,6 +4517,7 @@ function customGeometryPathsToXml(paths) {
|
|
|
4504
4517
|
"a:path": xmlPaths.length === 1 ? xmlPaths[0] : xmlPaths
|
|
4505
4518
|
}
|
|
4506
4519
|
};
|
|
4520
|
+
return result;
|
|
4507
4521
|
}
|
|
4508
4522
|
|
|
4509
4523
|
// src/core/builders/sdk/ElementFactory.ts
|
|
@@ -5250,6 +5264,9 @@ ${Array.from(
|
|
|
5250
5264
|
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
5251
5265
|
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
5252
5266
|
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
5267
|
+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
5268
|
+
xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
5269
|
+
xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"
|
|
5253
5270
|
saveSubsetFonts="1">
|
|
5254
5271
|
<p:sldMasterIdLst>
|
|
5255
5272
|
<p:sldMasterId id="2147483648" r:id="rId1"/>
|
|
@@ -6671,6 +6688,22 @@ var PptxPresentationSlidesReconciler = class {
|
|
|
6671
6688
|
};
|
|
6672
6689
|
|
|
6673
6690
|
// src/core/core/builders/PptxSlideRelationshipRegistry.ts
|
|
6691
|
+
function isExternalTarget(target) {
|
|
6692
|
+
const normalized = target.trim();
|
|
6693
|
+
if (normalized.length === 0) {
|
|
6694
|
+
return false;
|
|
6695
|
+
}
|
|
6696
|
+
const colonIdx = normalized.indexOf(":");
|
|
6697
|
+
if (colonIdx <= 0) {
|
|
6698
|
+
return false;
|
|
6699
|
+
}
|
|
6700
|
+
const slashIdx = normalized.indexOf("/");
|
|
6701
|
+
if (slashIdx !== -1 && slashIdx < colonIdx) {
|
|
6702
|
+
return false;
|
|
6703
|
+
}
|
|
6704
|
+
const scheme = normalized.slice(0, colonIdx);
|
|
6705
|
+
return /^[A-Za-z][A-Za-z0-9+\-.]*$/.test(scheme);
|
|
6706
|
+
}
|
|
6674
6707
|
var PptxSlideRelationshipRegistry = class {
|
|
6675
6708
|
relationships;
|
|
6676
6709
|
usedRelationshipIds = /* @__PURE__ */ new Set();
|
|
@@ -6741,7 +6774,7 @@ var PptxSlideRelationshipRegistry = class {
|
|
|
6741
6774
|
return existingRelationshipId;
|
|
6742
6775
|
}
|
|
6743
6776
|
const relationshipId = this.nextRelationshipId();
|
|
6744
|
-
const targetMode =
|
|
6777
|
+
const targetMode = isExternalTarget(normalizedTarget) ? "External" : void 0;
|
|
6745
6778
|
this.upsertRelationship(
|
|
6746
6779
|
relationshipId,
|
|
6747
6780
|
this.hyperlinkRelationshipType,
|
|
@@ -6991,6 +7024,82 @@ var PptxSlideNotesPartUpdater = class {
|
|
|
6991
7024
|
}
|
|
6992
7025
|
};
|
|
6993
7026
|
|
|
7027
|
+
// src/core/utils/xml-reorder.ts
|
|
7028
|
+
function reorderObjectKeys(obj, schemaOrder) {
|
|
7029
|
+
const result = {};
|
|
7030
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
7031
|
+
for (const key of schemaOrder) {
|
|
7032
|
+
if (Object.hasOwn(obj, key)) {
|
|
7033
|
+
const value = obj[key];
|
|
7034
|
+
if (value !== void 0) {
|
|
7035
|
+
result[key] = value;
|
|
7036
|
+
}
|
|
7037
|
+
consumed.add(key);
|
|
7038
|
+
}
|
|
7039
|
+
}
|
|
7040
|
+
for (const key of Object.keys(obj)) {
|
|
7041
|
+
if (consumed.has(key)) {
|
|
7042
|
+
continue;
|
|
7043
|
+
}
|
|
7044
|
+
const value = obj[key];
|
|
7045
|
+
if (value !== void 0) {
|
|
7046
|
+
result[key] = value;
|
|
7047
|
+
}
|
|
7048
|
+
}
|
|
7049
|
+
return result;
|
|
7050
|
+
}
|
|
7051
|
+
var EFFECT_LST_ORDER = [
|
|
7052
|
+
"a:blur",
|
|
7053
|
+
"a:fillOverlay",
|
|
7054
|
+
"a:glow",
|
|
7055
|
+
"a:innerShdw",
|
|
7056
|
+
"a:outerShdw",
|
|
7057
|
+
"a:prstShdw",
|
|
7058
|
+
"a:reflection",
|
|
7059
|
+
"a:softEdge"
|
|
7060
|
+
];
|
|
7061
|
+
var SP_PR_ORDER = [
|
|
7062
|
+
"a:xfrm",
|
|
7063
|
+
"a:custGeom",
|
|
7064
|
+
"a:prstGeom",
|
|
7065
|
+
"a:noFill",
|
|
7066
|
+
"a:solidFill",
|
|
7067
|
+
"a:gradFill",
|
|
7068
|
+
"a:blipFill",
|
|
7069
|
+
"a:pattFill",
|
|
7070
|
+
"a:grpFill",
|
|
7071
|
+
"a:ln",
|
|
7072
|
+
"a:effectLst",
|
|
7073
|
+
"a:effectDag",
|
|
7074
|
+
"a:scene3d",
|
|
7075
|
+
"a:sp3d",
|
|
7076
|
+
"a:extLst"
|
|
7077
|
+
];
|
|
7078
|
+
var TC_PR_BORDERS_ORDER = [
|
|
7079
|
+
"a:lnL",
|
|
7080
|
+
"a:lnR",
|
|
7081
|
+
"a:lnT",
|
|
7082
|
+
"a:lnB",
|
|
7083
|
+
"a:lnTlToBr",
|
|
7084
|
+
"a:lnBlToTr",
|
|
7085
|
+
"a:cell3D",
|
|
7086
|
+
"a:noFill",
|
|
7087
|
+
"a:solidFill",
|
|
7088
|
+
"a:gradFill",
|
|
7089
|
+
"a:blipFill",
|
|
7090
|
+
"a:pattFill",
|
|
7091
|
+
"a:grpFill",
|
|
7092
|
+
"a:headers",
|
|
7093
|
+
"a:extLst"
|
|
7094
|
+
];
|
|
7095
|
+
var BLIP_FILL_ORDER = ["a:blip", "a:srcRect", "a:tile", "a:stretch"];
|
|
7096
|
+
var SHAPE_STYLE_ORDER = [
|
|
7097
|
+
"a:lnRef",
|
|
7098
|
+
"a:fillRef",
|
|
7099
|
+
"a:effectRef",
|
|
7100
|
+
"a:fontRef"
|
|
7101
|
+
];
|
|
7102
|
+
|
|
6994
7103
|
// src/core/core/builders/PptxSlideBackgroundBuilder.ts
|
|
6995
7104
|
var PptxSlideBackgroundBuilder = class {
|
|
6996
7105
|
applyBackground(init) {
|
|
@@ -7026,10 +7135,13 @@ var PptxSlideBackgroundBuilder = class {
|
|
|
7026
7135
|
init.slideImageRelationshipType,
|
|
7027
7136
|
relativeBackgroundImagePath
|
|
7028
7137
|
);
|
|
7029
|
-
backgroundProperties["a:blipFill"] =
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7138
|
+
backgroundProperties["a:blipFill"] = reorderObjectKeys(
|
|
7139
|
+
{
|
|
7140
|
+
"a:blip": { "@_r:embed": backgroundRelationshipId },
|
|
7141
|
+
"a:stretch": { "a:fillRect": {} }
|
|
7142
|
+
},
|
|
7143
|
+
BLIP_FILL_ORDER
|
|
7144
|
+
);
|
|
7033
7145
|
}
|
|
7034
7146
|
} else if (hasBackgroundColor && init.slide.backgroundColor) {
|
|
7035
7147
|
backgroundProperties["a:solidFill"] = {
|
|
@@ -7773,6 +7885,45 @@ var PptxGradientStyleCodec = class {
|
|
|
7773
7885
|
b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
|
|
7774
7886
|
};
|
|
7775
7887
|
}
|
|
7888
|
+
extractGradientFlip(gradFill) {
|
|
7889
|
+
const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
|
|
7890
|
+
if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
|
|
7891
|
+
return flipRaw;
|
|
7892
|
+
}
|
|
7893
|
+
return void 0;
|
|
7894
|
+
}
|
|
7895
|
+
extractGradientRotWithShape(gradFill) {
|
|
7896
|
+
const rot = gradFill["@_rotWithShape"];
|
|
7897
|
+
if (rot === void 0 || rot === null) {
|
|
7898
|
+
return void 0;
|
|
7899
|
+
}
|
|
7900
|
+
const token = String(rot).trim().toLowerCase();
|
|
7901
|
+
if (token === "1" || token === "true") {
|
|
7902
|
+
return true;
|
|
7903
|
+
}
|
|
7904
|
+
if (token === "0" || token === "false") {
|
|
7905
|
+
return false;
|
|
7906
|
+
}
|
|
7907
|
+
return void 0;
|
|
7908
|
+
}
|
|
7909
|
+
extractGradientScaled(gradFill) {
|
|
7910
|
+
const lin = gradFill["a:lin"];
|
|
7911
|
+
if (!lin) {
|
|
7912
|
+
return void 0;
|
|
7913
|
+
}
|
|
7914
|
+
const scaled = lin["@_scaled"];
|
|
7915
|
+
if (scaled === void 0 || scaled === null) {
|
|
7916
|
+
return void 0;
|
|
7917
|
+
}
|
|
7918
|
+
const token = String(scaled).trim().toLowerCase();
|
|
7919
|
+
if (token === "1" || token === "true") {
|
|
7920
|
+
return true;
|
|
7921
|
+
}
|
|
7922
|
+
if (token === "0" || token === "false") {
|
|
7923
|
+
return false;
|
|
7924
|
+
}
|
|
7925
|
+
return void 0;
|
|
7926
|
+
}
|
|
7776
7927
|
extractGradientAngle(gradFill) {
|
|
7777
7928
|
const angleRaw = Number.parseInt(
|
|
7778
7929
|
String(gradFill["a:lin"]?.["@_ang"] || ""),
|
|
@@ -7859,11 +8010,14 @@ var PptxGradientStyleCodec = class {
|
|
|
7859
8010
|
return void 0;
|
|
7860
8011
|
}
|
|
7861
8012
|
const gradientType = shapeStyle.fillGradientType || "linear";
|
|
7862
|
-
const gradientXml = {
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
8013
|
+
const gradientXml = {};
|
|
8014
|
+
if (shapeStyle.fillGradientFlip && shapeStyle.fillGradientFlip !== "none") {
|
|
8015
|
+
gradientXml["@_flip"] = shapeStyle.fillGradientFlip;
|
|
8016
|
+
}
|
|
8017
|
+
if (shapeStyle.fillGradientRotWithShape !== void 0) {
|
|
8018
|
+
gradientXml["@_rotWithShape"] = shapeStyle.fillGradientRotWithShape ? "1" : "0";
|
|
8019
|
+
}
|
|
8020
|
+
gradientXml["a:gsLst"] = { "a:gs": stops };
|
|
7867
8021
|
if (gradientType === "radial") {
|
|
7868
8022
|
const pathType = shapeStyle.fillGradientPathType || "circle";
|
|
7869
8023
|
const pathXml = {
|
|
@@ -7893,10 +8047,15 @@ var PptxGradientStyleCodec = class {
|
|
|
7893
8047
|
gradientXml["a:path"] = pathXml;
|
|
7894
8048
|
} else {
|
|
7895
8049
|
const normalizedAngle = typeof shapeStyle.fillGradientAngle === "number" && Number.isFinite(shapeStyle.fillGradientAngle) ? shapeStyle.fillGradientAngle : 90;
|
|
7896
|
-
|
|
7897
|
-
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7898
|
-
"@_scaled": "1"
|
|
8050
|
+
const linNode = {
|
|
8051
|
+
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7899
8052
|
};
|
|
8053
|
+
if (shapeStyle.fillGradientScaled !== void 0) {
|
|
8054
|
+
linNode["@_scaled"] = shapeStyle.fillGradientScaled ? "1" : "0";
|
|
8055
|
+
} else {
|
|
8056
|
+
linNode["@_scaled"] = "1";
|
|
8057
|
+
}
|
|
8058
|
+
gradientXml["a:lin"] = linNode;
|
|
7900
8059
|
}
|
|
7901
8060
|
return gradientXml;
|
|
7902
8061
|
}
|
|
@@ -8293,6 +8452,30 @@ var PRESET_SHADOW_OPACITY_MAP = {
|
|
|
8293
8452
|
};
|
|
8294
8453
|
|
|
8295
8454
|
// src/core/core/builders/PptxShapeEffectStyleExtractor.ts
|
|
8455
|
+
var VALID_ALIGNMENTS = /* @__PURE__ */ new Set(["tl", "t", "tr", "l", "ctr", "r", "bl", "b", "br"]);
|
|
8456
|
+
function parseIntAttr(value) {
|
|
8457
|
+
if (value === void 0 || value === null || value === "") {
|
|
8458
|
+
return void 0;
|
|
8459
|
+
}
|
|
8460
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
8461
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
8462
|
+
}
|
|
8463
|
+
function parseAlignmentAttr(value) {
|
|
8464
|
+
const v = String(value ?? "").trim();
|
|
8465
|
+
return VALID_ALIGNMENTS.has(v) ? v : void 0;
|
|
8466
|
+
}
|
|
8467
|
+
function parseBoolAttr(value) {
|
|
8468
|
+
if (typeof value === "boolean") {
|
|
8469
|
+
return value;
|
|
8470
|
+
}
|
|
8471
|
+
if (value === "1" || value === "true") {
|
|
8472
|
+
return true;
|
|
8473
|
+
}
|
|
8474
|
+
if (value === "0" || value === "false") {
|
|
8475
|
+
return false;
|
|
8476
|
+
}
|
|
8477
|
+
return void 0;
|
|
8478
|
+
}
|
|
8296
8479
|
var PptxShapeEffectStyleExtractor = class {
|
|
8297
8480
|
context;
|
|
8298
8481
|
constructor(context) {
|
|
@@ -8316,7 +8499,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8316
8499
|
const shadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8317
8500
|
const shadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8318
8501
|
const rotateWithShape = outerShadow["@_rotWithShape"];
|
|
8319
|
-
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : void 0;
|
|
8502
|
+
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : rotateWithShape === "0" || rotateWithShape === "false" ? false : void 0;
|
|
8503
|
+
const shadowScaleX = parseIntAttr(outerShadow["@_sx"]);
|
|
8504
|
+
const shadowScaleY = parseIntAttr(outerShadow["@_sy"]);
|
|
8505
|
+
const shadowSkewX = parseIntAttr(outerShadow["@_kx"]);
|
|
8506
|
+
const shadowSkewY = parseIntAttr(outerShadow["@_ky"]);
|
|
8507
|
+
const shadowAlignment = parseAlignmentAttr(outerShadow["@_algn"]);
|
|
8320
8508
|
return {
|
|
8321
8509
|
shadowColor,
|
|
8322
8510
|
shadowOpacity,
|
|
@@ -8325,7 +8513,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8325
8513
|
shadowOffsetY,
|
|
8326
8514
|
shadowAngle: directionDegrees,
|
|
8327
8515
|
shadowDistance: distance,
|
|
8328
|
-
shadowRotateWithShape
|
|
8516
|
+
shadowRotateWithShape,
|
|
8517
|
+
shadowScaleX,
|
|
8518
|
+
shadowScaleY,
|
|
8519
|
+
shadowSkewX,
|
|
8520
|
+
shadowSkewY,
|
|
8521
|
+
shadowAlignment
|
|
8329
8522
|
};
|
|
8330
8523
|
}
|
|
8331
8524
|
extractPresetShadowStyle(effectLstParent) {
|
|
@@ -8371,12 +8564,14 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8371
8564
|
const directionRadians = directionDegrees * Math.PI / 180;
|
|
8372
8565
|
const innerShadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8373
8566
|
const innerShadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8567
|
+
const innerShadowRotateWithShape = parseBoolAttr(innerShadow["@_rotWithShape"]);
|
|
8374
8568
|
return {
|
|
8375
8569
|
innerShadowColor,
|
|
8376
8570
|
innerShadowOpacity,
|
|
8377
8571
|
innerShadowBlur,
|
|
8378
8572
|
innerShadowOffsetX,
|
|
8379
|
-
innerShadowOffsetY
|
|
8573
|
+
innerShadowOffsetY,
|
|
8574
|
+
innerShadowRotateWithShape
|
|
8380
8575
|
};
|
|
8381
8576
|
}
|
|
8382
8577
|
extractGlowStyle(shapeProps) {
|
|
@@ -8425,6 +8620,16 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8425
8620
|
const reflectionRotation = Number.isFinite(rotationRaw) ? rotationRaw / 6e4 : void 0;
|
|
8426
8621
|
const distanceRaw = Number.parseInt(String(reflectionNode["@_dist"] || ""), 10);
|
|
8427
8622
|
const reflectionDistance = Number.isFinite(distanceRaw) && distanceRaw >= 0 ? distanceRaw / this.context.emuPerPx : void 0;
|
|
8623
|
+
const fadeDirRaw = parseIntAttr(reflectionNode["@_fadeDir"]);
|
|
8624
|
+
const reflectionFadeDirection = fadeDirRaw !== void 0 ? fadeDirRaw / 6e4 : void 0;
|
|
8625
|
+
const reflectionScaleX = parseIntAttr(reflectionNode["@_sx"]);
|
|
8626
|
+
const reflectionScaleY = parseIntAttr(reflectionNode["@_sy"]);
|
|
8627
|
+
const reflectionSkewX = parseIntAttr(reflectionNode["@_kx"]);
|
|
8628
|
+
const reflectionSkewY = parseIntAttr(reflectionNode["@_ky"]);
|
|
8629
|
+
const reflectionAlignment = parseAlignmentAttr(reflectionNode["@_algn"]);
|
|
8630
|
+
const reflectionRotateWithShape = parseBoolAttr(reflectionNode["@_rotWithShape"]);
|
|
8631
|
+
const stPosRaw = parseIntAttr(reflectionNode["@_stPos"]);
|
|
8632
|
+
const reflectionStartPosition = stPosRaw !== void 0 ? stPosRaw / 1e5 : void 0;
|
|
8428
8633
|
return {
|
|
8429
8634
|
reflectionBlurRadius,
|
|
8430
8635
|
reflectionStartOpacity,
|
|
@@ -8432,7 +8637,15 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8432
8637
|
reflectionEndPosition,
|
|
8433
8638
|
reflectionDirection,
|
|
8434
8639
|
reflectionRotation,
|
|
8435
|
-
reflectionDistance
|
|
8640
|
+
reflectionDistance,
|
|
8641
|
+
reflectionFadeDirection,
|
|
8642
|
+
reflectionScaleX,
|
|
8643
|
+
reflectionScaleY,
|
|
8644
|
+
reflectionSkewX,
|
|
8645
|
+
reflectionSkewY,
|
|
8646
|
+
reflectionAlignment,
|
|
8647
|
+
reflectionRotateWithShape,
|
|
8648
|
+
reflectionStartPosition
|
|
8436
8649
|
};
|
|
8437
8650
|
}
|
|
8438
8651
|
extractBlurStyle(shapeProps) {
|
|
@@ -8484,11 +8697,56 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8484
8697
|
}
|
|
8485
8698
|
}
|
|
8486
8699
|
};
|
|
8700
|
+
if (typeof shapeStyle.shadowScaleX === "number") {
|
|
8701
|
+
xmlObj["@_sx"] = String(Math.round(shapeStyle.shadowScaleX));
|
|
8702
|
+
}
|
|
8703
|
+
if (typeof shapeStyle.shadowScaleY === "number") {
|
|
8704
|
+
xmlObj["@_sy"] = String(Math.round(shapeStyle.shadowScaleY));
|
|
8705
|
+
}
|
|
8706
|
+
if (typeof shapeStyle.shadowSkewX === "number") {
|
|
8707
|
+
xmlObj["@_kx"] = String(Math.round(shapeStyle.shadowSkewX));
|
|
8708
|
+
}
|
|
8709
|
+
if (typeof shapeStyle.shadowSkewY === "number") {
|
|
8710
|
+
xmlObj["@_ky"] = String(Math.round(shapeStyle.shadowSkewY));
|
|
8711
|
+
}
|
|
8712
|
+
if (shapeStyle.shadowAlignment) {
|
|
8713
|
+
xmlObj["@_algn"] = shapeStyle.shadowAlignment;
|
|
8714
|
+
}
|
|
8487
8715
|
if (typeof shapeStyle.shadowRotateWithShape === "boolean") {
|
|
8488
8716
|
xmlObj["@_rotWithShape"] = shapeStyle.shadowRotateWithShape ? "1" : "0";
|
|
8489
8717
|
}
|
|
8490
8718
|
return xmlObj;
|
|
8491
8719
|
}
|
|
8720
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8721
|
+
const preset = shapeStyle.presetShadowName;
|
|
8722
|
+
if (!preset || preset.length === 0) {
|
|
8723
|
+
return void 0;
|
|
8724
|
+
}
|
|
8725
|
+
const shadowColor = String(shapeStyle.shadowColor || "#000000").trim();
|
|
8726
|
+
const shadowOpacity = typeof shapeStyle.shadowOpacity === "number" && Number.isFinite(shapeStyle.shadowOpacity) ? this.context.clampUnitInterval(shapeStyle.shadowOpacity) : 0.5;
|
|
8727
|
+
let distance;
|
|
8728
|
+
let directionDegrees;
|
|
8729
|
+
if (typeof shapeStyle.shadowAngle === "number" && typeof shapeStyle.shadowDistance === "number") {
|
|
8730
|
+
directionDegrees = shapeStyle.shadowAngle;
|
|
8731
|
+
distance = shapeStyle.shadowDistance;
|
|
8732
|
+
} else {
|
|
8733
|
+
const ox = typeof shapeStyle.shadowOffsetX === "number" ? shapeStyle.shadowOffsetX : 0;
|
|
8734
|
+
const oy = typeof shapeStyle.shadowOffsetY === "number" ? shapeStyle.shadowOffsetY : 0;
|
|
8735
|
+
distance = Math.sqrt(ox * ox + oy * oy);
|
|
8736
|
+
directionDegrees = (Math.atan2(oy, ox) * 180 / Math.PI + 360) % 360;
|
|
8737
|
+
}
|
|
8738
|
+
return {
|
|
8739
|
+
"@_prst": preset,
|
|
8740
|
+
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8741
|
+
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
8742
|
+
"a:srgbClr": {
|
|
8743
|
+
"@_val": shadowColor.replace("#", ""),
|
|
8744
|
+
"a:alpha": {
|
|
8745
|
+
"@_val": String(Math.round(shadowOpacity * 1e5))
|
|
8746
|
+
}
|
|
8747
|
+
}
|
|
8748
|
+
};
|
|
8749
|
+
}
|
|
8492
8750
|
buildInnerShadowXml(shapeStyle) {
|
|
8493
8751
|
const innerColor = String(shapeStyle.innerShadowColor || "").trim();
|
|
8494
8752
|
if (innerColor.length === 0 || innerColor === "transparent") {
|
|
@@ -8500,7 +8758,7 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8500
8758
|
const opacity = typeof shapeStyle.innerShadowOpacity === "number" && Number.isFinite(shapeStyle.innerShadowOpacity) ? this.context.clampUnitInterval(shapeStyle.innerShadowOpacity) : 0.5;
|
|
8501
8759
|
const distance = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
|
|
8502
8760
|
const directionDegrees = (Math.atan2(offsetY, offsetX) * 180 / Math.PI + 360) % 360;
|
|
8503
|
-
|
|
8761
|
+
const xmlObj = {
|
|
8504
8762
|
"@_blurRad": String(Math.round(blurValue * this.context.emuPerPx)),
|
|
8505
8763
|
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8506
8764
|
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
@@ -8511,6 +8769,10 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8511
8769
|
}
|
|
8512
8770
|
}
|
|
8513
8771
|
};
|
|
8772
|
+
if (typeof shapeStyle.innerShadowRotateWithShape === "boolean") {
|
|
8773
|
+
xmlObj["@_rotWithShape"] = shapeStyle.innerShadowRotateWithShape ? "1" : "0";
|
|
8774
|
+
}
|
|
8775
|
+
return xmlObj;
|
|
8514
8776
|
}
|
|
8515
8777
|
buildGlowXml(shapeStyle) {
|
|
8516
8778
|
const glowColor = String(shapeStyle.glowColor || "").trim();
|
|
@@ -8572,6 +8834,30 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8572
8834
|
Math.round(shapeStyle.reflectionDistance * this.context.emuPerPx)
|
|
8573
8835
|
);
|
|
8574
8836
|
}
|
|
8837
|
+
if (typeof shapeStyle.reflectionFadeDirection === "number") {
|
|
8838
|
+
reflectionXml["@_fadeDir"] = String(Math.round(shapeStyle.reflectionFadeDirection * 6e4));
|
|
8839
|
+
}
|
|
8840
|
+
if (typeof shapeStyle.reflectionScaleX === "number") {
|
|
8841
|
+
reflectionXml["@_sx"] = String(Math.round(shapeStyle.reflectionScaleX));
|
|
8842
|
+
}
|
|
8843
|
+
if (typeof shapeStyle.reflectionScaleY === "number") {
|
|
8844
|
+
reflectionXml["@_sy"] = String(Math.round(shapeStyle.reflectionScaleY));
|
|
8845
|
+
}
|
|
8846
|
+
if (typeof shapeStyle.reflectionSkewX === "number") {
|
|
8847
|
+
reflectionXml["@_kx"] = String(Math.round(shapeStyle.reflectionSkewX));
|
|
8848
|
+
}
|
|
8849
|
+
if (typeof shapeStyle.reflectionSkewY === "number") {
|
|
8850
|
+
reflectionXml["@_ky"] = String(Math.round(shapeStyle.reflectionSkewY));
|
|
8851
|
+
}
|
|
8852
|
+
if (shapeStyle.reflectionAlignment) {
|
|
8853
|
+
reflectionXml["@_algn"] = shapeStyle.reflectionAlignment;
|
|
8854
|
+
}
|
|
8855
|
+
if (typeof shapeStyle.reflectionRotateWithShape === "boolean") {
|
|
8856
|
+
reflectionXml["@_rotWithShape"] = shapeStyle.reflectionRotateWithShape ? "1" : "0";
|
|
8857
|
+
}
|
|
8858
|
+
if (typeof shapeStyle.reflectionStartPosition === "number") {
|
|
8859
|
+
reflectionXml["@_stPos"] = String(Math.round(shapeStyle.reflectionStartPosition * 1e5));
|
|
8860
|
+
}
|
|
8575
8861
|
return reflectionXml;
|
|
8576
8862
|
}
|
|
8577
8863
|
buildBlurXml(shapeStyle) {
|
|
@@ -8679,6 +8965,9 @@ var PptxShapeEffectXmlCodec = class {
|
|
|
8679
8965
|
buildOuterShadowXml(shapeStyle) {
|
|
8680
8966
|
return this.builder.buildOuterShadowXml(shapeStyle);
|
|
8681
8967
|
}
|
|
8968
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8969
|
+
return this.builder.buildPresetShadowXml(shapeStyle);
|
|
8970
|
+
}
|
|
8682
8971
|
buildInnerShadowXml(shapeStyle) {
|
|
8683
8972
|
return this.builder.buildInnerShadowXml(shapeStyle);
|
|
8684
8973
|
}
|
|
@@ -8839,6 +9128,9 @@ var PptxColorStyleCodec = class {
|
|
|
8839
9128
|
buildOuterShadowXml(shapeStyle) {
|
|
8840
9129
|
return this.shapeEffectXmlCodec.buildOuterShadowXml(shapeStyle);
|
|
8841
9130
|
}
|
|
9131
|
+
buildPresetShadowXml(shapeStyle) {
|
|
9132
|
+
return this.shapeEffectXmlCodec.buildPresetShadowXml(shapeStyle);
|
|
9133
|
+
}
|
|
8842
9134
|
buildInnerShadowXml(shapeStyle) {
|
|
8843
9135
|
return this.shapeEffectXmlCodec.buildInnerShadowXml(shapeStyle);
|
|
8844
9136
|
}
|
|
@@ -8860,6 +9152,15 @@ var PptxColorStyleCodec = class {
|
|
|
8860
9152
|
extractGradientFillColor(gradFill) {
|
|
8861
9153
|
return this.gradientStyleCodec.extractGradientFillColor(gradFill);
|
|
8862
9154
|
}
|
|
9155
|
+
extractGradientFlip(gradFill) {
|
|
9156
|
+
return this.gradientStyleCodec.extractGradientFlip(gradFill);
|
|
9157
|
+
}
|
|
9158
|
+
extractGradientRotWithShape(gradFill) {
|
|
9159
|
+
return this.gradientStyleCodec.extractGradientRotWithShape(gradFill);
|
|
9160
|
+
}
|
|
9161
|
+
extractGradientScaled(gradFill) {
|
|
9162
|
+
return this.gradientStyleCodec.extractGradientScaled(gradFill);
|
|
9163
|
+
}
|
|
8863
9164
|
extractGradientPathType(gradFill) {
|
|
8864
9165
|
return this.gradientStyleCodec.extractGradientPathType(gradFill);
|
|
8865
9166
|
}
|
|
@@ -8871,6 +9172,61 @@ var PptxColorStyleCodec = class {
|
|
|
8871
9172
|
}
|
|
8872
9173
|
};
|
|
8873
9174
|
|
|
9175
|
+
// src/core/utils/color-xml-preservation.ts
|
|
9176
|
+
var COLOR_CHOICE_KEYS = [
|
|
9177
|
+
"a:srgbClr",
|
|
9178
|
+
"a:schemeClr",
|
|
9179
|
+
"a:sysClr",
|
|
9180
|
+
"a:prstClr",
|
|
9181
|
+
"a:scrgbClr",
|
|
9182
|
+
"a:hslClr"
|
|
9183
|
+
];
|
|
9184
|
+
function extractColorChoiceXml(parent) {
|
|
9185
|
+
if (!parent) {
|
|
9186
|
+
return void 0;
|
|
9187
|
+
}
|
|
9188
|
+
for (const key of COLOR_CHOICE_KEYS) {
|
|
9189
|
+
if (parent[key] !== void 0) {
|
|
9190
|
+
return { [key]: parent[key] };
|
|
9191
|
+
}
|
|
9192
|
+
}
|
|
9193
|
+
return void 0;
|
|
9194
|
+
}
|
|
9195
|
+
function normalizeHex(value) {
|
|
9196
|
+
const raw = String(value ?? "").trim();
|
|
9197
|
+
if (raw.length === 0) {
|
|
9198
|
+
return "";
|
|
9199
|
+
}
|
|
9200
|
+
const hex = raw.replace(/^#/, "");
|
|
9201
|
+
if (/^[0-9a-fA-F]{6}$/.test(hex)) {
|
|
9202
|
+
return hex.toUpperCase();
|
|
9203
|
+
}
|
|
9204
|
+
return raw.toLowerCase();
|
|
9205
|
+
}
|
|
9206
|
+
function colorsEqual(left, right) {
|
|
9207
|
+
if (left === void 0 || right === void 0) {
|
|
9208
|
+
return false;
|
|
9209
|
+
}
|
|
9210
|
+
return normalizeHex(left) === normalizeHex(right);
|
|
9211
|
+
}
|
|
9212
|
+
function buildSrgbColorChoice(hex, opacity) {
|
|
9213
|
+
const normalized = String(hex || "").replace(/^#/, "");
|
|
9214
|
+
const srgb = { "@_val": normalized };
|
|
9215
|
+
if (typeof opacity === "number" && Number.isFinite(opacity) && opacity >= 0 && opacity < 1) {
|
|
9216
|
+
const alphaPct = Math.round(Math.max(0, Math.min(1, opacity)) * 1e5);
|
|
9217
|
+
srgb["a:alpha"] = { "@_val": String(alphaPct) };
|
|
9218
|
+
}
|
|
9219
|
+
return { "a:srgbClr": srgb };
|
|
9220
|
+
}
|
|
9221
|
+
function serializeColorChoice(originalColorXml, currentResolvedHex, fallbackHex, opacity, options = {}) {
|
|
9222
|
+
if (originalColorXml && colorsEqual(currentResolvedHex, fallbackHex)) {
|
|
9223
|
+
if (options.preserveAlphaFromOriginal !== false) {
|
|
9224
|
+
return originalColorXml;
|
|
9225
|
+
}
|
|
9226
|
+
}
|
|
9227
|
+
return buildSrgbColorChoice(fallbackHex, opacity);
|
|
9228
|
+
}
|
|
9229
|
+
|
|
8874
9230
|
// src/core/core/builders/shape-style-3d-helpers.ts
|
|
8875
9231
|
function applyScene3dStyle(shapeProps, style) {
|
|
8876
9232
|
const scene3dNode = shapeProps["a:scene3d"];
|
|
@@ -8956,6 +9312,10 @@ function applyStrokeColor(lineNode, style, context) {
|
|
|
8956
9312
|
const lineFill = lineNode["a:solidFill"];
|
|
8957
9313
|
style.strokeColor = context.parseColor(lineFill);
|
|
8958
9314
|
style.strokeOpacity = context.extractColorOpacity(lineFill);
|
|
9315
|
+
const strokeColorXml = extractColorChoiceXml(lineFill);
|
|
9316
|
+
if (strokeColorXml) {
|
|
9317
|
+
style.strokeColorXml = strokeColorXml;
|
|
9318
|
+
}
|
|
8959
9319
|
} else if (lineNode["a:gradFill"]) {
|
|
8960
9320
|
style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
|
|
8961
9321
|
style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
|
|
@@ -9023,6 +9383,14 @@ function applyJoinCapCompound(lineNode, style) {
|
|
|
9023
9383
|
style.lineJoin = "bevel";
|
|
9024
9384
|
} else if ("a:miter" in lineNode) {
|
|
9025
9385
|
style.lineJoin = "miter";
|
|
9386
|
+
const miterNode = lineNode["a:miter"];
|
|
9387
|
+
const limRaw = miterNode?.["@_lim"];
|
|
9388
|
+
if (limRaw !== void 0 && limRaw !== "") {
|
|
9389
|
+
const parsed = parseInt(String(limRaw), 10);
|
|
9390
|
+
if (Number.isFinite(parsed)) {
|
|
9391
|
+
style.miterLimit = parsed;
|
|
9392
|
+
}
|
|
9393
|
+
}
|
|
9026
9394
|
}
|
|
9027
9395
|
const capValue = String(lineNode["@_cap"] || "").trim().toLowerCase();
|
|
9028
9396
|
if (capValue === "rnd" || capValue === "sq" || capValue === "flat") {
|
|
@@ -9079,6 +9447,10 @@ var PptxShapeStyleExtractor = class {
|
|
|
9079
9447
|
style.fillMode = "solid";
|
|
9080
9448
|
style.fillColor = this.context.parseColor(solidFill);
|
|
9081
9449
|
style.fillOpacity = this.context.extractColorOpacity(solidFill);
|
|
9450
|
+
const solidFillColorXml = extractColorChoiceXml(solidFill);
|
|
9451
|
+
if (solidFillColorXml) {
|
|
9452
|
+
style.fillColorXml = solidFillColorXml;
|
|
9453
|
+
}
|
|
9082
9454
|
} else if (gradFill) {
|
|
9083
9455
|
style.fillMode = "gradient";
|
|
9084
9456
|
style.fillColor = this.context.extractGradientFillColor(gradFill);
|
|
@@ -9090,6 +9462,18 @@ var PptxShapeStyleExtractor = class {
|
|
|
9090
9462
|
style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
|
|
9091
9463
|
style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
|
|
9092
9464
|
style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
|
|
9465
|
+
const gradFlip = this.context.extractGradientFlip(gradFill);
|
|
9466
|
+
if (gradFlip) {
|
|
9467
|
+
style.fillGradientFlip = gradFlip;
|
|
9468
|
+
}
|
|
9469
|
+
const gradRot = this.context.extractGradientRotWithShape(gradFill);
|
|
9470
|
+
if (gradRot !== void 0) {
|
|
9471
|
+
style.fillGradientRotWithShape = gradRot;
|
|
9472
|
+
}
|
|
9473
|
+
const gradScaled = this.context.extractGradientScaled(gradFill);
|
|
9474
|
+
if (gradScaled !== void 0) {
|
|
9475
|
+
style.fillGradientScaled = gradScaled;
|
|
9476
|
+
}
|
|
9093
9477
|
} else if (pattFill) {
|
|
9094
9478
|
style.fillMode = "pattern";
|
|
9095
9479
|
style.fillColor = this.context.parseColor(pattFill["a:fgClr"]) || this.context.parseColor(pattFill["a:bgClr"]);
|
|
@@ -9171,10 +9555,45 @@ var PptxShapeStyleExtractor = class {
|
|
|
9171
9555
|
if (styleNode?.["a:effectRef"]) {
|
|
9172
9556
|
this.context.resolveThemeEffectRef(styleNode["a:effectRef"], style);
|
|
9173
9557
|
}
|
|
9558
|
+
const fontRef = styleNode?.["a:fontRef"];
|
|
9559
|
+
if (fontRef) {
|
|
9560
|
+
const idxAttr = String(fontRef["@_idx"] || "").trim();
|
|
9561
|
+
if (idxAttr.length > 0) {
|
|
9562
|
+
style.fontRefIdx = idxAttr;
|
|
9563
|
+
}
|
|
9564
|
+
const overrideColorXml = this.extractFontRefColorXml(fontRef);
|
|
9565
|
+
if (overrideColorXml) {
|
|
9566
|
+
style.fontRefColorXml = overrideColorXml;
|
|
9567
|
+
}
|
|
9568
|
+
}
|
|
9174
9569
|
applyScene3dStyle(shapeProps, style);
|
|
9175
9570
|
applyShape3dStyle(shapeProps, style, this.context);
|
|
9176
9571
|
return style;
|
|
9177
9572
|
}
|
|
9573
|
+
/**
|
|
9574
|
+
* Pull the verbatim colour-choice child out of an `a:fontRef` element,
|
|
9575
|
+
* preserving any contained colour transforms for round-trip.
|
|
9576
|
+
*/
|
|
9577
|
+
extractFontRefColorXml(refNode) {
|
|
9578
|
+
if (!refNode) {
|
|
9579
|
+
return void 0;
|
|
9580
|
+
}
|
|
9581
|
+
const keys = [
|
|
9582
|
+
"a:scrgbClr",
|
|
9583
|
+
"a:srgbClr",
|
|
9584
|
+
"a:hslClr",
|
|
9585
|
+
"a:sysClr",
|
|
9586
|
+
"a:schemeClr",
|
|
9587
|
+
"a:prstClr"
|
|
9588
|
+
];
|
|
9589
|
+
for (const key of keys) {
|
|
9590
|
+
const child = refNode[key];
|
|
9591
|
+
if (child !== void 0) {
|
|
9592
|
+
return { [key]: child };
|
|
9593
|
+
}
|
|
9594
|
+
}
|
|
9595
|
+
return void 0;
|
|
9596
|
+
}
|
|
9178
9597
|
/**
|
|
9179
9598
|
* Extract p14:hiddenFill from the shape properties extension list.
|
|
9180
9599
|
* URI: {AF507438-7753-43E0-B8FC-AC1667EBCBE1}
|
|
@@ -9225,10 +9644,15 @@ var PptxShapeStyleExtractor = class {
|
|
|
9225
9644
|
function applyCellFillStyle(cellProperties, style, context) {
|
|
9226
9645
|
let hasStyle = false;
|
|
9227
9646
|
if (cellProperties?.["a:solidFill"]) {
|
|
9228
|
-
const
|
|
9647
|
+
const solidFillNode = cellProperties["a:solidFill"];
|
|
9648
|
+
const fillColor = context.parseColor(solidFillNode);
|
|
9229
9649
|
if (fillColor) {
|
|
9230
9650
|
style.fillMode = "solid";
|
|
9231
9651
|
style.backgroundColor = fillColor;
|
|
9652
|
+
const bgColorXml = extractColorChoiceXml(solidFillNode);
|
|
9653
|
+
if (bgColorXml) {
|
|
9654
|
+
style.backgroundColorXml = bgColorXml;
|
|
9655
|
+
}
|
|
9232
9656
|
hasStyle = true;
|
|
9233
9657
|
}
|
|
9234
9658
|
}
|
|
@@ -9265,6 +9689,10 @@ function applyCellFillStyle(cellProperties, style, context) {
|
|
|
9265
9689
|
}
|
|
9266
9690
|
}
|
|
9267
9691
|
}
|
|
9692
|
+
if (cellProperties?.["a:noFill"] !== void 0) {
|
|
9693
|
+
style.fillMode = "none";
|
|
9694
|
+
hasStyle = true;
|
|
9695
|
+
}
|
|
9268
9696
|
if (cellProperties?.["a:pattFill"]) {
|
|
9269
9697
|
const pattFill = cellProperties["a:pattFill"];
|
|
9270
9698
|
const fgColor = context.parseColor(pattFill["a:fgClr"]);
|
|
@@ -9571,8 +9999,7 @@ var PptxTableDataParser = class {
|
|
|
9571
9999
|
return width / totalWidthEmu;
|
|
9572
10000
|
}) : gridColumns.map(() => 1 / Math.max(gridColumns.length, 1));
|
|
9573
10001
|
const tableProperties = tableNode["a:tblPr"] || {};
|
|
9574
|
-
const
|
|
9575
|
-
const tableStyleId = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim() || void 0;
|
|
10002
|
+
const tableStyleId = this.extractTableStyleId(tableProperties);
|
|
9576
10003
|
const xmlRows = this.context.ensureArray(tableNode["a:tr"]);
|
|
9577
10004
|
const rows = xmlRows.map((rowNode) => {
|
|
9578
10005
|
const rowHeightEmu = parseInt(String(rowNode?.["@_h"] || "0"), 10) || 0;
|
|
@@ -9607,6 +10034,28 @@ var PptxTableDataParser = class {
|
|
|
9607
10034
|
return void 0;
|
|
9608
10035
|
}
|
|
9609
10036
|
}
|
|
10037
|
+
/**
|
|
10038
|
+
* Read the table style ID from `a:tblPr`.
|
|
10039
|
+
*
|
|
10040
|
+
* ECMA-376 §21.1.3.13 defines `<a:tableStyleId>{GUID}</a:tableStyleId>` as
|
|
10041
|
+
* a child element of `a:tblPr` carrying the GUID as element text. Older
|
|
10042
|
+
* inputs (and earlier versions of this library) used the legacy
|
|
10043
|
+
* `<a:tblStyle val="{GUID}"/>` child element or a `@_tblStyle` attribute.
|
|
10044
|
+
* Accept all three; the spec form takes precedence.
|
|
10045
|
+
*/
|
|
10046
|
+
extractTableStyleId(tableProperties) {
|
|
10047
|
+
const tableStyleIdNode = tableProperties["a:tableStyleId"];
|
|
10048
|
+
if (tableStyleIdNode !== void 0 && tableStyleIdNode !== null) {
|
|
10049
|
+
const direct = typeof tableStyleIdNode === "string" || typeof tableStyleIdNode === "number" ? String(tableStyleIdNode) : String(tableStyleIdNode["#text"] ?? "");
|
|
10050
|
+
const trimmed = direct.trim();
|
|
10051
|
+
if (trimmed.length > 0) {
|
|
10052
|
+
return trimmed;
|
|
10053
|
+
}
|
|
10054
|
+
}
|
|
10055
|
+
const tableStyleNode = tableProperties["a:tblStyle"];
|
|
10056
|
+
const legacy = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim();
|
|
10057
|
+
return legacy.length > 0 ? legacy : void 0;
|
|
10058
|
+
}
|
|
9610
10059
|
extractTableCellText(tableCell) {
|
|
9611
10060
|
const paragraphs = this.context.ensureArray(tableCell?.["a:txBody"]?.["a:p"]);
|
|
9612
10061
|
const lines = [];
|
|
@@ -9885,6 +10334,19 @@ var PptxGraphicFrameParser = class {
|
|
|
9885
10334
|
if (graphicData["a:videoFile"] || graphicData["a:audioFile"] || uri.includes("/drawingml/2006/media")) {
|
|
9886
10335
|
return "media";
|
|
9887
10336
|
}
|
|
10337
|
+
if (graphicData["aink:ink"] || uri.includes("/2010/ink") || uri.includes("drawing/2010/ink")) {
|
|
10338
|
+
return "ink";
|
|
10339
|
+
}
|
|
10340
|
+
const alternateContent = graphicData["mc:AlternateContent"];
|
|
10341
|
+
if (alternateContent) {
|
|
10342
|
+
const choices = Array.isArray(alternateContent["mc:Choice"]) ? alternateContent["mc:Choice"] : alternateContent["mc:Choice"] ? [alternateContent["mc:Choice"]] : [];
|
|
10343
|
+
for (const choice of choices) {
|
|
10344
|
+
const requires = String(choice?.["@_Requires"] || "").toLowerCase();
|
|
10345
|
+
if (requires.includes("aink") || choice?.["aink:ink"]) {
|
|
10346
|
+
return "ink";
|
|
10347
|
+
}
|
|
10348
|
+
}
|
|
10349
|
+
}
|
|
9888
10350
|
return "unknown";
|
|
9889
10351
|
}
|
|
9890
10352
|
};
|
|
@@ -10786,6 +11248,7 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10786
11248
|
}));
|
|
10787
11249
|
if (sanitized.length === 0) {
|
|
10788
11250
|
this.context.zip.remove("docProps/custom.xml");
|
|
11251
|
+
await this.removeCustomPropertiesPackagingArtifacts();
|
|
10789
11252
|
return;
|
|
10790
11253
|
}
|
|
10791
11254
|
const customXml = {
|
|
@@ -10805,6 +11268,116 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10805
11268
|
}
|
|
10806
11269
|
};
|
|
10807
11270
|
this.context.zip.file("docProps/custom.xml", this.context.builder.build(customXml));
|
|
11271
|
+
await this.ensureCustomPropertiesPackagingArtifacts();
|
|
11272
|
+
}
|
|
11273
|
+
/**
|
|
11274
|
+
* Ensure `[Content_Types].xml` has an `Override` for `docProps/custom.xml`
|
|
11275
|
+
* and the root `_rels/.rels` references it (ECMA-376 §15.2.12.2 +
|
|
11276
|
+
* Part 2 §10.1.2.5). Without these, the package fails OPC validation
|
|
11277
|
+
* and Office strips the custom properties on next save.
|
|
11278
|
+
*/
|
|
11279
|
+
async ensureCustomPropertiesPackagingArtifacts() {
|
|
11280
|
+
const customContentType = "application/vnd.openxmlformats-officedocument.custom-properties+xml";
|
|
11281
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11282
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11283
|
+
if (ctFile) {
|
|
11284
|
+
try {
|
|
11285
|
+
const ctXml = await ctFile.async("string");
|
|
11286
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11287
|
+
const types = ctData["Types"];
|
|
11288
|
+
if (types) {
|
|
11289
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11290
|
+
const hasCustomOverride = overrides.some(
|
|
11291
|
+
(o) => String(o?.["@_PartName"] || "") === "/docProps/custom.xml"
|
|
11292
|
+
);
|
|
11293
|
+
if (!hasCustomOverride) {
|
|
11294
|
+
overrides.push({
|
|
11295
|
+
"@_PartName": "/docProps/custom.xml",
|
|
11296
|
+
"@_ContentType": customContentType
|
|
11297
|
+
});
|
|
11298
|
+
types["Override"] = overrides.length === 1 ? overrides[0] : overrides;
|
|
11299
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11300
|
+
}
|
|
11301
|
+
}
|
|
11302
|
+
} catch (error) {
|
|
11303
|
+
console.warn("Failed to update [Content_Types].xml for custom properties:", error);
|
|
11304
|
+
}
|
|
11305
|
+
}
|
|
11306
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11307
|
+
if (relsFile) {
|
|
11308
|
+
try {
|
|
11309
|
+
const relsXml = await relsFile.async("string");
|
|
11310
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11311
|
+
const relationships = relsData["Relationships"];
|
|
11312
|
+
if (relationships) {
|
|
11313
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11314
|
+
const hasCustomRel = rels.some((r) => String(r?.["@_Type"] || "") === customRelType);
|
|
11315
|
+
if (!hasCustomRel) {
|
|
11316
|
+
let maxId = 0;
|
|
11317
|
+
for (const rel of rels) {
|
|
11318
|
+
const id = String(rel?.["@_Id"] || "");
|
|
11319
|
+
const num = Number.parseInt(id.replace(/^rId/, ""), 10);
|
|
11320
|
+
if (Number.isFinite(num) && num > maxId) {
|
|
11321
|
+
maxId = num;
|
|
11322
|
+
}
|
|
11323
|
+
}
|
|
11324
|
+
rels.push({
|
|
11325
|
+
"@_Id": `rId${maxId + 1}`,
|
|
11326
|
+
"@_Type": customRelType,
|
|
11327
|
+
"@_Target": "docProps/custom.xml"
|
|
11328
|
+
});
|
|
11329
|
+
relationships["Relationship"] = rels;
|
|
11330
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11331
|
+
}
|
|
11332
|
+
}
|
|
11333
|
+
} catch (error) {
|
|
11334
|
+
console.warn("Failed to update _rels/.rels for custom properties:", error);
|
|
11335
|
+
}
|
|
11336
|
+
}
|
|
11337
|
+
}
|
|
11338
|
+
/**
|
|
11339
|
+
* Remove the Override + root rel for `docProps/custom.xml` when the
|
|
11340
|
+
* caller has emptied custom properties so the package doesn't keep an
|
|
11341
|
+
* orphan content-type entry referencing a deleted part.
|
|
11342
|
+
*/
|
|
11343
|
+
async removeCustomPropertiesPackagingArtifacts() {
|
|
11344
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11345
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11346
|
+
if (ctFile) {
|
|
11347
|
+
try {
|
|
11348
|
+
const ctXml = await ctFile.async("string");
|
|
11349
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11350
|
+
const types = ctData["Types"];
|
|
11351
|
+
if (types) {
|
|
11352
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11353
|
+
const filtered = overrides.filter(
|
|
11354
|
+
(o) => String(o?.["@_PartName"] || "") !== "/docProps/custom.xml"
|
|
11355
|
+
);
|
|
11356
|
+
if (filtered.length !== overrides.length) {
|
|
11357
|
+
types["Override"] = filtered.length === 1 ? filtered[0] : filtered;
|
|
11358
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11359
|
+
}
|
|
11360
|
+
}
|
|
11361
|
+
} catch {
|
|
11362
|
+
}
|
|
11363
|
+
}
|
|
11364
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11365
|
+
if (relsFile) {
|
|
11366
|
+
try {
|
|
11367
|
+
const relsXml = await relsFile.async("string");
|
|
11368
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11369
|
+
const relationships = relsData["Relationships"];
|
|
11370
|
+
if (relationships) {
|
|
11371
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11372
|
+
const filtered = rels.filter((r) => String(r?.["@_Type"] || "") !== customRelType);
|
|
11373
|
+
if (filtered.length !== rels.length) {
|
|
11374
|
+
relationships["Relationship"] = filtered;
|
|
11375
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11376
|
+
}
|
|
11377
|
+
}
|
|
11378
|
+
} catch {
|
|
11379
|
+
}
|
|
11380
|
+
}
|
|
10808
11381
|
}
|
|
10809
11382
|
normalizeCustomPropertyType(type) {
|
|
10810
11383
|
const supportedTypes = /* @__PURE__ */ new Set([
|
|
@@ -11148,6 +11721,7 @@ var PptxSlideLoaderService = class {
|
|
|
11148
11721
|
await params.loadSlideRelationships(path2, slideRelsPath);
|
|
11149
11722
|
const clrMapOverride = params.parseSlideClrMapOverride(slideXmlObj);
|
|
11150
11723
|
params.setCurrentSlideClrMapOverride(clrMapOverride);
|
|
11724
|
+
await params.setActiveMasterForSlide?.(path2);
|
|
11151
11725
|
let restoreThemeOverride;
|
|
11152
11726
|
try {
|
|
11153
11727
|
const layoutPathForOverride = params.findLayoutPathForSlide(path2);
|
|
@@ -15899,6 +16473,20 @@ var AXIS_TYPE_MAP = {
|
|
|
15899
16473
|
dateAx: "dateAx",
|
|
15900
16474
|
serAx: "serAx"
|
|
15901
16475
|
};
|
|
16476
|
+
function upsertChartAxisChild(parent, localName, value, getLocalName) {
|
|
16477
|
+
const existingKey = Object.keys(parent).find((k) => getLocalName(k) === localName);
|
|
16478
|
+
if (value === void 0) {
|
|
16479
|
+
if (existingKey) {
|
|
16480
|
+
delete parent[existingKey];
|
|
16481
|
+
}
|
|
16482
|
+
return;
|
|
16483
|
+
}
|
|
16484
|
+
if (existingKey) {
|
|
16485
|
+
parent[existingKey]["@_val"] = value;
|
|
16486
|
+
} else {
|
|
16487
|
+
parent[`c:${localName}`] = { "@_val": value };
|
|
16488
|
+
}
|
|
16489
|
+
}
|
|
15902
16490
|
function parseChartAxes(plotArea, xmlLookup, colorParser, getLocalName) {
|
|
15903
16491
|
const result = [];
|
|
15904
16492
|
for (const key of Object.keys(plotArea)) {
|
|
@@ -16019,6 +16607,27 @@ function parseSingleAxis(axisNode, axisType, xmlLookup, colorParser) {
|
|
|
16019
16607
|
if (dispUnitsNode) {
|
|
16020
16608
|
parseDisplayUnits(dispUnitsNode, xmlLookup, result);
|
|
16021
16609
|
}
|
|
16610
|
+
const majorUnitNode = xmlLookup.getChildByLocalName(axisNode, "majorUnit");
|
|
16611
|
+
if (majorUnitNode) {
|
|
16612
|
+
const majorVal = parseFloat(String(majorUnitNode["@_val"]));
|
|
16613
|
+
if (Number.isFinite(majorVal)) {
|
|
16614
|
+
result.majorUnit = majorVal;
|
|
16615
|
+
}
|
|
16616
|
+
}
|
|
16617
|
+
const minorUnitNode = xmlLookup.getChildByLocalName(axisNode, "minorUnit");
|
|
16618
|
+
if (minorUnitNode) {
|
|
16619
|
+
const minorVal = parseFloat(String(minorUnitNode["@_val"]));
|
|
16620
|
+
if (Number.isFinite(minorVal)) {
|
|
16621
|
+
result.minorUnit = minorVal;
|
|
16622
|
+
}
|
|
16623
|
+
}
|
|
16624
|
+
const tickLblPosNode = xmlLookup.getChildByLocalName(axisNode, "tickLblPos");
|
|
16625
|
+
if (tickLblPosNode) {
|
|
16626
|
+
const v = String(tickLblPosNode["@_val"] || "").trim();
|
|
16627
|
+
if (v === "high" || v === "low" || v === "nextTo" || v === "none") {
|
|
16628
|
+
result.tickLblPos = v;
|
|
16629
|
+
}
|
|
16630
|
+
}
|
|
16022
16631
|
return result;
|
|
16023
16632
|
}
|
|
16024
16633
|
var VALID_DISPLAY_UNITS = /* @__PURE__ */ new Set([
|
|
@@ -17330,23 +17939,55 @@ var SHAPE_TREE_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
17330
17939
|
"p16:model3D",
|
|
17331
17940
|
...VML_SHAPE_TAGS
|
|
17332
17941
|
]);
|
|
17942
|
+
function diagnoseSelection(ac) {
|
|
17943
|
+
const choices = ensureArray2(ac["mc:Choice"]);
|
|
17944
|
+
for (let i = 0; i < choices.length; i++) {
|
|
17945
|
+
const choice = choices[i];
|
|
17946
|
+
const requires = String(choice?.["@_Requires"] ?? "").trim();
|
|
17947
|
+
if (requires.length === 0 || areNamespacesSupported(requires)) {
|
|
17948
|
+
const resolved = resolveNestedAlternateContent(choice);
|
|
17949
|
+
return { branch: "choice", choiceIndex: i, resolved };
|
|
17950
|
+
}
|
|
17951
|
+
}
|
|
17952
|
+
const fallback = ac["mc:Fallback"];
|
|
17953
|
+
if (fallback) {
|
|
17954
|
+
return { branch: "fallback", resolved: resolveNestedAlternateContent(fallback) };
|
|
17955
|
+
}
|
|
17956
|
+
return void 0;
|
|
17957
|
+
}
|
|
17333
17958
|
function unwrapAlternateContent(container) {
|
|
17334
17959
|
const altContents = ensureArray2(container["mc:AlternateContent"]);
|
|
17335
17960
|
if (altContents.length === 0) {
|
|
17336
|
-
return;
|
|
17961
|
+
return [];
|
|
17337
17962
|
}
|
|
17963
|
+
const blocks = [];
|
|
17338
17964
|
for (const ac of altContents) {
|
|
17339
|
-
const
|
|
17340
|
-
if (!
|
|
17965
|
+
const diagnosis = diagnoseSelection(ac);
|
|
17966
|
+
if (!diagnosis) {
|
|
17341
17967
|
continue;
|
|
17342
17968
|
}
|
|
17969
|
+
const block = {
|
|
17970
|
+
rawAc: ac,
|
|
17971
|
+
selectedBranch: diagnosis.branch,
|
|
17972
|
+
choiceIndex: diagnosis.branch === "choice" ? diagnosis.choiceIndex : void 0,
|
|
17973
|
+
childRefs: []
|
|
17974
|
+
};
|
|
17975
|
+
const branch = diagnosis.resolved;
|
|
17343
17976
|
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
17344
17977
|
const children = ensureArray2(branch[tag]);
|
|
17345
17978
|
if (children.length > 0) {
|
|
17346
17979
|
container[tag] = [...ensureArray2(container[tag]), ...children];
|
|
17980
|
+
for (const child of children) {
|
|
17981
|
+
block.childRefs.push({ tag, node: child });
|
|
17982
|
+
}
|
|
17347
17983
|
}
|
|
17348
17984
|
}
|
|
17985
|
+
if (block.childRefs.length > 0) {
|
|
17986
|
+
blocks.push(block);
|
|
17987
|
+
}
|
|
17349
17988
|
}
|
|
17989
|
+
delete container["mc:AlternateContent"];
|
|
17990
|
+
return blocks;
|
|
17350
17991
|
}
|
|
17351
17992
|
function ensureArray2(val) {
|
|
17352
17993
|
if (!val) {
|
|
@@ -17358,7 +17999,7 @@ function ensureArray2(val) {
|
|
|
17358
17999
|
|
|
17359
18000
|
// src/core/utils/body-properties-parser.ts
|
|
17360
18001
|
function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
17361
|
-
const
|
|
18002
|
+
const parseBoolAttr2 = (attr) => {
|
|
17362
18003
|
const raw = bodyPr[attr];
|
|
17363
18004
|
if (raw === void 0) {
|
|
17364
18005
|
return void 0;
|
|
@@ -17366,19 +18007,19 @@ function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17366
18007
|
const val = String(raw).trim().toLowerCase();
|
|
17367
18008
|
return val === "1" || val === "true";
|
|
17368
18009
|
};
|
|
17369
|
-
const compatLnSpc =
|
|
18010
|
+
const compatLnSpc = parseBoolAttr2("@_compatLnSpc");
|
|
17370
18011
|
if (compatLnSpc !== void 0) {
|
|
17371
18012
|
textStyle.compatibleLineSpacing = compatLnSpc;
|
|
17372
18013
|
}
|
|
17373
|
-
const forceAA =
|
|
18014
|
+
const forceAA = parseBoolAttr2("@_forceAA");
|
|
17374
18015
|
if (forceAA !== void 0) {
|
|
17375
18016
|
textStyle.forceAntiAlias = forceAA;
|
|
17376
18017
|
}
|
|
17377
|
-
const upright =
|
|
18018
|
+
const upright = parseBoolAttr2("@_upright");
|
|
17378
18019
|
if (upright !== void 0) {
|
|
17379
18020
|
textStyle.upright = upright;
|
|
17380
18021
|
}
|
|
17381
|
-
const fromWordArt =
|
|
18022
|
+
const fromWordArt = parseBoolAttr2("@_fromWordArt");
|
|
17382
18023
|
if (fromWordArt !== void 0) {
|
|
17383
18024
|
textStyle.fromWordArt = fromWordArt;
|
|
17384
18025
|
}
|
|
@@ -17401,46 +18042,6 @@ function writeBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17401
18042
|
}
|
|
17402
18043
|
}
|
|
17403
18044
|
|
|
17404
|
-
// src/core/utils/theme-override-utils.ts
|
|
17405
|
-
var COLOR_MAP_ALIAS_KEYS = [
|
|
17406
|
-
"bg1",
|
|
17407
|
-
"tx1",
|
|
17408
|
-
"bg2",
|
|
17409
|
-
"tx2",
|
|
17410
|
-
"accent1",
|
|
17411
|
-
"accent2",
|
|
17412
|
-
"accent3",
|
|
17413
|
-
"accent4",
|
|
17414
|
-
"accent5",
|
|
17415
|
-
"accent6",
|
|
17416
|
-
"hlink",
|
|
17417
|
-
"folHlink"
|
|
17418
|
-
];
|
|
17419
|
-
var DEFAULT_COLOR_MAP = {
|
|
17420
|
-
bg1: "lt1",
|
|
17421
|
-
tx1: "dk1",
|
|
17422
|
-
bg2: "lt2",
|
|
17423
|
-
tx2: "dk2",
|
|
17424
|
-
accent1: "accent1",
|
|
17425
|
-
accent2: "accent2",
|
|
17426
|
-
accent3: "accent3",
|
|
17427
|
-
accent4: "accent4",
|
|
17428
|
-
accent5: "accent5",
|
|
17429
|
-
accent6: "accent6",
|
|
17430
|
-
hlink: "hlink",
|
|
17431
|
-
folHlink: "folHlink"
|
|
17432
|
-
};
|
|
17433
|
-
function buildClrMapOverrideXml(override) {
|
|
17434
|
-
if (!override || Object.keys(override).length === 0) {
|
|
17435
|
-
return { "a:masterClrMapping": {} };
|
|
17436
|
-
}
|
|
17437
|
-
const attrs2 = {};
|
|
17438
|
-
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
17439
|
-
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
17440
|
-
}
|
|
17441
|
-
return { "a:overrideClrMapping": attrs2 };
|
|
17442
|
-
}
|
|
17443
|
-
|
|
17444
18045
|
// src/core/utils/data-url-utils.ts
|
|
17445
18046
|
function parseDataUrlToBytes(dataUrl) {
|
|
17446
18047
|
const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);
|
|
@@ -17538,6 +18139,46 @@ async function fetchUrlToBytes(url) {
|
|
|
17538
18139
|
}
|
|
17539
18140
|
}
|
|
17540
18141
|
|
|
18142
|
+
// src/core/utils/theme-override-utils.ts
|
|
18143
|
+
var COLOR_MAP_ALIAS_KEYS = [
|
|
18144
|
+
"bg1",
|
|
18145
|
+
"tx1",
|
|
18146
|
+
"bg2",
|
|
18147
|
+
"tx2",
|
|
18148
|
+
"accent1",
|
|
18149
|
+
"accent2",
|
|
18150
|
+
"accent3",
|
|
18151
|
+
"accent4",
|
|
18152
|
+
"accent5",
|
|
18153
|
+
"accent6",
|
|
18154
|
+
"hlink",
|
|
18155
|
+
"folHlink"
|
|
18156
|
+
];
|
|
18157
|
+
var DEFAULT_COLOR_MAP = {
|
|
18158
|
+
bg1: "lt1",
|
|
18159
|
+
tx1: "dk1",
|
|
18160
|
+
bg2: "lt2",
|
|
18161
|
+
tx2: "dk2",
|
|
18162
|
+
accent1: "accent1",
|
|
18163
|
+
accent2: "accent2",
|
|
18164
|
+
accent3: "accent3",
|
|
18165
|
+
accent4: "accent4",
|
|
18166
|
+
accent5: "accent5",
|
|
18167
|
+
accent6: "accent6",
|
|
18168
|
+
hlink: "hlink",
|
|
18169
|
+
folHlink: "folHlink"
|
|
18170
|
+
};
|
|
18171
|
+
function buildClrMapOverrideXml(override) {
|
|
18172
|
+
if (!override || Object.keys(override).length === 0) {
|
|
18173
|
+
return { "a:masterClrMapping": {} };
|
|
18174
|
+
}
|
|
18175
|
+
const attrs2 = {};
|
|
18176
|
+
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
18177
|
+
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
18178
|
+
}
|
|
18179
|
+
return { "a:overrideClrMapping": attrs2 };
|
|
18180
|
+
}
|
|
18181
|
+
|
|
17541
18182
|
// src/core/utils/encryption-detection.ts
|
|
17542
18183
|
var OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 27, 26, 225]);
|
|
17543
18184
|
var ZIP_MAGIC = new Uint8Array([80, 75]);
|
|
@@ -23300,7 +23941,7 @@ function parseActiveXControlsFromSlide(slideXml2) {
|
|
|
23300
23941
|
}
|
|
23301
23942
|
|
|
23302
23943
|
// src/core/utils/theme-switching.ts
|
|
23303
|
-
function
|
|
23944
|
+
function normalizeHex2(hex) {
|
|
23304
23945
|
if (!hex) {
|
|
23305
23946
|
return "";
|
|
23306
23947
|
}
|
|
@@ -23310,8 +23951,8 @@ function buildColorRemapTable(oldColorMap, newColorMap) {
|
|
|
23310
23951
|
const remap = /* @__PURE__ */ new Map();
|
|
23311
23952
|
const allKeys = [...THEME_COLOR_SCHEME_KEYS, "tx1", "bg1", "tx2", "bg2"];
|
|
23312
23953
|
for (const key of allKeys) {
|
|
23313
|
-
const oldVal =
|
|
23314
|
-
const newVal =
|
|
23954
|
+
const oldVal = normalizeHex2(oldColorMap[key]);
|
|
23955
|
+
const newVal = normalizeHex2(newColorMap[key]);
|
|
23315
23956
|
if (oldVal && newVal && oldVal !== newVal) {
|
|
23316
23957
|
remap.set(oldVal, `#${newVal}`);
|
|
23317
23958
|
remap.set(`#${oldVal}`, `#${newVal}`);
|
|
@@ -23323,7 +23964,7 @@ function remapColor(color, remap) {
|
|
|
23323
23964
|
if (!color) {
|
|
23324
23965
|
return color;
|
|
23325
23966
|
}
|
|
23326
|
-
const normalized =
|
|
23967
|
+
const normalized = normalizeHex2(color);
|
|
23327
23968
|
const remapped = remap.get(normalized) ?? remap.get(`#${normalized}`);
|
|
23328
23969
|
return remapped ?? color;
|
|
23329
23970
|
}
|
|
@@ -23463,7 +24104,7 @@ function remapSlideColors(slide, remap) {
|
|
|
23463
24104
|
function buildThemeColorMap(colorScheme) {
|
|
23464
24105
|
const map = {};
|
|
23465
24106
|
for (const key of THEME_COLOR_SCHEME_KEYS) {
|
|
23466
|
-
map[key] =
|
|
24107
|
+
map[key] = normalizeHex2(colorScheme[key]);
|
|
23467
24108
|
}
|
|
23468
24109
|
map.tx1 = map.dk1;
|
|
23469
24110
|
map.bg1 = map.lt1;
|
|
@@ -23499,8 +24140,11 @@ function applyThemeToData(data, newColorScheme, newFontScheme, themeName) {
|
|
|
23499
24140
|
|
|
23500
24141
|
// src/core/core/runtime/PptxHandlerRuntimeSaveParagraphHelpers.ts
|
|
23501
24142
|
var EMU_PER_PX4 = 9525;
|
|
23502
|
-
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing) {
|
|
24143
|
+
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing, level) {
|
|
23503
24144
|
const paragraphProps = {};
|
|
24145
|
+
if (typeof level === "number" && Number.isFinite(level) && level > 0) {
|
|
24146
|
+
paragraphProps["@_lvl"] = String(Math.min(Math.max(Math.round(level), 0), 8));
|
|
24147
|
+
}
|
|
23504
24148
|
if (paragraphAlign) {
|
|
23505
24149
|
paragraphProps["@_algn"] = paragraphAlign;
|
|
23506
24150
|
}
|
|
@@ -23572,23 +24216,28 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23572
24216
|
paragraphProps["a:buNone"] = {};
|
|
23573
24217
|
return;
|
|
23574
24218
|
}
|
|
23575
|
-
if (bulletInfo.
|
|
24219
|
+
if (bulletInfo.colorInherit) {
|
|
24220
|
+
paragraphProps["a:buClrTx"] = {};
|
|
24221
|
+
} else if (bulletInfo.color) {
|
|
23576
24222
|
const colorHex = bulletInfo.color.replace("#", "");
|
|
23577
24223
|
paragraphProps["a:buClr"] = {
|
|
23578
24224
|
"a:srgbClr": { "@_val": colorHex }
|
|
23579
24225
|
};
|
|
23580
24226
|
}
|
|
23581
|
-
if (bulletInfo.
|
|
24227
|
+
if (bulletInfo.sizeInherit) {
|
|
24228
|
+
paragraphProps["a:buSzTx"] = {};
|
|
24229
|
+
} else if (bulletInfo.sizePercent !== void 0) {
|
|
23582
24230
|
paragraphProps["a:buSzPct"] = {
|
|
23583
24231
|
"@_val": String(Math.round(bulletInfo.sizePercent * 1e3))
|
|
23584
24232
|
};
|
|
23585
|
-
}
|
|
23586
|
-
if (bulletInfo.sizePts !== void 0) {
|
|
24233
|
+
} else if (bulletInfo.sizePts !== void 0) {
|
|
23587
24234
|
paragraphProps["a:buSzPts"] = {
|
|
23588
24235
|
"@_val": String(Math.round(bulletInfo.sizePts * 100))
|
|
23589
24236
|
};
|
|
23590
24237
|
}
|
|
23591
|
-
if (bulletInfo.
|
|
24238
|
+
if (bulletInfo.fontInherit) {
|
|
24239
|
+
paragraphProps["a:buFontTx"] = {};
|
|
24240
|
+
} else if (bulletInfo.fontFamily) {
|
|
23592
24241
|
paragraphProps["a:buFont"] = {
|
|
23593
24242
|
"@_typeface": bulletInfo.fontFamily
|
|
23594
24243
|
};
|
|
@@ -23611,7 +24260,7 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23611
24260
|
};
|
|
23612
24261
|
}
|
|
23613
24262
|
}
|
|
23614
|
-
function assembleParagraphXml(runs, paragraphProps) {
|
|
24263
|
+
function assembleParagraphXml(runs, paragraphProps, endParaRunProperties) {
|
|
23615
24264
|
const paragraph = {
|
|
23616
24265
|
"a:pPr": paragraphProps
|
|
23617
24266
|
};
|
|
@@ -23633,7 +24282,11 @@ function assembleParagraphXml(runs, paragraphProps) {
|
|
|
23633
24282
|
if (cleanRegularRuns.length === 0 && fieldRuns.length === 0) {
|
|
23634
24283
|
paragraph["a:r"] = runs.length > 1 ? runs : runs[0];
|
|
23635
24284
|
}
|
|
23636
|
-
|
|
24285
|
+
if (endParaRunProperties && typeof endParaRunProperties === "object") {
|
|
24286
|
+
paragraph["a:endParaRPr"] = endParaRunProperties;
|
|
24287
|
+
} else {
|
|
24288
|
+
paragraph["a:endParaRPr"] = { "@_lang": "en-US" };
|
|
24289
|
+
}
|
|
23637
24290
|
return paragraph;
|
|
23638
24291
|
}
|
|
23639
24292
|
function computeUniformSegmentOverrides(textStyle, textSegments) {
|
|
@@ -23937,6 +24590,140 @@ var PptxHandlerRuntime = class {
|
|
|
23937
24590
|
* `p:clrMapOvr / a:overrideClrMapping`.
|
|
23938
24591
|
*/
|
|
23939
24592
|
currentSlideClrMapOverride = null;
|
|
24593
|
+
/**
|
|
24594
|
+
* Per-master colour map alias dictionaries parsed from each master's
|
|
24595
|
+
* `<p:clrMap>` element (e.g. `bg1 → lt1`, `tx1 → dk1`, `accent1 → accent1`).
|
|
24596
|
+
*
|
|
24597
|
+
* `clrMap` is the *aliasing* layer between logical colour names used in
|
|
24598
|
+
* DrawingML and the raw theme scheme slots. Per ECMA-376 §19.3.1.7 it
|
|
24599
|
+
* lives on each `p:sldMaster`, and slide layouts/slides may further
|
|
24600
|
+
* override it via `p:clrMapOvr`. Resolution must happen at colour-lookup
|
|
24601
|
+
* time, *not* by baking it into {@link themeColorMap}.
|
|
24602
|
+
*
|
|
24603
|
+
* Phase 2 Stream B / C-H4.
|
|
24604
|
+
*/
|
|
24605
|
+
masterClrMaps = /* @__PURE__ */ new Map();
|
|
24606
|
+
/**
|
|
24607
|
+
* Per-master theme color maps. Each master may reference its own theme
|
|
24608
|
+
* file via `_rels/slideMasterN.xml.rels`. For multi-master decks, slides
|
|
24609
|
+
* must resolve scheme colours against their *own* master's theme.
|
|
24610
|
+
*
|
|
24611
|
+
* Falls back to {@link themeColorMap} when a master entry is missing.
|
|
24612
|
+
*
|
|
24613
|
+
* Phase 2 Stream B / C-H4.
|
|
24614
|
+
*/
|
|
24615
|
+
masterThemeColorMaps = /* @__PURE__ */ new Map();
|
|
24616
|
+
/**
|
|
24617
|
+
* Per-master theme font maps. Same rationale as
|
|
24618
|
+
* {@link masterThemeColorMaps}: multi-master decks may have one font
|
|
24619
|
+
* scheme per theme.
|
|
24620
|
+
*/
|
|
24621
|
+
masterThemeFontMaps = /* @__PURE__ */ new Map();
|
|
24622
|
+
/**
|
|
24623
|
+
* Per-master format schemes (fmtScheme). For multi-master decks each
|
|
24624
|
+
* master's slides should resolve fill/line/effect refs against the
|
|
24625
|
+
* matrix from that master's theme.
|
|
24626
|
+
*/
|
|
24627
|
+
masterThemeFormatSchemes = /* @__PURE__ */ new Map();
|
|
24628
|
+
/**
|
|
24629
|
+
* Per-master mapping from slide-master path to the theme path it
|
|
24630
|
+
* references via `_rels/slideMasterN.xml.rels`. Populated by
|
|
24631
|
+
* {@link loadPerMasterThemes} during load. Used by the save-side
|
|
24632
|
+
* theme writer to know which themeN.xml to (re)emit for each master.
|
|
24633
|
+
*
|
|
24634
|
+
* Phase 4 Stream A / C-H3.
|
|
24635
|
+
*/
|
|
24636
|
+
masterThemePaths = /* @__PURE__ */ new Map();
|
|
24637
|
+
/**
|
|
24638
|
+
* Per-script font tables for major and minor fonts. Captured per master
|
|
24639
|
+
* theme. Keys are master paths; values map `mj`/`mn` -> script tag (e.g.
|
|
24640
|
+
* `Hans`, `Hant`, `Arab`, `Hebr`, `Thai`, `Beng`, …) -> typeface name.
|
|
24641
|
+
*
|
|
24642
|
+
* Phase 4 Stream A / M4.
|
|
24643
|
+
*/
|
|
24644
|
+
masterThemeMajorFontScripts = /* @__PURE__ */ new Map();
|
|
24645
|
+
masterThemeMinorFontScripts = /* @__PURE__ */ new Map();
|
|
24646
|
+
/**
|
|
24647
|
+
* Theme name attribute (`<a:theme @name>`) per master theme path.
|
|
24648
|
+
* Captured for byte-stable round-trip.
|
|
24649
|
+
*/
|
|
24650
|
+
masterThemeNames = /* @__PURE__ */ new Map();
|
|
24651
|
+
/**
|
|
24652
|
+
* `<a:fontScheme @name>` per master theme path.
|
|
24653
|
+
*/
|
|
24654
|
+
masterThemeFontSchemeNames = /* @__PURE__ */ new Map();
|
|
24655
|
+
/**
|
|
24656
|
+
* `<a:clrScheme @name>` per master theme path.
|
|
24657
|
+
*/
|
|
24658
|
+
masterThemeColorSchemeNames = /* @__PURE__ */ new Map();
|
|
24659
|
+
/**
|
|
24660
|
+
* Raw original theme XML keyed by theme path. Captured at load-time.
|
|
24661
|
+
* Used by the save pipeline to passthrough the full theme XML when no
|
|
24662
|
+
* in-memory mutation has occurred — preserving fillStyleLst /
|
|
24663
|
+
* lnStyleLst / effectStyleLst / bgFillStyleLst /
|
|
24664
|
+
* extraClrSchemeLst / objectDefaults / extLst exactly as written.
|
|
24665
|
+
*
|
|
24666
|
+
* Phase 4 Stream A / C-H3.
|
|
24667
|
+
*/
|
|
24668
|
+
originalThemeXmlByPath = /* @__PURE__ */ new Map();
|
|
24669
|
+
/**
|
|
24670
|
+
* Set of theme paths whose in-memory state has been mutated since
|
|
24671
|
+
* load. Saving a theme path that's NOT dirty is a no-op (the original
|
|
24672
|
+
* file already exists in the ZIP). Saving a dirty theme path
|
|
24673
|
+
* regenerates the part from in-memory state.
|
|
24674
|
+
*
|
|
24675
|
+
* Phase 4 Stream A / C-H3.
|
|
24676
|
+
*/
|
|
24677
|
+
dirtyThemePaths = /* @__PURE__ */ new Set();
|
|
24678
|
+
/**
|
|
24679
|
+
* Per-master parsed `<p:txStyles>` (titleStyle/bodyStyle/otherStyle).
|
|
24680
|
+
* Populated by {@link enrichSlideMastersWithTxStyles} during load so the
|
|
24681
|
+
* inheritance chain can find the master text-style cascade without
|
|
24682
|
+
* re-parsing master XML on every lookup. Phase 4 Stream B / P-H1.
|
|
24683
|
+
*/
|
|
24684
|
+
masterTxStylesCache = /* @__PURE__ */ new Map();
|
|
24685
|
+
/**
|
|
24686
|
+
* Captured `<a:objectDefaults>` snapshot per master theme path. The
|
|
24687
|
+
* full ECMA-376 inheritance chain (master / layout / placeholder /
|
|
24688
|
+
* objectDefaults) is non-trivial; we store the raw spDef/lnDef/txDef
|
|
24689
|
+
* subtrees and re-emit them verbatim for round-trip.
|
|
24690
|
+
*
|
|
24691
|
+
* Phase 4 Stream A / M5.
|
|
24692
|
+
*/
|
|
24693
|
+
masterThemeObjectDefaults = /* @__PURE__ */ new Map();
|
|
24694
|
+
/**
|
|
24695
|
+
* Captured `<a:extraClrSchemeLst>` raw subtree per master theme path
|
|
24696
|
+
* for verbatim round-trip.
|
|
24697
|
+
*
|
|
24698
|
+
* Phase 4 Stream A.
|
|
24699
|
+
*/
|
|
24700
|
+
masterThemeExtraClrSchemeLst = /* @__PURE__ */ new Map();
|
|
24701
|
+
/**
|
|
24702
|
+
* Captured `<a:custClrLst>` raw subtree per master theme path
|
|
24703
|
+
* for verbatim round-trip.
|
|
24704
|
+
*
|
|
24705
|
+
* Phase 4 Stream A.
|
|
24706
|
+
*/
|
|
24707
|
+
masterThemeCustClrLst = /* @__PURE__ */ new Map();
|
|
24708
|
+
/**
|
|
24709
|
+
* Captured theme-level `<a:extLst>` raw subtree per master theme path.
|
|
24710
|
+
*/
|
|
24711
|
+
masterThemeExtLst = /* @__PURE__ */ new Map();
|
|
24712
|
+
/**
|
|
24713
|
+
* Active master's clrMap for the slide currently being parsed. Walked
|
|
24714
|
+
* after `currentSlideClrMapOverride` (slide and layout overrides take
|
|
24715
|
+
* precedence). `null` means "fall through to themeColorMap directly".
|
|
24716
|
+
*/
|
|
24717
|
+
currentMasterClrMap = null;
|
|
24718
|
+
/**
|
|
24719
|
+
* Snapshot of the global theme state taken right after
|
|
24720
|
+
* {@link loadThemeData} completes. Used as the fallback when a slide's
|
|
24721
|
+
* master has no per-master theme entry, so per-slide multi-master
|
|
24722
|
+
* switching does not leak the previous slide's master state.
|
|
24723
|
+
*/
|
|
24724
|
+
globalThemeColorMapSnapshot = {};
|
|
24725
|
+
globalThemeFontMapSnapshot = {};
|
|
24726
|
+
globalThemeFormatSchemeSnapshot;
|
|
23940
24727
|
/** Thumbnail image data from `docProps/thumbnail.jpeg` preserved for round-trip. */
|
|
23941
24728
|
thumbnailData = null;
|
|
23942
24729
|
/** Raw VBA project binary preserved for macro-enabled (.pptm) round-trip. */
|
|
@@ -23947,6 +24734,19 @@ var PptxHandlerRuntime = class {
|
|
|
23947
24734
|
signatureDetection = null;
|
|
23948
24735
|
/** Custom XML data parts parsed from `customXml/` in the OPC package. */
|
|
23949
24736
|
customXmlParts = [];
|
|
24737
|
+
/**
|
|
24738
|
+
* Maps an element's `rawXml` reference to the `mc:AlternateContent`
|
|
24739
|
+
* envelope that originally wrapped it (CC-4). Populated during slide
|
|
24740
|
+
* (and `p:grpSp`) parsing; consulted at save time to re-emit the
|
|
24741
|
+
* original `<mc:Choice>` / `<mc:Fallback>` shape so legacy renderers
|
|
24742
|
+
* keep their fallback content.
|
|
24743
|
+
*
|
|
24744
|
+
* Multiple sibling elements may share the same `AlternateContentBlock`
|
|
24745
|
+
* value (a single AC envelope often wraps several child shapes — e.g.
|
|
24746
|
+
* `p14:media` + its `p:pic` fallback nest one each). WeakMap so AC
|
|
24747
|
+
* envelopes are GC'd if the parsed XmlObject is dropped.
|
|
24748
|
+
*/
|
|
24749
|
+
alternateContentBlockByRawXml = /* @__PURE__ */ new WeakMap();
|
|
23950
24750
|
/** Embedded fonts extracted during load, preserved for automatic re-embedding on save. */
|
|
23951
24751
|
loadedEmbeddedFonts = [];
|
|
23952
24752
|
/** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
|
|
@@ -25760,7 +26560,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25760
26560
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25761
26561
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25762
26562
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25763
|
-
|
|
26563
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26564
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26565
|
+
if (hf) {
|
|
26566
|
+
result.headerFooter = hf;
|
|
26567
|
+
}
|
|
26568
|
+
return result;
|
|
25764
26569
|
} catch (e) {
|
|
25765
26570
|
console.warn("Failed to parse handout master:", e);
|
|
25766
26571
|
return void 0;
|
|
@@ -25786,7 +26591,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25786
26591
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25787
26592
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25788
26593
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25789
|
-
|
|
26594
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26595
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26596
|
+
if (hf) {
|
|
26597
|
+
result.headerFooter = hf;
|
|
26598
|
+
}
|
|
26599
|
+
return result;
|
|
25790
26600
|
} catch (e) {
|
|
25791
26601
|
console.warn("Failed to parse notes master:", e);
|
|
25792
26602
|
return void 0;
|
|
@@ -25831,6 +26641,10 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25831
26641
|
const uVal = String(userDrawn).trim().toLowerCase();
|
|
25832
26642
|
layout.userDrawn = uVal === "1" || uVal === "true";
|
|
25833
26643
|
}
|
|
26644
|
+
const hf = parseHeaderFooterFlags(sldLayout["p:hf"]);
|
|
26645
|
+
if (hf) {
|
|
26646
|
+
layout.headerFooter = hf;
|
|
26647
|
+
}
|
|
25834
26648
|
const clrMapOvr = sldLayout["p:clrMapOvr"];
|
|
25835
26649
|
if (clrMapOvr && clrMapOvr["a:masterClrMapping"] === void 0) {
|
|
25836
26650
|
const overrideNode = clrMapOvr["a:overrideClrMapping"];
|
|
@@ -26436,6 +27250,18 @@ function buildClrChangeNode(style) {
|
|
|
26436
27250
|
}
|
|
26437
27251
|
|
|
26438
27252
|
// src/core/core/runtime/PptxHandlerRuntimeSaveRunProperties.ts
|
|
27253
|
+
function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
|
|
27254
|
+
if (panose && panose.length > 0) {
|
|
27255
|
+
fontNode["@_panose"] = panose;
|
|
27256
|
+
}
|
|
27257
|
+
if (typeof pitchFamily === "number" && Number.isFinite(pitchFamily)) {
|
|
27258
|
+
fontNode["@_pitchFamily"] = String(pitchFamily);
|
|
27259
|
+
}
|
|
27260
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
27261
|
+
fontNode["@_charset"] = String(charset);
|
|
27262
|
+
}
|
|
27263
|
+
return fontNode;
|
|
27264
|
+
}
|
|
26439
27265
|
var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime11 {
|
|
26440
27266
|
createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
|
|
26441
27267
|
const runProps = {
|
|
@@ -26493,6 +27319,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26493
27319
|
if (style.bookmark) {
|
|
26494
27320
|
runProps["@_bmk"] = style.bookmark;
|
|
26495
27321
|
}
|
|
27322
|
+
if (style.altLanguage) {
|
|
27323
|
+
runProps["@_altLang"] = style.altLanguage;
|
|
27324
|
+
}
|
|
27325
|
+
if (typeof style.smartTagId === "number" && Number.isFinite(style.smartTagId)) {
|
|
27326
|
+
runProps["@_smtId"] = String(style.smartTagId);
|
|
27327
|
+
}
|
|
26496
27328
|
if (style.textOutlineWidth || style.textOutlineColor) {
|
|
26497
27329
|
const lnObj = {};
|
|
26498
27330
|
if (typeof style.textOutlineWidth === "number" && style.textOutlineWidth > 0) {
|
|
@@ -26508,11 +27340,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26508
27340
|
runProps["a:ln"] = lnObj;
|
|
26509
27341
|
}
|
|
26510
27342
|
if (style.color) {
|
|
26511
|
-
|
|
26512
|
-
|
|
26513
|
-
|
|
26514
|
-
|
|
26515
|
-
|
|
27343
|
+
const resolvedOriginalColor = style.colorXml ? this.parseColor(style.colorXml) : void 0;
|
|
27344
|
+
runProps["a:solidFill"] = serializeColorChoice(
|
|
27345
|
+
style.colorXml,
|
|
27346
|
+
resolvedOriginalColor,
|
|
27347
|
+
style.color
|
|
27348
|
+
);
|
|
26516
27349
|
} else if (style.textFillGradientStops && style.textFillGradientStops.length > 0) {
|
|
26517
27350
|
const gradStops = style.textFillGradientStops.filter((stop) => Boolean(stop?.color)).map((stop) => {
|
|
26518
27351
|
const rawPos = (stop.position ?? 0) / 100;
|
|
@@ -26585,16 +27418,32 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26585
27418
|
};
|
|
26586
27419
|
}
|
|
26587
27420
|
if (style.fontFamily) {
|
|
26588
|
-
runProps["a:latin"] =
|
|
26589
|
-
|
|
26590
|
-
|
|
26591
|
-
|
|
26592
|
-
|
|
26593
|
-
|
|
26594
|
-
|
|
27421
|
+
runProps["a:latin"] = applyFontMetadata(
|
|
27422
|
+
{ "@_typeface": style.fontFamily },
|
|
27423
|
+
style.latinFontPanose,
|
|
27424
|
+
style.latinFontPitchFamily,
|
|
27425
|
+
style.latinFontCharset
|
|
27426
|
+
);
|
|
27427
|
+
runProps["a:ea"] = applyFontMetadata(
|
|
27428
|
+
{ "@_typeface": style.eastAsiaFont || style.fontFamily },
|
|
27429
|
+
style.eastAsiaFontPanose,
|
|
27430
|
+
style.eastAsiaFontPitchFamily,
|
|
27431
|
+
style.eastAsiaFontCharset
|
|
27432
|
+
);
|
|
27433
|
+
runProps["a:cs"] = applyFontMetadata(
|
|
27434
|
+
{ "@_typeface": style.complexScriptFont || style.fontFamily },
|
|
27435
|
+
style.complexScriptFontPanose,
|
|
27436
|
+
style.complexScriptFontPitchFamily,
|
|
27437
|
+
style.complexScriptFontCharset
|
|
27438
|
+
);
|
|
26595
27439
|
}
|
|
26596
27440
|
if (style.symbolFont) {
|
|
26597
|
-
runProps["a:sym"] =
|
|
27441
|
+
runProps["a:sym"] = applyFontMetadata(
|
|
27442
|
+
{ "@_typeface": style.symbolFont },
|
|
27443
|
+
style.symbolFontPanose,
|
|
27444
|
+
style.symbolFontPitchFamily,
|
|
27445
|
+
style.symbolFontCharset
|
|
27446
|
+
);
|
|
26598
27447
|
}
|
|
26599
27448
|
if (style.hyperlink && resolveHyperlinkRelationshipId) {
|
|
26600
27449
|
const hyperlinkTarget = String(style.hyperlink).trim();
|
|
@@ -26669,14 +27518,15 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26669
27518
|
lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
|
|
26670
27519
|
lineSpacingExactPt: textStyle?.lineSpacingExactPt
|
|
26671
27520
|
};
|
|
26672
|
-
const createParagraph = (runs, bulletInfo) => {
|
|
27521
|
+
const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
|
|
26673
27522
|
const paragraphProps = buildParagraphPropertiesXml(
|
|
26674
27523
|
textStyle,
|
|
26675
27524
|
paragraphAlign,
|
|
26676
27525
|
bulletInfo,
|
|
26677
|
-
spacing
|
|
27526
|
+
spacing,
|
|
27527
|
+
level
|
|
26678
27528
|
);
|
|
26679
|
-
return assembleParagraphXml(runs, paragraphProps);
|
|
27529
|
+
return assembleParagraphXml(runs, paragraphProps, endParaRunProperties);
|
|
26680
27530
|
};
|
|
26681
27531
|
const createRun = (runText, style) => ({
|
|
26682
27532
|
"a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
|
|
@@ -26724,13 +27574,19 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26724
27574
|
const paragraphs = [];
|
|
26725
27575
|
let currentRuns = [];
|
|
26726
27576
|
let currentBulletInfo;
|
|
27577
|
+
let currentLevel;
|
|
27578
|
+
let currentEndParaRunProperties;
|
|
26727
27579
|
const pushParagraph = () => {
|
|
26728
27580
|
if (currentRuns.length === 0) {
|
|
26729
27581
|
currentRuns.push(createRun("", textStyle));
|
|
26730
27582
|
}
|
|
26731
|
-
paragraphs.push(
|
|
27583
|
+
paragraphs.push(
|
|
27584
|
+
createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
|
|
27585
|
+
);
|
|
26732
27586
|
currentRuns = [];
|
|
26733
27587
|
currentBulletInfo = void 0;
|
|
27588
|
+
currentLevel = void 0;
|
|
27589
|
+
currentEndParaRunProperties = void 0;
|
|
26734
27590
|
};
|
|
26735
27591
|
if (textSegments && textSegments.length > 0) {
|
|
26736
27592
|
const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
|
|
@@ -26742,8 +27598,16 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26742
27598
|
};
|
|
26743
27599
|
const segmentText = String(segment.text ?? "");
|
|
26744
27600
|
const lineParts = segmentText.split("\n");
|
|
26745
|
-
if (currentRuns.length === 0
|
|
26746
|
-
|
|
27601
|
+
if (currentRuns.length === 0) {
|
|
27602
|
+
if (segment.bulletInfo) {
|
|
27603
|
+
currentBulletInfo = segment.bulletInfo;
|
|
27604
|
+
}
|
|
27605
|
+
if (segment.paragraphLevel !== void 0) {
|
|
27606
|
+
currentLevel = segment.paragraphLevel;
|
|
27607
|
+
}
|
|
27608
|
+
if (segment.endParaRunProperties) {
|
|
27609
|
+
currentEndParaRunProperties = segment.endParaRunProperties;
|
|
27610
|
+
}
|
|
26747
27611
|
}
|
|
26748
27612
|
lineParts.forEach((linePart, lineIndex) => {
|
|
26749
27613
|
if (segment.rubyText !== void 0) {
|
|
@@ -26841,6 +27705,9 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
|
|
|
26841
27705
|
};
|
|
26842
27706
|
|
|
26843
27707
|
// src/core/core/runtime/PptxHandlerRuntimeSaveShapeXml.ts
|
|
27708
|
+
var OLE_OBJECT_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
|
|
27709
|
+
var IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
27710
|
+
var OLE_GRAPHIC_DATA_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
|
|
26844
27711
|
var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime14 {
|
|
26845
27712
|
/**
|
|
26846
27713
|
* Build a `p:graphicFrame` XML skeleton for an SDK-created table.
|
|
@@ -26891,6 +27758,148 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26891
27758
|
}
|
|
26892
27759
|
};
|
|
26893
27760
|
}
|
|
27761
|
+
/**
|
|
27762
|
+
* Build a `p:graphicFrame` XML skeleton for an OLE object element.
|
|
27763
|
+
*
|
|
27764
|
+
* Used both for SDK-created OLE elements (no `rawXml`) and to refresh
|
|
27765
|
+
* a few key attributes on a loaded element when the typed fields have
|
|
27766
|
+
* been mutated. The output is the canonical
|
|
27767
|
+
* `p:graphicFrame > a:graphic > a:graphicData uri="…/ole" > p:oleObj`
|
|
27768
|
+
* shape per ECMA-376 §19.3.1.34 / §13.3.4.
|
|
27769
|
+
*
|
|
27770
|
+
* The caller (`processSlideElement`) is responsible for ensuring the
|
|
27771
|
+
* embed / preview-image relationships referenced from `r:id` / `r:embed`
|
|
27772
|
+
* exist in the slide's rels file. This method does not register them
|
|
27773
|
+
* itself because the typed model does not currently carry the binary
|
|
27774
|
+
* payload — the binary part must already be in the package (loaded from
|
|
27775
|
+
* the original file). A fully-fabricated SDK OLE element therefore
|
|
27776
|
+
* still requires the consumer to attach the binary out-of-band; this
|
|
27777
|
+
* method simply emits a schema-valid envelope referencing the
|
|
27778
|
+
* specified relationship ID.
|
|
27779
|
+
*/
|
|
27780
|
+
createOleGraphicFrameXml(el, embedRelationshipId) {
|
|
27781
|
+
const EMU = _PptxHandlerRuntime.EMU_PER_PX;
|
|
27782
|
+
const offX = String(Math.round(el.x * EMU));
|
|
27783
|
+
const offY = String(Math.round(el.y * EMU));
|
|
27784
|
+
const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
|
|
27785
|
+
const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
|
|
27786
|
+
const oleObj = {
|
|
27787
|
+
"@_showAsIcon": "0",
|
|
27788
|
+
"@_imgW": extCx,
|
|
27789
|
+
"@_imgH": extCy
|
|
27790
|
+
};
|
|
27791
|
+
if (el.oleProgId) {
|
|
27792
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27793
|
+
}
|
|
27794
|
+
if (el.oleName) {
|
|
27795
|
+
oleObj["@_name"] = el.oleName;
|
|
27796
|
+
}
|
|
27797
|
+
if (el.oleClsId) {
|
|
27798
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27799
|
+
}
|
|
27800
|
+
if (embedRelationshipId) {
|
|
27801
|
+
oleObj["@_r:id"] = embedRelationshipId;
|
|
27802
|
+
}
|
|
27803
|
+
if (el.isLinked) {
|
|
27804
|
+
oleObj["p:link"] = {
|
|
27805
|
+
"@_r:id": embedRelationshipId,
|
|
27806
|
+
"@_updateAutomatic": "1"
|
|
27807
|
+
};
|
|
27808
|
+
} else {
|
|
27809
|
+
oleObj["p:embed"] = {};
|
|
27810
|
+
}
|
|
27811
|
+
oleObj["p:pic"] = {
|
|
27812
|
+
"p:nvPicPr": {
|
|
27813
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || "OleObject" },
|
|
27814
|
+
"p:cNvPicPr": {},
|
|
27815
|
+
"p:nvPr": {}
|
|
27816
|
+
},
|
|
27817
|
+
"p:blipFill": {
|
|
27818
|
+
"a:blip": {},
|
|
27819
|
+
"a:stretch": { "a:fillRect": {} }
|
|
27820
|
+
},
|
|
27821
|
+
"p:spPr": {
|
|
27822
|
+
"a:xfrm": {
|
|
27823
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27824
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27825
|
+
},
|
|
27826
|
+
"a:prstGeom": { "@_prst": "rect", "a:avLst": {} }
|
|
27827
|
+
}
|
|
27828
|
+
};
|
|
27829
|
+
return {
|
|
27830
|
+
"p:nvGraphicFramePr": {
|
|
27831
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || el.fileName || "OleObject" },
|
|
27832
|
+
"p:cNvGraphicFramePr": {
|
|
27833
|
+
"a:graphicFrameLocks": { "@_noChangeAspect": "1" }
|
|
27834
|
+
},
|
|
27835
|
+
"p:nvPr": {}
|
|
27836
|
+
},
|
|
27837
|
+
"p:xfrm": {
|
|
27838
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27839
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27840
|
+
},
|
|
27841
|
+
"a:graphic": {
|
|
27842
|
+
"a:graphicData": {
|
|
27843
|
+
"@_uri": OLE_GRAPHIC_DATA_URI,
|
|
27844
|
+
"p:oleObj": oleObj
|
|
27845
|
+
}
|
|
27846
|
+
}
|
|
27847
|
+
};
|
|
27848
|
+
}
|
|
27849
|
+
/**
|
|
27850
|
+
* Refresh editable typed-field attributes on a loaded OLE graphicFrame's
|
|
27851
|
+
* raw XML. Only attributes that round-trip through the typed model
|
|
27852
|
+
* (`progId`, `name`, `classid`) are touched so unknown extension data
|
|
27853
|
+
* passes through verbatim.
|
|
27854
|
+
*/
|
|
27855
|
+
applyOleTypedFieldUpdates(shape, el) {
|
|
27856
|
+
const oleObj = shape["a:graphic"]?.["a:graphicData"]?.["p:oleObj"];
|
|
27857
|
+
if (!oleObj) {
|
|
27858
|
+
return;
|
|
27859
|
+
}
|
|
27860
|
+
if (el.oleProgId) {
|
|
27861
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27862
|
+
}
|
|
27863
|
+
if (el.oleName !== void 0) {
|
|
27864
|
+
if (el.oleName.length > 0) {
|
|
27865
|
+
oleObj["@_name"] = el.oleName;
|
|
27866
|
+
} else {
|
|
27867
|
+
delete oleObj["@_name"];
|
|
27868
|
+
}
|
|
27869
|
+
}
|
|
27870
|
+
if (el.oleClsId) {
|
|
27871
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27872
|
+
}
|
|
27873
|
+
}
|
|
27874
|
+
/** Look up the existing OLE binary relationship ID for this slide, if any. */
|
|
27875
|
+
resolveOleEmbedRelationshipId(slideRelationships, oleTarget) {
|
|
27876
|
+
if (!oleTarget) {
|
|
27877
|
+
return void 0;
|
|
27878
|
+
}
|
|
27879
|
+
const normalisedTarget = oleTarget.replace(/^ppt\//, "../").replace(/^\/+/, "");
|
|
27880
|
+
const lowerTarget = normalisedTarget.toLowerCase();
|
|
27881
|
+
for (const rel of slideRelationships) {
|
|
27882
|
+
const relType = String(rel?.["@_Type"] || "");
|
|
27883
|
+
if (relType !== OLE_OBJECT_RELATIONSHIP_TYPE) {
|
|
27884
|
+
continue;
|
|
27885
|
+
}
|
|
27886
|
+
const target = String(rel?.["@_Target"] || "").toLowerCase().trim();
|
|
27887
|
+
if (target === lowerTarget || target.endsWith(lowerTarget) || lowerTarget.endsWith(target)) {
|
|
27888
|
+
const relId = String(rel?.["@_Id"] || "").trim();
|
|
27889
|
+
if (relId.length > 0) {
|
|
27890
|
+
return relId;
|
|
27891
|
+
}
|
|
27892
|
+
}
|
|
27893
|
+
}
|
|
27894
|
+
const fallback = slideRelationships.find(
|
|
27895
|
+
(rel) => String(rel?.["@_Type"] || "") === OLE_OBJECT_RELATIONSHIP_TYPE
|
|
27896
|
+
);
|
|
27897
|
+
const fallbackId = String(fallback?.["@_Id"] || "").trim();
|
|
27898
|
+
return fallbackId.length > 0 ? fallbackId : void 0;
|
|
27899
|
+
}
|
|
27900
|
+
/** Constants are exposed so the element-writer mixin can reuse them. */
|
|
27901
|
+
static OLE_OBJECT_RELATIONSHIP_TYPE = OLE_OBJECT_RELATIONSHIP_TYPE;
|
|
27902
|
+
static OLE_IMAGE_RELATIONSHIP_TYPE = IMAGE_RELATIONSHIP_TYPE;
|
|
26894
27903
|
/**
|
|
26895
27904
|
* Build a p:sp XML object for an ink annotation element.
|
|
26896
27905
|
* Each ink path becomes a separate a:path within a:pathLst,
|
|
@@ -27207,6 +28216,9 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
|
|
|
27207
28216
|
buildOuterShadowXml(shapeStyle) {
|
|
27208
28217
|
return this.colorStyleCodec.buildOuterShadowXml(shapeStyle);
|
|
27209
28218
|
}
|
|
28219
|
+
buildPresetShadowXml(shapeStyle) {
|
|
28220
|
+
return this.colorStyleCodec.buildPresetShadowXml(shapeStyle);
|
|
28221
|
+
}
|
|
27210
28222
|
buildInnerShadowXml(shapeStyle) {
|
|
27211
28223
|
return this.colorStyleCodec.buildInnerShadowXml(shapeStyle);
|
|
27212
28224
|
}
|
|
@@ -27757,6 +28769,10 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27757
28769
|
const solidFill = runProperties["a:solidFill"];
|
|
27758
28770
|
if (solidFill) {
|
|
27759
28771
|
style.color = this.parseColor(solidFill);
|
|
28772
|
+
const colorXml = extractColorChoiceXml(solidFill);
|
|
28773
|
+
if (colorXml) {
|
|
28774
|
+
style.colorXml = colorXml;
|
|
28775
|
+
}
|
|
27760
28776
|
}
|
|
27761
28777
|
this.applyHyperlinkStyle(style, runProperties, relationshipMap);
|
|
27762
28778
|
const capAttr = String(runProperties["@_cap"] || "").trim().toLowerCase();
|
|
@@ -27804,12 +28820,86 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27804
28820
|
if (bmk) {
|
|
27805
28821
|
style.bookmark = bmk;
|
|
27806
28822
|
}
|
|
28823
|
+
const altLang = String(runProperties["@_altLang"] || "").trim();
|
|
28824
|
+
if (altLang) {
|
|
28825
|
+
style.altLanguage = altLang;
|
|
28826
|
+
}
|
|
28827
|
+
if (runProperties["@_smtId"] !== void 0) {
|
|
28828
|
+
const smtIdRaw = Number.parseInt(String(runProperties["@_smtId"]), 10);
|
|
28829
|
+
if (Number.isFinite(smtIdRaw)) {
|
|
28830
|
+
style.smartTagId = smtIdRaw;
|
|
28831
|
+
}
|
|
28832
|
+
}
|
|
28833
|
+
this.applyTextFontMetadata(style, latin, "latin");
|
|
28834
|
+
this.applyTextFontMetadata(style, eastAsian, "eastAsia");
|
|
28835
|
+
this.applyTextFontMetadata(style, complexScript, "complexScript");
|
|
28836
|
+
this.applyTextFontMetadata(style, runProperties["a:sym"], "symbol");
|
|
27807
28837
|
const runEffectList = runProperties["a:effectLst"];
|
|
27808
28838
|
if (runEffectList) {
|
|
27809
28839
|
this.applyTextRunEffects(style, runEffectList);
|
|
27810
28840
|
}
|
|
27811
28841
|
return style;
|
|
27812
28842
|
}
|
|
28843
|
+
/**
|
|
28844
|
+
* Copy `@panose` / `@pitchFamily` / `@charset` from a font child node
|
|
28845
|
+
* (`a:latin`, `a:ea`, `a:cs`, `a:sym`) onto the matching `*Font*`
|
|
28846
|
+
* fields of `style`.
|
|
28847
|
+
*/
|
|
28848
|
+
applyTextFontMetadata(style, fontNode, kind) {
|
|
28849
|
+
if (!fontNode) {
|
|
28850
|
+
return;
|
|
28851
|
+
}
|
|
28852
|
+
const panose = String(fontNode["@_panose"] || "").trim();
|
|
28853
|
+
const pitchRaw = fontNode["@_pitchFamily"];
|
|
28854
|
+
const charsetRaw = fontNode["@_charset"];
|
|
28855
|
+
const pitch = pitchRaw !== void 0 && pitchRaw !== null ? Number.parseInt(String(pitchRaw), 10) : void 0;
|
|
28856
|
+
const charset = charsetRaw !== void 0 && charsetRaw !== null ? Number.parseInt(String(charsetRaw), 10) : void 0;
|
|
28857
|
+
if (kind === "latin") {
|
|
28858
|
+
if (panose) {
|
|
28859
|
+
style.latinFontPanose = panose;
|
|
28860
|
+
}
|
|
28861
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28862
|
+
style.latinFontPitchFamily = pitch;
|
|
28863
|
+
}
|
|
28864
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28865
|
+
style.latinFontCharset = charset;
|
|
28866
|
+
}
|
|
28867
|
+
return;
|
|
28868
|
+
}
|
|
28869
|
+
if (kind === "eastAsia") {
|
|
28870
|
+
if (panose) {
|
|
28871
|
+
style.eastAsiaFontPanose = panose;
|
|
28872
|
+
}
|
|
28873
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28874
|
+
style.eastAsiaFontPitchFamily = pitch;
|
|
28875
|
+
}
|
|
28876
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28877
|
+
style.eastAsiaFontCharset = charset;
|
|
28878
|
+
}
|
|
28879
|
+
return;
|
|
28880
|
+
}
|
|
28881
|
+
if (kind === "complexScript") {
|
|
28882
|
+
if (panose) {
|
|
28883
|
+
style.complexScriptFontPanose = panose;
|
|
28884
|
+
}
|
|
28885
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28886
|
+
style.complexScriptFontPitchFamily = pitch;
|
|
28887
|
+
}
|
|
28888
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28889
|
+
style.complexScriptFontCharset = charset;
|
|
28890
|
+
}
|
|
28891
|
+
return;
|
|
28892
|
+
}
|
|
28893
|
+
if (panose) {
|
|
28894
|
+
style.symbolFontPanose = panose;
|
|
28895
|
+
}
|
|
28896
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28897
|
+
style.symbolFontPitchFamily = pitch;
|
|
28898
|
+
}
|
|
28899
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28900
|
+
style.symbolFontCharset = charset;
|
|
28901
|
+
}
|
|
28902
|
+
}
|
|
27813
28903
|
};
|
|
27814
28904
|
|
|
27815
28905
|
// src/core/core/runtime/PptxHandlerRuntimeTextEditing.ts
|
|
@@ -28245,7 +29335,7 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
|
|
|
28245
29335
|
};
|
|
28246
29336
|
|
|
28247
29337
|
// src/core/core/runtime/table-cell-save-helpers.ts
|
|
28248
|
-
function writeCellFill(tcPr, style) {
|
|
29338
|
+
function writeCellFill(tcPr, style, resolveColorXml) {
|
|
28249
29339
|
if (style.fillMode === "gradient" && style.gradientFillStops && style.gradientFillStops.length > 0) {
|
|
28250
29340
|
delete tcPr["a:solidFill"];
|
|
28251
29341
|
delete tcPr["a:pattFill"];
|
|
@@ -28324,11 +29414,12 @@ function writeCellFill(tcPr, style) {
|
|
|
28324
29414
|
} else if (style.backgroundColor) {
|
|
28325
29415
|
delete tcPr["a:gradFill"];
|
|
28326
29416
|
delete tcPr["a:pattFill"];
|
|
28327
|
-
|
|
28328
|
-
|
|
28329
|
-
|
|
28330
|
-
|
|
28331
|
-
|
|
29417
|
+
const resolvedOriginal = style.backgroundColorXml && resolveColorXml ? resolveColorXml(style.backgroundColorXml) : void 0;
|
|
29418
|
+
tcPr["a:solidFill"] = serializeColorChoice(
|
|
29419
|
+
style.backgroundColorXml,
|
|
29420
|
+
resolvedOriginal,
|
|
29421
|
+
style.backgroundColor
|
|
29422
|
+
);
|
|
28332
29423
|
}
|
|
28333
29424
|
}
|
|
28334
29425
|
function writeDiagonalBorders(tcPr, style, emuPerPx) {
|
|
@@ -28459,7 +29550,7 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28459
29550
|
xmlCell["a:tcPr"] = {};
|
|
28460
29551
|
}
|
|
28461
29552
|
const tcPr = xmlCell["a:tcPr"];
|
|
28462
|
-
writeCellFill(tcPr, style);
|
|
29553
|
+
writeCellFill(tcPr, style, (colorXml) => this.parseColor(colorXml));
|
|
28463
29554
|
if (style.vAlign) {
|
|
28464
29555
|
const vAlignMap = {
|
|
28465
29556
|
top: "t",
|
|
@@ -28541,35 +29632,29 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28541
29632
|
}
|
|
28542
29633
|
}
|
|
28543
29634
|
}
|
|
28544
|
-
|
|
28545
|
-
|
|
28546
|
-
|
|
28547
|
-
tcPr["a:tcMar"] = {};
|
|
28548
|
-
}
|
|
28549
|
-
const tcMar = tcPr["a:tcMar"];
|
|
28550
|
-
if (style.marginLeft !== void 0) {
|
|
28551
|
-
tcMar["a:marL"] = {
|
|
28552
|
-
"@_w": String(Math.round(style.marginLeft * emuPerPx))
|
|
28553
|
-
};
|
|
28554
|
-
}
|
|
28555
|
-
if (style.marginRight !== void 0) {
|
|
28556
|
-
tcMar["a:marR"] = {
|
|
28557
|
-
"@_w": String(Math.round(style.marginRight * emuPerPx))
|
|
28558
|
-
};
|
|
28559
|
-
}
|
|
28560
|
-
if (style.marginTop !== void 0) {
|
|
28561
|
-
tcMar["a:marT"] = {
|
|
28562
|
-
"@_w": String(Math.round(style.marginTop * emuPerPx))
|
|
28563
|
-
};
|
|
28564
|
-
}
|
|
28565
|
-
if (style.marginBottom !== void 0) {
|
|
28566
|
-
tcMar["a:marB"] = {
|
|
28567
|
-
"@_w": String(Math.round(style.marginBottom * emuPerPx))
|
|
28568
|
-
};
|
|
28569
|
-
}
|
|
29635
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
29636
|
+
if (style.marginLeft !== void 0) {
|
|
29637
|
+
tcPr["@_marL"] = String(Math.round(style.marginLeft * emuPerPx));
|
|
28570
29638
|
}
|
|
29639
|
+
if (style.marginRight !== void 0) {
|
|
29640
|
+
tcPr["@_marR"] = String(Math.round(style.marginRight * emuPerPx));
|
|
29641
|
+
}
|
|
29642
|
+
if (style.marginTop !== void 0) {
|
|
29643
|
+
tcPr["@_marT"] = String(Math.round(style.marginTop * emuPerPx));
|
|
29644
|
+
}
|
|
29645
|
+
if (style.marginBottom !== void 0) {
|
|
29646
|
+
tcPr["@_marB"] = String(Math.round(style.marginBottom * emuPerPx));
|
|
29647
|
+
}
|
|
29648
|
+
delete tcPr["a:tcMar"];
|
|
28571
29649
|
writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime.EMU_PER_PX);
|
|
28572
29650
|
writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
|
|
29651
|
+
const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
|
|
29652
|
+
for (const key of Object.keys(tcPr)) {
|
|
29653
|
+
delete tcPr[key];
|
|
29654
|
+
}
|
|
29655
|
+
for (const key of Object.keys(reordered)) {
|
|
29656
|
+
tcPr[key] = reordered[key];
|
|
29657
|
+
}
|
|
28573
29658
|
}
|
|
28574
29659
|
};
|
|
28575
29660
|
|
|
@@ -28673,6 +29758,49 @@ function createDefaultXmlCell() {
|
|
|
28673
29758
|
// src/core/core/runtime/table-xml-rebuild.ts
|
|
28674
29759
|
var GRID_COL_ID_EXT_URI = "{9D8B030D-6E8A-4147-A177-3AD203B41FA5}";
|
|
28675
29760
|
var A16_NAMESPACE = "http://schemas.microsoft.com/office/drawing/2014/main";
|
|
29761
|
+
function ensureA16NamespaceOnSlideRoot(slideRoot) {
|
|
29762
|
+
if (!slideRoot["@_xmlns:a16"]) {
|
|
29763
|
+
slideRoot["@_xmlns:a16"] = A16_NAMESPACE;
|
|
29764
|
+
}
|
|
29765
|
+
if (!slideRoot["@_xmlns:mc"]) {
|
|
29766
|
+
slideRoot["@_xmlns:mc"] = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
29767
|
+
}
|
|
29768
|
+
const existingIgnorable = String(slideRoot["@_mc:Ignorable"] || "").trim();
|
|
29769
|
+
if (existingIgnorable.length === 0) {
|
|
29770
|
+
slideRoot["@_mc:Ignorable"] = "a16";
|
|
29771
|
+
return;
|
|
29772
|
+
}
|
|
29773
|
+
const tokens = existingIgnorable.split(/\s+/).filter((token) => token.length > 0);
|
|
29774
|
+
if (!tokens.includes("a16")) {
|
|
29775
|
+
tokens.push("a16");
|
|
29776
|
+
slideRoot["@_mc:Ignorable"] = tokens.join(" ");
|
|
29777
|
+
}
|
|
29778
|
+
}
|
|
29779
|
+
function slideContainsA16Element(node) {
|
|
29780
|
+
if (node === null || node === void 0) {
|
|
29781
|
+
return false;
|
|
29782
|
+
}
|
|
29783
|
+
if (Array.isArray(node)) {
|
|
29784
|
+
for (const entry of node) {
|
|
29785
|
+
if (slideContainsA16Element(entry)) {
|
|
29786
|
+
return true;
|
|
29787
|
+
}
|
|
29788
|
+
}
|
|
29789
|
+
return false;
|
|
29790
|
+
}
|
|
29791
|
+
if (typeof node !== "object") {
|
|
29792
|
+
return false;
|
|
29793
|
+
}
|
|
29794
|
+
for (const [key, value] of Object.entries(node)) {
|
|
29795
|
+
if (key.startsWith("a16:")) {
|
|
29796
|
+
return true;
|
|
29797
|
+
}
|
|
29798
|
+
if (slideContainsA16Element(value)) {
|
|
29799
|
+
return true;
|
|
29800
|
+
}
|
|
29801
|
+
}
|
|
29802
|
+
return false;
|
|
29803
|
+
}
|
|
28676
29804
|
function randomColumnId() {
|
|
28677
29805
|
return String(Math.floor(Math.random() * 4294967295));
|
|
28678
29806
|
}
|
|
@@ -28703,8 +29831,10 @@ function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
|
|
|
28703
29831
|
"a:extLst": {
|
|
28704
29832
|
"a:ext": {
|
|
28705
29833
|
"@_uri": GRID_COL_ID_EXT_URI,
|
|
29834
|
+
// `xmlns:a16` is declared on the slide root by
|
|
29835
|
+
// `ensureA16NamespaceOnSlideRoot`; emitting it here too is
|
|
29836
|
+
// schema-redundant and PowerPoint flags it.
|
|
28706
29837
|
"a16:colId": {
|
|
28707
|
-
"@_xmlns:a16": A16_NAMESPACE,
|
|
28708
29838
|
"@_val": existingColIds[i] || randomColumnId()
|
|
28709
29839
|
}
|
|
28710
29840
|
}
|
|
@@ -29063,26 +30193,64 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
29063
30193
|
continue;
|
|
29064
30194
|
}
|
|
29065
30195
|
const scalingNode = this.xmlLookupService.getChildByLocalName(axisNode, "scaling");
|
|
29066
|
-
if (
|
|
29067
|
-
|
|
30196
|
+
if (scalingNode) {
|
|
30197
|
+
if (matchingAxis.logBase !== void 0 && matchingAxis.logBase > 0) {
|
|
30198
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30199
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30200
|
+
);
|
|
30201
|
+
if (logBaseKey) {
|
|
30202
|
+
scalingNode[logBaseKey]["@_val"] = String(matchingAxis.logBase);
|
|
30203
|
+
} else {
|
|
30204
|
+
scalingNode["c:logBase"] = {
|
|
30205
|
+
"@_val": String(matchingAxis.logBase)
|
|
30206
|
+
};
|
|
30207
|
+
}
|
|
30208
|
+
} else if (matchingAxis.logScale === false) {
|
|
30209
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30210
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30211
|
+
);
|
|
30212
|
+
if (logBaseKey) {
|
|
30213
|
+
delete scalingNode[logBaseKey];
|
|
30214
|
+
}
|
|
30215
|
+
}
|
|
30216
|
+
this.upsertChartAxisChild(
|
|
30217
|
+
scalingNode,
|
|
30218
|
+
"min",
|
|
30219
|
+
matchingAxis.min !== void 0 ? String(matchingAxis.min) : void 0
|
|
30220
|
+
);
|
|
30221
|
+
this.upsertChartAxisChild(
|
|
30222
|
+
scalingNode,
|
|
30223
|
+
"max",
|
|
30224
|
+
matchingAxis.max !== void 0 ? String(matchingAxis.max) : void 0
|
|
30225
|
+
);
|
|
29068
30226
|
}
|
|
29069
|
-
if (matchingAxis.
|
|
29070
|
-
const
|
|
29071
|
-
(k) => this.compatibilityService.getXmlLocalName(k) === "
|
|
30227
|
+
if (matchingAxis.numFmt) {
|
|
30228
|
+
const numFmtKey = Object.keys(axisNode).find(
|
|
30229
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "numFmt"
|
|
29072
30230
|
);
|
|
29073
|
-
|
|
29074
|
-
|
|
30231
|
+
const numFmtAttrs = {
|
|
30232
|
+
"@_formatCode": matchingAxis.numFmt.formatCode,
|
|
30233
|
+
"@_sourceLinked": matchingAxis.numFmt.sourceLinked ? "1" : "0"
|
|
30234
|
+
};
|
|
30235
|
+
if (numFmtKey) {
|
|
30236
|
+
axisNode[numFmtKey] = numFmtAttrs;
|
|
29075
30237
|
} else {
|
|
29076
|
-
|
|
29077
|
-
"@_val": String(matchingAxis.logBase)
|
|
29078
|
-
};
|
|
30238
|
+
axisNode["c:numFmt"] = numFmtAttrs;
|
|
29079
30239
|
}
|
|
29080
|
-
}
|
|
29081
|
-
|
|
29082
|
-
|
|
30240
|
+
}
|
|
30241
|
+
this.upsertChartAxisChild(
|
|
30242
|
+
axisNode,
|
|
30243
|
+
"majorUnit",
|
|
30244
|
+
matchingAxis.majorUnit !== void 0 ? String(matchingAxis.majorUnit) : void 0
|
|
30245
|
+
);
|
|
30246
|
+
if (matchingAxis.tickLblPos !== void 0) {
|
|
30247
|
+
const tickLblKey = Object.keys(axisNode).find(
|
|
30248
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "tickLblPos"
|
|
29083
30249
|
);
|
|
29084
|
-
if (
|
|
29085
|
-
|
|
30250
|
+
if (tickLblKey) {
|
|
30251
|
+
axisNode[tickLblKey]["@_val"] = matchingAxis.tickLblPos;
|
|
30252
|
+
} else {
|
|
30253
|
+
axisNode["c:tickLblPos"] = { "@_val": matchingAxis.tickLblPos };
|
|
29086
30254
|
}
|
|
29087
30255
|
}
|
|
29088
30256
|
}
|
|
@@ -29095,6 +30263,18 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
29095
30263
|
}
|
|
29096
30264
|
this.pendingChartUpdates = void 0;
|
|
29097
30265
|
}
|
|
30266
|
+
/**
|
|
30267
|
+
* Upsert a `c:<localName>` child with `@_val` on an axis or scaling node.
|
|
30268
|
+
* When `value` is undefined, removes any existing child of that local name.
|
|
30269
|
+
*/
|
|
30270
|
+
upsertChartAxisChild(parent, localName, value) {
|
|
30271
|
+
upsertChartAxisChild(
|
|
30272
|
+
parent,
|
|
30273
|
+
localName,
|
|
30274
|
+
value,
|
|
30275
|
+
(key) => this.compatibilityService.getXmlLocalName(key)
|
|
30276
|
+
);
|
|
30277
|
+
}
|
|
29098
30278
|
/**
|
|
29099
30279
|
* Update the cached point values in a chart reference node
|
|
29100
30280
|
* (numRef/strRef or numLit/strLit).
|
|
@@ -30374,17 +31554,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30374
31554
|
delete spPr["a:noFill"];
|
|
30375
31555
|
delete spPr["a:gradFill"];
|
|
30376
31556
|
delete spPr["a:blipFill"];
|
|
30377
|
-
const
|
|
30378
|
-
|
|
30379
|
-
|
|
30380
|
-
|
|
30381
|
-
|
|
30382
|
-
|
|
30383
|
-
|
|
30384
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.fillOpacity) * 1e5))
|
|
30385
|
-
};
|
|
30386
|
-
}
|
|
30387
|
-
spPr["a:solidFill"] = solidFill;
|
|
31557
|
+
const resolvedOriginal = shapeStyle.fillColorXml ? this.parseColor(shapeStyle.fillColorXml) : void 0;
|
|
31558
|
+
spPr["a:solidFill"] = serializeColorChoice(
|
|
31559
|
+
shapeStyle.fillColorXml,
|
|
31560
|
+
resolvedOriginal,
|
|
31561
|
+
fillColor,
|
|
31562
|
+
shapeStyle.fillOpacity
|
|
31563
|
+
);
|
|
30388
31564
|
}
|
|
30389
31565
|
}
|
|
30390
31566
|
if (shapeStyle.strokeColor !== void 0) {
|
|
@@ -30399,17 +31575,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30399
31575
|
delete lineNode["a:solidFill"];
|
|
30400
31576
|
} else {
|
|
30401
31577
|
delete lineNode["a:noFill"];
|
|
30402
|
-
const
|
|
30403
|
-
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
30408
|
-
|
|
30409
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.strokeOpacity) * 1e5))
|
|
30410
|
-
};
|
|
30411
|
-
}
|
|
30412
|
-
lineNode["a:solidFill"] = lineFill;
|
|
31578
|
+
const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
|
|
31579
|
+
lineNode["a:solidFill"] = serializeColorChoice(
|
|
31580
|
+
shapeStyle.strokeColorXml,
|
|
31581
|
+
resolvedStrokeOriginal,
|
|
31582
|
+
shapeStyle.strokeColor,
|
|
31583
|
+
shapeStyle.strokeOpacity
|
|
31584
|
+
);
|
|
30413
31585
|
}
|
|
30414
31586
|
}
|
|
30415
31587
|
if (shapeStyle.strokeDash !== void 0) {
|
|
@@ -30490,7 +31662,11 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30490
31662
|
} else if (shapeStyle.lineJoin === "bevel") {
|
|
30491
31663
|
lineNode["a:bevel"] = {};
|
|
30492
31664
|
} else if (shapeStyle.lineJoin === "miter") {
|
|
30493
|
-
|
|
31665
|
+
const miterNode = {};
|
|
31666
|
+
if (typeof shapeStyle.miterLimit === "number" && Number.isFinite(shapeStyle.miterLimit) && shapeStyle.miterLimit !== 8e5) {
|
|
31667
|
+
miterNode["@_lim"] = String(Math.round(shapeStyle.miterLimit));
|
|
31668
|
+
}
|
|
31669
|
+
lineNode["a:miter"] = miterNode;
|
|
30494
31670
|
}
|
|
30495
31671
|
}
|
|
30496
31672
|
if (shapeStyle.lineCap !== void 0) {
|
|
@@ -30510,6 +31686,82 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30510
31686
|
spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
|
|
30511
31687
|
}
|
|
30512
31688
|
}
|
|
31689
|
+
/**
|
|
31690
|
+
* Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
|
|
31691
|
+
* from the persisted ref indices/colour XML. Emits children in spec
|
|
31692
|
+
* order: `lnRef → fillRef → effectRef → fontRef`.
|
|
31693
|
+
*
|
|
31694
|
+
* When the original shape XML already contained a `<p:style>` we mutate
|
|
31695
|
+
* that node in place so any unmodelled attributes/children are preserved.
|
|
31696
|
+
* When it didn't, we create one. When the shape no longer has any ref
|
|
31697
|
+
* data we leave the existing `<p:style>` (if any) untouched — silently
|
|
31698
|
+
* dropping it would break round-tripping.
|
|
31699
|
+
*
|
|
31700
|
+
* Phase 2 Stream B / C-H2.
|
|
31701
|
+
*/
|
|
31702
|
+
applyShapeStyleRefs(shape, shapeStyle) {
|
|
31703
|
+
const hasAnyRef = shapeStyle.lnRefIdx !== void 0 || shapeStyle.fillRefIdx !== void 0 || shapeStyle.effectRefIdx !== void 0 || shapeStyle.fontRefIdx !== void 0;
|
|
31704
|
+
if (!hasAnyRef) {
|
|
31705
|
+
return;
|
|
31706
|
+
}
|
|
31707
|
+
const existing = shape["p:style"];
|
|
31708
|
+
const styleNode = existing ?? {};
|
|
31709
|
+
if (shapeStyle.lnRefIdx !== void 0) {
|
|
31710
|
+
const lnRef = styleNode["a:lnRef"] ?? {};
|
|
31711
|
+
lnRef["@_idx"] = String(shapeStyle.lnRefIdx);
|
|
31712
|
+
this.replaceRefColorChoice(lnRef, shapeStyle.lnRefColorXml);
|
|
31713
|
+
styleNode["a:lnRef"] = lnRef;
|
|
31714
|
+
}
|
|
31715
|
+
if (shapeStyle.fillRefIdx !== void 0) {
|
|
31716
|
+
const fillRef = styleNode["a:fillRef"] ?? {};
|
|
31717
|
+
fillRef["@_idx"] = String(shapeStyle.fillRefIdx);
|
|
31718
|
+
this.replaceRefColorChoice(fillRef, shapeStyle.fillRefColorXml);
|
|
31719
|
+
styleNode["a:fillRef"] = fillRef;
|
|
31720
|
+
}
|
|
31721
|
+
if (shapeStyle.effectRefIdx !== void 0) {
|
|
31722
|
+
const effectRef = styleNode["a:effectRef"] ?? {};
|
|
31723
|
+
effectRef["@_idx"] = String(shapeStyle.effectRefIdx);
|
|
31724
|
+
this.replaceRefColorChoice(effectRef, shapeStyle.effectRefColorXml);
|
|
31725
|
+
styleNode["a:effectRef"] = effectRef;
|
|
31726
|
+
}
|
|
31727
|
+
if (shapeStyle.fontRefIdx !== void 0) {
|
|
31728
|
+
const fontRef = styleNode["a:fontRef"] ?? {};
|
|
31729
|
+
fontRef["@_idx"] = shapeStyle.fontRefIdx;
|
|
31730
|
+
this.replaceRefColorChoice(fontRef, shapeStyle.fontRefColorXml);
|
|
31731
|
+
styleNode["a:fontRef"] = fontRef;
|
|
31732
|
+
}
|
|
31733
|
+
const reordered = reorderObjectKeys(styleNode, SHAPE_STYLE_ORDER);
|
|
31734
|
+
for (const key of Object.keys(styleNode)) {
|
|
31735
|
+
delete styleNode[key];
|
|
31736
|
+
}
|
|
31737
|
+
for (const key of Object.keys(reordered)) {
|
|
31738
|
+
styleNode[key] = reordered[key];
|
|
31739
|
+
}
|
|
31740
|
+
shape["p:style"] = styleNode;
|
|
31741
|
+
}
|
|
31742
|
+
/**
|
|
31743
|
+
* Replace any existing colour-choice child on a style-matrix-reference
|
|
31744
|
+
* element with the given preserved XML, or strip all colour children
|
|
31745
|
+
* when the override is undefined.
|
|
31746
|
+
*/
|
|
31747
|
+
replaceRefColorChoice(refNode, colorXml) {
|
|
31748
|
+
for (const key of [
|
|
31749
|
+
"a:scrgbClr",
|
|
31750
|
+
"a:srgbClr",
|
|
31751
|
+
"a:hslClr",
|
|
31752
|
+
"a:sysClr",
|
|
31753
|
+
"a:schemeClr",
|
|
31754
|
+
"a:prstClr"
|
|
31755
|
+
]) {
|
|
31756
|
+
delete refNode[key];
|
|
31757
|
+
}
|
|
31758
|
+
if (!colorXml) {
|
|
31759
|
+
return;
|
|
31760
|
+
}
|
|
31761
|
+
for (const [key, value] of Object.entries(colorXml)) {
|
|
31762
|
+
refNode[key] = value;
|
|
31763
|
+
}
|
|
31764
|
+
}
|
|
30513
31765
|
};
|
|
30514
31766
|
|
|
30515
31767
|
// src/core/core/runtime/PptxHandlerRuntimeSaveEffectsWriter.ts
|
|
@@ -30519,17 +31771,22 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30519
31771
|
* effectDag, 3D scene, and 3D shape properties to the given spPr XML object.
|
|
30520
31772
|
*/
|
|
30521
31773
|
applyEffectsAndThreeD(spPr, shapeStyle) {
|
|
30522
|
-
const
|
|
31774
|
+
const presetShadowXml = shapeStyle.presetShadowName ? this.buildPresetShadowXml(shapeStyle) : void 0;
|
|
31775
|
+
const outerShadowXml = presetShadowXml ? void 0 : this.buildOuterShadowXml(shapeStyle);
|
|
30523
31776
|
const innerShadowXml = this.buildInnerShadowXml(shapeStyle);
|
|
30524
31777
|
const glowXml = this.buildGlowXml(shapeStyle);
|
|
30525
31778
|
const softEdgeXml = this.buildSoftEdgeXml(shapeStyle);
|
|
30526
31779
|
const reflectionXml = this.buildReflectionXml(shapeStyle);
|
|
30527
31780
|
const blurXml = this.buildBlurXml(shapeStyle);
|
|
30528
|
-
const hasAnyEffect = outerShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
31781
|
+
const hasAnyEffect = outerShadowXml || presetShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
30529
31782
|
if (hasAnyEffect) {
|
|
30530
31783
|
const effectList = spPr["a:effectLst"] || {};
|
|
30531
|
-
if (
|
|
31784
|
+
if (presetShadowXml) {
|
|
31785
|
+
effectList["a:prstShdw"] = presetShadowXml;
|
|
31786
|
+
delete effectList["a:outerShdw"];
|
|
31787
|
+
} else if (outerShadowXml) {
|
|
30532
31788
|
effectList["a:outerShdw"] = outerShadowXml;
|
|
31789
|
+
delete effectList["a:prstShdw"];
|
|
30533
31790
|
}
|
|
30534
31791
|
if (innerShadowXml) {
|
|
30535
31792
|
effectList["a:innerShdw"] = innerShadowXml;
|
|
@@ -30546,12 +31803,13 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30546
31803
|
if (blurXml) {
|
|
30547
31804
|
effectList["a:blur"] = blurXml;
|
|
30548
31805
|
}
|
|
30549
|
-
spPr["a:effectLst"] = effectList;
|
|
31806
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30550
31807
|
} else {
|
|
30551
31808
|
const effectList = spPr["a:effectLst"];
|
|
30552
31809
|
if (effectList) {
|
|
30553
|
-
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml) {
|
|
31810
|
+
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml && !presetShadowXml) {
|
|
30554
31811
|
delete effectList["a:outerShdw"];
|
|
31812
|
+
delete effectList["a:prstShdw"];
|
|
30555
31813
|
}
|
|
30556
31814
|
if (shapeStyle.innerShadowColor !== void 0 && !innerShadowXml) {
|
|
30557
31815
|
delete effectList["a:innerShdw"];
|
|
@@ -30570,6 +31828,8 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30570
31828
|
}
|
|
30571
31829
|
if (Object.keys(effectList).length === 0) {
|
|
30572
31830
|
delete spPr["a:effectLst"];
|
|
31831
|
+
} else {
|
|
31832
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30573
31833
|
}
|
|
30574
31834
|
}
|
|
30575
31835
|
}
|
|
@@ -30730,7 +31990,8 @@ var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30730
31990
|
);
|
|
30731
31991
|
}
|
|
30732
31992
|
if (el.textStyle?.hOverflow) {
|
|
30733
|
-
bodyPr["@
|
|
31993
|
+
bodyPr["@_horzOverflow"] = el.textStyle.hOverflow;
|
|
31994
|
+
delete bodyPr["@_hOverflow"];
|
|
30734
31995
|
}
|
|
30735
31996
|
if (el.textStyle?.vertOverflow) {
|
|
30736
31997
|
bodyPr["@_vertOverflow"] = el.textStyle.vertOverflow;
|
|
@@ -30961,7 +32222,10 @@ var PptxHandlerRuntime31 = class extends PptxHandlerRuntime30 {
|
|
|
30961
32222
|
const elWithPaths = el;
|
|
30962
32223
|
if (elWithPaths.customGeometryPaths && elWithPaths.customGeometryPaths.length > 0) {
|
|
30963
32224
|
delete spPr["a:prstGeom"];
|
|
30964
|
-
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32225
|
+
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32226
|
+
elWithPaths.customGeometryPaths,
|
|
32227
|
+
elWithPaths.customGeometryRawData
|
|
32228
|
+
);
|
|
30965
32229
|
} else if (spPr["a:prstGeom"]) {
|
|
30966
32230
|
const presetGeometry = el.type === "connector" ? this.normalizePresetGeometry(el.shapeType || "straightConnector1") : this.normalizePresetGeometry(el.shapeType);
|
|
30967
32231
|
const prstGeom = spPr["a:prstGeom"];
|
|
@@ -31086,6 +32350,42 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31086
32350
|
isGraphicFrameShape(shape) {
|
|
31087
32351
|
return Boolean(shape["p:nvGraphicFramePr"] || shape["a:graphic"] && shape["p:xfrm"]);
|
|
31088
32352
|
}
|
|
32353
|
+
/**
|
|
32354
|
+
* Reorder children of `p:spPr` to match CT_ShapeProperties (§20.1.2.2.35).
|
|
32355
|
+
* Also reorders any nested `a:blipFill` per CT_BlipFillProperties.
|
|
32356
|
+
* fast-xml-parser preserves insertion order; PowerPoint validates against
|
|
32357
|
+
* the schema's required order, so save-side mutations must be re-sorted.
|
|
32358
|
+
*/
|
|
32359
|
+
finalizeSpPrSchemaOrder(shape) {
|
|
32360
|
+
const spPr = shape["p:spPr"];
|
|
32361
|
+
if (!spPr) {
|
|
32362
|
+
return;
|
|
32363
|
+
}
|
|
32364
|
+
const blipFill = spPr["a:blipFill"];
|
|
32365
|
+
if (blipFill) {
|
|
32366
|
+
this.reorderInPlace(blipFill, BLIP_FILL_ORDER);
|
|
32367
|
+
}
|
|
32368
|
+
this.reorderInPlace(spPr, SP_PR_ORDER);
|
|
32369
|
+
}
|
|
32370
|
+
/**
|
|
32371
|
+
* Reorder children of the picture-level `p:blipFill` (CT_BlipFillProperties).
|
|
32372
|
+
* Picture elements carry their blip data on the `p:pic` root, not under spPr.
|
|
32373
|
+
*/
|
|
32374
|
+
finalizePictureBlipFillOrder(shape) {
|
|
32375
|
+
const pBlipFill = shape["p:blipFill"];
|
|
32376
|
+
if (pBlipFill) {
|
|
32377
|
+
this.reorderInPlace(pBlipFill, BLIP_FILL_ORDER);
|
|
32378
|
+
}
|
|
32379
|
+
}
|
|
32380
|
+
reorderInPlace(target, schemaOrder) {
|
|
32381
|
+
const reordered = reorderObjectKeys(target, schemaOrder);
|
|
32382
|
+
for (const key of Object.keys(target)) {
|
|
32383
|
+
delete target[key];
|
|
32384
|
+
}
|
|
32385
|
+
for (const key of Object.keys(reordered)) {
|
|
32386
|
+
target[key] = reordered[key];
|
|
32387
|
+
}
|
|
32388
|
+
}
|
|
31089
32389
|
/** Whether an element ID indicates a template (layout/master) element. */
|
|
31090
32390
|
isTemplateElementId(elementId) {
|
|
31091
32391
|
return elementId.startsWith("layout-") || elementId.startsWith("master-");
|
|
@@ -31109,18 +32409,51 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31109
32409
|
}
|
|
31110
32410
|
return;
|
|
31111
32411
|
}
|
|
32412
|
+
if (el.type === "contentPart") {
|
|
32413
|
+
if (shape) {
|
|
32414
|
+
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
32415
|
+
collectors.contentParts.push(shape);
|
|
32416
|
+
} else {
|
|
32417
|
+
this.compatibilityService.reportWarning({
|
|
32418
|
+
code: "SAVE_ELEMENT_SKIPPED",
|
|
32419
|
+
message: `Content part '${el.id}' has no rawXml and was skipped during save.`,
|
|
32420
|
+
scope: "save",
|
|
32421
|
+
slideId: ctx.slide.id,
|
|
32422
|
+
elementId: el.id
|
|
32423
|
+
});
|
|
32424
|
+
}
|
|
32425
|
+
return;
|
|
32426
|
+
}
|
|
31112
32427
|
if (!shape && (el.type === "text" || el.type === "shape")) {
|
|
31113
32428
|
shape = this.createElementXml(el);
|
|
31114
32429
|
}
|
|
31115
32430
|
if (!shape && el.type === "connector") {
|
|
31116
32431
|
shape = this.createConnectorXml(el);
|
|
31117
32432
|
}
|
|
31118
|
-
if (
|
|
31119
|
-
|
|
32433
|
+
if (el.type === "ink") {
|
|
32434
|
+
if (!shape) {
|
|
32435
|
+
shape = this.createInkShapeXml(el);
|
|
32436
|
+
this.compatibilityService.reportWarning({
|
|
32437
|
+
code: "SAVE_INK_ENCODED_AS_CUSTGEOM",
|
|
32438
|
+
message: "SDK-created ink element serialized as custGeom shape; pressure/tool metadata not represented in OOXML aink format.",
|
|
32439
|
+
scope: "save",
|
|
32440
|
+
slideId: ctx.slide.id,
|
|
32441
|
+
elementId: el.id
|
|
32442
|
+
});
|
|
32443
|
+
}
|
|
31120
32444
|
}
|
|
31121
32445
|
if (!shape && el.type === "table") {
|
|
31122
32446
|
shape = this.createTableGraphicFrameXml(el);
|
|
31123
32447
|
}
|
|
32448
|
+
if (el.type === "ole") {
|
|
32449
|
+
const oleEl = el;
|
|
32450
|
+
if (shape) {
|
|
32451
|
+
this.applyOleTypedFieldUpdates(shape, oleEl);
|
|
32452
|
+
} else {
|
|
32453
|
+
const embedRid = this.resolveOleEmbedRelationshipId(ctx.slideRelationships, oleEl.oleTarget) || ctx.slideRelationshipRegistry.nextRelationshipId();
|
|
32454
|
+
shape = this.createOleGraphicFrameXml(oleEl, embedRid);
|
|
32455
|
+
}
|
|
32456
|
+
}
|
|
31124
32457
|
if (!shape) {
|
|
31125
32458
|
this.compatibilityService.reportWarning({
|
|
31126
32459
|
code: "SAVE_ELEMENT_SKIPPED",
|
|
@@ -31133,11 +32466,14 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31133
32466
|
}
|
|
31134
32467
|
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
31135
32468
|
this.applyImageProperties(shape, el);
|
|
32469
|
+
this.finalizePictureBlipFillOrder(shape);
|
|
31136
32470
|
this.applyGeometryUpdate(shape, el);
|
|
31137
32471
|
if (hasShapeProperties(el) && el.shapeStyle && shape["p:spPr"]) {
|
|
31138
32472
|
const spPr = shape["p:spPr"];
|
|
31139
32473
|
this.applyFillAndStroke(spPr, el.shapeStyle);
|
|
31140
32474
|
this.applyEffectsAndThreeD(spPr, el.shapeStyle);
|
|
32475
|
+
this.finalizeSpPrSchemaOrder(shape);
|
|
32476
|
+
this.applyShapeStyleRefs(shape, el.shapeStyle);
|
|
31141
32477
|
}
|
|
31142
32478
|
if (hasTextProperties(el)) {
|
|
31143
32479
|
this.applyTextBodyContent(
|
|
@@ -31295,7 +32631,8 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31295
32631
|
connectors: [],
|
|
31296
32632
|
graphicFrames: [],
|
|
31297
32633
|
groups: [],
|
|
31298
|
-
model3ds: []
|
|
32634
|
+
model3ds: [],
|
|
32635
|
+
contentParts: []
|
|
31299
32636
|
};
|
|
31300
32637
|
const ctx = {
|
|
31301
32638
|
slide,
|
|
@@ -31327,6 +32664,12 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31327
32664
|
} else {
|
|
31328
32665
|
delete spTree["p16:model3D"];
|
|
31329
32666
|
}
|
|
32667
|
+
if (collectors.contentParts.length > 0) {
|
|
32668
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32669
|
+
} else {
|
|
32670
|
+
delete spTree["p:contentPart"];
|
|
32671
|
+
}
|
|
32672
|
+
this.reapplyAlternateContentEnvelopes(spTree, collectors);
|
|
31330
32673
|
const reassigned = shapeIdValidator.validateAndDeduplicateIds(
|
|
31331
32674
|
spTree,
|
|
31332
32675
|
(v) => this.ensureArray(v)
|
|
@@ -31344,12 +32687,426 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31344
32687
|
this.zip.file(slideRelsPath, this.builder.build(slideRelsData));
|
|
31345
32688
|
this.applySlideDrawingGuides(slideNode, slide);
|
|
31346
32689
|
this.deduplicateExtensionLists(xmlObj);
|
|
32690
|
+
if (slideContainsA16Element(slideNode)) {
|
|
32691
|
+
ensureA16NamespaceOnSlideRoot(slideNode);
|
|
32692
|
+
}
|
|
31347
32693
|
this.zip.file(slide.id, this.builder.build(xmlObj));
|
|
31348
32694
|
}
|
|
32695
|
+
/**
|
|
32696
|
+
* Re-wrap selected children with their original `<mc:AlternateContent>`
|
|
32697
|
+
* envelope (CC-4).
|
|
32698
|
+
*
|
|
32699
|
+
* Parsing merged the selected branch (Choice when supported, otherwise
|
|
32700
|
+
* Fallback) into the spTree's tag arrays. Without re-wrapping, dirty
|
|
32701
|
+
* save would emit flat `<p:sp>`/`<p:pic>` etc. and drop the
|
|
32702
|
+
* `<mc:Fallback>` branch — losing legacy rendering for files originally
|
|
32703
|
+
* authored with newer-namespace features.
|
|
32704
|
+
*
|
|
32705
|
+
* Strategy: for each XmlObject in `collectors.*` that traces back to a
|
|
32706
|
+
* known AC block, group by block and:
|
|
32707
|
+
* 1. Remove the node from its flat collector / spTree array.
|
|
32708
|
+
* 2. Clone the original AC envelope.
|
|
32709
|
+
* 3. Replace the selected branch's `<{tag}>` children with the
|
|
32710
|
+
* live (possibly edited) nodes from the collectors.
|
|
32711
|
+
* 4. Leave the unselected branch verbatim.
|
|
32712
|
+
*
|
|
32713
|
+
* Final envelopes are appended to `spTree['mc:AlternateContent']`.
|
|
32714
|
+
*/
|
|
32715
|
+
reapplyAlternateContentEnvelopes(spTree, collectors) {
|
|
32716
|
+
const TAG_TO_COLLECTOR = {
|
|
32717
|
+
"p:sp": collectors.shapes,
|
|
32718
|
+
"p:pic": collectors.pics,
|
|
32719
|
+
"p:cxnSp": collectors.connectors,
|
|
32720
|
+
"p:graphicFrame": collectors.graphicFrames,
|
|
32721
|
+
"p:grpSp": collectors.groups,
|
|
32722
|
+
"p:contentPart": collectors.contentParts,
|
|
32723
|
+
// `model3d` does not flow through SHAPE_TREE_ELEMENT_TAGS, but the
|
|
32724
|
+
// AC pathway in OpenXML decks frequently uses Choice = p16:model3D
|
|
32725
|
+
// + Fallback = p:pic, so map it for completeness.
|
|
32726
|
+
"p16:model3D": collectors.model3ds
|
|
32727
|
+
};
|
|
32728
|
+
const blockGroups = /* @__PURE__ */ new Map();
|
|
32729
|
+
for (const tag of Object.keys(TAG_TO_COLLECTOR)) {
|
|
32730
|
+
const collector = TAG_TO_COLLECTOR[tag];
|
|
32731
|
+
if (!collector) {
|
|
32732
|
+
continue;
|
|
32733
|
+
}
|
|
32734
|
+
for (const node of collector) {
|
|
32735
|
+
const block = this.alternateContentBlockByRawXml.get(node);
|
|
32736
|
+
if (!block) {
|
|
32737
|
+
continue;
|
|
32738
|
+
}
|
|
32739
|
+
let entries = blockGroups.get(block);
|
|
32740
|
+
if (!entries) {
|
|
32741
|
+
entries = [];
|
|
32742
|
+
blockGroups.set(block, entries);
|
|
32743
|
+
}
|
|
32744
|
+
entries.push({ tag, node, collector });
|
|
32745
|
+
}
|
|
32746
|
+
}
|
|
32747
|
+
if (blockGroups.size === 0) {
|
|
32748
|
+
return;
|
|
32749
|
+
}
|
|
32750
|
+
const envelopes = [];
|
|
32751
|
+
for (const [block, entries] of blockGroups) {
|
|
32752
|
+
for (const entry of entries) {
|
|
32753
|
+
const idx = entry.collector.indexOf(entry.node);
|
|
32754
|
+
if (idx !== -1) {
|
|
32755
|
+
entry.collector.splice(idx, 1);
|
|
32756
|
+
}
|
|
32757
|
+
}
|
|
32758
|
+
const clonedAc = { ...block.rawAc };
|
|
32759
|
+
const liveByTag = /* @__PURE__ */ new Map();
|
|
32760
|
+
for (const entry of entries) {
|
|
32761
|
+
let arr = liveByTag.get(entry.tag);
|
|
32762
|
+
if (!arr) {
|
|
32763
|
+
arr = [];
|
|
32764
|
+
liveByTag.set(entry.tag, arr);
|
|
32765
|
+
}
|
|
32766
|
+
arr.push(entry.node);
|
|
32767
|
+
}
|
|
32768
|
+
if (block.selectedBranch === "choice") {
|
|
32769
|
+
const choices = this.ensureArray(clonedAc["mc:Choice"]);
|
|
32770
|
+
const targetIdx = block.choiceIndex ?? 0;
|
|
32771
|
+
const original = choices[targetIdx];
|
|
32772
|
+
if (original) {
|
|
32773
|
+
const rebuilt = { ...original };
|
|
32774
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32775
|
+
delete rebuilt[tag];
|
|
32776
|
+
}
|
|
32777
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32778
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32779
|
+
}
|
|
32780
|
+
choices[targetIdx] = rebuilt;
|
|
32781
|
+
clonedAc["mc:Choice"] = choices.length === 1 ? choices[0] : choices;
|
|
32782
|
+
}
|
|
32783
|
+
} else {
|
|
32784
|
+
const fallback = clonedAc["mc:Fallback"];
|
|
32785
|
+
if (fallback) {
|
|
32786
|
+
const rebuilt = { ...fallback };
|
|
32787
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32788
|
+
delete rebuilt[tag];
|
|
32789
|
+
}
|
|
32790
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32791
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32792
|
+
}
|
|
32793
|
+
clonedAc["mc:Fallback"] = rebuilt;
|
|
32794
|
+
}
|
|
32795
|
+
}
|
|
32796
|
+
envelopes.push(clonedAc);
|
|
32797
|
+
}
|
|
32798
|
+
spTree["p:sp"] = collectors.shapes;
|
|
32799
|
+
spTree["p:pic"] = collectors.pics;
|
|
32800
|
+
spTree["p:cxnSp"] = collectors.connectors;
|
|
32801
|
+
spTree["p:graphicFrame"] = collectors.graphicFrames;
|
|
32802
|
+
if (collectors.groups.length > 0) {
|
|
32803
|
+
spTree["p:grpSp"] = collectors.groups;
|
|
32804
|
+
} else {
|
|
32805
|
+
delete spTree["p:grpSp"];
|
|
32806
|
+
}
|
|
32807
|
+
if (collectors.contentParts.length > 0) {
|
|
32808
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32809
|
+
} else {
|
|
32810
|
+
delete spTree["p:contentPart"];
|
|
32811
|
+
}
|
|
32812
|
+
if (collectors.model3ds.length > 0) {
|
|
32813
|
+
spTree["p16:model3D"] = collectors.model3ds;
|
|
32814
|
+
} else {
|
|
32815
|
+
delete spTree["p16:model3D"];
|
|
32816
|
+
}
|
|
32817
|
+
spTree["mc:AlternateContent"] = envelopes.length === 1 ? envelopes[0] : envelopes;
|
|
32818
|
+
}
|
|
32819
|
+
};
|
|
32820
|
+
|
|
32821
|
+
// src/core/core/runtime/PptxHandlerRuntimeSaveTheme.ts
|
|
32822
|
+
var PptxHandlerRuntime34 = class extends PptxHandlerRuntime33 {
|
|
32823
|
+
/**
|
|
32824
|
+
* Mark a theme path as dirty so the save pipeline will regenerate
|
|
32825
|
+
* the theme XML from in-memory state. Optional — without this the
|
|
32826
|
+
* original XML is preserved verbatim on save (C-H3).
|
|
32827
|
+
*/
|
|
32828
|
+
markThemeDirty(themePath) {
|
|
32829
|
+
this.dirtyThemePaths.add(themePath);
|
|
32830
|
+
}
|
|
32831
|
+
/**
|
|
32832
|
+
* Mark all known theme paths dirty in one call.
|
|
32833
|
+
*/
|
|
32834
|
+
markAllThemesDirty() {
|
|
32835
|
+
for (const themePath of this.originalThemeXmlByPath.keys()) {
|
|
32836
|
+
this.dirtyThemePaths.add(themePath);
|
|
32837
|
+
}
|
|
32838
|
+
for (const themePath of this.masterThemePaths.values()) {
|
|
32839
|
+
this.dirtyThemePaths.add(themePath);
|
|
32840
|
+
}
|
|
32841
|
+
}
|
|
32842
|
+
/**
|
|
32843
|
+
* Persist all theme parts during save. Called from the save pipeline
|
|
32844
|
+
* after master / layout XML have been flushed and before
|
|
32845
|
+
* presentation.xml is serialized.
|
|
32846
|
+
*
|
|
32847
|
+
* Order of operations per theme path:
|
|
32848
|
+
*
|
|
32849
|
+
* 1. If the path is *not* in {@link dirtyThemePaths}, the existing
|
|
32850
|
+
* ZIP entry is already correct — no-op. (Original XML was placed
|
|
32851
|
+
* into the ZIP at load time.)
|
|
32852
|
+
* 2. If the path is dirty, build a fresh `<a:theme>` document from
|
|
32853
|
+
* in-memory state and the captured raw subtrees, then overwrite
|
|
32854
|
+
* the ZIP entry.
|
|
32855
|
+
*/
|
|
32856
|
+
async persistThemeParts() {
|
|
32857
|
+
const seenThemePaths = /* @__PURE__ */ new Set();
|
|
32858
|
+
for (const [masterPath, themePath] of this.masterThemePaths.entries()) {
|
|
32859
|
+
if (!themePath) {
|
|
32860
|
+
continue;
|
|
32861
|
+
}
|
|
32862
|
+
seenThemePaths.add(themePath);
|
|
32863
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32864
|
+
continue;
|
|
32865
|
+
}
|
|
32866
|
+
const themeXml2 = this.buildThemeXml(themePath, masterPath);
|
|
32867
|
+
if (themeXml2) {
|
|
32868
|
+
this.zip.file(themePath, themeXml2);
|
|
32869
|
+
}
|
|
32870
|
+
}
|
|
32871
|
+
for (const [themePath] of this.originalThemeXmlByPath.entries()) {
|
|
32872
|
+
if (seenThemePaths.has(themePath)) {
|
|
32873
|
+
continue;
|
|
32874
|
+
}
|
|
32875
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32876
|
+
continue;
|
|
32877
|
+
}
|
|
32878
|
+
const themeXml2 = this.buildThemeXml(themePath, void 0);
|
|
32879
|
+
if (themeXml2) {
|
|
32880
|
+
this.zip.file(themePath, themeXml2);
|
|
32881
|
+
}
|
|
32882
|
+
}
|
|
32883
|
+
}
|
|
32884
|
+
/**
|
|
32885
|
+
* Build a complete `<a:theme>` XML document from in-memory state.
|
|
32886
|
+
* Returns the serialized XML string (with XML prolog), or `undefined`
|
|
32887
|
+
* if there is no source data to emit.
|
|
32888
|
+
*
|
|
32889
|
+
* - Color scheme: built from per-master color map (or global fallback).
|
|
32890
|
+
* - Font scheme: built from per-master font map + per-script entries.
|
|
32891
|
+
* - Format scheme: re-emit the original XML subtree if available; else
|
|
32892
|
+
* build a minimal scheme from {@link themeFormatScheme}.
|
|
32893
|
+
* - objectDefaults / extraClrSchemeLst / custClrLst / extLst: re-emit
|
|
32894
|
+
* captured raw subtrees.
|
|
32895
|
+
*/
|
|
32896
|
+
buildThemeXml(themePath, masterPath) {
|
|
32897
|
+
const colorMap = masterPath && this.masterThemeColorMaps.get(masterPath) || this.globalThemeColorMapSnapshot || this.themeColorMap;
|
|
32898
|
+
const fontMap = masterPath && this.masterThemeFontMaps.get(masterPath) || this.globalThemeFontMapSnapshot || this.themeFontMap;
|
|
32899
|
+
const themeName = this.masterThemeNames.get(themePath) || "Office Theme";
|
|
32900
|
+
const colorSchemeName = this.masterThemeColorSchemeNames.get(themePath) || themeName;
|
|
32901
|
+
const fontSchemeName = this.masterThemeFontSchemeNames.get(themePath) || themeName;
|
|
32902
|
+
const majorScripts = this.masterThemeMajorFontScripts.get(themePath) || {};
|
|
32903
|
+
const minorScripts = this.masterThemeMinorFontScripts.get(themePath) || {};
|
|
32904
|
+
const clrScheme = this.buildClrSchemeObject(colorSchemeName, colorMap);
|
|
32905
|
+
const fontScheme = this.buildFontSchemeObject(
|
|
32906
|
+
fontSchemeName,
|
|
32907
|
+
fontMap,
|
|
32908
|
+
majorScripts,
|
|
32909
|
+
minorScripts
|
|
32910
|
+
);
|
|
32911
|
+
const fmtScheme = this.extractRawSubtreeFromOriginal(themePath, [
|
|
32912
|
+
"a:theme",
|
|
32913
|
+
"a:themeElements",
|
|
32914
|
+
"a:fmtScheme"
|
|
32915
|
+
]);
|
|
32916
|
+
const themeElements = {
|
|
32917
|
+
"a:clrScheme": clrScheme,
|
|
32918
|
+
"a:fontScheme": fontScheme
|
|
32919
|
+
};
|
|
32920
|
+
if (fmtScheme !== void 0) {
|
|
32921
|
+
themeElements["a:fmtScheme"] = fmtScheme;
|
|
32922
|
+
} else {
|
|
32923
|
+
themeElements["a:fmtScheme"] = this.buildMinimalFmtScheme(themeName);
|
|
32924
|
+
}
|
|
32925
|
+
const themeRoot = {
|
|
32926
|
+
"@_xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
32927
|
+
"@_name": themeName,
|
|
32928
|
+
"a:themeElements": themeElements
|
|
32929
|
+
};
|
|
32930
|
+
const objectDefaults = this.masterThemeObjectDefaults.get(themePath);
|
|
32931
|
+
if (objectDefaults && (objectDefaults.spDef || objectDefaults.lnDef || objectDefaults.txDef)) {
|
|
32932
|
+
const od = {};
|
|
32933
|
+
if (objectDefaults.spDef !== void 0) {
|
|
32934
|
+
od["a:spDef"] = objectDefaults.spDef;
|
|
32935
|
+
}
|
|
32936
|
+
if (objectDefaults.lnDef !== void 0) {
|
|
32937
|
+
od["a:lnDef"] = objectDefaults.lnDef;
|
|
32938
|
+
}
|
|
32939
|
+
if (objectDefaults.txDef !== void 0) {
|
|
32940
|
+
od["a:txDef"] = objectDefaults.txDef;
|
|
32941
|
+
}
|
|
32942
|
+
themeRoot["a:objectDefaults"] = od;
|
|
32943
|
+
} else {
|
|
32944
|
+
themeRoot["a:objectDefaults"] = {};
|
|
32945
|
+
}
|
|
32946
|
+
const extraClr = this.masterThemeExtraClrSchemeLst.get(themePath);
|
|
32947
|
+
themeRoot["a:extraClrSchemeLst"] = extraClr !== void 0 ? extraClr : {};
|
|
32948
|
+
const custClr = this.masterThemeCustClrLst.get(themePath);
|
|
32949
|
+
if (custClr !== void 0) {
|
|
32950
|
+
themeRoot["a:custClrLst"] = custClr;
|
|
32951
|
+
}
|
|
32952
|
+
const themeExt = this.masterThemeExtLst.get(themePath);
|
|
32953
|
+
if (themeExt !== void 0) {
|
|
32954
|
+
themeRoot["a:extLst"] = themeExt;
|
|
32955
|
+
}
|
|
32956
|
+
const doc = {
|
|
32957
|
+
"?xml": { "@_version": "1.0", "@_encoding": "UTF-8", "@_standalone": "yes" },
|
|
32958
|
+
"a:theme": themeRoot
|
|
32959
|
+
};
|
|
32960
|
+
try {
|
|
32961
|
+
return this.builder.build(doc);
|
|
32962
|
+
} catch (error) {
|
|
32963
|
+
console.warn(`Failed to build theme XML for ${themePath}:`, error);
|
|
32964
|
+
return void 0;
|
|
32965
|
+
}
|
|
32966
|
+
}
|
|
32967
|
+
/**
|
|
32968
|
+
* Build the `a:clrScheme` XmlObject from a colour map. Each slot
|
|
32969
|
+
* value is interpreted as either a `#RRGGBB` srgb hex or a known
|
|
32970
|
+
* sysClr token (currently always emitted as srgbClr — the in-memory
|
|
32971
|
+
* map is hex-typed; sysClr round-trip belongs to the broader C-H3
|
|
32972
|
+
* fix to preserve original color XML and is out of scope here).
|
|
32973
|
+
*/
|
|
32974
|
+
buildClrSchemeObject(schemeName, colorMap) {
|
|
32975
|
+
const slot = (key) => {
|
|
32976
|
+
const hex = String(colorMap[key] || "").replace(/^#/, "");
|
|
32977
|
+
const srgb = hex.length === 6 ? hex.toUpperCase() : "000000";
|
|
32978
|
+
return { "a:srgbClr": { "@_val": srgb } };
|
|
32979
|
+
};
|
|
32980
|
+
return {
|
|
32981
|
+
"@_name": schemeName,
|
|
32982
|
+
"a:dk1": slot("dk1"),
|
|
32983
|
+
"a:lt1": slot("lt1"),
|
|
32984
|
+
"a:dk2": slot("dk2"),
|
|
32985
|
+
"a:lt2": slot("lt2"),
|
|
32986
|
+
"a:accent1": slot("accent1"),
|
|
32987
|
+
"a:accent2": slot("accent2"),
|
|
32988
|
+
"a:accent3": slot("accent3"),
|
|
32989
|
+
"a:accent4": slot("accent4"),
|
|
32990
|
+
"a:accent5": slot("accent5"),
|
|
32991
|
+
"a:accent6": slot("accent6"),
|
|
32992
|
+
"a:hlink": slot("hlink"),
|
|
32993
|
+
"a:folHlink": slot("folHlink")
|
|
32994
|
+
};
|
|
32995
|
+
}
|
|
32996
|
+
/**
|
|
32997
|
+
* Build the `a:fontScheme` XmlObject from a font map plus per-script
|
|
32998
|
+
* font tables.
|
|
32999
|
+
*
|
|
33000
|
+
* Phase 4 Stream A / M4.
|
|
33001
|
+
*/
|
|
33002
|
+
buildFontSchemeObject(schemeName, fontMap, majorScripts, minorScripts) {
|
|
33003
|
+
const buildFontGroup = (latinKey, eaKey, csKey, scripts) => {
|
|
33004
|
+
const group = {
|
|
33005
|
+
"a:latin": { "@_typeface": fontMap[latinKey] || "Calibri" },
|
|
33006
|
+
"a:ea": { "@_typeface": fontMap[eaKey] || "" },
|
|
33007
|
+
"a:cs": { "@_typeface": fontMap[csKey] || "" }
|
|
33008
|
+
};
|
|
33009
|
+
const scriptKeys = Object.keys(scripts);
|
|
33010
|
+
if (scriptKeys.length > 0) {
|
|
33011
|
+
const fontEntries = scriptKeys.map((script) => ({
|
|
33012
|
+
"@_script": script,
|
|
33013
|
+
"@_typeface": scripts[script]
|
|
33014
|
+
}));
|
|
33015
|
+
group["a:font"] = fontEntries.length === 1 ? fontEntries[0] : fontEntries;
|
|
33016
|
+
}
|
|
33017
|
+
return group;
|
|
33018
|
+
};
|
|
33019
|
+
return {
|
|
33020
|
+
"@_name": schemeName,
|
|
33021
|
+
"a:majorFont": buildFontGroup("mj-lt", "mj-ea", "mj-cs", majorScripts),
|
|
33022
|
+
"a:minorFont": buildFontGroup("mn-lt", "mn-ea", "mn-cs", minorScripts)
|
|
33023
|
+
};
|
|
33024
|
+
}
|
|
33025
|
+
/**
|
|
33026
|
+
* Re-parse the original theme XML and pluck out a subtree by path,
|
|
33027
|
+
* returning the raw parser object. Returns `undefined` when the
|
|
33028
|
+
* original is missing or the path doesn't exist.
|
|
33029
|
+
*
|
|
33030
|
+
* Used to preserve `a:fmtScheme` byte-for-byte through a regenerate
|
|
33031
|
+
* round-trip, since the in-memory PptxThemeFormatScheme is lossy.
|
|
33032
|
+
*/
|
|
33033
|
+
extractRawSubtreeFromOriginal(themePath, path2) {
|
|
33034
|
+
const original = this.originalThemeXmlByPath.get(themePath);
|
|
33035
|
+
if (!original) {
|
|
33036
|
+
return void 0;
|
|
33037
|
+
}
|
|
33038
|
+
try {
|
|
33039
|
+
const parsed = this.parser.parse(original);
|
|
33040
|
+
let cursor = parsed;
|
|
33041
|
+
for (const segment of path2) {
|
|
33042
|
+
if (cursor && typeof cursor === "object" && segment in cursor) {
|
|
33043
|
+
cursor = cursor[segment];
|
|
33044
|
+
} else {
|
|
33045
|
+
return void 0;
|
|
33046
|
+
}
|
|
33047
|
+
}
|
|
33048
|
+
return cursor;
|
|
33049
|
+
} catch {
|
|
33050
|
+
return void 0;
|
|
33051
|
+
}
|
|
33052
|
+
}
|
|
33053
|
+
/**
|
|
33054
|
+
* Last-resort minimal `<a:fmtScheme>` body. Mirrors the SDK new-deck
|
|
33055
|
+
* builder's output for new presentations, scaled down to the smallest
|
|
33056
|
+
* schema-valid form.
|
|
33057
|
+
*/
|
|
33058
|
+
buildMinimalFmtScheme(name) {
|
|
33059
|
+
const phClrSolid = { "a:solidFill": { "a:schemeClr": { "@_val": "phClr" } } };
|
|
33060
|
+
return {
|
|
33061
|
+
"@_name": name,
|
|
33062
|
+
"a:fillStyleLst": {
|
|
33063
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33064
|
+
"a:gradFill": []
|
|
33065
|
+
},
|
|
33066
|
+
"a:lnStyleLst": {
|
|
33067
|
+
"a:ln": [
|
|
33068
|
+
{
|
|
33069
|
+
"@_w": "6350",
|
|
33070
|
+
"@_cap": "flat",
|
|
33071
|
+
"@_cmpd": "sng",
|
|
33072
|
+
"@_algn": "ctr",
|
|
33073
|
+
...phClrSolid,
|
|
33074
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33075
|
+
"a:miter": { "@_lim": "800000" }
|
|
33076
|
+
},
|
|
33077
|
+
{
|
|
33078
|
+
"@_w": "12700",
|
|
33079
|
+
"@_cap": "flat",
|
|
33080
|
+
"@_cmpd": "sng",
|
|
33081
|
+
"@_algn": "ctr",
|
|
33082
|
+
...phClrSolid,
|
|
33083
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33084
|
+
"a:miter": { "@_lim": "800000" }
|
|
33085
|
+
},
|
|
33086
|
+
{
|
|
33087
|
+
"@_w": "19050",
|
|
33088
|
+
"@_cap": "flat",
|
|
33089
|
+
"@_cmpd": "sng",
|
|
33090
|
+
"@_algn": "ctr",
|
|
33091
|
+
...phClrSolid,
|
|
33092
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33093
|
+
"a:miter": { "@_lim": "800000" }
|
|
33094
|
+
}
|
|
33095
|
+
]
|
|
33096
|
+
},
|
|
33097
|
+
"a:effectStyleLst": {
|
|
33098
|
+
"a:effectStyle": [{ "a:effectLst": {} }, { "a:effectLst": {} }, { "a:effectLst": {} }]
|
|
33099
|
+
},
|
|
33100
|
+
"a:bgFillStyleLst": {
|
|
33101
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33102
|
+
"a:gradFill": []
|
|
33103
|
+
}
|
|
33104
|
+
};
|
|
33105
|
+
}
|
|
31349
33106
|
};
|
|
31350
33107
|
|
|
31351
33108
|
// src/core/core/runtime/PptxHandlerRuntimeSavePipeline.ts
|
|
31352
|
-
var
|
|
33109
|
+
var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime34 {
|
|
31353
33110
|
/**
|
|
31354
33111
|
* Resolve the effective conformance class for this save operation.
|
|
31355
33112
|
*
|
|
@@ -31436,6 +33193,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31436
33193
|
for (const [masterPath, masterXmlObj] of this.masterXmlMap.entries()) {
|
|
31437
33194
|
this.zip.file(masterPath, this.builder.build(masterXmlObj));
|
|
31438
33195
|
}
|
|
33196
|
+
await this.persistThemeParts();
|
|
31439
33197
|
await this.applyEmbeddedFontPreservation(options?.embeddedFonts);
|
|
31440
33198
|
if (this.presentationData) {
|
|
31441
33199
|
this.presentationSaveBuilder.applySaveOptions({
|
|
@@ -31525,7 +33283,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31525
33283
|
};
|
|
31526
33284
|
|
|
31527
33285
|
// src/core/core/runtime/PptxHandlerRuntimeElementParsing.ts
|
|
31528
|
-
var
|
|
33286
|
+
var PptxHandlerRuntime36 = class _PptxHandlerRuntime extends PptxHandlerRuntime35 {
|
|
31529
33287
|
/**
|
|
31530
33288
|
* Parse media data (video/audio path and MIME type) from graphic frame data.
|
|
31531
33289
|
*/
|
|
@@ -31747,7 +33505,7 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31747
33505
|
};
|
|
31748
33506
|
|
|
31749
33507
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderLookup.ts
|
|
31750
|
-
var
|
|
33508
|
+
var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
31751
33509
|
findPlaceholderInShapeTree(spTree, expected) {
|
|
31752
33510
|
if (!spTree) {
|
|
31753
33511
|
return void 0;
|
|
@@ -31900,7 +33658,7 @@ var PptxHandlerRuntime36 = class extends PptxHandlerRuntime35 {
|
|
|
31900
33658
|
};
|
|
31901
33659
|
|
|
31902
33660
|
// src/core/core/runtime/PptxHandlerRuntimeGeometryParsing.ts
|
|
31903
|
-
var
|
|
33661
|
+
var PptxHandlerRuntime38 = class extends PptxHandlerRuntime37 {
|
|
31904
33662
|
parseGeometryAdjustments(prstGeom) {
|
|
31905
33663
|
if (!prstGeom) {
|
|
31906
33664
|
return void 0;
|
|
@@ -32009,6 +33767,103 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
32009
33767
|
}
|
|
32010
33768
|
return handles.length > 0 ? handles : void 0;
|
|
32011
33769
|
}
|
|
33770
|
+
/**
|
|
33771
|
+
* Extract `a:gdLst`/`a:ahLst`/`a:cxnLst`/`a:rect` raw XML from a `a:custGeom`
|
|
33772
|
+
* node so they can be re-emitted on save when the geometry is edited.
|
|
33773
|
+
* Returns `undefined` when none of these auxiliary children carry data.
|
|
33774
|
+
*/
|
|
33775
|
+
extractCustomGeometryRawData(custGeom) {
|
|
33776
|
+
if (!custGeom) {
|
|
33777
|
+
return void 0;
|
|
33778
|
+
}
|
|
33779
|
+
const isNonEmpty = (node) => {
|
|
33780
|
+
if (node === void 0 || node === null) {
|
|
33781
|
+
return false;
|
|
33782
|
+
}
|
|
33783
|
+
if (typeof node !== "object") {
|
|
33784
|
+
return true;
|
|
33785
|
+
}
|
|
33786
|
+
return Object.keys(node).length > 0;
|
|
33787
|
+
};
|
|
33788
|
+
const result = {};
|
|
33789
|
+
const gdLst = custGeom["a:gdLst"];
|
|
33790
|
+
if (isNonEmpty(gdLst)) {
|
|
33791
|
+
result.gdLstXml = gdLst;
|
|
33792
|
+
}
|
|
33793
|
+
const ahLst = custGeom["a:ahLst"];
|
|
33794
|
+
if (isNonEmpty(ahLst)) {
|
|
33795
|
+
result.ahLstXml = ahLst;
|
|
33796
|
+
}
|
|
33797
|
+
const cxnLst = custGeom["a:cxnLst"];
|
|
33798
|
+
if (isNonEmpty(cxnLst)) {
|
|
33799
|
+
result.cxnLstXml = cxnLst;
|
|
33800
|
+
}
|
|
33801
|
+
const rect = custGeom["a:rect"];
|
|
33802
|
+
if (isNonEmpty(rect)) {
|
|
33803
|
+
result.rectXml = rect;
|
|
33804
|
+
}
|
|
33805
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
33806
|
+
}
|
|
33807
|
+
/**
|
|
33808
|
+
* Build structured `CustomGeometryPath[]` from a parsed `a:custGeom` node,
|
|
33809
|
+
* including per-path `@fill`/`@stroke`/`@extrusionOk` attributes so they
|
|
33810
|
+
* survive a round-trip when the path list is later regenerated.
|
|
33811
|
+
*
|
|
33812
|
+
* Falls back to SVG → structured-path conversion when no structured path
|
|
33813
|
+
* info is otherwise available.
|
|
33814
|
+
*/
|
|
33815
|
+
buildStructuredCustomGeometryPaths(custGeom, pathData, pathWidth, pathHeight) {
|
|
33816
|
+
if (!custGeom) {
|
|
33817
|
+
return void 0;
|
|
33818
|
+
}
|
|
33819
|
+
const pathLst = custGeom["a:pathLst"];
|
|
33820
|
+
if (!pathLst) {
|
|
33821
|
+
return void 0;
|
|
33822
|
+
}
|
|
33823
|
+
const pathNodes = this.ensureArray(pathLst["a:path"]);
|
|
33824
|
+
if (pathNodes.length === 0) {
|
|
33825
|
+
return void 0;
|
|
33826
|
+
}
|
|
33827
|
+
const segments = svgToCustomGeometryPaths(pathData, pathWidth, pathHeight);
|
|
33828
|
+
if (segments.length === 0) {
|
|
33829
|
+
return void 0;
|
|
33830
|
+
}
|
|
33831
|
+
const validFillModes = /* @__PURE__ */ new Set([
|
|
33832
|
+
"norm",
|
|
33833
|
+
"lighten",
|
|
33834
|
+
"lightenLess",
|
|
33835
|
+
"darken",
|
|
33836
|
+
"darkenLess",
|
|
33837
|
+
"none"
|
|
33838
|
+
]);
|
|
33839
|
+
const parseBoolAttr2 = (value) => {
|
|
33840
|
+
if (value === void 0 || value === null || value === "") {
|
|
33841
|
+
return void 0;
|
|
33842
|
+
}
|
|
33843
|
+
if (value === "1" || value === "true" || value === true) {
|
|
33844
|
+
return true;
|
|
33845
|
+
}
|
|
33846
|
+
if (value === "0" || value === "false" || value === false) {
|
|
33847
|
+
return false;
|
|
33848
|
+
}
|
|
33849
|
+
return void 0;
|
|
33850
|
+
};
|
|
33851
|
+
const target = segments[0];
|
|
33852
|
+
const firstNode = pathNodes[0];
|
|
33853
|
+
const fillAttr = String(firstNode["@_fill"] ?? "").trim();
|
|
33854
|
+
if (validFillModes.has(fillAttr)) {
|
|
33855
|
+
target.fillMode = fillAttr;
|
|
33856
|
+
}
|
|
33857
|
+
const strokeAttr = parseBoolAttr2(firstNode["@_stroke"]);
|
|
33858
|
+
if (strokeAttr !== void 0) {
|
|
33859
|
+
target.stroke = strokeAttr;
|
|
33860
|
+
}
|
|
33861
|
+
const extrusionAttr = parseBoolAttr2(firstNode["@_extrusionOk"]);
|
|
33862
|
+
if (extrusionAttr !== void 0) {
|
|
33863
|
+
target.extrusionOk = extrusionAttr;
|
|
33864
|
+
}
|
|
33865
|
+
return segments;
|
|
33866
|
+
}
|
|
32012
33867
|
parseCustomGeometry(custGeom, shapeWidth, shapeHeight) {
|
|
32013
33868
|
if (!custGeom || !custGeom["a:pathLst"] || !custGeom["a:pathLst"]?.["a:path"]) {
|
|
32014
33869
|
return null;
|
|
@@ -32077,7 +33932,7 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
32077
33932
|
};
|
|
32078
33933
|
|
|
32079
33934
|
// src/core/core/runtime/PptxHandlerRuntimeShapeImageFill.ts
|
|
32080
|
-
var
|
|
33935
|
+
var PptxHandlerRuntime39 = class _PptxHandlerRuntime extends PptxHandlerRuntime38 {
|
|
32081
33936
|
/**
|
|
32082
33937
|
* Parse a shape that has an image fill (a:blipFill inside spPr)
|
|
32083
33938
|
* This handles shapes like rectangles filled with images (e.g., wood texture backgrounds)
|
|
@@ -32277,7 +34132,7 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
32277
34132
|
};
|
|
32278
34133
|
|
|
32279
34134
|
// src/core/core/runtime/PptxHandlerRuntimeTextDefaults.ts
|
|
32280
|
-
var
|
|
34135
|
+
var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
32281
34136
|
/**
|
|
32282
34137
|
* Apply {@link PlaceholderDefaults} body-level properties to a
|
|
32283
34138
|
* {@link TextStyle} as fallback values (only sets fields that are
|
|
@@ -32401,7 +34256,7 @@ var PptxHandlerRuntime39 = class extends PptxHandlerRuntime38 {
|
|
|
32401
34256
|
};
|
|
32402
34257
|
|
|
32403
34258
|
// src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
|
|
32404
|
-
var
|
|
34259
|
+
var PptxHandlerRuntime41 = class extends PptxHandlerRuntime40 {
|
|
32405
34260
|
resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
|
|
32406
34261
|
if (!paragraph) {
|
|
32407
34262
|
return null;
|
|
@@ -32432,7 +34287,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32432
34287
|
if (candidate["a:buNone"]) {
|
|
32433
34288
|
return { none: true };
|
|
32434
34289
|
}
|
|
32435
|
-
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"]) {
|
|
34290
|
+
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"] || candidate["a:buFontTx"] !== void 0 || candidate["a:buClrTx"] !== void 0 || candidate["a:buSzTx"] !== void 0) {
|
|
32436
34291
|
resolvedBulletProps = candidate;
|
|
32437
34292
|
break;
|
|
32438
34293
|
}
|
|
@@ -32446,6 +34301,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32446
34301
|
}
|
|
32447
34302
|
const buFont = resolvedBulletProps["a:buFont"];
|
|
32448
34303
|
const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
|
|
34304
|
+
const fontInherit = resolvedBulletProps["a:buFontTx"] !== void 0;
|
|
32449
34305
|
const buSzPct = resolvedBulletProps["a:buSzPct"];
|
|
32450
34306
|
let sizePercent;
|
|
32451
34307
|
if (buSzPct?.["@_val"] !== void 0) {
|
|
@@ -32462,6 +34318,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32462
34318
|
sizePts = ptsRaw / 100;
|
|
32463
34319
|
}
|
|
32464
34320
|
}
|
|
34321
|
+
const sizeInherit = resolvedBulletProps["a:buSzTx"] !== void 0;
|
|
32465
34322
|
const buClr = resolvedBulletProps["a:buClr"];
|
|
32466
34323
|
let color;
|
|
32467
34324
|
if (buClr) {
|
|
@@ -32470,6 +34327,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32470
34327
|
color = String(srgb["@_val"]);
|
|
32471
34328
|
}
|
|
32472
34329
|
}
|
|
34330
|
+
const colorInherit = resolvedBulletProps["a:buClrTx"] !== void 0;
|
|
32473
34331
|
const bulletChar = String(
|
|
32474
34332
|
resolvedBulletProps["a:buChar"]?.["@_char"] || ""
|
|
32475
34333
|
);
|
|
@@ -32479,7 +34337,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32479
34337
|
fontFamily,
|
|
32480
34338
|
sizePercent,
|
|
32481
34339
|
sizePts,
|
|
32482
|
-
color
|
|
34340
|
+
color,
|
|
34341
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34342
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34343
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32483
34344
|
};
|
|
32484
34345
|
}
|
|
32485
34346
|
const autoNum = resolvedBulletProps["a:buAutoNum"];
|
|
@@ -32494,7 +34355,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32494
34355
|
fontFamily,
|
|
32495
34356
|
sizePercent,
|
|
32496
34357
|
sizePts,
|
|
32497
|
-
color
|
|
34358
|
+
color,
|
|
34359
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34360
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34361
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32498
34362
|
};
|
|
32499
34363
|
}
|
|
32500
34364
|
const buBlip = resolvedBulletProps["a:buBlip"];
|
|
@@ -32606,7 +34470,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32606
34470
|
};
|
|
32607
34471
|
|
|
32608
34472
|
// src/core/core/runtime/PptxHandlerRuntimeShapeBodyParsing.ts
|
|
32609
|
-
var
|
|
34473
|
+
var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime41 {
|
|
32610
34474
|
/**
|
|
32611
34475
|
* Parse `a:spLocks` attributes into a structured {@link PptxShapeLocks} object.
|
|
32612
34476
|
* Returns `undefined` when the node is absent or contains no lock attributes.
|
|
@@ -32701,7 +34565,8 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32701
34565
|
if (Number.isFinite(spcColRaw) && spcColRaw > 0) {
|
|
32702
34566
|
textStyle.columnSpacing = spcColRaw / _PptxHandlerRuntime.EMU_PER_PX;
|
|
32703
34567
|
}
|
|
32704
|
-
const
|
|
34568
|
+
const hOverflowRaw = bodyPr["@_horzOverflow"] ?? bodyPr["@_hOverflow"];
|
|
34569
|
+
const hOverflow = String(hOverflowRaw || "").trim();
|
|
32705
34570
|
if (hOverflow === "overflow" || hOverflow === "clip") {
|
|
32706
34571
|
textStyle.hOverflow = hOverflow;
|
|
32707
34572
|
}
|
|
@@ -32884,7 +34749,7 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32884
34749
|
};
|
|
32885
34750
|
|
|
32886
34751
|
// src/core/core/runtime/PptxHandlerRuntimeShapeTextParsing.ts
|
|
32887
|
-
var
|
|
34752
|
+
var PptxHandlerRuntime43 = class _PptxHandlerRuntime extends PptxHandlerRuntime42 {
|
|
32888
34753
|
/**
|
|
32889
34754
|
* Resolve paragraph-level styles (alignment, spacing, margins, tabs,
|
|
32890
34755
|
* level styles) for a single paragraph. Modifies `textStyle` in place
|
|
@@ -33066,7 +34931,7 @@ var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33066
34931
|
};
|
|
33067
34932
|
|
|
33068
34933
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParagraphContentParsing.ts
|
|
33069
|
-
var
|
|
34934
|
+
var PptxHandlerRuntime44 = class extends PptxHandlerRuntime43 {
|
|
33070
34935
|
/**
|
|
33071
34936
|
* Collect text content (runs, fields, equations, bullets) for a single
|
|
33072
34937
|
* paragraph and return text parts + segments. The returned `seedStyle`
|
|
@@ -33249,6 +35114,23 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33249
35114
|
parts.push("\n");
|
|
33250
35115
|
segments.push({ text: "\n", style: { ...mergedDefaultRunStyle } });
|
|
33251
35116
|
}
|
|
35117
|
+
const firstSegmentIndex = segments.length === 0 ? -1 : 0;
|
|
35118
|
+
if (firstSegmentIndex >= 0) {
|
|
35119
|
+
const pPrRaw = p["a:pPr"];
|
|
35120
|
+
const lvlRaw = pPrRaw?.["@_lvl"];
|
|
35121
|
+
if (lvlRaw !== void 0) {
|
|
35122
|
+
const lvlParsed = Number.parseInt(String(lvlRaw), 10);
|
|
35123
|
+
if (Number.isFinite(lvlParsed) && lvlParsed > 0) {
|
|
35124
|
+
segments[firstSegmentIndex].paragraphLevel = Math.min(Math.max(lvlParsed, 0), 8);
|
|
35125
|
+
}
|
|
35126
|
+
}
|
|
35127
|
+
const endParaRPrRaw = p["a:endParaRPr"];
|
|
35128
|
+
if (endParaRPrRaw && typeof endParaRPrRaw === "object") {
|
|
35129
|
+
segments[firstSegmentIndex].endParaRunProperties = {
|
|
35130
|
+
...endParaRPrRaw
|
|
35131
|
+
};
|
|
35132
|
+
}
|
|
35133
|
+
}
|
|
33252
35134
|
return { parts, segments, seedStyle };
|
|
33253
35135
|
}
|
|
33254
35136
|
/**
|
|
@@ -33358,7 +35240,7 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33358
35240
|
};
|
|
33359
35241
|
|
|
33360
35242
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParsing.ts
|
|
33361
|
-
var
|
|
35243
|
+
var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime44 {
|
|
33362
35244
|
parseShape(shape, id, slidePath) {
|
|
33363
35245
|
try {
|
|
33364
35246
|
const spPr = shape["p:spPr"];
|
|
@@ -33394,6 +35276,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33394
35276
|
let pathData;
|
|
33395
35277
|
let pathWidth;
|
|
33396
35278
|
let pathHeight;
|
|
35279
|
+
let customGeometryRawData;
|
|
33397
35280
|
const custGeom = effectiveSpPr?.["a:custGeom"];
|
|
33398
35281
|
if (custGeom) {
|
|
33399
35282
|
const customPath = this.parseCustomGeometry(
|
|
@@ -33406,6 +35289,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33406
35289
|
pathData = customPath.pathData;
|
|
33407
35290
|
pathWidth = customPath.pathWidth;
|
|
33408
35291
|
pathHeight = customPath.pathHeight;
|
|
35292
|
+
customGeometryRawData = this.extractCustomGeometryRawData(custGeom);
|
|
33409
35293
|
}
|
|
33410
35294
|
}
|
|
33411
35295
|
const geomNode = custGeom ?? effectiveSpPr?.["a:prstGeom"];
|
|
@@ -33563,7 +35447,8 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33563
35447
|
type: "shape",
|
|
33564
35448
|
pathData,
|
|
33565
35449
|
pathWidth,
|
|
33566
|
-
pathHeight
|
|
35450
|
+
pathHeight,
|
|
35451
|
+
customGeometryRawData
|
|
33567
35452
|
};
|
|
33568
35453
|
} catch (e) {
|
|
33569
35454
|
console.warn(`[pptx] Skipping shape element (${id}):`, e);
|
|
@@ -33573,7 +35458,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33573
35458
|
};
|
|
33574
35459
|
|
|
33575
35460
|
// src/core/core/runtime/PptxHandlerRuntimePictureParsing.ts
|
|
33576
|
-
var
|
|
35461
|
+
var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime45 {
|
|
33577
35462
|
async parsePicture(pic, id, slidePath) {
|
|
33578
35463
|
try {
|
|
33579
35464
|
const spPr = pic["p:spPr"];
|
|
@@ -33812,7 +35697,7 @@ var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33812
35697
|
};
|
|
33813
35698
|
|
|
33814
35699
|
// src/core/core/runtime/PptxHandlerRuntimeSpTreeParsing.ts
|
|
33815
|
-
var
|
|
35700
|
+
var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime46 {
|
|
33816
35701
|
/**
|
|
33817
35702
|
* Known element tag names that appear as direct children of `p:spTree`
|
|
33818
35703
|
* (or `p:grpSp`) and represent renderable shapes/objects.
|
|
@@ -34157,9 +36042,18 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34157
36042
|
* Unwrap mc:AlternateContent elements within a shape tree (or group),
|
|
34158
36043
|
* merging selected branch children into the parent element arrays.
|
|
34159
36044
|
* Delegates to the standalone alternate-content utility.
|
|
36045
|
+
*
|
|
36046
|
+
* Records each consumed AC envelope in {@link alternateContentBlockByRawXml}
|
|
36047
|
+
* so the save layer can re-emit the original `<mc:Choice>` /
|
|
36048
|
+
* `<mc:Fallback>` shape on dirty save (CC-4).
|
|
34160
36049
|
*/
|
|
34161
36050
|
unwrapAlternateContent(container) {
|
|
34162
|
-
unwrapAlternateContent(container);
|
|
36051
|
+
const blocks = unwrapAlternateContent(container);
|
|
36052
|
+
for (const block of blocks) {
|
|
36053
|
+
for (const ref of block.childRefs) {
|
|
36054
|
+
this.alternateContentBlockByRawXml.set(ref.node, block);
|
|
36055
|
+
}
|
|
36056
|
+
}
|
|
34163
36057
|
}
|
|
34164
36058
|
/**
|
|
34165
36059
|
* Forward declaration – implemented in PptxHandlerRuntimeGroupParsing.
|
|
@@ -34170,7 +36064,7 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34170
36064
|
};
|
|
34171
36065
|
|
|
34172
36066
|
// src/core/core/runtime/PptxHandlerRuntimeGroupParsing.ts
|
|
34173
|
-
var
|
|
36067
|
+
var PptxHandlerRuntime48 = class _PptxHandlerRuntime extends PptxHandlerRuntime47 {
|
|
34174
36068
|
async parseGroupShape(group, baseId, slidePath, rawXmlStr) {
|
|
34175
36069
|
const grpSpPr = group["p:grpSpPr"];
|
|
34176
36070
|
const xfrm = grpSpPr?.["a:xfrm"];
|
|
@@ -34343,7 +36237,7 @@ var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34343
36237
|
};
|
|
34344
36238
|
|
|
34345
36239
|
// src/core/core/runtime/PptxHandlerRuntimeSlideParsing.ts
|
|
34346
|
-
var
|
|
36240
|
+
var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
34347
36241
|
/**
|
|
34348
36242
|
* Parse text body from a connector shape (p:cxnSp > p:txBody).
|
|
34349
36243
|
* Uses the same text run extraction logic as regular shapes but
|
|
@@ -34455,7 +36349,7 @@ var PptxHandlerRuntime48 = class extends PptxHandlerRuntime47 {
|
|
|
34455
36349
|
};
|
|
34456
36350
|
|
|
34457
36351
|
// src/core/core/runtime/PptxHandlerRuntimeColorAndEffects.ts
|
|
34458
|
-
var
|
|
36352
|
+
var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
34459
36353
|
/**
|
|
34460
36354
|
* Forward declaration – implemented in PptxHandlerRuntimeThemeProcessing.
|
|
34461
36355
|
* Re-resolves gradient stops by substituting `phClr` with the given colour.
|
|
@@ -34496,8 +36390,9 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34496
36390
|
return void 0;
|
|
34497
36391
|
}
|
|
34498
36392
|
const resolvedKey = normalized === "phclr" ? "accent1" : normalized;
|
|
34499
|
-
|
|
34500
|
-
|
|
36393
|
+
const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
|
|
36394
|
+
if (overrideMap) {
|
|
36395
|
+
const remapped = overrideMap[resolvedKey];
|
|
34501
36396
|
if (remapped) {
|
|
34502
36397
|
return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
|
|
34503
36398
|
}
|
|
@@ -34580,7 +36475,7 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34580
36475
|
};
|
|
34581
36476
|
|
|
34582
36477
|
// src/core/core/runtime/PptxHandlerRuntimeBackgroundParsing.ts
|
|
34583
|
-
var
|
|
36478
|
+
var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
34584
36479
|
async extractBackgroundImage(slideXml2, slidePath, rootElement = "p:sld") {
|
|
34585
36480
|
try {
|
|
34586
36481
|
const bg = slideXml2[rootElement]?.["p:cSld"]?.["p:bg"];
|
|
@@ -34791,7 +36686,7 @@ var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
|
34791
36686
|
};
|
|
34792
36687
|
|
|
34793
36688
|
// src/core/core/runtime/PptxHandlerRuntimeSlideUtils.ts
|
|
34794
|
-
var
|
|
36689
|
+
var PptxHandlerRuntime52 = class extends PptxHandlerRuntime51 {
|
|
34795
36690
|
/**
|
|
34796
36691
|
* Retrieve the background gradient from a layout, falling back to master.
|
|
34797
36692
|
*/
|
|
@@ -34862,6 +36757,64 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34862
36757
|
}
|
|
34863
36758
|
return void 0;
|
|
34864
36759
|
}
|
|
36760
|
+
/**
|
|
36761
|
+
* Find the master file path referenced by a layout via its relationships.
|
|
36762
|
+
*/
|
|
36763
|
+
findMasterPathForLayoutBase(layoutPath) {
|
|
36764
|
+
const layoutRels = this.slideRelsMap.get(layoutPath);
|
|
36765
|
+
if (!layoutRels) {
|
|
36766
|
+
return void 0;
|
|
36767
|
+
}
|
|
36768
|
+
for (const [, target] of layoutRels.entries()) {
|
|
36769
|
+
if (target.includes("slideMaster")) {
|
|
36770
|
+
const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
|
|
36771
|
+
return target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
|
|
36772
|
+
}
|
|
36773
|
+
}
|
|
36774
|
+
return void 0;
|
|
36775
|
+
}
|
|
36776
|
+
/**
|
|
36777
|
+
* Switch the active master state (clrMap + theme color/font/format
|
|
36778
|
+
* scheme) so that scheme-colour resolution for the slide currently
|
|
36779
|
+
* being parsed walks through the correct master.
|
|
36780
|
+
*
|
|
36781
|
+
* Multi-master decks must resolve scheme colours against each slide's
|
|
36782
|
+
* own master rather than always against `masterFiles[0]`.
|
|
36783
|
+
*
|
|
36784
|
+
* Phase 2 Stream B / C-H4.
|
|
36785
|
+
*/
|
|
36786
|
+
async setActiveMasterForSlide(slidePath) {
|
|
36787
|
+
const layoutPath = this.findLayoutPathForSlide(slidePath);
|
|
36788
|
+
if (!layoutPath) {
|
|
36789
|
+
this.currentMasterClrMap = null;
|
|
36790
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36791
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36792
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36793
|
+
return;
|
|
36794
|
+
}
|
|
36795
|
+
if (!this.slideRelsMap.has(layoutPath)) {
|
|
36796
|
+
const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
|
|
36797
|
+
try {
|
|
36798
|
+
await this.loadSlideRelationships(layoutPath, layoutRelsPath);
|
|
36799
|
+
} catch {
|
|
36800
|
+
}
|
|
36801
|
+
}
|
|
36802
|
+
const masterPath = this.findMasterPathForLayoutBase(layoutPath);
|
|
36803
|
+
if (!masterPath) {
|
|
36804
|
+
this.currentMasterClrMap = null;
|
|
36805
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36806
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36807
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36808
|
+
return;
|
|
36809
|
+
}
|
|
36810
|
+
this.currentMasterClrMap = this.masterClrMaps.get(masterPath) ?? null;
|
|
36811
|
+
const masterColorMap = this.masterThemeColorMaps.get(masterPath);
|
|
36812
|
+
this.themeColorMap = masterColorMap ? { ...masterColorMap } : { ...this.globalThemeColorMapSnapshot };
|
|
36813
|
+
const masterFontMap = this.masterThemeFontMaps.get(masterPath);
|
|
36814
|
+
this.themeFontMap = masterFontMap ? { ...masterFontMap } : { ...this.globalThemeFontMapSnapshot };
|
|
36815
|
+
const masterFormatScheme = this.masterThemeFormatSchemes.get(masterPath);
|
|
36816
|
+
this.themeFormatScheme = masterFormatScheme ?? this.globalThemeFormatSchemeSnapshot;
|
|
36817
|
+
}
|
|
34865
36818
|
/**
|
|
34866
36819
|
* Extract the `p:bg/@showAnimation` flag from a slide's XML.
|
|
34867
36820
|
* Returns `true` when the background should animate, `false` when
|
|
@@ -35002,7 +36955,7 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
35002
36955
|
};
|
|
35003
36956
|
|
|
35004
36957
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderStyles.ts
|
|
35005
|
-
var
|
|
36958
|
+
var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime52 {
|
|
35006
36959
|
/**
|
|
35007
36960
|
* Parse a single `a:lvlXpPr` node into a structured
|
|
35008
36961
|
* {@link PlaceholderTextLevelStyle}.
|
|
@@ -35123,7 +37076,7 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35123
37076
|
};
|
|
35124
37077
|
|
|
35125
37078
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderDefaults.ts
|
|
35126
|
-
var
|
|
37079
|
+
var PptxHandlerRuntime54 = class _PptxHandlerRuntime extends PptxHandlerRuntime53 {
|
|
35127
37080
|
/**
|
|
35128
37081
|
* Extract structured {@link PlaceholderDefaults} from a layout or master
|
|
35129
37082
|
* shape that carries a `p:ph` element.
|
|
@@ -35266,7 +37219,118 @@ var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35266
37219
|
};
|
|
35267
37220
|
|
|
35268
37221
|
// src/core/core/runtime/PptxHandlerRuntimeMasterElements.ts
|
|
35269
|
-
|
|
37222
|
+
function parseHeaderFooterFlags(hf) {
|
|
37223
|
+
if (!hf) {
|
|
37224
|
+
return void 0;
|
|
37225
|
+
}
|
|
37226
|
+
const result = {};
|
|
37227
|
+
if (hf["@_hdr"] !== void 0) {
|
|
37228
|
+
result.hasHeader = String(hf["@_hdr"]) !== "0";
|
|
37229
|
+
}
|
|
37230
|
+
if (hf["@_ftr"] !== void 0) {
|
|
37231
|
+
result.hasFooter = String(hf["@_ftr"]) !== "0";
|
|
37232
|
+
}
|
|
37233
|
+
if (hf["@_dt"] !== void 0) {
|
|
37234
|
+
result.hasDateTime = String(hf["@_dt"]) !== "0";
|
|
37235
|
+
}
|
|
37236
|
+
if (hf["@_sldNum"] !== void 0) {
|
|
37237
|
+
result.hasSlideNumber = String(hf["@_sldNum"]) !== "0";
|
|
37238
|
+
}
|
|
37239
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
37240
|
+
}
|
|
37241
|
+
var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
37242
|
+
/**
|
|
37243
|
+
* Parse a `CT_TextListStyle` node (`a:defPPr` + `a:lvl1pPr` … `a:lvl9pPr`)
|
|
37244
|
+
* into a level-keyed style map. Used for `<p:txStyles>` children
|
|
37245
|
+
* (`p:titleStyle`, `p:bodyStyle`, `p:otherStyle`) — see ECMA-376 §19.3.1.52.
|
|
37246
|
+
*/
|
|
37247
|
+
parseTextListStyle(node) {
|
|
37248
|
+
if (!node) {
|
|
37249
|
+
return void 0;
|
|
37250
|
+
}
|
|
37251
|
+
const levels = {};
|
|
37252
|
+
const defParsed = this.parsePlaceholderLevelStyle(node["a:defPPr"]);
|
|
37253
|
+
if (defParsed) {
|
|
37254
|
+
levels[-1] = defParsed;
|
|
37255
|
+
}
|
|
37256
|
+
for (let lvl = 1; lvl <= 9; lvl++) {
|
|
37257
|
+
const parsed = this.parsePlaceholderLevelStyle(
|
|
37258
|
+
node[`a:lvl${lvl}pPr`]
|
|
37259
|
+
);
|
|
37260
|
+
if (parsed) {
|
|
37261
|
+
levels[lvl - 1] = parsed;
|
|
37262
|
+
}
|
|
37263
|
+
}
|
|
37264
|
+
return Object.keys(levels).length > 0 ? levels : void 0;
|
|
37265
|
+
}
|
|
37266
|
+
/**
|
|
37267
|
+
* Parse `<p:txStyles>` from a slide-master XML object into a structured
|
|
37268
|
+
* {@link PptxMasterTextStyles}. Used to populate `PptxSlideMaster.txStyles`
|
|
37269
|
+
* so the title/body/other text-style cascade (P-H1) is visible on the
|
|
37270
|
+
* typed model.
|
|
37271
|
+
*/
|
|
37272
|
+
parseMasterTxStyles(masterXml) {
|
|
37273
|
+
const txStyles = masterXml?.["p:txStyles"];
|
|
37274
|
+
if (!txStyles) {
|
|
37275
|
+
return void 0;
|
|
37276
|
+
}
|
|
37277
|
+
const titleStyle = this.parseTextListStyle(txStyles["p:titleStyle"]);
|
|
37278
|
+
const bodyStyle = this.parseTextListStyle(txStyles["p:bodyStyle"]);
|
|
37279
|
+
const otherStyle = this.parseTextListStyle(txStyles["p:otherStyle"]);
|
|
37280
|
+
if (!titleStyle && !bodyStyle && !otherStyle) {
|
|
37281
|
+
return void 0;
|
|
37282
|
+
}
|
|
37283
|
+
const result = {};
|
|
37284
|
+
if (titleStyle) {
|
|
37285
|
+
result.titleStyle = titleStyle;
|
|
37286
|
+
}
|
|
37287
|
+
if (bodyStyle) {
|
|
37288
|
+
result.bodyStyle = bodyStyle;
|
|
37289
|
+
}
|
|
37290
|
+
if (otherStyle) {
|
|
37291
|
+
result.otherStyle = otherStyle;
|
|
37292
|
+
}
|
|
37293
|
+
return result;
|
|
37294
|
+
}
|
|
37295
|
+
/**
|
|
37296
|
+
* Enrich an array of {@link PptxSlideMaster} entries (already produced by
|
|
37297
|
+
* `parseSlideMasters`) with parsed `<p:txStyles>`. Loads each master's XML
|
|
37298
|
+
* once, parses, and caches it in `masterXmlMap` for downstream consumers.
|
|
37299
|
+
*
|
|
37300
|
+
* Also stores the parsed result on the per-master cache so that the
|
|
37301
|
+
* inheritance chain in `applyMasterTextStyleCascade` can find it without
|
|
37302
|
+
* re-parsing.
|
|
37303
|
+
*/
|
|
37304
|
+
async enrichSlideMastersWithTxStyles(slideMasters) {
|
|
37305
|
+
for (const master of slideMasters) {
|
|
37306
|
+
try {
|
|
37307
|
+
let masterXmlObj = this.masterXmlMap.get(master.path);
|
|
37308
|
+
if (!masterXmlObj) {
|
|
37309
|
+
const xmlStr = await this.zip.file(master.path)?.async("string");
|
|
37310
|
+
if (!xmlStr) {
|
|
37311
|
+
continue;
|
|
37312
|
+
}
|
|
37313
|
+
masterXmlObj = this.parser.parse(xmlStr);
|
|
37314
|
+
this.masterXmlMap.set(master.path, masterXmlObj);
|
|
37315
|
+
}
|
|
37316
|
+
const sldMaster = masterXmlObj["p:sldMaster"];
|
|
37317
|
+
if (!sldMaster) {
|
|
37318
|
+
continue;
|
|
37319
|
+
}
|
|
37320
|
+
const parsed = this.parseMasterTxStyles(sldMaster);
|
|
37321
|
+
if (parsed) {
|
|
37322
|
+
master.txStyles = parsed;
|
|
37323
|
+
this.masterTxStylesCache.set(master.path, parsed);
|
|
37324
|
+
}
|
|
37325
|
+
const hf = parseHeaderFooterFlags(sldMaster["p:hf"]);
|
|
37326
|
+
if (hf) {
|
|
37327
|
+
master.headerFooter = hf;
|
|
37328
|
+
}
|
|
37329
|
+
} catch (e) {
|
|
37330
|
+
console.warn("Failed to parse master txStyles:", e);
|
|
37331
|
+
}
|
|
37332
|
+
}
|
|
37333
|
+
}
|
|
35270
37334
|
parsePresentationDefaultTextStyle() {
|
|
35271
37335
|
const presentation = this.presentationData?.["p:presentation"];
|
|
35272
37336
|
const defaultTextStyle = presentation?.["p:defaultTextStyle"];
|
|
@@ -35422,7 +37486,7 @@ var PptxHandlerRuntime54 = class extends PptxHandlerRuntime53 {
|
|
|
35422
37486
|
};
|
|
35423
37487
|
|
|
35424
37488
|
// src/core/core/runtime/PptxHandlerRuntimeLayoutElements.ts
|
|
35425
|
-
var
|
|
37489
|
+
var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
|
|
35426
37490
|
async getLayoutElements(slidePath) {
|
|
35427
37491
|
const slideRels = this.slideRelsMap.get(slidePath);
|
|
35428
37492
|
if (!slideRels) {
|
|
@@ -35546,10 +37610,10 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35546
37610
|
}
|
|
35547
37611
|
}
|
|
35548
37612
|
}
|
|
35549
|
-
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35550
37613
|
const layoutShowMasterSp = layoutXmlObj["p:sldLayout"]?.["@_showMasterSp"];
|
|
35551
37614
|
const showMasterSp = layoutShowMasterSp === void 0 || String(layoutShowMasterSp).trim().toLowerCase() !== "0" && String(layoutShowMasterSp).trim().toLowerCase() !== "false";
|
|
35552
37615
|
const masterElements = showMasterSp ? await this.getMasterElements(layoutPath) : [];
|
|
37616
|
+
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35553
37617
|
const allElements = [...masterElements, ...elements];
|
|
35554
37618
|
this.layoutCache.set(layoutPath, allElements);
|
|
35555
37619
|
return allElements;
|
|
@@ -35561,7 +37625,7 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35561
37625
|
};
|
|
35562
37626
|
|
|
35563
37627
|
// src/core/core/runtime/PptxHandlerRuntimeThemeFormatScheme.ts
|
|
35564
|
-
var
|
|
37628
|
+
var PptxHandlerRuntime57 = class _PptxHandlerRuntime extends PptxHandlerRuntime56 {
|
|
35565
37629
|
/**
|
|
35566
37630
|
* Collect fill-style children from a style list node, preserving
|
|
35567
37631
|
* document order. Handles `a:solidFill`, `a:gradFill`, `a:pattFill`,
|
|
@@ -35803,7 +37867,7 @@ var PptxHandlerRuntime56 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35803
37867
|
};
|
|
35804
37868
|
|
|
35805
37869
|
// src/core/core/runtime/PptxHandlerRuntimeThemeOverrides.ts
|
|
35806
|
-
var
|
|
37870
|
+
var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
35807
37871
|
/**
|
|
35808
37872
|
* Parse the `a:fmtScheme` element from the theme into a structured
|
|
35809
37873
|
* {@link PptxThemeFormatScheme}. Each sub-list (fillStyleLst, lnStyleLst,
|
|
@@ -36000,8 +38064,10 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
36000
38064
|
}
|
|
36001
38065
|
const fontScheme = root["a:fontScheme"];
|
|
36002
38066
|
if (fontScheme) {
|
|
36003
|
-
const
|
|
36004
|
-
const
|
|
38067
|
+
const majorFontNode = fontScheme["a:majorFont"];
|
|
38068
|
+
const minorFontNode = fontScheme["a:minorFont"];
|
|
38069
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38070
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
36005
38071
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
36006
38072
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
36007
38073
|
if (!result.colorOverrides) {
|
|
@@ -36024,13 +38090,46 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
36024
38090
|
};
|
|
36025
38091
|
|
|
36026
38092
|
// src/core/core/runtime/PptxHandlerRuntimeThemeRefResolution.ts
|
|
36027
|
-
var
|
|
38093
|
+
var COLOR_CHOICE_KEYS2 = [
|
|
38094
|
+
"a:scrgbClr",
|
|
38095
|
+
"a:srgbClr",
|
|
38096
|
+
"a:hslClr",
|
|
38097
|
+
"a:sysClr",
|
|
38098
|
+
"a:schemeClr",
|
|
38099
|
+
"a:prstClr"
|
|
38100
|
+
];
|
|
38101
|
+
var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
38102
|
+
/**
|
|
38103
|
+
* Pull the verbatim colour-choice child out of a style-matrix-reference
|
|
38104
|
+
* element (`a:lnRef`/`a:fillRef`/`a:effectRef`/`a:fontRef`). Returns the
|
|
38105
|
+
* full child object so it can be round-tripped at save time, preserving
|
|
38106
|
+
* any contained colour transforms (`a:lumMod`, `a:tint`, etc.).
|
|
38107
|
+
*/
|
|
38108
|
+
extractRefColorXml(refNode) {
|
|
38109
|
+
if (!refNode) {
|
|
38110
|
+
return void 0;
|
|
38111
|
+
}
|
|
38112
|
+
for (const key of COLOR_CHOICE_KEYS2) {
|
|
38113
|
+
const child = refNode[key];
|
|
38114
|
+
if (child !== void 0) {
|
|
38115
|
+
return { [key]: child };
|
|
38116
|
+
}
|
|
38117
|
+
}
|
|
38118
|
+
return void 0;
|
|
38119
|
+
}
|
|
36028
38120
|
/**
|
|
36029
38121
|
* Resolve a `a:effectRef` element into concrete effect properties
|
|
36030
38122
|
* by looking up `@_idx` in the theme format scheme's effect style list.
|
|
36031
38123
|
*/
|
|
36032
38124
|
resolveThemeEffectRef(refNode, style) {
|
|
36033
38125
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38126
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38127
|
+
style.effectRefIdx = idx;
|
|
38128
|
+
}
|
|
38129
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38130
|
+
if (overrideColorXml) {
|
|
38131
|
+
style.effectRefColorXml = overrideColorXml;
|
|
38132
|
+
}
|
|
36034
38133
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.effectStyles.length) {
|
|
36035
38134
|
return;
|
|
36036
38135
|
}
|
|
@@ -36083,6 +38182,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36083
38182
|
resolveThemeLineRef(refNode, style) {
|
|
36084
38183
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
36085
38184
|
const overrideColor = this.parseColor(refNode);
|
|
38185
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38186
|
+
style.lnRefIdx = idx;
|
|
38187
|
+
}
|
|
38188
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38189
|
+
if (overrideColorXml) {
|
|
38190
|
+
style.lnRefColorXml = overrideColorXml;
|
|
38191
|
+
}
|
|
36086
38192
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.lineStyles.length) {
|
|
36087
38193
|
style.strokeColor = overrideColor;
|
|
36088
38194
|
if (overrideColor) {
|
|
@@ -36154,6 +38260,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36154
38260
|
*/
|
|
36155
38261
|
resolveThemeFillRef(refNode, style) {
|
|
36156
38262
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38263
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38264
|
+
style.fillRefIdx = idx;
|
|
38265
|
+
}
|
|
38266
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38267
|
+
if (overrideColorXml) {
|
|
38268
|
+
style.fillRefColorXml = overrideColorXml;
|
|
38269
|
+
}
|
|
36157
38270
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme) {
|
|
36158
38271
|
style.fillMode = "theme";
|
|
36159
38272
|
style.fillColor = this.parseColor(refNode);
|
|
@@ -36219,7 +38332,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36219
38332
|
};
|
|
36220
38333
|
|
|
36221
38334
|
// src/core/core/runtime/PptxHandlerRuntimeThemeLoading.ts
|
|
36222
|
-
var
|
|
38335
|
+
var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
36223
38336
|
async resolvePrimaryThemePath() {
|
|
36224
38337
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36225
38338
|
if (!masterFiles || masterFiles.length === 0) {
|
|
@@ -36329,62 +38442,97 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36329
38442
|
formatScheme: this.themeFormatScheme
|
|
36330
38443
|
};
|
|
36331
38444
|
}
|
|
36332
|
-
|
|
38445
|
+
/**
|
|
38446
|
+
* Parse every slide master's `<p:clrMap>` element and store the alias
|
|
38447
|
+
* dictionaries on {@link masterClrMaps}. Do *not* mutate
|
|
38448
|
+
* {@link themeColorMap} — alias resolution happens at colour-lookup
|
|
38449
|
+
* time so that:
|
|
38450
|
+
*
|
|
38451
|
+
* 1. The raw theme scheme stays the source of truth (clrMap is a
|
|
38452
|
+
* routing layer, not a colour table).
|
|
38453
|
+
* 2. Multi-master decks resolve each slide against its own master's
|
|
38454
|
+
* clrMap rather than always against `masterFiles[0]`.
|
|
38455
|
+
* 3. Layout `clrMapOvr` semantics work correctly when a slide's master
|
|
38456
|
+
* differs from the deck's first master.
|
|
38457
|
+
*
|
|
38458
|
+
* Phase 2 Stream B / C-H4.
|
|
38459
|
+
*/
|
|
38460
|
+
async applySlideMasterColorMap(_defaultMap) {
|
|
36333
38461
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36334
38462
|
if (!masterFiles || masterFiles.length === 0) {
|
|
36335
38463
|
return;
|
|
36336
38464
|
}
|
|
36337
|
-
|
|
36338
|
-
|
|
36339
|
-
|
|
36340
|
-
|
|
36341
|
-
|
|
36342
|
-
|
|
36343
|
-
|
|
36344
|
-
|
|
36345
|
-
|
|
36346
|
-
|
|
36347
|
-
|
|
36348
|
-
|
|
36349
|
-
|
|
36350
|
-
|
|
36351
|
-
|
|
36352
|
-
|
|
36353
|
-
"
|
|
36354
|
-
|
|
36355
|
-
"
|
|
36356
|
-
|
|
36357
|
-
];
|
|
36358
|
-
for (const aliasKey of aliasKeys) {
|
|
36359
|
-
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
36360
|
-
if (!mappedKey) {
|
|
38465
|
+
const aliasKeys = [
|
|
38466
|
+
"bg1",
|
|
38467
|
+
"tx1",
|
|
38468
|
+
"bg2",
|
|
38469
|
+
"tx2",
|
|
38470
|
+
"accent1",
|
|
38471
|
+
"accent2",
|
|
38472
|
+
"accent3",
|
|
38473
|
+
"accent4",
|
|
38474
|
+
"accent5",
|
|
38475
|
+
"accent6",
|
|
38476
|
+
"hlink",
|
|
38477
|
+
"folHlink"
|
|
38478
|
+
];
|
|
38479
|
+
for (const file of masterFiles) {
|
|
38480
|
+
try {
|
|
38481
|
+
const masterXml = await file.async("string");
|
|
38482
|
+
const masterData = this.parser.parse(masterXml);
|
|
38483
|
+
const clrMap = masterData?.["p:sldMaster"]?.["p:clrMap"];
|
|
38484
|
+
if (!clrMap) {
|
|
36361
38485
|
continue;
|
|
36362
38486
|
}
|
|
36363
|
-
const
|
|
36364
|
-
|
|
36365
|
-
|
|
38487
|
+
const aliasMap = {};
|
|
38488
|
+
for (const aliasKey of aliasKeys) {
|
|
38489
|
+
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
38490
|
+
if (mappedKey) {
|
|
38491
|
+
aliasMap[aliasKey] = mappedKey;
|
|
38492
|
+
}
|
|
38493
|
+
}
|
|
38494
|
+
if (Object.keys(aliasMap).length > 0) {
|
|
38495
|
+
this.masterClrMaps.set(file.name, aliasMap);
|
|
36366
38496
|
}
|
|
38497
|
+
} catch (error) {
|
|
38498
|
+
console.warn(`Failed to parse slide master color map for ${file.name}:`, error);
|
|
36367
38499
|
}
|
|
36368
|
-
} catch (error) {
|
|
36369
|
-
console.warn("Failed to parse slide master color map:", error);
|
|
36370
38500
|
}
|
|
36371
38501
|
}
|
|
36372
|
-
|
|
36373
|
-
|
|
36374
|
-
|
|
36375
|
-
|
|
38502
|
+
/**
|
|
38503
|
+
* Parse a single theme part into structured colour, font, and format
|
|
38504
|
+
* scheme dictionaries. Used both for the global default theme and for
|
|
38505
|
+
* each master's per-master theme (multi-master support).
|
|
38506
|
+
*
|
|
38507
|
+
* Phase 2 Stream B / C-H4.
|
|
38508
|
+
*/
|
|
38509
|
+
async parseThemePart(themePath) {
|
|
38510
|
+
const themeFile = this.zip.file(themePath);
|
|
38511
|
+
if (!themeFile) {
|
|
38512
|
+
return null;
|
|
36376
38513
|
}
|
|
36377
|
-
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
36378
|
-
const preferredThemeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) : void 0;
|
|
36379
|
-
const themeFile = preferredThemeFile ?? themeFiles[0];
|
|
36380
38514
|
const themeXml2 = await themeFile.async("string");
|
|
38515
|
+
this.originalThemeXmlByPath.set(themePath, themeXml2);
|
|
36381
38516
|
const themeData = this.parser.parse(themeXml2);
|
|
36382
38517
|
const themeRoot = themeData["a:theme"];
|
|
36383
38518
|
const themeElements = themeRoot?.["a:themeElements"];
|
|
36384
38519
|
const colorScheme = themeElements?.["a:clrScheme"];
|
|
36385
38520
|
const fontScheme = themeElements?.["a:fontScheme"];
|
|
38521
|
+
const fmtScheme = themeElements?.["a:fmtScheme"];
|
|
38522
|
+
const themeName = String(themeRoot?.["@_name"] || "").trim();
|
|
38523
|
+
if (themeName) {
|
|
38524
|
+
this.masterThemeNames.set(themePath, themeName);
|
|
38525
|
+
}
|
|
38526
|
+
const colorSchemeName = String(colorScheme?.["@_name"] || "").trim();
|
|
38527
|
+
if (colorSchemeName) {
|
|
38528
|
+
this.masterThemeColorSchemeNames.set(themePath, colorSchemeName);
|
|
38529
|
+
}
|
|
38530
|
+
const fontSchemeName = String(fontScheme?.["@_name"] || "").trim();
|
|
38531
|
+
if (fontSchemeName) {
|
|
38532
|
+
this.masterThemeFontSchemeNames.set(themePath, fontSchemeName);
|
|
38533
|
+
}
|
|
36386
38534
|
const defaultMap = this.getDefaultSchemeColorMap();
|
|
36387
|
-
|
|
38535
|
+
const colorMap = { ...defaultMap };
|
|
36388
38536
|
if (colorScheme) {
|
|
36389
38537
|
const schemeKeys = [
|
|
36390
38538
|
"dk1",
|
|
@@ -36404,39 +38552,196 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36404
38552
|
const colorNode = colorScheme[`a:${key}`];
|
|
36405
38553
|
const parsed = this.parseColorChoice(colorNode);
|
|
36406
38554
|
if (parsed) {
|
|
36407
|
-
|
|
38555
|
+
colorMap[key] = parsed;
|
|
36408
38556
|
}
|
|
36409
38557
|
}
|
|
36410
38558
|
}
|
|
36411
|
-
|
|
36412
|
-
|
|
36413
|
-
|
|
36414
|
-
|
|
36415
|
-
|
|
36416
|
-
const
|
|
36417
|
-
const
|
|
38559
|
+
colorMap["tx1"] = colorMap["dk1"] || defaultMap["dk1"];
|
|
38560
|
+
colorMap["bg1"] = colorMap["lt1"] || defaultMap["lt1"];
|
|
38561
|
+
colorMap["tx2"] = colorMap["dk2"] || defaultMap["dk2"];
|
|
38562
|
+
colorMap["bg2"] = colorMap["lt2"] || defaultMap["lt2"];
|
|
38563
|
+
const majorFontNode = fontScheme?.["a:majorFont"];
|
|
38564
|
+
const minorFontNode = fontScheme?.["a:minorFont"];
|
|
38565
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38566
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
36418
38567
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
36419
38568
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
36420
|
-
|
|
38569
|
+
const fontMap = {};
|
|
36421
38570
|
if (majorFont) {
|
|
36422
|
-
|
|
36423
|
-
|
|
36424
|
-
|
|
38571
|
+
fontMap["mj-lt"] = majorFont;
|
|
38572
|
+
fontMap["mj-ea"] = majorFont;
|
|
38573
|
+
fontMap["mj-cs"] = majorFont;
|
|
36425
38574
|
}
|
|
36426
38575
|
if (minorFont) {
|
|
36427
|
-
|
|
36428
|
-
|
|
36429
|
-
|
|
38576
|
+
fontMap["mn-lt"] = minorFont;
|
|
38577
|
+
fontMap["mn-ea"] = minorFont;
|
|
38578
|
+
fontMap["mn-cs"] = minorFont;
|
|
36430
38579
|
}
|
|
36431
|
-
const
|
|
36432
|
-
|
|
36433
|
-
|
|
38580
|
+
const majorEa = this.normalizeTypefaceToken(
|
|
38581
|
+
String(majorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38582
|
+
);
|
|
38583
|
+
if (majorEa) {
|
|
38584
|
+
fontMap["mj-ea"] = majorEa;
|
|
36434
38585
|
}
|
|
38586
|
+
const majorCs = this.normalizeTypefaceToken(
|
|
38587
|
+
String(majorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38588
|
+
);
|
|
38589
|
+
if (majorCs) {
|
|
38590
|
+
fontMap["mj-cs"] = majorCs;
|
|
38591
|
+
}
|
|
38592
|
+
const minorEa = this.normalizeTypefaceToken(
|
|
38593
|
+
String(minorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38594
|
+
);
|
|
38595
|
+
if (minorEa) {
|
|
38596
|
+
fontMap["mn-ea"] = minorEa;
|
|
38597
|
+
}
|
|
38598
|
+
const minorCs = this.normalizeTypefaceToken(
|
|
38599
|
+
String(minorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38600
|
+
);
|
|
38601
|
+
if (minorCs) {
|
|
38602
|
+
fontMap["mn-cs"] = minorCs;
|
|
38603
|
+
}
|
|
38604
|
+
const majorScripts = this.collectFontScriptOverrides(majorFontNode);
|
|
38605
|
+
if (Object.keys(majorScripts).length > 0) {
|
|
38606
|
+
this.masterThemeMajorFontScripts.set(themePath, majorScripts);
|
|
38607
|
+
}
|
|
38608
|
+
const minorScripts = this.collectFontScriptOverrides(minorFontNode);
|
|
38609
|
+
if (Object.keys(minorScripts).length > 0) {
|
|
38610
|
+
this.masterThemeMinorFontScripts.set(themePath, minorScripts);
|
|
38611
|
+
}
|
|
38612
|
+
const objectDefaultsNode = themeRoot?.["a:objectDefaults"];
|
|
38613
|
+
if (objectDefaultsNode) {
|
|
38614
|
+
const od = {
|
|
38615
|
+
spDef: objectDefaultsNode["a:spDef"],
|
|
38616
|
+
lnDef: objectDefaultsNode["a:lnDef"],
|
|
38617
|
+
txDef: objectDefaultsNode["a:txDef"]
|
|
38618
|
+
};
|
|
38619
|
+
if (od.spDef !== void 0 || od.lnDef !== void 0 || od.txDef !== void 0) {
|
|
38620
|
+
this.masterThemeObjectDefaults.set(themePath, od);
|
|
38621
|
+
}
|
|
38622
|
+
}
|
|
38623
|
+
const extraClrSchemeLst = themeRoot?.["a:extraClrSchemeLst"];
|
|
38624
|
+
if (extraClrSchemeLst !== void 0) {
|
|
38625
|
+
this.masterThemeExtraClrSchemeLst.set(themePath, extraClrSchemeLst);
|
|
38626
|
+
}
|
|
38627
|
+
const custClrLst = themeRoot?.["a:custClrLst"];
|
|
38628
|
+
if (custClrLst !== void 0) {
|
|
38629
|
+
this.masterThemeCustClrLst.set(themePath, custClrLst);
|
|
38630
|
+
}
|
|
38631
|
+
const themeExtLst = themeRoot?.["a:extLst"];
|
|
38632
|
+
if (themeExtLst !== void 0) {
|
|
38633
|
+
this.masterThemeExtLst.set(themePath, themeExtLst);
|
|
38634
|
+
}
|
|
38635
|
+
const formatScheme = fmtScheme ? this.parseFormatScheme(fmtScheme) : void 0;
|
|
38636
|
+
return { colorMap, fontMap, formatScheme };
|
|
38637
|
+
}
|
|
38638
|
+
/**
|
|
38639
|
+
* Parse `<a:font script="…" typeface="…"/>` children of a major or
|
|
38640
|
+
* minor font node into a `script -> typeface` dictionary.
|
|
38641
|
+
*
|
|
38642
|
+
* fast-xml-parser collapses repeated tags into arrays, so iterate
|
|
38643
|
+
* over the array form regardless of how many siblings are present.
|
|
38644
|
+
*
|
|
38645
|
+
* Phase 4 Stream A / M4.
|
|
38646
|
+
*/
|
|
38647
|
+
collectFontScriptOverrides(fontNode) {
|
|
38648
|
+
const overrides = {};
|
|
38649
|
+
if (!fontNode) {
|
|
38650
|
+
return overrides;
|
|
38651
|
+
}
|
|
38652
|
+
const fontEntries = this.ensureArray(fontNode["a:font"]);
|
|
38653
|
+
for (const entry of fontEntries) {
|
|
38654
|
+
const script = String(entry?.["@_script"] || "").trim();
|
|
38655
|
+
const typeface = this.normalizeTypefaceToken(String(entry?.["@_typeface"] || ""));
|
|
38656
|
+
if (script && typeface) {
|
|
38657
|
+
overrides[script] = typeface;
|
|
38658
|
+
}
|
|
38659
|
+
}
|
|
38660
|
+
return overrides;
|
|
38661
|
+
}
|
|
38662
|
+
/**
|
|
38663
|
+
* Resolve the theme file path referenced by a given master's `.rels`.
|
|
38664
|
+
* Returns `undefined` when the master has no theme relationship.
|
|
38665
|
+
*/
|
|
38666
|
+
async resolveThemePathForMaster(masterPath) {
|
|
38667
|
+
const relsPath = masterPath.replace(
|
|
38668
|
+
/ppt\/slideMasters\/(slideMaster\d+)\.xml/,
|
|
38669
|
+
"ppt/slideMasters/_rels/$1.xml.rels"
|
|
38670
|
+
);
|
|
38671
|
+
const relsXml = this.zip.file(relsPath);
|
|
38672
|
+
if (!relsXml) {
|
|
38673
|
+
return void 0;
|
|
38674
|
+
}
|
|
38675
|
+
const relsData = this.parser.parse(await relsXml.async("string"));
|
|
38676
|
+
const relNodes = this.ensureArray(relsData?.Relationships?.Relationship);
|
|
38677
|
+
for (const rel of relNodes) {
|
|
38678
|
+
const target = String(rel["@_Target"] || "");
|
|
38679
|
+
if (!target.includes("theme")) {
|
|
38680
|
+
continue;
|
|
38681
|
+
}
|
|
38682
|
+
const themePath = target.startsWith("..") ? this.resolvePath(masterPath.substring(0, masterPath.lastIndexOf("/") + 1), target) : target.startsWith("/") ? target.slice(1) : `ppt/${target.replace(/^\.?\//, "")}`;
|
|
38683
|
+
if (themePath.startsWith("ppt/theme/")) {
|
|
38684
|
+
return themePath;
|
|
38685
|
+
}
|
|
38686
|
+
}
|
|
38687
|
+
return void 0;
|
|
38688
|
+
}
|
|
38689
|
+
/**
|
|
38690
|
+
* Populate {@link masterThemeColorMaps}, {@link masterThemeFontMaps},
|
|
38691
|
+
* and {@link masterThemeFormatSchemes} for every slide master in the
|
|
38692
|
+
* deck. Multi-master support — Phase 2 Stream B / C-H4.
|
|
38693
|
+
*/
|
|
38694
|
+
async loadPerMasterThemes() {
|
|
38695
|
+
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
38696
|
+
if (!masterFiles || masterFiles.length === 0) {
|
|
38697
|
+
return;
|
|
38698
|
+
}
|
|
38699
|
+
for (const file of masterFiles) {
|
|
38700
|
+
try {
|
|
38701
|
+
const themePath = await this.resolveThemePathForMaster(file.name);
|
|
38702
|
+
if (!themePath) {
|
|
38703
|
+
continue;
|
|
38704
|
+
}
|
|
38705
|
+
this.masterThemePaths.set(file.name, themePath);
|
|
38706
|
+
const parsed = await this.parseThemePart(themePath);
|
|
38707
|
+
if (!parsed) {
|
|
38708
|
+
continue;
|
|
38709
|
+
}
|
|
38710
|
+
this.masterThemeColorMaps.set(file.name, parsed.colorMap);
|
|
38711
|
+
this.masterThemeFontMaps.set(file.name, parsed.fontMap);
|
|
38712
|
+
if (parsed.formatScheme) {
|
|
38713
|
+
this.masterThemeFormatSchemes.set(file.name, parsed.formatScheme);
|
|
38714
|
+
}
|
|
38715
|
+
} catch (error) {
|
|
38716
|
+
console.warn(`Failed to load per-master theme for ${file.name}:`, error);
|
|
38717
|
+
}
|
|
38718
|
+
}
|
|
38719
|
+
}
|
|
38720
|
+
async loadThemeData() {
|
|
38721
|
+
const themeFiles = this.zip.file(/^ppt\/theme\/theme\d+\.xml$/);
|
|
38722
|
+
if (!themeFiles || themeFiles.length === 0) {
|
|
38723
|
+
return;
|
|
38724
|
+
}
|
|
38725
|
+
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
38726
|
+
const themeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) ?? themeFiles[0] : themeFiles[0];
|
|
38727
|
+
const parsed = await this.parseThemePart(themeFile.name);
|
|
38728
|
+
if (parsed) {
|
|
38729
|
+
this.themeColorMap = parsed.colorMap;
|
|
38730
|
+
this.themeFontMap = parsed.fontMap;
|
|
38731
|
+
if (parsed.formatScheme) {
|
|
38732
|
+
this.themeFormatScheme = parsed.formatScheme;
|
|
38733
|
+
}
|
|
38734
|
+
}
|
|
38735
|
+
await this.applySlideMasterColorMap(this.getDefaultSchemeColorMap());
|
|
38736
|
+
await this.loadPerMasterThemes();
|
|
38737
|
+
this.globalThemeColorMapSnapshot = { ...this.themeColorMap };
|
|
38738
|
+
this.globalThemeFontMapSnapshot = { ...this.themeFontMap };
|
|
38739
|
+
this.globalThemeFormatSchemeSnapshot = this.themeFormatScheme;
|
|
36435
38740
|
}
|
|
36436
38741
|
};
|
|
36437
38742
|
|
|
36438
38743
|
// src/core/core/runtime/PptxHandlerRuntimeThemeProcessing.ts
|
|
36439
|
-
var
|
|
38744
|
+
var PptxHandlerRuntime61 = class extends PptxHandlerRuntime60 {
|
|
36440
38745
|
// ---------------------------------------------------------------------------
|
|
36441
38746
|
// Theme editing — update colour scheme, font scheme, and name in the zip
|
|
36442
38747
|
// ---------------------------------------------------------------------------
|
|
@@ -36586,7 +38891,7 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
|
36586
38891
|
};
|
|
36587
38892
|
|
|
36588
38893
|
// src/core/core/runtime/PptxHandlerRuntimeComments.ts
|
|
36589
|
-
var
|
|
38894
|
+
var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime61 {
|
|
36590
38895
|
/**
|
|
36591
38896
|
* Parse modern threaded comments (PowerPoint 2019+ / Office 365).
|
|
36592
38897
|
* Modern comments use `p188:cmLst`/`p15:cmLst` roots within
|
|
@@ -36819,7 +39124,7 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
36819
39124
|
};
|
|
36820
39125
|
|
|
36821
39126
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtXmlUtils.ts
|
|
36822
|
-
var
|
|
39127
|
+
var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
|
|
36823
39128
|
async readXmlPartByRelationshipId(slidePath, relationshipId) {
|
|
36824
39129
|
const normalizedRelationshipId = String(relationshipId || "").trim();
|
|
36825
39130
|
if (normalizedRelationshipId.length === 0) {
|
|
@@ -36974,7 +39279,7 @@ var PptxHandlerRuntime62 = class extends PptxHandlerRuntime61 {
|
|
|
36974
39279
|
};
|
|
36975
39280
|
|
|
36976
39281
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtParsing.ts
|
|
36977
|
-
var
|
|
39282
|
+
var PptxHandlerRuntime64 = class _PptxHandlerRuntime extends PptxHandlerRuntime63 {
|
|
36978
39283
|
/**
|
|
36979
39284
|
* Parse quick style from `ppt/diagrams/quickStyles*.xml`.
|
|
36980
39285
|
*/
|
|
@@ -37133,7 +39438,7 @@ var PptxHandlerRuntime63 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
37133
39438
|
};
|
|
37134
39439
|
|
|
37135
39440
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArt.ts
|
|
37136
|
-
var
|
|
39441
|
+
var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime64 {
|
|
37137
39442
|
async getSmartArtDataForGraphicFrame(slidePath, graphicFrame) {
|
|
37138
39443
|
const graphicData = this.xmlLookupService.getChildByLocalName(
|
|
37139
39444
|
this.xmlLookupService.getChildByLocalName(graphicFrame, "graphic"),
|
|
@@ -37184,10 +39489,14 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37184
39489
|
const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
|
|
37185
39490
|
const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
|
|
37186
39491
|
const chrome = this.parseSmartArtChrome(dataModel);
|
|
37187
|
-
const drawingRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37188
|
-
const drawingShapes = await this.parseSmartArtDrawingShapes(slidePath, drawingRelationshipId);
|
|
37189
39492
|
const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37190
39493
|
const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
|
|
39494
|
+
const drawingResolution = await this.resolveSmartArtDrawingPart(
|
|
39495
|
+
slidePath,
|
|
39496
|
+
diagramDataRelationshipId
|
|
39497
|
+
);
|
|
39498
|
+
const drawingShapes = drawingResolution ? await this.parseSmartArtDrawingShapesFromPath(drawingResolution.path) : [];
|
|
39499
|
+
const drawingRelationshipId = drawingResolution?.relId;
|
|
37191
39500
|
const styleRelationshipId = String(relationshipIds["@_r:qs"] || "").trim();
|
|
37192
39501
|
const quickStyle = await this.parseSmartArtQuickStyle(slidePath, styleRelationshipId);
|
|
37193
39502
|
return {
|
|
@@ -37199,11 +39508,87 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37199
39508
|
colorTransform,
|
|
37200
39509
|
quickStyle,
|
|
37201
39510
|
dataRelId: diagramDataRelationshipId,
|
|
37202
|
-
drawingRelId: drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
39511
|
+
drawingRelId: drawingRelationshipId && drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
37203
39512
|
colorsRelId: colorsRelationshipId.length > 0 ? colorsRelationshipId : void 0,
|
|
37204
39513
|
styleRelId: styleRelationshipId.length > 0 ? styleRelationshipId : void 0
|
|
37205
39514
|
};
|
|
37206
39515
|
}
|
|
39516
|
+
/**
|
|
39517
|
+
* Resolve the SmartArt drawing-shapes part path + relationship id.
|
|
39518
|
+
*
|
|
39519
|
+
* Strategy:
|
|
39520
|
+
* 1. Locate the data-model part's rels file
|
|
39521
|
+
* (`ppt/diagrams/_rels/data*.xml.rels`) via `slideRelsMap`.
|
|
39522
|
+
* 2. Find a relationship whose `Type` matches the `…/diagramDrawing`
|
|
39523
|
+
* URI. PowerPoint emits this for any deck that has had its
|
|
39524
|
+
* SmartArt rendered to drawing shapes.
|
|
39525
|
+
* 3. Return the matched part path (so the caller can load it
|
|
39526
|
+
* directly) and the relationship id (for round-trip preservation).
|
|
39527
|
+
*/
|
|
39528
|
+
async resolveSmartArtDrawingPart(slidePath, diagramDataRelationshipId) {
|
|
39529
|
+
if (diagramDataRelationshipId.length === 0) {
|
|
39530
|
+
return void 0;
|
|
39531
|
+
}
|
|
39532
|
+
const slideRels = this.slideRelsMap.get(slidePath);
|
|
39533
|
+
const dataTarget = slideRels?.get(diagramDataRelationshipId);
|
|
39534
|
+
if (!dataTarget) {
|
|
39535
|
+
return void 0;
|
|
39536
|
+
}
|
|
39537
|
+
const dataPath = this.resolveImagePath(slidePath, dataTarget);
|
|
39538
|
+
const dataDir = dataPath.replace(/\/[^/]+$/, "");
|
|
39539
|
+
const dataFile = dataPath.split("/").pop() ?? "";
|
|
39540
|
+
const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
|
|
39541
|
+
const relsXml = await this.zip.file(dataRelsPath)?.async("string");
|
|
39542
|
+
if (!relsXml) {
|
|
39543
|
+
return void 0;
|
|
39544
|
+
}
|
|
39545
|
+
try {
|
|
39546
|
+
const parsed = this.parser.parse(relsXml);
|
|
39547
|
+
const relsRoot = parsed["Relationships"];
|
|
39548
|
+
if (!relsRoot) {
|
|
39549
|
+
return void 0;
|
|
39550
|
+
}
|
|
39551
|
+
const rels = this.ensureArray(relsRoot["Relationship"]);
|
|
39552
|
+
const drawingRel = rels.find(
|
|
39553
|
+
(rel) => String(rel?.["@_Type"] || "").endsWith("/diagramDrawing")
|
|
39554
|
+
);
|
|
39555
|
+
const id = String(drawingRel?.["@_Id"] || "").trim();
|
|
39556
|
+
const target = String(drawingRel?.["@_Target"] || "").trim();
|
|
39557
|
+
if (id.length === 0 || target.length === 0) {
|
|
39558
|
+
return void 0;
|
|
39559
|
+
}
|
|
39560
|
+
const drawingPath = this.resolveImagePath(dataPath, target);
|
|
39561
|
+
return { relId: id, path: drawingPath };
|
|
39562
|
+
} catch {
|
|
39563
|
+
return void 0;
|
|
39564
|
+
}
|
|
39565
|
+
}
|
|
39566
|
+
/**
|
|
39567
|
+
* Parse SmartArt drawing shapes given an absolute part path.
|
|
39568
|
+
*
|
|
39569
|
+
* Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
|
|
39570
|
+
* relationship id) with a path-based lookup so the resolution layer
|
|
39571
|
+
* can pull the part from anywhere in the package.
|
|
39572
|
+
*/
|
|
39573
|
+
async parseSmartArtDrawingShapesFromPath(drawingPath) {
|
|
39574
|
+
const xmlString = await this.zip.file(drawingPath)?.async("string");
|
|
39575
|
+
if (!xmlString) {
|
|
39576
|
+
return [];
|
|
39577
|
+
}
|
|
39578
|
+
try {
|
|
39579
|
+
const xml = this.parser.parse(xmlString);
|
|
39580
|
+
const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
|
|
39581
|
+
const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
|
|
39582
|
+
if (!spTree) {
|
|
39583
|
+
return [];
|
|
39584
|
+
}
|
|
39585
|
+
const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
|
|
39586
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
39587
|
+
return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
|
|
39588
|
+
} catch {
|
|
39589
|
+
return [];
|
|
39590
|
+
}
|
|
39591
|
+
}
|
|
37207
39592
|
parseSmartArtConnections(dataModel) {
|
|
37208
39593
|
const connectionList = this.xmlLookupService.getChildByLocalName(dataModel, "cxnLst");
|
|
37209
39594
|
const rawConnections = this.xmlLookupService.getChildrenArrayByLocalName(connectionList, "cxn");
|
|
@@ -37234,7 +39619,7 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37234
39619
|
};
|
|
37235
39620
|
|
|
37236
39621
|
// src/core/core/runtime/PptxHandlerRuntimeChartDetection.ts
|
|
37237
|
-
var
|
|
39622
|
+
var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
37238
39623
|
detectChartType(plotArea) {
|
|
37239
39624
|
if (!plotArea) {
|
|
37240
39625
|
return "unknown";
|
|
@@ -37343,7 +39728,7 @@ var PptxHandlerRuntime65 = class extends PptxHandlerRuntime64 {
|
|
|
37343
39728
|
};
|
|
37344
39729
|
|
|
37345
39730
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsingHelpers.ts
|
|
37346
|
-
var
|
|
39731
|
+
var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
37347
39732
|
/**
|
|
37348
39733
|
* Parse `c:plotVisOnly` from the chart root element.
|
|
37349
39734
|
*
|
|
@@ -37404,7 +39789,7 @@ var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
|
37404
39789
|
};
|
|
37405
39790
|
|
|
37406
39791
|
// src/core/core/runtime/PptxHandlerRuntimeChartExternalData.ts
|
|
37407
|
-
var
|
|
39792
|
+
var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
37408
39793
|
/**
|
|
37409
39794
|
* Parse `c:externalData` from the chart's `c:chartSpace` and resolve
|
|
37410
39795
|
* the external relationship target from the chart part's .rels file.
|
|
@@ -37520,7 +39905,7 @@ var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
|
37520
39905
|
};
|
|
37521
39906
|
|
|
37522
39907
|
// src/core/core/runtime/PptxHandlerRuntimeChartColorStyle.ts
|
|
37523
|
-
var
|
|
39908
|
+
var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
37524
39909
|
/**
|
|
37525
39910
|
* Parse the Office 2013+ chart color style part (`chartColorStyle*.xml`)
|
|
37526
39911
|
* referenced from the chart's relationships.
|
|
@@ -37627,7 +40012,7 @@ var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
|
37627
40012
|
};
|
|
37628
40013
|
|
|
37629
40014
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsing.ts
|
|
37630
|
-
var
|
|
40015
|
+
var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
37631
40016
|
/**
|
|
37632
40017
|
* Parse chart data from a graphic frame element on a slide.
|
|
37633
40018
|
*
|
|
@@ -37874,7 +40259,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
|
37874
40259
|
};
|
|
37875
40260
|
|
|
37876
40261
|
// src/core/core/runtime/PptxHandlerRuntimePresentationStructure.ts
|
|
37877
|
-
var
|
|
40262
|
+
var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
37878
40263
|
parseEditorAnimations(slideXml2) {
|
|
37879
40264
|
return this.editorAnimationService.parseEditorAnimations(slideXml2);
|
|
37880
40265
|
}
|
|
@@ -38119,7 +40504,7 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
|
38119
40504
|
};
|
|
38120
40505
|
|
|
38121
40506
|
// src/core/core/runtime/PptxHandlerRuntimeEmbeddedFonts.ts
|
|
38122
|
-
var
|
|
40507
|
+
var PptxHandlerRuntime72 = class extends PptxHandlerRuntime71 {
|
|
38123
40508
|
async getEmbeddedFonts() {
|
|
38124
40509
|
const embeddedFontEntries = this.ensureArray(
|
|
38125
40510
|
this.presentationData?.["p:presentation"]?.["p:embeddedFontLst"]?.["p:embeddedFont"]
|
|
@@ -38291,7 +40676,7 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
|
38291
40676
|
};
|
|
38292
40677
|
|
|
38293
40678
|
// src/core/core/runtime/PptxHandlerRuntimeLoadSession.ts
|
|
38294
|
-
var
|
|
40679
|
+
var PptxHandlerRuntime73 = class _PptxHandlerRuntime extends PptxHandlerRuntime72 {
|
|
38295
40680
|
isZipContainer(data) {
|
|
38296
40681
|
const bytes = new Uint8Array(data);
|
|
38297
40682
|
if (bytes.byteLength < 4) {
|
|
@@ -38334,6 +40719,23 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38334
40719
|
this.imageDataCache.clear();
|
|
38335
40720
|
this.themeColorMap = {};
|
|
38336
40721
|
this.themeFontMap = {};
|
|
40722
|
+
this.masterClrMaps.clear();
|
|
40723
|
+
this.masterThemeColorMaps.clear();
|
|
40724
|
+
this.masterThemeFontMaps.clear();
|
|
40725
|
+
this.masterThemeFormatSchemes.clear();
|
|
40726
|
+
this.masterThemePaths.clear();
|
|
40727
|
+
this.masterThemeMajorFontScripts.clear();
|
|
40728
|
+
this.masterThemeMinorFontScripts.clear();
|
|
40729
|
+
this.masterThemeNames.clear();
|
|
40730
|
+
this.masterThemeFontSchemeNames.clear();
|
|
40731
|
+
this.masterThemeColorSchemeNames.clear();
|
|
40732
|
+
this.originalThemeXmlByPath.clear();
|
|
40733
|
+
this.dirtyThemePaths.clear();
|
|
40734
|
+
this.masterThemeObjectDefaults.clear();
|
|
40735
|
+
this.masterThemeExtraClrSchemeLst.clear();
|
|
40736
|
+
this.masterThemeCustClrLst.clear();
|
|
40737
|
+
this.masterThemeExtLst.clear();
|
|
40738
|
+
this.currentMasterClrMap = null;
|
|
38337
40739
|
this.presentationDefaultTextStyle = void 0;
|
|
38338
40740
|
this.commentAuthorMap.clear();
|
|
38339
40741
|
this.commentAuthorDetails.clear();
|
|
@@ -38488,6 +40890,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38488
40890
|
setCurrentSlideClrMapOverride: (override) => {
|
|
38489
40891
|
this.currentSlideClrMapOverride = override;
|
|
38490
40892
|
},
|
|
40893
|
+
setActiveMasterForSlide: (slidePath) => this.setActiveMasterForSlide(slidePath),
|
|
38491
40894
|
findLayoutPathForSlide: (slidePath) => this.findLayoutPathForSlide(slidePath),
|
|
38492
40895
|
loadThemeOverride: (partBasePath) => this.loadThemeOverride(partBasePath),
|
|
38493
40896
|
applyThemeOverrideState: (override) => this.applyThemeOverrideState(override),
|
|
@@ -38518,7 +40921,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38518
40921
|
};
|
|
38519
40922
|
|
|
38520
40923
|
// src/core/core/runtime/PptxHandlerRuntimeLoadPipeline.ts
|
|
38521
|
-
var
|
|
40924
|
+
var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
|
|
38522
40925
|
async buildLoadData(presentationState, slidesWithWarnings) {
|
|
38523
40926
|
const headerFooter = this.extractHeaderFooter();
|
|
38524
40927
|
const presentationProperties = await this.parsePresentationProperties();
|
|
@@ -38530,6 +40933,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38530
40933
|
const notesMaster = await this.parseNotesMaster();
|
|
38531
40934
|
const handoutMaster = await this.parseHandoutMaster();
|
|
38532
40935
|
const slideMasters = await this.parseSlideMasters();
|
|
40936
|
+
await this.enrichSlideMastersWithTxStyles(slideMasters);
|
|
38533
40937
|
const tags = await this.parseTags();
|
|
38534
40938
|
const customProperties = await this.parseCustomProperties();
|
|
38535
40939
|
const coreProperties = await this.parseCoreProperties();
|
|
@@ -38864,7 +41268,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38864
41268
|
};
|
|
38865
41269
|
|
|
38866
41270
|
// src/core/core/runtime/PptxHandlerRuntimeImplementation.ts
|
|
38867
|
-
var
|
|
41271
|
+
var PptxHandlerRuntime75 = class _PptxHandlerRuntime extends PptxHandlerRuntime74 {
|
|
38868
41272
|
constructor(dependencyFactory = new PptxRuntimeDependencyFactory()) {
|
|
38869
41273
|
super();
|
|
38870
41274
|
this.dependencyFactory = dependencyFactory;
|
|
@@ -38912,6 +41316,9 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38912
41316
|
extractGradientPathType: (gradFill) => this.colorStyleCodec.extractGradientPathType(gradFill),
|
|
38913
41317
|
extractGradientFocalPoint: (gradFill) => this.colorStyleCodec.extractGradientFocalPoint(gradFill),
|
|
38914
41318
|
extractGradientFillToRect: (gradFill) => this.colorStyleCodec.extractGradientFillToRect(gradFill),
|
|
41319
|
+
extractGradientFlip: (gradFill) => this.colorStyleCodec.extractGradientFlip(gradFill),
|
|
41320
|
+
extractGradientRotWithShape: (gradFill) => this.colorStyleCodec.extractGradientRotWithShape(gradFill),
|
|
41321
|
+
extractGradientScaled: (gradFill) => this.colorStyleCodec.extractGradientScaled(gradFill),
|
|
38915
41322
|
normalizeStrokeDashType: (value) => this.normalizeStrokeDashType(value),
|
|
38916
41323
|
normalizeConnectorArrowType: (value) => this.normalizeConnectorArrowType(value),
|
|
38917
41324
|
ensureArray: (value) => this.ensureArray(value),
|
|
@@ -38985,11 +41392,11 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38985
41392
|
};
|
|
38986
41393
|
|
|
38987
41394
|
// src/core/core/PptxHandlerRuntime.ts
|
|
38988
|
-
var
|
|
41395
|
+
var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
|
|
38989
41396
|
};
|
|
38990
41397
|
|
|
38991
41398
|
// src/core/core/PptxHandlerRuntimeFactory.ts
|
|
38992
|
-
var createDefaultPptxHandlerRuntime = () => new
|
|
41399
|
+
var createDefaultPptxHandlerRuntime = () => new PptxHandlerRuntime76();
|
|
38993
41400
|
|
|
38994
41401
|
// src/core/PptxHandlerCore.ts
|
|
38995
41402
|
var PptxHandlerCore = class {
|