@office-open/pptx 0.4.4 → 0.4.6
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/README.md +13 -13
- package/dist/index.d.mts +29 -34
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +594 -900
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { i as __toCommonJS, n as __exportAll, r as __reExport, t as __esmMin } f
|
|
|
2
2
|
import { AppProperties, BaseXmlComponent, BuilderElement, Formatter, ImportedXmlComponent, NextAttributeComponent, OoxmlMimeType, PrettifyType, Relationships, StringContainer, XmlComponent, addSmartArtRelationships, buildCorePropertiesXml, collectPlaceholderKeys, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertOutput, convertPixelsToEmu, convertPixelsToEmu as convertPixelsToEmu$1, convertPointsToEmu, convertPrettifyType, escapeRegex, formatId, getReferencedMedia, hasPlaceholders, hashedId, parseDocument, replaceChartPlaceholders, replaceImagePlaceholders, replaceSmartArtPlaceholders, uniqueId, uniqueNumericIdCreator, uniqueUuid } from "@office-open/core";
|
|
3
3
|
import { BevelPresetType, CompoundLine, LineCap, LineJoin, PathShadeType, PenAlignment, PresetDash, PresetGeometry, PresetMaterialType, Stretch, TileFlipMode, buildFill, createBevel, createBlip, createBottomBevel, createColorElement, createColorTransforms, createEffectList, createEffectList as createEffectList$1, createGradientFill, createGradientStop, createGroupTransform2D, createOutline, createOutline as createOutline$1, createScene3D, createScene3D as createScene3D$1, createShape3D, createShape3D as createShape3D$1, createTransform2D, extractBlipFillMedia } from "@office-open/core/drawingml";
|
|
4
4
|
import { ChartCollection, ChartSpace } from "@office-open/core/chart";
|
|
5
|
-
import { attr,
|
|
5
|
+
import { attr, xml } from "@office-open/xml";
|
|
6
6
|
import { DEFAULT_DRAWING_XML, SmartArtCollection, createDataModel, getColorXml, getLayoutXml, getStyleXml } from "@office-open/core/smartart";
|
|
7
7
|
import { Zip, ZipDeflate, ZipPassThrough, zipSync } from "fflate";
|
|
8
8
|
export * from "@office-open/core/values";
|
|
@@ -599,9 +599,6 @@ init_xml_components();
|
|
|
599
599
|
function buildEndParagraphRunProperties(lang = "en-US") {
|
|
600
600
|
return { "a:endParaRPr": { _attr: { lang } } };
|
|
601
601
|
}
|
|
602
|
-
function buildEndParagraphRunPropertiesXml(lang = "en-US") {
|
|
603
|
-
return `<a:endParaRPr${attrs({ lang })}/>`;
|
|
604
|
-
}
|
|
605
602
|
/**
|
|
606
603
|
* a:endParaRPr — End paragraph run properties.
|
|
607
604
|
* Lazy: stores lang, builds XML object in prepForXml.
|
|
@@ -683,48 +680,7 @@ var ParagraphProperties = class extends XmlComponent {
|
|
|
683
680
|
prepForXml(_context) {
|
|
684
681
|
return buildParagraphProperties(this.options);
|
|
685
682
|
}
|
|
686
|
-
toXml() {
|
|
687
|
-
return buildParagraphPropertiesXml(this.options);
|
|
688
|
-
}
|
|
689
683
|
};
|
|
690
|
-
function buildBulletChildrenXml(options) {
|
|
691
|
-
if (options.type === "none") return "<a:buNone/>";
|
|
692
|
-
let s = "";
|
|
693
|
-
if (options.color) s += `<a:buClr><a:srgbClr${attrs({ val: options.color.replace("#", "") })}/></a:buClr>`;
|
|
694
|
-
if (options.size !== void 0) s += `<a:buSzPct${attrs({ val: `${options.size}%` })}/>`;
|
|
695
|
-
s += `<a:buFont${attrs({
|
|
696
|
-
typeface: "Arial",
|
|
697
|
-
panose: "020B0604020202020204",
|
|
698
|
-
pitchFamily: "34",
|
|
699
|
-
charset: "0"
|
|
700
|
-
})}/>`;
|
|
701
|
-
if (options.type === "char") s += `<a:buChar${attrs({ char: options.char ?? "•" })}/>`;
|
|
702
|
-
else if (options.type === "autoNum") {
|
|
703
|
-
const buAttrs = { type: options.format ?? "arabicPeriod" };
|
|
704
|
-
if (options.startAt !== void 0) buAttrs.startAt = options.startAt;
|
|
705
|
-
s += `<a:buAutoNum${attrs(buAttrs)}/>`;
|
|
706
|
-
}
|
|
707
|
-
return s;
|
|
708
|
-
}
|
|
709
|
-
function buildParagraphPropertiesXml(options) {
|
|
710
|
-
const attrStr = attrs({
|
|
711
|
-
algn: options.alignment ? TextAlignment[options.alignment] : void 0,
|
|
712
|
-
lvl: options.indentLevel,
|
|
713
|
-
marL: options.marginIndent,
|
|
714
|
-
marR: options.marginRight,
|
|
715
|
-
defTabSz: options.defTabSize
|
|
716
|
-
});
|
|
717
|
-
const body = [];
|
|
718
|
-
if (options.lineSpacing !== void 0) body.push(`<a:lnSpc><a:spcPct${attrs({ val: options.lineSpacing * 1e3 })}/></a:lnSpc>`);
|
|
719
|
-
if (options.lineSpacingPoints !== void 0) body.push(`<a:lnSpc><a:spcPts${attrs({ val: options.lineSpacingPoints * 100 })}/></a:lnSpc>`);
|
|
720
|
-
if (options.marginBottom !== void 0 || options.marginTop !== void 0) body.push(`<a:spcAft><a:spcPts${attrs({ val: options.marginBottom ?? 0 })}/></a:spcAft>`);
|
|
721
|
-
if (options.marginTop !== void 0) body.push(`<a:spcBef><a:spcPts${attrs({ val: options.marginTop })}/></a:spcBef>`);
|
|
722
|
-
if (options.bullet) body.push(buildBulletChildrenXml(options.bullet));
|
|
723
|
-
else if (options.bulletNone !== false) body.push("<a:buNone/>");
|
|
724
|
-
if (!attrStr && body.length === 0) return "";
|
|
725
|
-
if (body.length === 0) return `<a:pPr${attrStr}/>`;
|
|
726
|
-
return `<a:pPr${attrStr}>${body.join("")}</a:pPr>`;
|
|
727
|
-
}
|
|
728
684
|
//#endregion
|
|
729
685
|
//#region src/file/shape/paragraph/run-properties.ts
|
|
730
686
|
init_fill();
|
|
@@ -821,66 +777,7 @@ var RunProperties = class extends XmlComponent {
|
|
|
821
777
|
} }).prepForXml(context) ?? void 0;
|
|
822
778
|
return buildRunProperties(opts, hyperlinkKey, fillObj, effectListObj, outlineObj);
|
|
823
779
|
}
|
|
824
|
-
toXml(context) {
|
|
825
|
-
const opts = this.options;
|
|
826
|
-
let hyperlinkKey;
|
|
827
|
-
if (opts.hyperlink) {
|
|
828
|
-
hyperlinkKey = `hlink_${nextHyperlinkId++}`;
|
|
829
|
-
context.fileData?.Hyperlinks?.addHyperlink(hyperlinkKey, opts.hyperlink.url, opts.hyperlink.tooltip);
|
|
830
|
-
}
|
|
831
|
-
let fillObj;
|
|
832
|
-
if (opts.fill !== void 0) fillObj = buildFill(opts.fill).prepForXml(context) ?? void 0;
|
|
833
|
-
let outlineObj;
|
|
834
|
-
if (opts.outline) outlineObj = createOutline$1({
|
|
835
|
-
width: 12700,
|
|
836
|
-
type: "solidFill",
|
|
837
|
-
color: { value: "000000" }
|
|
838
|
-
}).prepForXml(context) ?? void 0;
|
|
839
|
-
let effectListObj;
|
|
840
|
-
if (opts.shadow) effectListObj = createEffectList$1({ outerShadow: {
|
|
841
|
-
blurRadius: 50800,
|
|
842
|
-
distance: 38100,
|
|
843
|
-
direction: 27e5,
|
|
844
|
-
color: {
|
|
845
|
-
value: "000000",
|
|
846
|
-
transforms: { alpha: 4e4 }
|
|
847
|
-
}
|
|
848
|
-
} }).prepForXml(context) ?? void 0;
|
|
849
|
-
return buildRunPropertiesXml(opts, hyperlinkKey, fillObj, effectListObj, outlineObj);
|
|
850
|
-
}
|
|
851
780
|
};
|
|
852
|
-
/**
|
|
853
|
-
* String version of buildRunProperties for zero-allocation serialization.
|
|
854
|
-
*/
|
|
855
|
-
function buildRunPropertiesXml(options, hyperlinkKey, fillObject, effectListObject, outlineObject) {
|
|
856
|
-
const a = {};
|
|
857
|
-
if (options.fontSize) a.sz = options.fontSize * 100;
|
|
858
|
-
if (options.bold !== void 0) a.b = options.bold;
|
|
859
|
-
if (options.italic !== void 0) a.i = options.italic;
|
|
860
|
-
if (options.underline) a.u = UnderlineStyle[options.underline];
|
|
861
|
-
if (options.lang) a.lang = options.lang;
|
|
862
|
-
if (options.strike) a.strike = StrikeStyle[options.strike];
|
|
863
|
-
if (options.baseline !== void 0) a.baseline = options.baseline;
|
|
864
|
-
if (options.capitalization) a.cap = TextCapitalization[options.capitalization] ?? options.capitalization;
|
|
865
|
-
if (options.spacing !== void 0) a.spc = options.spacing;
|
|
866
|
-
if (options.noProof !== void 0) a.noProof = options.noProof;
|
|
867
|
-
if (options.dirty !== void 0) a.dirty = options.dirty;
|
|
868
|
-
const attrStr = attrs(a);
|
|
869
|
-
const body = [];
|
|
870
|
-
if (options.font) body.push(`<a:latin${attrs({ typeface: options.font })}/><a:ea${attrs({ typeface: options.font })}/>`);
|
|
871
|
-
if (options.hyperlink && hyperlinkKey) {
|
|
872
|
-
const h = { "r:id": `{hlink:${hyperlinkKey}}` };
|
|
873
|
-
if (options.hyperlink.tooltip) h.tooltip = options.hyperlink.tooltip;
|
|
874
|
-
body.push(`<a:hlinkClick${attrs(h)}/>`);
|
|
875
|
-
}
|
|
876
|
-
if (options.rightToLeft !== void 0) body.push(`<a:rtl${attrs({ val: options.rightToLeft ? 1 : 0 })}/>`);
|
|
877
|
-
if (fillObject) body.push(xml(fillObject));
|
|
878
|
-
if (outlineObject) body.push(xml(outlineObject));
|
|
879
|
-
if (effectListObject) body.push(xml(effectListObject));
|
|
880
|
-
if (!attrStr && body.length === 0) return "";
|
|
881
|
-
if (body.length === 0) return `<a:rPr${attrStr}/>`;
|
|
882
|
-
return `<a:rPr${attrStr}>${body.join("")}</a:rPr>`;
|
|
883
|
-
}
|
|
884
781
|
//#endregion
|
|
885
782
|
//#region src/file/shape/paragraph/run.ts
|
|
886
783
|
init_xml_components();
|
|
@@ -903,16 +800,6 @@ var TextRun = class extends XmlComponent {
|
|
|
903
800
|
if (this.options.text) children.push({ "a:t": [this.options.text] });
|
|
904
801
|
return { "a:r": children.length === 0 ? {} : children.length === 1 && "_attr" in children[0] ? children[0] : children };
|
|
905
802
|
}
|
|
906
|
-
toXml(context) {
|
|
907
|
-
let s = "<a:r>";
|
|
908
|
-
if (RunProperties.hasProperties(this.options)) {
|
|
909
|
-
const rp = new RunProperties(this.options);
|
|
910
|
-
s += rp.toXml(context);
|
|
911
|
-
}
|
|
912
|
-
if (this.options.text) s += `<a:t>${escapeXml(this.options.text)}</a:t>`;
|
|
913
|
-
s += "</a:r>";
|
|
914
|
-
return s;
|
|
915
|
-
}
|
|
916
803
|
};
|
|
917
804
|
//#endregion
|
|
918
805
|
//#region src/file/shape/paragraph/paragraph.ts
|
|
@@ -942,16 +829,6 @@ var Paragraph = class extends XmlComponent {
|
|
|
942
829
|
children.push(buildEndParagraphRunProperties());
|
|
943
830
|
return { "a:p": children };
|
|
944
831
|
}
|
|
945
|
-
toXml(context) {
|
|
946
|
-
let s = "<a:p>";
|
|
947
|
-
const pPr = buildParagraphPropertiesXml(this.options.properties ?? {});
|
|
948
|
-
if (pPr) s += pPr;
|
|
949
|
-
if (this.options.text) s += new TextRun(this.options.text).toXml(context);
|
|
950
|
-
if (this.options.children) for (const child of this.options.children) s += child.toXml(context);
|
|
951
|
-
s += buildEndParagraphRunPropertiesXml();
|
|
952
|
-
s += "</a:p>";
|
|
953
|
-
return s;
|
|
954
|
-
}
|
|
955
832
|
};
|
|
956
833
|
//#endregion
|
|
957
834
|
//#region src/file/table/table-cell-properties.ts
|
|
@@ -1072,25 +949,6 @@ function buildBodyPr(options) {
|
|
|
1072
949
|
bodyPrContent.push(...bodyPrChildren);
|
|
1073
950
|
return { "a:bodyPr": bodyPrContent.length === 1 && "_attr" in bodyPrContent[0] ? bodyPrContent[0] : bodyPrContent.length > 0 ? bodyPrContent : {} };
|
|
1074
951
|
}
|
|
1075
|
-
function buildBodyPrXml(options) {
|
|
1076
|
-
let s = "<a:bodyPr";
|
|
1077
|
-
const a = {};
|
|
1078
|
-
if (options.vertical) a.vert = options.vertical;
|
|
1079
|
-
if (options.anchor) a.anchor = VerticalAlignment[options.anchor];
|
|
1080
|
-
if (options.wrap) a.wrap = options.wrap;
|
|
1081
|
-
if (options.margins?.top !== void 0) a.tIns = options.margins.top;
|
|
1082
|
-
if (options.margins?.bottom !== void 0) a.bIns = options.margins.bottom;
|
|
1083
|
-
if (options.margins?.left !== void 0) a.lIns = options.margins.left;
|
|
1084
|
-
if (options.margins?.right !== void 0) a.rIns = options.margins.right;
|
|
1085
|
-
if (options.columns !== void 0) a.numCol = options.columns;
|
|
1086
|
-
if (options.columnSpacing !== void 0) a.spcCol = options.columnSpacing * 100;
|
|
1087
|
-
s += attrs(a);
|
|
1088
|
-
let inner = "";
|
|
1089
|
-
if (options.autoFit === "normal") inner += "<a:normAutofit/>";
|
|
1090
|
-
else if (options.autoFit === "shape") inner += "<a:spAutoFit/>";
|
|
1091
|
-
else if (options.autoFit === "none") inner += "<a:noAutofit/>";
|
|
1092
|
-
return inner ? `${s}>${inner}</a:bodyPr>` : `${s}/>`;
|
|
1093
|
-
}
|
|
1094
952
|
/**
|
|
1095
953
|
* p:txBody — Text body within a shape.
|
|
1096
954
|
* Lazy: stores options, builds XML object in prepForXml.
|
|
@@ -1115,18 +973,6 @@ var TextBody = class extends XmlComponent {
|
|
|
1115
973
|
}
|
|
1116
974
|
return { "p:txBody": children };
|
|
1117
975
|
}
|
|
1118
|
-
toXml(context) {
|
|
1119
|
-
let s = "<p:txBody>";
|
|
1120
|
-
s += buildBodyPrXml(this.options);
|
|
1121
|
-
s += "<a:lstStyle/>";
|
|
1122
|
-
if (this.options.paragraphs) for (const p of this.options.paragraphs) {
|
|
1123
|
-
const para = typeof p === "string" ? new Paragraph({ children: [new TextRun({ text: p })] }) : p;
|
|
1124
|
-
s += para.toXml(context);
|
|
1125
|
-
}
|
|
1126
|
-
else s += new Paragraph().toXml(context);
|
|
1127
|
-
s += "</p:txBody>";
|
|
1128
|
-
return s;
|
|
1129
|
-
}
|
|
1130
976
|
};
|
|
1131
977
|
//#endregion
|
|
1132
978
|
//#region src/file/notes/notes-slide.ts
|
|
@@ -2848,708 +2694,86 @@ var SlideTiming = class extends XmlComponent {
|
|
|
2848
2694
|
}
|
|
2849
2695
|
};
|
|
2850
2696
|
//#endregion
|
|
2851
|
-
//#region src/file/
|
|
2697
|
+
//#region src/file/transition/transition.ts
|
|
2852
2698
|
init_xml_components();
|
|
2699
|
+
const ORIENT_TYPES = new Set([
|
|
2700
|
+
"blinds",
|
|
2701
|
+
"checker",
|
|
2702
|
+
"comb",
|
|
2703
|
+
"randomBar"
|
|
2704
|
+
]);
|
|
2705
|
+
const SIDE_DIR_TYPES = new Set(["push", "wipe"]);
|
|
2706
|
+
const EIGHT_DIR_TYPES = new Set(["cover", "pull"]);
|
|
2707
|
+
function buildTransitionElement(type, dir, orient, thruBlk, spokes) {
|
|
2708
|
+
const attrs = {};
|
|
2709
|
+
if (ORIENT_TYPES.has(type) && dir) attrs.dir = dir;
|
|
2710
|
+
else if (SIDE_DIR_TYPES.has(type) && dir) attrs.dir = dir;
|
|
2711
|
+
else if (EIGHT_DIR_TYPES.has(type) && dir) attrs.dir = dir;
|
|
2712
|
+
else if (type === "strips" && dir) attrs.dir = dir;
|
|
2713
|
+
else if ((type === "fade" || type === "cut") && thruBlk !== void 0) attrs.thruBlk = thruBlk ? 1 : 0;
|
|
2714
|
+
else if (type === "split") {
|
|
2715
|
+
attrs.orient = orient ?? "horz";
|
|
2716
|
+
attrs.dir = dir ?? "out";
|
|
2717
|
+
} else if (type === "wheel") attrs.spokes = spokes ?? 4;
|
|
2718
|
+
else if (type === "zoom" && dir) attrs.dir = dir;
|
|
2719
|
+
return { [`p:${type}`]: Object.keys(attrs).length > 0 ? { _attr: attrs } : {} };
|
|
2720
|
+
}
|
|
2721
|
+
function buildTransition(options) {
|
|
2722
|
+
const children = [];
|
|
2723
|
+
const attrs = {};
|
|
2724
|
+
if (options.speed) attrs.spd = options.speed;
|
|
2725
|
+
if (options.advanceOnClick !== void 0) attrs.advClick = options.advanceOnClick ? 1 : 0;
|
|
2726
|
+
if (options.advanceAfterTime !== void 0) attrs.advTm = options.advanceAfterTime;
|
|
2727
|
+
if (Object.keys(attrs).length > 0) children.push({ _attr: attrs });
|
|
2728
|
+
if (options.type) children.push(buildTransitionElement(options.type, options.dir, options.orient, options.thruBlk, options.spokes));
|
|
2729
|
+
return { "p:transition": children.length === 0 ? {} : children };
|
|
2730
|
+
}
|
|
2853
2731
|
/**
|
|
2854
|
-
*
|
|
2855
|
-
*
|
|
2732
|
+
* p:transition — Slide transition effect.
|
|
2733
|
+
* Lazy: stores options, builds XML object in prepForXml.
|
|
2856
2734
|
*/
|
|
2857
|
-
var
|
|
2858
|
-
|
|
2859
|
-
constructor(options
|
|
2860
|
-
super(
|
|
2861
|
-
this.
|
|
2735
|
+
var Transition = class extends BaseXmlComponent {
|
|
2736
|
+
options;
|
|
2737
|
+
constructor(options = {}) {
|
|
2738
|
+
super("p:transition");
|
|
2739
|
+
this.options = options;
|
|
2862
2740
|
}
|
|
2863
|
-
prepForXml(
|
|
2864
|
-
return this.
|
|
2741
|
+
prepForXml(_context) {
|
|
2742
|
+
return buildTransition(this.options);
|
|
2865
2743
|
}
|
|
2866
2744
|
};
|
|
2867
2745
|
//#endregion
|
|
2868
|
-
//#region src/file/
|
|
2746
|
+
//#region src/file/slide/slide.ts
|
|
2869
2747
|
init_xml_components();
|
|
2870
|
-
|
|
2748
|
+
function isAnimatable(child) {
|
|
2749
|
+
return "ShapeId" in child && "Animation" in child;
|
|
2750
|
+
}
|
|
2751
|
+
function collectAnimations(children) {
|
|
2752
|
+
const entries = [];
|
|
2753
|
+
for (const child of children) if (isAnimatable(child)) {
|
|
2754
|
+
const anim = child.Animation;
|
|
2755
|
+
if (anim) entries.push({
|
|
2756
|
+
spid: child.ShapeId,
|
|
2757
|
+
options: anim
|
|
2758
|
+
});
|
|
2759
|
+
}
|
|
2760
|
+
return entries;
|
|
2761
|
+
}
|
|
2871
2762
|
/**
|
|
2872
|
-
* p:
|
|
2873
|
-
*
|
|
2874
|
-
* Uses a media relationship for the audio file (via {media:fileName} placeholder).
|
|
2763
|
+
* p:sld — A slide in a presentation.
|
|
2764
|
+
* Lazy: stores options, builds XML object in prepForXml.
|
|
2875
2765
|
*/
|
|
2876
|
-
var
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
constructor(
|
|
2882
|
-
super("p:
|
|
2883
|
-
|
|
2884
|
-
this.
|
|
2885
|
-
this.
|
|
2886
|
-
|
|
2887
|
-
const mediaFileName = `${name.replace(/\s+/g, "_")}.${options.type}`;
|
|
2888
|
-
this.audioData = {
|
|
2889
|
-
type: options.type,
|
|
2890
|
-
fileName: mediaFileName,
|
|
2891
|
-
transformation: {
|
|
2892
|
-
pixels: {
|
|
2893
|
-
x: options.width ?? 0,
|
|
2894
|
-
y: options.height ?? 0
|
|
2895
|
-
},
|
|
2896
|
-
emus: {
|
|
2897
|
-
x: convertPixelsToEmu$1(options.width ?? 0),
|
|
2898
|
-
y: convertPixelsToEmu$1(options.height ?? 0)
|
|
2899
|
-
}
|
|
2900
|
-
},
|
|
2901
|
-
data: options.data
|
|
2902
|
-
};
|
|
2903
|
-
this.root.push(new BuilderElement({
|
|
2904
|
-
name: "p:nvPicPr",
|
|
2905
|
-
children: [
|
|
2906
|
-
new BuilderElement({
|
|
2907
|
-
name: "a:cNvPr",
|
|
2908
|
-
attributes: {
|
|
2909
|
-
id: {
|
|
2910
|
-
key: "id",
|
|
2911
|
-
value: id
|
|
2912
|
-
},
|
|
2913
|
-
name: {
|
|
2914
|
-
key: "name",
|
|
2915
|
-
value: name
|
|
2916
|
-
},
|
|
2917
|
-
descr: {
|
|
2918
|
-
key: "descr",
|
|
2919
|
-
value: ""
|
|
2920
|
-
}
|
|
2921
|
-
}
|
|
2922
|
-
}),
|
|
2923
|
-
new BuilderElement({
|
|
2924
|
-
name: "a:cNvPicPr",
|
|
2925
|
-
children: [new BuilderElement({
|
|
2926
|
-
name: "a:picLocks",
|
|
2927
|
-
attributes: { noChangeAspect: {
|
|
2928
|
-
key: "noChangeAspect",
|
|
2929
|
-
value: "1"
|
|
2930
|
-
} }
|
|
2931
|
-
})]
|
|
2932
|
-
}),
|
|
2933
|
-
new BuilderElement({
|
|
2934
|
-
name: "p:nvPr",
|
|
2935
|
-
children: [new BuilderElement({
|
|
2936
|
-
name: "p:extLst",
|
|
2937
|
-
children: [new BuilderElement({
|
|
2938
|
-
name: "p:ext",
|
|
2939
|
-
attributes: { uri: {
|
|
2940
|
-
key: "uri",
|
|
2941
|
-
value: MEDIA_EXT_URI$1
|
|
2942
|
-
} },
|
|
2943
|
-
children: [new BuilderElement({
|
|
2944
|
-
name: "p14:media",
|
|
2945
|
-
attributes: {
|
|
2946
|
-
"r:embed": {
|
|
2947
|
-
key: "r:embed",
|
|
2948
|
-
value: `{media:${mediaFileName}}`
|
|
2949
|
-
},
|
|
2950
|
-
"xmlns:p14": {
|
|
2951
|
-
key: "xmlns:p14",
|
|
2952
|
-
value: "http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
2953
|
-
}
|
|
2954
|
-
}
|
|
2955
|
-
})]
|
|
2956
|
-
})]
|
|
2957
|
-
})]
|
|
2958
|
-
})
|
|
2959
|
-
]
|
|
2960
|
-
}));
|
|
2961
|
-
this.root.push(new BuilderElement({
|
|
2962
|
-
name: "p:blipFill",
|
|
2963
|
-
children: [new BuilderElement({
|
|
2964
|
-
name: "a:stretch",
|
|
2965
|
-
children: [new BuilderElement({ name: "a:fillRect" })]
|
|
2966
|
-
})]
|
|
2967
|
-
}));
|
|
2968
|
-
this.root.push(new BuilderElement({
|
|
2969
|
-
name: "p:spPr",
|
|
2970
|
-
children: [new Transform2D({
|
|
2971
|
-
x: convertPixelsToEmu$1(options.x ?? 0),
|
|
2972
|
-
y: convertPixelsToEmu$1(options.y ?? 0),
|
|
2973
|
-
width: convertPixelsToEmu$1(options.width ?? 0),
|
|
2974
|
-
height: convertPixelsToEmu$1(options.height ?? 0)
|
|
2975
|
-
}), new PresetGeometry({ preset: "rect" })]
|
|
2976
|
-
}));
|
|
2977
|
-
}
|
|
2978
|
-
get ShapeId() {
|
|
2979
|
-
return this.shapeId;
|
|
2980
|
-
}
|
|
2981
|
-
get Animation() {
|
|
2982
|
-
return this.animationOptions;
|
|
2983
|
-
}
|
|
2984
|
-
prepForXml(context) {
|
|
2985
|
-
context.fileData?.Media.addMedia(this.audioData.fileName, this.audioData);
|
|
2986
|
-
return super.prepForXml(context);
|
|
2987
|
-
}
|
|
2988
|
-
};
|
|
2989
|
-
//#endregion
|
|
2990
|
-
//#region src/file/media/video-frame.ts
|
|
2991
|
-
init_xml_components();
|
|
2992
|
-
const MEDIA_EXT_URI = "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}";
|
|
2993
|
-
/** Minimal 1x1 transparent PNG (67 bytes). */
|
|
2994
|
-
const MINIMAL_PNG = new Uint8Array([
|
|
2995
|
-
137,
|
|
2996
|
-
80,
|
|
2997
|
-
78,
|
|
2998
|
-
71,
|
|
2999
|
-
13,
|
|
3000
|
-
10,
|
|
3001
|
-
26,
|
|
3002
|
-
10,
|
|
3003
|
-
0,
|
|
3004
|
-
0,
|
|
3005
|
-
0,
|
|
3006
|
-
13,
|
|
3007
|
-
73,
|
|
3008
|
-
72,
|
|
3009
|
-
68,
|
|
3010
|
-
82,
|
|
3011
|
-
0,
|
|
3012
|
-
0,
|
|
3013
|
-
0,
|
|
3014
|
-
1,
|
|
3015
|
-
0,
|
|
3016
|
-
0,
|
|
3017
|
-
0,
|
|
3018
|
-
1,
|
|
3019
|
-
8,
|
|
3020
|
-
6,
|
|
3021
|
-
0,
|
|
3022
|
-
0,
|
|
3023
|
-
0,
|
|
3024
|
-
31,
|
|
3025
|
-
21,
|
|
3026
|
-
196,
|
|
3027
|
-
137,
|
|
3028
|
-
0,
|
|
3029
|
-
0,
|
|
3030
|
-
0,
|
|
3031
|
-
13,
|
|
3032
|
-
73,
|
|
3033
|
-
68,
|
|
3034
|
-
65,
|
|
3035
|
-
84,
|
|
3036
|
-
8,
|
|
3037
|
-
215,
|
|
3038
|
-
99,
|
|
3039
|
-
24,
|
|
3040
|
-
5,
|
|
3041
|
-
163,
|
|
3042
|
-
0,
|
|
3043
|
-
0,
|
|
3044
|
-
0,
|
|
3045
|
-
2,
|
|
3046
|
-
0,
|
|
3047
|
-
1,
|
|
3048
|
-
226,
|
|
3049
|
-
33,
|
|
3050
|
-
188,
|
|
3051
|
-
51,
|
|
3052
|
-
0,
|
|
3053
|
-
0,
|
|
3054
|
-
0,
|
|
3055
|
-
0,
|
|
3056
|
-
73,
|
|
3057
|
-
69,
|
|
3058
|
-
78,
|
|
3059
|
-
68,
|
|
3060
|
-
174,
|
|
3061
|
-
66,
|
|
3062
|
-
96,
|
|
3063
|
-
130
|
|
3064
|
-
]);
|
|
3065
|
-
/**
|
|
3066
|
-
* p:pic — A video frame on a slide.
|
|
3067
|
-
*
|
|
3068
|
-
* Uses three relationships:
|
|
3069
|
-
* - Image relationship for poster frame (via {posterFileName} placeholder)
|
|
3070
|
-
* - Video relationship for video file (via {video:fileName} placeholder in a:videoFile r:link)
|
|
3071
|
-
* - Media relationship for video file (via {media:fileName} placeholder in p14:media r:embed)
|
|
3072
|
-
*/
|
|
3073
|
-
var VideoFrame = class VideoFrame extends XmlComponent {
|
|
3074
|
-
static nextId = 100;
|
|
3075
|
-
posterData;
|
|
3076
|
-
videoData;
|
|
3077
|
-
shapeId;
|
|
3078
|
-
animationOptions;
|
|
3079
|
-
constructor(options) {
|
|
3080
|
-
super("p:pic");
|
|
3081
|
-
const id = VideoFrame.nextId++;
|
|
3082
|
-
this.shapeId = id;
|
|
3083
|
-
this.animationOptions = options.animation;
|
|
3084
|
-
const name = options.name ?? `Video ${id}`;
|
|
3085
|
-
const mediaFileName = `${name.replace(/\s+/g, "_")}.${options.type}`;
|
|
3086
|
-
const posterBytes = options.poster ?? MINIMAL_PNG;
|
|
3087
|
-
const posterType = options.posterType ?? "png";
|
|
3088
|
-
const posterFileName = `${name.replace(/\s+/g, "_")}_poster.${posterType}`;
|
|
3089
|
-
this.videoData = {
|
|
3090
|
-
type: options.type,
|
|
3091
|
-
fileName: mediaFileName,
|
|
3092
|
-
transformation: {
|
|
3093
|
-
pixels: {
|
|
3094
|
-
x: options.width ?? 0,
|
|
3095
|
-
y: options.height ?? 0
|
|
3096
|
-
},
|
|
3097
|
-
emus: {
|
|
3098
|
-
x: convertPixelsToEmu$1(options.width ?? 0),
|
|
3099
|
-
y: convertPixelsToEmu$1(options.height ?? 0)
|
|
3100
|
-
}
|
|
3101
|
-
},
|
|
3102
|
-
data: options.data
|
|
3103
|
-
};
|
|
3104
|
-
this.posterData = {
|
|
3105
|
-
type: posterType === "jpg" ? "jpg" : "png",
|
|
3106
|
-
fileName: posterFileName,
|
|
3107
|
-
transformation: {
|
|
3108
|
-
pixels: {
|
|
3109
|
-
x: options.width ?? 0,
|
|
3110
|
-
y: options.height ?? 0
|
|
3111
|
-
},
|
|
3112
|
-
emus: {
|
|
3113
|
-
x: convertPixelsToEmu$1(options.width ?? 0),
|
|
3114
|
-
y: convertPixelsToEmu$1(options.height ?? 0)
|
|
3115
|
-
}
|
|
3116
|
-
},
|
|
3117
|
-
data: posterBytes
|
|
3118
|
-
};
|
|
3119
|
-
const nvPrChildren = [new BuilderElement({
|
|
3120
|
-
name: "a:videoFile",
|
|
3121
|
-
attributes: { "r:link": {
|
|
3122
|
-
key: "r:link",
|
|
3123
|
-
value: `{video:${mediaFileName}}`
|
|
3124
|
-
} }
|
|
3125
|
-
}), new BuilderElement({
|
|
3126
|
-
name: "p:extLst",
|
|
3127
|
-
children: [new BuilderElement({
|
|
3128
|
-
name: "p:ext",
|
|
3129
|
-
attributes: { uri: {
|
|
3130
|
-
key: "uri",
|
|
3131
|
-
value: MEDIA_EXT_URI
|
|
3132
|
-
} },
|
|
3133
|
-
children: [new BuilderElement({
|
|
3134
|
-
name: "p14:media",
|
|
3135
|
-
attributes: {
|
|
3136
|
-
"r:embed": {
|
|
3137
|
-
key: "r:embed",
|
|
3138
|
-
value: `{media:${mediaFileName}}`
|
|
3139
|
-
},
|
|
3140
|
-
"xmlns:p14": {
|
|
3141
|
-
key: "xmlns:p14",
|
|
3142
|
-
value: "http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
3143
|
-
}
|
|
3144
|
-
}
|
|
3145
|
-
})]
|
|
3146
|
-
})]
|
|
3147
|
-
})];
|
|
3148
|
-
this.root.push(new BuilderElement({
|
|
3149
|
-
name: "p:nvPicPr",
|
|
3150
|
-
children: [
|
|
3151
|
-
new BuilderElement({
|
|
3152
|
-
name: "p:cNvPr",
|
|
3153
|
-
attributes: {
|
|
3154
|
-
id: {
|
|
3155
|
-
key: "id",
|
|
3156
|
-
value: id
|
|
3157
|
-
},
|
|
3158
|
-
name: {
|
|
3159
|
-
key: "name",
|
|
3160
|
-
value: name
|
|
3161
|
-
},
|
|
3162
|
-
descr: {
|
|
3163
|
-
key: "descr",
|
|
3164
|
-
value: ""
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
}),
|
|
3168
|
-
new BuilderElement({
|
|
3169
|
-
name: "p:cNvPicPr",
|
|
3170
|
-
children: [new BuilderElement({
|
|
3171
|
-
name: "a:picLocks",
|
|
3172
|
-
attributes: { noChangeAspect: {
|
|
3173
|
-
key: "noChangeAspect",
|
|
3174
|
-
value: "1"
|
|
3175
|
-
} }
|
|
3176
|
-
})]
|
|
3177
|
-
}),
|
|
3178
|
-
new BuilderElement({
|
|
3179
|
-
name: "p:nvPr",
|
|
3180
|
-
children: nvPrChildren
|
|
3181
|
-
})
|
|
3182
|
-
]
|
|
3183
|
-
}));
|
|
3184
|
-
this.root.push(new BuilderElement({
|
|
3185
|
-
name: "p:blipFill",
|
|
3186
|
-
children: [new BuilderElement({
|
|
3187
|
-
name: "a:blip",
|
|
3188
|
-
attributes: { "r:embed": {
|
|
3189
|
-
key: "r:embed",
|
|
3190
|
-
value: `{${posterFileName}}`
|
|
3191
|
-
} }
|
|
3192
|
-
}), new BuilderElement({
|
|
3193
|
-
name: "a:stretch",
|
|
3194
|
-
children: [new BuilderElement({ name: "a:fillRect" })]
|
|
3195
|
-
})]
|
|
3196
|
-
}));
|
|
3197
|
-
this.root.push(new BuilderElement({
|
|
3198
|
-
name: "p:spPr",
|
|
3199
|
-
children: [new Transform2D({
|
|
3200
|
-
x: convertPixelsToEmu$1(options.x ?? 0),
|
|
3201
|
-
y: convertPixelsToEmu$1(options.y ?? 0),
|
|
3202
|
-
width: convertPixelsToEmu$1(options.width ?? 0),
|
|
3203
|
-
height: convertPixelsToEmu$1(options.height ?? 0)
|
|
3204
|
-
}), new PresetGeometry({ preset: "rect" })]
|
|
3205
|
-
}));
|
|
3206
|
-
}
|
|
3207
|
-
get ShapeId() {
|
|
3208
|
-
return this.shapeId;
|
|
3209
|
-
}
|
|
3210
|
-
get Animation() {
|
|
3211
|
-
return this.animationOptions;
|
|
3212
|
-
}
|
|
3213
|
-
prepForXml(context) {
|
|
3214
|
-
const file = context.fileData;
|
|
3215
|
-
file?.Media.addImage(this.posterData.fileName, this.posterData);
|
|
3216
|
-
file?.Media.addMedia(this.videoData.fileName, this.videoData);
|
|
3217
|
-
return super.prepForXml(context);
|
|
3218
|
-
}
|
|
3219
|
-
};
|
|
3220
|
-
//#endregion
|
|
3221
|
-
//#region src/file/drawingml/outline.ts
|
|
3222
|
-
const DASH_STYLE_MAP = {
|
|
3223
|
-
solid: "SOLID",
|
|
3224
|
-
dash: "DASH",
|
|
3225
|
-
dashDot: "DASH_DOT",
|
|
3226
|
-
lgDash: "LG_DASH",
|
|
3227
|
-
sysDot: "SYS_DOT",
|
|
3228
|
-
sysDash: "SYS_DASH"
|
|
3229
|
-
};
|
|
3230
|
-
const ARROWHEAD_MAP = {
|
|
3231
|
-
triangle: "TRIANGLE",
|
|
3232
|
-
stealth: "STEALTH",
|
|
3233
|
-
diamond: "DIAMOND",
|
|
3234
|
-
oval: "OVAL",
|
|
3235
|
-
open: "ARROW"
|
|
3236
|
-
};
|
|
3237
|
-
const ARROWHEAD_SIZE_MAP = {
|
|
3238
|
-
sm: "SMALL",
|
|
3239
|
-
med: "MEDIUM",
|
|
3240
|
-
lg: "LARGE"
|
|
3241
|
-
};
|
|
3242
|
-
function toCoreLineEnd(type, width, length) {
|
|
3243
|
-
return {
|
|
3244
|
-
type: ARROWHEAD_MAP[type] ?? "TRIANGLE",
|
|
3245
|
-
...width ? { width: ARROWHEAD_SIZE_MAP[width] } : {},
|
|
3246
|
-
...length ? { length: ARROWHEAD_SIZE_MAP[length] } : {}
|
|
3247
|
-
};
|
|
3248
|
-
}
|
|
3249
|
-
/**
|
|
3250
|
-
* Creates an outline element using pptx's simplified API.
|
|
3251
|
-
*/
|
|
3252
|
-
const createOutlineCompat = (options = {}, arrowheads) => createOutline$1({
|
|
3253
|
-
width: options.width,
|
|
3254
|
-
...options.color ? {
|
|
3255
|
-
type: "solidFill",
|
|
3256
|
-
color: { value: options.color.replace("#", "") }
|
|
3257
|
-
} : { type: "noFill" },
|
|
3258
|
-
...options.dashStyle && { dash: DASH_STYLE_MAP[options.dashStyle] ?? "SOLID" },
|
|
3259
|
-
...arrowheads?.endType ? { headEnd: toCoreLineEnd(arrowheads.endType, arrowheads.width, arrowheads.length) } : {},
|
|
3260
|
-
...arrowheads?.beginType ? { tailEnd: toCoreLineEnd(arrowheads.beginType, arrowheads.width, arrowheads.length) } : {}
|
|
3261
|
-
});
|
|
3262
|
-
//#endregion
|
|
3263
|
-
//#region src/file/drawingml/shape-properties.ts
|
|
3264
|
-
init_xml_components();
|
|
3265
|
-
init_effects();
|
|
3266
|
-
init_fill();
|
|
3267
|
-
/**
|
|
3268
|
-
* p:spPr — Shape properties (transform, geometry, fill, outline, effects).
|
|
3269
|
-
* Lazy: stores options, builds XML object directly in prepForXml.
|
|
3270
|
-
*/
|
|
3271
|
-
var ShapeProperties = class extends BaseXmlComponent {
|
|
3272
|
-
options;
|
|
3273
|
-
constructor(options) {
|
|
3274
|
-
super("p:spPr");
|
|
3275
|
-
this.options = options;
|
|
3276
|
-
}
|
|
3277
|
-
prepForXml(context) {
|
|
3278
|
-
const opts = this.options;
|
|
3279
|
-
const children = [];
|
|
3280
|
-
if (opts.x !== void 0 || opts.y !== void 0 || opts.width !== void 0 || opts.height !== void 0 || opts.flipHorizontal !== void 0 || opts.rotation !== void 0) {
|
|
3281
|
-
const xfrmObj = new Transform2D(opts).prepForXml(context);
|
|
3282
|
-
if (xfrmObj) children.push(xfrmObj);
|
|
3283
|
-
}
|
|
3284
|
-
const geomObj = new PresetGeometry({ preset: opts.geometry ?? "rect" }).prepForXml(context);
|
|
3285
|
-
if (geomObj) children.push(geomObj);
|
|
3286
|
-
const media = opts.fill ? extractBlipFillMedia(opts.fill) : void 0;
|
|
3287
|
-
if (media) context.fileData?.Media.addImage(media.fileName, {
|
|
3288
|
-
data: media.data,
|
|
3289
|
-
fileName: media.fileName,
|
|
3290
|
-
type: media.type,
|
|
3291
|
-
transformation: {
|
|
3292
|
-
pixels: {
|
|
3293
|
-
x: 0,
|
|
3294
|
-
y: 0
|
|
3295
|
-
},
|
|
3296
|
-
emus: {
|
|
3297
|
-
x: 0,
|
|
3298
|
-
y: 0
|
|
3299
|
-
}
|
|
3300
|
-
}
|
|
3301
|
-
});
|
|
3302
|
-
const fillObj = buildFill(opts.fill !== void 0 ? opts.fill : { type: "none" }).prepForXml(context);
|
|
3303
|
-
if (fillObj) children.push(fillObj);
|
|
3304
|
-
if (opts.outline) {
|
|
3305
|
-
const outlineObj = createOutlineCompat(opts.outline).prepForXml(context);
|
|
3306
|
-
if (outlineObj) children.push(outlineObj);
|
|
3307
|
-
}
|
|
3308
|
-
if (opts.effects) {
|
|
3309
|
-
const effectObj = createPptxEffectList(opts.effects);
|
|
3310
|
-
if (effectObj) {
|
|
3311
|
-
const effectXmlObj = effectObj.prepForXml(context);
|
|
3312
|
-
if (effectXmlObj) children.push(effectXmlObj);
|
|
3313
|
-
}
|
|
3314
|
-
const scene3d = buildScene3D(opts.effects);
|
|
3315
|
-
if (scene3d) {
|
|
3316
|
-
const sceneObj = scene3d.prepForXml(context);
|
|
3317
|
-
if (sceneObj) children.push(sceneObj);
|
|
3318
|
-
}
|
|
3319
|
-
const shape3d = buildShape3D(opts.effects);
|
|
3320
|
-
if (shape3d) {
|
|
3321
|
-
const shapeObj = shape3d.prepForXml(context);
|
|
3322
|
-
if (shapeObj) children.push(shapeObj);
|
|
3323
|
-
}
|
|
3324
|
-
}
|
|
3325
|
-
if (opts.connectionSites && opts.connectionSites.length > 0) {
|
|
3326
|
-
const cxnChildren = [];
|
|
3327
|
-
for (const site of opts.connectionSites) {
|
|
3328
|
-
const siteAttrs = { pos: `${site.x} ${site.y}` };
|
|
3329
|
-
if (site.angle !== void 0) siteAttrs.ang = site.angle;
|
|
3330
|
-
cxnChildren.push({ "a:cxn": { _attr: siteAttrs } });
|
|
3331
|
-
}
|
|
3332
|
-
children.push({ "a:cxnLst": cxnChildren });
|
|
3333
|
-
}
|
|
3334
|
-
return { "p:spPr": children };
|
|
3335
|
-
}
|
|
3336
|
-
};
|
|
3337
|
-
//#endregion
|
|
3338
|
-
//#region src/file/shape/shape.ts
|
|
3339
|
-
init_xml_components();
|
|
3340
|
-
/**
|
|
3341
|
-
* Pure function: builds p:ph element for placeholder.
|
|
3342
|
-
*/
|
|
3343
|
-
function buildPlaceholder(type, index) {
|
|
3344
|
-
const attrs = { type };
|
|
3345
|
-
if (index !== void 0) attrs.idx = index;
|
|
3346
|
-
return { "p:ph": { _attr: attrs } };
|
|
3347
|
-
}
|
|
3348
|
-
/**
|
|
3349
|
-
* p:sp — A shape on a slide.
|
|
3350
|
-
* Lazy: stores options, builds XML object in prepForXml.
|
|
3351
|
-
*
|
|
3352
|
-
* x/y/width/height accept pixel values and are internally converted to EMUs.
|
|
3353
|
-
*/
|
|
3354
|
-
var Shape = class Shape extends XmlComponent {
|
|
3355
|
-
static nextId = 2;
|
|
3356
|
-
shapeId;
|
|
3357
|
-
animationOptions;
|
|
3358
|
-
options;
|
|
3359
|
-
constructor(options = {}) {
|
|
3360
|
-
super("p:sp");
|
|
3361
|
-
const id = options.id ?? Shape.nextId++;
|
|
3362
|
-
this.shapeId = id;
|
|
3363
|
-
this.animationOptions = options.animation;
|
|
3364
|
-
this.options = {
|
|
3365
|
-
...options,
|
|
3366
|
-
id
|
|
3367
|
-
};
|
|
3368
|
-
}
|
|
3369
|
-
get ShapeId() {
|
|
3370
|
-
return this.shapeId;
|
|
3371
|
-
}
|
|
3372
|
-
get Animation() {
|
|
3373
|
-
return this.animationOptions;
|
|
3374
|
-
}
|
|
3375
|
-
prepForXml(context) {
|
|
3376
|
-
const opts = this.options;
|
|
3377
|
-
const id = this.shapeId;
|
|
3378
|
-
const name = opts.name ?? `Shape ${id}`;
|
|
3379
|
-
const children = [];
|
|
3380
|
-
const nvPrChildren = [];
|
|
3381
|
-
if (opts.placeholder) nvPrChildren.push(buildPlaceholder(opts.placeholder, opts.placeholderIndex));
|
|
3382
|
-
children.push({ "p:nvSpPr": [
|
|
3383
|
-
{ "p:cNvPr": { _attr: {
|
|
3384
|
-
id,
|
|
3385
|
-
name
|
|
3386
|
-
} } },
|
|
3387
|
-
{ "p:cNvSpPr": {} },
|
|
3388
|
-
{ "p:nvPr": nvPrChildren.length > 0 ? nvPrChildren : {} }
|
|
3389
|
-
] });
|
|
3390
|
-
const spPrObj = new ShapeProperties({
|
|
3391
|
-
x: opts.x !== void 0 ? convertPixelsToEmu$1(opts.x) : void 0,
|
|
3392
|
-
y: opts.y !== void 0 ? convertPixelsToEmu$1(opts.y) : void 0,
|
|
3393
|
-
width: opts.width !== void 0 ? convertPixelsToEmu$1(opts.width) : void 0,
|
|
3394
|
-
height: opts.height !== void 0 ? convertPixelsToEmu$1(opts.height) : void 0,
|
|
3395
|
-
geometry: opts.geometry,
|
|
3396
|
-
fill: opts.fill,
|
|
3397
|
-
outline: opts.outline,
|
|
3398
|
-
effects: opts.effects,
|
|
3399
|
-
flipHorizontal: opts.flipHorizontal,
|
|
3400
|
-
rotation: opts.rotation
|
|
3401
|
-
}).prepForXml(context);
|
|
3402
|
-
if (spPrObj) children.push(spPrObj);
|
|
3403
|
-
const txBodyObj = new TextBody({
|
|
3404
|
-
paragraphs: opts.paragraphs ?? (opts.text ? [new Paragraph({ text: opts.text })] : void 0),
|
|
3405
|
-
vertical: opts.textVertical,
|
|
3406
|
-
anchor: opts.textAnchor,
|
|
3407
|
-
autoFit: opts.textAutoFit,
|
|
3408
|
-
wrap: opts.textWrap,
|
|
3409
|
-
margins: opts.textMargins,
|
|
3410
|
-
columns: opts.textColumns,
|
|
3411
|
-
columnSpacing: opts.textColumnSpacing
|
|
3412
|
-
}).prepForXml(context);
|
|
3413
|
-
if (txBodyObj) children.push(txBodyObj);
|
|
3414
|
-
return { "p:sp": children };
|
|
3415
|
-
}
|
|
3416
|
-
toXml(context) {
|
|
3417
|
-
const opts = this.options;
|
|
3418
|
-
const id = this.shapeId;
|
|
3419
|
-
const name = escapeXml(opts.name ?? `Shape ${id}`);
|
|
3420
|
-
let s = "<p:sp><p:nvSpPr>";
|
|
3421
|
-
s += `<p:cNvPr${attrs({
|
|
3422
|
-
id,
|
|
3423
|
-
name
|
|
3424
|
-
})}/>`;
|
|
3425
|
-
s += "<p:cNvSpPr/>";
|
|
3426
|
-
if (opts.placeholder) {
|
|
3427
|
-
const phAttrs = { type: opts.placeholder };
|
|
3428
|
-
if (opts.placeholderIndex !== void 0) phAttrs.idx = opts.placeholderIndex;
|
|
3429
|
-
s += `<p:nvPr><p:ph${attrs(phAttrs)}/></p:nvPr>`;
|
|
3430
|
-
} else s += "<p:nvPr/>";
|
|
3431
|
-
s += "</p:nvSpPr>";
|
|
3432
|
-
const spPrObj = new ShapeProperties({
|
|
3433
|
-
x: opts.x !== void 0 ? convertPixelsToEmu$1(opts.x) : void 0,
|
|
3434
|
-
y: opts.y !== void 0 ? convertPixelsToEmu$1(opts.y) : void 0,
|
|
3435
|
-
width: opts.width !== void 0 ? convertPixelsToEmu$1(opts.width) : void 0,
|
|
3436
|
-
height: opts.height !== void 0 ? convertPixelsToEmu$1(opts.height) : void 0,
|
|
3437
|
-
geometry: opts.geometry,
|
|
3438
|
-
fill: opts.fill,
|
|
3439
|
-
outline: opts.outline,
|
|
3440
|
-
effects: opts.effects,
|
|
3441
|
-
flipHorizontal: opts.flipHorizontal,
|
|
3442
|
-
rotation: opts.rotation
|
|
3443
|
-
}).prepForXml(context);
|
|
3444
|
-
if (spPrObj) s += xml(spPrObj);
|
|
3445
|
-
const txBodyOpts = {
|
|
3446
|
-
paragraphs: opts.paragraphs ?? (opts.text ? [new Paragraph({ text: opts.text })] : void 0),
|
|
3447
|
-
vertical: opts.textVertical,
|
|
3448
|
-
anchor: opts.textAnchor,
|
|
3449
|
-
autoFit: opts.textAutoFit,
|
|
3450
|
-
wrap: opts.textWrap,
|
|
3451
|
-
margins: opts.textMargins,
|
|
3452
|
-
columns: opts.textColumns,
|
|
3453
|
-
columnSpacing: opts.textColumnSpacing
|
|
3454
|
-
};
|
|
3455
|
-
s += new TextBody(txBodyOpts).toXml(context);
|
|
3456
|
-
s += "</p:sp>";
|
|
3457
|
-
return s;
|
|
3458
|
-
}
|
|
3459
|
-
};
|
|
3460
|
-
//#endregion
|
|
3461
|
-
//#region src/file/transition/transition.ts
|
|
3462
|
-
init_xml_components();
|
|
3463
|
-
const ORIENT_TYPES = new Set([
|
|
3464
|
-
"blinds",
|
|
3465
|
-
"checker",
|
|
3466
|
-
"comb",
|
|
3467
|
-
"randomBar"
|
|
3468
|
-
]);
|
|
3469
|
-
const SIDE_DIR_TYPES = new Set(["push", "wipe"]);
|
|
3470
|
-
const EIGHT_DIR_TYPES = new Set(["cover", "pull"]);
|
|
3471
|
-
function buildTransitionElement(type, dir, orient, thruBlk, spokes) {
|
|
3472
|
-
const attrs = {};
|
|
3473
|
-
if (ORIENT_TYPES.has(type) && dir) attrs.dir = dir;
|
|
3474
|
-
else if (SIDE_DIR_TYPES.has(type) && dir) attrs.dir = dir;
|
|
3475
|
-
else if (EIGHT_DIR_TYPES.has(type) && dir) attrs.dir = dir;
|
|
3476
|
-
else if (type === "strips" && dir) attrs.dir = dir;
|
|
3477
|
-
else if ((type === "fade" || type === "cut") && thruBlk !== void 0) attrs.thruBlk = thruBlk ? 1 : 0;
|
|
3478
|
-
else if (type === "split") {
|
|
3479
|
-
attrs.orient = orient ?? "horz";
|
|
3480
|
-
attrs.dir = dir ?? "out";
|
|
3481
|
-
} else if (type === "wheel") attrs.spokes = spokes ?? 4;
|
|
3482
|
-
else if (type === "zoom" && dir) attrs.dir = dir;
|
|
3483
|
-
return { [`p:${type}`]: Object.keys(attrs).length > 0 ? { _attr: attrs } : {} };
|
|
3484
|
-
}
|
|
3485
|
-
function buildTransition(options) {
|
|
3486
|
-
const children = [];
|
|
3487
|
-
const attrs = {};
|
|
3488
|
-
if (options.speed) attrs.spd = options.speed;
|
|
3489
|
-
if (options.advanceOnClick !== void 0) attrs.advClick = options.advanceOnClick ? 1 : 0;
|
|
3490
|
-
if (options.advanceAfterTime !== void 0) attrs.advTm = options.advanceAfterTime;
|
|
3491
|
-
if (Object.keys(attrs).length > 0) children.push({ _attr: attrs });
|
|
3492
|
-
if (options.type) children.push(buildTransitionElement(options.type, options.dir, options.orient, options.thruBlk, options.spokes));
|
|
3493
|
-
return { "p:transition": children.length === 0 ? {} : children };
|
|
3494
|
-
}
|
|
3495
|
-
/**
|
|
3496
|
-
* p:transition — Slide transition effect.
|
|
3497
|
-
* Lazy: stores options, builds XML object in prepForXml.
|
|
3498
|
-
*/
|
|
3499
|
-
var Transition = class extends BaseXmlComponent {
|
|
3500
|
-
options;
|
|
3501
|
-
constructor(options = {}) {
|
|
3502
|
-
super("p:transition");
|
|
3503
|
-
this.options = options;
|
|
3504
|
-
}
|
|
3505
|
-
prepForXml(_context) {
|
|
3506
|
-
return buildTransition(this.options);
|
|
3507
|
-
}
|
|
3508
|
-
};
|
|
3509
|
-
//#endregion
|
|
3510
|
-
//#region src/file/slide/slide.ts
|
|
3511
|
-
init_xml_components();
|
|
3512
|
-
const NV_GRP_SP_PR = "<p:nvGrpSpPr><p:cNvPr id=\"1\" name=\"\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>";
|
|
3513
|
-
const GRP_SP_PR = "<p:grpSpPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"0\" cy=\"0\"/><a:chOff x=\"0\" y=\"0\"/><a:chExt cx=\"0\" cy=\"0\"/></a:xfrm></p:grpSpPr>";
|
|
3514
|
-
const CLR_MAP_OVR = "<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>";
|
|
3515
|
-
const XMLNS = " xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"";
|
|
3516
|
-
function collectAnimations(children) {
|
|
3517
|
-
const entries = [];
|
|
3518
|
-
for (const child of children) {
|
|
3519
|
-
let anim;
|
|
3520
|
-
let spid;
|
|
3521
|
-
if (child instanceof Shape) {
|
|
3522
|
-
anim = child.Animation;
|
|
3523
|
-
spid = child.ShapeId;
|
|
3524
|
-
} else if (child instanceof VideoFrame) {
|
|
3525
|
-
anim = child.Animation;
|
|
3526
|
-
spid = child.ShapeId;
|
|
3527
|
-
} else if (child instanceof AudioFrame) {
|
|
3528
|
-
anim = child.Animation;
|
|
3529
|
-
spid = child.ShapeId;
|
|
3530
|
-
}
|
|
3531
|
-
if (anim && spid !== void 0) entries.push({
|
|
3532
|
-
spid,
|
|
3533
|
-
options: anim
|
|
3534
|
-
});
|
|
3535
|
-
}
|
|
3536
|
-
return entries;
|
|
3537
|
-
}
|
|
3538
|
-
/**
|
|
3539
|
-
* p:sld — A slide in a presentation.
|
|
3540
|
-
* Lazy: stores options, builds XML object in prepForXml.
|
|
3541
|
-
*/
|
|
3542
|
-
var Slide = class extends XmlComponent {
|
|
3543
|
-
children;
|
|
3544
|
-
background;
|
|
3545
|
-
transition;
|
|
3546
|
-
HeaderFooter;
|
|
3547
|
-
constructor(children, background, transition, headerFooter) {
|
|
3548
|
-
super("p:sld");
|
|
3549
|
-
this.children = children;
|
|
3550
|
-
this.background = background;
|
|
3551
|
-
this.transition = transition;
|
|
3552
|
-
this.HeaderFooter = headerFooter;
|
|
2766
|
+
var Slide = class extends XmlComponent {
|
|
2767
|
+
children;
|
|
2768
|
+
background;
|
|
2769
|
+
transition;
|
|
2770
|
+
HeaderFooter;
|
|
2771
|
+
constructor(children, background, transition, headerFooter) {
|
|
2772
|
+
super("p:sld");
|
|
2773
|
+
this.children = children;
|
|
2774
|
+
this.background = background;
|
|
2775
|
+
this.transition = transition;
|
|
2776
|
+
this.HeaderFooter = headerFooter;
|
|
3553
2777
|
}
|
|
3554
2778
|
prepForXml(context) {
|
|
3555
2779
|
const children = [];
|
|
@@ -3606,35 +2830,6 @@ var Slide = class extends XmlComponent {
|
|
|
3606
2830
|
}
|
|
3607
2831
|
return { "p:sld": children };
|
|
3608
2832
|
}
|
|
3609
|
-
toXml(context) {
|
|
3610
|
-
let s = `<p:sld${XMLNS}>`;
|
|
3611
|
-
s += "<p:cSld>";
|
|
3612
|
-
if (this.background) {
|
|
3613
|
-
const bgObj = this.background.prepForXml(context);
|
|
3614
|
-
if (bgObj) s += xml(bgObj);
|
|
3615
|
-
}
|
|
3616
|
-
s += "<p:spTree>";
|
|
3617
|
-
s += NV_GRP_SP_PR;
|
|
3618
|
-
s += GRP_SP_PR;
|
|
3619
|
-
for (const child of this.children) if (typeof child.toXml === "function") s += child.toXml(context);
|
|
3620
|
-
else {
|
|
3621
|
-
const obj = child.prepForXml(context);
|
|
3622
|
-
if (obj) s += xml(obj);
|
|
3623
|
-
}
|
|
3624
|
-
s += "</p:spTree></p:cSld>";
|
|
3625
|
-
s += CLR_MAP_OVR;
|
|
3626
|
-
if (this.transition) {
|
|
3627
|
-
const transObj = buildTransition(this.transition);
|
|
3628
|
-
if (transObj) s += xml(transObj);
|
|
3629
|
-
}
|
|
3630
|
-
const animations = collectAnimations(this.children);
|
|
3631
|
-
if (animations.length > 0) {
|
|
3632
|
-
const timingObj = new SlideTiming(animations).prepForXml(context);
|
|
3633
|
-
if (timingObj) s += xml(timingObj);
|
|
3634
|
-
}
|
|
3635
|
-
s += "</p:sld>";
|
|
3636
|
-
return s;
|
|
3637
|
-
}
|
|
3638
2833
|
};
|
|
3639
2834
|
//#endregion
|
|
3640
2835
|
//#region src/file/table-styles.ts
|
|
@@ -4117,6 +3312,250 @@ var File = class {
|
|
|
4117
3312
|
}
|
|
4118
3313
|
};
|
|
4119
3314
|
//#endregion
|
|
3315
|
+
//#region src/file/drawingml/outline.ts
|
|
3316
|
+
const DASH_STYLE_MAP = {
|
|
3317
|
+
solid: "SOLID",
|
|
3318
|
+
dash: "DASH",
|
|
3319
|
+
dashDot: "DASH_DOT",
|
|
3320
|
+
lgDash: "LG_DASH",
|
|
3321
|
+
sysDot: "SYS_DOT",
|
|
3322
|
+
sysDash: "SYS_DASH"
|
|
3323
|
+
};
|
|
3324
|
+
const ARROWHEAD_MAP = {
|
|
3325
|
+
triangle: "TRIANGLE",
|
|
3326
|
+
stealth: "STEALTH",
|
|
3327
|
+
diamond: "DIAMOND",
|
|
3328
|
+
oval: "OVAL",
|
|
3329
|
+
open: "ARROW"
|
|
3330
|
+
};
|
|
3331
|
+
const ARROWHEAD_SIZE_MAP = {
|
|
3332
|
+
sm: "SMALL",
|
|
3333
|
+
med: "MEDIUM",
|
|
3334
|
+
lg: "LARGE"
|
|
3335
|
+
};
|
|
3336
|
+
function toCoreLineEnd(type, width, length) {
|
|
3337
|
+
return {
|
|
3338
|
+
type: ARROWHEAD_MAP[type] ?? "TRIANGLE",
|
|
3339
|
+
...width ? { width: ARROWHEAD_SIZE_MAP[width] } : {},
|
|
3340
|
+
...length ? { length: ARROWHEAD_SIZE_MAP[length] } : {}
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
/**
|
|
3344
|
+
* Creates an outline element using pptx's simplified API.
|
|
3345
|
+
*/
|
|
3346
|
+
const createOutlineCompat = (options = {}, arrowheads) => createOutline$1({
|
|
3347
|
+
width: options.width,
|
|
3348
|
+
...options.color ? {
|
|
3349
|
+
type: "solidFill",
|
|
3350
|
+
color: { value: options.color.replace("#", "") }
|
|
3351
|
+
} : { type: "noFill" },
|
|
3352
|
+
...options.dashStyle && { dash: DASH_STYLE_MAP[options.dashStyle] ?? "SOLID" },
|
|
3353
|
+
...arrowheads?.endType ? { headEnd: toCoreLineEnd(arrowheads.endType, arrowheads.width, arrowheads.length) } : {},
|
|
3354
|
+
...arrowheads?.beginType ? { tailEnd: toCoreLineEnd(arrowheads.beginType, arrowheads.width, arrowheads.length) } : {}
|
|
3355
|
+
});
|
|
3356
|
+
//#endregion
|
|
3357
|
+
//#region src/file/drawingml/transform-2d.ts
|
|
3358
|
+
init_xml_components();
|
|
3359
|
+
/**
|
|
3360
|
+
* a:xfrm / p:xfrm — 2D transform for shapes and graphic frames (position + size in EMUs).
|
|
3361
|
+
* Delegates to core createTransform2D.
|
|
3362
|
+
*/
|
|
3363
|
+
var Transform2D = class extends XmlComponent {
|
|
3364
|
+
core;
|
|
3365
|
+
constructor(options, prefix = "a") {
|
|
3366
|
+
super(`${prefix}:xfrm`);
|
|
3367
|
+
this.core = createTransform2D(options, `${prefix}:xfrm`);
|
|
3368
|
+
}
|
|
3369
|
+
prepForXml(context) {
|
|
3370
|
+
return this.core["prepForXml"]?.(context);
|
|
3371
|
+
}
|
|
3372
|
+
};
|
|
3373
|
+
//#endregion
|
|
3374
|
+
//#region src/file/drawingml/shape-properties.ts
|
|
3375
|
+
init_xml_components();
|
|
3376
|
+
init_effects();
|
|
3377
|
+
init_fill();
|
|
3378
|
+
/**
|
|
3379
|
+
* p:spPr — Shape properties (transform, geometry, fill, outline, effects).
|
|
3380
|
+
* Lazy: stores options, builds XML object directly in prepForXml.
|
|
3381
|
+
*/
|
|
3382
|
+
var ShapeProperties = class extends BaseXmlComponent {
|
|
3383
|
+
options;
|
|
3384
|
+
constructor(options) {
|
|
3385
|
+
super("p:spPr");
|
|
3386
|
+
this.options = options;
|
|
3387
|
+
}
|
|
3388
|
+
prepForXml(context) {
|
|
3389
|
+
const opts = this.options;
|
|
3390
|
+
const children = [];
|
|
3391
|
+
if (opts.x !== void 0 || opts.y !== void 0 || opts.width !== void 0 || opts.height !== void 0 || opts.flipHorizontal !== void 0 || opts.rotation !== void 0) {
|
|
3392
|
+
const xfrmObj = new Transform2D(opts).prepForXml(context);
|
|
3393
|
+
if (xfrmObj) children.push(xfrmObj);
|
|
3394
|
+
}
|
|
3395
|
+
const geomObj = new PresetGeometry({ preset: opts.geometry ?? "rect" }).prepForXml(context);
|
|
3396
|
+
if (geomObj) children.push(geomObj);
|
|
3397
|
+
const media = opts.fill ? extractBlipFillMedia(opts.fill) : void 0;
|
|
3398
|
+
if (media) context.fileData?.Media.addImage(media.fileName, {
|
|
3399
|
+
data: media.data,
|
|
3400
|
+
fileName: media.fileName,
|
|
3401
|
+
type: media.type,
|
|
3402
|
+
transformation: {
|
|
3403
|
+
pixels: {
|
|
3404
|
+
x: 0,
|
|
3405
|
+
y: 0
|
|
3406
|
+
},
|
|
3407
|
+
emus: {
|
|
3408
|
+
x: 0,
|
|
3409
|
+
y: 0
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
});
|
|
3413
|
+
const fillObj = buildFill(opts.fill !== void 0 ? opts.fill : { type: "none" }).prepForXml(context);
|
|
3414
|
+
if (fillObj) children.push(fillObj);
|
|
3415
|
+
if (opts.outline) {
|
|
3416
|
+
const outlineObj = createOutlineCompat(opts.outline).prepForXml(context);
|
|
3417
|
+
if (outlineObj) children.push(outlineObj);
|
|
3418
|
+
}
|
|
3419
|
+
if (opts.effects) {
|
|
3420
|
+
const effectObj = createPptxEffectList(opts.effects);
|
|
3421
|
+
if (effectObj) {
|
|
3422
|
+
const effectXmlObj = effectObj.prepForXml(context);
|
|
3423
|
+
if (effectXmlObj) children.push(effectXmlObj);
|
|
3424
|
+
}
|
|
3425
|
+
const scene3d = buildScene3D(opts.effects);
|
|
3426
|
+
if (scene3d) {
|
|
3427
|
+
const sceneObj = scene3d.prepForXml(context);
|
|
3428
|
+
if (sceneObj) children.push(sceneObj);
|
|
3429
|
+
}
|
|
3430
|
+
const shape3d = buildShape3D(opts.effects);
|
|
3431
|
+
if (shape3d) {
|
|
3432
|
+
const shapeObj = shape3d.prepForXml(context);
|
|
3433
|
+
if (shapeObj) children.push(shapeObj);
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
if (opts.connectionSites && opts.connectionSites.length > 0) {
|
|
3437
|
+
const cxnChildren = [];
|
|
3438
|
+
for (const site of opts.connectionSites) {
|
|
3439
|
+
const siteAttrs = { pos: `${site.x} ${site.y}` };
|
|
3440
|
+
if (site.angle !== void 0) siteAttrs.ang = site.angle;
|
|
3441
|
+
cxnChildren.push({ "a:cxn": { _attr: siteAttrs } });
|
|
3442
|
+
}
|
|
3443
|
+
children.push({ "a:cxnLst": cxnChildren });
|
|
3444
|
+
}
|
|
3445
|
+
return { "p:spPr": children };
|
|
3446
|
+
}
|
|
3447
|
+
};
|
|
3448
|
+
//#endregion
|
|
3449
|
+
//#region src/util/position.ts
|
|
3450
|
+
/**
|
|
3451
|
+
* Position/size conversion utilities for PPTX components.
|
|
3452
|
+
* @module
|
|
3453
|
+
*/
|
|
3454
|
+
/**
|
|
3455
|
+
* Converts pixel position/size values to EMU, defaulting missing values to 0.
|
|
3456
|
+
*
|
|
3457
|
+
* Used by components that always need a transform (ChartFrame, Picture,
|
|
3458
|
+
* TableFrame, SmartArtFrame, MediaFrameBase, etc.).
|
|
3459
|
+
*/
|
|
3460
|
+
function emuPosition(opts) {
|
|
3461
|
+
return {
|
|
3462
|
+
x: convertPixelsToEmu$1(opts.x ?? 0),
|
|
3463
|
+
y: convertPixelsToEmu$1(opts.y ?? 0),
|
|
3464
|
+
width: convertPixelsToEmu$1(opts.width ?? 0),
|
|
3465
|
+
height: convertPixelsToEmu$1(opts.height ?? 0)
|
|
3466
|
+
};
|
|
3467
|
+
}
|
|
3468
|
+
/**
|
|
3469
|
+
* Converts pixel position/size values to EMU, preserving undefined.
|
|
3470
|
+
*
|
|
3471
|
+
* Used by Shape which may omit position to let PowerPoint auto-layout.
|
|
3472
|
+
*/
|
|
3473
|
+
function emuPositionOptional(opts) {
|
|
3474
|
+
return {
|
|
3475
|
+
x: opts.x !== void 0 ? convertPixelsToEmu$1(opts.x) : void 0,
|
|
3476
|
+
y: opts.y !== void 0 ? convertPixelsToEmu$1(opts.y) : void 0,
|
|
3477
|
+
width: opts.width !== void 0 ? convertPixelsToEmu$1(opts.width) : void 0,
|
|
3478
|
+
height: opts.height !== void 0 ? convertPixelsToEmu$1(opts.height) : void 0
|
|
3479
|
+
};
|
|
3480
|
+
}
|
|
3481
|
+
//#endregion
|
|
3482
|
+
//#region src/file/shape/shape.ts
|
|
3483
|
+
init_xml_components();
|
|
3484
|
+
/**
|
|
3485
|
+
* Pure function: builds p:ph element for placeholder.
|
|
3486
|
+
*/
|
|
3487
|
+
function buildPlaceholder(type, index) {
|
|
3488
|
+
const attrs = { type };
|
|
3489
|
+
if (index !== void 0) attrs.idx = index;
|
|
3490
|
+
return { "p:ph": { _attr: attrs } };
|
|
3491
|
+
}
|
|
3492
|
+
/**
|
|
3493
|
+
* p:sp — A shape on a slide.
|
|
3494
|
+
* Lazy: stores options, builds XML object in prepForXml.
|
|
3495
|
+
*
|
|
3496
|
+
* x/y/width/height accept pixel values and are internally converted to EMUs.
|
|
3497
|
+
*/
|
|
3498
|
+
var Shape = class Shape extends XmlComponent {
|
|
3499
|
+
static nextId = 2;
|
|
3500
|
+
shapeId;
|
|
3501
|
+
animationOptions;
|
|
3502
|
+
options;
|
|
3503
|
+
constructor(options = {}) {
|
|
3504
|
+
super("p:sp");
|
|
3505
|
+
const id = options.id ?? Shape.nextId++;
|
|
3506
|
+
this.shapeId = id;
|
|
3507
|
+
this.animationOptions = options.animation;
|
|
3508
|
+
this.options = {
|
|
3509
|
+
...options,
|
|
3510
|
+
id
|
|
3511
|
+
};
|
|
3512
|
+
}
|
|
3513
|
+
get ShapeId() {
|
|
3514
|
+
return this.shapeId;
|
|
3515
|
+
}
|
|
3516
|
+
get Animation() {
|
|
3517
|
+
return this.animationOptions;
|
|
3518
|
+
}
|
|
3519
|
+
prepForXml(context) {
|
|
3520
|
+
const opts = this.options;
|
|
3521
|
+
const id = this.shapeId;
|
|
3522
|
+
const name = opts.name ?? `Shape ${id}`;
|
|
3523
|
+
const children = [];
|
|
3524
|
+
const nvPrChildren = [];
|
|
3525
|
+
if (opts.placeholder) nvPrChildren.push(buildPlaceholder(opts.placeholder, opts.placeholderIndex));
|
|
3526
|
+
children.push({ "p:nvSpPr": [
|
|
3527
|
+
{ "p:cNvPr": { _attr: {
|
|
3528
|
+
id,
|
|
3529
|
+
name
|
|
3530
|
+
} } },
|
|
3531
|
+
{ "p:cNvSpPr": {} },
|
|
3532
|
+
{ "p:nvPr": nvPrChildren.length > 0 ? nvPrChildren : {} }
|
|
3533
|
+
] });
|
|
3534
|
+
const spPrObj = new ShapeProperties({
|
|
3535
|
+
...emuPositionOptional(opts),
|
|
3536
|
+
geometry: opts.geometry,
|
|
3537
|
+
fill: opts.fill,
|
|
3538
|
+
outline: opts.outline,
|
|
3539
|
+
effects: opts.effects,
|
|
3540
|
+
flipHorizontal: opts.flipHorizontal,
|
|
3541
|
+
rotation: opts.rotation
|
|
3542
|
+
}).prepForXml(context);
|
|
3543
|
+
if (spPrObj) children.push(spPrObj);
|
|
3544
|
+
const txBodyObj = new TextBody({
|
|
3545
|
+
paragraphs: opts.paragraphs ?? (opts.text ? [new Paragraph({ text: opts.text })] : void 0),
|
|
3546
|
+
vertical: opts.textVertical,
|
|
3547
|
+
anchor: opts.textAnchor,
|
|
3548
|
+
autoFit: opts.textAutoFit,
|
|
3549
|
+
wrap: opts.textWrap,
|
|
3550
|
+
margins: opts.textMargins,
|
|
3551
|
+
columns: opts.textColumns,
|
|
3552
|
+
columnSpacing: opts.textColumnSpacing
|
|
3553
|
+
}).prepForXml(context);
|
|
3554
|
+
if (txBodyObj) children.push(txBodyObj);
|
|
3555
|
+
return { "p:sp": children };
|
|
3556
|
+
}
|
|
3557
|
+
};
|
|
3558
|
+
//#endregion
|
|
4120
3559
|
//#region src/file/shape/paragraph/text.ts
|
|
4121
3560
|
init_xml_components();
|
|
4122
3561
|
/**
|
|
@@ -4502,6 +3941,281 @@ var ConnectorShape = class ConnectorShape extends XmlComponent {
|
|
|
4502
3941
|
}
|
|
4503
3942
|
};
|
|
4504
3943
|
//#endregion
|
|
3944
|
+
//#region src/file/media/media-frame-base.ts
|
|
3945
|
+
/**
|
|
3946
|
+
* Shared base class for media frames (video, audio) on slides.
|
|
3947
|
+
* @module
|
|
3948
|
+
*/
|
|
3949
|
+
init_xml_components();
|
|
3950
|
+
/**
|
|
3951
|
+
* Builds an IMediaData object from pixel dimensions and raw data.
|
|
3952
|
+
* Generic parameter preserves the specific type literal for correct union narrowing.
|
|
3953
|
+
*/
|
|
3954
|
+
function buildMediaData(type, fileName, width, height, data) {
|
|
3955
|
+
return {
|
|
3956
|
+
type,
|
|
3957
|
+
fileName,
|
|
3958
|
+
transformation: {
|
|
3959
|
+
pixels: {
|
|
3960
|
+
x: width,
|
|
3961
|
+
y: height
|
|
3962
|
+
},
|
|
3963
|
+
emus: {
|
|
3964
|
+
x: convertPixelsToEmu$1(width),
|
|
3965
|
+
y: convertPixelsToEmu$1(height)
|
|
3966
|
+
}
|
|
3967
|
+
},
|
|
3968
|
+
data
|
|
3969
|
+
};
|
|
3970
|
+
}
|
|
3971
|
+
/**
|
|
3972
|
+
* Base class for media frames (video, audio) on slides.
|
|
3973
|
+
*
|
|
3974
|
+
* Encapsulates the common structure: ID assignment, media data building,
|
|
3975
|
+
* p:spPr (Transform2D + PresetGeometry), p:blipFill, p:nvPicPr parts,
|
|
3976
|
+
* and media registration in prepForXml.
|
|
3977
|
+
*/
|
|
3978
|
+
var MediaFrameBase = class extends XmlComponent {
|
|
3979
|
+
shapeId;
|
|
3980
|
+
animationOptions;
|
|
3981
|
+
mediaData;
|
|
3982
|
+
posterData;
|
|
3983
|
+
constructor(options, id, mediaFileName, params) {
|
|
3984
|
+
super("p:pic");
|
|
3985
|
+
this.shapeId = id;
|
|
3986
|
+
this.animationOptions = options.animation;
|
|
3987
|
+
const name = options.name ?? `Media ${id}`;
|
|
3988
|
+
const w = options.width ?? 0;
|
|
3989
|
+
const h = options.height ?? 0;
|
|
3990
|
+
this.mediaData = buildMediaData(options.type, mediaFileName, w, h, options.data);
|
|
3991
|
+
if (params.posterBytes) {
|
|
3992
|
+
const pt = params.posterType ?? "png";
|
|
3993
|
+
const pfn = params.posterFileName ?? `${name.replace(/\s+/g, "_")}_poster.${pt}`;
|
|
3994
|
+
this.posterData = buildMediaData(pt === "jpg" ? "jpg" : "png", pfn, w, h, params.posterBytes);
|
|
3995
|
+
}
|
|
3996
|
+
const nvPrChildren = [...params.nvPrExtraChildren ?? []];
|
|
3997
|
+
nvPrChildren.push(new BuilderElement({
|
|
3998
|
+
name: "p:extLst",
|
|
3999
|
+
children: [new BuilderElement({
|
|
4000
|
+
name: "p:ext",
|
|
4001
|
+
attributes: { uri: {
|
|
4002
|
+
key: "uri",
|
|
4003
|
+
value: params.extUri
|
|
4004
|
+
} },
|
|
4005
|
+
children: [new BuilderElement({
|
|
4006
|
+
name: "p14:media",
|
|
4007
|
+
attributes: {
|
|
4008
|
+
"r:embed": {
|
|
4009
|
+
key: "r:embed",
|
|
4010
|
+
value: `{media:${mediaFileName}}`
|
|
4011
|
+
},
|
|
4012
|
+
"xmlns:p14": {
|
|
4013
|
+
key: "xmlns:p14",
|
|
4014
|
+
value: "http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
})]
|
|
4018
|
+
})]
|
|
4019
|
+
}));
|
|
4020
|
+
this.root.push(new BuilderElement({
|
|
4021
|
+
name: "p:nvPicPr",
|
|
4022
|
+
children: [
|
|
4023
|
+
new BuilderElement({
|
|
4024
|
+
name: `${params.cNvPrPrefix}:cNvPr`,
|
|
4025
|
+
attributes: {
|
|
4026
|
+
id: {
|
|
4027
|
+
key: "id",
|
|
4028
|
+
value: id
|
|
4029
|
+
},
|
|
4030
|
+
name: {
|
|
4031
|
+
key: "name",
|
|
4032
|
+
value: name
|
|
4033
|
+
},
|
|
4034
|
+
descr: {
|
|
4035
|
+
key: "descr",
|
|
4036
|
+
value: ""
|
|
4037
|
+
}
|
|
4038
|
+
}
|
|
4039
|
+
}),
|
|
4040
|
+
new BuilderElement({
|
|
4041
|
+
name: `${params.cNvPrPrefix}:cNvPicPr`,
|
|
4042
|
+
children: [new BuilderElement({
|
|
4043
|
+
name: "a:picLocks",
|
|
4044
|
+
attributes: { noChangeAspect: {
|
|
4045
|
+
key: "noChangeAspect",
|
|
4046
|
+
value: "1"
|
|
4047
|
+
} }
|
|
4048
|
+
})]
|
|
4049
|
+
}),
|
|
4050
|
+
new BuilderElement({
|
|
4051
|
+
name: "p:nvPr",
|
|
4052
|
+
children: nvPrChildren
|
|
4053
|
+
})
|
|
4054
|
+
]
|
|
4055
|
+
}));
|
|
4056
|
+
const blipFillChildren = [];
|
|
4057
|
+
if (this.posterData) blipFillChildren.push(new BuilderElement({
|
|
4058
|
+
name: "a:blip",
|
|
4059
|
+
attributes: { "r:embed": {
|
|
4060
|
+
key: "r:embed",
|
|
4061
|
+
value: `{${this.posterData.fileName}}`
|
|
4062
|
+
} }
|
|
4063
|
+
}));
|
|
4064
|
+
blipFillChildren.push(new BuilderElement({
|
|
4065
|
+
name: "a:stretch",
|
|
4066
|
+
children: [new BuilderElement({ name: "a:fillRect" })]
|
|
4067
|
+
}));
|
|
4068
|
+
this.root.push(new BuilderElement({
|
|
4069
|
+
name: "p:blipFill",
|
|
4070
|
+
children: blipFillChildren
|
|
4071
|
+
}));
|
|
4072
|
+
this.root.push(new BuilderElement({
|
|
4073
|
+
name: "p:spPr",
|
|
4074
|
+
children: [new Transform2D({ ...emuPosition(options) }), new PresetGeometry({ preset: "rect" })]
|
|
4075
|
+
}));
|
|
4076
|
+
}
|
|
4077
|
+
get ShapeId() {
|
|
4078
|
+
return this.shapeId;
|
|
4079
|
+
}
|
|
4080
|
+
get Animation() {
|
|
4081
|
+
return this.animationOptions;
|
|
4082
|
+
}
|
|
4083
|
+
prepForXml(context) {
|
|
4084
|
+
const file = context.fileData;
|
|
4085
|
+
if (this.posterData) file?.Media.addImage(this.posterData.fileName, this.posterData);
|
|
4086
|
+
file?.Media.addMedia(this.mediaData.fileName, this.mediaData);
|
|
4087
|
+
return super.prepForXml(context);
|
|
4088
|
+
}
|
|
4089
|
+
};
|
|
4090
|
+
//#endregion
|
|
4091
|
+
//#region src/file/media/video-frame.ts
|
|
4092
|
+
init_xml_components();
|
|
4093
|
+
const MEDIA_EXT_URI$1 = "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}";
|
|
4094
|
+
/** Minimal 1x1 transparent PNG (67 bytes). */
|
|
4095
|
+
const MINIMAL_PNG = new Uint8Array([
|
|
4096
|
+
137,
|
|
4097
|
+
80,
|
|
4098
|
+
78,
|
|
4099
|
+
71,
|
|
4100
|
+
13,
|
|
4101
|
+
10,
|
|
4102
|
+
26,
|
|
4103
|
+
10,
|
|
4104
|
+
0,
|
|
4105
|
+
0,
|
|
4106
|
+
0,
|
|
4107
|
+
13,
|
|
4108
|
+
73,
|
|
4109
|
+
72,
|
|
4110
|
+
68,
|
|
4111
|
+
82,
|
|
4112
|
+
0,
|
|
4113
|
+
0,
|
|
4114
|
+
0,
|
|
4115
|
+
1,
|
|
4116
|
+
0,
|
|
4117
|
+
0,
|
|
4118
|
+
0,
|
|
4119
|
+
1,
|
|
4120
|
+
8,
|
|
4121
|
+
6,
|
|
4122
|
+
0,
|
|
4123
|
+
0,
|
|
4124
|
+
0,
|
|
4125
|
+
31,
|
|
4126
|
+
21,
|
|
4127
|
+
196,
|
|
4128
|
+
137,
|
|
4129
|
+
0,
|
|
4130
|
+
0,
|
|
4131
|
+
0,
|
|
4132
|
+
13,
|
|
4133
|
+
73,
|
|
4134
|
+
68,
|
|
4135
|
+
65,
|
|
4136
|
+
84,
|
|
4137
|
+
8,
|
|
4138
|
+
215,
|
|
4139
|
+
99,
|
|
4140
|
+
24,
|
|
4141
|
+
5,
|
|
4142
|
+
163,
|
|
4143
|
+
0,
|
|
4144
|
+
0,
|
|
4145
|
+
0,
|
|
4146
|
+
2,
|
|
4147
|
+
0,
|
|
4148
|
+
1,
|
|
4149
|
+
226,
|
|
4150
|
+
33,
|
|
4151
|
+
188,
|
|
4152
|
+
51,
|
|
4153
|
+
0,
|
|
4154
|
+
0,
|
|
4155
|
+
0,
|
|
4156
|
+
0,
|
|
4157
|
+
73,
|
|
4158
|
+
69,
|
|
4159
|
+
78,
|
|
4160
|
+
68,
|
|
4161
|
+
174,
|
|
4162
|
+
66,
|
|
4163
|
+
96,
|
|
4164
|
+
130
|
|
4165
|
+
]);
|
|
4166
|
+
/**
|
|
4167
|
+
* p:pic — A video frame on a slide.
|
|
4168
|
+
*
|
|
4169
|
+
* Uses three relationships:
|
|
4170
|
+
* - Image relationship for poster frame (via {posterFileName} placeholder)
|
|
4171
|
+
* - Video relationship for video file (via {video:fileName} placeholder in a:videoFile r:link)
|
|
4172
|
+
* - Media relationship for video file (via {media:fileName} placeholder in p14:media r:embed)
|
|
4173
|
+
*/
|
|
4174
|
+
var VideoFrame = class VideoFrame extends MediaFrameBase {
|
|
4175
|
+
static nextId = 100;
|
|
4176
|
+
constructor(options) {
|
|
4177
|
+
const id = VideoFrame.nextId++;
|
|
4178
|
+
const name = options.name ?? `Video ${id}`;
|
|
4179
|
+
const mediaFileName = `${name.replace(/\s+/g, "_")}.${options.type}`;
|
|
4180
|
+
const posterBytes = options.poster ?? MINIMAL_PNG;
|
|
4181
|
+
const posterType = options.posterType ?? "png";
|
|
4182
|
+
const posterFileName = `${name.replace(/\s+/g, "_")}_poster.${posterType}`;
|
|
4183
|
+
super(options, id, mediaFileName, {
|
|
4184
|
+
extUri: MEDIA_EXT_URI$1,
|
|
4185
|
+
cNvPrPrefix: "p",
|
|
4186
|
+
nvPrExtraChildren: [new BuilderElement({
|
|
4187
|
+
name: "a:videoFile",
|
|
4188
|
+
attributes: { "r:link": {
|
|
4189
|
+
key: "r:link",
|
|
4190
|
+
value: `{video:${mediaFileName}}`
|
|
4191
|
+
} }
|
|
4192
|
+
})],
|
|
4193
|
+
posterBytes,
|
|
4194
|
+
posterType,
|
|
4195
|
+
posterFileName
|
|
4196
|
+
});
|
|
4197
|
+
}
|
|
4198
|
+
};
|
|
4199
|
+
//#endregion
|
|
4200
|
+
//#region src/file/media/audio-frame.ts
|
|
4201
|
+
const MEDIA_EXT_URI = "{CF1602FD-DB20-4165-A070-5F299619DA56}";
|
|
4202
|
+
/**
|
|
4203
|
+
* p:pic — An audio frame on a slide.
|
|
4204
|
+
*
|
|
4205
|
+
* Uses a media relationship for the audio file (via {media:fileName} placeholder).
|
|
4206
|
+
*/
|
|
4207
|
+
var AudioFrame = class AudioFrame extends MediaFrameBase {
|
|
4208
|
+
static nextId = 200;
|
|
4209
|
+
constructor(options) {
|
|
4210
|
+
const id = AudioFrame.nextId++;
|
|
4211
|
+
const mediaFileName = `${(options.name ?? `Audio ${id}`).replace(/\s+/g, "_")}.${options.type}`;
|
|
4212
|
+
super(options, id, mediaFileName, {
|
|
4213
|
+
extUri: MEDIA_EXT_URI,
|
|
4214
|
+
cNvPrPrefix: "a"
|
|
4215
|
+
});
|
|
4216
|
+
}
|
|
4217
|
+
};
|
|
4218
|
+
//#endregion
|
|
4505
4219
|
//#region src/file/shape-tree/shape-tree.ts
|
|
4506
4220
|
init_xml_components();
|
|
4507
4221
|
/**
|
|
@@ -4673,12 +4387,7 @@ var Picture = class Picture extends XmlComponent {
|
|
|
4673
4387
|
this.root.push(new BlipFill(fileName));
|
|
4674
4388
|
this.root.push(new BuilderElement({
|
|
4675
4389
|
name: "p:spPr",
|
|
4676
|
-
children: [new Transform2D({
|
|
4677
|
-
x: convertPixelsToEmu$1(options.x ?? 0),
|
|
4678
|
-
y: convertPixelsToEmu$1(options.y ?? 0),
|
|
4679
|
-
width: convertPixelsToEmu$1(options.width ?? 0),
|
|
4680
|
-
height: convertPixelsToEmu$1(options.height ?? 0)
|
|
4681
|
-
}), new PresetGeometry({ preset: "rect" })]
|
|
4390
|
+
children: [new Transform2D({ ...emuPosition(options) }), new PresetGeometry({ preset: "rect" })]
|
|
4682
4391
|
}));
|
|
4683
4392
|
}
|
|
4684
4393
|
prepForXml(context) {
|
|
@@ -4873,12 +4582,7 @@ var TableFrame = class extends XmlComponent {
|
|
|
4873
4582
|
constructor(options) {
|
|
4874
4583
|
super("p:graphicFrame");
|
|
4875
4584
|
this.root.push(new GraphicFrameNonVisual$2());
|
|
4876
|
-
this.root.push(new Transform2D({
|
|
4877
|
-
x: convertPixelsToEmu$1(options.x ?? 0),
|
|
4878
|
-
y: convertPixelsToEmu$1(options.y ?? 0),
|
|
4879
|
-
width: convertPixelsToEmu$1(options.width ?? 0),
|
|
4880
|
-
height: convertPixelsToEmu$1(options.height ?? 0)
|
|
4881
|
-
}, "p"));
|
|
4585
|
+
this.root.push(new Transform2D({ ...emuPosition(options) }, "p"));
|
|
4882
4586
|
const table = new Table(options);
|
|
4883
4587
|
this.root.push(new Graphic(table));
|
|
4884
4588
|
}
|
|
@@ -4902,12 +4606,7 @@ var ChartFrame = class extends XmlComponent {
|
|
|
4902
4606
|
this.chartKey = `chart_${nextChartFrameId++}`;
|
|
4903
4607
|
const id = nextChartFrameId++;
|
|
4904
4608
|
this.root.push(new GraphicFrameNonVisual$1(id));
|
|
4905
|
-
this.root.push(new Transform2D({
|
|
4906
|
-
x: convertPixelsToEmu$1(options.x ?? 0),
|
|
4907
|
-
y: convertPixelsToEmu$1(options.y ?? 0),
|
|
4908
|
-
width: convertPixelsToEmu$1(options.width ?? 0),
|
|
4909
|
-
height: convertPixelsToEmu$1(options.height ?? 0)
|
|
4910
|
-
}, "p"));
|
|
4609
|
+
this.root.push(new Transform2D({ ...emuPosition(options) }, "p"));
|
|
4911
4610
|
this.root.push(new ChartGraphic(this.chartKey));
|
|
4912
4611
|
}
|
|
4913
4612
|
prepForXml(context) {
|
|
@@ -5009,12 +4708,7 @@ var SmartArtFrame = class extends XmlComponent {
|
|
|
5009
4708
|
const id = nextSmartArtFrameId++;
|
|
5010
4709
|
const name = options.name ?? `Diagram ${id}`;
|
|
5011
4710
|
this.root.push(new GraphicFrameNonVisual(id, name));
|
|
5012
|
-
this.root.push(new Transform2D({
|
|
5013
|
-
x: convertPixelsToEmu$1(options.x ?? 0),
|
|
5014
|
-
y: convertPixelsToEmu$1(options.y ?? 0),
|
|
5015
|
-
width: convertPixelsToEmu$1(options.width ?? 0),
|
|
5016
|
-
height: convertPixelsToEmu$1(options.height ?? 0)
|
|
5017
|
-
}, "p"));
|
|
4711
|
+
this.root.push(new Transform2D({ ...emuPosition(options) }, "p"));
|
|
5018
4712
|
this.root.push(new SmartArtGraphic(this.smartArtKey));
|
|
5019
4713
|
}
|
|
5020
4714
|
prepForXml(context) {
|